source: Sophya/trunk/SophyaLib/HiStats/ntuple.cc@ 3534

Last change on this file since 3534 was 3392, checked in by ansari, 18 years ago

Implementation NTuple::Fill(), BaseDataTable:;AddRow()/GetRow() thread-safe - Reza 22/11/2007

File size: 19.2 KB
RevLine 
[763]1#include <stdio.h>
2#include <string.h>
3
4#include "strutil.h"
5#include "perrors.h"
6#include "ntuple.h"
[3392]7#include "thsafeop.h"
[763]8
[3236]9namespace SOPHYA {
[763]10
11#define LENNAME 8
12#define LENNAME1 (LENNAME+1)
[2663]13#define BADVAL -1.e19
[763]14
[1371]15/*!
[3236]16 \class NTuple
[1371]17 \ingroup HiStats
[2667]18 Simple NTuple class (a Table or 2-D data set) with double or
19 single precision floating point value columns.
[3392]20 \warning
21 Thread safe fill operation can be activated using the method SetThreadSafe()
22 Default mode is NON thread-safe fill.
[1405]23 \sa SOPHYA::ObjFileIO<NTuple>
24
25 \code
26 #include "ntuple.h"
27 // ...
28 char * names[3] = {"XPos", "YPos", "Val"};
[2667]29 // NTuple (Table) creation with 3 columns (double precision)
[1405]30 NTuple nt(3, names);
31 // Filling the NTuple
[2667]32 r_8 x[3];
[1405]33 for(int i=0; i<63; i++) {
34 x[0] = (i%9)-4.; x[1] = (i/9)-3.; x[2] = x[0]*x[0]+x[1]*x[1];
35 nt.Fill(x);
36 }
37 // Printing table info
38 cout << nt ;
39 // Saving object into a PPF file
40 POutPersist po("nt.ppf");
41 po << nt ;
42 \endcode
[1371]43*/
44
[763]45//++
46// Class NTuple
47// Lib Outils++
48// include ntuple.h
49//
50// Classe de ntuples
51//--
52//++
53// Links Parents
54// PPersist
55// NTupleInterface
56//--
57
58/* --Methode-- */
[2808]59//! Default constructor - To be used when reading in an NTuple.
[763]60//++
61NTuple::NTuple()
62//
63// Createur par defaut
64//--
65{
66mNVar = mNEnt = mBlk = mNBlk = 0;
67mVar = NULL;
68mVarD = NULL;
[2663]69mFgDouble = true;
[763]70mInfo = NULL;
[3392]71mThS = NULL;
[763]72}
73
74
[1405]75//! Constructor with specification of number of columns and column name
76/*!
77 \param nvar : Number of columns in the table
78 \param noms : Array of column names (length(name) < 8 characters)
79 \param blk : Optional argument specifying number of table lines
80 in a given data block
[2663]81 \param fgdouble : if \b true: internal data kept as double precision values (r_8),
82 simple precision (r_4) otherwise
[1405]83 */
[763]84//++
[2663]85NTuple::NTuple(int nvar, char** noms, int blk, bool fgdouble)
[763]86//
87// Createur d'un ntuple de `nvar' variables dont les
[3112]88// noms sont dans le tableau de chaines de caracteres `noms'
[763]89// avec `blk' d'evenements par blocks.
90//--
91{
92mNVar = mNEnt = mBlk = mNBlk = 0;
93mVar = NULL;
94mVarD = NULL;
95mInfo = NULL;
[3392]96mThS = NULL;
[2507]97if (nvar <= 0) throw ParmError("NTuple::NTuple(nvar<=0) ");
[763]98mNVar = nvar;
99mVar = new r_4[nvar];
100mVarD = new r_8[nvar];
101if (blk < 10) blk = 10;
102mBlk = blk;
[2663]103
104if (fgdouble) {
105 r_8* pt = new r_8[nvar*blk];
106 mNBlk = 1;
107 mPtrD.push_back(pt);
108 mFgDouble = true;
109}
110else {
111 r_4* pt = new r_4[nvar*blk];
112 mNBlk = 1;
113 mPtr.push_back(pt);
114 mFgDouble = false;
115}
116for(int i=0; i<nvar; i++) mNames.push_back(noms[i]);
[763]117return;
118}
119
[3112]120//! Constructor with specification of number of columns and column name
121/*!
122 \param noms : Array of column names (length(name) < 8 characters)
123 \param blk : Optional argument specifying number of table lines
124 in a given data block
125 \param fgdouble : if \b true: internal data kept as double precision values (r_8),
126 simple precision (r_4) otherwise
127 */
128NTuple::NTuple(vector<string>& noms, int blk, bool fgdouble)
129{
130mNVar = mNEnt = mBlk = mNBlk = 0;
131mVar = NULL;
132mVarD = NULL;
133mInfo = NULL;
[3392]134mThS = NULL;
[3112]135int nvar = noms.size();
136if (nvar <= 0) throw ParmError("NTuple::NTuple(nvar<=0) ");
137mNVar = nvar;
138mVar = new r_4[nvar];
139mVarD = new r_8[nvar];
140if (blk < 10) blk = 10;
141mBlk = blk;
142
143if (fgdouble) {
144 r_8* pt = new r_8[nvar*blk];
145 mNBlk = 1;
146 mPtrD.push_back(pt);
147 mFgDouble = true;
148}
149else {
150 r_4* pt = new r_4[nvar*blk];
151 mNBlk = 1;
152 mPtr.push_back(pt);
153 mFgDouble = false;
154}
155for(int i=0; i<nvar; i++) mNames.push_back(noms[i]);
156return;
157}
158
[3392]159/*!
160 Copy constructor - Copies the table definition and associated data,
161 as well as the tread safety state
162*/
[763]163// cmv 8/10/99
164//++
165NTuple::NTuple(const NTuple& NT)
166//
167// Createur par copie (clone).
168//--
169: mNVar(0), mNEnt(0), mBlk(0), mNBlk(0)
[3392]170 , mVar(NULL), mVarD(NULL), mInfo(NULL),mThS(NULL)
[763]171{
172if(NT.mNVar<=0) return; // cas ou NT est cree par defaut
173mNVar = NT.mNVar;
174mBlk = NT.mBlk;
175mVar = new r_4[NT.mNVar];
176mVarD = new r_8[NT.mNVar];
177
[2663]178mNames = NT.mNames;
179
[763]180int i;
[2663]181mFgDouble = NT.mFgDouble;
182if (mFgDouble) {
183 r_8* pt = new r_8[mNVar*mBlk];
184 mNBlk = 1; mPtrD.push_back(pt);
185 if(NT.mNEnt > 0)
186 for(i=0;i<NT.mNEnt;i++) {pt=NT.GetVecD(i,NULL); Fill(pt);}
187}
188else {
189 r_4* pt = new r_4[mNVar*mBlk];
190 mNBlk = 1; mPtr.push_back(pt);
191 for(i=0;i<NT.mNEnt;i++) {pt=NT.GetVec(i,NULL); Fill(pt);}
192}
[763]193
[2663]194mNames = NT.mNames;
[763]195
196if(NT.mInfo!=NULL) {mInfo = new DVList; *mInfo = *(NT.mInfo);}
[3392]197mThS = NULL;
198if(NT.mThS!=NULL) SetThreadSafe(true);
[763]199return;
200}
201
202
203/* --Methode-- */
204NTuple::~NTuple()
205{
206Clean();
207}
[3392]208/* --Methode-- */
209/*!
210 \brief Activate or deactivate thread-safe \b Fill() operations
211 If fg==true, create an ThSafeOp object in order to insure atomic Fill()
212 operations. if fg==false, the ThSafeOp object (mThS) of the target NTuple
213 is destroyed.
214 \warning The default Fill() operation mode for NTuples is NOT thread-safe.
215 Please note also that the thread-safety state is NOt saved to PPF (or FITS) streams.
216*/
217void NTuple::SetThreadSafe(bool fg)
218{
219if (fg) {
220 if (mThS) return;
221 else mThS = new ThSafeOp();
222}
223else {
224 if (mThS) delete mThS;
225 mThS = NULL;
226}
227}
[763]228
229/* --Methode-- */
[1405]230//! Clear the data table definition and deletes the associated data
[763]231void NTuple::Clean()
232{
233if (mVar) delete[] mVar;
234if (mVarD) delete[] mVarD;
235if (mInfo) delete mInfo;
[3392]236if (mThS) delete mThS;
[763]237int i;
[2663]238if(mNBlk>0) {
239 if (mFgDouble) for(i=0; i<mNBlk; i++) delete[] mPtrD[i];
240 else for(i=0; i<mNBlk; i++) delete[] mPtr[i];
241}
242if (mFgDouble) mPtrD.erase(mPtrD.begin(), mPtrD.end());
243else mPtr.erase(mPtr.begin(), mPtr.end());
[763]244mNVar = mNEnt = mBlk = mNBlk = 0;
245mVar = NULL;
246mVarD = NULL;
247mInfo = NULL;
[3392]248mThS = NULL;
[763]249return;
250}
251
252/* --Methode-- cmv 08/10/99 */
[1405]253//! = operator, copies the data table definition and its contents
[763]254//++
255NTuple& NTuple::operator = (const NTuple& NT)
256//
257// Operateur egal (clone).
258//--
259{
260if(this == &NT) return *this;
261Clean();
262if(NT.mNVar<=0) return *this; // cas ou NT est cree par defaut
263mNVar = NT.mNVar;
264mBlk = NT.mBlk;
265mVar = new r_4[NT.mNVar];
266mVarD = new r_8[NT.mNVar];
267
[2663]268mNames = NT.mNames;
269
[763]270int i;
[2663]271mFgDouble = NT.mFgDouble;
272if (mFgDouble) {
273 r_8* pt = new r_8[mNVar*mBlk];
274 mNBlk = 1; mPtrD.push_back(pt);
275 if(NT.mNEnt > 0)
276 for(i=0;i<NT.mNEnt;i++) {pt=NT.GetVecD(i,NULL); Fill(pt);}
277}
278else {
279 r_4* pt = new r_4[mNVar*mBlk];
280 mNBlk = 1; mPtr.push_back(pt);
281 for(i=0;i<NT.mNEnt;i++) {pt=NT.GetVec(i,NULL); Fill(pt);}
282}
[763]283
284if(NT.mInfo!=NULL) {mInfo = new DVList; *mInfo = *(NT.mInfo);}
285
286return *this;
287}
288
289/* --Methode-- */
[1405]290//! Adds an entry (a line) to the table
291/*!
292 \param x : content of the line to be appended to the table
293 */
[763]294//++
295void NTuple::Fill(r_4* x)
296//
297// Remplit le ntuple avec le tableau cd reels `x'.
298//--
299{
[3392]300if (mThS) mThS->lock(); // Thread-safe operation
[763]301int numb = mNEnt/mBlk;
302if (numb >= mNBlk) {
[2663]303 if (mFgDouble) {
304 r_8* pt = new r_8[mNVar*mBlk];
305 mNBlk++;
306 mPtrD.push_back(pt);
307 }
308 else {
309 r_4* pt = new r_4[mNVar*mBlk];
310 mNBlk++;
311 mPtr.push_back(pt);
312 }
[763]313}
[2663]314
[763]315int offb = mNEnt-numb*mBlk;
[2663]316if (mFgDouble)
317 for(int i=0; i<mNVar; i++) (mPtrD[numb]+offb*mNVar)[i] = x[i];
318else memcpy((mPtr[numb]+offb*mNVar), x, mNVar*sizeof(r_4));
[763]319mNEnt++;
[3392]320if (mThS) mThS->unlock(); // Thread-safe operation
[763]321return;
322}
323
[2663]324/* --Methode-- */
325//! Adds an entry (a line) to the table (double precision)
326/*!
327 \param x : content of the line to be appended to the table
328 */
329//++
330void NTuple::Fill(r_8* x)
331//
332// Remplit le ntuple avec le tableau double precision `x'.
333//--
334{
[3392]335if (mThS) mThS->lock(); // Thread-safe operation
[2663]336int numb = mNEnt/mBlk;
337if (numb >= mNBlk) {
338 if (mFgDouble) {
339 r_8* pt = new r_8[mNVar*mBlk];
340 mNBlk++;
341 mPtrD.push_back(pt);
342 }
343 else {
344 r_4* pt = new r_4[mNVar*mBlk];
345 mNBlk++;
346 mPtr.push_back(pt);
347 }
348}
[763]349
[2663]350int offb = mNEnt-numb*mBlk;
351if (mFgDouble)
352 memcpy((mPtrD[numb]+offb*mNVar), x, mNVar*sizeof(r_8));
353else
354 for(int i=0; i<mNVar; i++) (mPtr[numb]+offb*mNVar)[i] = x[i];
355
356mNEnt++;
[3392]357if (mThS) mThS->unlock(); // Thread-safe operation
[2663]358return;
359}
360
361
[763]362/* --Methode-- */
363//++
364float NTuple::GetVal(int n, int k) const
365//
366// Retourne la valeur de la variable `k' de l'evenement `n'.
367//--
368{
369if (n >= mNEnt) return(BADVAL);
370if ( (k < 0) || (k >= mNVar) ) return(BADVAL);
371int numb = n/mBlk;
372int offb = n-numb*mBlk;
[2663]373if ( mFgDouble) return(*(mPtrD[numb]+offb*mNVar+k));
374else return(*(mPtr[numb]+offb*mNVar+k));
[763]375}
376
377
378/* --Methode-- */
379//++
380int NTuple::IndexNom(const char* nom) const
381//
382// Retourne le numero de la variable de nom `nom'.
383//--
384{
385int i;
[2663]386string snom = nom;
[763]387for(i=0; i<mNVar; i++)
[2663]388 if ( mNames[i] == snom) return(i);
[763]389return(-1);
390}
391
392
[2663]393static char nomretour[256];
[763]394/* --Methode-- */
395//++
396char* NTuple::NomIndex(int k) const
397//
398// Retourne le nom de la variable numero 'k'
399//--
400{
401nomretour[0] = '\0';
[2663]402if ((k >= 0) && (k < mNVar)) strncpy(nomretour, mNames[k].c_str(), 255);
[763]403return(nomretour);
404}
405
406
407/* --Methode-- */
408//++
409r_4* NTuple::GetVec(int n, r_4* ret) const
410//
411// Retourne l'evenement `n' dans le vecteur `ret'.
412//--
413{
414int i;
415if (ret == NULL) ret = mVar;
416if (n >= mNEnt) {
417 for(i=0; i<mNVar; i++) ret[i] = BADVAL;
418 return(ret);
419}
420
421int numb = n/mBlk;
422int offb = n-numb*mBlk;
[2663]423if (mFgDouble) for(i=0; i<mNVar; i++) ret[i] = (mPtrD[numb]+offb*mNVar)[i];
424else memcpy(ret, (mPtr[numb]+offb*mNVar), mNVar*sizeof(r_4));
[763]425return(ret);
426}
427
428/* --Methode-- */
429//++
430r_8* NTuple::GetVecD(int n, r_8* ret) const
431//
432// Retourne l'evenement `n' dans le vecteur `ret'.
433//--
434{
435int i;
436if (ret == NULL) ret = mVarD;
[2663]437if (n >= mNEnt) {
438 for(i=0; i<mNVar; i++) ret[i] = BADVAL;
439 return(ret);
440}
441
442int numb = n/mBlk;
443int offb = n-numb*mBlk;
[2667]444if (mFgDouble) memcpy(ret, (mPtrD[numb]+offb*mNVar), mNVar*sizeof(r_8));
445else for(i=0; i<mNVar; i++) ret[i] = (mPtr[numb]+offb*mNVar)[i];
[763]446return(ret);
447}
448
449
450
451/* --Methode-- */
452//++
453DVList& NTuple::Info()
454//
455// Renvoie une référence sur l'objet DVList Associé
456//--
457{
458if (mInfo == NULL) mInfo = new DVList;
459return(*mInfo);
460}
461
462/* --Methode-- */
463//++
464void NTuple::Print(int num, int nmax) const
465//
466// Imprime `nmax' evenements a partir du numero `num'.
467//--
468{
469int i,j;
470
471printf("Num ");
[2663]472for(i=0; i<mNVar; i++) printf("%8s ", mNames[i].c_str());
[763]473putchar('\n');
474
475if (nmax <= 0) nmax = 1;
476if (num < 0) num = 0;
477nmax += num;
478if (nmax > mNEnt) nmax = mNEnt;
479for(i=num; i<nmax; i++) {
480 GetVec(i, NULL);
481 printf("%6d ", i);
482 for(j=0; j<mNVar; j++) printf("%8g ", (float)mVar[j]);
483 putchar('\n');
484}
485return;
486}
487
488/* --Methode-- */
[1405]489//! Prints table definition and number of entries
[763]490//++
491void NTuple::Show(ostream& os) const
492//
493// Imprime l'information generale sur le ntuple.
494//--
495{
[2663]496char * tt = "float";
497if (mFgDouble) tt = "double";
498os << "NTuple T=" << tt << " : NVar= " << mNVar << " NEnt=" << mNEnt
[763]499 << " (Blk Sz,Nb= " << mBlk << " ," << mNBlk << ")\n";
500os << " Variables Min Max \n";
501int i;
502double min, max;
503char buff[128];
504for(i=0; i<mNVar; i++) {
505 GetMinMax(i, min, max);
[2663]506 sprintf(buff, "%3d %16s %10g %10g \n", i, mNames[i].c_str(), min, max);
[763]507 os << (string)buff ;
508 }
509os << endl;
510}
511
512
513/* --Methode-- */
[1405]514//! Fills the table, reading lines from an ascii file
515/*!
516 \param fn : file name
517 \param defval : default value for empty cells in the ascii file
518 */
[763]519//++
520int NTuple::FillFromASCIIFile(string const& fn, float defval)
521//
522// Remplit le ntuple a partir d'un fichier ASCII.
523// Renvoie le nombre de lignes ajoutees.
524//--
525{
526if (NbColumns() < 1) {
527 cout << "NTuple::FillFromASCIIFile() Ntuple has " << NbColumns() << " columns" << endl;
528 return(-1);
529 }
530FILE * fip = fopen(fn.c_str(), "r");
531if (fip == NULL) {
532 cout << "NTuple::FillFromASCIIFile() Error opening file " << fn << endl;
533 return(-2);
534 }
535
536char lineb[4096];
537char *line;
538char* ccp;
[809]539int j,kk;
[763]540int postab, posb;
[2663]541double* xv = new double[NbColumns()];
[763]542
543int nlread = 0;
544int nvar = NbColumns();
545// On boucle sur toutes les lignes
546while (fgets(lineb,4096,fip) != NULL) {
547 lineb[4095] = '\0';
548 j = 0; line = lineb;
549// On enleve les espaces et tab de debut
550 while ( (line[j] != '\0') && ((line[j] == ' ') || (line[j] == '\t')) ) j++;
551 line = lineb+j;
552// Il faut que le premier caractere non-espace soit un digit, ou + ou - ou .
553 if (!( isdigit(line[0]) || (line[0] == '+') || (line[0] == '-') || (line[0] == '.') )) continue;
554 ccp = line;
555 for(kk=0; kk<nvar; kk++) xv[kk] = defval;
556 for(kk=0; kk<nvar; kk++) {
557// Les mots sont separes par des espaces ou des tab
558 postab = posc(ccp, '\t' );
559 posb = posc(ccp, ' ' );
560 if (postab >= 0) {
561 if (posb < 0) posb = postab;
562 else if (postab < posb) posb = postab;
563 }
564 if (posb >= 0) ccp[posb] = '\0';
565 if ( isdigit(line[0]) || (line[0] == '+') || (line[0] == '-') || (line[0] == '.') )
566 xv[kk] = atof(ccp);
567 if (posb < 0) break;
568 ccp += posb+1; j = 0;
569 while ( (ccp[j] != '\0') && ((ccp[j] == ' ') || (ccp[j] == '\t')) ) j++;
570 ccp += j;
571 }
572 Fill(xv);
573 nlread++;
574 }
575
576delete[] xv;
577cout << "NTuple::FillFromASCIIFile( " << fn << ") " << nlread << " fill from file " << endl;
578return(nlread);
579}
580
581
582// ------- Implementation de l interface NTuple ---------
583
584/* --Methode-- */
[2682]585sa_size_t NTuple::NbLines() const
[763]586{
587return(NEntry());
588}
589/* --Methode-- */
[2682]590sa_size_t NTuple::NbColumns() const
[763]591{
592return(NVar());
593}
594
595/* --Methode-- */
[2682]596r_8 * NTuple::GetLineD(sa_size_t n) const
[763]597{
598return(GetVecD(n));
599}
600
601/* --Methode-- */
[2682]602r_8 NTuple::GetCell(sa_size_t n, sa_size_t k) const
[763]603{
604return(GetVal(n, k));
605}
606
607/* --Methode-- */
[2682]608r_8 NTuple::GetCell(sa_size_t n, string const & nom) const
[763]609{
610return(GetVal(n, nom.c_str()));
611}
612
613/* --Methode-- */
614//++
[2682]615void NTuple::GetMinMax(sa_size_t k, double& min, double& max) const
[763]616//
617// Retourne le minimum et le maximum de la variable `k'.
618//--
619{
620min = 9.e19; max = -9.e19;
621if ( (k < 0) || (k >= mNVar) ) return;
622int jb,ib,i;
623double x;
624i=0;
625for(jb=0; jb< mNBlk; jb++)
626 for(ib=0; ib< mBlk; ib++) {
627 if (i >= mNEnt) break;
628 i++;
[2663]629 x = (mFgDouble) ? *(mPtrD[jb]+ib*mNVar+k) : *(mPtr[jb]+ib*mNVar+k);
[763]630 if(i==1) {min = x; max = x;}
631 if (x < min) min = x;
632 if (x > max) max = x;
633 }
634return;
635}
636
637/* --Methode-- */
638void NTuple::GetMinMax(string const & nom, double& min, double& max) const
639{
640GetMinMax(IndexNom(nom.c_str()), min, max);
641}
642
643/* --Methode-- */
[2682]644sa_size_t NTuple::ColumnIndex(string const & nom) const
[763]645{
646return(IndexNom(nom.c_str()));
647}
648
649/* --Methode-- */
[2682]650string NTuple::ColumnName(sa_size_t k) const
[763]651{
652return(NomIndex(k));
653}
654
655/* --Methode-- */
656//++
657string NTuple::VarList_C(const char* nomx) const
658//
659// Retourne une chaine de caracteres avec la declaration des noms de
660// variables. si "nomx!=NULL" , des instructions d'affectation
661// a partir d'un tableau "nomx[i]" sont ajoutees.
662//--
663{
664string rets="";
665int i;
666for(i=0; i<mNVar; i++) {
667 if ( (i%5 == 0) && (i > 0) ) rets += ";";
668 if (i%5 == 0) rets += "\ndouble ";
669 else rets += ",";
[2663]670 rets += mNames[i];
[763]671 }
672rets += "; \n";
673if (nomx) {
674 char buff[256];
675 for(i=0; i<mNVar; i++) {
[2663]676 sprintf(buff,"%s=%s[%d]; ", mNames[i].c_str(), nomx, i);
[763]677 rets += buff;
678 if ( (i%3 == 0) && (i > 0) ) rets += "\n";
679 }
680 }
681
682return(rets);
683}
684
685
686/* --Methode-- */
687//++
688string NTuple::LineHeaderToString() const
689// Retourne une chaine de caracteres avec la liste des noms de
690// variables, utilisables pour une impression
691//--
692{
693char buff[32];
694string rets=" Num ";
695for(int i=0; i<mNVar; i++) {
[2663]696 sprintf(buff, "%8s ", mNames[i].c_str());
[763]697 rets += buff;
698 }
699rets += '\n';
700return(rets);
701}
702
703/* --Methode-- */
704//++
[2682]705string NTuple::LineToString(sa_size_t n) const
[763]706// Retourne une chaine de caracteres avec le contenu de la ligne "n"
707// utilisable pour une impression
708//--
709{
710char buff[32];
711double* val;
712val = GetLineD(n);
713sprintf(buff,"%6d: ",n);
714string rets=buff;
715int i;
716for(i=0; i<mNVar; i++) {
717 sprintf(buff, "%8.3g ", val[i]);
718 rets += buff;
719 }
720rets += '\n';
721return(rets);
722}
723
[1405]724/*!
[3236]725 \class ObjFileIO<NTuple>
[1405]726 \ingroup HiStats
727 Persistence (serialisation) handler for class NTuple
728*/
[763]729
[846]730/* --Methode-- */
[763]731//++
[2341]732DECL_TEMP_SPEC /* equivalent a template <> , pour SGI-CC en particulier */
[763]733void ObjFileIO<NTuple>::WriteSelf(POutPersist& s) const
734//
735// Ecriture ppersist du ntuple.
736//--
737{
[1155]738if (dobj == NULL) return;
739
[2663]740// On ecrit cette chaine pour compatibilite avec les anciennes version (1,2)
[1155]741string strg = "NTuple";
742s.Put(strg);
743
744// On ecrit 3 uint_4 ....
[2663]745// [0]: Numero de version ;
746// [1] : bit1 non nul -> has info, bit 2 non nul mFgDouble=true
747// [2] : reserve
[1155]748uint_4 itab[3];
[2663]749itab[0] = 3; // Numero de version a 3
[1155]750itab[1] = itab[2] = 0;
751if (dobj->mInfo) itab[1] = 1;
[2663]752if (dobj->mFgDouble) itab[1] += 2;
[1155]753s.Put(itab, 3);
754
755s.Put(dobj->mNVar);
[2663]756for(int k=0; k<dobj->mNVar; k++) s.Put(dobj->mNames[k]);
[1155]757s.Put(dobj->mNEnt);
758s.Put(dobj->mBlk);
759s.Put(dobj->mNBlk);
[2663]760
[763]761if (dobj->mInfo) s << (*(dobj->mInfo));
762int jb;
[2663]763if (dobj->mFgDouble)
764 for(jb=0; jb<dobj->mNBlk; jb++)
765 s.Put(dobj->mPtrD[jb], dobj->mNVar*dobj->mBlk);
766else
767 for(jb=0; jb<dobj->mNBlk; jb++)
768 s.Put(dobj->mPtr[jb], dobj->mNVar*dobj->mBlk);
[763]769return;
770}
771
772/* --Methode-- */
773//++
[2341]774DECL_TEMP_SPEC /* equivalent a template <> , pour SGI-CC en particulier */
[763]775void ObjFileIO<NTuple>::ReadSelf(PInPersist& s)
776//
777// Lecture ppersist du ntuple.
778//--
779{
780
[1155]781if (dobj == NULL) dobj = new NTuple;
782else dobj->Clean();
[763]783
784bool hadinfo = false;
[1155]785string strg;
786s.Get(strg);
[2663]787uint_4 itab[3] = {0,0,0};
[1155]788if (strg == "NTuple") {
789 s.Get(itab, 3);
[2663]790 if ( ((itab[0] < 3) && (itab[1] != 0)) ||
791 ((itab[0] >= 3) && ((itab[1]&1) == 1)) ) hadinfo = true;
[1155]792}
793else {
794// Ancienne version de PPF NTuple - Pour savoir s'il y avait un DVList Info associe
795 char buff[256];
796 strcpy(buff, strg.c_str());
797 if (strncmp(buff+strlen(buff)-7, "HasInfo", 7) == 0) hadinfo = true;
798}
[2663]799if (itab[0] < 3) { // Lecture version anterieures V= 1 , 2
800 s.Get(dobj->mNVar);
801 dobj->mVar = new r_4[dobj->mNVar];
802 dobj->mVarD = new r_8[dobj->mNVar];
803
804 char * names = new char[dobj->mNVar*LENNAME1];
805 s.GetBytes(names, dobj->mNVar*LENNAME1);
806 for(int k=0; k<dobj->mNVar; k++) dobj->mNames.push_back(names+k*LENNAME1);
807 s.Get(dobj->mNEnt);
808 s.Get(dobj->mBlk);
809 s.Get(dobj->mNBlk);
810 if (hadinfo) { // Lecture eventuelle du DVList Info
811 if (dobj->mInfo == NULL) dobj->mInfo = new DVList;
812 s >> (*(dobj->mInfo));
[763]813 }
[2663]814 // Il n'y avait que des NTuple avec data float pour V < 3
815 dobj->mFgDouble = false;
816 int jb;
817 for(jb=0; jb<dobj->mNBlk; jb++) {
818 r_4* pt = new r_4[dobj->mNVar*dobj->mBlk];
819 dobj->mPtr.push_back(pt);
820 s.Get(dobj->mPtr[jb], dobj->mNVar*dobj->mBlk);
821 }
[763]822}
[2663]823else { // Lecture version V 3
824 s.Get(dobj->mNVar);
825 dobj->mVar = new r_4[dobj->mNVar];
826 dobj->mVarD = new r_8[dobj->mNVar];
827 string nom;
828 for(int k=0; k<dobj->mNVar; k++) {
829 s.Get(nom);
830 dobj->mNames.push_back(nom);
831 }
832 s.Get(dobj->mNEnt);
833 s.Get(dobj->mBlk);
834 s.Get(dobj->mNBlk);
835 if (hadinfo) { // Lecture eventuelle du DVList Info
836 if (dobj->mInfo == NULL) dobj->mInfo = new DVList;
837 s >> (*(dobj->mInfo));
838 }
839 // Il n'y avait que des NTuple avec data float pour V < 3
840 dobj->mFgDouble = ((itab[1]&2) == 2) ? true : false;
841 int jb;
842 if (dobj->mFgDouble) {
843 for(jb=0; jb<dobj->mNBlk; jb++) {
844 r_8* pt = new r_8[dobj->mNVar*dobj->mBlk];
845 dobj->mPtrD.push_back(pt);
846 s.Get(dobj->mPtrD[jb], dobj->mNVar*dobj->mBlk);
847 }
848 }
849 else {
850 for(jb=0; jb<dobj->mNBlk; jb++) {
851 r_4* pt = new r_4[dobj->mNVar*dobj->mBlk];
852 dobj->mPtr.push_back(pt);
853 s.Get(dobj->mPtr[jb], dobj->mNVar*dobj->mBlk);
854 }
855 }
856} // Fin lecture V3
[763]857
858}
859
[846]860
[763]861#ifdef __CXX_PRAGMA_TEMPLATES__
862#pragma define_template ObjFileIO<NTuple>
863#endif
864
865#if defined(ANSI_TEMPLATES) || defined(GNU_TEMPLATES)
[3236]866template class ObjFileIO<NTuple>;
[763]867#endif
[3236]868
869} // FIN namespace SOPHYA
Note: See TracBrowser for help on using the repository browser.