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

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

Derniers ajouts ds document sophya.tex (user's guide) pour V=2.2, Reza 12/08/2010

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