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

Last change on this file since 2745 was 2682, checked in by ansari, 20 years ago

remplacement de int par sa_size_t ds la classe interface NTuple (gestion de tres grand NTuple > 109 entrees - Reza 21/4/2005

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