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

Last change on this file since 1405 was 1405, checked in by ansari, 25 years ago

Ajout documentation - Reza 15/2/2001

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