source: Sophya/trunk/SophyaLib/HiStats/xntuple.cc@ 3205

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

Suppression flags MWERKS (compilo CodeWarrior pour MacOS8,9) , Reza 10/04/2007

File size: 25.8 KB
Line 
1// -*- C++ -*-
2//
3// xntuple.cc
4// N. Regnault - 98-99
5// Extended NTuples
6//
7#include <string.h>
8#include "sopnamsp.h"
9#include "ppersist.h"
10#include "perrors.h"
11#include "xntuple.h"
12#ifdef OS_MACOSX
13#include <unistd.h>
14#endif
15
16#define LENNAME 31
17#define MAXLEN 128
18#define BADVAL -1.e19
19
20/*!
21 \class SOPHYA::XNTuple
22 \ingroup HiStats
23 NTuple class (a Table or 2-D data set) with the possibility of having
24 columns with int, float or string type content. In addition, this class
25 can handle large data sets, using swap space on disk.
26
27 \sa SOPHYA::BaseDataTable SOPHYA::DataTable SOPHYA::SwPPFDataTable
28
29 \deprecated
30 This class is being deprecated. Use classes derived from SOPHYA::BaseDataTable
31 whenever possible
32
33
34 \code
35 #include "xntuple.h"
36 // ...
37 char * names[4] = {"X", "X2", "XInt","XStr"};
38 // XNTuple (Table) creation with 4 columns, of integer,
39 // double(2) and string type
40 XNTuple xnt(2,0,1,1, names);
41 // Filling the NTuple
42 r_8 xd[2];
43 int_4 xi[2];
44 char xss[2][32];
45 char * xs[2] = {xss[0], xss[1]} ;
46 for(int i=0; i<50; i++) {
47 xi[0] = i; xd[0] = i+0.5; xd[1] = xd[0]*xd[0];
48 sprintf(xs[0],"X=%g", xd[0]);
49 xnt.Fill(xd, NULL, xi, xs);
50 }
51 // Printing table info
52 cout << xnt ;
53 // Saving object into a PPF file
54 POutPersist po("xnt.ppf");
55 po << xnt ;
56 \endcode
57
58*/
59
60//++
61// Class XNTuple
62// Lib Outils++
63// include xntuple.h
64//
65// Classe de ntuples
66//--
67//++
68// Links Parents
69// PPersist
70// NTupleInterface
71//--
72//++
73// Links Voir aussi
74// NTuple
75//--
76
77
78char* XNTuple::glob_swp = NULL ;
79long int XNTuple::NbNT = 0 ;
80
81
82NTBlk::NTBlk(int ndvar, int nfvar, int nivar, int nsvar, int strsz, int sz)
83 : sw(0), // pas swappe
84 swoff(-1),
85 ddata(NULL), fdata(NULL),
86 idata(NULL), sdata(NULL)
87{
88 if(ndvar) ddata = new r_8[ndvar*sz] ;
89 if(nfvar) fdata = new r_4[nfvar*sz] ;
90 if(nivar) idata = new int_4[nivar*sz] ;
91 if(nsvar) sdata = new char[nsvar*(strsz+1)*sz] ;
92}
93
94NTBlk::~NTBlk()
95{
96 free() ;
97}
98
99void NTBlk::free()
100{
101 if(ddata) delete[] ddata ; ddata = NULL ;
102 if(fdata) delete[] fdata ; fdata = NULL ;
103 if(idata) delete[] idata ; idata = NULL ;
104 if(sdata) delete[] sdata ; sdata = NULL ;
105}
106
107//
108// relit bloc ds fichier swap
109// (seulement si bloc n'est plus en memoire)
110//
111void XNTuple::read_blk(NTBlk* blk) const
112{
113 // deja en memoire ?
114 if( !blk->sw ) return ;
115
116 blk->free() ;
117
118 // On va --> blk
119 fseek(swf, blk->swoff, SEEK_SET) ;
120
121 if(mD) {
122 blk->ddata = new r_8[mD*mBlkSz] ;
123 fread(blk->ddata, sizeof(r_8), mD*mBlkSz, swf) ;
124 }
125 if(mF) {
126 blk->fdata = new r_4[mF*mBlkSz] ;
127 fread(blk->fdata, sizeof(r_4), mF*mBlkSz, swf) ;
128 }
129 if(mI) {
130 blk->idata = new int_4[mI*mBlkSz] ;
131 fread(blk->idata, sizeof(int_4), mI*mBlkSz, swf) ;
132 }
133 if(mS) {
134 blk->sdata = new char[mS*(mStrSz+1)*mBlkSz] ;
135 fread(blk->sdata, sizeof(char), mS*mBlkSz*(mStrSz+1), swf) ;
136 }
137}
138
139//
140// swappe le bloc present en memoire
141// depuis le + longtemps
142//
143void XNTuple::swap() const
144{
145 // fichier de swap ouvert ?
146 if(!swf) {
147 swf_name = new char[swp.length()+64] ;
148 strncpy(swf_name, swp.c_str(), swp.length()+1) ;
149 strcat(swf_name, "NTupleXXXXXX") ;
150 // swf_name = strdup("NTupleXXXXXX") ;
151 mktemp(swf_name) ;
152 swf = fopen(swf_name, "w+") ;
153 if(!swf) throw IOExc("XNTuple::swap() - Error opening swap File");
154 }
155
156 // bloc a swapper
157 NTBlk* blk = sw.front() ;
158
159 // bloc dans fichiers de swap ?
160 // if( blk->swoff > 0 )
161 write_blk(blk) ;
162 blk->free() ;
163
164 blk->sw = 1 ; // on marque le bloc swappe
165 sw.pop_front() ; // on le vire de la liste de swap
166 mNSwBlk++ ;
167}
168
169
170//
171// unswap()
172//
173void XNTuple::get_blk(int i) const
174{
175 if(i<0 || i>=mNBlk) return ;
176 read_blk(ptr[i]) ;
177 ptr[i]->sw = 0 ;
178 sw.push_back(ptr[i]) ;
179 mNSwBlk-- ;
180}
181
182
183//
184// ecrit le bloc en bout de fichier
185// (seulement si swoff < 0 )
186//
187void XNTuple::write_blk(NTBlk* blk) const
188{
189 // deja swappe ?
190 if( blk->swoff >= 0 ) return ;
191 fseek(swf, 0, SEEK_END) ;
192 // position debut du bloc
193 blk->swoff = ftell(swf) ;
194 if(blk->ddata) fwrite(blk->ddata, sizeof(r_8), mD*mBlkSz, swf) ;
195 if(blk->fdata) fwrite(blk->fdata, sizeof(r_4), mF*mBlkSz, swf) ;
196 if(blk->idata) fwrite(blk->idata, sizeof(int_4), mI*mBlkSz, swf) ;
197 if(blk->sdata) fwrite(blk->sdata, sizeof(char), mS*mBlkSz*(mStrSz+1), swf) ;
198}
199
200
201void XNTuple::add_blk()
202{
203 // l'ancien bloc en ecriture peut maintenant
204 // etre swappe (s'il existe)
205 if(mBlk>=0) sw.push_back(ptr[mBlk]) ;
206
207 // si pas de place, on swappe
208 if( mNBlk+1 >= mMaxBlk ) swap() ;
209
210 // nouveau bloc
211 NTBlk* tmp = new NTBlk(mD, mF, mI, mS, mStrSz, mBlkSz) ;
212 ptr.push_back(tmp) ;
213
214 // mNBlk++ ;
215 // mOff = 0 ;
216 // mBlk++ ;
217}
218
219
220XNTuple::XNTuple()
221 : mNEnt(0), mNBlk(0), mNSwBlk(0),
222 mBlkSz(0), mBlk(-1), mOff(0),
223 mMaxBlk(0), mStrSz(0),
224 mD(0), mF(0), mI(0), mS(0),
225 mVarD(NULL), mMin(NULL), mMax(NULL),
226 mNVars(0), mNames(NULL),
227 swf(NULL), swf_name(NULL), mInfo(NULL)
228{
229 if(!glob_swp) SetSwapPath() ;
230 swp = glob_swp ;
231 NbNT++ ;
232}
233
234//++
235// Titre Constructeurs
236//--
237//++
238// XNTuple(int ndvar, int nfvar, int nivar, int nsvar, char** vnames, -
239// int blk=512, int maxblk=100, int strsz=30)
240// Constructeur - Création d'un XNTuple de "ndvar" variables de type "r_8", -
241// "nfvar" de type "r_4", "nivar" de type "int" et "nsvar" de type -
242// "char*".
243//| * "blk" = taille blocs de données (en nombre d'entrées)
244//| * "maxblk" = nombre max de blocs présents en mémoire (non swappés)
245//| * "strsz" = taille des données de type char*
246// XNTuple(XNTuple const& nt)
247// Constructeur de copie.
248// XNTuple(string const& flnm)
249// Constructeur - lecture à partir d'un fichier PPersist.
250//--
251
252//! Constructor with specification colum types and names
253/*!
254 \param ndvar : Number of columns with type double (r_8)
255 \param nfvar : Number of columns with type float (r_4)
256 \param nivar : Number of columns with type integer (int_4)
257 \param nsvar : Number of columns with type string
258 \param vnames : Column names (in the order r_8 r_4 int_4 string)
259 (colum names are limited to 31 characters)
260 \param blk : data block size (in number of table lines)
261 \param maxblk : Maximum number of data block in memory
262 \param strsz : string length (for string type columns)
263 */
264XNTuple::XNTuple(int ndvar, int nfvar, int nivar, int nsvar,
265 char** vnames,
266 int blk, int maxblk, int strsz)
267 : mNEnt(0), mNBlk(0), mNSwBlk(0),
268 mBlkSz(blk), mBlk(-1), mOff(0),
269 mMaxBlk(maxblk), mStrSz(strsz),
270 mD(ndvar), mF(nfvar), mI(nivar), mS(nsvar),
271 mVarD(NULL), mMin(NULL), mMax(NULL),
272 mNVars(ndvar+nfvar+nivar+nsvar), mNames(NULL),
273 swf(NULL), swf_name(NULL), mInfo(NULL)
274{
275 if(!glob_swp) SetSwapPath() ;
276 swp = glob_swp ;
277
278 mVarD = new r_8[mNVars] ;
279 mMin = new r_8[mD+mF+mI] ;
280 int i;
281 for(i = 0 ; i < (mD+mF+mI) ; i++) mMin[i] = 9E19 ;
282 mMax = new r_8[mD+mF+mI] ;
283 for(i = 0 ; i < (mD+mF+mI) ; i++) mMax[i] = -9E19 ;
284
285 if(mNVars) mNames = new char[mNVars*(LENNAME+1)] ;
286 memset(mNames, 0, mNVars*(LENNAME+1));
287 for(i = 0 ; i < mNVars ; i++)
288 strncpy(mNames+i*(LENNAME+1), vnames[i], LENNAME);
289
290 NbNT++ ;
291}
292
293
294
295//! Constructor with table initialized from a PPF file
296XNTuple::XNTuple(string const& flnm)
297 : mNEnt(0), mNBlk(0), mNSwBlk(0),
298 mBlkSz(0), mBlk(-1), mOff(0),
299 mMaxBlk(0), mStrSz(0),
300 mD(0), mF(0), mI(0), mS(0),
301 mVarD(NULL), mMin(NULL), mMax(NULL),
302 mNVars(0), mNames(NULL),
303 swf(NULL), swf_name(NULL), mInfo(NULL)
304{
305 if(!glob_swp) SetSwapPath() ;
306 swp = glob_swp ;
307
308 PInPersist s(flnm);
309 ObjFileIO<XNTuple> fiont(this);
310 fiont.Read(s);
311 NbNT++ ;
312}
313
314
315//! Copy constructor - Copies the table definition and associated data
316XNTuple::XNTuple(XNTuple const& nt)
317 : mNEnt(0), mNBlk(0), mNSwBlk(0),
318 mBlkSz(0), mBlk(-1), mOff(0),
319 mMaxBlk(0), mStrSz(0),
320 mD(0), mF(0), mI(0), mS(0),
321 mVarD(NULL), mMin(NULL), mMax(NULL),
322 mNVars(0), mNames(NULL),
323 swf(NULL), swf_name(NULL), mInfo(NULL)
324{
325 if(!glob_swp) SetSwapPath() ;
326 swp = glob_swp ;
327 Copy(nt) ;
328 NbNT++ ;
329}
330
331
332
333XNTuple::~XNTuple()
334{
335 clean() ;
336 NbNT-- ;
337 if(NbNT==0) {delete[] glob_swp ; glob_swp = NULL;}
338}
339
340
341
342//! Clear the data table definition and deletes the associated data
343void XNTuple::clean()
344{
345 // On libere tous les blocs
346 for(int i = 0 ; i < mNBlk ; i++)
347 if(!ptr[i]->sw) delete ptr[i] ;
348 ptr.erase(ptr.begin(), ptr.end()) ;
349 sw.erase(sw.begin(), sw.end()) ;
350
351 // on ferme le fichier de swap
352 if(swf) {
353 fclose(swf) ; swf = NULL ;
354 remove(swf_name) ;
355 delete swf_name ; swf_name = NULL ;
356 }
357 // tout le monde remis a 0
358 mNEnt = 0 ; mNBlk = 0 ;
359 mNSwBlk = 0 ; mBlkSz = 0 ;
360 mBlk = -1 ; mOff = 0 ;
361 mMaxBlk = 0 ; mStrSz = 0 ;
362 mD = 0 ; mF = 0 ;
363 mI = 0 ; mS = 0 ;
364 mNVars = 0 ;
365
366
367 if(mVarD) { delete[] mVarD ; mVarD = NULL ; }
368 if(mMin) { delete[] mMin ; mMin = NULL ; }
369 if(mMax) { delete[] mMax ; mMax = NULL ; }
370
371 if(mNames) {delete[] mNames ; mNames = NULL ; }
372 if (mInfo) delete mInfo;
373
374}
375
376
377//++
378// Titre Méthodes
379//--
380//++
381// void Fill(r_8* d_data, r_4* f_data, int* i_data, char** s_data)
382// Remplissage d'une ligne dans le NTuple
383// void Show(ostream& os) const
384// Impression de la liste des variables avec min-max sur le flot "os"
385// void Show() const
386// Identique à "Show(cout)"
387// XNTuple& operator = (XNTuple const& nt)
388// Opérateur égal (=) , copie "nt" dans le premier NTuple
389//--
390//! Appends an entry (line) to the table
391/*!
392 \param d_data : double (r_8) line elements
393 \param f_data : float (r_4) line elements
394 \param i_data : integer (int_4) line elements
395 \param s_data : string line elements
396 */
397void XNTuple::Fill(r_8* d_data, r_4* f_data, int_4* i_data, char** s_data)
398{
399 // place disponible dans bloc courant ?
400 if( mOff==mBlkSz || mOff==0 ) {
401 add_blk() ; mOff = 0 ; mNBlk++ ; mBlk++ ;
402 }
403
404 if( mD && !ptr[mBlk]->ddata ||
405 mF && !ptr[mBlk]->fdata ||
406 mI && !ptr[mBlk]->idata ||
407 mS && !ptr[mBlk]->sdata )
408 throw ParmError("XNTuple::Fill(...) Missing (NULL) argument ");
409
410 r_8 x ;
411 // copie variables et update mMin, mMax
412 if(mD) {
413 memcpy(ptr[mBlk]->ddata+mOff*mD, d_data, mD*sizeof(r_8)) ;
414 for(int i = 0 ; i < mD ; i++) {
415 x = d_data[i] ;
416 if(x<mMin[i]) mMin[i] = x ;
417 if(x>mMax[i]) mMax[i] = x ;
418 }
419 }
420
421 if(mF) {
422 memcpy(ptr[mBlk]->fdata+mOff*mF, f_data, mF*sizeof(r_4)) ;
423 for(int i = 0 ; i < mF ; i++) {
424 x = f_data[i] ;
425 if(x<mMin[i+mD]) mMin[i+mD] = x ;
426 if(x>mMax[i+mD]) mMax[i+mD] = x ;
427 }
428 }
429
430 if(mI) {
431 memcpy(ptr[mBlk]->idata+mOff*mI, i_data, mI*sizeof(int_4)) ;
432 for(int i = 0 ; i < mI ; i++) {
433 x = i_data[i] ;
434 if(x<mMin[i+mD+mF]) mMin[i+mD+mF] = x ;
435 if(x>mMax[i+mD+mF]) mMax[i+mD+mF] = x ;
436 }
437 }
438 for(int i = 0 ; i < mS ; i++)
439 memcpy(ptr[mBlk]->sdata+(mOff*mS+i)*(mStrSz+1),
440 s_data[i], (strlen(s_data[i])+1)*sizeof(char)) ;
441 mOff++ ;
442 mNEnt++ ;
443}
444
445//
446// A quel index correspond mon nom ?
447//
448int XNTuple::IndexNom(char const* nom) const
449{
450 int i ;
451 for(i = 0 ; i < (mD+mF+mI+mS) ; i++)
452 if( !strncmp( mNames+i*(LENNAME+1), nom, LENNAME+1) )
453 return i ;
454 return -1 ;
455}
456
457string XNTuple::NomIndex(int k) const
458{
459 if( k<0 || k>=mNVars ) return "" ;
460 return mNames + k*(LENNAME+1) ;
461}
462
463
464//
465//
466//
467r_8 XNTuple::GetDVal(int i, int k) const
468{
469 if( i<0 || i>=mNEnt || k<0 || k>=mD )
470 throw RangeCheckError("XNTuple::GetDVal() Invalid line/column index");
471
472 // Bloc ?
473 int blk = (int)(i/mBlkSz) ;
474 int off = i%mBlkSz ;
475
476 // bloc swappe ?
477 if( ptr[blk]->sw ) { get_blk(blk) ; swap() ; }
478 return ptr[blk]->ddata[off*mD+k] ;
479}
480
481//
482//
483//
484r_4 XNTuple::GetFVal(int i, int k) const
485{
486 if( i<0 || i>=mNEnt || k<mD || k>=(mD+mF) )
487 throw RangeCheckError("XNTuple::GetFVal() Invalid line/column index");
488 k -= mD ;
489
490 // Bloc ?
491 int blk = (int)(i/mBlkSz) ;
492 int off = i%mBlkSz ;
493
494 // bloc swappe ?
495 if( ptr[blk]->sw ) { get_blk(blk) ; swap() ; }
496 return ptr[blk]->fdata[off*mF+k] ;
497}
498
499//
500//
501//
502int_4 XNTuple::GetIVal(int i, int k) const
503{
504 if( i<0 || i>=mNEnt || k<(mD+mF) || k>=(mD+mF+mI) )
505 throw RangeCheckError("XNTuple::GetIVal() Invalid line/column index");
506
507 k -= (mD+mF) ;
508
509 // Bloc ?
510 int blk = (int)(i/mBlkSz) ;
511 int off = i%mBlkSz ;
512
513 // bloc swappe ?
514 if( ptr[blk]->sw ) { get_blk(blk) ; swap() ; }
515
516 return ptr[blk]->idata[off*mI+k] ;
517}
518
519//
520//
521//
522string XNTuple::GetSVal(int i, int k) const
523{
524 if( i<0 || i>=mNEnt || k<(mD+mF+mI) || k>=(mD+mF+mI+mS) )
525 throw RangeCheckError("XNTuple::GetSVal() Invalid line/column index");
526
527 k -= (mD+mF+mI) ;
528
529 // Bloc ?
530 int blk = (int)(i/mBlkSz) ;
531 int off = i%mBlkSz ;
532
533 // bloc swappe ?
534 if( ptr[blk]->sw ) { get_blk(blk) ; swap() ; }
535
536 // copie de la chaine
537 // string ret = strdup(ptr[blk]->sdata + (off*mS+k)*(mStrSz+1)) ; // $CHECK$ EA fuite de memoire
538 // attention, strdup fait un malloc et on ne fait jamais de free...
539 // a quoi sert ce strdup ?????????
540 string ret = ptr[blk]->sdata + (off*mS+k)*(mStrSz+1) ;
541 // return ptr[blk]->sdata[k] ;
542 return ret ;
543}
544
545
546//
547// Copie bloc a bloc, avec meme parametres
548//
549void XNTuple::Copy(XNTuple const& nt)
550{
551 clean() ;
552 // Parametres
553 mNEnt = nt.mNEnt ;
554 mBlkSz = nt.mBlkSz ;
555 mOff = nt.mOff ;
556 mMaxBlk = nt.mMaxBlk ;
557 mStrSz = nt.mStrSz ;
558 mD = nt.mD ;
559 mF = nt.mF ;
560 mI = nt.mI ;
561 mS = nt.mS ;
562 mNVars = nt.mNVars ;
563
564 // noms
565 if(mNVars) {
566 mNames = new char[mNVars*(LENNAME+1)] ;
567 mVarD = new r_8[mNVars];
568 memcpy(mNames, nt.mNames, mNVars*(LENNAME+1)*sizeof(char)) ;
569 }
570 // MinMax
571 if(nt.mMin) {
572 mMin = new r_8[(mD+mF+mI)] ;
573 memcpy(mMin, nt.mMin, (mD+mF+mI)*sizeof(r_8)) ;
574 }
575 if(nt.mMax) {
576 mMax = new r_8[(mD+mF+mI)] ;
577 memcpy(mMax, nt.mMax, (mD+mF+mI)*sizeof(r_8)) ;
578 }
579
580 //dup blocs
581 mNBlk = 0 ;
582 mBlk = -1 ;
583 for(int i = 0 ; i < nt.mNBlk ; i++) {
584 add_blk() ; mBlk++ ; mNBlk++ ;
585 // si nt.ptr[i] swappe, on le relit
586 if(nt.ptr[i]->sw) nt.read_blk(nt.ptr[i]) ;
587 if(mD)
588 memcpy(ptr[i]->ddata, nt.ptr[i]->ddata, mD*mBlkSz*sizeof(r_8)) ;
589 if(mF)
590 memcpy(ptr[i]->fdata, nt.ptr[i]->fdata, mF*mBlkSz*sizeof(r_4)) ;
591 if(mI)
592 memcpy(ptr[i]->idata, nt.ptr[i]->idata, mF*mBlkSz*sizeof(int_4)) ;
593 if(mS)
594 memcpy(ptr[i]->sdata, nt.ptr[i]->sdata, mS*mBlkSz*sizeof(char)*(mStrSz+1)) ;
595 if(nt.ptr[i]->sw) nt.ptr[i]->free() ;
596 }
597
598 // DVList Info block
599 if(nt.mInfo!=NULL) {mInfo = new DVList; *mInfo = *(nt.mInfo);}
600
601}
602
603//++
604// DVList& Info()
605// Renvoie une référence sur l'objet DVList Associé
606//--
607
608//! Returns the associated DVList object
609DVList& XNTuple::Info()
610{
611 if (mInfo == NULL) mInfo = new DVList;
612 return(*mInfo);
613}
614
615void XNTuple::Print(int num, int nmax) const
616{
617 printf("XNTuple::Print() : \n") ;
618 printf(" Entrees = %d, Blocs = %d, Bloc Size = %d\n",
619 mNEnt, mNBlk, mBlkSz) ;
620 int i,j;
621 printf(" D_Vars = %d : ", mD) ;
622 for(i = 0 ; i < mD ; i++)
623 printf("%s ", NomIndex(i).c_str() ) ;
624 printf("\n") ;
625
626 printf(" F_Vars = %d : ", mF) ;
627 for(i = 0 ; i < mF ; i++)
628 printf("%s ", NomIndex(i+mD).c_str() ) ;
629 printf("\n") ;
630
631 printf(" I_Vars = %d : ", mI) ;
632 for(i = 0 ; i < mI ; i++)
633 printf("%s ", NomIndex(i+mD+mF).c_str() ) ;
634 printf("\n") ;
635
636 printf(" S_Vars = %d : ", mS) ;
637 for(i = 0 ; i < mS ; i++)
638 printf("%s ", NomIndex(i+mD+mF+mI).c_str() ) ;
639 printf("\n") ;
640
641 for(i = num ; i < num+nmax ; i++) {
642 for(j = 0 ; j < mD ; j++) printf("%f ", GetDVal(i,j)) ;
643 printf(" -- ") ;
644 for(j = 0 ; j < mF ; j++) printf("%f ", GetFVal(i,j+mD)) ;
645 printf(" -- ") ;
646 for(j = 0 ; j < mI ; j++) printf("%d ", GetIVal(i,j+mD+mF)) ;
647 printf(" -- ") ;
648 for(j = 0 ; j < mS ; j++) printf("%s ", GetSVal(i,j+mD+mF+mI).c_str()) ;
649 printf("\n") ;
650 }
651}
652
653
654//! Prints table definition and number of entries
655void XNTuple::Show(ostream& os) const
656{
657 os << "XNTuple: NVar= " << mNVars << " NEnt= " << mNEnt
658 << " (BlkSz,NBlk= " << mBlkSz << ", " << mNBlk << ")"
659 << " (mNSwBlk= " << mNSwBlk << ")" << endl ;
660 os << "(Sw File= " ; if(swf_name) os << swf_name ; os << ")" << endl ;
661
662 char* buff = new char[80] ;
663 sprintf(buff, "Variables : Type Min Max \n") ;
664 os << buff ;
665
666 r_8 min, max ;
667 int i;
668 for(i = 0 ; i < mD ; i++) {
669 GetMinMax(i, min, max) ;
670 sprintf(buff, " %-10s: D %12.6g %12.6g \n",
671 NomIndex(i).c_str(), min, max) ;
672 os << buff ;
673 }
674 for(i = 0 ; i < mF ; i++) {
675 GetMinMax(i+mD, min, max) ;
676 sprintf(buff, " %-10s: F %12.6g %12.6g \n",
677 NomIndex(i+mD).c_str(), min, max) ;
678 os << buff ;
679 }
680 for(i = 0 ; i < mI ; i++) {
681 GetMinMax(i+mD+mF, min, max) ;
682 sprintf(buff, " %-10s: I %12.6g %12.6g \n",
683 NomIndex(i+mD+mF).c_str(), min, max) ;
684 os << buff ;
685 }
686 for(i = 0 ; i < mS ; i++) {
687 sprintf(buff, " %-10s: S ----- ----- \n",
688 NomIndex(i+mD+mF+mI).c_str()) ;
689 os << buff ;
690 }
691 delete[] buff ;
692}
693
694//! NOT YET IMPLEMENTED ! - Fills table from an ascii file
695int XNTuple::FillFromASCIIFile(string const& fn, r_8 ddval, r_4 dfval,
696 int dival, const char * dsval)
697// Remplit le ntuple a partir d'un fichier ASCII.
698// Renvoie le nombre de lignes ajoutees.
699{
700// a faire
701return(0);
702}
703
704
705//! Defines swap file path for XNTuple objects (Default=$TMPDIR or /tmp/)
706void XNTuple::SetSwapPath(char* p)
707{
708 if (p == NULL) {
709 p = getenv("TMPDIR");
710 if (p == NULL) p = "/tmp/";
711 }
712 if(!glob_swp) glob_swp = new char[MAXLEN+2] ;
713 strncpy(glob_swp,p,MAXLEN);
714 if(glob_swp[strlen(glob_swp)] != '/') strcat(glob_swp,"/");
715}
716
717//
718//
719// Interface NTuple
720//
721//
722sa_size_t XNTuple::NbLines() const
723{
724 return(NEntry());
725}
726
727sa_size_t XNTuple::NbColumns() const
728{
729 return(NVar());
730}
731
732r_8* XNTuple::GetLineD(sa_size_t n) const
733{
734 // memcpy() impossible
735 // il faut faire des GetVal
736 int i;
737 for(i = 0 ; i < mD ; i++)
738 mVarD[i] = GetDVal(n, i) ;
739 for(i = 0 ; i < mF ; i++)
740 mVarD[i+mD] = (r_8)GetFVal(n, i+mD) ;
741 for(i = 0 ; i < mI ; i++)
742 mVarD[i+mD+mF] = (r_8)GetIVal(n, i+mD+mF) ;
743 for(i = 0 ; i < mS ; i++)
744 mVarD[i+mD+mF+mI] = atof(GetSVal(n, i+mD+mF+mI).c_str()) ;
745 return mVarD ;
746}
747
748
749r_8 XNTuple::GetCell(sa_size_t n, sa_size_t k) const
750{
751 if( k<0 || k>=(mD+mF+mI+mS) ) return BADVAL ;
752 if(k<mD) return GetDVal(n,k) ;
753 if(k<(mF+mD)) return GetFVal(n,k) ;
754 if(k<(mF+mD+mI)) return GetIVal(n,k) ;
755 if(k<(mD+mF+mI+mS)) return atof(GetSVal(n,k).c_str()) ;
756 return BADVAL ;
757}
758
759
760r_8 XNTuple::GetCell(sa_size_t n, string const& nom) const
761{
762 int k = IndexNom(nom.c_str()) ;
763 if(k<0) return BADVAL ;
764 if(k<mD) return GetDVal(n,k) ;
765 if(k<(mF+mD)) return GetFVal(n,k) ;
766 if(k<(mF+mD+mI)) return GetIVal(n,k) ;
767 if(k<(mD+mF+mI+mS)) return atof(GetSVal(n,k).c_str()) ;
768 return BADVAL ;
769}
770
771string XNTuple::GetCelltoString(sa_size_t n, sa_size_t k) const
772{
773 char buff[32];
774 if(k<0) return ("");
775 else if(k<mD)
776 { sprintf(buff, "%g", GetDVal(n,k)); return(buff) ; }
777 else if(k<(mF+mD))
778 { sprintf(buff, "%g", (double)GetFVal(n,k)); return(buff) ; }
779 else if(k<(mF+mD+mI))
780 { sprintf(buff, "%d", GetIVal(n,k)); return(buff) ; }
781 else if(k<(mD+mF+mI+mS))
782 return(GetSVal(n,k).c_str()) ;
783 return("");
784}
785
786void XNTuple::GetMinMax(sa_size_t k, double& min, double& max) const
787{
788 min = 9E19 ; max = -9E19 ;
789 // variables string non traitees
790 if( k<0 || k>=(mD+mF+mI) ) return ;
791
792 min = mMin[k] ;
793 max = mMax[k] ;
794 return ;
795}
796
797
798void XNTuple::GetMinMax(string const & nom, double& min, double& max) const
799{
800 GetMinMax(IndexNom(nom.c_str()), min, max) ;
801}
802
803
804sa_size_t XNTuple::ColumnIndex(string const& nom) const
805{
806 return IndexNom(nom.c_str()) ;
807}
808
809
810string XNTuple::ColumnName(sa_size_t k) const
811{
812 return NomIndex(k) ;
813}
814
815
816string XNTuple::VarList_C(const char* nomx) const
817{
818 string rets = "" ;
819 rets += "/* r_8 type variables */ \n";
820 // variables r_8
821 int i;
822 for(i = 0 ; i < mD ; i++) {
823 if( i>0 && (i%5)==0 ) rets += ";" ;
824 if( (i%5)==0 ) rets+="\ndouble " ;
825 else rets += ", " ;
826 rets += NomIndex(i) ;
827 }
828 if(mD) rets += ";" ;
829
830 // variables r_4
831 rets += "/* r_4 type variables */ \n";
832 for(i = 0 ; i < mF ; i++) {
833 if( i>0 && (i%5)==0 ) rets += ";" ;
834 if( (i%5)==0 ) rets+="\ndouble " ;
835 else rets += ", " ;
836 rets += NomIndex(i+mD) ;
837 }
838 if(mF) rets += ";" ;
839
840 // variables int
841 rets += "/* int type variables */ \n";
842 for(i = 0 ; i < mI ; i++) {
843 if( i>0 && (i%5)==0 ) rets += ";" ;
844 if( (i%5)==0 ) rets+="\ndouble " ;
845 else rets += ", " ;
846 rets += NomIndex(i+mD+mF) ;
847 }
848 if(mI) rets += ";" ;
849
850 // variables string
851 rets += "/* string type variables */ \n";
852 for(i = 0 ; i < mS ; i++) {
853 if( i>0 && (i%5)==0 ) rets += ";" ;
854 if( (i%5)==0 ) rets+="\ndouble " ;
855 else rets += ", " ;
856 rets += NomIndex(i+mD+mF+mI) ;
857 }
858 if(mS) rets += "; \n" ;
859
860 if(nomx) {
861 char buff[256] ;
862 for(i = 0 ; i < mNVars ; i++) {
863 sprintf(buff, "%s=%s[%d]; ", NomIndex(i).c_str(), nomx, i) ;
864 rets+=buff ;
865 if( (i%3 == 0) && (i>0) ) rets += "\n" ;
866 }
867 }
868 return rets ;
869}
870
871
872string XNTuple::LineHeaderToString() const
873{
874 char buff[32];
875 string rets=" Num ";
876 for(int i=0; i<mNVars; i++) {
877 sprintf(buff, "%8s ", NomIndex(i).c_str() );
878 rets += buff;
879 }
880 rets += '\n';
881 return(rets);
882
883}
884
885
886string XNTuple::LineToString(sa_size_t n) const
887{
888 char buff[32];
889 r_8* val;
890 val = GetLineD(n);
891 sprintf(buff,"%6d: ",n);
892 string rets=buff;
893 int i;
894 for(i=0; i<(mD+mF+mI); i++) {
895 sprintf(buff, "%8.3g ", val[i]);
896 rets += buff;
897 }
898
899 for(i = mD+mF+mI ; i < mNVars ; i++) {
900 sprintf(buff, "%8s ", GetSVal(n,i).c_str() ) ;
901 rets += buff ;
902 }
903
904 rets += '\n';
905 return(rets);
906}
907
908/*!
909 \class SOPHYA::ObjFileIO<XNTuple>
910 \ingroup HiStats
911 Persistence (serialisation) handler for class XNTuple
912*/
913
914DECL_TEMP_SPEC /* equivalent a template <> , pour SGI-CC en particulier */
915void ObjFileIO<XNTuple>::WriteSelf(POutPersist& ppout) const
916{
917 if (dobj == NULL) return;
918// On ecrit 3 uint_4 ....
919// 0: Numero de version, 1 : non nul -> has info, 2 : reserve
920 uint_4 itab[3];
921 itab[0] = 1; // Numero de version a 1
922 itab[1] = itab[2] = 0;
923 if (dobj->mInfo) itab[1] = 1;
924 ppout.Put(itab,3);
925 if (dobj->mInfo) if (dobj->mInfo) ppout << (*(dobj->mInfo));
926
927 // variables internes
928 ppout.PutI4(dobj->mNEnt) ;
929 ppout.PutI4(dobj->mNBlk) ;
930 ppout.PutI4(dobj->mBlkSz) ;
931 ppout.PutI4(dobj->mBlk) ;
932 ppout.PutI4(dobj->mOff) ;
933 ppout.PutI4(dobj->mMaxBlk) ;
934 ppout.PutI4(dobj->mStrSz) ;
935 ppout.PutI4(dobj->mD) ;
936 ppout.PutI4(dobj->mF) ;
937 ppout.PutI4(dobj->mI) ;
938 ppout.PutI4(dobj->mS) ;
939 ppout.PutI4(dobj->mNVars) ;
940
941 // Noms
942 ppout.PutBytes(dobj->mNames, dobj->mNVars*(LENNAME+1)) ;
943
944 // MinMax
945 ppout.PutR8s(dobj->mMin, (dobj->mD+dobj->mF+dobj->mI)) ;
946 ppout.PutR8s(dobj->mMax, (dobj->mD+dobj->mF+dobj->mI)) ;
947
948 // Ecriture blocs N'ecrire que si datas existent
949 for(int i = 0 ; i < dobj->mNBlk ; i++) {
950 // si bloc swappe, on le relit en douce ...
951 if( dobj->ptr[i]->sw ) dobj->read_blk(dobj->ptr[i]) ;
952 ppout.PutR8s(dobj->ptr[i]->ddata, dobj->mD*dobj->mBlkSz) ;
953 ppout.PutR4s(dobj->ptr[i]->fdata, dobj->mF*dobj->mBlkSz) ;
954 ppout.PutI4s(dobj->ptr[i]->idata, dobj->mI*dobj->mBlkSz) ;
955 ppout.PutBytes(dobj->ptr[i]->sdata, dobj->mS*dobj->mBlkSz*(dobj->mStrSz+1)) ;
956 if(dobj->ptr[i]->sw) dobj->ptr[i]->free() ;
957 }
958}
959
960
961DECL_TEMP_SPEC /* equivalent a template <> , pour SGI-CC en particulier */
962void ObjFileIO<XNTuple>::ReadSelf(PInPersist& ppin)
963{
964 if (dobj == NULL) dobj = new XNTuple;
965 else dobj->clean() ;
966// On lit 3 uint_4 ....
967// 0: Numero de version, 1 : non nul -> has info, 2 : reserve
968 uint_4 itab[3];
969 ppin.Get(itab,3);
970 if (itab[1] != 0) { // Lecture eventuelle du DVList Info
971 if (dobj->mInfo == NULL) dobj->mInfo = new DVList;
972 ppin >> (*(dobj->mInfo));
973 }
974
975 ppin.GetI4(dobj->mNEnt) ;
976 ppin.GetI4(dobj->mNBlk) ;
977 ppin.GetI4(dobj->mBlkSz) ;
978 ppin.GetI4(dobj->mBlk) ;
979 ppin.GetI4(dobj->mOff) ;
980 ppin.GetI4(dobj->mMaxBlk) ;
981 ppin.GetI4(dobj->mStrSz) ;
982 ppin.GetI4(dobj->mD) ;
983 ppin.GetI4(dobj->mF) ;
984 ppin.GetI4(dobj->mI) ;
985 ppin.GetI4(dobj->mS) ;
986 ppin.GetI4(dobj->mNVars) ;
987
988 // Noms
989 dobj->mNames = new char[dobj->mNVars*(LENNAME+1)] ;
990 dobj->mVarD = new r_8[dobj->mNVars];
991 ppin.GetBytes(dobj->mNames, dobj->mNVars*(LENNAME+1)) ;
992
993 // MinMax
994 dobj->mMin = new r_8[dobj->mD+dobj->mF+dobj->mI] ;
995 ppin.GetR8s(dobj->mMin, dobj->mD+dobj->mF+dobj->mI) ;
996 dobj->mMax = new r_8[dobj->mD+dobj->mF+dobj->mI] ;
997 ppin.GetR8s(dobj->mMax, dobj->mD+dobj->mF+dobj->mI) ;
998
999 // lecture Blocs
1000 int nblk = dobj->mNBlk ;
1001 dobj->mBlk = -1 ; dobj->mNBlk = 0 ;
1002 for(int i = 0 ; i < nblk ; i++) {
1003 dobj->add_blk() ; dobj->mBlk++ ; dobj->mNBlk++ ;
1004 ppin.GetR8s(dobj->ptr[i]->ddata, dobj->mD*dobj->mBlkSz) ;
1005 ppin.GetR4s(dobj->ptr[i]->fdata, dobj->mF*dobj->mBlkSz) ;
1006 ppin.GetI4s(dobj->ptr[i]->idata, dobj->mI*dobj->mBlkSz) ;
1007 ppin.GetBytes(dobj->ptr[i]->sdata, dobj->mS*dobj->mBlkSz*(dobj->mStrSz+1)) ;
1008 }
1009}
1010
1011
1012
1013
1014
1015#ifdef __CXX_PRAGMA_TEMPLATES__
1016#pragma define_template ObjFileIO<XNTuple>
1017#endif
1018
1019#if defined(ANSI_TEMPLATES) || defined(GNU_TEMPLATES)
1020template class SOPHYA::ObjFileIO<XNTuple>;
1021#endif
1022
Note: See TracBrowser for help on using the repository browser.