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

Last change on this file since 4055 was 3858, checked in by ansari, 15 years ago

petit ajout ds sophya.tex (ConvertTostdvec()), Reza 12/08/2010

File size: 132.8 KB
RevLine 
[3015]1\documentclass[twoside,10pt]{article}
[887]2% Package standard : Utilisation de caracteres accentues, mode francais et graphique
[988]3\usepackage{url}
[887]4\usepackage[latin1]{inputenc}
5\usepackage[T1]{fontenc}
6\usepackage[english]{babel}
7\usepackage{graphicx}
8% package a mettre pour faire du pdf
[978]9\usepackage{palatino}
[887]10
11% Extension de symboles mathematiques
12\usepackage{amssymb}
13
[988]14% Definition pour Docs Sophya
[974]15\usepackage{defsophya}
16
[1362]17% Constitution d'index
18\usepackage{makeidx}
[2280]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}
[887]25
[2280]26\makeindex % Constitution d'index
27
[3006]28\newcommand{\rond}{$\bullet \ $}
29\newcommand{\etoile}{$\star \ $}
30\newcommand{\cercle}{$\circ \ $}
31\newcommand{\carre}{$\Box \ $}
32
[3856]33\newcommand{\bitem}[1]{\item[]{\bf #1} }
[3006]34
[887]35\begin{document}
36
37\begin{titlepage}
[988]38% The title page - top of the page with the title of the paper
[3856]39\titrehp{SOPHYA user's guide }
[988]40% Authors list
[978]41\auteurs{
[988]42R. Ansari & ansari@lal.in2p3.fr \\
[1340]43E. Aubourg & aubourg@hep.saclay.cea.fr \\
[988]44G. Le Meur & lemeur@lal.in2p3.fr \\
45C. Magneville & cmv@hep.saclay.cea.fr \\
[887]46}
[978]47% \auteursall
[988]48% The title page - bottom of the page with the paper number
[1362]49\vspace{1cm}
50\begin{center}
[3856]51{\bf \Large SOPHYA Version: 2.2 (V\_Sep2010) }
[1362]52\end{center}
[988]53\titrebp{1}
[887]54\end{titlepage}
55
56\tableofcontents
57
58\newpage
59
60\section{Introduction}
61
[1362]62{\bf SOPHYA} ({\bf SO}ftware for {\bf PHY}sics {\bf A}nalysis)
[887]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.
[2790]66Although some of the SOPHYA modules (SkyMap, Samba, SkyT)
[3045]67have been designed with the specific goal of CMB data analysis, most
[2790]68modules presented here have a much broader scope and can be
69used in scientific data analysis and modeling/simulation.
[3006]70Whenever possible, we use existing numerical packages and libraries,
71encapsulating them in classes in order to facilitate their usage.
[1435]72\par
[3006]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}
[1435]96This documents
[1434]97presents only a brief overview of the class library,
98mainly from the user's point of view. A more complete description
[2278]99can be found in the reference manual, available from the SOPHYA
[2280]100web site: % {\bf http://www.sophya.org}.
101\href{http://www.sophya.org}{http://www.sophya.org}.
[3006]102%%%
103%%%
[3438]104\subsection{Acknowlegments}
105Many people have contributed to the development SOPHYA and/or the PI library
[3839]106and (s)piapp interactive analysis tool, in particular:
[3438]107
108\begin{tabular}{lcl}
109Reza Ansari & \hspace{5mm} & (LAL-Univ.Paris Sud, Orsay) \\
110Eric Aubourg & & (DAPNIA-CEA/APC, Saclay) \\
111Sophie Henrot-Versille & & (LAL-IN2P3/CNRS, Orsay) \\
112Alex Kim & & (LBL, Berkeley) \\
113Guy Le Meur & & (LAL-IN2P3/CNRS, Orsay) \\
114Eric Lesquoy & & (DAPNIA-CEA, Saclay) \\
115Christophe Magneville & & (DAPNIA-CEA, Saclay) \\
116Bruno Mansoux & & (LAL-IN2P3/CNRS, Orsay) \\
117Olivier Perdereau & & (LAL-IN2P3/CNRS, Orsay) \\
118Nicolas Regnault & & (LPNHE-IN2P3/CNRS, Paris) \\
119Benoit Revenu & & (APC/Univ.Paris 7, Paris) \\
120Francois Touze & & (LAL-IN2P3/CNRS, Orsay) \\
121\end{tabular}
122
123We thank also the persons who have helped us by useful suggestions, among others : \\
[3441]124S. Bargot, S. Plasczczynski, C. Renault and D. Yvon.
[3438]125
[3006]126\subsection{SOPHYA modules}
[3045]127\label{sopmodules}
[1434]128The source directory tree
[2790]129\footnote{ CVS: cvsserver.lal.in2p3.fr:/exp/eros/CVSSophya}
[887]130is organised into a number of modules.
131
132\begin{itemize}
[2790]133\item[] {\bf BuildMgr/} Scripts for code management,
[887]134makefile generation and software installation
[2278]135\item[] {\bf BaseTools/} General architecture support classes such
[887]136as {\tt PPersist, NDataBlock<T>}, and few utility classes
[2278]137such as the dynamic variable list manager ({\tt DVList}) as well
138as the basic set of exception classes used in SOPHYA.
[1340]139\item[] {\bf TArray/} template numerical arrays, vectors and matrices \\
[1648]140({\tt TArray<T> TMatrix<T> TVector<T> } \ldots)
[887]141\item[] {\bf NTools/} Some standard numerical analysis tools
142(linear, and non linear parameter fitting, FFT, \ldots)
[1648]143\item[] {\bf HiStats/} Histogram-ming and data set handling classes (tuples) \\
[2790]144({\tt Histo Histo2D NTuple DataTable} \ldots)
145\item[] {\bf SkyMap/} Local and full sky maps, and some 3D geometry
[1648]146handling utility classes. \\
147({\tt PixelMap<T>, LocalMap<T>, SphericalMap<T>, \ldots})
[2790]148\item[] {\bf SUtils/} This module contains few utility classes, such as the
[2278]149{\tt DataCard} class, as well as string manipulation functions in C and C++.
150\item[] {\bf SysTools/} This module contains classes implementing
151an interface to various OS specific services, such
[3856]152as threads and dynamic link/shared library handling.
[2278]153
[887]154\end{itemize}
155
[978]156The modules listed below are more tightly related to the
157CMB (Cosmic Microwave Background) data analysis problem:
[887]158\begin{itemize}
159\item[] {\bf SkyT/}
160classes for spectral emission and detector frequency response modelling \\
[3839]161({\tt SpectralResponse, RadSpectra, BlackBody} \ldots). This module needs extensive
162checking and corrections.
[1436]163\item[] {\bf Samba/} Spherical harmonic analysis, noise generators \ldots
[887]164\end{itemize}
165
[978]166The following modules contain the interface classes with
167external libraries:
[887]168\begin{itemize}
[988]169\item[] {\bf FitsIOServer/} Classes for handling file input-output
[3006]170in FITS format using the cfitsio library.
171FITS is maintained by NASA and SAO and is available from: \\
172\href{http://heasarc.gsfc.nasa.gov/docs/software/fitsio/fitsio.html}
173{http://heasarc.gsfc.nasa.gov/docs/software/fitsio/fitsio.html}
174\item[] {\bf LinAlg/} Interface with Lapack linear algebra package.
175Lapack is a linear algebra package and can be downloaded from: \\
176\href{http://www.netlib.org/lapack/}{http://www.netlib.org/lapack/}
177\item[] {\bf IFFTW/} Interface with FFTW package (libfftw.a).
178FFTW is a package for performing Fourier transforms, written in C.
179Documentation and source code can be found at: \\
180\href{http://www.fftw.org/}{http://www.fftw.org/}
[1648]181\item[] {\bf XAstroPack/} Interface to some common astronomical
182computation libraries. Presently, this module uses an external library
183extracted from the {\bf Xephem } source code. The corresponding source
184code is also available from SOPHYA cvs repository, module {\bf XephemAstroLib}.
[3006]185Information on Xephem can be found at : \\
186\href{http://www.clearskyinstitute.com/xephem/}{http://www.clearskyinstitute.com/xephem/}
[2790]187
[887]188\end{itemize}
189
[2278]190The following modules contain each a set of related programs using the
191SOPHYA library.
[887]192\begin{itemize}
[3856]193\item[] {\bf Tests/} Simple test programs. Many of these test programs can also be
194used as examples for using SOPHYA.
[1340]195\item[] {\bf PrgUtil/} Various utility programs (runcxx, scanppf, scanfits, \ldots)
[2278]196\item[] {\bf PrgMap/} Programs performing operations on skymaps: projections,
197power spectrum in harmonic space, \ldots
198\end{itemize}
199
200As a companion to SOPHYA, the {\bf (s)piapp} interactive data analysis
201program is built on top of SOPHYA and the {\bf PI} GUI class library
202and application framework. The {\bf PI} ({\bf P}eida {\bf Interactive})
203development started in 1995, in the EROS \footnote{EROS: {\bf E}xp\'erience
204de {\bf R}echerche d'{\bf O}bjets {\bf S}ombres - http://eros.in2p3.fr}
205microlensing search collaboration, with PEIDA++ \footnote {PEIDA++:
206The EROS data analysis class library -
207http://www.lal.in2p3.fr/recherche/eros/PeidaDoc/}.
208The {\bf PI} documentation and the {\bf piapp} user's guide are available
[2280]209from \href{http://www.sophya.org}{http://www.sophya.org}.
[2278]210%\href{http://www.sophya.org}{http://www.sophya.org}.
211The {\bf PI} is organized as the following modules:
212\begin{itemize}
[2280]213\item[] {\bf PI/} Portable GUI class library and application development
[2278]214framework kernel.
[2280]215\item[] {\bf PIGcont/} Contour-plot drawing classes.
216\item[] {\bf PIext/} Specific drawers and adapters for SOPHYA objects,
[2278]217and the {\bf piapp} interactive data analysis framework.
218\item[] {\bf ProgPI/} interactive analysis tool main program and pre-loaded
219modules.
[887]220\end{itemize}
221
[3006]222Modules containing examples and demo programs and scripts:
[1434]223\begin{itemize}
224\item[] {\bf Examples/} Sample SOPHYA codes and example programs and
[2790]225makefiles.
226\item[] {\bf DemoPIApp/} Sample scripts and programs for (s)piapp
[1434]227interactive analysis tools.
[3856]228\item[] {\bf DemoData/} data files (PPF, FITS \ldots) useful for the (s)piapp
229user's manual examples.
[1434]230\end{itemize}
[3415]231
[3856]232The following modules contains additional programs or libraries, which rely on SOPHYA:
[3415]233\begin{itemize}
234\item[] {\bf AnaLC} contains program files extracted from the EROS/PEIDA software
235and adapted to be compiled with SOPHYA. It can be used in particular to read and analyse
[3856]236EROS light curve data files (fichiers de suivi).
237\item[] {\bf LUC} ( {\bf L}ittle {\bf U}niverse {\bf C}alculator) is a module containing classes to
[3415]238perform basic computation related to the universe geometry (FRW metric).
[3856]239\item[] {\bf SimLSS} Tools for the {\bf Sim}ulation and analysis of cosmological
240{\bf L}arge {\bf S}cale {\bf S}tructures
241\item[] {\bf PIPhoto} is an interface module for (s)piapp and ImageMagick for
242import/export of graphics in image format (jpeg, gif \ldots) in piapp.
[3839]243\item[] {\bf PMixer/} skymixer and related programs. This module is {\bf obsolete}.
[3415]244\end{itemize}
245
[988]246\newpage
247
[978]248\section{Using Sophya}
[2996]249The organisation of SOPHYA directories and some of the associated
250utility programs are described in this section.
[3045]251Basic usage of Sophya classes is described in the following sections.
[2278]252Complete Sophya documentation can be found at our web site
[1434]253{\bf http://www.sophya.org}.
[1362]254
[2790]255\subsection{Directories, environment variables, configuration files}
[3015]256\label{directories}
[2790]257The environment variable {\bf SOPHYABASE} is used
[3006]258to define the path where the Sophya libraries and binaries are installed.
[978]259\begin{itemize}
[2790]260\item \$SOPHYABASE/include : Include (.h) files
261\item \$SOPHYABASE/lib : Path for the archive libraries (.a)
[3015]262\item \$SOPHYABASE/slb: Shared library path (.so or .dylib on Darwin/MacOS)
[3006]263\item \$SOPHYABASE/exe : Path for binary program files
[978]264\end{itemize}
265
[2790]266The directory { \tt \$SOPHYABASE/include/SophyaConfInfo/ } contains files
267describing the installed configuration of SOPHYA software.
[978]268
[2790]269The file { \tt \$SOPHYABASE/include/machdefs.h } contains definitions
[3015]270(flags, typedef) used in SOPHYA, while some more specific flags,
271are found in { \tt \$SOPHYABASE/include/sspvflags.h }
[2790]272
273The file { \tt \$SOPHYABASE/include/sophyamake.inc } contains the
274compilation commands and flags used for building the software.
275Users can use most of compilation and link commands defined in this file:
276 {\tt \$CCOMPILE , \$CXXCOMPILE . \$CXXLINK \ldots}.
277 (See module Example).
278
279The configure script (BuildMgr/configure) creates the directory tree and the
[3015]280above files. It also copy (or create symbolic link) for all SOPHYA include
281files as well as symbolic links for external libraries
282include files path in {\tt \$SOPHYABASE/include} (FitsIO, FFTW, XAstro \ldots).
[2790]283
[3015]284Object files for each module are grouped in a static archive library
285by the build procedure (libXXX.a for module
286XXX, with XXX = BaseTools, TArray, HiStats, FitsIOServer \ldots).
287
288When shared libraries are build, all stand alone SOPHYA modules
289are grouped in {\tt libsophya.so}, {\tt libextsophya.so} contains
290the interface modules with external libraries {\bf (FitsIOServer, LinAlg \ldots)},
291while {\bf PI, PIext, PIGcont} modules are grouped in {\tt libPI.so}.
292Alternatively, it is possible to group all modules in a single shared
293library {\tt libAsophyaextPI.so} (See \ref{build})
294
295In order to use the shared libraries, the {\bf LD\_LIBRARY\_PATH} variable
296should contain the Sophya shared library path
297({\tt \$SOPHYABASE/slb}).
298On Silicon Graphics machines with IRIX64 operating system,
299the default SOPHYA configuration correspond to the 64 bit architecture.
300The environment variable { \bf LD\_LIBRARY64\_PATH } replace in
301this case the usual {\bf LD\_LIBRARY\_PATH} variable.
302On IBM machines with AIX, the {\bf LIBPATH} environment variables
303contains the shared libraries search path.
304
305When using the dynamic load services in SOPHYA ({\tt PDynLinkMgr}
306class), in runcxx or (s)piapp applications for example, the shared
307library search path must contain the current working directory (
308dot . in unix).
309
[3419]310\subsection{Copy constructor and assignment operator}
311\label{memgt}
312In C++, objects can be copied by assignment or by initialisation.
313Copying by initialisation corresponds to creating an object and
314initialising its value through the copy constructor.
315The copy constructor has its first argument as a reference, or
316const reference to the object's class type. It can have
317more arguments, if default values are provided.
318Copying by assignment applies to an existing object and
319is performed through the assignment operator (=).
320The copy constructor implements this for identical type objects:
321\begin{verbatim}
322class MyObject {
323public:
324 MyObject(); // Default constructor
325 MyObject(MyObject const & a); // Copy constructor
326 MyObject & operator = (MyObject const & a) // Assignment operator
327}
328\end{verbatim}
329The copy constructors play an important role, as they are
330called when class objects are passed by value,
331returned by value, or thrown as an exception.
332\begin{verbatim}
333// A function declaration with an argument of type MyObject,
334// passed by value, and returning a MyObject
335MyObject f(MyObject x)
336{
337 MyObject r;
338 ...
339 return(r); // Copy constructor is called here
340}
341// Calling the function :
342MyObject a;
343f(a); // Copy constructor called for a
344\end{verbatim}
345It should be noted that the C++ syntax is ambiguous for the
346assignment operator. {\tt MyObject x; x=y; } and
347{\tt MyObject x=y;} have different meaning.
348\begin{verbatim}
349MyObject a; // default constructor call
350MyObject b(a); // copy constructor call
351MyObject bb = a; // identical to bb(a) : copy constructor call
352MyObject c; // default constructor call
353c = a; // assignment operator call
354\end{verbatim}
355
356As a general rule in SOPHYA, objects which implements
357reference sharing on their data members have a copy constructor
358which shares the data, while the assignment operator copies or
359duplicate the data.
360
361\subsection{Multi-thread programming with SOPHYA}
362Multi-thread programming is usually safe as long as different threads DO NOT access
363the same memory locations. SOPHYA is mainly organized as classes having only
364data members, with very few cases having static data members (memory locations
365common to all instances of a class), or seldom, global variables. \\
366Using different instances of a class in different threads is thus safe for most
367classes / methods in SOPHYA. \\
368A major exception is the reference sharing mechanism, where different instances
[3856]369of a class may share memory locations. This reference sharing mechanism has been
[3419]370made thread-safe in SOPHYA, from version V=2.1. \\
371As a consequence, different execution threads can access non overlapping sub-arrays
372and access (read/write) the corresponding elements without the need of
373mutex and thread synchonisation. Moreover, thread safe filling of
374NTuple and DataTable objects can be activated, on an object per object basis. \\
375The {\tt ZThread, ZMutex \ldots} classes in the {\bf SysTools } module offer a relatively
[3856]376easy way of writing multi-threaded programs (See \ref{mtpsop}).
[3419]377
[1362]378\subsection{the runcxx program}
[3037]379\index{runcxx} \label{runcxx}
[1362]380{\bf runcxx} is a simple program which can be used to compile, link
381and run simple C++ programs. It handles the creation of a
382complete program file, containing the basic set C++ include files,
383the necessary include files for SOPHYA SysTools, TArray, HiStats
384and NTools modules, and the main program with exception handling.
385Other Sophya modules can be included using the {\tt -import} flag.
[1435]386Use of additional include files can be specified using the
387{\tt -inc} flag.
[1362]388\begin{verbatim}
389csh> runcxx -h
[2790]390 PIOPersist::Initialize() Starting Sophya Persistence management service
391SOPHYA Version 1.9 Revision 0 (V_Mai2005) -- May 31 2005 15:11:32 cxx
392 runcxx : compiling and running of a piece of C++ code
393 Usage: runcxx [-compopt CompileOptions] [-linkopt LinkOptions]
394 [-tmpdir TmpDirectory] [-f C++CodeFileName]
395 [-inc includefile] [-inc includefile ...]
396 [-import modulename] [-import modulename ...]
397 [-uarg UserArg1 UserArg2 ...]
398 if no file name is specified, read from standard input
399 modulenames: SkyMap, Samba, SkyT, FitsIOServer,
400 LinAlg, IFFTW, XAstroPack
[1362]401\end{verbatim}
[3419]402Most examples in this manual can be tested using runcxx.
403The preprocessor macro {\tt KeepObj()} is defined by runcxx and let the user
404to save an objet to an PPF file, with the same name as the corresponding variable.
405The example below shows how to compile, link and run a sample
[1362]406code.
407\begin{verbatim}
[3419]408## File example.icc :
409
410Matrix mxa(3,3);
411mxa = IdentityMatrix(1.);
412cout << mxa ;
413// Save the object mxa in a PPF file named mxa
414KeepObj(mxa);
415
416## Executing this sample code
[1362]417csh> runcxx -f example.icc
418\end{verbatim}
[2278]419
420\subsection{the scanppf program}
[3037]421\index{scanppf} \label{scanppf}
[2278]422{\bf scanppf} is a simple SOPHYA application which can be used to check
[2790]423PPF files and list their contents. It can also provide the list of all registered
424PPF handlers.
[2278]425\begin{verbatim}
426csh> scanppf -h
[2790]427 PIOPersist::Initialize() Starting Sophya Persistence management service
[3034]428SOPHYA Version 2.0 Revision 0 (V_Jul2006) -- Jul 17 2006 14:13:27 cxx
[2790]429 Usage: scanppf [flags] filename
[3034]430 flags = -s -n -a0 -a1 -a2 -a3 -lh -lho -lmod
[2790]431 -s[=default} : Sequential reading of objects
432 -n : Object reading at NameTags
433 -a0...a3 : Tag List with PInPersist.AnalyseTags(0...3)
434 -lh : List PPersist handler classes
435 -lho : List PPersist handler and dataobj classes
[3034]436 -lmod : List initialized/registered modules
[2278]437\end{verbatim}
438
[3037]439\subsection{the scanfits program}
440\index{scanfits} \label{scanfits}
[2996]441{\bf scanfits} is a SOPHYA program using the FitsIOServer
442\footnote{FitsIOServer module uses the cfitsio library. scanfits has to be linked with
443with FitsIOServer module and cfitsio libraries, or libextsophya.so}
444module which can be used
445to analyse the content of FITS files. It can list the FITS headers, the appropriate
446SOPHYA-FITS handler (implementing {\tt FitsHandlerInterface}) class, and the list of
447all registered FITS handlers.
448\begin{verbatim}
449csh> scanfits -h
450 PIOPersist::Initialize() Starting Sophya Persistence management service
[3037]451SOPHYA Version 2.0 Revision 0 (V_Jul2006) -- Jul 17 2006 14:13:27 cxx
[2996]452 Usage: scanfits [flags] filename
453 flags = -V1 -lh -rd -header
454 -V1 : Scan using old (V1) code version
455 -lh : Print the list of registered handlers (FitsHandlerInterface)
456 -rd : try to read each HDU data using appropriate handler
457 -header : List header information
458\end{verbatim}
[2278]459
[3415]460\subsection{the spiapp program}
461\index{spiapp} \label{spiapp}
462{\bf spiapp} is an interactive data analysis program, built on top of the SOPHYA
463library, , the PI GUI library. The interactive data analysis framework is defined
464by the classes in the {\bf PIext} module. spiapp has a c-shell like
465command interpreter and can be used to manipulate SOPHYA and display
466objects. Refer to the piapp user manual for more information.
467\begin{verbatim}
468csh> spiapp -h
469 SophyaInitiator::SophyaInitiator() BaseTools Init
470 PIOPersist::Initialize() Starting Sophya Persistence management service
471SOPHYA Version 2.1 Revision 0 (V_Nov2007) -- Nov 24 2007 13:08:58 gcc 3.3 20030304 (Apple Computer, Inc. build 1495)
472
473 piapp: Interactive data analysis and visualisation program
474 Usage: piapp [-nored] [-doublered] [-termread] [-term]
475 [-hidezswin] [-small] [-nosig] [-nosigfpe] [-nosigsegv]
476 [-tmpdir TmpDirectory] [-help2tex] [-exec file [args]]
477 -nored : Don't redirect stdout/stderr to piapp console
478 -doublered : Redirect stdout/stderr to piapp console AND the terminal
479 -termread : Read commands on terminal (stdin)
480 -term : equivalent to -nored -termread -small
481 -hidezswin : Hide Zoom/Stat/ColMap window
482 -small : Create small size main piapp window
483 -nosig : Don't catch SigFPE, SigSEGV
484 -nosigfpe -nosigsegv: Don t catch SigFPE / SigSEGV
485 -tmpdir TmpDirectory: defines TMDIR for temporary files
486 -help2tex: Create a LaTeX help file (piahelp.tex)
487 -exec file [args] : Execute command file (last option)
488
489\end{verbatim}
[978]490
[1299]491
[1435]492\newpage
[2278]493\section{Module BaseTools}
[1299]494
[2278]495{\bf BaseTools} contains utility classes such as
[1299]496{\tt DVlist}, an hierarchy of exception classes for Sophya, a template
497class {\tcls{NDataBlock}} for handling reference counting on numerical
498arrays, as well as classes providing the services for implementing simple
[3419]499serialisation (object persistence services).
[1299]500\vspace*{5mm}
501
[3034]502\subsection{Initialisation}
503\index{SophyaInitiator}
504A number of actions have to be taken before
505some of the services provided by SOPHYA become operational. This is the case
506of SOPHYA persistence, as well as FITS I/O facilities.
507Initialisation of many SOPHYA modules is performed through an initialiser class,
[3040]508which inherits from {\bf SophyaInitiator}.
509\par
510Static instance of each initialiser class exist in the library and the various SOPHYA services
511should be operational when the user code ({\tt main()}) starts, except for
512modules in the second or third shared libraries
513({\tt libextsophya.so libPI.so}). Indeed, a problem related
514to the initialisation of shared libraries arises on some systems
515(Darwin/Mac OS X in particular) causing program crash at start-up,
516if static instance of initialiser class is present in the second shared library.
517The FitsIOServer module should thus be explicitly initialised in the user
518program.
519\par
520In cases where the run time loader does not perform correctly the static
521object initialisation, the initialiser class for the modules used in the
522program must be instanciated in the beginning of your main program: \\
523{\tt TArrayInitiator , HiStatsInitiator , SkyMapInitiator , FitsIOServer \ldots}
[3034]524%%%
[1340]525\subsection{SOPHYA persistence}
[3006]526\label{ppfdesc}
[1362]527\index{PPersist} \index{PInPersist} \index{POutPersist}
[1299]528\begin{figure}[hbt]
529\dclsa{PPersist}
[2790]530\dclsccc{PPFBinarIOStream}{PPFBinaryInputStream}{PInPersist}
531\dclscc{PPFBinaryOutputStream}{POutPersist}
[1299]532\caption{partial class diagram for classes handling persistence in Sophya}
533\end{figure}
[1340]534A simple persistence mechanism is defined in SOPHYA. Its main
535features are:
536\begin{itemize}
537\item[] Portable file format, containing the description of the data structures
538and object hierarchy. \\
539{\bf PPF} {\bf P}ortable {\bf P}ersistence file {\bf F}ormat.
[1648]540\index{PPF}
[1435]541\item[] Handling of read/write for multiply referenced objects.
[1340]542\item[] All write operations are carried using sequential access only. This
543holds also for read operations, unless positional tags are used.
544SOPHYA persistence services can thus be used to transfer objects
545through network links.
[1360]546\item[] The serialisation (reading/writing) for objects for a given class
[1435]547is implemented through a handler object. The handler class inherits
[1360]548from {\tt PPersist} class.
[1435]549\item[] A run time registration mechanism is used in conjunction with
550RTTI (Run Time Type Identification) for identifying handler classes
551when reading {\bf PInPersist} streams, or for associating handlers
552with data objects {\bf AnyDataObject} for write operations.
[1340]553\end{itemize}
[3419]554The most useful methods for using Sophya
555persistence are listed below. A brief description of the PPF file format
556and some guidelines for writing writing delegate classes for handling
557object persistence can be found in the following paragraphs.
[1435]558\begin{itemize}
559\item[] {\tt POutPersist::PutObject(AnyDataObj \& o)} \\
560Writes the data object {\bf o} to the output stream.
561\item[] {\tt POutPersist::PutObject(AnyDataObj \& o, string tagname)} \\
562Writes the data object {\bf o} to the output stream, associated with an
563identification tag {\bf tagname}.
564\item[] {\tt PInPersist::GetObject(AnyDataObj \& o)} \\
565Reads the next object in stream into {\bf o}. An exception is
566generated for incompatible object types.
567\item[] {\tt PInPersist::GetObject(AnyDataObj \& o, string tagname)} \\
568Reads the object associated with the tag {\bf tagname} into {\bf o}.
569An exception is generated for incompatible object types.
570\end{itemize}
571The operators {\tt operator << (POutPersist ...) } and
572{\tt operator >> (PInPersist ...) } are often overloaded
[2790]573to perform {\tt PutObject()} and {\tt GetObject()} operations.
574the {\bf PPFNameTag} (ppfnametag.h) class can be used in conjunction with
575{\tt << >> } operators to write objects with a name tag or to retrieve
576an object identified with a name tag. The example below shows the
577usage of these operators:
[1435]578\begin{verbatim}
579// Creating and filling a histogram
580Histo hw(0.,10.,100);
581...
582// Writing histogram to a PPF stream
583POutPersist os("hw.ppf");
[2790]584os << PPFNameTag("myhisto") << hw;
585
[1435]586// Reading a histogram from a PPF stream
587PInPersist is("hr.ppf");
[2790]588is >> PPFNameTag("myhisto") >> hr;
[1435]589\end{verbatim}
[1360]590
[1435]591The {\bf scanppf} program can be used to list the content of a PPF file.
592
[3419]593\subsubsection{PPF file format}
594The PPF file consist of :
595\begin{itemize}
596\item[\rond] A file header (3x32=96 bytes) , containing an identification string,
597PPF format version (currently V3), the file endiannes {\tt (BIG-ENDIAN , LITTLE-ENDIAN)}
598and the file creation date and time. It should be noted that the present SOPHYA version
[3839]599(V=2.2) does not allow updating an existing PPF file.
[3419]600\item[\rond] A collection of tagged data items and data structuring tags.
601the PPF tags are one byte (8 bits) long and may be followed by a length information
602for arrays, or strings. The length information might be 4 bytes or 8 bytes long.
603Characters, various length (1,2,4,8 bytes long) signed and unsigned integers,
604simple or double precision (4/8) bytes floating point and complex numbers are
605the basic data types handled by PPF streams.
606\begin{verbatim}
607tag=PPS_SIMPLE_Integer4 + data (4 bytes)
608tag=PPS_SIMPLE_Float4 + data (4 bytes)
609tag=PPS_SIMPLE_Complex8 + data (2x8=16 bytes)
610tag=PPS_STRING + Length (4 bytes) + data (Length bytes)
611tag=PPS_SIMPLE_ARRAY4_UInt2 + Length (4 bytes) + data (2xLength bytes)
612\end{verbatim}
613The two tags {\tt PPS\_OBJECT} and {\tt PPS\_ENDOBJECT} are used for identifying
614objects.
615\item[\rond] The file trailer contains some global statistics such as the total number
616of objects in file, the list of name tags, with their corresponding positions.
617These informations are grouped under the identifier tag {\tt PPS\_NAMETAG\_TABLE }.
618The last byte in file contains the value {\tt PPS\_EOF}
619\end{itemize}
620We show below the result of the analysis of a PPF file using
621 {\tt PPFBinaryInputStream::AnalyseTags()}. This can easily be done using the
622 {\bf runcxx} program.
623The PPF file contains four objects:
624a {\tt TimeStamp} object, two {\tt NDataBlock} objects, the second one sharing its data with
625the first one. The second NDataBlock is only written as a reference to the first object. The fourth
626object is a {\tt RandomGenerator} which has an {\tt NDataBlock} object as data member.
627Notice the corresponding nested structure of object marker tags.
628The first object and the last objects in the file are written associated with a {\bf NameTag}.
629{\small
630\begin{verbatim}
631 ----------------------------------------------------------
632 PPFBinaryInputStream::AnalyseTags(Level= 49)
633 FileName= toto.ppf
634 Version= 3 FileSize= 8884 Creation Date= Fri Dec 7 15:30:58 2007
635
636 NbPosTag=0 NbNameTag=2 NbObjs=4 NbTopLevObjs=3 NbRefs=1 MaxNest=2
637
638<PPS_NAMETAG_MARK> tag at position 60
639<PPS_OBJECT> tag at position 61 ClassId= c09dfe032b341cee ObjectId= 10
640 <PPS_SIMPLE> tag at position 72 DataType=INTEGER x4
641 <PPS_SIMPLE> tag at position 77 DataType=INTEGER x8
642 <PPS_SIMPLE> tag at position 80 DataType=FLOAT x8
643<PPS_ENDOBJECT> tag at position 89 ObjectId= 10
644<PPS_OBJECT> tag at position 92 ClassId= e670300b367585d1 ObjectId= 21
645 <PPS_SIMPLE_ARRAY4> tag at position a3 DataType=UNSIGNED x8 NElts= 3
646 <PPS_SIMPLE_ARRAY4> tag at position c0 DataType=INTEGER x4 NElts= 50
647<PPS_ENDOBJECT> tag at position 18d ObjectId= 21
648<PPS_REFERENCE> tag at position 196 ObjectId= 21 OrigPos=92
649<PPS_NAMETAG_MARK> tag at position 1a7
650<PPS_OBJECT> tag at position 1a8 ClassId= eb6c427a5a30caed ObjectId= 30
651 <PPS_SIMPLE_ARRAY4> tag at position 1b9 DataType=UNSIGNED x4 NElts= 6
652 <PPS_SIMPLE> tag at position 1d6 DataType=UNSIGNED x8
653 <PPS_SIMPLE> tag at position 1df DataType=UNSIGNED x8
654 <PPS_OBJECT> tag at position 1e8 ClassId= 6531a8f47336d4aa ObjectId= 41
655 <PPS_SIMPLE_ARRAY4> tag at position 1f9 DataType=UNSIGNED x8 NElts= 3
656 <PPS_SIMPLE_ARRAY4> tag at position 216 DataType=FLOAT x8 NElts= 1024
657 <PPS_ENDOBJECT> tag at position 221b ObjectId= 41
658<PPS_ENDOBJECT> tag at position 2224 ObjectId= 30
659<PPS_NAMETAG_TABLE> tag at position 222d
660<PPS_NAMETAG_ENTRY> NameTag=rg-randgen NameTagMark Position=1a7
661<PPS_NAMETAG_ENTRY> NameTag=ts-timestamp NameTagMark Position=60
662<PPS_EOF> tag at position 22b3 TagPos=222d
663 PPFBinaryInputStream::AnalyseTags() - End - Total Number of Tags= 23
664 ----------------------------------------------------------
665\end{verbatim}
666} % fin de small
667
668\subsubsection{Writing PPF handlers}
669Here are some guidelines for creating PPF handler classes to make
670a class persistent through the SOPHYA PPersist mechanism. The example
671discussed here can be found in the {\bf Examples} module, in the directory
672{\bf MyPPF}.
673\begin{enumerate}
674\item The class should inherit from the {\bf SOPHYA::AnyDataObj} class.
675 In the example here, we want to make the class {\bf Vfs} persistent
676\begin{verbatim}
677class Vfs : public SOPHYA::AnyDataObj {
678 ...
679}
680\end{verbatim}
681%%%%
682\item The PPF handler class
683should inherit from {\bf SOPHYA::PPersist} . The pure virtual methods
684of PPersist class (DataObj() , SetDataObj() , ReadSelf(), WriteSelf()
685must be implemented.
686\begin{verbatim}
687class PPFHandlerVfs : public SOPHYA::PPersist {
688public:
689 virtual SOPHYA::AnyDataObj* DataObj();
690 virtual void SetDataObj(SOPHYA::AnyDataObj &);
691protected:
692 virtual void ReadSelf(SOPHYA::PInPersist&);
693 virtual void WriteSelf(SOPHYA::POutPersist&) const;
694}
695\end{verbatim}
696%%%
697It is possible to use the template class {\tt SOPHYA::ObjFileIO<T>}, and
698specialize it for the tharget class (here {\tt SOPHYA::ObjFileIO<Vfs>}),
699by defining the two methods : \\
700\hspace*{5mm} {\tt SOPHYA::ObjFileIO<Vfs>::ReadSelf(SOPHYA::PInPersist\&) } \\
701\hspace*{5mm} {\tt SOPHYA::ObjFileIO<Vfs>::WriteSelf(SOPHYA::POutPersist\&) const }
702%%%%
703\item If it is NOT possible to have the target class inherit from {\bf AnyDataObj},
704a wrapper class should be used. The same class can play the role of wrapper
705AND the PPF handler. See the PPF handler / wrapper class for STL vectors : \\
706\hspace*{5mm} {\tt SOPHYA::PPFWrapperSTLVector<T>} in file BaseTools/ppfwrapstlv.h
707%%%
708\item Implement the ReadSelf() and WriteSelf() methods of the PPF handler.
709All the I/O services from the following classes can be used :
710\begin{itemize}
711\item PPFBinaryIOStrem , PPFBinaryInputStream , PInPersist
712\item PPFBinaryIOStrem , PPFBinaryOutputStream , POutPersist
713\end{itemize}
714Writing and reading of the embeded objects for which a handler has been register
715ed can simply be performed by : \\
716\hspace*{5mm} {\tt POutPersist::PutObject() } \\
717\hspace*{5mm} {\tt PInPersist::GetObject() }
718
719{\bf Warning:} The services associated with nametags : \\
720\hspace*{5mm} {\tt PPFBinaryOutputStream::WriteNameTag() } \\
721\hspace*{5mm} {\tt PPFBinaryInputStream::GotoNameTag() } \\
722are {\bf NOT} intented to be used in WriteSelf() , ReadSelf()
723%%%%%
724\item The new PPF handler, as well as the list of classes it can handle has to be
725registered prior to use PPF read/write for the target classes. This must be
726performed during the initialization phase, for example at the beginning of the
727main() program. Another possibility is to use a module initializer
728(See {\bf SophyaInitiator} class in file BaseTools/sophyainit.h )
729and declare a static instance of the class. Notice that this works only if
730the system loader handles correcly the call of constructor
731for the statically declared objects.
732
733The registration can be performed using the CPP macros defined in
734BaseTools/ppersist.h
735\begin{verbatim}
736 // First, register the PPF handler ObjFileIO<Vfs>
737 PPRegister(ObjFileIO<Vfs>);
738 // Register the list of classes which can be handled by ObjFileIO<Vfs>
739 DObjRegister(ObjFileIO<Vfs>, Vfs);
740\end{verbatim}
741%%%%%%%%%%%%%%%%
742\end{enumerate}
743
744%%%%%%%%%%%%
[1360]745\subsection{\tcls{NDataBlock}}
[1362]746\index{\tcls{NDataBlock}}
747\begin{figure}[hbt]
748\dclsbb{AnyDataObj}{\tcls{NDataBlock}}
749\dclsbb{PPersist}{\tcls{FIO\_NDataBlock}}
750\end{figure}
[1360]751The {\bf \tcls{NDataBlock}} is designed to handle reference counting
752and sharing of memory blocs (contiguous arrays) for numerical data
753types. Initialisation, resizing, basic arithmetic operations, as
754well as persistence handling services are provided.
755The persistence handler class ({\tt \tcls{FIO\_NDataBlock}}) insures
756that a single copy of data is written for multiply referenced objects,
757and the data is shared among objects when reading.
758\par
759The example below shows writing of NDataBlock objects through the
760use of overloaded operator $ << $ :
[1340]761\begin{verbatim}
762#include "fiondblock.h"
763// ...
764POutPersist pos("aa.ppf");
765NDataBlock<r_4> rdb(40);
766rdb = 567.89;
767pos << rdb;
768// We can also use the PutObject method
769NDataBlock<int_4> idb(20);
770idb = 123;
771pos.PutObject(idb);
772\end{verbatim}
773The following sample programs show the reading of the created PPF file :
774\begin{verbatim}
775PInPersist pis("aa.ppf");
776NDataBlock<r_4> rdb;
777pis >> rdb;
778cout << rdb;
779NDataBlock<int_4> idb;
780cout << idb;
781\end{verbatim}
[1299]782
[2996]783\subsection{DVList, MuTyV and TimeStamp classes}
784\index{DVList} \index{MuTyV} \index{TimeStamp}
[1362]785\begin{figure}[hbt]
[2996]786\dclsa{MuTyV}
[1362]787\dclsbb{AnyDataObj}{DVList}
788\dclsbb{PPersist}{\tclsc{ObjFileIO}{DVList}}
789\end{figure}
790The {\bf DVList} class objects can be used to create and manage list
791of values, associated with names. A list of pairs of (MuTyV, name(string))
792is maintained by DVList objects. {\bf MuTyV} is a simple class
793capable of holding string, integer, float or complex values,
794providing easy conversion methods between these objects.
[2996]795{\bf MuTyV} objects can also hold {\bf TimeStamp } objects.
[1362]796\begin{verbatim}
797// Using MuTyV objects
798MuTyV s("hello"); // string type value
799MuTyV x;
[1435]800x = "3.14159626"; // string type value, ASCII representation for Pi
[1362]801double d = x; // x converted to double = 3.141596
802x = 314; // x contains the integer value = 314
803// Using DVList
804DVList dvl;
805dvl("Pi") = 3.14159626; // float value, named Pi
806dvl("Log2") = 0.30102999; // float value, named Log2
807dvl("FileName") = "myfile.fits"; // string value, named myfile.fits
808// Printing DVList object
809cout << dvl;
810\end{verbatim}
811
[2996]812\begin{figure}[hbt]
813\dclsbb{AnyDataObj}{TimeStamp}
814\end{figure}
815%
816The {\bf TimeStamp} class represent date and time and provides
817many standard operations, such as Initialisation from strings,
818conversion to strings and time interval computations. \\
819Usage example:
820\begin{verbatim}
821// Create a object with the current date and time and prints it to cout
822TimeStamp ts;
823cout << ts << endl;
824// Create an object with a specified date and time
825TimeStamp ts2("01/01/1905","00:00:00");
826// Get the number of days since 0 Jan 1901
827cout << ts2.ToDays() << endl;
828
829// Combined use of TimeStamp and MuTyV
830string s;
831TimeStamp ts; // Current date/time
832MuTyV mvt = ts;
833s = mvt; // s contains the current date in string format
834cout << s << endl;
835\end{verbatim}
836
[2790]837\subsection{\tcls{SegDataBlock} , \tcls{SwSegDataBlock}}
[3037]838\index{\tcls{SegDataBlock}} \index{\tcls{SwSegDataBlock}}
839%%
[2790]840\begin{figure}[hbt]
841\dclsccc{AnyDataObj}{\tcls{SegDBInterface}}{ \tcls{SegDataBlock} }
842\dclscc{\tcls{SegDBInterface}}{ \tcls{SwSegDataBlock} }
843\end{figure}
844\begin{itemize}
[3415]845\item[\rond] \tcls{SegDataBlock} handles arrays of object of
[2790]846type {\bf T} with reference sharing in memory. The array can be extended
847(increase in array size) with fixed segment size. It implements the interface
[2996]848defined by \tcls{SegDBInterface}.
[3415]849\item[\rond] \tcls{SwSegDataBlock} Implements the same \tcls{SegDBInterface}
[2996]850using a data swapper object. Data swappers implement the interface defined in
851(\tcls{DataSwapperInterface} class. \tcls{SwSegDataBlock} can
852thus be used to handle arrays with very large number of objects.
853These classes handles reference sharing.
[2790]854\end{itemize}
855
[3839]856 \subsection{Pseudo-random number generators}
[3856]857 \index{Random numbers} \label{randgen}
[3723]858\begin{figure}[hbt]
859\dclsbb{ AnyDataObj }{ RandomGeneratorInterface }
860\vspace*{5mm}
861\dclsccc{RandomGeneratorInterface}{DR48RandGen}{ ThSDR48RandGen }
862\dclsbb{ RandomGeneratorInterface }{ FMTRandGen }
863\end{figure}
[3839]864The {\bf RandomGeneratorInterface } is a pure virtual class which
865defines the interface for random number generator classes and implements the
866generation algorithm for few probability distribution functions:
867flat, Gaussian, Poisson, Exponential, 2D gaussian \ldots. The pure virtual method
868{\tt Next() } should be implemented by inheriting classes.
869 \index{RandomGeneratorInterface}
870
871Several implementations using different pseud-random generators are provided by SOPHYA:
872\begin{enumerate}
873\item {\bf DR48RandGen} uses the well known {\tt drand48() } pseudo-random
874sequence generator. It implements also the possibility of initializing the generator state, as well saving and
875restoring the generator state through the SOPHYA PPF mechanism. The {\tt drand48() } and thus
876{\bf DR48RandGen} objects are not NOT thread safe. Different instances of {\bf DR48RandGen} share
877the same underlying 48 bit state.
878\item {\bf ThSDR48RandGen} is a thread safe version of DR48RandGen. Using the constructor flag, in can
879be instanciated to reproduce the non thread-safe behaviour of DR48RandGen.
880Several instances of this class can be used in different threads without the risk of
881corrupting the internal state of the drand48() generator. However, in multi-thread applications,
882 there is no guarantee to obtain the same sequence of numbers in each thread.
883\index{ ThSDR48RandGen}
884\item {\bf FMTRandGen } ids an implementation of RandomGeneratorInterface using
885the SIMD-oriented Fast Mersenne Twister (SFMT). It uses the code developed by
886Mutsuo Saito and Makoto Matsumoto from Hiroshima University. For more information on this
887method, refer to \\
888\href{http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html}
889{ttp://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html} \\
890The instances of FMTRandGen are thread safe, each instance having its own internal state
891and produces an independent sequence of random numbers.
892\index{FMTRandGen }
893\end{enumerate}
894
895A number of c-like functions are defined in the file BaseTools/srandgen.h and can be used
896to generate random sequences: \\
897{\tt drand01() , drandpm1() , GaussianRand() , PoissonRand \ldots} \\
898These functions use a global instance of RandomGeneratorInterface class which can be
899defined and accessed through the static methods:\\
900\hspace*{5mm} { \tt RandomGeneratorInterface* RandomGeneratorInterface::GetGlobalRandGenP() } \\
901\hspace*{5mm} { \tt void SetGlobalRandGenP(RandomGeneratorInterface* rgp) } \\
902
903In multi-threaded programs, an instance of ThSDR48RandGen or FMTRandGen
904should be created in each thread running in parallel and needing to generate random sequences.
905All the three classes discussed here implement the automatic initialization method defined
906{\tt (AutoInit() ) } defined in the interface class and implement a number of other initialization
907methods {\tt (SetSeed() )}. SOPHYA provides also PPF handlers for these classes
908which can be used to save the complete state of the object and the underlying generator to PPF files.
909The generator object state can be restored subsequently from the PPF file. This feature can be used
910to generate very long sequence of random numbers, distributed over several runs.
911The example below illustrates the use of the generator classes and state save/restore
912through PPF files:
913\begin{enumerate}
914\item We create and use a {\bf ThSDR48RandGen} object in a first program. Its sate is saved
915to the PPF file rg.ppf at some point in the program.
[3419]916\begin{verbatim}
[3839]917// ------ program A
918// A.1- Create a thread safe generator based on drand48()
919ThSDR48RandGen rg;
920// A.2- Auto initilize its state (using the system time)
921rg.AutoInit();
922// A.3- compute and print a smal sequence of random numbers
923int N = 10;
924for(int i=0; i<N; i++)
925 cout << " I=" << i << " rand_flat01= " << rg.Flat01()
926 << " rand.gaussian= " << rg.Gaussian() << endl;
927// A.4- Save the generator state for subsequent use
[3419]928POutPersist po("rg.ppf");
[3839]929po << rg;
930// A.5- compute and print a second sequence of random numbers
931for(int i=0; i<N; i++)
932 cout << "++ I=" << i+N << " rand_flat01= " << rg.Flat01()
933 << " rand.gaussian= " << rg.Gaussian() << endl;
[3419]934\end{verbatim}
935
[3839]936\item The pseudo-random generator object state is restored in a second program from the previously created
937PPF file, before being used :
938 \begin{verbatim}
939// ------ program B
940// B.1- Create and initialize the generator from the previously saved state
941ThSDR48RandGen rgr;
942PInPersist pin("rg.ppf");
943pin >> rgr;
944int N = 10;
945// B.2- Compute and print a sequence of random number,
[3856]946// should be compared to the sequence A.5
[3839]947for(int i=0; i<N; i++)
948 cout << "-- I=" << i << " rand_flat01= " << rgr.Flat01()
949 << " rand.gaussian= " << rgr.Gaussian() << endl;
950\end{verbatim}
951\end{enumerate}
952
[3419]953%%%%%%%%%%%%
[1435]954\newpage
[1299]955\section{Module TArray}
[1362]956\index{\tcls{TArray}}
[1299]957{\bf TArray} module contains template classes for handling standard
958operations on numerical arrays. Using the class {\tt \tcls{TArray} },
959it is possible to create and manipulate up to 5-dimension numerical
[1362]960arrays {\tt (int, float, double, complex, \ldots)}. The include
961file {\tt array.h} declares all the classes and definitions
[1435]962in module TArray. {\bf Array} is a typedef for arrays
[1411]963with double precision floating value elements. \\
964{\tt typedef TArray$<$r\_8$>$ Array ; }
[1299]965
966\begin{figure}[hbt]
967\dclsccc{AnyDataObj}{BaseArray}{\tcls{TArray}}
[1362]968\dclsbb{PPersist}{\tcls{FIO\_TArray}}
[1299]969\end{figure}
970
[2919]971The development of this module started around 1999-2000,
972after evaluation of a number of publicly available
973C++ array hadling packages, including TNT, Lapack++, Blitz++,
974as well as commercial packages from RogueWave (math.h++ \ldots).
975Most of these packages provide interesting functionalities, however,
976not any one package seemed to fulfill most of our requirements.
977\begin{itemize}
978\item Capability to handle {\bf large - multidimensional - dense}
979arrays, for numerical data types. Although we have used templates, for
[3856]980data type specialisation, the actual code, apart from inline functions is
981not in the header files. Instead, we use explicit instanciation, and the
[2919]982compiled code for the various numerical types of arrays is the
983library .
984\item The shape and size of the arrays can be defined and changed
985at run time. The classes ensure the memory management of the
986created objets, with reference sharing for the array data.
987The default behaviour of the copy constructor is to share the data,
988avoiding expensive memory copies.
989\item The package provides transparent management of sub-arrays
990and slices, in an intuitive way, somehow similar to what is
991available in Mathlab or Scilab.
992\item The memory organisation for arrays, specially matrices
993(row-major or column major) can be
994controled. This provide compatibility when using existing C or
995Fortran coded numerical libraries.
996\item The classes provide efficient methods to perform basic arithmetic
997and mathematical operations on arrays. In addition, operator overload
998provides intuitive programming for element acces and most basic
999arithmetic operations.
1000\item Conversion can be performed between arrays with different
1001data types. Copy and arithmetic operations can be done transparently
1002between arrays with different memory organisation patterns.
1003\item This module does not provide more complex operations
1004such as FFT or linear algebra. Additional libraries are used, with interface
1005classes for these operations.
1006\item ASCII formatted I/O, for printing and read/write operations to/from text files.
1007\item Efficient binary I/O for object persistence (PPF format), or import/export
1008to other data formats, such as FITS are provided by helper or handler classes.
1009\end{itemize}
[1360]1010
[1299]1011\subsection{Using arrays}
[1362]1012\index{Sequence} \index{RandomSequence} \index{RegularSequence}
1013\index{EnumeratedSequence}
[1435]1014The example below shows basic usage of arrays, creation, initialisation
[1362]1015and arithmetic operations. Different kind of {\bf Sequence} objects
[1435]1016can be used for initialising arrays.
[1411]1017
[1362]1018\begin{figure}[hbt]
1019\dclsbb{Sequence}{RandomSequence}
1020\dclsb{RegularSequence}
1021\dclsb{EnumeratedSequence}
1022\end{figure}
[1299]1023
[1340]1024The example below shows basic usage of arrays:
[1414]1025\index{\tcls{TArray}}
[1340]1026\begin{verbatim}
[1435]1027// Creating and initialising a 1-D array of integers
[1362]1028TArray<int> ia(5);
1029EnumeratedSequence es;
1030es = 24, 35, 46, 57, 68;
1031ia = es;
1032cout << "Array<int> ia = " << ia;
1033// 2-D array of floats
1034TArray<r_4> b(6,4), c(6,4);
1035// Initializing b with a constant
1036b = 2.71828;
1037// Filling c with random numbers
1038c = RandomSequence();
1039// Arithmetic operations
1040TArray<r_4> d = b+0.3f*c;
1041cout << "Array<float> d = " << d;
[1340]1042\end{verbatim}
1043
[1362]1044The copy constructor shares the array data, while the assignment operator
1045copies the array elements, as illustrated in the following example:
1046\begin{verbatim}
1047TArray<int> a1(4,3);
1048a1 = RegularSequence(0,2);
1049// Array a2 and a1 shares their data
1050TArray<int> a2(a1);
1051// a3 and a1 have the same size and identical elements
1052TArray<int> a3;
1053a3 = a1;
1054// Changing one of the a2 elements
1055a2(1,1,0) = 555;
1056// a1(1,1) is also changed to 555, but not a3(1,1)
1057cout << "Array<int> a1 = " << a1;
1058cout << "Array<int> a3 = " << a3;
1059\end{verbatim}
1060
[3037]1061\subsection{Arithmetic operations}
1062The four usual arithmetic operators ({\bf + \, - \, * \, / }) are defined
1063to perform constant addition, subtraction, multiplication and division.
1064The three operators ({\bf + \, - \, / }) between two arrays of the same type
1065are defined to perform element by element addition, subtraction
1066and division. In order to avoid confusion with matrix multiplication,
1067element by element multiplication is defined by overloading the
1068operator {\bf \, \&\& \, }, as shown in the example below:
1069\begin{verbatim}
1070TArray<int_4> a(4,3), b(4,3), c , d, e;
1071a = RegularSequence(1.,1.);
1072b = RegularSequence(10.,10.);
1073cout << a << b ;
1074c = a && b;
1075d = c / a;
1076e = (c / b) - a;
1077cout << c << d << e;
1078\end{verbatim}
1079
[1362]1080\subsection{Matrices and vectors}
1081\index{\tcls{TMatrix}} \index{\tcls{TVector}}
1082\begin{figure}[hbt]
1083\dclsccc{\tcls{TArray}}{\tcls{TMatrix}}{\tcls{TVector}}
1084\end{figure}
1085Vectors and matrices are 2 dimensional arrays. The array size
1086along one dimension is equal 1 for vectors. Column vectors
1087have {\tt NCols() = 1} and row vectors have {\tt NRows() = 1}.
[1411]1088Mathematical expressions involving matrices and vectors can easily
1089be translated into C++ code using {\tt TMatrix} and
1090{\tt TVector} objects. {\bf Matrix} and {\bf Vector} are
1091typedefs for double precision float matrices and vectors.
1092The operator {\bf *} beteween matrices is redefined to
1093perform matrix multiplication. One can then write: \\
1094\begin{verbatim}
1095 // We create a row vector
1096 Vector v(1000, BaseArray::RowVector);
1097 // Initialize values with a random sequence
1098 v = RandomSequence();
1099 // Compute the vector length (norm)
1100 double norm = (v*v.Transpose()).toScalar();
1101 cout << "Norm(v) = " << norm << endl;
1102\end{verbatim}
[1362]1103
[1414]1104This module contains basic array and matrix operations
1105such as the Gauss matrix inversion algorithm
[1411]1106which can be used to solve linear systems, as illustrated by the
1107example below:
[1340]1108\begin{verbatim}
[1411]1109#include "sopemtx.h"
1110// ...
1111// Creation of a random 5x5 matrix
1112Matrix A(5,5);
1113A = RandomSequence(RandomSequence::Flat);
1114Vector X0(5);
1115X0 = RandomSequence(RandomSequence::Gaussian);
1116// Computing B = A*X0
1117Vector B = A*X0;
1118// Solving the system A*X = B
1119Vector X;
1120LinSolve(A, B, X);
1121// Checking the result
1122Vector diff = X-X0;
1123cout << "X-X0= " << diff ;
1124double min,max;
1125diff.MinMax(min, max);
1126cout << " Min(X-X0) = " << min << " Max(X-X0) = " << max << endl;
1127\end{verbatim}
1128
[2919]1129{\bf Warning: } The operations defined in {\tt sopemtx.h}, such as
1130matrix inversion and linear system solver use a basic Gauss pivot
1131algorithm which are not adapted for large matrices ($>\sim 100x100$).
1132The services provided in other modules, such as {\bf LinAlg} should
1133be preferred in such cases.
1134
[3856]1135\subsubsection{TVectors and std::vector}
1136SOPHYA \tcls{TVector} objects can be constructed or filled from \tcls{std::vector} objects.
1137TVector objects can also be converted to std::vector.
1138\begin{verbatim}
1139TVector(const vector<T>& v, short lcv=BaseArray::AutoVectorType);
[3858]1140sa_size_t TVector<T>::FillFr(const vector<T>& v,bool noresize=false);
1141sa_size_t TVector<T>::FillTo(vector<T>& v,bool addtoend=false);
1142vector<T> TVector<T>::ConvertTostdvec()
1143
[3856]1144\end{verbatim}
1145
1146In addition, \tcls{std::vector} objects can be written to, read from PPF streams
1147through the class \tcls{PPFWrapperSTLVector} (file ppfwrapstlv.h). The std::vector
1148PPF handler is currently registered for the following data types: \\
1149\hspace*{5mm} {\tt string, int\_2, uint\_2, int\_4, uint\_4, int\_8, uint\_8 } \\
1150\hspace*{5mm} {\tt r\_4 , r\_8, complex$<$r\_4$>$ , complex$<$r\_8$>$ }
1151
[1411]1152\subsection{Working with sub-arrays and Ranges}
[1414]1153\index{Range}
[1411]1154A powerful mechanism is included in array classes for working with
1155sub-arrays. The class {\bf Range} can be used to specify range of array
1156indexes in any of the array dimensions. Any regularly spaced index
1157range can be specified, using the {\tt start} and {\tt end} index
1158and an optional step (or stride). It is also possible to specify
[2919]1159the {\tt start} index and the number of elements.
1160\begin{itemize}
1161\item {\bf Range::all()} {\tt = Range(Range::firstIndex(), Range::lastIndex())} \\
1162return a Range objects representing all valid indexes along the
1163corresponding axe.
1164\item {\bf Range::first()} {\tt = Range(Range::firstIndex())} \\
1165return a Range object representing the first valid index
1166\item {\bf Range::last()} {\tt = Range(Range::lastIndex())}
1167return a Range object representing the last valid index
1168\item {\bf Range(idx)} represents a single index ({\bf = idx})
1169\item {\bf Range(first, last)} represents the range of indices
[3415]1170{\bf first} $\leq$ index $\leq$ {\bf last}.\\
[2919]1171The static method {\tt Range::lastIndex()} can be used
1172to specify the last valid index.
1173\item {\bf Range(first, last, step)} represents the range of index
1174which is equivalent to \\ {\tt for(index=first; index <= last; index += step) }
1175\item { \bf Range (first, last, size, step) } the general form can be used
1176to specify an index range, using the number of elements.
1177It is possible to specify a range of index, ending with the last valid index.
1178For example \\
1179\hspace*{5mm}
1180{\tt Range(Range::lastIndex(), Range::lastIndex(), 3, 2) } \\
1181defines the index range: \hspace*{5mm} last-4, last-2, last.
1182
[1648]1183\begin{center}
1184\begin{tabular}{ll}
[3034]1185\hline \\
[2919]1186\multicolumn{2}{c}{ {\bf Range} {\tt (start, end, size, step) } } \\[2mm]
[1648]1187\hline \\
[3034]1188{\bf Range} {\tt r(7); } & index range: \hspace{2mm} 7 \\
[2919]1189{\bf Range} {\tt r(3,6); } & index range: \hspace{2mm} 3,4,5,6 \\
[3034]1190{\bf Range} {\tt r(3,7,2); } & index range: \hspace{2mm} 3,5,7 \\
[2919]1191{\bf Range} {\tt r(7,0,3,1); } & index range: \hspace{2mm} 7,8,9 \\
[3034]1192{\bf Range} {\tt r(10,0,5,2); } & index range: \hspace{2mm} 10,12,14,16,18 \\[2mm]
1193\hline
[1648]1194\end{tabular}
1195\end{center}
[2919]1196\end{itemize}
[1648]1197
[2919]1198The method {\tt TArray<T>SubArray(Range ...)} can be used
1199to extract subarrays and slices. The operator {\tt operator() (Range rx, Range ry ...)}
1200is also overloaded for sub-array extraction.
1201For matrices, {\tt TMatrix<T>::Row()} and {\tt TMatrix<T>::Column()}
1202extract selected matrix rows and columns.
1203
1204The example illustrates the sub-array extraction using Range objects:
1205\begin{verbatim}
1206 // Creating and initialising a 2-D (6 x 4) array of integers
1207 TArray<int> iaa(6, 4);
1208 iaa = RegularSequence(1,2);
1209 cout << "Array<int> iaa = \n" << iaa;
1210 // We extract a sub-array - data is shared with iaa
1211 TArray<int> iae = iaa(Range(1, Range::lastIndex(), 3) ,
1212 Range::all(), Range::first() );
1213 cout << "Array<int> iae=subarray(iaa) = \n" << iae;
1214 // Changing iae elements changes corresponding iaa elements
1215 iae = 0;
1216 cout << "Array<int> iae=0 --> iaa = \n" << iaa;
1217
1218\end{verbatim}
1219
[1648]1220In the following example, a simple low-pass filter, on a one
[1411]1221dimensional stream (Vector) has been written using sub-arrays:
1222
1223\begin{verbatim}
[1340]1224// Input Vector containing a noisy periodic signal
1225 Vector in(1024), out(1024);
1226 in = RandomSequence(RandomSequence::Gaussian, 0., 1.);
1227 for(int kk=0; kk<in.Size(); kk++)
1228 in(kk) += 2*sin(kk*0.05);
1229// Compute the output vector by a simple low pass filter
1230 Vector out(1024);
1231 int w = 2;
1232 for(int k=w; k<in.Size()-w; k++)
1233 out(k) = in(Range(k-w, k+w).Sum()/(2.*w+1.);
1234\end{verbatim}
1235
[3839]1236
1237\subsection{Persistence, IO}
[1648]1238Arrays can easily be saved to, or restored from files in different formats.
1239SOPHYA library can handle array I/O to ASCII formatted files, to PPF streams,
1240as well as to files in FITS format.
1241FITS format input/output is provided through the classes in
[3037]1242{\bf FitsIOServer} module. Only arrays with data types
[1648]1243supported by the FITS standard can be handled during
1244I/O operations to and from FITS streams (See the FitsIOServer section
1245for additional details).
1246
1247\subsubsection{PPF streams}
1248
1249SOPHYA persistence (PPF streams) handles reference sharing, and multiply
1250referenced objects are only written once. A hierarchy of arrays and sub-arrays
1251written to a PPF stream is thus completely recovered, when the stream is read.
1252The following example illustrates this point:
1253\begin{verbatim}
1254{
1255// Saving an array with a sub-array into a POutPersist file
1256Matrix A(3,4);
1257A = RegularSequence(10,5);
1258// Create a sub-array of A
1259Matrix AS = A(Range(1,2), Range(2,3));
1260// Save the two arrays to a PPF stream
1261POutPersist pos("aas.ppf");
1262pos << A << AS;
1263}
1264{
1265// Reading arrays from the previously created PPF file aas.ppf
1266PInPersist pis("aas.ppf");
1267Matrix B,BS;
1268pis >> B >> BS;
1269// BS is a sub-array of B, modifying BS changes also B
1270BS(1,1) = 98765.;
1271cout << " B , BS after BS(1,1) = 98765. "
1272 << B << BS << endl;
1273}
1274\end{verbatim}
1275The execution of this sample code creates the file {\tt aas.ppf} and
[2919]1276its output is reproduced here. Notice that the array hierarchy is
[1648]1277recovered. BS is a sub-array of B, and modifying BS changes also
1278the corresponding element in B.
1279\begin{verbatim}
1280 B , BS after BS(1,1) = 98765.
1281
1282--- TMatrix<double>(NRows=3, NCols=4) ND=2 SizeX*Y*...= 4x3 ---
128310 15 20 25
128430 35 40 45
128550 55 60 98765
1286
1287--- TMatrix<double>(NRows=2, NCols=2) ND=2 SizeX*Y*...= 2x2 ---
128840 45
128960 98765
1290\end{verbatim}
1291
[3417]1292{\bf Warning: }
[1648]1293There is a drawback in this behaviour: only a single
1294copy of an array is written to a file, even if the array is modified,
[3417]1295without being resized and written (dumped) again to the same PPF stream.
1296However, this behavior can be changed using the {\tt RenewObjId()} method,
1297as illustrated below.
[1648]1298\begin{verbatim}
1299{
1300POutPersist pos("mca.ppf");
1301TArray<int_4> ia(5,3);
1302ia = 8;
[3419]1303pos << ia; // (1)
[1648]1304ia = 16;
[3419]1305pos << ia; // (2) Only a reference to the previously ia array is written
[1648]1306ia = 32;
[3417]1307ia.RenewObjId(); // We change the object Id
[3419]1308pos << ia; // (3) The complete array is dumped again
[1648]1309}
1310\end{verbatim}
1311
1312Only a single copy of the data is effectively written to the output
[3417]1313PPF file, corresponding to the value 8 for array elements, for the first two
1314write operations. When we
[1648]1315read the three array from the file mca.ppf, the same array elements
[3417]1316are obtained two times (all elements equal to 8), and a different array is obtained
1317the third time
[1648]1318\begin{verbatim}
1319{
1320PInPersist pis("mca.ppf");
1321TArray<int_4> ib;
1322pis >> ib;
1323cout << " First array read from mca.ppf : " << ib;
1324pis >> ib;
1325cout << " Second array read from mca.ppf : " << ib;
1326pis >> ib;
1327cout << " Third array read from mca.ppf : " << ib;
1328}
1329\end{verbatim}
1330
1331\subsubsection{ASCII streams}
1332
1333The {\bf WriteASCII} method can be used to dump an array to an ASCII
1334formatted file, while the {\bf ReadASCII} method can be used to decode
1335ASCII formatted files. Space or tabs are the possible separators.
1336Complex numbers should be specified as a pair of comma separated
1337real and imaginary parts, enclosed in parenthesis.
1338
1339\begin{verbatim}
1340{
1341// Creating array A and writing it to an ASCII file (aaa.txt)
1342Array A(4,6);
1343A = RegularSequence(0.5, 0.2);
1344ofstream ofs("aaa.txt");
1345A.WriteASCII(ofs);
1346}
1347{
1348// Decoding the ASCII file aaa.txt
1349ifstream ifs("aaa.txt");
1350Array B;
1351sa_size_t nr, nc;
1352B.ReadASCII(ifs,nr,nc);
1353cout << " Array B; B.ReadASCII() from file " << endl;
1354cout << B ;
1355}
1356\end{verbatim}
1357
[3417]1358\subsection{Cast without conversion}
1359Data conversion between arrays with different data type is handled transparently,
1360through the copy constructor or the assignment (=) operator . However, in rare cases,
1361one wants to access the same memory locations, without data type conversion.
1362The template functions defined in {\tt arrctcast.h} can be used to access the same
1363memory locations, by arrays with different data types. The SOPHYA/NDataBlock
1364reference sharing mechanism is effective When using these functions.
1365Notice that the array size or stride may change during these cast operations. \\
1366 {\tt arrctcast.h} has been introduced in version V=2.1 (Nov 2007), and has not been
1367 fully tested for non packed arrays.
1368\begin{verbatim}
1369// We define and initialize a real array :
1370TArray<r_4> fa(5);
1371fa = RegularSequence(1.25,0.5);
1372cout << " fa= " << fa;
1373// We construct an integer array from fa, where the floating point values
1374// are converted to integer values
1375TArray<uint_2> ia(fa);
1376cout << " ia= " << ia;
1377cout << " ia (in hex)= " << hex << ia << dec;
1378// We can also access the fa memory locations interpreted as short integers
1379uint_2 ui2;
1380// Note that sfia size is double the fa size
1381TArray<uint_2> sfia = ArrayCast(fa, ui2);
1382cout << " sfia= " << sfia;
1383cout << " sfia (in hex)= " << hex << sfia << dec;
1384\end{verbatim}
1385One of the most useful case of these array type cast without conversion
1386correspond to accessing the real or imaginary part of a complex array.
1387Two specific template functions {\tt SDRealPart()} and {\tt SDImagPart()}
1388are also defined in {\tt arrctcast.h}. Two other functions {\tt ArrCastR2C()}
1389and {\tt ArrCastC2R() } are also defined for real to complex, and
1390complex to real cast.
1391Their usage is shown in the next paragraph on complex arrays.
[1648]1392
1393\subsection{Complex arrays}
1394The {\bf TArray} module provides few functions for manipulating
1395arrays of complex numbers (single and double precision).
1396These functions are declared in {\tt matharr.h}.
1397\begin{itemize}
1398\item[\bul] Creating a complex array through the specification of the
1399real and imaginary parts.
1400\item[\bul] Functions returning arrays corresponding to real and imaginary
1401parts of a complex array: {\tt real(za) , imag(za) }
[3419]1402({\bf Warning:} Note that the these functions create an array and copies
1403the data from the original complex array. They do not provide
1404shared memory access to real and imaginary parts.
1405For shared memory access, use functions {\tt SDRealPart()} and
1406{\tt SDImagPart() } (see below).
[1648]1407\item[\bul] Functions returning arrays corresponding to the module,
1408phase, and module squared of a complex array:
1409 {\tt phase(za) , module(za) , module2(za) }
1410\end{itemize}
1411
1412\begin{verbatim}
1413 TVector<r_4> p_real(10, BaseArray::RowVector);
1414 TVector<r_4> p_imag(10, BaseArray::RowVector);
1415 p_real = RegularSequence(0., 0.5);
1416 p_imag = RegularSequence(0., 0.25);
1417 TVector< complex<r_4> > zvec = ComplexArray(p_real, p_imag);
1418 cout << " :: zvec= " << zvec;
1419 cout << " :: real(zvec) = " << real(zvec) ;
1420 cout << " :::: imag(zvec) = " << imag(zvec) ;
1421 cout << " :::: module2(zvec) = " << module2(zvec) ;
1422 cout << " :::: module(zvec) = " << module(zvec) ;
1423 cout << " :::: phase(zvec) = " << phase(zvec) ;
1424\end{verbatim}
1425
1426The decoding of complex numbers from an ASCII formatted stream
1427is illustrated by the next example. As mentionned already,
1428complex numbers should be specified as a pair of comma separated
1429real and imaginary parts, enclosed in parenthesis.
1430
1431\begin{verbatim}
1432csh> cat zzz.txt
1433(1.,-1) (2., 2.5) -3. 12.
1434-24. (-6.,7.) 14.2 (8.,64.)
1435
1436// Decoding of complex numbers from an ASCII file
1437// Notice that the << operator can be used instead of ReadASCII
1438TArray< complex<r_4> > Z;
1439ifstream ifs("zzz.txt");
1440ifs >> Z;
1441cout << " TArray< complex<r_4> > Z from file zzz.txt " << Z ;
1442\end{verbatim}
1443
[3417]1444\noindent {\bf Shared data access :} It is possible to access a complex array
1445elements (real and imaginary parts) through the template functions defined
[3839]1446in {\tt arrctcast.h} and discussed above. Four specific template functions are
1447defined for shared data access to complex arrays:
1448\begin{itemize}
1449\item {\bf SDRealPart } return a float/double TArray, when applied to an
1450array with complex elements, corresponding the the {\bf real} part of the complex values.
1451\item {\bf SDImagPart } return a float/double TArray, when applied to an
1452array with complex elements, corresponding the the {\bf imaginary} part of the complex values.
1453\item {\bf ArrCastC2R } return a float/double TArray, when applied to an
1454array with complex elements. The data is shared between the two arrays, the real array
1455containing real and imaginary parts as successive elements.
1456\item {\bf ArrCastR2C } return a complex valued TArray, when applied to a float/double array.
1457\end{itemize}
1458The example below shows how to use these functions:
[1648]1459
[3417]1460\begin{verbatim}
1461// We define a complex array
1462TArray< complex<r_4> > za(5);
1463cout << " za= " << za;
1464// And two real arrays, corresponding to the real and imaginary parts
1465TArray<r_4> rza = SDRealPart(za);
1466TArray<r_4> iza = SDImagPart(za);
1467// We initialize the real and imaginary parts of the complex array
1468rza = RegularSequence(10.,2.);
1469iza = RegularSequence(5.,0.75);
1470cout << " rza=..., iza=... ----> za = " << za;
1471// The complex array seen as a real array (double size)
1472TArray<r_4> aza = ArrCastC2R(za);
1473cout << " za --> aza= " << aza;
[3419]1474TArray< complex<r_4> > zb;
1475zb = ArrCastR2C(aza);
1476KeepObj(zb);
[3417]1477\end{verbatim}
1478
[1360]1479\subsection{Memory organisation}
1480{\tt \tcls{TArray} } can handle numerical arrays with various memory
1481organisation, as long as the spacing (steps) along each axis is
1482regular. The five axis are labeled X,Y,Z,T,U. The examples below
1483illustrates the memory location for a 2-dimensional, $N_x=4 \times N_y=3$.
1484The first index is along the X axis and the second index along the Y axis.
1485\begin{verbatim}
[3419]1486 | (0,0) (1,0) (2,0) (3,0) |
1487 | (0,1) (1,1) (2,1) (3,1) |
1488 | (0,2) (1,2) (2,2) (3,2) |
[1360]1489\end{verbatim}
1490In the first case, the array is completely packed
1491($Step_X=1, Step_Y=N_X=4$), with zero offset,
1492while in the second case, $Step_X=2, Step_Y=10, Offset=10$:
1493\begin{verbatim}
1494 | 0 1 2 3 | | 10 12 14 16 |
1495Ex1 | 4 5 6 7 | Ex2 | 20 22 24 26 |
1496 | 8 9 10 11 | | 30 32 34 36 |
1497\end{verbatim}
1498
1499For matrices and vectors, an optional argument ({\tt MemoryMapping})
1500can be used to select the memory mapping, where two basic schemes
1501are available: \\
1502{\tt CMemoryMapping} and {\tt FortranMemoryMapping}. \\
1503In the case where {\tt CMemoryMapping} is used, a given matrix line
1504is packed in memory, while the columns are packed when
1505{\tt FortranMemoryMapping} is used. The first index when addressing
1506the matrix elements (line number index) runs along
1507the Y-axis if {\tt CMemoryMapping} is used, and along the X-axis
1508in the case of {\tt FortranMemoryMapping}.
1509Arithmetic operations between matrices
1510with different memory organisation is allowed as long as
1511the two matrices have the same sizes (Number of rows and columns).
1512The following code example and the corresponding output illustrates
[1414]1513these two memory mappings. The {\tt \tcls{TMatrix}::TransposeSelf() }
1514method changes effectively the matrix memory mapping, which is also
1515the case of {\tt \tcls{TMatrix}::Transpose() } method without argument.
1516
[1360]1517\begin{verbatim}
[3419]1518BaseArray::SetDefaultMemoryMapping(BaseArray::CMemoryMapping);
[1360]1519TArray<r_4> X(4,2);
1520X = RegularSequence(1,1);
1521cout << "Array X= " << X << endl;
[3419]1522TMatrix<r_4> X_C(X, true);
[1360]1523cout << "Matrix X_C (CMemoryMapping) = " << X_C << endl;
[3419]1524TMatrix<r_4> X_F(X_C, true);
1525X_F.TransposeSelf(); // we make it a FortranMemoryMapping matrix
[1360]1526cout << "Matrix X_F (FortranMemoryMapping) = " << X_F << endl;
1527\end{verbatim}
1528This code would produce the following output (X\_F = Transpose(X\_C)) :
1529\begin{verbatim}
1530Array X=
1531--- TArray<f> ND=2 SizeX*Y*...= 4x2 ---
15321, 2, 3, 4
15335, 6, 7, 8
1534
1535Matrix X_C (CMemoryMapping) =
1536--- TMatrix<f>(NRows=2, NCols=4) ND=2 SizeX*Y*...= 4x2 ---
15371, 2, 3, 4
15385, 6, 7, 8
1539
1540Matrix X_F (FortranMemoryMapping) =
1541--- TMatrix<f>(NRows=4, NCols=2) ND=2 SizeX*Y*...= 4x2 ---
15421, 5
15432, 6
15443, 7
15454, 8
1546\end{verbatim}
1547
[3419]1548{\bf Note:} Only the {\tt TMatrix} class is sensitive to the memory organisation. It should also
1549be noted that the first index for a matrix is the row index. For a {\tt TArray} object, the first
1550index correspond always to the X axis. For a matrix in the {\tt CMemoryMapping}, the row
1551index is the Y index of the corresponding array, while for a matrix
1552with {\tt FortranMemoryMapping}, the row index is the X index.
1553\begin{verbatim}
1554# 2D array arr , matrix mx
1555TArray<r_4> arr;
1556...
1557TMatrix<r_4> mx(arr);
1558...
1559### CMemoryMapping :
1560mx( row , col ) -> arr( ix=col, jy= row )
1561### FortranMemoryMapping :
1562mx( row , col ) -> arr( ix=row, jy= col )
1563\end{verbatim}
1564The following code fragment shows the difference between element access
1565index order for the different memory organisation:
1566\begin{verbatim}
1567 TArray<int_4> a(5,3);
1568 a = RegularSequence(10,2);
1569 cout << "Array a = " << a << endl;
1570 TMatrix<r_4> mac(a);
1571 cout << "Matrix mac (CMemoryMapping) = " << mac << endl;
1572 TMatrix<r_4> maf(mac);
1573 maf.TransposeSelf(); // we make it a FortranMemoryMapping matrix
1574 cout << "Matrix maf (FortranMemoryMapping) = " << maf << endl;
1575 // ---- element access
1576 cout << " Array(ix,jy) : a(2,0)= " << a(2,0) << " a(1,2)= " << a(1,2)
1577 << " a(0,2)= " << a(0,2) << endl;
1578 cout << " mac(row,col) : mac(2,0)= " << mac(2,0) << " mac(1,2)= " << mac(1,2)
1579 << " mac(0,2)= " << mac(0,2) << endl;
1580 cout << " maf(row,col) : maf(2,0)= " << maf(2,0) << " maf(1,2)= " << maf(1,2)
1581 << " maf(0,2)= " << maf(0,2) << endl;
1582\end{verbatim}
1583
1584
[3839]1585\subsection{Special Square Matrices (SSQM) }
1586SOPHYA V2.2 introduces new classes for handling special square matrices (diagonal, symmetric, triangular \ldots).
1587The figure below shows the corresponding class hierarchy:
1588\begin{figure}[hbt]
1589\dclsccc{AnyDataObj}{\tcls{SpecialSquareMatrix}}{ \tcls{ DiagonalMatrix } }
1590\dclsc{ \tcls{ LowerTriangularMatrix } }
1591\dclsc{ \tcls{ SymmetricMatrix } }
1592\end{figure}
1593
1594\index{ \tcls{DiagonalMatrix} }
1595\index{ \tcls{SymmetricMatrix} }
1596\index{ \tcls{TriangularMatrix} }
1597
1598Theses classes provides methods similar to TArray/TMatrix objects for manipulating these special kind of matrices.
1599However, no sub-matrix extraction method is provided. The following features are currently implemented:
1600\begin{itemize}
1601\item These classes implements reference sharing and behave in a way similar to TArray objects. The copy
1602constructor shares the data, while the equal operator (=) performs an element by element copy.
1603\item The {\bf FIO\_SpecialSquareMatrix$<$T$>$ } manages the persistence (I/O) in PPF format for these classes.
1604\item Constructor from and conversion to general {\bf TMatrix$<$T$>$ } objects.
1605 Non relevant elements are ignored when constructing from a general matrix and the special square matrix can be
1606converted to the general matrix through the {\tt ConvertToStdMatrix () }.
1607\item Definition of element access operator {\tt mx(r,c) } as well as global assignment operator {\tt mx = a; mxb=mxa; }.
1608operator {\tt mx[k] } can be used to access the non zero element k.
1609\item Addition, subtraction of a constant, multiplication or division by a constant, as well as
1610\item Element by element addition, subtraction, multiplication and division methods between same type of SSQM
1611matrices. As in the cases of general matrices, the four binary operators ( + , - , \&\& , /) are overloaded to perform
1612these operations.
1613\item Matrix multiplication operation between same type SSQM objects or between a general matrix and an SSQM
1614object is defined through the methods: \\
1615{\\ Multiply() , MultiplyXG(), MultiplyGX(), X=D,S,T } \\
1616The binary multiplication operator ( * ) is then overloaded to perform matrix multiplication.
1617\end{itemize}
1618The sample code below illustrates the use of these special matrices:
1619\begin{verbatim}
1620// Create and initialize a diagonal matrix
1621DiagonalMatrix<double> diag(3);
1622diag(0,0)=1.; diag(1,1)=2.; diag(2,2)=3.;
1623// use of multiplication by a constant operator
1624diag *= 10.;
1625// check the diagonal matrix
1626cout << diag << diag.ConvertToStdMatrix() << endl;
1627// define and initialize a general matrix
1628TMatrix<double> mx(3,3);
1629mx=RegularSequence();
1630cout << mx;
1631// check the result of a matrix mutiplication
1632cout << mx*diag;
1633\end{verbatim}
1634
[988]1635\newpage
1636
[1299]1637\section{Module HiStats}
1638\begin{figure}[hbt]
[2996]1639\dclsbb{AnyDataObj}{Histo}
1640\dclscc{Histo}{HProf}
[1299]1641\dclsbb{AnyDataObj}{Histo2D}
[3137]1642\dclsbb{AnyDataObj}{HistoErr}
1643\dclsbb{AnyDataObj}{Histo2DErr}
[1299]1644\caption{partial class diagram for histograms and ntuples}
1645\end{figure}
1646
[1347]1647{\bf HiStats} contains classes for creating, filling, printing and
1648doing various operations on one or two dimensional histograms
1649{\tt Histo} and {\tt Histo2D} as well as profile histograms {\tt HProf}. \\
[3006]1650This module also contains {\tt NTuple} and {\tt DataTable} which are
1651more or less the same as the binary or ascii FITS tables.
[1347]1652
[3006]1653\subsection{Histograms}
1654\subsubsection{1D Histograms}
[1414]1655\index{Histo}
[1347]1656For 1D histograms, various numerical methods are provided such as
1657computing means and sigmas, finding maxima, fitting, rebinning,
1658integrating \dots \\
[1435]1659The example below shows creating and filling a one dimensional histogram
1660of 100 bins from $-5.$ to $+5.$ to create a Gaussian normal distribution
[1347]1661with errors~:
1662\begin{verbatim}
1663#include "histos.h"
1664// ...
1665Histo H(-0.5,0.5,100);
1666H.Errors();
1667for(int i=0;i<25000;i++) {
1668 double x = NorRand();
1669 H.Add(x);
1670}
1671H.Print(80);
1672\end{verbatim}
1673
[3006]1674\subsubsection{2D Histograms}
[1414]1675\index{Histo2D}
[1347]1676Much of these operations are also valid for 2D histograms. 1D projection
1677or slices can be set~:
1678\begin{verbatim}
1679#include "histos2.h"
1680// ...
[1414]1681Histo2D H2(-1.,1.,100,0.,60.,50);
[1347]1682H2.SetProjX(); // create the 1D histo for X projection
1683H2.SetBandX(25.,35.); // create 1D histo projection for 25.<y<35.
1684H2.SetBandX(35.,45.); // create 1D histo projection for 35.<y<45.
1685H2.SetBandX(40.,55.); // create 1D histo projection for 40.<y<55.
1686//... fill H2 with what ever you want
1687H2.Print();
1688Histo *hx = H2.HProjX();
1689 hx->Print(80);
1690Histo *hbx2 = HBandX(1); // Get the second X band (35.<y<45.)
1691 hbx2->Print(80);
1692\end{verbatim}
1693
[3006]1694\subsubsection{Profile Histograms}
[1414]1695\index{HProf}
1696Profiles histograms {\bf HProf} contains the mean and the
1697sigma of the distribution
[1347]1698of the values filled in each bin. The sigma can be changed to
1699the error on the mean. When filled, the profile histogram looks
1700like a 1D histogram and much of the operations that can be done on 1D histo
1701may be applied onto profile histograms.
1702
[3137]1703\subsubsection{Histograms HistoErr and Histo2DErr}
[3061]1704\index{HistoErr}
[3137]1705The {\bf HistoErr} are basic histograms where the number of entries for each bin is kept.
1706Methods to compute of the mean and the variance in each bin are provided.
1707The {\bf Histo2DErr} is the same for $2$ dimensions.
[3061]1708
[1435]1709\subsection{Data tables (tuples)}
[3006]1710\begin{figure}[hbt]
1711\dclsbb{AnyDataObj}{NTuple}
1712\dclsccc{AnyDataObj}{BaseDataTable}{DataTable}
1713\dclscc{BaseDataTable}{SwPPFDataTable}
1714\end{figure}
1715
1716\subsubsection{NTuple}
[1414]1717\index{NTuple}
[3048]1718{\bf NTuple} are memory resident tables of 32 or 64 bits floating values
[2790]1719(float/double).They are arranged in columns. Each line is often called an event.
[1347]1720These objects are frequently used to analyze data.
[3856]1721The piapp interactive analysis tool can be used to create 1D, 2D and 3D plots using the date from
1722NTuples and DataTables. \\
[1347]1723Here is an example of creation and filling~:
1724\begin{verbatim}
1725#include "ntuple.h"
1726#include "srandgen.h"
1727// ...
1728char* nament[4] = {"i","x","y","ey"};
1729r_4 xnt[4];
1730NTuple NT(4,nament);
1731for(i=0;i<5000;i++) {
1732 xnt[0] = i+1;
1733 xnt[1] = 5.*drandpm1(); // a random value between -5 and +5
1734 xnt[2] = 100.*exp(-0.5*xnt[1]*xnt[1]) + 1.;
1735 xnt[3] = sqrt(xnt[2]);
1736 xnt[2] += xnt[3] * NorRand(); // add a random gaussian error
1737 NT.Fill(xnt);
1738}
1739\end{verbatim}
1740
[3048]1741{\bf XNTuple} provide additional functionalities, compared to NTuple. However,
1742this class is deprecated and superseded by classes inheriting from BaseDataTable.
1743It is only kept for backward compatibility and should not be used anymore.
1744Use DataTable and SwPPFDataTable instead.
[2790]1745Object of type XNTuple handle various types
[1414]1746of column values (double,float,int,string,...) and can handle
1747very large data sets, through swap space on disk.
[2790]1748
[3006]1749\subsubsection{DataTables}
[3034]1750\label{datatables}
[2790]1751\index{DataTable}
1752The class {\bf DataTable} extends significantly the functionalities provided by
1753NTuple. DataTable is a memory resident implementation of the interface
1754{\bf BaseDataTable } which organizes the data as a 2-D table. User can define
1755the name and data type of each column. Data is added to the table as rows.
1756The table is extended as necessary when adding rows.
1757The sample code below shows an example of DataTable usage :
[1414]1758\begin{verbatim}
[2790]1759 #include "datatable.h"
1760 // ...
[3037]1761 {
[2790]1762 DataTable dt(64);
1763 dt.AddFloatColumn("X0_f");
1764 dt.AddFloatColumn("X1_f");
1765 dt.AddDoubleColumn("X0X0pX1X1_d");
1766 double x[5];
1767 for(int i=0; i<63; i++) {
1768 x[0] = (i/9)-4.; x[1] = (i/9)-3.; x[2] = x[0]*x[0]+x[1]*x[1];
1769 dt.AddLine(x);
1770 }
1771 // Printing table info
1772 cout << dt ;
1773 // Saving object into a PPF file
1774 POutPersist po("dtable.ppf");
1775 po << dt ;
[3037]1776 }
[1414]1777\end{verbatim}
[1347]1778
[2790]1779
1780\index{SwPPFDataTable}
1781The class {\bf SwPPFDataTable} implements the BaseDataTable interface
1782using segmented data blocks with swap on PPF streams. Very large data sets
[3048]1783can be created and manipulated through this class. A similar class
1784SwFitsDataTable (\ref{SwFitsDataTable}), using
1785FITS files as swap space is also provided in the FitsIOServer module.
[2790]1786
[3006]1787\index{DataTableRow}
1788The class {\bf DataTableRow } is an auxiliary class which simplifies the manipulation
1789of BaseDataTable object rows.
[3034]1790The example below show how to create and filling a table, using a PPF stream as
1791swap space. In addition, we have used a {\tt DataTableRow} to prepare data
1792for each table line.
[3006]1793\begin{verbatim}
[3034]1794 #include "swppfdtable.h"
[3006]1795 // ...
[3034]1796 {
1797 // ---------- Create an output PPF stream (file)
1798 POutPersist po("swdtable.ppf");
1799 // ------------------
1800 // Create a table with 3 columns, using the above stream as swap space
1801 SwPPFDataTable dtrow(po, 64);
[3006]1802 dtrow.AddStringColumn("sline");
1803 dtrow.AddIntegerColumn("line");
[3034]1804 dtrow.AddDateTimeColumn("datime");
1805 //
[3006]1806 TimeStamp ts, ts2; // Initialize current date and time
1807 string sline;
[3034]1808 //---- Create a table row with the required structure
[3006]1809 DataTableRow row = dtrow.EmptyRow();
[3034]1810 // ----- Fill the table
1811 for(int k = 0; k<2500; k++) {
[3006]1812 sline = "L-";
1813 sline += (string)MuTyV(k);
1814 row["sline"] = sline;
1815 row[1] = k;
1816 ts2.Set(ts.ToDays()+(double)k);
1817 row["datime"] = ts2;
1818 dtrow.AddRow(row);
1819 }
[3034]1820 //------ Write the table itself to the stream, before closing the file
1821 po << PPFNameTag("SwTable") << dtrow;
1822 }
[3006]1823\end{verbatim}
[3034]1824%%
1825The previously created table can easily be read in, as shown below:
1826%%
1827\begin{verbatim}
1828 #include "swppfdtable.h"
1829 // ...
1830 {
1831 // ------ Create the input PPF stream (file)
1832 PInPersist pin("swdtable.ppf");
1833 // ------ Read in the SwPPFDataTable object
1834 SwPPFDataTable dtr;
1835 pin >> PPFNameTag("SwTable") >> dtr;
1836 // ---- Create a table row with the required structure
1837 DataTableRow row = dtr.EmptyRow();
1838 // ---- Acces and print two of the table rows :
1839 cout << dtr.GetRow(6, row) << endl;
1840 cout << dtr.GetRow(17, row) << endl;
1841 }
1842\end{verbatim}
1843
[3856]1844\subsection{Persistence and visualisation }
[3419]1845%%
1846Histogram and NTuple/DataTable objects have PPF handlers and
[3856]1847can be written to or read from PPF files. Sophya interactive analysis tool
1848(spiapp) can automatically display and operate on all of these objects.
[1347]1849The following example shows how to write the previously created objects
1850into such a file~:
1851\begin{verbatim}
1852{
1853char *fileout = "myfile.ppf";
1854string tag;
1855POutPersist outppf(fileout);
1856tag = "H"; outppf.PutObject(H,tag);
1857tag = "H2"; outppf.PutObject(H2,tag);
1858tag = "NT"; outppf.PutObject(NT,tag);
1859} // closing ``}'' destroy ``outppf'' and automatically close the file !
1860\end{verbatim}
1861
[1414]1862\newpage
[1299]1863\section{Module NTools}
1864
[1347]1865This module provides elementary numerical tools for numerical integration,
1866fitting, sorting and ODE solving. FFTs are also provided (Mayer,FFTPack).
1867
[3856]1868\subsection{Optimisation and parameter fitting}
1869\subsubsection{GeneralFit: non linear fitting}
[1435]1870\index{Fitting} \index{Minimisation}
[1347]1871Fitting is done with two classes {\tt GeneralFit} and {\tt GeneralFitData}
1872and is based on the Levenberg-Marquardt method.
[1414]1873\index{GeneralFit} \index{GeneralFitData}
[1347]1874GeneralFitData is a class which provide a description of the data
1875to be fitted. GeneralFit is the fitter class. Parametrized functions
1876can be given as classes which inherit {\tt GeneralFunction}
1877or as simple C functions. Classes of pre-defined functions are provided
1878(see files fct1dfit.h and fct2dfit.h). The user interface is very close
1879from that of the CERN {\tt Minuit} fitter.
1880Number of objects (Histo, HProf \dots ) are interfaced with GeneralFit
1881and can be easily fitted. \\
1882Here is a very simple example for fitting the previously created NTuple
[1435]1883with a Gaussian~:
[1347]1884\begin{verbatim}
1885#include "fct1dfit.h"
1886// ...
1887
1888// Read from ppf file
1889NTuple nt;
1890{
1891PInPersist pis("myfile.ppf");
1892string tag = "NT"; pis.GetObject(nt,tag);
1893}
1894
1895// Fill GeneralData
1896GeneralData mGdata(nt.NEntry());
1897for(int i=0; i<nt.NEntry(); i++)
1898 mGdata.AddData1(xnt[1],xnt[2],xnt[3]); // Fill x, y and error on y
1899mGData.PrintStatus();
1900
1901// Function for fitting : y = f(x) + noise
1902Gauss1DPol mFunction; // gaussian + constant
1903
1904// Prepare for fit
1905GeneralFit mFit(&mFunction); // create a fitter for the choosen function
1906mFit.SetData(&mGData); // connect data to the fitter
1907
[1435]1908// Set and initialise the parameters (that's non-linear fitting!)
[1347]1909// (num par, name, guess start, step, [limits min and max])
1910mFit.SetParam(0,"high",90.,1..);
1911mFit.SetParam(1,"xcenter",0.05,0.01);
1912mFit.SetParam(2,"sigma",sig,0.05,0.01,10.);
1913 // Give limits to avoid division by zero
1914mFit.SetParam(3,"constant",0.,1.);
1915
1916// Fit and print result
1917int rcfit = mFit.Fit();
1918mFit.PrintFit();
1919if(rcfit>0) {)
1920 cout<<"Reduce_Chisquare = "<<mFit.GetChi2Red()
1921 <<" nstep="<<mFit.GetNStep()<<" rc="<<rcfit<<endl;
1922} else {
1923 cout<<"Fit_Error, rc = "<<rcfit<<" nstep="<<mFit.GetNStep()<<endl;
1924 mFit.PrintFitErr(rcfit);
1925}
1926
1927// Get the result for further use
1928TVector<r_8> ParResult = mFit.GetParm();
1929cout<<ParResult;
1930\end{verbatim}
1931
1932Much more usefull possibilities and detailed informations might be found
1933in the HTML pages of the Sophya manual.
1934
[3856]1935\subsubsection{Simplex method}
[3438]1936The class {\bf MinZSimplex} implements the simplex method for non linear
[3856]1937optimization / minimization. See the SOPHYA reference manual and the
1938Tests/tsimplex.cc for more information.
[3438]1939
[3856]1940\subsection{Interpolation}
1941\index{Interpolation} \index{SLinInterp1D}
1942The class {\bf SLinInterp1D} (file slininterp.h) can be used for linear 1D interpolation.
1943\begin{verbatim}
1944#include "slininterp.h"
1945#include "srandgen.h"
1946 ...
1947vector<double> ys;
1948double xmin = 0.5;
1949double xmax = 0.;
1950for(int i=0; i<=12; i++) {
1951 xmax = xmin+i*0.1;
1952 yreg.push_back(sin(xmax)*cos(2.2*xmax));
1953}
1954SLinInterp1D interpYR(xmin, xmax, yreg);
1955cout << interpYR
1956for(int i=0; i<=12; i++) {
1957 double x = drand01()*2.;
1958 cout << " Interpol result for X=" << x << " -> " << interpYR(x)
1959 << " ?= " << sin(x)*cos(2.2*x) << endl;
1960}
1961\end{verbatim}
1962The {\bf CSpline} and {\bf CSpline2} classes perform one dimensional and two dimensional spline interpolation.
1963
[1350]1964\subsection{Polynomial}
[1414]1965\index{Polynomial} \index{Poly} \index{Poly2}
[1350]1966Polynomials of 1 or 2 variables are supported ({\tt Poly} and {\tt Poly2}).
1967Various operations are supported~:
1968\begin{itemize}
1969\item elementary operations between polynomials $(+,-,*,/) $
1970\item setting or getting coefficients
1971\item computing the value of the polynomial for a given value
1972 of the variable(s),
1973\item derivating
1974\item computing roots (degre 1 or 2)
1975\item fitting the polynomial to vectors of data.
1976\end{itemize}
1977Here is an example of polynomial fitting~:
1978\begin{verbatim}
1979#include "poly.h"
1980// ...
1981Poly pol(2);
1982pol[0] = 100.; pol[1] = 0.; pol[2] = 0.01; // Setting coefficients
1983TVector<r_8> x(100);
1984TVector<r_8> y(100);
1985TVector<r_8> ey(100);
1986for(int i=0;i<100;i++) {
1987 x(i) = i;
1988 ey(i) = 10.;
1989 y(i) = pol((double) i) + ey(i)*NorRand();
1990 ey(i) *= ey(i)
1991}
1992
1993TVector<r_8> errcoef;
1994Poly polfit;
1995polfit.Fit(x,y,ey,2,errcoef);
1996
1997cout<<"Fit Result"<<polfit<<endl;
1998cout<<"Errors :"<<errcoef;
1999\end{verbatim}
2000
2001Similar operations can be done on polynomials with 2 variables.
2002
[1435]2003\subsection{Integration, Differential equations}
2004\index{Integration}
2005The NTools module provide also simple classes for numerical integration
2006of functions and differential equations.
2007\begin{figure}[hbt]
2008\dclsbb{Integrator}{GLInteg}
2009\dclsb{TrpzInteg}
2010\end{figure}
2011
2012\index{GLInteg} \index{TrpzInteg}
2013{\bf GLInteg} implements the integration through Gauss-Legendre method
2014and {\bf TrpzInteg} implements trapeze integration. For {\bf TrpzInteg},
2015number of steps specify the number of trapeze, and integration step,
2016their width.
2017The sample code below illustrates the use of TrpzInteg class:
2018\begin{verbatim}
2019#include "integ.h"
2020// ......................................................
2021// Function to be integrated
2022double myf(double x)
2023{
2024// Simple a x + b x^2 (a=2 b=3)
2025return (x*(2.+3.*x));
2026}
2027// ......................................................
2028
2029// Compute Integral(myf, 2., 5.) between xmin=2., xmax=5.
2030TrpzInteg trpz(myf, 2., 5.);
2031// We specify an integration step
2032trpz.DX(0.01);
2033// The integral can be computed as trpz.Value()
2034double myf_integral = trpz.Value();
2035// We could have used the cast operator :
2036cout << "Integral[myf, 2., 5.]= " << (double)trpz << endl;
2037// Limits can be specified through ValueBetween() method
2038cout << "Integral[myf, 0., 4.]= " << trpz.ValueBetween(0.,4.) << endl;
2039\end{verbatim}
2040
2041\subsection{Fourier transform (FFT)}
2042\index{FFT} \index{FFTPackServer}
2043An abstract interface for performing FFT operations is defined by the
2044{\bf FFTServerInterface} class. The {\bf FFTPackSever} class implements
2045one dimensional FFT, on real and complex data. FFTPackServer uses an
2046adapted and extended version of FFTPack (available from netlib),
2047translated in C, and can operate on single and double precision
2048({\tt float, double}) data.
2049
2050The sample code below illustrates the use of FFTServers:
2051\begin{verbatim}
2052#include "fftpserver.h"
2053 // ...
2054TVector<r_8> in(32);
2055TVector< complex<r_8> > out;
2056in = RandomSequence();
2057FFTPackServer ffts;
2058ffts.setNormalize(true); // To have normalized transforms
2059cout << " FFTServer info string= " << ffts.getInfo() << endl;
2060cout << "in= " << in << endl;
2061cout << " Calling ffts.FFTForward(in, out) : " << endl;
2062ffts.FFTForward(in, out);
2063cout << "out= " << out << endl;
2064\end{verbatim}
2065
[2278]2066% \newpage
2067\section{Module SUtils}
2068Some utility classes and C/C++ string manipulation functions are gathered
2069in {\bf SUtils} module.
2070\subsection{Using DataCards}
2071\index{DataCards}
2072The {\bf DataCards} class can be used to read parameters from a file.
2073Each line in the file starting with \@ defines a set of values
2074associated with a keyword. In the example below, we read the
2075parameters corresponding with the keyword {\tt SIZE} from the
2076file {\tt ex.d}. We suppose that {\tt ex.d} contains the line: \\
2077{\tt @SIZE 400 250} \\
2078\begin{verbatim}
2079#include "datacards.h"
2080// ...
2081// Initialising DataCards object dc from file ex.d
2082DataCards dc( "ex.d" );
2083// Getting the first and second parameters for keyword size
2084// We define a default value 100
2085int size_x = dc.IParam("SIZE", 0, 100);
2086int size_y = dc.IParam("SIZE", 1, 100);
2087cout << " size_x= " << size_x << " size_y= " << size_y << endl;
2088\end{verbatim}
2089
2090\section{Module SysTools}
2091The {\bf SysTools} module contains classes implementing interface to some
[3015]2092OS specific services, such as thread creation and management, dynamic loading and
2093resource usage information. For example, yhe class {\bf Periodic} provides the
2094necessary services needed to implement the execution of a periodic action.
2095
2096\subsection{Resource usage (CPU, memory \ldots) }
2097 The class {\bf ResourceUsage} \index{ResourceUsage}
[3037]2098and {\bf Timer} \index{Timer} provides access to information
[2304]2099about various resource usage (memory, CPU, ...).
[3037]2100The class {\bf Timer} \index{time (CPU, elapsed)} and c-functions
[3015]2101{\tt InitTim() , PrtTim(const char * Comm) } can be used to print
2102the amount of CPU and elapsed time in programs.
[2790]2103
[3015]2104The following sample code illustrates the use of {\bf ResourceUsage} :
2105\begin{verbatim}
2106 // How to check resource usage for a given part of the program
2107 ResourceUsage res;
2108 // --- Part of the program to be checked : Start
2109 // ...
2110 res.Update();
2111 cout << " Memory size increase (KB):" << res.getDeltaMemorySize() << endl;
2112 cout << " Resource usage info : \n" << res << endl;
2113\end{verbatim}
2114
[2790]2115\subsection{Thread management classes}
[3856]2116\index{ZThread} \index{ZMutex} \label{thrcls}
[3037]2117A basic interface to POSIX threads is also provided
[3015]2118through the \index{threads} {\bf ZThread}, {\bf ZMutex} and {\bf ZSync}
2119classes. The best way to use thread management classes is by inheriting
2120from {\bf ZThread} and redefining the {\tt run() } method.
2121It is also possible to use the default {\tt run() } implementation and associate
2122a function to perform the action, as in the example below :
2123\begin{verbatim}
2124 // The functions to perform computing
2125 void fun1(void *arg) { }
2126 void fun2(void *arg) { }
2127 // ...
2128 ZThread zt1;
2129 zt1.setAction(fun1, arg[1]);
2130 ZThread zt2;
[3856]2131 zt2.setAction(fun2, arg[2]);
[3015]2132 cout << " Starting threads ... " << endl;
2133 zt1.start();
2134 zt2.start();
2135 cout << " Waiting for threads to end ... " << endl;
2136 zt1.join();
2137 zt2.join();
2138\end{verbatim}
2139The classes {\bf ZMutex} \index{mutex} and {\bf ZSync} can be used
[3856]2140to perform synchronisation and signaling between threads. Each {\bf ZMutex} object
2141contains a pair of mutex and condition variable.
2142The {\bf ParallelExecutor } class can be used for parallel simultaneous execution
2143of several function of objects inheriting from {\bf ParallelTaskInterface}.
2144Some hints about parallel programming and usage of these classes can be found in
2145\index{ParallelExecutor} \index{ ParallelTaskInterface }
2146\ref{mtpsop}.
[3419]2147
[3723]2148\begin{figure}[hbt]
[3856]2149\dclsa{ParallelExecutor}
2150\dclsbb{ParallelTaskInterface}{ParallelTaskFunction}
[3723]2151\dclsbb{ZThread}{ParalExThread}
[3856]2152\dclsa{ZMutex}
[3723]2153\end{figure}
2154
[3856]2155
[2790]2156\subsection{Dynamic linker and C++ compiler classes}
[2278]2157\index{PDynLinkMgr}
2158The class {\bf PDynLinkMgr} can be used for managing shared libraries
2159at run time. The example below shows the run time linking of a function:\\
2160{\tt extern "C" { void myfunc(); } } \\
2161\begin{verbatim}
2162#include "pdlmgr.h"
2163// ...
2164string soname = "mylib.so";
2165string funcname = "myfunc";
2166PDynLinkMgr dyl(soname);
2167DlFunction f = dyl.GetFunction(funcname);
2168if (f != NULL) {
2169// Calling the function
2170 f();
2171}
2172\end{verbatim}
2173
2174\index{CxxCompilerLinker}
[2790]2175The {\bf CxxCompilerLinker} class provides the services to compile C++ code and building
[2278]2176shared libraries, using the same compiler and options which have
2177been used to create the SOPHYA shared library.
2178The sample program below illustrates using this class to build
2179the shared library (myfunc.so) from the source file myfunc.cc :
2180\begin{verbatim}
2181#include "cxxcmplnk.h"
2182// ...
2183string flnm = "myfunc.cc";
2184string oname, soname;
2185int rc;
2186CxxCompilerLinker cxx;
2187// The Compile method provides a default object file name
2188rc = cxx.Compile(flnm, oname);
2189if (rc != 0 ) { // Error when compiling ... }
2190// The BuildSO method provides a default shared object file name
2191rc = cxx.BuildSO(oname, soname);
2192if (rc != 0 ) { // Error when creating shared object ... }
2193\end{verbatim}
2194
[2790]2195\subsection{Command interpreter}
[3419]2196\index{Commander}
2197\index{Expression evaluation}
[2790]2198The class {\bf Commander} can be used in interactive programs to provide
2199c-shell like command interpreter and scripting capabilties.
2200Arithmetic expression evaluation is implemented through the {\bf CExpressionEvaluator}
[3419]2201and {\bf RPNExpressionEvaluator} classes. The latter can be used to perform evaluation
2202in reverse polish notation (old HP calculators),
2203while the former uses the usual algebraic (c-language like) expressions.
[3015]2204The command language provides variable manipulation through the usual
2205{\tt \$varname} vector variable and arithmetic expression extensions, as well
[3856]2206as the control and test blocs. A description of this command interpreter syntax
2207and possibilities can be found in the (s)piapp user's guide.
[3015]2208\begin{verbatim}
2209#include "commander.h"
2210...
2211Commander cmd;
2212char* ss[3] = {"foreach f ( AA bbb CCCC ddddd )", "echo $f" , "end"};
2213for(int k=0; k<3; k++) {
2214 string line = ss[k];
2215 cmd.Interpret(line);
2216}
2217\end{verbatim}
[2790]2218
[1435]2219\newpage
2220\section{Module SkyMap}
2221\begin{figure}[hbt]
2222\dclsbb{AnyDataObj}{PixelMap}
2223\dclsccc{PixelMap}{Sphericalmap}{SphereHEALPix}
2224\dclsc{SphereThetaPhi}
[3006]2225\dclsc{SphereECP}
[1435]2226\dclsb{LocalMap}
[3006]2227\caption{partial class diagram for spherical map classes in Sophya}
[1435]2228\end{figure}
2229The {\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.
[3419]2230\subsection{3D geometry}
2231Some of the classes in this module simplify the angle manipulation, or the 3D geometry
2232and rotation calculations, such as the {\bf Vector3d} and {\bf UnitVector} classes.
2233\index{Vector3d}
2234The classes {\bf Vector3d} and {\bf UnitVector} are useful for angle conversions.
2235\index{Angle}
2236{\bf LongLat} class and {\bf Angle} class (defined in file vector3d.h) can be used for
2237angle conversions :
2238\begin{verbatim}
2239 // Example to convert 0.035 radians to arcsec
2240 double vr = 0.035;
2241 cout << "Angle rad= " << vr << " ->arcsec= " << Angle(vr).ToArcSec() << endl;
2242 // Example to convert 2.3 arcmin to radian - we use the conversion operator
2243 double vam = 2.3;
2244 cout << "Angle arcmin= " << vam << " ->rad= "
2245 << (double)Angle(vam, Angle::ArcMin) << endl;
2246\end{verbatim}
2247%%%
[1435]2248\subsection {Spherical maps}
[3438]2249SkyMap module provides three classes for representing data with pixels distributed over complete ($4 \pi$ steradians) spheres. These classes implements the common interface defined
2250in the base class \tcls{SphericalMap} with three different algorithms or
[3006]2251pixelization scheme.
[3438]2252The spherical maps can be instanciated for the followind data types: \\
2253\hspace*{5mm} int\_4 , r\_4 (float) , r\_8 (double) , complex$<$r\_4$>$ , complex$<$r\_8$>$. \\
2254The SphereHEALPix can in addition be instanciated for T=uint\_2.
[1435]2255
[3438]2256\begin{enumerate}
2257\item \index{\tcls{SphereHEALPix}}
2258{\bf \tcls{SphereHEALPix}} implements the HEALPix
2259({\bf H}ierarchical {\bf E}qual {\bf A}rea iso{\bf L}atitude {\bf Pix}elization) scheme,
2260developped originaly by K. Gorski \& E. Hivon. Refer to
2261\href{http://healpix.jpl.nasa.gov/}{HEALPix home page} for
2262detailed information about this pixelisation scheme and related software
2263\footnote{HEALPix home page: http://healpix.jpl.nasa.gov/ }.
2264FITS read/write for SphereHEALPix objects is handled by the \tcls{FITS\_SphereHEALPix}
2265class in module FitsIOServer.
2266\item \index{\tcls{SphereThetaPhi}}
2267{\bf \tcls{SphereThetaPhi}} represents spheres pixelized following an algorithm
2268developed at LAL-ORSAY, for SOPHYA.
2269The sphere is divided into a number of rings or slices
2270along the parallels, corresponding to different values of the angle $\theta$.
2271Each slice is then divided into a number of pixels, with an aspect ratio close
2272to one (square pixels). Pixels are exactly iso-latitude and very uniform in surface,
2273over the sphere.
2274
2275\item \index{\tcls{SphereECP}}
2276
2277The {\bf \tcls{SphereECP}} class correspond to the cylindrical projection.
2278Like SphereThetaPhi class, the sphere is divided into a number of rings
2279or slices, and each ring is divided into a constant number of pixels
2280along the $\varphi$ direction. Although the \tcls{SphereECP} does not have
2281equal area pixels when used for complete spheres, it can be used for
2282representing partial or full spherical maps.
2283\end{enumerate}
2284
2285The example below shows creating and filling of a
2286SphereHEALPix with nside = 8
2287(The sphere will have $12 \times 8 \times 8= 768$ pixels) :
2288
[1435]2289\begin{verbatim}
2290#include "spherehealpix.h"
2291// ...
2292SphereHEALPix<double> sph(8);
2293for (int k=0; k< sph.NbPixels(); k++) sph(k) = (double)(10*k);
2294\end{verbatim}
2295
[3438]2296Pixels at an angular posistion can be directly accessed through the operator \\
2297\hspace*{15mm} T \tcls{SphericalMap}::operator()($\theta, \varphi$) :
2298\begin{verbatim}
2299#include "vector3d.h"
2300#include "spherethetaphi.h"
2301...
2302// Create a sphere with 40 arcmin resolution
2303int M = SphereThetaPhi<r_4>::ResolToSizeIndex(
2304 Angle(40., Angle::ArcMin).ToRadian() );
2305SphereThetaPhi<r_4> sphtp(M);
2306double tet, phi;
2307for (int k=0; k< sphtp.NbPixels(); k++) {
2308 sphtp.PixThetaPhi(k, tet, phi);
2309 sphtp(k) = cos(5.*tet)*sin(7.*phi);
2310}
2311cout << sphtp;
2312// To save sphtp to file sphtp (if executed through runcxx)
2313KeepObj(sphtp);
2314\end{verbatim}
2315
[1435]2316\index{\tcls{SphereThetaPhi}}
2317
2318\subsection {Local maps}
2319\index{\tcls{LocalMap}}
2320A 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).
2321
2322Internally, 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(...))
2323
2324The 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).
2325\begin{verbatim}
2326#include "localmap.h"
2327//..............
2328 LocalMap<r_4> locmap(4,5);
2329 for (int k=0; k<locmap.NbPixels();k++) locmap(k)=10.*k;
2330 locmap.SetOrigin();
2331 locmap.SetSize(30.,30.);
2332\end{verbatim}
2333
[3856]2334\subsection{Persistence and visualisation }
2335The different SkyMap objects have PPF handlers and written to or read from PPF files.
2336The following example shows how to save the previously created objects
[1435]2337into such a file~:
2338\begin{verbatim}
2339//-- Writing
2340
2341#include "fiospherehealpix.h"
2342//................
2343
2344char *fileout = "myfile.ppf";
2345POutPersist outppf(fileout);
2346FIO_SphereHEALPix<r_8> outsph(sph);
2347outsph.Write(outppf);
2348FIO_LocalMap<r_8> outloc(locmap);
2349outloc.Write(outppf);
2350// It is also possible to use the << operator
2351POutPersist os("sph.ppf");
2352os << outsph;
2353os << outloc;
2354\end{verbatim}
2355
[3856]2356Sophya interactive analysis tool (spiapp) can automatically display and operate
2357on SkyMap objects.
[1435]2358
2359\newpage
[3015]2360\section{Samba and SkyT}
2361\subsection{Samba}
[1414]2362\index{Spherical Harmonics}
2363\index{SphericalTransformServer}
[1435]2364The 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...
[1387]2365\begin{verbatim}
2366#include "skymap.h"
2367#include "samba.h"
2368....................
2369
2370// Generate input spectra a + b* l + c * gaussienne(l, 50, 20)
2371int lmax = 92;
2372Vector clin(lmax);
2373for(int l=0; l<lmax; l++) {
2374 double xx = (l-50.)/10.;
2375 clin(l) = 1.e-2 -1.e-4*l + 0.1*exp(-xx*xx);
2376}
2377
2378// Compute map from spectra
2379SphericalTransformServer<r_8> ylmserver;
2380int m = 128; // HealPix pixelisation parameter
2381SphereHEALPix<r_8> map(m);
2382ylmserver.GenerateFromCl(map, m, clin, 0.);
2383// Compute power spectrum from map
2384Vector clout = ylmserver.DecomposeToCl(map, lmax, 0.);
2385\end{verbatim}
2386
[3015]2387\subsection{Module SkyT}
[3037]2388\index{RadSpectra} \index{SpectralResponse}
[3856]2389\begin{center}
2390{\bf \large THIS MODULE NEEDS EXTENSIVE CHECKING/DEBUGGING AND REDESIGN }
2391\end{center}
[1435]2392The SkyT module is composed of two types of classes:
2393\begin{itemize}
2394\item{} one which corresponds to an emission spectrum of
2395radiation, which is called RadSpectra
2396\item{} one which corresponds to the spectral response
2397of a given detector (i.e. corresponding to a detector
2398filter in a given frequency domain), which is called
2399SpectralResponse.
2400\end{itemize}
2401\begin{figure}[hbt]
2402\dclsbb{RadSpectra}{RadSpectraVec}
2403\dclsb{BlackBody}
2404\dclsccc{AnyDataObj}{SpectralResponse}{SpecRespVec}
2405\dclsc{GaussianFilter}
2406\caption{partial class for SkyT module}
2407\end{figure}
[1299]2408
[1435]2409\begin{verbatim}
2410#include "skyt.h"
2411// ....
2412// Compute the flux from a blackbody at 2.73 K through a square filter
2413BlackBody myBB(2.73);
2414// We define a square filter from 100 - 200 GHz
2415SquareFilter mySF(100,200);
2416// Compute the filtered integrated flux :
2417double flux = myBB.filteredIntegratedFlux(mySF);
2418\end{verbatim}
2419
2420A more detailed description of SkyT module can be found in:
2421{\it The SkyMixer (SkyT and PMixer modules) - Sophya Note No 2. }
2422available also from Sophya Web site.
2423
2424\newpage
[1387]2425\section{Module FitsIOServer}
[3037]2426This module provides classes for handling file input-output in FITS
2427\footnote{http://heasarc.gsfc.nasa.gov/docs/software/fitsio/fitsio.html}
2428format using the cfitsio library. Its
[3015]2429design is similar to the SOPHYA persistence (see Module BaseTools).
2430Delegate classes or handlers perform the actual read/write from/to fits files.
[3037]2431\par
[3015]2432Compared to the SOPHYA native persistence (PPF format),
2433FITS format has the advantage of being used extensively, and handled
2434by a many different software tools. It is a de facto standard in
2435astronomy and astrophysics.
2436However, FITS lacks some of the features present in SOPHYA PPF, and although
2437many SOPHYA objects can be saved in FITS files, FITS persistence has
2438some limitations. For example, FITS does not currently handle complex arrays.
[3037]2439\subsection{FITS streams}
2440\index{FITS} \index{FitsInOutFile}
2441%%
[3015]2442The class {\bf FitsInOutFile} can be seen as a wrapper class for the cfitsio library functions.
2443This class has been introduced in 2005 (V=1.9), when the module has been
2444extensively changed. In order to keep backward compatibility, the old fits wrapper
[3037]2445classes ({\bf FitsFile, FitsInFile, FitsOutFile}) has been changed to inherit from
[3015]2446 {\bf FitsInOutFile}. The use of class FitsFile and specific services of these old classes
2447 should be avoided, but FitsInFile, FitsOutFile can be safely considered a specialisation
2448 of FitsInOutFile for read/input and write/output operations respectively.
[3037]2449 Most c-fitsio errors are converted to an exception: {\bf FitsIOException}.
2450 \par
2451 File names are passed to cfitsio library. It is thus possible to use cfitsio file name conventions,
2452 such as {\bf ! } as the first character, for overwriting existing files (when creating files).
[3015]2453 The diagram below shows the class hierarchy for cfitsio wrapper classes.
[1387]2454\begin{figure}[hbt]
[3015]2455\dclsa{FitsInOutFile}
2456\dclscc{FitsFile}{FitsInFile}
2457\dclscc{FitsFile}{FitsOutFile}
[1387]2458\end{figure}
[3015]2459%%%%
[3048]2460\subsection{FITS handlers and I/O operators}
[3037]2461\index{FitsManager}
[3015]2462Handlers classes inheriting from {\bf FitsHandlerInterface} perform write/read operations
2463for AnyDataObj objects to/from FitsInOutFile streams. The {\bf FitsManager} class provides
2464top level services for object read/write in FITS files.
[3037]2465\par In most cases,
2466\hspace{5mm} {\tt FitsInOutFile\& $<<$ } \, and \, {\tt FitsInOutFile\& $>>$ } \hspace{5mm}
2467operators can be used to write and read objects.
[3048]2468When reading objects from a fits file using the {\tt FitsInOutFile\& $>>$ } operator,
2469the fits file is positioned on the next HDU, after reading. Also, if the {\bf FitsInOutFile}
2470object is positioned on a first empty HDU (without data, naxis=0), reading in objects
2471corresponding to a binary or ascii table using the operator $>>$ will skip automatically
2472the empty HDU and position the fits file on the second HDU, before trying to read in
2473the object.
[3037]2474\par
2475The two main types of fits data structures, images and tables
[3015]2476{\tt (IMAGE\_HDU , BINARY\_TBL , ASCII\_TBL)} are handled by the generic handlers: \\
[3037]2477{\bf \tcls{FitsArrayHandler}} and {\bf FitsHandler$<$BaseDataTable$>$}.
2478\par
[3015]2479A number of more specific handlers are also available, in particular for NTuple,
[3034]2480\tcls{SphereHealPix} and \tcls{SphereThetaPhi}. \\[2mm]
[3048]2481{\bf Warning:} Some handlers were written with the old FitsIOServer classes.
2482They inherit from the intermediate class {\bf FitsIOHandler} and
2483have been adapted to the new scheme. \\[2mm]
[3015]2484%%%
[3037]2485The examples below illustrates the usage of FitsIOServer classes. They can be compiled
2486and executed using runcxx, without the {\tt include} lines: \\[1mm]
2487\hspace*{5mm} {\tt csh> runcxx -import SkyMap -import FitsIOServer -inc fiosinit.h }
2488%%%
[3015]2489\begin{enumerate}
2490\item Saving an array and a HealPix map to a Fits file
[3856]2491\index{HEALPix-FITS}
[1387]2492\begin{verbatim}
[3026]2493#include "fitsioserver.h"
[3034]2494#include "fiosinit.h"
[3015]2495// ....
2496{
[3034]2497// Make sure FitsIOServer module is initialised :
[3015]2498FitsIOServerInit();
2499// Create and open a fits file named myfile.fits
2500FitsInOutFile fos("myfile.fits", FitsInOutFile ::Fits_Create);
2501// Create and save a 15x11 matrix of integers
2502TMatrix<int_4> mxi(15, 11);
2503mxi = RegularSequence(10.,10.);
2504fos << mxi;
2505// Save a HEALPix spherical map using FitsManager services
2506SphereHEALPix<r_8> sph(16);
2507sph = 48.3;
2508FitsManager::Write(fos, sph);
[3037]2509// --- The << operator could have been used instead : fos << sph;
[3015]2510}
2511\end{verbatim}
[3034]2512%%%%
2513%%%%
2514\item Reading objects and the header from the previously created fits file:
[3015]2515\begin{verbatim}
[3034]2516{
2517FitsIOServerInit(); // Initialisation
2518// ---- Open the fits file named myfile.fits
2519FitsInFile fis("myfile.fits");
2520//---- print file information on cout
2521cout << fis << endl;
2522//--- Read in the array
2523TArray<int_4> arr;
2524fis >> arr;
2525arr.Show();
2526//--- Position on second HDU
2527fis.MoveAbsToHDU(2);
2528//--- read and display header information
2529DVList hdu2;
2530fis.GetHeaderRecords(hdu2, true, true);
2531cout << hdu2;
2532//--- read in the HEALPix map
2533SphereHEALPix<r_8> sph;
2534FitsManager::Read(fis, sph);
[3037]2535// --- The >> operator could have been used instead : fis >> sph;
[3034]2536sph.Show();
2537}
[1387]2538\end{verbatim}
[3034]2539%%%%%%%
2540%%%
2541\item DataTable objects can be read from and written to FITS files as ASCII or
[3856]2542binary tables. The example below show reading the DataTable created in the example
[3037]2543in section \ref{datatables} from a PPF file and saving it to a fits file.
[3856]2544\index{DataTable-FITS}
[1435]2545\begin{verbatim}
[3037]2546#include "swfitsdtable.h"
2547// ....
[3034]2548{
[3037]2549FitsIOServerInit(); // FitsIOServer Initialisation
2550//--- Reading in DataTable object from PPF file
2551PInPersist pin("dtable.ppf");
2552DataTable dt;
2553pin >> dt;
2554dt.Show();
2555//--- Saving table to FITS
2556FitsInOutFile fos("!dtable.fits", FitsInOutFile ::Fits_Create);
2557fos << dt;
[3034]2558}
[1435]2559\end{verbatim}
[3034]2560%%%%
2561\end{enumerate}
[3037]2562%%%
[3015]2563A partial class diagram of FITS persistence handling classes is shown below. The
2564class {\tt FitsIOhandler} conforms to the old FitsIOServer module design and
2565should not be used anymore.
[1648]2566\begin{figure}[hbt]
[3015]2567\dclsbb{FitsHandlerInterface}{FitsArrayHandler$<$T$>$}
2568\dclsb{\tcls{FitsHandler}}
2569\dclscc{FitsIOhandler}{FITS\_NTuple}
2570\dclsc{FITS\_SphereHEALPix}
[1648]2571% \dclsb{FITS\_LocalMap}
2572\end{figure}
[1387]2573
[3856]2574\subsection{Fits Array I/O in chunk }
2575Array read/write from/to FITS files (Image HDU) is rather straightforward, in particular thanks to
2576the overloaded stream operators, as in the examples given above and here:
2577\index{Array-FITS}
2578\begin{verbatim}
2579// ---- Writing an array to fits file
2580// Create and open a fits file named myfile.fits
2581FitsInOutFile fos("!myarr.fits", FitsInOutFile ::Fits_Create);
2582TArray<r_8> a(50,30);
2583// ... fill the array
2584// Write the array to file
2585fos << a;
2586
2587// ---- Reading an array from file myarr.fits
2588// Open the fits file for reading
2589FitsInOutFile fis("myarr.fits", FitsInOutFile::Fits_RO);
2590TArray<r_8> a;
2591// Read in the array
2592fis >> a;
2593\end{verbatim}
2594
2595It is also possible to write arrays FITS Image HDU in chunks or read arrays in chunk,
2596using the following methods : \\
2597\begin{verbatim}
2598void FitsArrayHandler<T>::ReadAtOffset(FitsInOutFile& is, sa_size_t* offset);
2599void FitsArrayHandler<T>::WriteAtOffset(FitsInOutFile& os, sa_size_t* offset);
2600\end{verbatim}
2601The sample code below show how a FITS file corresponding to a 3D data cube of $5\times4\times3$ elements
2602can be created and written as a series of 2D slices:
2603\begin{verbatim}
2604// Make sure FitsIOServer module is initialised :
2605FitsIOServerInit();
2606// Open/create the output file, named mycube.fits (overwrite it)
2607FitsInOutFile fos("!mycube.fits", FitsInOutFile ::Fits_Create);
2608// Define the cube size
2609LONGLONG size[3] = {5,4,3};
2610// Create a 2D array corresponding to an x-y cube slice
2611TArray<int_4> slice(size[0], size[1]);
2612// Create an IMAGE HDU: cube size and slice data type
2613fos.CreateImageHDU(FitsTypes::ImageType(slice(0,0)), 3, size);
2614// initialize the array content
2615slice = RegularSequence();
2616// Create a Fits handler for the array
2617FitsArrayHandler<int_4> fh(slice);
2618// Write the 3 slices to the file
2619sa_size_t offset[3];
2620offset[0]=0; offset[1]=0;
2621for(int k=0;k<size[2]; k++) {
2622 slice += (int_4)(k*100);
2623 offset[2]=k;
2624 fh.WriteAtOffset(fos,offset);
2625}
2626\end{verbatim}
2627The example below show how to read arrays from Image HDU in chunk:
2628\begin{verbatim}
2629// Make sure FitsIOServer module is initialised :
2630FitsIOServerInit();
2631// Open the existing file mycube.fits for reading
2632FitsInOutFile fis("mycube.fits", FitsInOutFile::Fits_RO);
2633// Get the array size
2634int naxis=BASEARRAY_MAXNDIMS;
2635LONGLONG axes[BASEARRAY_MAXNDIMS];
2636fis.GetImageHDUInfo(naxis, axes);
2637// Read in the data as 2D slices
2638TArray<int_4> slice(axes[0], axes[1]);
2639FitsArrayHandler<int_4> fh(slice);
2640sa_size_t offset[3];
2641offset[0]=0; offset[1]=0;
2642for(int k=0;k<axes[2]; k++) {
2643 offset[2]=k;
2644 fh.ReadAtOffset(fis,offset);
2645 cout << " Slice k=" << k << " Sx=" << axes[0] << " Sy=" << axes[1] << endl;
2646 slice.Print(cout,slice.Size()); cout << endl;
2647}
2648\end{verbatim}
2649
[3034]2650\subsection{SwFitsDataTable and other classes}
[3048]2651\label{SwFitsDataTable}
[3037]2652\index{SwFitsDataTable}
2653The {\bf SwFitsDataTable} class implements the BaseDataTable interface
2654using a FITS file as swap space. Compared to SwPPFDataTable, they can be
2655used in R/W mode (reading from the table, when it is being created / filled).
2656They can be used in a way similar to DataTable and SwPPFDataTable.
2657When creating the table, a {\tt FitsInOutFile } stream, opened for writing has
2658to be passed to the creator. No further operation is needed.
2659\begin{verbatim}
2660// ....
2661FitsInOutFile so("!myswtable.fits", FitsInOutFile::Fits_Create);
2662SwFitsDataTable dt(so, 16);
2663// define table columns
2664dt.AddIntegerColumn("X0_i");
2665dt.AddFloatColumn("X1_f");
2666// ... Fill the table
2667r_8 x[5];
2668for(int i=0; i<63; i++) {
2669 x[0] = (i%9)-4.; x[1] = (i/9)-3.;
2670 dt.AddLine(x);
2671}
2672\end{verbatim}
2673The class {\bf FitsBTNtuIntf } provide an alternative tool to read FITS tables.
2674{\bf FitsABTColRd} , {\bf FitsABTWriter } and {\bf FitsImg2DWriter } can also
2675be used to manipulate FITS files.
2676\par
2677The {\bf scanfits} program can be used to check FITS files and analyse their
2678content (See \ref{scanfits}).
[3034]2679
[3037]2680%%%%
[1340]2681\newpage
[1435]2682\section{LinAlg and IFFTW modules}
2683An interface to use LAPACK library (available from {\tt http://www.netlib.org})
2684is implemented by the {\bf LapackServer} class, in module LinAlg.
2685\index{LapackServer}.
2686The sample code below shows how to use SVD (Singular Value Decomposition)
2687through LapackServer:
2688\begin{verbatim}
2689#include "intflapack.h"
2690// ...
2691// Use FortranMemoryMapping as default
2692BaseArray::SetDefaultMemoryMapping(BaseArray::FortranMemoryMapping);
2693// Create an fill the arrays A and its copy AA
2694int n = 20;
2695Matrix A(n , n), AA;
2696A = RandomSequence(RandomSequence::Gaussian, 0., 4.);
2697AA = A; // AA is a copy of A
2698// Compute the SVD decomposition
2699Vector S; // Vector of singular values
2700Matrix U, VT;
2701LapackServer<r_8> lpks;
2702lpks.SVD(AA, S, U, VT);
2703// We create a diagonal matrix using S
2704Matrix SM(n, n);
2705for(int k=0; k<n; k++) SM(k,k) = S(k);
2706// Check the result : A = U*SM*VT
2707Matrix diff = U*(SM*VT) - A;
2708double min, max;
2709diff.MinMax(min, max);
2710cout << " Min/Max difference Matrix (?=0) , Min= " << min
2711 << " Max= " << max << endl;
2712\end{verbatim}
2713
2714\index{FFTWServer}
2715The {\bf FFTWServer} class (in module FFTW) implements FFTServerInterface class
2716methods, for one dimensional and multi-dimensional Fourier
[3419]2717transforms using the FFTW package (available from {\tt http://www.fftw.org}).
2718Depending on the configuration options during library build, only
2719transforms on double precision data might be available.
[3856]2720Usage example:
2721\begin{verbatim}
2722int nx=500, ny=500;
2723TArray<r_8> img(nx, ny);
2724// fill in the image
2725....
2726// Compute Fourier transform of the image
2727TArray< complex<r_8> > fourimg;
2728FFTWServer ffts;
2729ffts.setNormalize(true);
2730ffts.FFTForward(img, fourimg);
2731// perform some filtering in Fourier domain
2732// modifying the fourier coefficients fourimg
2733...
2734// Compute back the new (filtered) image
2735TArray<r_8> img2(nx, ny);
2736ffts.FFTBackward(fourimg, img2);
2737\end{verbatim}
[1435]2738
[3856]2739\section{Multi-thread and parallel programming with SOPHYA}
2740 \label{mtpsop}
2741A general introduction to parallel programming model in the Shared Memory multi-Processor
2742systems and the POSIX thread model is well beyond the scope of this
2743document. Interested readers can find some introductory texts on the following
2744web pages:
2745\begin{enumerate}
2746\item Symmetric multiprocessing, \\
2747\href{http://en.wikipedia.org/wiki/Symmetric\_multiprocessing } {http://en.wikipedia.org/wiki/Symmetric\_multiprocessing }
2748\item POSIX Threads Tutorial {\it Mark Hays, Software Interest Group }\\
2749\href{ http://math.arizona.edu/\~swig/documentation/pthreads/ } {http://math.arizona.edu/\~swig/documentation/pthreads/}
2750\item POSIX Threads Programming {\it Blaise Barney, Lawrence Livermore National Laboratory } \\
2751\href{ https://computing.llnl.gov/tutorials/pthreads/ } {https://computing.llnl.gov/tutorials/pthreads/ }
2752\end{enumerate}
2753In this section, we present some tips and example, focusing on the use of SOPHYA thread management classes.
2754Few examples of multithread programs using these classes can be found in the {\bf Tests} module : \\
2755\hspace{10mm} {\tt zthr.cc , tmtdt.cc , tmtrnd.cc }
2756
2757\subsection{General guidelines}
2758\begin{enumerate}
2759\item In general, most classes in SOPHYA are inherently thread-safe, as they do not have global (static) data class
2760members and methods operate on instance data members. This is in particular the case of data objects
2761in SOPHYA: \\
2762\tcls{NDataBlock}. \tcls{TArray}, Histo, DataTable, NTuple, \tcls{SphericalMap} \ldots \\
2763This means that different instances of these classes can be used within threads without any precaution.
2764The SOPHYA reference sharing mechanism being itself thread safe.
2765\item Once the handlers have been registered, the SOPHYA persistence mechanism is in principle thread safe,
2766as long as I/O is performed on different files in different threads. Synchronisation through mutex should
2767be implemented if the same PPF file (PInPersist/POutPersist object) is being used in different threads.
2768\item If you want to use the same NTuple or DataTable or SwPPFDataTable object in different threads, you have
2769to call the method {\tt SetThreadSafe()} on the corresponding object:
2770\begin{verbatim}
2771---> Set fg=true for thread safe operations
2772void NTuple::SetThreadSafe(bool fg);
2773void BaseDataTable::SetThreadSafe(bool fg);
2774\end{verbatim}
2775\item Some computation functions or classes in SOPHYA use currently global data and are not thread-safe.
2776FFTPackServer, FFTWServer and SphericalTransform servers are not thread safe. FFTWServer is not currently
2777thread safe as the creation of fftw\_plan is not thread safe in fftw library.
2778\item the cfitsio library is not thread safe, making the services of the FitsIOServer NON thread-safe
2779\item Many functions in the standard libraries are NOT thread-safe. This is the case of the usual random generators.
2780Refer to section \ref{randgen} for using random generators in multi-thread applications.
2781\end{enumerate}
2782
2783\subsection{Using ZThread and ZMutex }
2784\begin{itemize}
2785\item Define and implement a class inheriting from the {\bf ZThread} class (zthread.h).
2786This class should overwrite the {\tt virtual void ZThread::run() } method of the base class
2787which has to perform the actual computation.
2788At the end of the computation in the {\tt run()} method, the {\tt setRC(int rc) } can be called to set
2789the return code of the thread object.
2790\item If the actual computation is performed by a function having a single {\tt void *} argument,
2791the ZThread base class can directly be used. See the example in paragraph \ref{thrcls}.
2792\item The actual thread is created by the {\tt start()} method. This method has to be called
2793on each ZThread object to perform the computation. The {\tt start() } method return immediately
2794after the creation of the underlying thread object.
2795\item The method {\tt join() } can be used to wait for the thread termination.
2796\item {\bf ZMutex} objects should be used to control to data (memory location) shared
2797by several threads. These ZMutex objects would usually be attributes (data members) of the
2798ZThread objects or classes used by the ZThread objects. Consider a variable {\tt int count }
2799which is accessed by two different threads. Thread A changes (increment or decrement for example)
2800the value of {\tt count}, while thread B waits until {\tt count} reaches a given threshold, before
2801performing some actions and resetting {\tt count}. Access to {\tt count} should be protected by
2802a ZMutex object; The actual code would then look like:
2803\begin{verbatim}
2804// count and its associated ZMutex declaration
2805int count = 0;
2806int threshold=10;
2807ZMutex mex;
2808.......
2809// ----- Code executed by thread A
2810mex.lock();
2811count++;
2812mex.unlock();
2813mex.signal();
2814// Alternatively, mex.broadcast() can be called to wake up
2815// several threads waiting on the ZMutex condition variable
2816.......
2817// ----- Code executed by thread B
2818mex.lock();
2819while (count<threshold) mex.wait();
2820// here, count has reached or exceeded the threshold
2821// Do some action, and reset count
2822count=0;
2823mex.unlock();
2824\end{verbatim}
2825\end{itemize}
2826
2827\subsection{Using ParallelExecutor }
2828The {\bf ParallelExecutor } class (parlex.h) objects can be used to perform a computation divided into
2829parts which can be performed independently and in parallel in different threads. A typical
2830would be the application of a complex function to all elements in an array.
2831\begin{itemize}
2832\item Define and implement a class inheriting from the {\bf ParallelTaskInterface} class. This class should
2833implement the pure virtual method {\tt int execute(int tid)}. {\tt tid} is the thread identifier, or rank in the
2834set of parallel threads assigned to perform the computation. The first thread has a rank=0 and
2835{\tt ParallelTaskInterface::getNbParallelThreads() } method can be used to find the total
2836number of threads assigned to the task in the parallel execution context.
2837\item Create an {\bf ParallelExecutor} object passing to it the ParallelTask object and the number of
2838threads, or alternatively, a vector of ParallelTask object pointers.
2839\item The set of threads are started by calling the {\tt ParallelExecutor::start() } method. The created threads
2840will be in a waiting state, until the {\tt ParallelExecutor::execute() } is called.
2841\item The call to {\tt execute() } triggers the execution of the {\tt ParallelTask::execute(tid) } methods
2842for all of the parallel threads in the context. The {\tt execute() } method returns when all the threads
2843have finished executing the {\tt ParallelTask::execute(tid) } .
2844\item The threads will then be again in a waiting state, ready for a new call to {\tt execute() }.
2845The threads will terminate when the ParallelExecutor object is destroyed.
2846\end{itemize}
2847
2848\begin{verbatim}
2849// Class MyTask implements ParallelTaskInterface
2850MyTask ptask(...);
2851// Create a parallel execution context with 4 threads
2852ParallelExecutor parex(ptask,4);
2853// Start the threads
2854parex.start();
2855// Loop over several data sets that
2856int NDS=5;
2857for(int i=0; i<NDS; i++ {
2858 // Prepare the data
2859 ...
2860 // Do the parallel computation
2861 parex.execute();
2862}
2863\end{verbatim}
2864
[1435]2865\newpage
[978]2866\section{Building and installing Sophya}
[3045]2867\subsection{Supported platforms}
[3856]2868Presently, the SOPHYA and PI libraries and tools have been compiled and tested with
[3839]2869the following compiler/platform pairs:
[978]2870
2871\begin{center}
[2790]2872\begin{tabular}{|l|l|}
2873\hline
2874OS & compiler \\
2875\hline
[3839]2876Linux (SL5, 64) & g++ 4.1 \\
2877Linux (SL5, 64) & icc - Intel compiler (10.1) \\
2878Linux Ubuntu & g++ 4.4 \\
2879MacOSX/Darwin 10.3 (PowerPC) \, 10.4 (Intel) & Apple g++ 3.3 \, 4.0 \\
2880MacOSX/Darwin 10.5 (Intel) & Apple g++ 4.0 \\
2881MacOSX/Darwin 10.6 (Intel) Snow Leopard & Apple g++ 4.2 \\
2882IBM AIX 5.3 & xlC 8.0 \\
2883HP/Compaq/DEC Tru64 ( OSF1) & cxx 6.1 \, 6.3 \\
[2790]2884\hline
[978]2885\end{tabular}
2886\end{center}
2887
[3839]2888The SOPHYA and PI library and associated tools (spiapp, runcxx \ldots) were ported and tested
2889on the Silicon Graphics (SGI) IRIX system and the corresponding native c++ compiler ( IRIX64, CC 7.3 ),
2890up to SOPHYA V2.1 (V\_Nov2007).
2891
[3045]2892\subsection{Library and makefile structure}
2893%
[978]2894The object files from a given Sophya module are grouped in an archive library
2895with the module's name ({\tt libmodulename.a}). All Sophya modules
2896 are grouped in a single shared library ({\tt libsophya.so}), while the
2897modules with reference to external libraries are grouped in
2898({\tt libextsophya.so}). The {\bf PI} and {\bf PIext} modules are
2899grouped in ({\tt libPI.so}).
[3015]2900Alternatively, it is possible to group all modules in a single shared
2901library {\tt libAsophyaextPI.so}.
[3037]2902\par
2903Each library module has a {\tt Makefile} which compiles the source files
2904and build the correspond static (archive) library using the compilation
[3045]2905rules and flags defined in \\
2906\hspace*{5mm} {\tt \$SOPHYABASE/include/sophyamake.inc}. \\
[3037]2907Each program module has a {\tt Makefile} which compiles and link the
2908corresponding programs using the compilation rules and libraries
2909defined in {\$SOPHYABASE/include/sophyamake.inc}.
2910The top level Makefile in BuildMgr/ compiles each library modules
2911and builds shared libraries.
[3045]2912\par
2913Some of the modules in the Sophya package uses external libraries. The
2914{\bf FitsIOServer} is an example of such a module, where the {\tt libcfitsio.a}
2915is used. The list of all Sophya modules using external libraries is
2916presented in section \ref{sopmodules}.
2917The external libraries should be installed before the configure step
2918(see below) and the compilation of the corresponding Sophya modules.
[3037]2919\par
2920The series of Makefiles use the link to {\tt sophyamake.inc} in BuildMgr.
2921There are also the {\tt smakefile} series which uses the explicit path, using
2922{\tt \$SOPHYABASE} environment variable.
[978]2923
[3856]2924\subsection{Build and install procedure}
[3015]2925\label{build}
2926The build procedure has two main steps:
2927\begin{enumerate}
2928\item The configure step (BuildMgr/configure) setup the directory structure and
2929the necessary configuration file. Refer to section \ref{directories} for
2930the description of SOPHYA directory tree and files.
2931\item The make step compiles the different sources files, create the library and optionaly
[2790]2932builds all or some of the associated executables.
[3015]2933\end{enumerate}
[2790]2934
[3856]2935{\tt BuildMgr/configure } is a c-shell script with a number of arguments. Please note
2936 that this is NOT an autoconf generated script, but a custom c-shell script and it does
2937not create the makefiles. The c-shell (or tcsh) must be accessible to run this script.
[2790]2938\begin{verbatim}
2939csh> ./configure -h
2940configure [-sbase SOPHYABASE] [-scxx SOPHYACXX] [-incln]
[3415]2941 [-minc mymake.inc] [-compopt 'cc/cxxOptions']
[3856]2942 [-arch64] [-arch32] [-sasz64] [-ldble128]
2943 [-nofpic] [-nothsafe] [-boundcheck] [-sodebug]
2944 [-extp dir1 -extp dir2 ...] [-extip dir1 -extip dir2 ... ]
2945 [-extlp dir1 -extlp dir2 ... ] [-followlink]
[3415]2946 [-noextlib] [-noext fits] [-noext fftw] [-noext lapack] [-noext astro]
2947 [-alsofftwfloat] [-usefftw2] [-uselapack2]
[3856]2948 [-wgrdl] [-epip mdir1 -epip mdir2 ...] [-noPI] [-slballinone]
[3415]2949 (See SOPHYA manual/web pages for a detailed description of configure options)
[2790]2950\end{verbatim}
2951\begin{itemize}
[3856]2952\item General parameters and options: \\[1mm]
2953{\bf -sbase {\it path} } define SOPHYA installation base directory. \$SOPHYABASE is used
2954if not specified \\
2955{\bf -scxx {\it cmd} } selects the C++ compiler. \$SOPHYACXX is used if not specified. \\
2956{\bf -incln } creates symbolic link for include files, instead of copying them. \\
2957{\bf -minc {\it filename} } give an explicit name for the file used as the seed to create the file \\
2958{\tt \$SOPHYABASE/include/sophyamake.inc}. \hspace{2mm}
2959If -minc is not specified, one of the files in BuildMgr/ directory is selected, based on the
2960system name and the compiler: \\
2961{\tt Linux\_g++\_make.inc , OSF1\_cxx\_make.inc , AIX\_xlC\_make.inc \ldots} \\
2962{\bf -compopt {\it opt} } can be used to specify additional compiler options
2963\item Conditional compilation flags related to SOPHYA configuration (see {\tt machdefs.h} )\\[1mm]
2964{\bf -arch64 } select/force 64 bits compilation mode. This is the default on 64 bits Linux systems and AIX. \\
2965{\bf -arch32 } select/force 32 bits compilation mode. useful on 64 bits Linux systems or AIX. \\
2966{\bf -sasz64 } select 8 byte (64 bits) size for array indices, useful if you need to allocate an manipulate
2967large arrays, with more than $2^32$ elements along a single array dimension. \\
2968{\bf -ldble128 } set the flags activating {\tt long double} (128 bits) arrays. \\
2969{\bf -nofpic } disable -fPIC (Position Independent Code) generation flag \\
2970{\bf -nothsafe } disable thread-safety protection procedures in SOPHYA : reference sharing \ldots.
2971 ( activate the conditional compilation flag {\tt SO\_NOTHSAFE } ) \\
2972{\bf -boundcheck } compile SOPHYA with bound checking activated when accessing array elements
2973( conditional compilation flag {\tt SO\_BOUNDCHECKING } ) \\
2974{\bf -sodebug } activate conditional compilation flag {\tt SOPHYA\_DEBUG } for debugging the library.
2975\item External libraries \\[1mm]
2976{\bf -extp {\it path} } Adds the specified path to the search path of the external libraries
2977include files and archive library. \\
2978{\bf -extip {\it path} } Adds the specified path to the search path of the external libraries
2979include files. \\
2980{\bf -extlp {\it path} } Adds the specified path to the search path of the external libraries
2981archive (libxxx.a). \\
2982{\bf -followlink} follow symbolic links when searching for include files and libraries
2983(-L option of the find command). default: don't follow symbolic links. \\
2984{\bf -noextlib } Disable compilation of all modules referencing external libraries. \\
2985{\bf -noext {\it modname} } Disable compiling of the specified module (with reference to external
2986library : {\tt -noext fits , -noext fftw -noext lapack -noext astro } \\
2987{\bf -usefftw2 } Use FFTW V2 instead of the default FFTW V3 - A preprocessor
2988flag will be defined in sspvflags.h \\
2989{\bf -uselapack2 } Use Lapack V2 istead of the default V3 - A preprocessor
2990flag will be defined in sspvflags.h \\
2991{\bf -alsofftwfloat } compile single precision (float) version of the Fourier
[3415]2992transform methods (module IFFTW, class FFTWServer). A preprocessor
2993flag will be defined in sspvflags.h and float version of the FFTW library
2994(libfftw3f.a) will be linked with SOPHYA, in addition to the default double
[3856]2995precision library (libfftw3.a). \\
2996{\bf -slballinone} Use of a single shared library for all SOPHYA, PI and
2997external library interface modules. A compilation flag
2998will be defined in sspvflags.h . See also target {\tt slballinone} below.
2999\item PI and piapp specific options \\[1mm]
3000{\bf -wgrdl } compile and link piapp with GNU readline library \\
3001{\bf -epip {\it path} } Adds the specified path to the search path for include
3002files and libraries for Motif, and GNU readline, if applicable. \\
3003{\bf -noPI } ignore PI modules
[2790]3004\end{itemize}
3005
[3856]3006\subsubsection{Configure steps }
3007
[3415]3008The configure script performs the following actions :
3009\begin{enumerate}
[3839]3010\item Creates directory tree under {\tt \$SOPHYABASE }
3011\item Copy include files to {\tt \$SOPHYABASE/include/ } (or creates symbolic link)
[3415]3012\item Search for external libraries include files and create the necessary links
3013in {\tt \$SOPHYABASE/include}
3014\item Search for external libraries (-lfits \ldots) and add the corresponding
3015directories to the library search path, in {\tt sophyamake.inc}
3016\item Creates the file { \tt \$SOPHYABASE/include/sophyamake.inc }
3017\item Creates the file {\tt machdefs.h} from { BaseTools/machdefs\_mkmf.h } and
3018{\tt sspvflags.h }
3019\item Creates the object list files for shared library creation
3020\end{enumerate}
3021
[3856]3022\subsubsection{Compile and install, an example }
[3415]3023
[978]3024In the example below, we assume that we want to install Sophya from a
3025released (tagged) version in the source directory {\tt \$SRC} in the
[2790]3026{\tt /usr/local/Sophya} directory, using {\tt g++}. We assume that
3027the external libraries can be found in {\tt /usr/local/ExtLibs/}.
[3180]3028We disable the compilation of the XAstroPack package.
[2790]3029
[978]3030\vspace*{3mm}
3031\begin{verbatim}
[2790]3032# Create the top level directory
[978]3033csh> mkdir /usr/local/Sophya/
[2790]3034csh> cd $SRC/BuildMgr
3035# Step 1.a : Run the configuration script
3036csh> ./configure -sbase /usr/local/Sophya -scxx g++ -extp /usr/local/ExtLibs/ \
[3180]3037-noext astro
[3015]3038# Step 1.b : Check the generated file $SOPHYABASE/include/sophyamake.inc
3039csh> ls -lt *.inc
3040csh> more sophyamake.inc
3041\end{verbatim}
3042If necessary, edit the generated file {\tt sophyamake.inc } in order to modify
3043compilation flags, library list. The file is rather short and self documented.
3044\begin{verbatim}
[2790]3045# Step 2.a: Compile the modules without external library reference
[978]3046csh> make libs
[2790]3047# Step 2.b: Compile the modules WITH external library reference (optional)
[978]3048csh> make extlibs
[2790]3049# Step 2.c: Build libsophya.so
[978]3050csh> make slb
[2790]3051# Step 2.d: Build libextsophya.so (optional)
[978]3052csh> make slbext
[2790]3053# Step 2.e: Compile the PI and PIext modules (optional)
[978]3054csh> make PI
[2790]3055# Step 2.f: Build the corresponding shared library libPI.so (optional)
[978]3056csh> make slbpi
3057\end{verbatim}
3058
3059To compile all modules and build the shared libraries, it is possible
[3015]3060to perform the steps 2.a to 2.f using the targets {\tt all} and {\tt slball}
3061defined in the Makefile
[978]3062\begin{verbatim}
[2790]3063# Step 2.a ... 2.f
[3015]3064csh> make all slball
[978]3065\end{verbatim}
3066
[3015]3067It is also possible to group all modules in a single shared library using
3068the target {\tt slballinone}.
3069\begin{verbatim}
3070# Step 2.a ... 2.f
3071csh> make all slballinone
3072\end{verbatim}
3073
[1435]3074At this step, all libraries should have been made. Programs using
[978]3075Sophya libraries can now be built:
3076\begin{verbatim}
[3015]3077# To compile some of the test programs
3078csh> make basetests
3079# To compile runcxx , scanppf , scanfits
3080csh> make prgutil
[978]3081# To build (s)piapp (libPI.so is needed)
[3015]3082csh> make piapp
[978]3083\end{verbatim}
3084
[3037]3085If no further modification or update of source files is foreseen, it is possible
3086to remove all .o files:
3087\begin{verbatim}
3088# To clean $SOPHYABASE/obj directory :
3089csh> make cleanobj
3090\end{verbatim}
3091
3092
3093\subsection{Notes}
[988]3094\begin{itemize}
[3037]3095\item[{\bf Makefile}] List of top level Makefile build targets
3096\begin{verbatim}
3097> libs extlibs PI = all
3098> slb slbext slbpi = slball (OR = slballinone)
3099> clean cleanobj
3100> tests prgutil prgmap progpi = prgall
3101> basetests piapp (ou progpi) pmixer
3102\end{verbatim}
3103\item[{\bf MacOS X}] A high performance mathematic and signal processing
3104library, including LAPACK and BLAS is packaged in Darwin/MacOS X (10.3, 10.4) : \\
3105\hspace*{5mm} {\bf -framework Accelerate}
3106\item[{\bf Tru64/OSF}] An optimised math library with LAPACK and BLAS might
3107optionaly be installed {\bf (-lcxlm) }. On our system, this libray contained Lapack V2.
3108So we used the LAPACK, as compiled from the public sources, and linked with
3109the Tru64 native BLAS.
3110\item[{\bf IRIX64}] We used the math library with LAPACK V2 and BLAS
3111from SGI : {\bf -lcomplib.sgimath}
[3015]3112\item[{\bf AIX}] There seem to be a problem on AIX when several shared
3113libraries are used. We have been able to run SOPHYA programs either
3114using static libraries, or a single shared library (libAsophyaextPI.so)
3115if extlibs and PI are needed, in addition to stand alone SOPHYA modules.
[3037]3116It has not been possible to link SOPHYA with fortran libraries
3117\item[{\bf Mgr}] This module contains makefiles and build scripts
3118that were used in SOPHYA up to version 1.7 (2004) : OBSOLETE.
[3015]3119\end{itemize}
[887]3120
[3015]3121\subsection{Files and scripts in BuildMgr/ }
3122\begin{itemize}
3123\item[] {\bf Makefile:} Top level Makefile for building SOPHYA.
3124{\tt smakefile} is similar to Makefile, except that it uses
3125the smakefiles in each module.
3126\item[] {\bf mkmflib:} c-shell script for creation of library module
[3045]3127Makefile / smakefile. \\
3128\hspace*{5mm} {\tt ./mkmflib -sbase /tmp/sbase SUtils }
[3015]3129\item[] {\b mkmfprog:}
[3045]3130c-shell script for creation of programs module Makefile / smakefile \\
3131\hspace*{5mm} {\tt ./mkmfprog -sbase /tmp/sbase ProgPI }
[3015]3132\item[] {\bf domkmf:} c-shell script - calls mkmflib for all modules \\
[3045]3133\hspace*{5mm} {\tt ./domkmf -sbase /tmp/sbase}
3134\item[] {\bf xxx\_make.inc:} Configuration files for different compilers and OS
3135{\tt ( Linux\_g++\_make.inc , OSF1\_cxx\_make.inc \ldots )}.
[3015]3136These files are used to generate {\tt sophyamake.inc}
[988]3137\end{itemize}
[3015]3138
[3856]3139\subsection{Test programs}
3140The module {\bf Tests} contains a number of test programs:
3141\begin{enumerate}
3142\item {\bf tobjio } tests part of SOPHYA persistence (PPF files)
3143\begin{verbatim}
3144csh> tobjio A
3145 ===> check the created file tobjio.ppf using scanppf
3146csh> scanppf tobjio.ppf
3147csh> tobjio B
3148 ===> OK if RC=0
3149\end{verbatim}
3150\item {\bf arrt } and {\bf carrt} perform some checks on TArray modules, including I/O,
3151sub-array extraction, array conversion and memory organisation, as well as array operations.
3152\begin{verbatim}
3153csh> arrt check
3154csh> carrt ac
3155csh> carrt oso
3156csh> carrt odo
3157 ===> OK if RC=0
3158csh> carrt ace
3159 ===> OK if RC=9 (throw an exception)
3160\end{verbatim}
3161\item {\bf spar } is a TArray performance measurement tool
3162\begin{verbatim}
3163csh> time spar 2 10 800 1000
3164csh> time spar 2 1000 80 100
3165\end{verbatim}
3166\item {\bf tssqmx } checks DiagonalMatrix, SymmetricMatrix and LowerTriangularMatrix classes
3167\begin{verbatim}
3168csh> tssqmx d
3169csh> tssqmx s
3170csh> tssqmx t
3171 ===> OK if RC=0
3172\end{verbatim}
3173\item {\bf ttimestamp } and {\bf tnt } perform some checks on various SOPHYA objects ( DVList, TimeStamp, NTuple \ldots)
3174\begin{verbatim}
3175csh> ttimestamp
3176 ===> OK if RC=0
3177csh> tnt d
3178 ===> DVList test, check the output
3179csh> tnt n
3180 ===> NTuple test, check the output
3181csh> tnt DT
3182 ===> DataTable test, check the output
3183csh> tnt DT
3184 ===> SwPPFDataTable test, check the output
3185\end{verbatim}
3186\item {\bf tfft } checks the operation of FFTPackServer and FFTWServer in 1D transforms
3187\begin{verbatim}
3188# FFTPackServer tests in double
3189csh> tfft 1531 P D 0 50 0.0002
3190csh> tfft 1220 P D 0 50 0.0002
3191 ===> OK if RC=0
3192# FFTPackServer tests in float
3193csh> tfft 1531 P F 0 50 0.0002
3194csh> tfft 1220 P F 0 50 0.0002
3195 ===> OK if RC=0
3196# FFTWServer tests in double
3197csh> tfft 1531 W D 0 50 0.0002
3198csh> tfft 1220 W D 0 50 0.0002
3199 ===> OK if RC=0
3200\end{verbatim}
3201\item {\bf lpk} checks the LinAlg interface module
3202\begin{verbatim}
3203csh> lpk inverse 100,100 0
3204 ===> OK if RC=0
3205csh> lpk linsolve 100,100 0
3206 ===> OK if RC=0
3207csh> lpk lss 100,50 0
3208 ===> OK if RC=0
3209csh> lpk svd 100,50 0
3210 ===> OK if RC=0
3211## These checks can be combined in a single call to lpk
3212csh> lpk all 100,50 0
3213\end{verbatim}
3214\item {\bf tmtdt } tests several aspects of SOPHYA : threads (ZThread, ZMutex \ldots), DataTables \ldots
3215\begin{verbatim}
3216csh> tmtdt NT 50000 2
3217 ===> OK if RC=0
3218csh> tmtdt DT 50000 2
3219 ===> OK if RC=0
3220csh> tmtdt SWPPF 50000 2
3221 ===> OK if RC=0
3222# cfitsio is NOT thread safe, test SwFitsDataTable with a single thread
3223csh> tmtdt SWFITS 50000 1
3224\end{verbatim}
[3015]3225
[3856]3226\end{enumerate}
[3015]3227
[988]3228\newpage
[1299]3229\appendix
[1362]3230\section{SOPHYA Exceptions}
3231\index{Exception classes} \index{PThrowable} \index{PError} \index{PException}
3232SOPHYA library defines a set of exceptions which are used
[3839]3233for signalling error conditions. From version V2.2 , all SOPHYA exceptions inherit from
3234the standard C++ exception class ( {\bf std::std::exception}). The method {\tt const char* what()} is
3235thus implemented and returns the corresponding error message.
3236The figure below shows a partial class diagram for exception classes in SOPHYA.
[1362]3237\begin{figure}[hbt]
3238\dclsbb{PThrowable}{PError}
3239\dclscc{PError}{AllocationError}
3240\dclscc{PError}{NullPtrError}
3241\dclscc{PError}{ForbiddenError}
3242\dclscc{PError}{AssertionFailedError}
3243\dclsbb{PThrowable}{PException}
3244\dclscc{PException}{IOExc}
3245\dclscc{PException}{SzMismatchError}
3246\dclscc{PException}{RangeCheckError}
3247\dclscc{PException}{ParmError}
3248\dclscc{PException}{TypeMismatchExc}
3249\dclscc{PException}{MathExc}
3250\dclscc{PException}{CaughtSignalExc}
3251\caption{partial class diagram for exception handling in Sophya}
3252\end{figure}
3253
[1299]3254For simple programs, it is a good practice to handle
[988]3255the exceptions at least at high level, in the {\tt main()} function.
3256The example below shows the exception handling and the usage
3257of Sophya persistence.
[1299]3258
[988]3259\input{ex1.inc}
[887]3260
[1362]3261\newpage
3262\addcontentsline{toc}{section}{Index}
3263\printindex
[1299]3264\end{document}
[1362]3265
Note: See TracBrowser for help on using the repository browser.