source: Sophya/trunk/SophyaLib/Manual/sophya.tex@ 3258

Last change on this file since 3258 was 3180, checked in by cmv, 19 years ago

modifs suite a la suppression de CodeMinuit et MinuitAdapt cmv 07/02/2007

File size: 85.1 KB
Line 
1\documentclass[twoside,10pt]{article}
2% Package standard : Utilisation de caracteres accentues, mode francais et graphique
3\usepackage{url}
4\usepackage[latin1]{inputenc}
5\usepackage[T1]{fontenc}
6\usepackage[english]{babel}
7\usepackage{graphicx}
8% package a mettre pour faire du pdf
9\usepackage{palatino}
10
11% Extension de symboles mathematiques
12\usepackage{amssymb}
13
14% Definition pour Docs Sophya
15\usepackage{defsophya}
16
17% Constitution d'index
18\usepackage{makeidx}
19
20\usepackage[ps2pdf,bookmarks,bookmarksnumbered,%
21 urlcolor=blue,citecolor=blue,linkcolor=blue,%
22 pagecolor=blue,%hyperindex,%
23 colorlinks=true,hyperfigures=true,hyperindex=true
24 ]{hyperref}
25
26\makeindex % Constitution d'index
27
28\newcommand{\rond}{$\bullet \ $}
29\newcommand{\etoile}{$\star \ $}
30\newcommand{\cercle}{$\circ \ $}
31\newcommand{\carre}{$\Box \ $}
32
33
34\begin{document}
35
36\begin{titlepage}
37% The title page - top of the page with the title of the paper
38\titrehp{Sophya \\ An overview }
39% Authors list
40\auteurs{
41R. Ansari & ansari@lal.in2p3.fr \\
42E. Aubourg & aubourg@hep.saclay.cea.fr \\
43G. Le Meur & lemeur@lal.in2p3.fr \\
44C. Magneville & cmv@hep.saclay.cea.fr \\
45S. Henrot-Versille & versille@in2p3.fr
46}
47% \auteursall
48% The title page - bottom of the page with the paper number
49\vspace{1cm}
50\begin{center}
51{\bf \Large Sophya Version: 2.0 (V\_Sep2006) }
52\end{center}
53\titrebp{1}
54\end{titlepage}
55
56\tableofcontents
57
58\newpage
59
60\section{Introduction}
61
62{\bf SOPHYA} ({\bf SO}ftware for {\bf PHY}sics {\bf A}nalysis)
63is a collection of C++ classes designed for numerical and
64physics analysis software development. Our goal is to provide
65easy to use, yet powerful classes which can be used by scientists.
66Although some of the SOPHYA modules (SkyMap, Samba, SkyT)
67have been designed with the specific goal of CMB data analysis, most
68modules presented here have a much broader scope and can be
69used in scientific data analysis and modeling/simulation.
70Whenever possible, we use existing numerical packages and libraries,
71encapsulating them in classes in order to facilitate their usage.
72\par
73Our main requirements in designing SOPHYA classes can be summarized as
74follow:
75\begin{itemize}
76\item[\rond] Provide a comprehensive set of data containers, such as arrays and tables
77(tuple) covering the most common needs in scientific simulation and data analysis
78softwares.
79\item[\rond] Take advantage of the C++ language and define methods and operators
80for most basic operation, such as arithmetic operations, in a rather intuitive way, while
81maintaining performances comparable to low level coding in other languages
82(C, Fortran, F90 \ldots)
83\item[\rond] Simplify memory management for programmers using the class library.
84This has been a strong requirement for most SOPHYA classes. Automatic reference
85sharing and memory management is implemented in SOPHYA classes intended
86for large size objects. We recommend to allocate SOPHYA objects on the stack,
87including when objects are returned by methods or functions.
88See section \ref{memgt} for more information.
89\item[\rond] Archiving, importing (reading) and exporting (writing) data in a
90efficient and consistent way is a major concern in many scientific software
91and projects. SOPHYA provide a native data I/O or persistence system,
92(PPF, \ref{ppfdesc}) as well as import/export services for ASCII and FITS formats.
93\end{itemize}
94
95% \vspace*{2mm}
96This documents
97presents only a brief overview of the class library,
98mainly from the user's point of view. A more complete description
99can be found in the reference manual, available from the SOPHYA
100web site: % {\bf http://www.sophya.org}.
101\href{http://www.sophya.org}{http://www.sophya.org}.
102%%%
103%%%
104\subsection{SOPHYA modules}
105\label{sopmodules}
106The source directory tree
107\footnote{ CVS: cvsserver.lal.in2p3.fr:/exp/eros/CVSSophya}
108is organised into a number of modules.
109
110\begin{itemize}
111\item[] {\bf BuildMgr/} Scripts for code management,
112makefile generation and software installation
113\item[] {\bf BaseTools/} General architecture support classes such
114as {\tt PPersist, NDataBlock<T>}, and few utility classes
115such as the dynamic variable list manager ({\tt DVList}) as well
116as the basic set of exception classes used in SOPHYA.
117\item[] {\bf TArray/} template numerical arrays, vectors and matrices \\
118({\tt TArray<T> TMatrix<T> TVector<T> } \ldots)
119\item[] {\bf NTools/} Some standard numerical analysis tools
120(linear, and non linear parameter fitting, FFT, \ldots)
121\item[] {\bf HiStats/} Histogram-ming and data set handling classes (tuples) \\
122({\tt Histo Histo2D NTuple DataTable} \ldots)
123\item[] {\bf SkyMap/} Local and full sky maps, and some 3D geometry
124handling utility classes. \\
125({\tt PixelMap<T>, LocalMap<T>, SphericalMap<T>, \ldots})
126\item[] {\bf SUtils/} This module contains few utility classes, such as the
127{\tt DataCard} class, as well as string manipulation functions in C and C++.
128\item[] {\bf SysTools/} This module contains classes implementing
129an interface to various OS specific services, such
130threads and dynamic link/shared library handling.
131
132\end{itemize}
133
134The modules listed below are more tightly related to the
135CMB (Cosmic Microwave Background) data analysis problem:
136\begin{itemize}
137\item[] {\bf SkyT/}
138classes for spectral emission and detector frequency response modelling \\
139({\tt SpectralResponse, RadSpectra, BlackBody} \ldots)
140\item[] {\bf Samba/} Spherical harmonic analysis, noise generators \ldots
141\end{itemize}
142
143The following modules contain the interface classes with
144external libraries:
145\begin{itemize}
146\item[] {\bf FitsIOServer/} Classes for handling file input-output
147in FITS format using the cfitsio library.
148FITS is maintained by NASA and SAO and is available from: \\
149\href{http://heasarc.gsfc.nasa.gov/docs/software/fitsio/fitsio.html}
150{http://heasarc.gsfc.nasa.gov/docs/software/fitsio/fitsio.html}
151\item[] {\bf LinAlg/} Interface with Lapack linear algebra package.
152Lapack is a linear algebra package and can be downloaded from: \\
153\href{http://www.netlib.org/lapack/}{http://www.netlib.org/lapack/}
154\item[] {\bf IFFTW/} Interface with FFTW package (libfftw.a).
155FFTW is a package for performing Fourier transforms, written in C.
156Documentation and source code can be found at: \\
157\href{http://www.fftw.org/}{http://www.fftw.org/}
158\item[] {\bf XAstroPack/} Interface to some common astronomical
159computation libraries. Presently, this module uses an external library
160extracted from the {\bf Xephem } source code. The corresponding source
161code is also available from SOPHYA cvs repository, module {\bf XephemAstroLib}.
162Information on Xephem can be found at : \\
163\href{http://www.clearskyinstitute.com/xephem/}{http://www.clearskyinstitute.com/xephem/}
164
165\end{itemize}
166
167The following modules contain each a set of related programs using the
168SOPHYA library.
169\begin{itemize}
170\item[] {\bf Tests/} Simple test programs
171\item[] {\bf PrgUtil/} Various utility programs (runcxx, scanppf, scanfits, \ldots)
172\item[] {\bf PrgMap/} Programs performing operations on skymaps: projections,
173power spectrum in harmonic space, \ldots
174\item[] {\bf PMixer/} skymixer and related programs
175\end{itemize}
176
177As a companion to SOPHYA, the {\bf (s)piapp} interactive data analysis
178program is built on top of SOPHYA and the {\bf PI} GUI class library
179and application framework. The {\bf PI} ({\bf P}eida {\bf Interactive})
180development started in 1995, in the EROS \footnote{EROS: {\bf E}xp\'erience
181de {\bf R}echerche d'{\bf O}bjets {\bf S}ombres - http://eros.in2p3.fr}
182microlensing search collaboration, with PEIDA++ \footnote {PEIDA++:
183The EROS data analysis class library -
184http://www.lal.in2p3.fr/recherche/eros/PeidaDoc/}.
185The {\bf PI} documentation and the {\bf piapp} user's guide are available
186from \href{http://www.sophya.org}{http://www.sophya.org}.
187%\href{http://www.sophya.org}{http://www.sophya.org}.
188The {\bf PI} is organized as the following modules:
189\begin{itemize}
190\item[] {\bf PI/} Portable GUI class library and application development
191framework kernel.
192\item[] {\bf PIGcont/} Contour-plot drawing classes.
193\item[] {\bf PIext/} Specific drawers and adapters for SOPHYA objects,
194and the {\bf piapp} interactive data analysis framework.
195\item[] {\bf ProgPI/} interactive analysis tool main program and pre-loaded
196modules.
197\end{itemize}
198
199Modules containing examples and demo programs and scripts:
200\begin{itemize}
201\item[] {\bf Examples/} Sample SOPHYA codes and example programs and
202makefiles.
203\item[] {\bf DemoPIApp/} Sample scripts and programs for (s)piapp
204interactive analysis tools.
205\end{itemize}
206\newpage
207
208\section{Using Sophya}
209The organisation of SOPHYA directories and some of the associated
210utility programs are described in this section.
211Basic usage of Sophya classes is described in the following sections.
212Complete Sophya documentation can be found at our web site
213{\bf http://www.sophya.org}.
214
215\subsection{Directories, environment variables, configuration files}
216\label{directories}
217The environment variable {\bf SOPHYABASE} is used
218to define the path where the Sophya libraries and binaries are installed.
219\begin{itemize}
220\item \$SOPHYABASE/include : Include (.h) files
221\item \$SOPHYABASE/lib : Path for the archive libraries (.a)
222\item \$SOPHYABASE/slb: Shared library path (.so or .dylib on Darwin/MacOS)
223\item \$SOPHYABASE/exe : Path for binary program files
224\end{itemize}
225
226The directory { \tt \$SOPHYABASE/include/SophyaConfInfo/ } contains files
227describing the installed configuration of SOPHYA software.
228
229The file { \tt \$SOPHYABASE/include/machdefs.h } contains definitions
230(flags, typedef) used in SOPHYA, while some more specific flags,
231are found in { \tt \$SOPHYABASE/include/sspvflags.h }
232
233The file { \tt \$SOPHYABASE/include/sophyamake.inc } contains the
234compilation commands and flags used for building the software.
235Users can use most of compilation and link commands defined in this file:
236 {\tt \$CCOMPILE , \$CXXCOMPILE . \$CXXLINK \ldots}.
237 (See module Example).
238
239The configure script (BuildMgr/configure) creates the directory tree and the
240above files. It also copy (or create symbolic link) for all SOPHYA include
241files as well as symbolic links for external libraries
242include files path in {\tt \$SOPHYABASE/include} (FitsIO, FFTW, XAstro \ldots).
243
244Object files for each module are grouped in a static archive library
245by the build procedure (libXXX.a for module
246XXX, with XXX = BaseTools, TArray, HiStats, FitsIOServer \ldots).
247
248When shared libraries are build, all stand alone SOPHYA modules
249are grouped in {\tt libsophya.so}, {\tt libextsophya.so} contains
250the interface modules with external libraries {\bf (FitsIOServer, LinAlg \ldots)},
251while {\bf PI, PIext, PIGcont} modules are grouped in {\tt libPI.so}.
252Alternatively, it is possible to group all modules in a single shared
253library {\tt libAsophyaextPI.so} (See \ref{build})
254
255In order to use the shared libraries, the {\bf LD\_LIBRARY\_PATH} variable
256should contain the Sophya shared library path
257({\tt \$SOPHYABASE/slb}).
258On Silicon Graphics machines with IRIX64 operating system,
259the default SOPHYA configuration correspond to the 64 bit architecture.
260The environment variable { \bf LD\_LIBRARY64\_PATH } replace in
261this case the usual {\bf LD\_LIBRARY\_PATH} variable.
262On IBM machines with AIX, the {\bf LIBPATH} environment variables
263contains the shared libraries search path.
264
265When using the dynamic load services in SOPHYA ({\tt PDynLinkMgr}
266class), in runcxx or (s)piapp applications for example, the shared
267library search path must contain the current working directory (
268dot . in unix).
269
270\subsection{the runcxx program}
271\index{runcxx} \label{runcxx}
272{\bf runcxx} is a simple program which can be used to compile, link
273and run simple C++ programs. It handles the creation of a
274complete program file, containing the basic set C++ include files,
275the necessary include files for SOPHYA SysTools, TArray, HiStats
276and NTools modules, and the main program with exception handling.
277Other Sophya modules can be included using the {\tt -import} flag.
278Use of additional include files can be specified using the
279{\tt -inc} flag.
280\begin{verbatim}
281csh> runcxx -h
282 PIOPersist::Initialize() Starting Sophya Persistence management service
283SOPHYA Version 1.9 Revision 0 (V_Mai2005) -- May 31 2005 15:11:32 cxx
284 runcxx : compiling and running of a piece of C++ code
285 Usage: runcxx [-compopt CompileOptions] [-linkopt LinkOptions]
286 [-tmpdir TmpDirectory] [-f C++CodeFileName]
287 [-inc includefile] [-inc includefile ...]
288 [-import modulename] [-import modulename ...]
289 [-uarg UserArg1 UserArg2 ...]
290 if no file name is specified, read from standard input
291 modulenames: SkyMap, Samba, SkyT, FitsIOServer,
292 LinAlg, IFFTW, XAstroPack
293\end{verbatim}
294Most examples in this manual can be tested using runcxx. The
295example below shows how to compile, link and run a sample
296code.
297\begin{verbatim}
298// File example.icc
299Matrix a(3,3);
300a = IdentityMatrix(1.);
301cout << a ;
302// Executing this sample code
303csh> runcxx -f example.icc
304\end{verbatim}
305
306\subsection{the scanppf program}
307\index{scanppf} \label{scanppf}
308{\bf scanppf} is a simple SOPHYA application which can be used to check
309PPF files and list their contents. It can also provide the list of all registered
310PPF handlers.
311\begin{verbatim}
312csh> scanppf -h
313 PIOPersist::Initialize() Starting Sophya Persistence management service
314SOPHYA Version 2.0 Revision 0 (V_Jul2006) -- Jul 17 2006 14:13:27 cxx
315 Usage: scanppf [flags] filename
316 flags = -s -n -a0 -a1 -a2 -a3 -lh -lho -lmod
317 -s[=default} : Sequential reading of objects
318 -n : Object reading at NameTags
319 -a0...a3 : Tag List with PInPersist.AnalyseTags(0...3)
320 -lh : List PPersist handler classes
321 -lho : List PPersist handler and dataobj classes
322 -lmod : List initialized/registered modules
323\end{verbatim}
324
325\subsection{the scanfits program}
326\index{scanfits} \label{scanfits}
327{\bf scanfits} is a SOPHYA program using the FitsIOServer
328\footnote{FitsIOServer module uses the cfitsio library. scanfits has to be linked with
329with FitsIOServer module and cfitsio libraries, or libextsophya.so}
330module which can be used
331to analyse the content of FITS files. It can list the FITS headers, the appropriate
332SOPHYA-FITS handler (implementing {\tt FitsHandlerInterface}) class, and the list of
333all registered FITS handlers.
334\begin{verbatim}
335csh> scanfits -h
336 PIOPersist::Initialize() Starting Sophya Persistence management service
337SOPHYA Version 2.0 Revision 0 (V_Jul2006) -- Jul 17 2006 14:13:27 cxx
338 Usage: scanfits [flags] filename
339 flags = -V1 -lh -rd -header
340 -V1 : Scan using old (V1) code version
341 -lh : Print the list of registered handlers (FitsHandlerInterface)
342 -rd : try to read each HDU data using appropriate handler
343 -header : List header information
344\end{verbatim}
345
346\newpage
347
348\section{Copy constructor and assignment operator}
349\label{memgt}
350In C++, objects can be copied by assignment or by initialisation.
351Copying by initialisation corresponds to creating an object and
352initialising its value through the copy constructor.
353The copy constructor has its first argument as a reference, or
354const reference to the object's class type. It can have
355more arguments, if default values are provided.
356Copying by assignment applies to an existing object and
357is performed through the assignment operator (=).
358The copy constructor implements this for identical type objects:
359\begin{verbatim}
360class MyObject {
361public:
362 MyObject(); // Default constructor
363 MyObject(MyObject const & a); // Copy constructor
364 MyObject & operator = (MyObject const & a) // Assignment operator
365}
366\end{verbatim}
367The copy constructors play an important role, as they are
368called when class objects are passed by value,
369returned by value, or thrown as an exception.
370\begin{verbatim}
371// A function declaration with an argument of type MyObject,
372// passed by value, and returning a MyObject
373MyObject f(MyObject x)
374{
375 MyObject r;
376 ...
377 return(r); // Copy constructor is called here
378}
379// Calling the function :
380MyObject a;
381f(a); // Copy constructor called for a
382\end{verbatim}
383It should be noted that the C++ syntax is ambiguous for the
384assignment operator. {\tt MyObject x; x=y; } and
385{\tt MyObject x=y;} have different meaning.
386\begin{verbatim}
387MyObject a; // default constructor call
388MyObject b(a); // copy constructor call
389MyObject bb = a; // identical to bb(a) : copy constructor call
390MyObject c; // default constructor call
391c = a; // assignment operator call
392\end{verbatim}
393
394As a general rule in SOPHYA, objects which implements
395reference sharing on their data members have a copy constructor
396which shares the data, while the assignment operator copies or
397duplicate the data.
398
399\newpage
400\section{Module BaseTools}
401
402{\bf BaseTools} contains utility classes such as
403{\tt DVlist}, an hierarchy of exception classes for Sophya, a template
404class {\tcls{NDataBlock}} for handling reference counting on numerical
405arrays, as well as classes providing the services for implementing simple
406serialisation.
407\vspace*{5mm}
408
409\subsection{Initialisation}
410\index{SophyaInitiator}
411A number of actions have to be taken before
412some of the services provided by SOPHYA become operational. This is the case
413of SOPHYA persistence, as well as FITS I/O facilities.
414Initialisation of many SOPHYA modules is performed through an initialiser class,
415which inherits from {\bf SophyaInitiator}.
416\par
417Static instance of each initialiser class exist in the library and the various SOPHYA services
418should be operational when the user code ({\tt main()}) starts, except for
419modules in the second or third shared libraries
420({\tt libextsophya.so libPI.so}). Indeed, a problem related
421to the initialisation of shared libraries arises on some systems
422(Darwin/Mac OS X in particular) causing program crash at start-up,
423if static instance of initialiser class is present in the second shared library.
424The FitsIOServer module should thus be explicitly initialised in the user
425program.
426\par
427In cases where the run time loader does not perform correctly the static
428object initialisation, the initialiser class for the modules used in the
429program must be instanciated in the beginning of your main program: \\
430{\tt TArrayInitiator , HiStatsInitiator , SkyMapInitiator , FitsIOServer \ldots}
431%%%
432\subsection{SOPHYA persistence}
433\label{ppfdesc}
434\index{PPersist} \index{PInPersist} \index{POutPersist}
435\begin{figure}[hbt]
436\dclsa{PPersist}
437\dclsccc{PPFBinarIOStream}{PPFBinaryInputStream}{PInPersist}
438\dclscc{PPFBinaryOutputStream}{POutPersist}
439\caption{partial class diagram for classes handling persistence in Sophya}
440\end{figure}
441A simple persistence mechanism is defined in SOPHYA. Its main
442features are:
443\begin{itemize}
444\item[] Portable file format, containing the description of the data structures
445and object hierarchy. \\
446{\bf PPF} {\bf P}ortable {\bf P}ersistence file {\bf F}ormat.
447\index{PPF}
448\item[] Handling of read/write for multiply referenced objects.
449\item[] All write operations are carried using sequential access only. This
450holds also for read operations, unless positional tags are used.
451SOPHYA persistence services can thus be used to transfer objects
452through network links.
453\item[] The serialisation (reading/writing) for objects for a given class
454is implemented through a handler object. The handler class inherits
455from {\tt PPersist} class.
456\item[] A run time registration mechanism is used in conjunction with
457RTTI (Run Time Type Identification) for identifying handler classes
458when reading {\bf PInPersist} streams, or for associating handlers
459with data objects {\bf AnyDataObject} for write operations.
460\end{itemize}
461A complete description of SOPHYA persistence mechanism and guidelines
462for writing delegate classes for handling object persistence is beyond
463the scope of this document. The most useful methods for using Sophya
464persistence are listed below:
465\begin{itemize}
466\item[] {\tt POutPersist::PutObject(AnyDataObj \& o)} \\
467Writes the data object {\bf o} to the output stream.
468\item[] {\tt POutPersist::PutObject(AnyDataObj \& o, string tagname)} \\
469Writes the data object {\bf o} to the output stream, associated with an
470identification tag {\bf tagname}.
471\item[] {\tt PInPersist::GetObject(AnyDataObj \& o)} \\
472Reads the next object in stream into {\bf o}. An exception is
473generated for incompatible object types.
474\item[] {\tt PInPersist::GetObject(AnyDataObj \& o, string tagname)} \\
475Reads the object associated with the tag {\bf tagname} into {\bf o}.
476An exception is generated for incompatible object types.
477\end{itemize}
478The operators {\tt operator << (POutPersist ...) } and
479{\tt operator >> (PInPersist ...) } are often overloaded
480to perform {\tt PutObject()} and {\tt GetObject()} operations.
481the {\bf PPFNameTag} (ppfnametag.h) class can be used in conjunction with
482{\tt << >> } operators to write objects with a name tag or to retrieve
483an object identified with a name tag. The example below shows the
484usage of these operators:
485\begin{verbatim}
486// Creating and filling a histogram
487Histo hw(0.,10.,100);
488...
489// Writing histogram to a PPF stream
490POutPersist os("hw.ppf");
491os << PPFNameTag("myhisto") << hw;
492
493// Reading a histogram from a PPF stream
494PInPersist is("hr.ppf");
495is >> PPFNameTag("myhisto") >> hr;
496\end{verbatim}
497
498The {\bf scanppf} program can be used to list the content of a PPF file.
499
500\subsection{\tcls{NDataBlock}}
501\index{\tcls{NDataBlock}}
502\begin{figure}[hbt]
503\dclsbb{AnyDataObj}{\tcls{NDataBlock}}
504\dclsbb{PPersist}{\tcls{FIO\_NDataBlock}}
505\end{figure}
506The {\bf \tcls{NDataBlock}} is designed to handle reference counting
507and sharing of memory blocs (contiguous arrays) for numerical data
508types. Initialisation, resizing, basic arithmetic operations, as
509well as persistence handling services are provided.
510The persistence handler class ({\tt \tcls{FIO\_NDataBlock}}) insures
511that a single copy of data is written for multiply referenced objects,
512and the data is shared among objects when reading.
513\par
514The example below shows writing of NDataBlock objects through the
515use of overloaded operator $ << $ :
516\begin{verbatim}
517#include "fiondblock.h"
518// ...
519POutPersist pos("aa.ppf");
520NDataBlock<r_4> rdb(40);
521rdb = 567.89;
522pos << rdb;
523// We can also use the PutObject method
524NDataBlock<int_4> idb(20);
525idb = 123;
526pos.PutObject(idb);
527\end{verbatim}
528The following sample programs show the reading of the created PPF file :
529\begin{verbatim}
530PInPersist pis("aa.ppf");
531NDataBlock<r_4> rdb;
532pis >> rdb;
533cout << rdb;
534NDataBlock<int_4> idb;
535cout << idb;
536\end{verbatim}
537
538\subsection{DVList, MuTyV and TimeStamp classes}
539\index{DVList} \index{MuTyV} \index{TimeStamp}
540\begin{figure}[hbt]
541\dclsa{MuTyV}
542\dclsbb{AnyDataObj}{DVList}
543\dclsbb{PPersist}{\tclsc{ObjFileIO}{DVList}}
544\end{figure}
545The {\bf DVList} class objects can be used to create and manage list
546of values, associated with names. A list of pairs of (MuTyV, name(string))
547is maintained by DVList objects. {\bf MuTyV} is a simple class
548capable of holding string, integer, float or complex values,
549providing easy conversion methods between these objects.
550{\bf MuTyV} objects can also hold {\bf TimeStamp } objects.
551\begin{verbatim}
552// Using MuTyV objects
553MuTyV s("hello"); // string type value
554MuTyV x;
555x = "3.14159626"; // string type value, ASCII representation for Pi
556double d = x; // x converted to double = 3.141596
557x = 314; // x contains the integer value = 314
558// Using DVList
559DVList dvl;
560dvl("Pi") = 3.14159626; // float value, named Pi
561dvl("Log2") = 0.30102999; // float value, named Log2
562dvl("FileName") = "myfile.fits"; // string value, named myfile.fits
563// Printing DVList object
564cout << dvl;
565\end{verbatim}
566
567\begin{figure}[hbt]
568\dclsbb{AnyDataObj}{TimeStamp}
569\end{figure}
570%
571The {\bf TimeStamp} class represent date and time and provides
572many standard operations, such as Initialisation from strings,
573conversion to strings and time interval computations. \\
574Usage example:
575\begin{verbatim}
576// Create a object with the current date and time and prints it to cout
577TimeStamp ts;
578cout << ts << endl;
579// Create an object with a specified date and time
580TimeStamp ts2("01/01/1905","00:00:00");
581// Get the number of days since 0 Jan 1901
582cout << ts2.ToDays() << endl;
583
584// Combined use of TimeStamp and MuTyV
585string s;
586TimeStamp ts; // Current date/time
587MuTyV mvt = ts;
588s = mvt; // s contains the current date in string format
589cout << s << endl;
590\end{verbatim}
591
592\subsection{\tcls{SegDataBlock} , \tcls{SwSegDataBlock}}
593\index{\tcls{SegDataBlock}} \index{\tcls{SwSegDataBlock}}
594%%
595\begin{figure}[hbt]
596\dclsccc{AnyDataObj}{\tcls{SegDBInterface}}{ \tcls{SegDataBlock} }
597\dclscc{\tcls{SegDBInterface}}{ \tcls{SwSegDataBlock} }
598\end{figure}
599\begin{itemize}
600\item[] \tcls{SegDataBlock} handles arrays of object of
601type {\bf T} with reference sharing in memory. The array can be extended
602(increase in array size) with fixed segment size. It implements the interface
603defined by \tcls{SegDBInterface}.
604\item[] \tcls{SwSegDataBlock} Implements the same \tcls{SegDBInterface}
605using a data swapper object. Data swappers implement the interface defined in
606(\tcls{DataSwapperInterface} class. \tcls{SwSegDataBlock} can
607thus be used to handle arrays with very large number of objects.
608These classes handles reference sharing.
609\end{itemize}
610
611\newpage
612\section{Module TArray}
613\index{\tcls{TArray}}
614{\bf TArray} module contains template classes for handling standard
615operations on numerical arrays. Using the class {\tt \tcls{TArray} },
616it is possible to create and manipulate up to 5-dimension numerical
617arrays {\tt (int, float, double, complex, \ldots)}. The include
618file {\tt array.h} declares all the classes and definitions
619in module TArray. {\bf Array} is a typedef for arrays
620with double precision floating value elements. \\
621{\tt typedef TArray$<$r\_8$>$ Array ; }
622
623\begin{figure}[hbt]
624\dclsccc{AnyDataObj}{BaseArray}{\tcls{TArray}}
625\dclsbb{PPersist}{\tcls{FIO\_TArray}}
626\end{figure}
627
628The development of this module started around 1999-2000,
629after evaluation of a number of publicly available
630C++ array hadling packages, including TNT, Lapack++, Blitz++,
631as well as commercial packages from RogueWave (math.h++ \ldots).
632Most of these packages provide interesting functionalities, however,
633not any one package seemed to fulfill most of our requirements.
634\begin{itemize}
635\item Capability to handle {\bf large - multidimensional - dense}
636arrays, for numerical data types. Although we have used templates, for
637data type specialisation, the actual code, apart inline functions is
638not in header files. Instead, we use explicit instanciation, and the
639compiled code for the various numerical types of arrays is the
640library .
641\item The shape and size of the arrays can be defined and changed
642at run time. The classes ensure the memory management of the
643created objets, with reference sharing for the array data.
644The default behaviour of the copy constructor is to share the data,
645avoiding expensive memory copies.
646\item The package provides transparent management of sub-arrays
647and slices, in an intuitive way, somehow similar to what is
648available in Mathlab or Scilab.
649\item The memory organisation for arrays, specially matrices
650(row-major or column major) can be
651controled. This provide compatibility when using existing C or
652Fortran coded numerical libraries.
653\item The classes provide efficient methods to perform basic arithmetic
654and mathematical operations on arrays. In addition, operator overload
655provides intuitive programming for element acces and most basic
656arithmetic operations.
657\item Conversion can be performed between arrays with different
658data types. Copy and arithmetic operations can be done transparently
659between arrays with different memory organisation patterns.
660\item This module does not provide more complex operations
661such as FFT or linear algebra. Additional libraries are used, with interface
662classes for these operations.
663\item ASCII formatted I/O, for printing and read/write operations to/from text files.
664\item Efficient binary I/O for object persistence (PPF format), or import/export
665to other data formats, such as FITS are provided by helper or handler classes.
666\end{itemize}
667
668\subsection{Using arrays}
669\index{Sequence} \index{RandomSequence} \index{RegularSequence}
670\index{EnumeratedSequence}
671The example below shows basic usage of arrays, creation, initialisation
672and arithmetic operations. Different kind of {\bf Sequence} objects
673can be used for initialising arrays.
674
675\begin{figure}[hbt]
676\dclsbb{Sequence}{RandomSequence}
677\dclsb{RegularSequence}
678\dclsb{EnumeratedSequence}
679\end{figure}
680
681The example below shows basic usage of arrays:
682\index{\tcls{TArray}}
683\begin{verbatim}
684// Creating and initialising a 1-D array of integers
685TArray<int> ia(5);
686EnumeratedSequence es;
687es = 24, 35, 46, 57, 68;
688ia = es;
689cout << "Array<int> ia = " << ia;
690// 2-D array of floats
691TArray<r_4> b(6,4), c(6,4);
692// Initializing b with a constant
693b = 2.71828;
694// Filling c with random numbers
695c = RandomSequence();
696// Arithmetic operations
697TArray<r_4> d = b+0.3f*c;
698cout << "Array<float> d = " << d;
699\end{verbatim}
700
701The copy constructor shares the array data, while the assignment operator
702copies the array elements, as illustrated in the following example:
703\begin{verbatim}
704TArray<int> a1(4,3);
705a1 = RegularSequence(0,2);
706// Array a2 and a1 shares their data
707TArray<int> a2(a1);
708// a3 and a1 have the same size and identical elements
709TArray<int> a3;
710a3 = a1;
711// Changing one of the a2 elements
712a2(1,1,0) = 555;
713// a1(1,1) is also changed to 555, but not a3(1,1)
714cout << "Array<int> a1 = " << a1;
715cout << "Array<int> a3 = " << a3;
716\end{verbatim}
717
718\subsection{Arithmetic operations}
719The four usual arithmetic operators ({\bf + \, - \, * \, / }) are defined
720to perform constant addition, subtraction, multiplication and division.
721The three operators ({\bf + \, - \, / }) between two arrays of the same type
722are defined to perform element by element addition, subtraction
723and division. In order to avoid confusion with matrix multiplication,
724element by element multiplication is defined by overloading the
725operator {\bf \, \&\& \, }, as shown in the example below:
726\begin{verbatim}
727TArray<int_4> a(4,3), b(4,3), c , d, e;
728a = RegularSequence(1.,1.);
729b = RegularSequence(10.,10.);
730cout << a << b ;
731c = a && b;
732d = c / a;
733e = (c / b) - a;
734cout << c << d << e;
735\end{verbatim}
736
737\subsection{Matrices and vectors}
738\index{\tcls{TMatrix}} \index{\tcls{TVector}}
739\begin{figure}[hbt]
740\dclsccc{\tcls{TArray}}{\tcls{TMatrix}}{\tcls{TVector}}
741\end{figure}
742Vectors and matrices are 2 dimensional arrays. The array size
743along one dimension is equal 1 for vectors. Column vectors
744have {\tt NCols() = 1} and row vectors have {\tt NRows() = 1}.
745Mathematical expressions involving matrices and vectors can easily
746be translated into C++ code using {\tt TMatrix} and
747{\tt TVector} objects. {\bf Matrix} and {\bf Vector} are
748typedefs for double precision float matrices and vectors.
749The operator {\bf *} beteween matrices is redefined to
750perform matrix multiplication. One can then write: \\
751\begin{verbatim}
752 // We create a row vector
753 Vector v(1000, BaseArray::RowVector);
754 // Initialize values with a random sequence
755 v = RandomSequence();
756 // Compute the vector length (norm)
757 double norm = (v*v.Transpose()).toScalar();
758 cout << "Norm(v) = " << norm << endl;
759\end{verbatim}
760
761This module contains basic array and matrix operations
762such as the Gauss matrix inversion algorithm
763which can be used to solve linear systems, as illustrated by the
764example below:
765\begin{verbatim}
766#include "sopemtx.h"
767// ...
768// Creation of a random 5x5 matrix
769Matrix A(5,5);
770A = RandomSequence(RandomSequence::Flat);
771Vector X0(5);
772X0 = RandomSequence(RandomSequence::Gaussian);
773// Computing B = A*X0
774Vector B = A*X0;
775// Solving the system A*X = B
776Vector X;
777LinSolve(A, B, X);
778// Checking the result
779Vector diff = X-X0;
780cout << "X-X0= " << diff ;
781double min,max;
782diff.MinMax(min, max);
783cout << " Min(X-X0) = " << min << " Max(X-X0) = " << max << endl;
784\end{verbatim}
785
786{\bf Warning: } The operations defined in {\tt sopemtx.h}, such as
787matrix inversion and linear system solver use a basic Gauss pivot
788algorithm which are not adapted for large matrices ($>\sim 100x100$).
789The services provided in other modules, such as {\bf LinAlg} should
790be preferred in such cases.
791
792\subsection{Working with sub-arrays and Ranges}
793\index{Range}
794A powerful mechanism is included in array classes for working with
795sub-arrays. The class {\bf Range} can be used to specify range of array
796indexes in any of the array dimensions. Any regularly spaced index
797range can be specified, using the {\tt start} and {\tt end} index
798and an optional step (or stride). It is also possible to specify
799the {\tt start} index and the number of elements.
800\begin{itemize}
801\item {\bf Range::all()} {\tt = Range(Range::firstIndex(), Range::lastIndex())} \\
802return a Range objects representing all valid indexes along the
803corresponding axe.
804\item {\bf Range::first()} {\tt = Range(Range::firstIndex())} \\
805return a Range object representing the first valid index
806\item {\bf Range::last()} {\tt = Range(Range::lastIndex())}
807return a Range object representing the last valid index
808\item {\bf Range(idx)} represents a single index ({\bf = idx})
809\item {\bf Range(first, last)} represents the range of indices
810{\bf first} $\leq$ index $\leq$ {\bf last}.
811The static method {\tt Range::lastIndex()} can be used
812to specify the last valid index.
813\item {\bf Range(first, last, step)} represents the range of index
814which is equivalent to \\ {\tt for(index=first; index <= last; index += step) }
815\item { \bf Range (first, last, size, step) } the general form can be used
816to specify an index range, using the number of elements.
817It is possible to specify a range of index, ending with the last valid index.
818For example \\
819\hspace*{5mm}
820{\tt Range(Range::lastIndex(), Range::lastIndex(), 3, 2) } \\
821defines the index range: \hspace*{5mm} last-4, last-2, last.
822
823\begin{center}
824\begin{tabular}{ll}
825\hline \\
826\multicolumn{2}{c}{ {\bf Range} {\tt (start, end, size, step) } } \\[2mm]
827\hline \\
828{\bf Range} {\tt r(7); } & index range: \hspace{2mm} 7 \\
829{\bf Range} {\tt r(3,6); } & index range: \hspace{2mm} 3,4,5,6 \\
830{\bf Range} {\tt r(3,7,2); } & index range: \hspace{2mm} 3,5,7 \\
831{\bf Range} {\tt r(7,0,3,1); } & index range: \hspace{2mm} 7,8,9 \\
832{\bf Range} {\tt r(10,0,5,2); } & index range: \hspace{2mm} 10,12,14,16,18 \\[2mm]
833\hline
834\end{tabular}
835\end{center}
836\end{itemize}
837
838The method {\tt TArray<T>SubArray(Range ...)} can be used
839to extract subarrays and slices. The operator {\tt operator() (Range rx, Range ry ...)}
840is also overloaded for sub-array extraction.
841For matrices, {\tt TMatrix<T>::Row()} and {\tt TMatrix<T>::Column()}
842extract selected matrix rows and columns.
843
844The example illustrates the sub-array extraction using Range objects:
845\begin{verbatim}
846 // Creating and initialising a 2-D (6 x 4) array of integers
847 TArray<int> iaa(6, 4);
848 iaa = RegularSequence(1,2);
849 cout << "Array<int> iaa = \n" << iaa;
850 // We extract a sub-array - data is shared with iaa
851 TArray<int> iae = iaa(Range(1, Range::lastIndex(), 3) ,
852 Range::all(), Range::first() );
853 cout << "Array<int> iae=subarray(iaa) = \n" << iae;
854 // Changing iae elements changes corresponding iaa elements
855 iae = 0;
856 cout << "Array<int> iae=0 --> iaa = \n" << iaa;
857
858\end{verbatim}
859
860In the following example, a simple low-pass filter, on a one
861dimensional stream (Vector) has been written using sub-arrays:
862
863\begin{verbatim}
864// Input Vector containing a noisy periodic signal
865 Vector in(1024), out(1024);
866 in = RandomSequence(RandomSequence::Gaussian, 0., 1.);
867 for(int kk=0; kk<in.Size(); kk++)
868 in(kk) += 2*sin(kk*0.05);
869// Compute the output vector by a simple low pass filter
870 Vector out(1024);
871 int w = 2;
872 for(int k=w; k<in.Size()-w; k++)
873 out(k) = in(Range(k-w, k+w).Sum()/(2.*w+1.);
874\end{verbatim}
875
876\subsection{Input, Output}
877Arrays can easily be saved to, or restored from files in different formats.
878SOPHYA library can handle array I/O to ASCII formatted files, to PPF streams,
879as well as to files in FITS format.
880FITS format input/output is provided through the classes in
881{\bf FitsIOServer} module. Only arrays with data types
882supported by the FITS standard can be handled during
883I/O operations to and from FITS streams (See the FitsIOServer section
884for additional details).
885
886\subsubsection{PPF streams}
887
888SOPHYA persistence (PPF streams) handles reference sharing, and multiply
889referenced objects are only written once. A hierarchy of arrays and sub-arrays
890written to a PPF stream is thus completely recovered, when the stream is read.
891The following example illustrates this point:
892\begin{verbatim}
893{
894// Saving an array with a sub-array into a POutPersist file
895Matrix A(3,4);
896A = RegularSequence(10,5);
897// Create a sub-array of A
898Matrix AS = A(Range(1,2), Range(2,3));
899// Save the two arrays to a PPF stream
900POutPersist pos("aas.ppf");
901pos << A << AS;
902}
903{
904// Reading arrays from the previously created PPF file aas.ppf
905PInPersist pis("aas.ppf");
906Matrix B,BS;
907pis >> B >> BS;
908// BS is a sub-array of B, modifying BS changes also B
909BS(1,1) = 98765.;
910cout << " B , BS after BS(1,1) = 98765. "
911 << B << BS << endl;
912}
913\end{verbatim}
914The execution of this sample code creates the file {\tt aas.ppf} and
915its output is reproduced here. Notice that the array hierarchy is
916recovered. BS is a sub-array of B, and modifying BS changes also
917the corresponding element in B.
918\begin{verbatim}
919 B , BS after BS(1,1) = 98765.
920
921--- TMatrix<double>(NRows=3, NCols=4) ND=2 SizeX*Y*...= 4x3 ---
92210 15 20 25
92330 35 40 45
92450 55 60 98765
925
926--- TMatrix<double>(NRows=2, NCols=2) ND=2 SizeX*Y*...= 2x2 ---
92740 45
92860 98765
929\end{verbatim}
930
931\centerline{\bf Warning: }
932
933There is a drawback in this behaviour: only a single
934copy of an array is written to a file, even if the array is modified,
935without being resized and written to a PPF stream.
936\begin{verbatim}
937{
938POutPersist pos("mca.ppf");
939TArray<int_4> ia(5,3);
940ia = 8;
941pos << ia;
942ia = 16;
943pos << ia;
944ia = 32;
945pos << ia;
946}
947\end{verbatim}
948
949Only a single copy of the data is effectively written to the output
950PPF file, corresponding to the value 8 for array elements. When we
951read the three array from the file mca.ppf, the same array elements
952are obtained three times (all elements equal to 8):
953\begin{verbatim}
954{
955PInPersist pis("mca.ppf");
956TArray<int_4> ib;
957pis >> ib;
958cout << " First array read from mca.ppf : " << ib;
959pis >> ib;
960cout << " Second array read from mca.ppf : " << ib;
961pis >> ib;
962cout << " Third array read from mca.ppf : " << ib;
963}
964\end{verbatim}
965
966\subsubsection{ASCII streams}
967
968The {\bf WriteASCII} method can be used to dump an array to an ASCII
969formatted file, while the {\bf ReadASCII} method can be used to decode
970ASCII formatted files. Space or tabs are the possible separators.
971Complex numbers should be specified as a pair of comma separated
972real and imaginary parts, enclosed in parenthesis.
973
974\begin{verbatim}
975{
976// Creating array A and writing it to an ASCII file (aaa.txt)
977Array A(4,6);
978A = RegularSequence(0.5, 0.2);
979ofstream ofs("aaa.txt");
980A.WriteASCII(ofs);
981}
982{
983// Decoding the ASCII file aaa.txt
984ifstream ifs("aaa.txt");
985Array B;
986sa_size_t nr, nc;
987B.ReadASCII(ifs,nr,nc);
988cout << " Array B; B.ReadASCII() from file " << endl;
989cout << B ;
990}
991\end{verbatim}
992
993
994\subsection{Complex arrays}
995The {\bf TArray} module provides few functions for manipulating
996arrays of complex numbers (single and double precision).
997These functions are declared in {\tt matharr.h}.
998\begin{itemize}
999\item[\bul] Creating a complex array through the specification of the
1000real and imaginary parts.
1001\item[\bul] Functions returning arrays corresponding to real and imaginary
1002parts of a complex array: {\tt real(za) , imag(za) }
1003({\bf Warning:} Note that the present implementation does not provide
1004shared memory access to real and imaginary parts.)
1005\item[\bul] Functions returning arrays corresponding to the module,
1006phase, and module squared of a complex array:
1007 {\tt phase(za) , module(za) , module2(za) }
1008\end{itemize}
1009
1010\begin{verbatim}
1011 TVector<r_4> p_real(10, BaseArray::RowVector);
1012 TVector<r_4> p_imag(10, BaseArray::RowVector);
1013 p_real = RegularSequence(0., 0.5);
1014 p_imag = RegularSequence(0., 0.25);
1015 TVector< complex<r_4> > zvec = ComplexArray(p_real, p_imag);
1016 cout << " :: zvec= " << zvec;
1017 cout << " :: real(zvec) = " << real(zvec) ;
1018 cout << " :::: imag(zvec) = " << imag(zvec) ;
1019 cout << " :::: module2(zvec) = " << module2(zvec) ;
1020 cout << " :::: module(zvec) = " << module(zvec) ;
1021 cout << " :::: phase(zvec) = " << phase(zvec) ;
1022\end{verbatim}
1023
1024The decoding of complex numbers from an ASCII formatted stream
1025is illustrated by the next example. As mentionned already,
1026complex numbers should be specified as a pair of comma separated
1027real and imaginary parts, enclosed in parenthesis.
1028
1029\begin{verbatim}
1030csh> cat zzz.txt
1031(1.,-1) (2., 2.5) -3. 12.
1032-24. (-6.,7.) 14.2 (8.,64.)
1033
1034// Decoding of complex numbers from an ASCII file
1035// Notice that the << operator can be used instead of ReadASCII
1036TArray< complex<r_4> > Z;
1037ifstream ifs("zzz.txt");
1038ifs >> Z;
1039cout << " TArray< complex<r_4> > Z from file zzz.txt " << Z ;
1040\end{verbatim}
1041
1042
1043\subsection{Memory organisation}
1044{\tt \tcls{TArray} } can handle numerical arrays with various memory
1045organisation, as long as the spacing (steps) along each axis is
1046regular. The five axis are labeled X,Y,Z,T,U. The examples below
1047illustrates the memory location for a 2-dimensional, $N_x=4 \times N_y=3$.
1048The first index is along the X axis and the second index along the Y axis.
1049\begin{verbatim}
1050 | (0,0) (0,1) (0,2) (0,3) |
1051 | (1,0) (1,1) (1,2) (1,3) |
1052 | (2,0) (2,1) (2,2) (2,3) |
1053\end{verbatim}
1054In the first case, the array is completely packed
1055($Step_X=1, Step_Y=N_X=4$), with zero offset,
1056while in the second case, $Step_X=2, Step_Y=10, Offset=10$:
1057\begin{verbatim}
1058 | 0 1 2 3 | | 10 12 14 16 |
1059Ex1 | 4 5 6 7 | Ex2 | 20 22 24 26 |
1060 | 8 9 10 11 | | 30 32 34 36 |
1061\end{verbatim}
1062
1063For matrices and vectors, an optional argument ({\tt MemoryMapping})
1064can be used to select the memory mapping, where two basic schemes
1065are available: \\
1066{\tt CMemoryMapping} and {\tt FortranMemoryMapping}. \\
1067In the case where {\tt CMemoryMapping} is used, a given matrix line
1068is packed in memory, while the columns are packed when
1069{\tt FortranMemoryMapping} is used. The first index when addressing
1070the matrix elements (line number index) runs along
1071the Y-axis if {\tt CMemoryMapping} is used, and along the X-axis
1072in the case of {\tt FortranMemoryMapping}.
1073Arithmetic operations between matrices
1074with different memory organisation is allowed as long as
1075the two matrices have the same sizes (Number of rows and columns).
1076The following code example and the corresponding output illustrates
1077these two memory mappings. The {\tt \tcls{TMatrix}::TransposeSelf() }
1078method changes effectively the matrix memory mapping, which is also
1079the case of {\tt \tcls{TMatrix}::Transpose() } method without argument.
1080
1081\begin{verbatim}
1082TArray<r_4> X(4,2);
1083X = RegularSequence(1,1);
1084cout << "Array X= " << X << endl;
1085TMatrix<r_4> X_C(X, true, BaseArray::CMemoryMapping);
1086cout << "Matrix X_C (CMemoryMapping) = " << X_C << endl;
1087TMatrix<r_4> X_F(X, true, BaseArray::FortranMemoryMapping);
1088cout << "Matrix X_F (FortranMemoryMapping) = " << X_F << endl;
1089\end{verbatim}
1090This code would produce the following output (X\_F = Transpose(X\_C)) :
1091\begin{verbatim}
1092Array X=
1093--- TArray<f> ND=2 SizeX*Y*...= 4x2 ---
10941, 2, 3, 4
10955, 6, 7, 8
1096
1097Matrix X_C (CMemoryMapping) =
1098--- TMatrix<f>(NRows=2, NCols=4) ND=2 SizeX*Y*...= 4x2 ---
10991, 2, 3, 4
11005, 6, 7, 8
1101
1102Matrix X_F (FortranMemoryMapping) =
1103--- TMatrix<f>(NRows=4, NCols=2) ND=2 SizeX*Y*...= 4x2 ---
11041, 5
11052, 6
11063, 7
11074, 8
1108\end{verbatim}
1109
1110\newpage
1111
1112\section{Module HiStats}
1113\begin{figure}[hbt]
1114\dclsbb{AnyDataObj}{Histo}
1115\dclscc{Histo}{HProf}
1116\dclsbb{AnyDataObj}{Histo2D}
1117\dclsbb{AnyDataObj}{HistoErr}
1118\dclsbb{AnyDataObj}{Histo2DErr}
1119\caption{partial class diagram for histograms and ntuples}
1120\end{figure}
1121
1122{\bf HiStats} contains classes for creating, filling, printing and
1123doing various operations on one or two dimensional histograms
1124{\tt Histo} and {\tt Histo2D} as well as profile histograms {\tt HProf}. \\
1125This module also contains {\tt NTuple} and {\tt DataTable} which are
1126more or less the same as the binary or ascii FITS tables.
1127
1128\subsection{Histograms}
1129\subsubsection{1D Histograms}
1130\index{Histo}
1131For 1D histograms, various numerical methods are provided such as
1132computing means and sigmas, finding maxima, fitting, rebinning,
1133integrating \dots \\
1134The example below shows creating and filling a one dimensional histogram
1135of 100 bins from $-5.$ to $+5.$ to create a Gaussian normal distribution
1136with errors~:
1137\begin{verbatim}
1138#include "histos.h"
1139// ...
1140Histo H(-0.5,0.5,100);
1141H.Errors();
1142for(int i=0;i<25000;i++) {
1143 double x = NorRand();
1144 H.Add(x);
1145}
1146H.Print(80);
1147\end{verbatim}
1148
1149\subsubsection{2D Histograms}
1150\index{Histo2D}
1151Much of these operations are also valid for 2D histograms. 1D projection
1152or slices can be set~:
1153\begin{verbatim}
1154#include "histos2.h"
1155// ...
1156Histo2D H2(-1.,1.,100,0.,60.,50);
1157H2.SetProjX(); // create the 1D histo for X projection
1158H2.SetBandX(25.,35.); // create 1D histo projection for 25.<y<35.
1159H2.SetBandX(35.,45.); // create 1D histo projection for 35.<y<45.
1160H2.SetBandX(40.,55.); // create 1D histo projection for 40.<y<55.
1161//... fill H2 with what ever you want
1162H2.Print();
1163Histo *hx = H2.HProjX();
1164 hx->Print(80);
1165Histo *hbx2 = HBandX(1); // Get the second X band (35.<y<45.)
1166 hbx2->Print(80);
1167\end{verbatim}
1168
1169\subsubsection{Profile Histograms}
1170\index{HProf}
1171Profiles histograms {\bf HProf} contains the mean and the
1172sigma of the distribution
1173of the values filled in each bin. The sigma can be changed to
1174the error on the mean. When filled, the profile histogram looks
1175like a 1D histogram and much of the operations that can be done on 1D histo
1176may be applied onto profile histograms.
1177
1178\subsubsection{Histograms HistoErr and Histo2DErr}
1179\index{HistoErr}
1180The {\bf HistoErr} are basic histograms where the number of entries for each bin is kept.
1181Methods to compute of the mean and the variance in each bin are provided.
1182The {\bf Histo2DErr} is the same for $2$ dimensions.
1183
1184\subsection{Data tables (tuples)}
1185\begin{figure}[hbt]
1186\dclsbb{AnyDataObj}{NTuple}
1187\dclsccc{AnyDataObj}{BaseDataTable}{DataTable}
1188\dclscc{BaseDataTable}{SwPPFDataTable}
1189\end{figure}
1190
1191\subsubsection{NTuple}
1192\index{NTuple}
1193{\bf NTuple} are memory resident tables of 32 or 64 bits floating values
1194(float/double).They are arranged in columns. Each line is often called an event.
1195These objects are frequently used to analyze data.
1196The piapp graphicals tools can plot a column against an other one
1197with respect to various selection cuts. \\
1198Here is an example of creation and filling~:
1199\begin{verbatim}
1200#include "ntuple.h"
1201#include "srandgen.h"
1202// ...
1203char* nament[4] = {"i","x","y","ey"};
1204r_4 xnt[4];
1205NTuple NT(4,nament);
1206for(i=0;i<5000;i++) {
1207 xnt[0] = i+1;
1208 xnt[1] = 5.*drandpm1(); // a random value between -5 and +5
1209 xnt[2] = 100.*exp(-0.5*xnt[1]*xnt[1]) + 1.;
1210 xnt[3] = sqrt(xnt[2]);
1211 xnt[2] += xnt[3] * NorRand(); // add a random gaussian error
1212 NT.Fill(xnt);
1213}
1214\end{verbatim}
1215
1216{\bf XNTuple} provide additional functionalities, compared to NTuple. However,
1217this class is deprecated and superseded by classes inheriting from BaseDataTable.
1218It is only kept for backward compatibility and should not be used anymore.
1219Use DataTable and SwPPFDataTable instead.
1220Object of type XNTuple handle various types
1221of column values (double,float,int,string,...) and can handle
1222very large data sets, through swap space on disk.
1223
1224\subsubsection{DataTables}
1225\label{datatables}
1226\index{DataTable}
1227The class {\bf DataTable} extends significantly the functionalities provided by
1228NTuple. DataTable is a memory resident implementation of the interface
1229{\bf BaseDataTable } which organizes the data as a 2-D table. User can define
1230the name and data type of each column. Data is added to the table as rows.
1231The table is extended as necessary when adding rows.
1232The sample code below shows an example of DataTable usage :
1233\begin{verbatim}
1234 #include "datatable.h"
1235 // ...
1236 {
1237 DataTable dt(64);
1238 dt.AddFloatColumn("X0_f");
1239 dt.AddFloatColumn("X1_f");
1240 dt.AddDoubleColumn("X0X0pX1X1_d");
1241 double x[5];
1242 for(int i=0; i<63; i++) {
1243 x[0] = (i/9)-4.; x[1] = (i/9)-3.; x[2] = x[0]*x[0]+x[1]*x[1];
1244 dt.AddLine(x);
1245 }
1246 // Printing table info
1247 cout << dt ;
1248 // Saving object into a PPF file
1249 POutPersist po("dtable.ppf");
1250 po << dt ;
1251 }
1252\end{verbatim}
1253
1254
1255\index{SwPPFDataTable}
1256The class {\bf SwPPFDataTable} implements the BaseDataTable interface
1257using segmented data blocks with swap on PPF streams. Very large data sets
1258can be created and manipulated through this class. A similar class
1259SwFitsDataTable (\ref{SwFitsDataTable}), using
1260FITS files as swap space is also provided in the FitsIOServer module.
1261
1262\index{DataTableRow}
1263The class {\bf DataTableRow } is an auxiliary class which simplifies the manipulation
1264of BaseDataTable object rows.
1265The example below show how to create and filling a table, using a PPF stream as
1266swap space. In addition, we have used a {\tt DataTableRow} to prepare data
1267for each table line.
1268\begin{verbatim}
1269 #include "swppfdtable.h"
1270 // ...
1271 {
1272 // ---------- Create an output PPF stream (file)
1273 POutPersist po("swdtable.ppf");
1274 // ------------------
1275 // Create a table with 3 columns, using the above stream as swap space
1276 SwPPFDataTable dtrow(po, 64);
1277 dtrow.AddStringColumn("sline");
1278 dtrow.AddIntegerColumn("line");
1279 dtrow.AddDateTimeColumn("datime");
1280 //
1281 TimeStamp ts, ts2; // Initialize current date and time
1282 string sline;
1283 //---- Create a table row with the required structure
1284 DataTableRow row = dtrow.EmptyRow();
1285 // ----- Fill the table
1286 for(int k = 0; k<2500; k++) {
1287 sline = "L-";
1288 sline += (string)MuTyV(k);
1289 row["sline"] = sline;
1290 row[1] = k;
1291 ts2.Set(ts.ToDays()+(double)k);
1292 row["datime"] = ts2;
1293 dtrow.AddRow(row);
1294 }
1295 //------ Write the table itself to the stream, before closing the file
1296 po << PPFNameTag("SwTable") << dtrow;
1297 }
1298\end{verbatim}
1299%%
1300The previously created table can easily be read in, as shown below:
1301%%
1302\begin{verbatim}
1303 #include "swppfdtable.h"
1304 // ...
1305 {
1306 // ------ Create the input PPF stream (file)
1307 PInPersist pin("swdtable.ppf");
1308 // ------ Read in the SwPPFDataTable object
1309 SwPPFDataTable dtr;
1310 pin >> PPFNameTag("SwTable") >> dtr;
1311 // ---- Create a table row with the required structure
1312 DataTableRow row = dtr.EmptyRow();
1313 // ---- Acces and print two of the table rows :
1314 cout << dtr.GetRow(6, row) << endl;
1315 cout << dtr.GetRow(17, row) << endl;
1316 }
1317\end{verbatim}
1318
1319\subsection{Writing, viewing \dots }
1320
1321All these objects have been design to be written to or read from a persistent file.
1322The following example shows how to write the previously created objects
1323into such a file~:
1324\begin{verbatim}
1325//-- Writing
1326{
1327char *fileout = "myfile.ppf";
1328string tag;
1329POutPersist outppf(fileout);
1330tag = "H"; outppf.PutObject(H,tag);
1331tag = "H2"; outppf.PutObject(H2,tag);
1332tag = "NT"; outppf.PutObject(NT,tag);
1333} // closing ``}'' destroy ``outppf'' and automatically close the file !
1334\end{verbatim}
1335
1336Sophya graphical tools (spiapp) can automatically display and operate
1337all these objects.
1338
1339\newpage
1340\section{Module NTools}
1341
1342This module provides elementary numerical tools for numerical integration,
1343fitting, sorting and ODE solving. FFTs are also provided (Mayer,FFTPack).
1344
1345\subsection{Fitting}
1346\index{Fitting} \index{Minimisation}
1347Fitting is done with two classes {\tt GeneralFit} and {\tt GeneralFitData}
1348and is based on the Levenberg-Marquardt method.
1349\index{GeneralFit} \index{GeneralFitData}
1350GeneralFitData is a class which provide a description of the data
1351to be fitted. GeneralFit is the fitter class. Parametrized functions
1352can be given as classes which inherit {\tt GeneralFunction}
1353or as simple C functions. Classes of pre-defined functions are provided
1354(see files fct1dfit.h and fct2dfit.h). The user interface is very close
1355from that of the CERN {\tt Minuit} fitter.
1356Number of objects (Histo, HProf \dots ) are interfaced with GeneralFit
1357and can be easily fitted. \\
1358Here is a very simple example for fitting the previously created NTuple
1359with a Gaussian~:
1360\begin{verbatim}
1361#include "fct1dfit.h"
1362// ...
1363
1364// Read from ppf file
1365NTuple nt;
1366{
1367PInPersist pis("myfile.ppf");
1368string tag = "NT"; pis.GetObject(nt,tag);
1369}
1370
1371// Fill GeneralData
1372GeneralData mGdata(nt.NEntry());
1373for(int i=0; i<nt.NEntry(); i++)
1374 mGdata.AddData1(xnt[1],xnt[2],xnt[3]); // Fill x, y and error on y
1375mGData.PrintStatus();
1376
1377// Function for fitting : y = f(x) + noise
1378Gauss1DPol mFunction; // gaussian + constant
1379
1380// Prepare for fit
1381GeneralFit mFit(&mFunction); // create a fitter for the choosen function
1382mFit.SetData(&mGData); // connect data to the fitter
1383
1384// Set and initialise the parameters (that's non-linear fitting!)
1385// (num par, name, guess start, step, [limits min and max])
1386mFit.SetParam(0,"high",90.,1..);
1387mFit.SetParam(1,"xcenter",0.05,0.01);
1388mFit.SetParam(2,"sigma",sig,0.05,0.01,10.);
1389 // Give limits to avoid division by zero
1390mFit.SetParam(3,"constant",0.,1.);
1391
1392// Fit and print result
1393int rcfit = mFit.Fit();
1394mFit.PrintFit();
1395if(rcfit>0) {)
1396 cout<<"Reduce_Chisquare = "<<mFit.GetChi2Red()
1397 <<" nstep="<<mFit.GetNStep()<<" rc="<<rcfit<<endl;
1398} else {
1399 cout<<"Fit_Error, rc = "<<rcfit<<" nstep="<<mFit.GetNStep()<<endl;
1400 mFit.PrintFitErr(rcfit);
1401}
1402
1403// Get the result for further use
1404TVector<r_8> ParResult = mFit.GetParm();
1405cout<<ParResult;
1406\end{verbatim}
1407
1408Much more usefull possibilities and detailed informations might be found
1409in the HTML pages of the Sophya manual.
1410
1411\subsection{Polynomial}
1412\index{Polynomial} \index{Poly} \index{Poly2}
1413Polynomials of 1 or 2 variables are supported ({\tt Poly} and {\tt Poly2}).
1414Various operations are supported~:
1415\begin{itemize}
1416\item elementary operations between polynomials $(+,-,*,/) $
1417\item setting or getting coefficients
1418\item computing the value of the polynomial for a given value
1419 of the variable(s),
1420\item derivating
1421\item computing roots (degre 1 or 2)
1422\item fitting the polynomial to vectors of data.
1423\end{itemize}
1424Here is an example of polynomial fitting~:
1425\begin{verbatim}
1426#include "poly.h"
1427// ...
1428Poly pol(2);
1429pol[0] = 100.; pol[1] = 0.; pol[2] = 0.01; // Setting coefficients
1430TVector<r_8> x(100);
1431TVector<r_8> y(100);
1432TVector<r_8> ey(100);
1433for(int i=0;i<100;i++) {
1434 x(i) = i;
1435 ey(i) = 10.;
1436 y(i) = pol((double) i) + ey(i)*NorRand();
1437 ey(i) *= ey(i)
1438}
1439
1440TVector<r_8> errcoef;
1441Poly polfit;
1442polfit.Fit(x,y,ey,2,errcoef);
1443
1444cout<<"Fit Result"<<polfit<<endl;
1445cout<<"Errors :"<<errcoef;
1446\end{verbatim}
1447
1448Similar operations can be done on polynomials with 2 variables.
1449
1450\subsection{Integration, Differential equations}
1451\index{Integration}
1452The NTools module provide also simple classes for numerical integration
1453of functions and differential equations.
1454\begin{figure}[hbt]
1455\dclsbb{Integrator}{GLInteg}
1456\dclsb{TrpzInteg}
1457\end{figure}
1458
1459\index{GLInteg} \index{TrpzInteg}
1460{\bf GLInteg} implements the integration through Gauss-Legendre method
1461and {\bf TrpzInteg} implements trapeze integration. For {\bf TrpzInteg},
1462number of steps specify the number of trapeze, and integration step,
1463their width.
1464The sample code below illustrates the use of TrpzInteg class:
1465\begin{verbatim}
1466#include "integ.h"
1467// ......................................................
1468// Function to be integrated
1469double myf(double x)
1470{
1471// Simple a x + b x^2 (a=2 b=3)
1472return (x*(2.+3.*x));
1473}
1474// ......................................................
1475
1476// Compute Integral(myf, 2., 5.) between xmin=2., xmax=5.
1477TrpzInteg trpz(myf, 2., 5.);
1478// We specify an integration step
1479trpz.DX(0.01);
1480// The integral can be computed as trpz.Value()
1481double myf_integral = trpz.Value();
1482// We could have used the cast operator :
1483cout << "Integral[myf, 2., 5.]= " << (double)trpz << endl;
1484// Limits can be specified through ValueBetween() method
1485cout << "Integral[myf, 0., 4.]= " << trpz.ValueBetween(0.,4.) << endl;
1486\end{verbatim}
1487
1488\subsection{Fourier transform (FFT)}
1489\index{FFT} \index{FFTPackServer}
1490An abstract interface for performing FFT operations is defined by the
1491{\bf FFTServerInterface} class. The {\bf FFTPackSever} class implements
1492one dimensional FFT, on real and complex data. FFTPackServer uses an
1493adapted and extended version of FFTPack (available from netlib),
1494translated in C, and can operate on single and double precision
1495({\tt float, double}) data.
1496
1497The sample code below illustrates the use of FFTServers:
1498\begin{verbatim}
1499#include "fftpserver.h"
1500 // ...
1501TVector<r_8> in(32);
1502TVector< complex<r_8> > out;
1503in = RandomSequence();
1504FFTPackServer ffts;
1505ffts.setNormalize(true); // To have normalized transforms
1506cout << " FFTServer info string= " << ffts.getInfo() << endl;
1507cout << "in= " << in << endl;
1508cout << " Calling ffts.FFTForward(in, out) : " << endl;
1509ffts.FFTForward(in, out);
1510cout << "out= " << out << endl;
1511\end{verbatim}
1512
1513% \newpage
1514\section{Module SUtils}
1515Some utility classes and C/C++ string manipulation functions are gathered
1516in {\bf SUtils} module.
1517\subsection{Using DataCards}
1518\index{DataCards}
1519The {\bf DataCards} class can be used to read parameters from a file.
1520Each line in the file starting with \@ defines a set of values
1521associated with a keyword. In the example below, we read the
1522parameters corresponding with the keyword {\tt SIZE} from the
1523file {\tt ex.d}. We suppose that {\tt ex.d} contains the line: \\
1524{\tt @SIZE 400 250} \\
1525\begin{verbatim}
1526#include "datacards.h"
1527// ...
1528// Initialising DataCards object dc from file ex.d
1529DataCards dc( "ex.d" );
1530// Getting the first and second parameters for keyword size
1531// We define a default value 100
1532int size_x = dc.IParam("SIZE", 0, 100);
1533int size_y = dc.IParam("SIZE", 1, 100);
1534cout << " size_x= " << size_x << " size_y= " << size_y << endl;
1535\end{verbatim}
1536
1537\section{Module SysTools}
1538The {\bf SysTools} module contains classes implementing interface to some
1539OS specific services, such as thread creation and management, dynamic loading and
1540resource usage information. For example, yhe class {\bf Periodic} provides the
1541necessary services needed to implement the execution of a periodic action.
1542
1543\subsection{Resource usage (CPU, memory \ldots) }
1544 The class {\bf ResourceUsage} \index{ResourceUsage}
1545and {\bf Timer} \index{Timer} provides access to information
1546about various resource usage (memory, CPU, ...).
1547The class {\bf Timer} \index{time (CPU, elapsed)} and c-functions
1548{\tt InitTim() , PrtTim(const char * Comm) } can be used to print
1549the amount of CPU and elapsed time in programs.
1550
1551The following sample code illustrates the use of {\bf ResourceUsage} :
1552\begin{verbatim}
1553 // How to check resource usage for a given part of the program
1554 ResourceUsage res;
1555 // --- Part of the program to be checked : Start
1556 // ...
1557 res.Update();
1558 cout << " Memory size increase (KB):" << res.getDeltaMemorySize() << endl;
1559 cout << " Resource usage info : \n" << res << endl;
1560\end{verbatim}
1561
1562\subsection{Thread management classes}
1563\index{ZThread} \index{ZMutex}
1564A basic interface to POSIX threads is also provided
1565through the \index{threads} {\bf ZThread}, {\bf ZMutex} and {\bf ZSync}
1566classes. The best way to use thread management classes is by inheriting
1567from {\bf ZThread} and redefining the {\tt run() } method.
1568It is also possible to use the default {\tt run() } implementation and associate
1569a function to perform the action, as in the example below :
1570\begin{verbatim}
1571 // The functions to perform computing
1572 void fun1(void *arg) { }
1573 void fun2(void *arg) { }
1574 // ...
1575 ZThread zt1;
1576 zt1.setAction(fun1, arg[1]);
1577 ZThread zt2;
1578 zt2.setAction(fun2, arg[1]);
1579 cout << " Starting threads ... " << endl;
1580 zt1.start();
1581 zt2.start();
1582 cout << " Waiting for threads to end ... " << endl;
1583 zt1.join();
1584 zt2.join();
1585\end{verbatim}
1586The classes {\bf ZMutex} \index{mutex} and {\bf ZSync} can be used
1587to perform synchronisation and signaling between threads.
1588
1589\subsection{Dynamic linker and C++ compiler classes}
1590\index{PDynLinkMgr}
1591The class {\bf PDynLinkMgr} can be used for managing shared libraries
1592at run time. The example below shows the run time linking of a function:\\
1593{\tt extern "C" { void myfunc(); } } \\
1594\begin{verbatim}
1595#include "pdlmgr.h"
1596// ...
1597string soname = "mylib.so";
1598string funcname = "myfunc";
1599PDynLinkMgr dyl(soname);
1600DlFunction f = dyl.GetFunction(funcname);
1601if (f != NULL) {
1602// Calling the function
1603 f();
1604}
1605\end{verbatim}
1606
1607\index{CxxCompilerLinker}
1608The {\bf CxxCompilerLinker} class provides the services to compile C++ code and building
1609shared libraries, using the same compiler and options which have
1610been used to create the SOPHYA shared library.
1611The sample program below illustrates using this class to build
1612the shared library (myfunc.so) from the source file myfunc.cc :
1613\begin{verbatim}
1614#include "cxxcmplnk.h"
1615// ...
1616string flnm = "myfunc.cc";
1617string oname, soname;
1618int rc;
1619CxxCompilerLinker cxx;
1620// The Compile method provides a default object file name
1621rc = cxx.Compile(flnm, oname);
1622if (rc != 0 ) { // Error when compiling ... }
1623// The BuildSO method provides a default shared object file name
1624rc = cxx.BuildSO(oname, soname);
1625if (rc != 0 ) { // Error when creating shared object ... }
1626\end{verbatim}
1627
1628\subsection{Command interpreter}
1629The class {\bf Commander} can be used in interactive programs to provide
1630c-shell like command interpreter and scripting capabilties.
1631Arithmetic expression evaluation is implemented through the {\bf CExpressionEvaluator}
1632and {\bf RPNExpressionEvaluator} classes.
1633The command language provides variable manipulation through the usual
1634{\tt \$varname} vector variable and arithmetic expression extensions, as well
1635as the control and test blocs.
1636\begin{verbatim}
1637#include "commander.h"
1638...
1639Commander cmd;
1640char* ss[3] = {"foreach f ( AA bbb CCCC ddddd )", "echo $f" , "end"};
1641for(int k=0; k<3; k++) {
1642 string line = ss[k];
1643 cmd.Interpret(line);
1644}
1645\end{verbatim}
1646
1647\newpage
1648\section{Module SkyMap}
1649\begin{figure}[hbt]
1650\dclsbb{AnyDataObj}{PixelMap}
1651\dclsccc{PixelMap}{Sphericalmap}{SphereHEALPix}
1652\dclsc{SphereThetaPhi}
1653\dclsc{SphereECP}
1654\dclsb{LocalMap}
1655\caption{partial class diagram for spherical map classes in Sophya}
1656\end{figure}
1657The {\bf SkyMap} module provides classes for creating, filling, reading pixelized spherical and 2D-maps. The types of values stored in pixels can be int, float, double , complex etc. according to the specialization of the template type.
1658\subsection {Spherical maps}
1659SkyMap module provides three kinds of complete ($4 \pi$) spherical maps according to the
1660pixelization scheme.
1661SphereHEALPix represents spheres pixelized following the HEALPIix algorithm (E. Hivon, K. Gorski)
1662\footnote{see the HEALPix Homepage: http://www.eso.org/kgorski/healpix/ }
1663, SphereThetaPhi represents spheres pixelized following an algorithm developed at LAL-ORSAY. The example below shows creating and filling of a SphereHEALPix with nside = 8 (it will be 12*8*8= 768 pixels) :
1664\index{\tcls{SphereHEALPix}}
1665
1666\begin{verbatim}
1667#include "spherehealpix.h"
1668// ...
1669SphereHEALPix<double> sph(8);
1670for (int k=0; k< sph.NbPixels(); k++) sph(k) = (double)(10*k);
1671\end{verbatim}
1672
1673SphereThetaPhi is used in a similar way with an argument representing number of slices in theta (Euler angle) for an hemisphere.
1674\index{\tcls{SphereThetaPhi}}
1675The SphereECP class correspond to the cylindrical projection and can be used for representing
1676partial or full spherical maps. However, it has the disadvantage of having non uniform pixel
1677size.
1678\index{\tcls{SphereECP}}
1679
1680\subsection {Local maps}
1681\index{\tcls{LocalMap}}
1682A local map is a 2 dimensional array, with i as column index and j as row index. The map is supposed to lie on a plan tangent to the celestial sphere in a point whose coordinates are (x0,y0) on the local map and (theta0, phi0) on the sphere. The range of the map is defined by two values of angles covered respectively by all the pixels in x direction and all the pixels in y direction (SetSize()). Default value of (x0, y0) is middle of the map, center of pixel(nx/2, ny/2).
1683
1684Internally, a map is first defined within this reference plane and tranported until the point (theta0, phi0) in such a way that both axes are kept parallel to meridian and parallel lines of the sphere. The user can define its own map with axes rotated with respect to reference axes (this rotation is characterized by angle between the local parallel line and the wanted x-axis-- method SetOrigin(...))
1685
1686The example below shows creating and filling of a LocalMap with 4 columns and 5 rows. The origin is set to default. The map covers a sphere portion defined by two angles of 30. degrees (methods \textit{SetOrigin()} and \textit{SetSize()} must be called in order to completely define the map).
1687\begin{verbatim}
1688#include "localmap.h"
1689//..............
1690 LocalMap<r_4> locmap(4,5);
1691 for (int k=0; k<locmap.NbPixels();k++) locmap(k)=10.*k;
1692 locmap.SetOrigin();
1693 locmap.SetSize(30.,30.);
1694\end{verbatim}
1695
1696\subsection{Writing, viewing \dots }
1697
1698All these objects have been design to be written to or read from a persistant file.
1699The following example shows how to write the previously created objects
1700into such a file~:
1701\begin{verbatim}
1702//-- Writing
1703
1704#include "fiospherehealpix.h"
1705//................
1706
1707char *fileout = "myfile.ppf";
1708POutPersist outppf(fileout);
1709FIO_SphereHEALPix<r_8> outsph(sph);
1710outsph.Write(outppf);
1711FIO_LocalMap<r_8> outloc(locmap);
1712outloc.Write(outppf);
1713// It is also possible to use the << operator
1714POutPersist os("sph.ppf");
1715os << outsph;
1716os << outloc;
1717\end{verbatim}
1718
1719Sophya graphical tools (spiapp) can automatically display and operate
1720all these objects.
1721
1722\newpage
1723\section{Samba and SkyT}
1724\subsection{Samba}
1725\index{Spherical Harmonics}
1726\index{SphericalTransformServer}
1727The module provides several classes for spherical harmonic analysis. The main class is \textit{SphericalTranformServer}. It contains methods for analysis and synthesis of spherical maps. The following example fills a vector of Cl's, generate a spherical map from these Cl's. This map is analysed back to Cl's...
1728\begin{verbatim}
1729#include "skymap.h"
1730#include "samba.h"
1731....................
1732
1733// Generate input spectra a + b* l + c * gaussienne(l, 50, 20)
1734int lmax = 92;
1735Vector clin(lmax);
1736for(int l=0; l<lmax; l++) {
1737 double xx = (l-50.)/10.;
1738 clin(l) = 1.e-2 -1.e-4*l + 0.1*exp(-xx*xx);
1739}
1740
1741// Compute map from spectra
1742SphericalTransformServer<r_8> ylmserver;
1743int m = 128; // HealPix pixelisation parameter
1744SphereHEALPix<r_8> map(m);
1745ylmserver.GenerateFromCl(map, m, clin, 0.);
1746// Compute power spectrum from map
1747Vector clout = ylmserver.DecomposeToCl(map, lmax, 0.);
1748\end{verbatim}
1749
1750\subsection{Module SkyT}
1751\index{RadSpectra} \index{SpectralResponse}
1752The SkyT module is composed of two types of classes:
1753\begin{itemize}
1754\item{} one which corresponds to an emission spectrum of
1755radiation, which is called RadSpectra
1756\item{} one which corresponds to the spectral response
1757of a given detector (i.e. corresponding to a detector
1758filter in a given frequency domain), which is called
1759SpectralResponse.
1760\end{itemize}
1761\begin{figure}[hbt]
1762\dclsbb{RadSpectra}{RadSpectraVec}
1763\dclsb{BlackBody}
1764\dclsccc{AnyDataObj}{SpectralResponse}{SpecRespVec}
1765\dclsc{GaussianFilter}
1766\caption{partial class for SkyT module}
1767\end{figure}
1768
1769\begin{verbatim}
1770#include "skyt.h"
1771// ....
1772// Compute the flux from a blackbody at 2.73 K through a square filter
1773BlackBody myBB(2.73);
1774// We define a square filter from 100 - 200 GHz
1775SquareFilter mySF(100,200);
1776// Compute the filtered integrated flux :
1777double flux = myBB.filteredIntegratedFlux(mySF);
1778\end{verbatim}
1779
1780A more detailed description of SkyT module can be found in:
1781{\it The SkyMixer (SkyT and PMixer modules) - Sophya Note No 2. }
1782available also from Sophya Web site.
1783
1784\newpage
1785\section{Module FitsIOServer}
1786This module provides classes for handling file input-output in FITS
1787\footnote{http://heasarc.gsfc.nasa.gov/docs/software/fitsio/fitsio.html}
1788format using the cfitsio library. Its
1789design is similar to the SOPHYA persistence (see Module BaseTools).
1790Delegate classes or handlers perform the actual read/write from/to fits files.
1791\par
1792Compared to the SOPHYA native persistence (PPF format),
1793FITS format has the advantage of being used extensively, and handled
1794by a many different software tools. It is a de facto standard in
1795astronomy and astrophysics.
1796However, FITS lacks some of the features present in SOPHYA PPF, and although
1797many SOPHYA objects can be saved in FITS files, FITS persistence has
1798some limitations. For example, FITS does not currently handle complex arrays.
1799\subsection{FITS streams}
1800\index{FITS} \index{FitsInOutFile}
1801%%
1802The class {\bf FitsInOutFile} can be seen as a wrapper class for the cfitsio library functions.
1803This class has been introduced in 2005 (V=1.9), when the module has been
1804extensively changed. In order to keep backward compatibility, the old fits wrapper
1805classes ({\bf FitsFile, FitsInFile, FitsOutFile}) has been changed to inherit from
1806 {\bf FitsInOutFile}. The use of class FitsFile and specific services of these old classes
1807 should be avoided, but FitsInFile, FitsOutFile can be safely considered a specialisation
1808 of FitsInOutFile for read/input and write/output operations respectively.
1809 Most c-fitsio errors are converted to an exception: {\bf FitsIOException}.
1810 \par
1811 File names are passed to cfitsio library. It is thus possible to use cfitsio file name conventions,
1812 such as {\bf ! } as the first character, for overwriting existing files (when creating files).
1813 The diagram below shows the class hierarchy for cfitsio wrapper classes.
1814\begin{figure}[hbt]
1815\dclsa{FitsInOutFile}
1816\dclscc{FitsFile}{FitsInFile}
1817\dclscc{FitsFile}{FitsOutFile}
1818\end{figure}
1819%%%%
1820\subsection{FITS handlers and I/O operators}
1821\index{FitsManager}
1822Handlers classes inheriting from {\bf FitsHandlerInterface} perform write/read operations
1823for AnyDataObj objects to/from FitsInOutFile streams. The {\bf FitsManager} class provides
1824top level services for object read/write in FITS files.
1825\par In most cases,
1826\hspace{5mm} {\tt FitsInOutFile\& $<<$ } \, and \, {\tt FitsInOutFile\& $>>$ } \hspace{5mm}
1827operators can be used to write and read objects.
1828When reading objects from a fits file using the {\tt FitsInOutFile\& $>>$ } operator,
1829the fits file is positioned on the next HDU, after reading. Also, if the {\bf FitsInOutFile}
1830object is positioned on a first empty HDU (without data, naxis=0), reading in objects
1831corresponding to a binary or ascii table using the operator $>>$ will skip automatically
1832the empty HDU and position the fits file on the second HDU, before trying to read in
1833the object.
1834\par
1835The two main types of fits data structures, images and tables
1836{\tt (IMAGE\_HDU , BINARY\_TBL , ASCII\_TBL)} are handled by the generic handlers: \\
1837{\bf \tcls{FitsArrayHandler}} and {\bf FitsHandler$<$BaseDataTable$>$}.
1838\par
1839A number of more specific handlers are also available, in particular for NTuple,
1840\tcls{SphereHealPix} and \tcls{SphereThetaPhi}. \\[2mm]
1841{\bf Warning:} Some handlers were written with the old FitsIOServer classes.
1842They inherit from the intermediate class {\bf FitsIOHandler} and
1843have been adapted to the new scheme. \\[2mm]
1844%%%
1845The examples below illustrates the usage of FitsIOServer classes. They can be compiled
1846and executed using runcxx, without the {\tt include} lines: \\[1mm]
1847\hspace*{5mm} {\tt csh> runcxx -import SkyMap -import FitsIOServer -inc fiosinit.h }
1848%%%
1849\begin{enumerate}
1850\item Saving an array and a HealPix map to a Fits file
1851\begin{verbatim}
1852#include "fitsioserver.h"
1853#include "fiosinit.h"
1854// ....
1855{
1856// Make sure FitsIOServer module is initialised :
1857FitsIOServerInit();
1858// Create and open a fits file named myfile.fits
1859FitsInOutFile fos("myfile.fits", FitsInOutFile ::Fits_Create);
1860// Create and save a 15x11 matrix of integers
1861TMatrix<int_4> mxi(15, 11);
1862mxi = RegularSequence(10.,10.);
1863fos << mxi;
1864// Save a HEALPix spherical map using FitsManager services
1865SphereHEALPix<r_8> sph(16);
1866sph = 48.3;
1867FitsManager::Write(fos, sph);
1868// --- The << operator could have been used instead : fos << sph;
1869}
1870\end{verbatim}
1871%%%%
1872%%%%
1873\item Reading objects and the header from the previously created fits file:
1874\begin{verbatim}
1875{
1876FitsIOServerInit(); // Initialisation
1877// ---- Open the fits file named myfile.fits
1878FitsInFile fis("myfile.fits");
1879//---- print file information on cout
1880cout << fis << endl;
1881//--- Read in the array
1882TArray<int_4> arr;
1883fis >> arr;
1884arr.Show();
1885//--- Position on second HDU
1886fis.MoveAbsToHDU(2);
1887//--- read and display header information
1888DVList hdu2;
1889fis.GetHeaderRecords(hdu2, true, true);
1890cout << hdu2;
1891//--- read in the HEALPix map
1892SphereHEALPix<r_8> sph;
1893FitsManager::Read(fis, sph);
1894// --- The >> operator could have been used instead : fis >> sph;
1895sph.Show();
1896}
1897\end{verbatim}
1898%%%%%%%
1899%%%
1900\item DataTable objects can be read from and written to FITS files as ASCII or
1901binary tables. The example belo show reading the DataTable created in the example
1902in section \ref{datatables} from a PPF file and saving it to a fits file.
1903\begin{verbatim}
1904#include "swfitsdtable.h"
1905// ....
1906{
1907FitsIOServerInit(); // FitsIOServer Initialisation
1908//--- Reading in DataTable object from PPF file
1909PInPersist pin("dtable.ppf");
1910DataTable dt;
1911pin >> dt;
1912dt.Show();
1913//--- Saving table to FITS
1914FitsInOutFile fos("!dtable.fits", FitsInOutFile ::Fits_Create);
1915fos << dt;
1916}
1917\end{verbatim}
1918%%%%
1919\end{enumerate}
1920%%%
1921A partial class diagram of FITS persistence handling classes is shown below. The
1922class {\tt FitsIOhandler} conforms to the old FitsIOServer module design and
1923should not be used anymore.
1924\begin{figure}[hbt]
1925\dclsbb{FitsHandlerInterface}{FitsArrayHandler$<$T$>$}
1926\dclsb{\tcls{FitsHandler}}
1927\dclscc{FitsIOhandler}{FITS\_NTuple}
1928\dclsc{FITS\_SphereHEALPix}
1929% \dclsb{FITS\_LocalMap}
1930\end{figure}
1931
1932\subsection{SwFitsDataTable and other classes}
1933\label{SwFitsDataTable}
1934\index{SwFitsDataTable}
1935The {\bf SwFitsDataTable} class implements the BaseDataTable interface
1936using a FITS file as swap space. Compared to SwPPFDataTable, they can be
1937used in R/W mode (reading from the table, when it is being created / filled).
1938They can be used in a way similar to DataTable and SwPPFDataTable.
1939When creating the table, a {\tt FitsInOutFile } stream, opened for writing has
1940to be passed to the creator. No further operation is needed.
1941\begin{verbatim}
1942// ....
1943FitsInOutFile so("!myswtable.fits", FitsInOutFile::Fits_Create);
1944SwFitsDataTable dt(so, 16);
1945// define table columns
1946dt.AddIntegerColumn("X0_i");
1947dt.AddFloatColumn("X1_f");
1948// ... Fill the table
1949r_8 x[5];
1950for(int i=0; i<63; i++) {
1951 x[0] = (i%9)-4.; x[1] = (i/9)-3.;
1952 dt.AddLine(x);
1953}
1954\end{verbatim}
1955The class {\bf FitsBTNtuIntf } provide an alternative tool to read FITS tables.
1956{\bf FitsABTColRd} , {\bf FitsABTWriter } and {\bf FitsImg2DWriter } can also
1957be used to manipulate FITS files.
1958\par
1959The {\bf scanfits} program can be used to check FITS files and analyse their
1960content (See \ref{scanfits}).
1961
1962%%%%
1963\newpage
1964\section{LinAlg and IFFTW modules}
1965An interface to use LAPACK library (available from {\tt http://www.netlib.org})
1966is implemented by the {\bf LapackServer} class, in module LinAlg.
1967\index{LapackServer}.
1968The sample code below shows how to use SVD (Singular Value Decomposition)
1969through LapackServer:
1970\begin{verbatim}
1971#include "intflapack.h"
1972// ...
1973// Use FortranMemoryMapping as default
1974BaseArray::SetDefaultMemoryMapping(BaseArray::FortranMemoryMapping);
1975// Create an fill the arrays A and its copy AA
1976int n = 20;
1977Matrix A(n , n), AA;
1978A = RandomSequence(RandomSequence::Gaussian, 0., 4.);
1979AA = A; // AA is a copy of A
1980// Compute the SVD decomposition
1981Vector S; // Vector of singular values
1982Matrix U, VT;
1983LapackServer<r_8> lpks;
1984lpks.SVD(AA, S, U, VT);
1985// We create a diagonal matrix using S
1986Matrix SM(n, n);
1987for(int k=0; k<n; k++) SM(k,k) = S(k);
1988// Check the result : A = U*SM*VT
1989Matrix diff = U*(SM*VT) - A;
1990double min, max;
1991diff.MinMax(min, max);
1992cout << " Min/Max difference Matrix (?=0) , Min= " << min
1993 << " Max= " << max << endl;
1994\end{verbatim}
1995
1996\index{FFTWServer}
1997The {\bf FFTWServer} class (in module FFTW) implements FFTServerInterface class
1998methods, for one dimensional and multi-dimensional Fourier
1999transforms on double precision data using the FFTW package
2000(available from {\tt http://www.fftw.org}).
2001
2002\newpage
2003\section{Building and installing Sophya}
2004\subsection{Supported platforms}
2005Presently, the Sophya library has been tested with the following
2006compiler/platform pairs:
2007
2008\begin{center}
2009\begin{tabular}{|l|l|}
2010\hline
2011OS & compiler \\
2012\hline
2013Linux & g++ (3.x \, 4.0) \\
2014Linux (SCL) & icc - Intel compiler (9.0) \\
2015MacOSX/Darwin (PowerPC) 10.3 \, 10.4 & g++ (3.3 \, 4.0)\\
2016MacOSX/Darwin (Intel) 10.4 & g++ (4.0)\\
2017HP/Compaq/DEC Tru64 ( OSF1) & cxx (6.1 6.3) \\
2018SGI IRIX64 & CC (7.3) \\
2019IBM AIX & xlC (7.x) \\
2020\hline
2021\end{tabular}
2022\end{center}
2023
2024\subsection{Library and makefile structure}
2025%
2026The object files from a given Sophya module are grouped in an archive library
2027with the module's name ({\tt libmodulename.a}). All Sophya modules
2028 are grouped in a single shared library ({\tt libsophya.so}), while the
2029modules with reference to external libraries are grouped in
2030({\tt libextsophya.so}). The {\bf PI} and {\bf PIext} modules are
2031grouped in ({\tt libPI.so}).
2032Alternatively, it is possible to group all modules in a single shared
2033library {\tt libAsophyaextPI.so}.
2034\par
2035Each library module has a {\tt Makefile} which compiles the source files
2036and build the correspond static (archive) library using the compilation
2037rules and flags defined in \\
2038\hspace*{5mm} {\tt \$SOPHYABASE/include/sophyamake.inc}. \\
2039Each program module has a {\tt Makefile} which compiles and link the
2040corresponding programs using the compilation rules and libraries
2041defined in {\$SOPHYABASE/include/sophyamake.inc}.
2042The top level Makefile in BuildMgr/ compiles each library modules
2043and builds shared libraries.
2044\par
2045Some of the modules in the Sophya package uses external libraries. The
2046{\bf FitsIOServer} is an example of such a module, where the {\tt libcfitsio.a}
2047is used. The list of all Sophya modules using external libraries is
2048presented in section \ref{sopmodules}.
2049The external libraries should be installed before the configure step
2050(see below) and the compilation of the corresponding Sophya modules.
2051\par
2052The series of Makefiles use the link to {\tt sophyamake.inc} in BuildMgr.
2053There are also the {\tt smakefile} series which uses the explicit path, using
2054{\tt \$SOPHYABASE} environment variable.
2055
2056\subsection{Build instructions}
2057\label{build}
2058The build procedure has two main steps:
2059\begin{enumerate}
2060\item The configure step (BuildMgr/configure) setup the directory structure and
2061the necessary configuration file. Refer to section \ref{directories} for
2062the description of SOPHYA directory tree and files.
2063\item The make step compiles the different sources files, create the library and optionaly
2064builds all or some of the associated executables.
2065\end{enumerate}
2066
2067{\tt BuildMgr/configure } is a c-shell script with a number of arguments:
2068\begin{verbatim}
2069csh> ./configure -h
2070configure [-sbase SOPHYABASE] [-scxx SOPHYACXX] [-incln]
2071 [-minc mymake.inc]
2072 [-extp dir1 -extp dir2 ...] [-extip dir1 -extip dir2 ... ]
2073 [-extlp dir1 -extlp dir2 ... ]
2074 [-noextlib -noext fits -noext fftw -noext lapack ]
2075 [-noext astro]
2076 [-usefftw2 -uselapack2] [-singleslb]
2077\end{verbatim}
2078\begin{itemize}
2079\item[] -sbase : define SOPHYA installation base directory. \$SOPHYABASE is used
2080if not specified.
2081\item[] -scxx : selects the C++ compiler. \$SOPHYACXX s used
2082if not specified.
2083\item[] -incln : creates symbolic link for include files, instead of copying them.
2084\item[] -minc : give an explicit name for the file used to generate
2085\$SOPHYABASE/include/sophyamake.inc.
2086\item[] -extp : Adds the specied path to the search path of the external libraries
2087include files and archive library.
2088\item[] -extip : Adds the specied path to the search path of the external libraries
2089include files.
2090\item[] -extp : Adds the specied path to the search path of the external libraries
2091archive (libxxx.a).
2092\item[] -noextlib : Disable compiling of modules referencing external libraries.
2093\item[] -noext : Disable compiling of the specified module (with reference to external
2094library.
2095\item[] -usefftw2: FFTW V2 is being used (default FFTW V3) - A compilation flag
2096will be defined in sspvflags.h
2097\item[] -uselapack2: Lapack V2 is being used (defaulr V3) - A compilation flag
2098will be defined in sspvflags.h
2099\item[] -singleslb: A single shared library for all SOPHYA, PI and external library interface
2100modules will be build. A compilation flag
2101will be defined in sspvflags.h . `See also target {\tt slballinone} below.
2102\end{itemize}
2103
2104In the example below, we assume that we want to install Sophya from a
2105released (tagged) version in the source directory {\tt \$SRC} in the
2106{\tt /usr/local/Sophya} directory, using {\tt g++}. We assume that
2107the external libraries can be found in {\tt /usr/local/ExtLibs/}.
2108We disable the compilation of the XAstroPack package.
2109
2110\vspace*{3mm}
2111\begin{verbatim}
2112# Create the top level directory
2113csh> mkdir /usr/local/Sophya/
2114csh> cd $SRC/BuildMgr
2115# Step 1.a : Run the configuration script
2116csh> ./configure -sbase /usr/local/Sophya -scxx g++ -extp /usr/local/ExtLibs/ \
2117-noext astro
2118# Step 1.b : Check the generated file $SOPHYABASE/include/sophyamake.inc
2119csh> ls -lt *.inc
2120csh> more sophyamake.inc
2121\end{verbatim}
2122If necessary, edit the generated file {\tt sophyamake.inc } in order to modify
2123compilation flags, library list. The file is rather short and self documented.
2124\begin{verbatim}
2125# Step 2.a: Compile the modules without external library reference
2126csh> make libs
2127# Step 2.b: Compile the modules WITH external library reference (optional)
2128csh> make extlibs
2129# Step 2.c: Build libsophya.so
2130csh> make slb
2131# Step 2.d: Build libextsophya.so (optional)
2132csh> make slbext
2133# Step 2.e: Compile the PI and PIext modules (optional)
2134csh> make PI
2135# Step 2.f: Build the corresponding shared library libPI.so (optional)
2136csh> make slbpi
2137\end{verbatim}
2138
2139To compile all modules and build the shared libraries, it is possible
2140to perform the steps 2.a to 2.f using the targets {\tt all} and {\tt slball}
2141defined in the Makefile
2142\begin{verbatim}
2143# Step 2.a ... 2.f
2144csh> make all slball
2145\end{verbatim}
2146
2147It is also possible to group all modules in a single shared library using
2148the target {\tt slballinone}.
2149\begin{verbatim}
2150# Step 2.a ... 2.f
2151csh> make all slballinone
2152\end{verbatim}
2153
2154At this step, all libraries should have been made. Programs using
2155Sophya libraries can now be built:
2156\begin{verbatim}
2157# To compile some of the test programs
2158csh> make basetests
2159# To compile runcxx , scanppf , scanfits
2160csh> make prgutil
2161# To build (s)piapp (libPI.so is needed)
2162csh> make piapp
2163\end{verbatim}
2164
2165If no further modification or update of source files is foreseen, it is possible
2166to remove all .o files:
2167\begin{verbatim}
2168# To clean $SOPHYABASE/obj directory :
2169csh> make cleanobj
2170\end{verbatim}
2171
2172
2173\subsection{Notes}
2174\begin{itemize}
2175\item[{\bf Makefile}] List of top level Makefile build targets
2176\begin{verbatim}
2177> libs extlibs PI = all
2178> slb slbext slbpi = slball (OR = slballinone)
2179> clean cleanobj
2180> tests prgutil prgmap progpi = prgall
2181> basetests piapp (ou progpi) pmixer
2182\end{verbatim}
2183\item[{\bf MacOS X}] A high performance mathematic and signal processing
2184library, including LAPACK and BLAS is packaged in Darwin/MacOS X (10.3, 10.4) : \\
2185\hspace*{5mm} {\bf -framework Accelerate}
2186\item[{\bf Tru64/OSF}] An optimised math library with LAPACK and BLAS might
2187optionaly be installed {\bf (-lcxlm) }. On our system, this libray contained Lapack V2.
2188So we used the LAPACK, as compiled from the public sources, and linked with
2189the Tru64 native BLAS.
2190\item[{\bf IRIX64}] We used the math library with LAPACK V2 and BLAS
2191from SGI : {\bf -lcomplib.sgimath}
2192\item[{\bf AIX}] There seem to be a problem on AIX when several shared
2193libraries are used. We have been able to run SOPHYA programs either
2194using static libraries, or a single shared library (libAsophyaextPI.so)
2195if extlibs and PI are needed, in addition to stand alone SOPHYA modules.
2196It has not been possible to link SOPHYA with fortran libraries
2197\item[{\bf Mgr}] This module contains makefiles and build scripts
2198that were used in SOPHYA up to version 1.7 (2004) : OBSOLETE.
2199\end{itemize}
2200
2201\subsection{Files and scripts in BuildMgr/ }
2202\begin{itemize}
2203\item[] {\bf Makefile:} Top level Makefile for building SOPHYA.
2204{\tt smakefile} is similar to Makefile, except that it uses
2205the smakefiles in each module.
2206\item[] {\bf mkmflib:} c-shell script for creation of library module
2207Makefile / smakefile. \\
2208\hspace*{5mm} {\tt ./mkmflib -sbase /tmp/sbase SUtils }
2209\item[] {\b mkmfprog:}
2210c-shell script for creation of programs module Makefile / smakefile \\
2211\hspace*{5mm} {\tt ./mkmfprog -sbase /tmp/sbase ProgPI }
2212\item[] {\bf domkmf:} c-shell script - calls mkmflib for all modules \\
2213\hspace*{5mm} {\tt ./domkmf -sbase /tmp/sbase}
2214\item[] {\bf xxx\_make.inc:} Configuration files for different compilers and OS
2215{\tt ( Linux\_g++\_make.inc , OSF1\_cxx\_make.inc \ldots )}.
2216These files are used to generate {\tt sophyamake.inc}
2217\end{itemize}
2218
2219
2220
2221\newpage
2222\appendix
2223\section{SOPHYA Exceptions}
2224\index{Exception classes} \index{PThrowable} \index{PError} \index{PException}
2225SOPHYA library defines a set of exceptions which are used
2226for signalling error conditions. The figure below shows a partial
2227class diagram for exception classes in SOPHYA.
2228\begin{figure}[hbt]
2229\dclsbb{PThrowable}{PError}
2230\dclscc{PError}{AllocationError}
2231\dclscc{PError}{NullPtrError}
2232\dclscc{PError}{ForbiddenError}
2233\dclscc{PError}{AssertionFailedError}
2234\dclsbb{PThrowable}{PException}
2235\dclscc{PException}{IOExc}
2236\dclscc{PException}{SzMismatchError}
2237\dclscc{PException}{RangeCheckError}
2238\dclscc{PException}{ParmError}
2239\dclscc{PException}{TypeMismatchExc}
2240\dclscc{PException}{MathExc}
2241\dclscc{PException}{CaughtSignalExc}
2242\caption{partial class diagram for exception handling in Sophya}
2243\end{figure}
2244
2245For simple programs, it is a good practice to handle
2246the exceptions at least at high level, in the {\tt main()} function.
2247The example below shows the exception handling and the usage
2248of Sophya persistence.
2249
2250\input{ex1.inc}
2251
2252
2253\newpage
2254\addcontentsline{toc}{section}{Index}
2255\printindex
2256\end{document}
2257
Note: See TracBrowser for help on using the repository browser.