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

Last change on this file since 1837 was 1783, checked in by aubourg, 24 years ago

pour compilation darwin (MacOS X 10.1.1)

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