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

Last change on this file since 2850 was 2808, checked in by ansari, 20 years ago

MAJ documentation - Reza 14/6/2005

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