source: Sophya/trunk/SophyaLib/HiStats/basedtable.cc@ 2700

Last change on this file since 2700 was 2699, checked in by ansari, 20 years ago

1/ Corrections diverses ds BaseDataTable, en particulier GetSegment() -> GetCstSegment(), et ameliorations/debug divers
2/ Classe SWPPFDataTable debugge, rendu +/- operationnelle
3/ Gestionnaire PPersist de DataTable et SWPPFDataTable fusionnee en une seule
classe ObjFileIO<BaseDataTable> - mis ds fio_dtable.cc
4/ mis a jour histats.h avec swppfdtable.h, objlist.list et histinit.cc

Reza, 27 Avril 2005

File size: 15.3 KB
RevLine 
[2688]1#include "basedtable.h"
2#include <ctype.h>
3#include "sopnamsp.h"
4#include "pexceptions.h"
5
6/*!
7 \class SOPHYA::BaseDataTable
8 \ingroup HiStats
9 Base class for data tables. Each line represent a record
10 and the column contains a given data type.
11*/
12
13string BaseDataTable::ColTypeToString(FieldType ft, bool fgl)
14{
15 string rs;
16 switch (ft) {
17 case IntegerField :
18 if (fgl) rs = "Integer";
19 else rs = "I";
20 break;
21 case LongField :
22 if (fgl) rs = "Long Integer";
23 else rs = "L";
24 break;
25 case FloatField :
26 if (fgl) rs = "Float";
27 else rs = "F";
28 break;
29 case DoubleField :
30 if (fgl) rs = "Double";
31 else rs = "D";
32 break;
33 case ComplexField :
34 if (fgl) rs = "Complex";
35 else rs = "Zx4";
36 break;
37 case DoubleComplexField :
38 if (fgl) rs = "DoubleComplex";
39 else rs = "Zx8";
40 break;
41 case StringField :
42 if (fgl) rs = "String";
43 else rs = "S";
44 break;
45 case DateField :
46 if (fgl) rs = "Date";
47 else rs = "Date";
48 break;
49 default:
50 rs = "??";
51 break;
52 }
53 return rs;
54}
55
56/* Constructeur */
57BaseDataTable::BaseDataTable(sa_size_t segsz)
58{
59 mNEnt = 0;
60 mSegSz = (segsz > 0) ? segsz : 16;
61 mNSeg = 0;
62 mVarD = NULL;
63 mVarMTV = NULL;
64 mInfo = NULL;
65}
66
67BaseDataTable::~BaseDataTable()
68{
69 if (mVarD) delete[] mVarD;
70 if (mVarMTV) delete[] mVarMTV;
71 if (mInfo) delete mInfo;
72}
73
74sa_size_t BaseDataTable::CopyStructure(BaseDataTable const & a)
75{
76 if (NVar() > 0)
77 throw ParmError("BaseDataTable::CopyStructure() Table already has columns");
78 if (a.NVar() == 0) {
79 cout << "BaseDataTable::CopyStructure(a)/Warning Table a is not initialized" << endl;
80 return 0;
81 }
82 for (size_t kk=0; kk<a.mNames.size(); kk++)
83 AddColumn(a.mNames[kk].type, a.mNames[kk].nom);
84 return NVar();
85}
86
87//! return true is same structure
88bool BaseDataTable::CompareStructure(BaseDataTable const & a)
89{
90 if (NVar() != a.NVar()) return false;
91 for (size_t kk=0; kk<mNames.size(); kk++)
92 if ( (mNames[kk].type != a.mNames[kk].type) ||
93 (mNames[kk].nom != a.mNames[kk].nom) ) return false;
94 return true;
95}
96
97bool BaseDataTable::CheckColName(string const & cnom)
98{
99 size_t l,k;
100 l = cnom.length();
101 if (l < 1)
102 throw ParmError("BaseDataTable::CheckColName() zero length column name");
103 if (!isalpha(cnom[0]))
104 throw ParmError("BaseDataTable::CheckColName() first character not alphabetical");
105 for(k=1; k<l; k++)
106 if ((!isalnum(cnom[k])) && (cnom[k] != '_'))
107 throw ParmError("BaseDataTable::CheckColName() Non alphanumeric char in name");
108 for(k=0; k<mNames.size(); k++)
109 if (cnom == mNames[k].nom)
110 throw ParmError("BaseDataTable::CheckColName() already existing name");
111 return true;
112}
113
114//
115// A quel index correspond mon nom ?
116//
117sa_size_t BaseDataTable::IndexNom(char const* nom) const
118{
[2699]119 for(sa_size_t k=0; k<NVar(); k++)
120 if ( mNames[k].nom == nom ) return k;
121 return -1;
122 // Reza:Avril 2005 : PINtuple se base sur le renvoi de -1 et pas d'une exception
123 // throw NotFoundExc("BaseDataTable::IndexNom() : column name not found ");
[2688]124}
125
126string BaseDataTable::NomIndex(sa_size_t k) const
127{
128 if ((k < 0) || (k >= NVar()))
129 throw RangeCheckError("BaseDataTable::NomIndex() out of range column index k");
130 return mNames[k].nom ;
131}
132
133
134sa_size_t BaseDataTable::AddLine(const r_8* data)
135{
136 if (NVar() == 0)
137 throw ParmError("BaseDataTable::AddLine(const r_8*) Table has no column !");
138 if (NEntry() == SegmentSize()*NbSegments()) Extend();
139 sa_size_t n = NEntry();
140 sa_size_t bid = n/mSegSz;
141 sa_size_t off = n%mSegSz;
142 for(sa_size_t k=0; k<mIColsP.size(); k++)
143 mIColsP[k]->GetSegment(bid)[off] = (int_4)data[mIColIdx[k]];
144 for(sa_size_t k=0; k<mLColsP.size(); k++)
145 mLColsP[k]->GetSegment(bid)[off] = (int_8)data[mLColIdx[k]];
146 for(sa_size_t k=0; k<mFColsP.size(); k++)
147 mFColsP[k]->GetSegment(bid)[off] = (r_4)data[mFColIdx[k]];
148 for(sa_size_t k=0; k<mDColsP.size(); k++)
149 mDColsP[k]->GetSegment(bid)[off] = data[mDColIdx[k]];
150 for(sa_size_t k=0; k<mSColsP.size(); k++)
151 mSColsP[k]->GetSegment(bid)[off] = (string)MuTyV(data[mSColIdx[k]]);
152
153 mNEnt++;
154 return mNEnt;
155}
156
157sa_size_t BaseDataTable::AddLine(const MuTyV* data)
158{
159 if (NVar() == 0)
160 throw ParmError("BaseDataTable::AddLine(const MuTyV*) Table has no column !");
161 if (NEntry() == SegmentSize()*NbSegments()) Extend();
162 sa_size_t n = NEntry();
163 sa_size_t bid = n/mSegSz;
164 sa_size_t off = n%mSegSz;
165 for(sa_size_t k=0; k<mIColsP.size(); k++)
166 mIColsP[k]->GetSegment(bid)[off] = (int_4)data[mIColIdx[k]];
167 for(sa_size_t k=0; k<mLColsP.size(); k++)
168 mLColsP[k]->GetSegment(bid)[off] = (int_8)data[mLColIdx[k]];
169 for(sa_size_t k=0; k<mSColsP.size(); k++)
170 mSColsP[k]->GetSegment(bid)[off] = (string)data[mSColIdx[k]];
171 for(sa_size_t k=0; k<mFColsP.size(); k++)
172 mFColsP[k]->GetSegment(bid)[off] = (r_4)data[mFColIdx[k]];
173 for(sa_size_t k=0; k<mDColsP.size(); k++)
174 mDColsP[k]->GetSegment(bid)[off] = (r_8)data[mDColIdx[k]];
175
176 mNEnt++;
177 return mNEnt;
178}
179
180sa_size_t BaseDataTable::Extend()
181{
182 for(sa_size_t k=0; k<mIColsP.size(); k++)
183 mIColsP[k]->Extend();
184 for(sa_size_t k=0; k<mLColsP.size(); k++)
185 mLColsP[k]->Extend();
186 for(sa_size_t k=0; k<mFColsP.size(); k++)
187 mFColsP[k]->Extend();
188 for(sa_size_t k=0; k<mDColsP.size(); k++)
189 mDColsP[k]->Extend();
190 for(sa_size_t k=0; k<mSColsP.size(); k++)
191 mSColsP[k]->Extend();
192 mNSeg++;
193 return mNSeg;
194}
195
196
197MuTyV* BaseDataTable::GetLine(sa_size_t n) const
198{
199 if ((n < 0) || (n >= NEntry()))
200 throw RangeCheckError("BaseDataTable::GetLine() out of range line index n");
201 if (mVarMTV == NULL) mVarMTV = new MuTyV[NVar()];
202
203 sa_size_t bid = n/mSegSz;
204 sa_size_t off = n%mSegSz;
205 for(sa_size_t k=0; k<mIColsP.size(); k++)
[2699]206 mVarMTV[mIColIdx[k]] = mIColsP[k]->GetCstSegment(bid)[off];
[2688]207 for(sa_size_t k=0; k<mLColsP.size(); k++)
[2699]208 mVarMTV[mLColIdx[k]] = mLColsP[k]->GetCstSegment(bid)[off];
[2688]209 for(sa_size_t k=0; k<mFColsP.size(); k++)
[2699]210 mVarMTV[mFColIdx[k]] = mFColsP[k]->GetCstSegment(bid)[off];
[2688]211 for(sa_size_t k=0; k<mDColsP.size(); k++)
[2699]212 mVarMTV[mDColIdx[k]] = mDColsP[k]->GetCstSegment(bid)[off];
[2688]213 for(sa_size_t k=0; k<mSColsP.size(); k++)
[2699]214 mVarMTV[mSColIdx[k]] = atof(mSColsP[k]->GetCstSegment(bid)[off].c_str());
[2688]215
216 return mVarMTV;
217}
218
219void BaseDataTable::CopyMerge(BaseDataTable const& a, bool cp)
220{
221 if (cp && (NEntry() > 0) )
222 throw ParmError("BaseDataTable::CopyMerge(a) Table has entries already");
223 if (a.NVar() == 0) throw ParmError("BaseDataTable::CopyMerge(a) Table a has no column");
224 if (NVar() == 0) CopyStructure(a);
225 else if (!CompareStructure(a))
226 throw SzMismatchError("BaseDataTable::CopyMerge(a) (this,a) have different table structure");
227 if (a.NEntry() == 0) {
228 cout << " BaseDataTable::CopyMerge(a)/Warning : table a has zero (0) entry ! " << endl;
229 return;
230 }
231 for(sa_size_t kk=0; kk<a.NEntry(); kk++)
232 AddLine(a.GetLine(kk));
233}
234
235
236//! Returns the associated DVList object
237DVList& BaseDataTable::Info() const
238{
239 if (mInfo == NULL) mInfo = new DVList;
240 return(*mInfo);
241}
242
243void BaseDataTable::Print(int num, int nmax) const
244{
245 // A faire
246 return;
247}
248
249
250//! Prints table definition and number of entries
251void BaseDataTable::Show(ostream& os) const
252{
253 os << "BaseDataTable: NVar= " << NVar() << " NEnt= " << NEntry()
254 << " ( SegSize= " << SegmentSize() << " NbSegments= "
255 << NbSegments() << " )" << endl;
256 os << "--------------------------------------------------------------------" << endl;
257 os << setw(3) << "i" << ":" << setw(20) << " Name" << " ("
258 << setw(4) << "Type" << ") | "
259 << setw(15) << " Min " << " | " << setw(15) << " Max " << endl;
260 os << "--------------------------------------------------------------------" << endl;
261 r_8 min, max ;
262 for(sa_size_t i = 0 ; i < NVar() ; i++) {
263 GetMinMax(i, min, max) ;
264 string nom;
265 if (mNames[i].nom.length() > 20)
266 nom = mNames[i].nom.substr(20);
267 else nom = mNames[i].nom;
268 os << setw(3) << i << ":" << setw(20) << nom << " ("
269 << setw(4) << ColTypeToString(mNames[i].type) << ") | "
270 << setw(15) << min << " | " << setw(15) << max << endl;
271 }
272 os << "--------------------------------------------------------------------" << endl;
273 return;
274}
275
276//! NOT YET IMPLEMENTED ! - Fills table from an ascii file
277int BaseDataTable::FillFromASCIIFile(string const& fn)
278// Remplit le ntuple a partir d'un fichier ASCII.
279// Renvoie le nombre de lignes ajoutees.
280{
281// a faire
282return(0);
283}
284
285
286
287//
288// ------------------------------------
289// ------- Interface NTuple -----------
290// ------------------------------------
291//
292sa_size_t BaseDataTable::NbLines() const
293{
294 return(NEntry());
295}
296
297sa_size_t BaseDataTable::NbColumns() const
298{
299 return(NVar());
300}
301
302r_8* BaseDataTable::GetLineD(sa_size_t n) const
303{
304 if ((n < 0) || (n >= NEntry()))
305 throw RangeCheckError("BaseDataTable::GetLineD() out of range line index n");
306 if (mVarD == NULL) mVarD = new r_8[NVar()];
307
308 sa_size_t bid = n/mSegSz;
309 sa_size_t off = n%mSegSz;
310 for(sa_size_t k=0; k<mIColsP.size(); k++)
[2699]311 mVarD[mIColIdx[k]] = mIColsP[k]->GetCstSegment(bid)[off];
[2688]312 for(sa_size_t k=0; k<mLColsP.size(); k++)
[2699]313 mVarD[mLColIdx[k]] = mLColsP[k]->GetCstSegment(bid)[off];
[2688]314 for(sa_size_t k=0; k<mFColsP.size(); k++)
[2699]315 mVarD[mFColIdx[k]] = mFColsP[k]->GetCstSegment(bid)[off];
[2688]316 for(sa_size_t k=0; k<mDColsP.size(); k++)
[2699]317 mVarD[mDColIdx[k]] = mDColsP[k]->GetCstSegment(bid)[off];
[2688]318 for(sa_size_t k=0; k<mSColsP.size(); k++)
[2699]319 mVarD[mSColIdx[k]] = atof(mSColsP[k]->GetCstSegment(bid)[off].c_str());
[2688]320
321 return mVarD;
322}
323
324#define BADVAL -1.e39
325
326r_8 BaseDataTable::GetCell(sa_size_t n, sa_size_t k) const
327{
328 if ((n < 0) || (n >= NEntry()))
329 throw RangeCheckError("BaseDataTable::GetCell() out of range line index n");
[2699]330 if ((k < 0) || (k >= NVar()))
[2688]331 throw RangeCheckError("BaseDataTable::GetCell() out of range column index k");
332 double rv = BADVAL;
333 sa_size_t sk = mNames[k].ser;
334 sa_size_t bid = n/mSegSz;
335 sa_size_t off = n%mSegSz;
[2699]336
[2688]337 switch (mNames[k].type) {
338 case IntegerField :
[2699]339 rv = mIColsP[sk]->GetCstSegment(bid)[off];
[2688]340 break;
341 case LongField :
[2699]342 rv = mLColsP[sk]->GetCstSegment(bid)[off];
[2688]343 break;
344 case FloatField :
[2699]345 rv = mFColsP[sk]->GetCstSegment(bid)[off];
[2688]346 break;
347 case DoubleField :
[2699]348 rv = mDColsP[sk]->GetCstSegment(bid)[off];
[2688]349 break;
350 case StringField :
[2699]351 rv = atof(mSColsP[sk]->GetCstSegment(bid)[off].c_str());
[2688]352 break;
353 default:
354 rv = BADVAL;
355 break;
356 }
357 return rv ;
358}
359
360
361r_8 BaseDataTable::GetCell(sa_size_t n, string const& nom) const
362{
363 return GetCell(n, IndexNom(nom));
364}
365
366string BaseDataTable::GetCelltoString(sa_size_t n, sa_size_t k) const
367{
368 if ((n < 0) || (n >= NEntry()))
369 throw RangeCheckError("BaseDataTable::GetCell() out of range line index n");
[2699]370 if ((k < 0) || (k >= NVar()))
[2688]371 throw RangeCheckError("BaseDataTable::GetCell() out of range column index k");
372 MuTyV rv;;
373 sa_size_t sk = mNames[k].ser;
374 sa_size_t bid = n/mSegSz;
375 sa_size_t off = n%mSegSz;
376 switch (mNames[k].type) {
377 case IntegerField :
[2699]378 rv = mIColsP[sk]->GetCstSegment(bid)[off];
[2688]379 break;
380 case LongField :
[2699]381 rv = mLColsP[sk]->GetCstSegment(bid)[off];
[2688]382 break;
383 case FloatField :
[2699]384 rv = mFColsP[sk]->GetCstSegment(bid)[off];
[2688]385 break;
386 case DoubleField :
[2699]387 rv = mDColsP[sk]->GetCstSegment(bid)[off];
[2688]388 break;
389 case StringField :
[2699]390 rv = mSColsP[sk]->GetCstSegment(bid)[off];
[2688]391 break;
392 default:
393 rv = " ";
394 break;
395 }
396 return (string)rv ;
397}
398
399void BaseDataTable::GetMinMax(sa_size_t k, double& min, double& max) const
400{
401 min = 9E39 ; max = -9E39 ;
402 if ((k < 0) || (k >= NVar()))
403 throw RangeCheckError("BaseDataTable::GetCell() out of range column index k");
404 if (mMinMaxNEnt.size() < NVar()) {
405 mMin.clear();
406 mMax.clear();
407 mMinMaxNEnt.clear();
408 for(size_t kk=0; kk<NVar(); kk++) {
409 mMin.push_back(0.);
410 mMax.push_back(0.);
411 mMinMaxNEnt.push_back(0);
412 }
413 }
414 if (mMinMaxNEnt[k] == mNEnt) {
415 min = mMin[k];
416 max = mMax[k];
417 return;
418 }
419 sa_size_t sk = mNames[k].ser;
420
421 sa_size_t cnt = 0;
422 switch (mNames[k].type) {
423 case IntegerField :
424 for(size_t is=0; is<mIColsP[sk]->NbSegments(); is++) {
[2699]425 const int_4* sp = mIColsP[sk]->GetCstSegment(is);
[2688]426 for(size_t n=0; n<mIColsP[sk]->SegmentSize(); n++) {
427 if (cnt >= NEntry()) break;
428 if (sp[n] > max) max = sp[n];
429 if (sp[n] < min) min = sp[n];
430 cnt++;
431 }
432 }
433
434 break;
435 case LongField :
436 for(size_t is=0; is<mLColsP[sk]->NbSegments(); is++) {
[2699]437 const int_8* sp = mLColsP[sk]->GetCstSegment(is);
[2688]438 for(size_t n=0; n<mLColsP[sk]->SegmentSize(); n++) {
439 if (cnt >= NEntry()) break;
440 if (sp[n] > max) max = sp[n];
441 if (sp[n] < min) min = sp[n];
442 cnt++;
443 }
444 }
445 break;
446 case FloatField :
447 for(size_t is=0; is<mFColsP[sk]->NbSegments(); is++) {
[2699]448 const r_4* sp = mFColsP[sk]->GetCstSegment(is);
[2688]449 for(size_t n=0; n<mFColsP[sk]->SegmentSize(); n++) {
450 if (cnt >= NEntry()) break;
451 if (sp[n] > max) max = sp[n];
452 if (sp[n] < min) min = sp[n];
453 cnt++;
454 }
455 }
456 break;
457 case DoubleField :
458 for(size_t is=0; is<mDColsP[sk]->NbSegments(); is++) {
[2699]459 const r_8* sp = mDColsP[sk]->GetCstSegment(is);
[2688]460 for(size_t n=0; n<mDColsP[sk]->SegmentSize(); n++) {
461 if (cnt >= NEntry()) break;
462 if (sp[n] > max) max = sp[n];
463 if (sp[n] < min) min = sp[n];
464 cnt++;
465 }
466 }
467 break;
468 case StringField :
469 return;
470 break;
471 default:
472 return;
473 break;
474 }
475
476 mMinMaxNEnt[k] = cnt;
477 mMin[k] = min;
478 mMax[k] = max;
479 return ;
480}
481
482
483void BaseDataTable::GetMinMax(string const & nom, double& min, double& max) const
484{
485 GetMinMax(IndexNom(nom), min, max) ;
486}
487
488
489sa_size_t BaseDataTable::ColumnIndex(string const& nom) const
490{
491 return IndexNom(nom) ;
492}
493
494
495string BaseDataTable::ColumnName(sa_size_t k) const
496{
497 return NomIndex(k) ;
498}
499
500
501string BaseDataTable::VarList_C(const char* nomx) const
502{
503 string rets="";
504 sa_size_t i;
505 for(i=0; i<NVar(); i++) {
506 if ( (i%5 == 0) && (i > 0) ) rets += ";";
507 if (i%5 == 0) rets += "\ndouble ";
508 else rets += ",";
509 rets += mNames[i].nom;
510 }
511 rets += "; \n";
512 if (nomx) {
513 char buff[256];
514 for(i=0; i<NVar(); i++) {
515 rets += mNames[i].nom;
516 rets += '=';
517
[2693]518 sprintf(buff,"%s[%ld]; ", nomx, (long)i);
[2688]519 rets += buff;
520 if ( (i%3 == 0) && (i > 0) ) rets += "\n";
521 }
522 }
523 return(rets);
524}
525
526
527string BaseDataTable::LineHeaderToString() const
528{
[2699]529 string rets,s;
530
[2688]531 for(int i=0; i<NVar(); i++) {
[2699]532 s = mNames[i].nom;
533 s += ' ';
534 size_t l = s.length();
535 for(size_t ii=l; ii<10; ii++) s += ' ';
536 rets += s;
[2688]537 }
538 return(rets);
539}
540
541
542string BaseDataTable::LineToString(sa_size_t n) const
543{
544 if ((n < 0) || (n >= NEntry()))
545 throw RangeCheckError("BaseDataTable::GetCell() out of range line index n");
546 string rs;
547 MuTyV rv;;
548 sa_size_t bid = n/mSegSz;
549 sa_size_t off = n%mSegSz;
550 for(sa_size_t k=0; k<NVar(); k++) {
551 sa_size_t sk = mNames[k].ser;
552 switch (mNames[k].type) {
553 case IntegerField :
[2699]554 rv = mIColsP[sk]->GetCstSegment(bid)[off];
[2688]555 break;
556 case LongField :
[2699]557 rv = mLColsP[sk]->GetCstSegment(bid)[off];
[2688]558 break;
559 case FloatField :
[2699]560 rv = mFColsP[sk]->GetCstSegment(bid)[off];
[2688]561 break;
562 case DoubleField :
[2699]563 rv = mDColsP[sk]->GetCstSegment(bid)[off];
[2688]564 break;
565 case StringField :
[2699]566 rv = mSColsP[sk]->GetCstSegment(bid)[off];
[2688]567 break;
568 default:
569 rv = " ";
570 break;
571 }
[2699]572 string s = (string)rv;
573 s += ' ';
574 size_t l = s.length();
575 for(size_t ii=l; ii<10; ii++) s += ' ';
576 rs += s;
[2688]577 }
578 return rs;
579}
580
Note: See TracBrowser for help on using the repository browser.