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

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

Ajout namespace SOPHYA ds les fichiers .cc au lieu de include sopnamsp.h en presence de DECL_TEMP_SPEC , cmv+reza 27/04/2007

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