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

Last change on this file was 4065, checked in by ansari, 13 years ago

MAJ fichier modifs.tex pour changement classes CExpressionEvaluator/introduction CE_VarListInterface, ajout description classes PrimeNumbers, QNumber, Units et PhysQty dans le user's guide de Sophya, Reza 27/04/2012

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