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

Last change on this file since 2150 was 2109, checked in by ansari, 23 years ago

Argument par defaut pour XNTuple::SetSwapPath() - Reza 17/7/2002

File size: 25.7 KB
RevLine 
[763]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"
[1783]11#ifdef OS_MACOSX
12#include <unistd.h>
13#endif
[763]14
15#define LENNAME 31
16#define MAXLEN 128
17#define BADVAL -1.e19
18
[1371]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.
[1405]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
[1371]51*/
52
[763]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
[835]74#ifdef __MWERKS__
75// mktemp() non connu sur Mac (?) - Dominique Yvon / R. Ansari
76char * mktemp(char * Filename);
77#endif
[763]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{
[1012]85 if(ndvar) ddata = new r_8[ndvar*sz] ;
86 if(nfvar) fdata = new r_4[nfvar*sz] ;
[763]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) {
[1012]119 blk->ddata = new r_8[mD*mBlkSz] ;
120 fread(blk->ddata, sizeof(r_8), mD*mBlkSz, swf) ;
[763]121 }
122 if(mF) {
[1012]123 blk->fdata = new r_4[mF*mBlkSz] ;
124 fread(blk->fdata, sizeof(r_4), mF*mBlkSz, swf) ;
[763]125 }
126 if(mI) {
127 blk->idata = new int_4[mI*mBlkSz] ;
[1012]128 fread(blk->idata, sizeof(int_4), mI*mBlkSz, swf) ;
[763]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+") ;
[1012]150 if(!swf) throw IOExc("XNTuple::swap() - Error opening swap File");
[763]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 ;
[829]188 fseek(swf, 0, SEEK_END) ;
[763]189 // position debut du bloc
190 blk->swoff = ftell(swf) ;
[1012]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) ;
[763]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{
[2109]226 if(!glob_swp) SetSwapPath() ;
[763]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)
[1012]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 -
[763]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
[1405]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 */
[763]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{
[2109]272 if(!glob_swp) SetSwapPath() ;
[763]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
[1405]292//! Constructor with table initialized from a PPF file
[763]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{
[2109]302 if(!glob_swp) SetSwapPath() ;
[763]303 swp = glob_swp ;
304
305 PInPersist s(flnm);
306 ObjFileIO<XNTuple> fiont(this);
307 fiont.Read(s);
308 NbNT++ ;
309}
310
311
[1405]312//! Copy constructor - Copies the table definition and associated data
[763]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{
[2109]322 if(!glob_swp) SetSwapPath() ;
[763]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
[1405]339//! Clear the data table definition and deletes the associated data
[763]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
[1135]349 if(swf) {
350 fclose(swf) ; swf = NULL ;
351 remove(swf_name) ;
352 delete swf_name ; swf_name = NULL ;
353 }
[763]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//++
[1012]378// void Fill(r_8* d_data, r_4* f_data, int* i_data, char** s_data)
[763]379// Remplissage d'une ligne dans le NTuple
380// void Show(ostream& os) const
[1012]381// Impression de la liste des variables avec min-max sur le flot "os"
[763]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//--
[1405]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 */
[1012]394void XNTuple::Fill(r_8* d_data, r_4* f_data, int_4* i_data, char** s_data)
[763]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 )
[1012]405 throw ParmError("XNTuple::Fill(...) Missing (NULL) argument ");
[763]406
[1012]407 r_8 x ;
[763]408 // copie variables et update mMin, mMax
409 if(mD) {
[1012]410 memcpy(ptr[mBlk]->ddata+mOff*mD, d_data, mD*sizeof(r_8)) ;
[763]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) {
[1012]419 memcpy(ptr[mBlk]->fdata+mOff*mF, f_data, mF*sizeof(r_4)) ;
[763]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) {
[1012]428 memcpy(ptr[mBlk]->idata+mOff*mI, i_data, mI*sizeof(int_4)) ;
[763]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//
[1012]464r_8 XNTuple::GetDVal(int i, int k) const
[763]465{
466 if( i<0 || i>=mNEnt || k<0 || k>=mD )
[1012]467 throw RangeCheckError("XNTuple::GetDVal() Invalid line/column index");
[763]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//
[1012]481r_4 XNTuple::GetFVal(int i, int k) const
[763]482{
483 if( i<0 || i>=mNEnt || k<mD || k>=(mD+mF) )
[1012]484 throw RangeCheckError("XNTuple::GetFVal() Invalid line/column index");
[763]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//
[1012]499int_4 XNTuple::GetIVal(int i, int k) const
[763]500{
501 if( i<0 || i>=mNEnt || k<(mD+mF) || k>=(mD+mF+mI) )
[1012]502 throw RangeCheckError("XNTuple::GetIVal() Invalid line/column index");
503
[763]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) )
[1012]522 throw RangeCheckError("XNTuple::GetSVal() Invalid line/column index");
523
[763]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)] ;
[1012]564 mVarD = new r_8[mNVars];
[763]565 memcpy(mNames, nt.mNames, mNVars*(LENNAME+1)*sizeof(char)) ;
566 }
567 // MinMax
568 if(nt.mMin) {
[1012]569 mMin = new r_8[(mD+mF+mI)] ;
570 memcpy(mMin, nt.mMin, (mD+mF+mI)*sizeof(r_8)) ;
[763]571 }
572 if(nt.mMax) {
[1012]573 mMax = new r_8[(mD+mF+mI)] ;
574 memcpy(mMax, nt.mMax, (mD+mF+mI)*sizeof(r_8)) ;
[763]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)
[1012]585 memcpy(ptr[i]->ddata, nt.ptr[i]->ddata, mD*mBlkSz*sizeof(r_8)) ;
[763]586 if(mF)
[1012]587 memcpy(ptr[i]->fdata, nt.ptr[i]->fdata, mF*mBlkSz*sizeof(r_4)) ;
[763]588 if(mI)
[1012]589 memcpy(ptr[i]->idata, nt.ptr[i]->idata, mF*mBlkSz*sizeof(int_4)) ;
[763]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
[1405]605//! Returns the associated DVList object
[763]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
[1405]651//! Prints table definition and number of entries
[763]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
[1012]663 r_8 min, max ;
[763]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
[1405]691//! NOT YET IMPLEMENTED ! - Fills table from an ascii file
[1012]692int XNTuple::FillFromASCIIFile(string const& fn, r_8 ddval, r_4 dfval,
[763]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
[2109]702//! Defines swap file path for XNTuple objects (Default=$TMPDIR or /tmp/)
[763]703void XNTuple::SetSwapPath(char* p)
704{
[2109]705 if (p == NULL) {
706 p = getenv("TMPDIR");
707 if (p == NULL) p = "/tmp/";
708 }
[1452]709 if(!glob_swp) glob_swp = new char[MAXLEN+2] ;
710 strncpy(glob_swp,p,MAXLEN);
711 if(glob_swp[strlen(glob_swp)] != '/') strcat(glob_swp,"/");
[763]712}
713
714//
715//
716// Interface NTuple
717//
718//
719uint_4 XNTuple::NbLines() const
720{
721 return(NEntry());
722}
723
724uint_4 XNTuple::NbColumns() const
725{
726 return(NVar());
727}
728
729r_8* XNTuple::GetLineD(int n) const
730{
731 // memcpy() impossible
732 // il faut faire des GetVal
733 int i;
734 for(i = 0 ; i < mD ; i++)
735 mVarD[i] = GetDVal(n, i) ;
736 for(i = 0 ; i < mF ; i++)
[1012]737 mVarD[i+mD] = (r_8)GetFVal(n, i+mD) ;
[763]738 for(i = 0 ; i < mI ; i++)
[1012]739 mVarD[i+mD+mF] = (r_8)GetIVal(n, i+mD+mF) ;
[763]740 for(i = 0 ; i < mS ; i++)
741 mVarD[i+mD+mF+mI] = atof(GetSVal(n, i+mD+mF+mI).c_str()) ;
742 return mVarD ;
743}
744
745
746r_8 XNTuple::GetCell(int n, int k) const
747{
748 if( k<0 || k>=(mD+mF+mI+mS) ) return BADVAL ;
749 if(k<mD) return GetDVal(n,k) ;
750 if(k<(mF+mD)) return GetFVal(n,k) ;
751 if(k<(mF+mD+mI)) return GetIVal(n,k) ;
752 if(k<(mD+mF+mI+mS)) return atof(GetSVal(n,k).c_str()) ;
753 return BADVAL ;
754}
755
756
757r_8 XNTuple::GetCell(int n, string const& nom) const
758{
759 int k = IndexNom(nom.c_str()) ;
760 if(k<0) return BADVAL ;
761 if(k<mD) return GetDVal(n,k) ;
762 if(k<(mF+mD)) return GetFVal(n,k) ;
763 if(k<(mF+mD+mI)) return GetIVal(n,k) ;
764 if(k<(mD+mF+mI+mS)) return atof(GetSVal(n,k).c_str()) ;
765 return BADVAL ;
766}
767
768string XNTuple::GetCelltoString(int n, int k) const
769{
770 char buff[32];
771 if(k<0) return ("");
772 else if(k<mD)
773 { sprintf(buff, "%g", GetDVal(n,k)); return(buff) ; }
774 else if(k<(mF+mD))
775 { sprintf(buff, "%g", (double)GetFVal(n,k)); return(buff) ; }
776 else if(k<(mF+mD+mI))
777 { sprintf(buff, "%d", GetIVal(n,k)); return(buff) ; }
778 else if(k<(mD+mF+mI+mS))
779 return(GetSVal(n,k).c_str()) ;
780 return("");
781}
782
783void XNTuple::GetMinMax(int k, double& min, double& max) const
784{
785 min = 9E19 ; max = -9E19 ;
786 // variables string non traitees
787 if( k<0 || k>=(mD+mF+mI) ) return ;
788
789 min = mMin[k] ;
790 max = mMax[k] ;
791 return ;
792}
793
794
795void XNTuple::GetMinMax(string const & nom, double& min, double& max) const
796{
797 GetMinMax(IndexNom(nom.c_str()), min, max) ;
798}
799
800
801int XNTuple::ColumnIndex(string const& nom) const
802{
803 return IndexNom(nom.c_str()) ;
804}
805
806
807string XNTuple::ColumnName(int k) const
808{
809 return NomIndex(k) ;
810}
811
812
813string XNTuple::VarList_C(const char* nomx) const
814{
815 string rets = "" ;
[1012]816 rets += "/* r_8 type variables */ \n";
817 // variables r_8
[763]818 int i;
819 for(i = 0 ; i < mD ; i++) {
820 if( i>0 && (i%5)==0 ) rets += ";" ;
821 if( (i%5)==0 ) rets+="\ndouble " ;
822 else rets += ", " ;
823 rets += NomIndex(i) ;
824 }
825 if(mD) rets += ";" ;
826
[1012]827 // variables r_4
828 rets += "/* r_4 type variables */ \n";
[763]829 for(i = 0 ; i < mF ; i++) {
830 if( i>0 && (i%5)==0 ) rets += ";" ;
831 if( (i%5)==0 ) rets+="\ndouble " ;
832 else rets += ", " ;
833 rets += NomIndex(i+mD) ;
834 }
835 if(mF) rets += ";" ;
836
837 // variables int
838 rets += "/* int type variables */ \n";
839 for(i = 0 ; i < mI ; i++) {
840 if( i>0 && (i%5)==0 ) rets += ";" ;
841 if( (i%5)==0 ) rets+="\ndouble " ;
842 else rets += ", " ;
843 rets += NomIndex(i+mD+mF) ;
844 }
845 if(mI) rets += ";" ;
846
847 // variables string
848 rets += "/* string type variables */ \n";
849 for(i = 0 ; i < mS ; i++) {
850 if( i>0 && (i%5)==0 ) rets += ";" ;
851 if( (i%5)==0 ) rets+="\ndouble " ;
852 else rets += ", " ;
853 rets += NomIndex(i+mD+mF+mI) ;
854 }
[1470]855 if(mS) rets += "; \n" ;
[763]856
857 if(nomx) {
858 char buff[256] ;
859 for(i = 0 ; i < mNVars ; i++) {
860 sprintf(buff, "%s=%s[%d]; ", NomIndex(i).c_str(), nomx, i) ;
861 rets+=buff ;
862 if( (i%3 == 0) && (i>0) ) rets += "\n" ;
863 }
864 }
865 return rets ;
866}
867
868
869string XNTuple::LineHeaderToString() const
870{
871 char buff[32];
872 string rets=" Num ";
873 for(int i=0; i<mNVars; i++) {
874 sprintf(buff, "%8s ", NomIndex(i).c_str() );
875 rets += buff;
876 }
877 rets += '\n';
878 return(rets);
879
880}
881
882
883string XNTuple::LineToString(int n) const
884{
885 char buff[32];
[1012]886 r_8* val;
[763]887 val = GetLineD(n);
888 sprintf(buff,"%6d: ",n);
889 string rets=buff;
890 int i;
891 for(i=0; i<(mD+mF+mI); i++) {
892 sprintf(buff, "%8.3g ", val[i]);
893 rets += buff;
894 }
895
896 for(i = mD+mF+mI ; i < mNVars ; i++) {
897 sprintf(buff, "%8s ", GetSVal(n,i).c_str() ) ;
898 rets += buff ;
899 }
900
901 rets += '\n';
902 return(rets);
903}
904
[1405]905/*!
906 \class SOPHYA::ObjFileIO<XNTuple>
907 \ingroup HiStats
908 Persistence (serialisation) handler for class XNTuple
909*/
[763]910
911void ObjFileIO<XNTuple>::WriteSelf(POutPersist& ppout) const
912{
913 if (dobj == NULL) return;
914// On ecrit 3 uint_4 ....
915// 0: Numero de version, 1 : non nul -> has info, 2 : reserve
916 uint_4 itab[3];
917 itab[0] = 1; // Numero de version a 1
918 itab[1] = itab[2] = 0;
919 if (dobj->mInfo) itab[1] = 1;
920 ppout.Put(itab,3);
921 if (dobj->mInfo) if (dobj->mInfo) ppout << (*(dobj->mInfo));
922
923 // variables internes
924 ppout.PutI4(dobj->mNEnt) ;
925 ppout.PutI4(dobj->mNBlk) ;
926 ppout.PutI4(dobj->mBlkSz) ;
927 ppout.PutI4(dobj->mBlk) ;
928 ppout.PutI4(dobj->mOff) ;
929 ppout.PutI4(dobj->mMaxBlk) ;
930 ppout.PutI4(dobj->mStrSz) ;
931 ppout.PutI4(dobj->mD) ;
932 ppout.PutI4(dobj->mF) ;
933 ppout.PutI4(dobj->mI) ;
934 ppout.PutI4(dobj->mS) ;
935 ppout.PutI4(dobj->mNVars) ;
936
937 // Noms
938 ppout.PutBytes(dobj->mNames, dobj->mNVars*(LENNAME+1)) ;
939
940 // MinMax
941 ppout.PutR8s(dobj->mMin, (dobj->mD+dobj->mF+dobj->mI)) ;
942 ppout.PutR8s(dobj->mMax, (dobj->mD+dobj->mF+dobj->mI)) ;
943
944 // Ecriture blocs N'ecrire que si datas existent
945 for(int i = 0 ; i < dobj->mNBlk ; i++) {
946 // si bloc swappe, on le relit en douce ...
947 if( dobj->ptr[i]->sw ) dobj->read_blk(dobj->ptr[i]) ;
948 ppout.PutR8s(dobj->ptr[i]->ddata, dobj->mD*dobj->mBlkSz) ;
949 ppout.PutR4s(dobj->ptr[i]->fdata, dobj->mF*dobj->mBlkSz) ;
950 ppout.PutI4s(dobj->ptr[i]->idata, dobj->mI*dobj->mBlkSz) ;
951 ppout.PutBytes(dobj->ptr[i]->sdata, dobj->mS*dobj->mBlkSz*(dobj->mStrSz+1)) ;
952 if(dobj->ptr[i]->sw) dobj->ptr[i]->free() ;
953 }
954}
955
956
957void ObjFileIO<XNTuple>::ReadSelf(PInPersist& ppin)
958{
959 if (dobj == NULL) dobj = new XNTuple;
960 else dobj->clean() ;
961// On lit 3 uint_4 ....
962// 0: Numero de version, 1 : non nul -> has info, 2 : reserve
963 uint_4 itab[3];
964 ppin.Get(itab,3);
965 if (itab[1] != 0) { // Lecture eventuelle du DVList Info
966 if (dobj->mInfo == NULL) dobj->mInfo = new DVList;
967 ppin >> (*(dobj->mInfo));
968 }
969
970 ppin.GetI4(dobj->mNEnt) ;
971 ppin.GetI4(dobj->mNBlk) ;
972 ppin.GetI4(dobj->mBlkSz) ;
973 ppin.GetI4(dobj->mBlk) ;
974 ppin.GetI4(dobj->mOff) ;
975 ppin.GetI4(dobj->mMaxBlk) ;
976 ppin.GetI4(dobj->mStrSz) ;
977 ppin.GetI4(dobj->mD) ;
978 ppin.GetI4(dobj->mF) ;
979 ppin.GetI4(dobj->mI) ;
980 ppin.GetI4(dobj->mS) ;
981 ppin.GetI4(dobj->mNVars) ;
982
983 // Noms
984 dobj->mNames = new char[dobj->mNVars*(LENNAME+1)] ;
[1012]985 dobj->mVarD = new r_8[dobj->mNVars];
[763]986 ppin.GetBytes(dobj->mNames, dobj->mNVars*(LENNAME+1)) ;
987
988 // MinMax
989 dobj->mMin = new r_8[dobj->mD+dobj->mF+dobj->mI] ;
990 ppin.GetR8s(dobj->mMin, dobj->mD+dobj->mF+dobj->mI) ;
991 dobj->mMax = new r_8[dobj->mD+dobj->mF+dobj->mI] ;
992 ppin.GetR8s(dobj->mMax, dobj->mD+dobj->mF+dobj->mI) ;
993
994 // lecture Blocs
995 int nblk = dobj->mNBlk ;
996 dobj->mBlk = -1 ; dobj->mNBlk = 0 ;
997 for(int i = 0 ; i < nblk ; i++) {
998 dobj->add_blk() ; dobj->mBlk++ ; dobj->mNBlk++ ;
999 ppin.GetR8s(dobj->ptr[i]->ddata, dobj->mD*dobj->mBlkSz) ;
1000 ppin.GetR4s(dobj->ptr[i]->fdata, dobj->mF*dobj->mBlkSz) ;
1001 ppin.GetI4s(dobj->ptr[i]->idata, dobj->mI*dobj->mBlkSz) ;
1002 ppin.GetBytes(dobj->ptr[i]->sdata, dobj->mS*dobj->mBlkSz*(dobj->mStrSz+1)) ;
1003 }
1004}
[1012]1005
1006
1007
[763]1008
[846]1009
[763]1010#ifdef __CXX_PRAGMA_TEMPLATES__
1011#pragma define_template ObjFileIO<XNTuple>
1012#endif
1013
1014#if defined(ANSI_TEMPLATES) || defined(GNU_TEMPLATES)
1015template class ObjFileIO<XNTuple>;
1016#endif
[829]1017
1018
[835]1019#ifdef __MWERKS__
[829]1020// Bricolo Dominique Yvon pour faire marcher sur Mac
[835]1021#include <stdio.h>
1022#include <stdlib.h>
[829]1023 static long mktempMemory=0;
1024 char * mktemp(char * Filename)
1025 { sprintf(Filename,"TempFile%8i",mktempMemory);
1026 mktempMemory++;
1027 return Filename;
1028 }
1029#endif
Note: See TracBrowser for help on using the repository browser.