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

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

Ajout operateur = pour DataTable pour eviter l utilisation d'un operateur = genere par le compilo ET correction format sprintf - Reza 26/4/2005

File size: 15.1 KB
Line 
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{
119 for(sa_size_t k=0; k<NVar(); k++)
120 if ( mNames[k].nom == nom ) return k;
121 throw NotFoundExc("BaseDataTable::IndexNom() : column name not found ");
122}
123
124string BaseDataTable::NomIndex(sa_size_t k) const
125{
126 if ((k < 0) || (k >= NVar()))
127 throw RangeCheckError("BaseDataTable::NomIndex() out of range column index k");
128 return mNames[k].nom ;
129}
130
131
132sa_size_t BaseDataTable::AddLine(const r_8* data)
133{
134 if (NVar() == 0)
135 throw ParmError("BaseDataTable::AddLine(const r_8*) Table has no column !");
136 if (NEntry() == SegmentSize()*NbSegments()) Extend();
137 sa_size_t n = NEntry();
138 sa_size_t bid = n/mSegSz;
139 sa_size_t off = n%mSegSz;
140 for(sa_size_t k=0; k<mIColsP.size(); k++)
141 mIColsP[k]->GetSegment(bid)[off] = (int_4)data[mIColIdx[k]];
142 for(sa_size_t k=0; k<mLColsP.size(); k++)
143 mLColsP[k]->GetSegment(bid)[off] = (int_8)data[mLColIdx[k]];
144 for(sa_size_t k=0; k<mFColsP.size(); k++)
145 mFColsP[k]->GetSegment(bid)[off] = (r_4)data[mFColIdx[k]];
146 for(sa_size_t k=0; k<mDColsP.size(); k++)
147 mDColsP[k]->GetSegment(bid)[off] = data[mDColIdx[k]];
148 for(sa_size_t k=0; k<mSColsP.size(); k++)
149 mSColsP[k]->GetSegment(bid)[off] = (string)MuTyV(data[mSColIdx[k]]);
150
151 mNEnt++;
152 return mNEnt;
153}
154
155sa_size_t BaseDataTable::AddLine(const MuTyV* data)
156{
157 if (NVar() == 0)
158 throw ParmError("BaseDataTable::AddLine(const MuTyV*) Table has no column !");
159 if (NEntry() == SegmentSize()*NbSegments()) Extend();
160 sa_size_t n = NEntry();
161 sa_size_t bid = n/mSegSz;
162 sa_size_t off = n%mSegSz;
163 for(sa_size_t k=0; k<mIColsP.size(); k++)
164 mIColsP[k]->GetSegment(bid)[off] = (int_4)data[mIColIdx[k]];
165 for(sa_size_t k=0; k<mLColsP.size(); k++)
166 mLColsP[k]->GetSegment(bid)[off] = (int_8)data[mLColIdx[k]];
167 for(sa_size_t k=0; k<mSColsP.size(); k++)
168 mSColsP[k]->GetSegment(bid)[off] = (string)data[mSColIdx[k]];
169 for(sa_size_t k=0; k<mFColsP.size(); k++)
170 mFColsP[k]->GetSegment(bid)[off] = (r_4)data[mFColIdx[k]];
171 for(sa_size_t k=0; k<mDColsP.size(); k++)
172 mDColsP[k]->GetSegment(bid)[off] = (r_8)data[mDColIdx[k]];
173
174 mNEnt++;
175 return mNEnt;
176}
177
178sa_size_t BaseDataTable::Extend()
179{
180 for(sa_size_t k=0; k<mIColsP.size(); k++)
181 mIColsP[k]->Extend();
182 for(sa_size_t k=0; k<mLColsP.size(); k++)
183 mLColsP[k]->Extend();
184 for(sa_size_t k=0; k<mFColsP.size(); k++)
185 mFColsP[k]->Extend();
186 for(sa_size_t k=0; k<mDColsP.size(); k++)
187 mDColsP[k]->Extend();
188 for(sa_size_t k=0; k<mSColsP.size(); k++)
189 mSColsP[k]->Extend();
190 mNSeg++;
191 return mNSeg;
192}
193
194
195MuTyV* BaseDataTable::GetLine(sa_size_t n) const
196{
197 if ((n < 0) || (n >= NEntry()))
198 throw RangeCheckError("BaseDataTable::GetLine() out of range line index n");
199 if (mVarMTV == NULL) mVarMTV = new MuTyV[NVar()];
200
201 sa_size_t bid = n/mSegSz;
202 sa_size_t off = n%mSegSz;
203 for(sa_size_t k=0; k<mIColsP.size(); k++)
204 mVarMTV[mIColIdx[k]] = mIColsP[k]->GetSegment(bid)[off];
205 for(sa_size_t k=0; k<mLColsP.size(); k++)
206 mVarMTV[mLColIdx[k]] = mLColsP[k]->GetSegment(bid)[off];
207 for(sa_size_t k=0; k<mFColsP.size(); k++)
208 mVarMTV[mFColIdx[k]] = mFColsP[k]->GetSegment(bid)[off];
209 for(sa_size_t k=0; k<mDColsP.size(); k++)
210 mVarMTV[mDColIdx[k]] = mDColsP[k]->GetSegment(bid)[off];
211 for(sa_size_t k=0; k<mSColsP.size(); k++)
212 mVarMTV[mSColIdx[k]] = atof(mSColsP[k]->GetSegment(bid)[off].c_str());
213
214 return mVarMTV;
215}
216
217void BaseDataTable::CopyMerge(BaseDataTable const& a, bool cp)
218{
219 if (cp && (NEntry() > 0) )
220 throw ParmError("BaseDataTable::CopyMerge(a) Table has entries already");
221 if (a.NVar() == 0) throw ParmError("BaseDataTable::CopyMerge(a) Table a has no column");
222 if (NVar() == 0) CopyStructure(a);
223 else if (!CompareStructure(a))
224 throw SzMismatchError("BaseDataTable::CopyMerge(a) (this,a) have different table structure");
225 if (a.NEntry() == 0) {
226 cout << " BaseDataTable::CopyMerge(a)/Warning : table a has zero (0) entry ! " << endl;
227 return;
228 }
229 for(sa_size_t kk=0; kk<a.NEntry(); kk++)
230 AddLine(a.GetLine(kk));
231}
232
233
234//! Returns the associated DVList object
235DVList& BaseDataTable::Info() const
236{
237 if (mInfo == NULL) mInfo = new DVList;
238 return(*mInfo);
239}
240
241void BaseDataTable::Print(int num, int nmax) const
242{
243 // A faire
244 return;
245}
246
247
248//! Prints table definition and number of entries
249void BaseDataTable::Show(ostream& os) const
250{
251 os << "BaseDataTable: NVar= " << NVar() << " NEnt= " << NEntry()
252 << " ( SegSize= " << SegmentSize() << " NbSegments= "
253 << NbSegments() << " )" << endl;
254 os << "--------------------------------------------------------------------" << endl;
255 os << setw(3) << "i" << ":" << setw(20) << " Name" << " ("
256 << setw(4) << "Type" << ") | "
257 << setw(15) << " Min " << " | " << setw(15) << " Max " << endl;
258 os << "--------------------------------------------------------------------" << endl;
259 r_8 min, max ;
260 for(sa_size_t i = 0 ; i < NVar() ; i++) {
261 GetMinMax(i, min, max) ;
262 string nom;
263 if (mNames[i].nom.length() > 20)
264 nom = mNames[i].nom.substr(20);
265 else nom = mNames[i].nom;
266 os << setw(3) << i << ":" << setw(20) << nom << " ("
267 << setw(4) << ColTypeToString(mNames[i].type) << ") | "
268 << setw(15) << min << " | " << setw(15) << max << endl;
269 }
270 os << "--------------------------------------------------------------------" << endl;
271 return;
272}
273
274//! NOT YET IMPLEMENTED ! - Fills table from an ascii file
275int BaseDataTable::FillFromASCIIFile(string const& fn)
276// Remplit le ntuple a partir d'un fichier ASCII.
277// Renvoie le nombre de lignes ajoutees.
278{
279// a faire
280return(0);
281}
282
283
284
285//
286// ------------------------------------
287// ------- Interface NTuple -----------
288// ------------------------------------
289//
290sa_size_t BaseDataTable::NbLines() const
291{
292 return(NEntry());
293}
294
295sa_size_t BaseDataTable::NbColumns() const
296{
297 return(NVar());
298}
299
300r_8* BaseDataTable::GetLineD(sa_size_t n) const
301{
302 if ((n < 0) || (n >= NEntry()))
303 throw RangeCheckError("BaseDataTable::GetLineD() out of range line index n");
304 if (mVarD == NULL) mVarD = new r_8[NVar()];
305
306 sa_size_t bid = n/mSegSz;
307 sa_size_t off = n%mSegSz;
308 for(sa_size_t k=0; k<mIColsP.size(); k++)
309 mVarD[mIColIdx[k]] = mIColsP[k]->GetSegment(bid)[off];
310 for(sa_size_t k=0; k<mLColsP.size(); k++)
311 mVarD[mLColIdx[k]] = mLColsP[k]->GetSegment(bid)[off];
312 for(sa_size_t k=0; k<mFColsP.size(); k++)
313 mVarD[mFColIdx[k]] = mFColsP[k]->GetSegment(bid)[off];
314 for(sa_size_t k=0; k<mDColsP.size(); k++)
315 mVarD[mDColIdx[k]] = mDColsP[k]->GetSegment(bid)[off];
316 for(sa_size_t k=0; k<mSColsP.size(); k++)
317 mVarD[mSColIdx[k]] = atof(mSColsP[k]->GetSegment(bid)[off].c_str());
318
319 return mVarD;
320}
321
322#define BADVAL -1.e39
323
324r_8 BaseDataTable::GetCell(sa_size_t n, sa_size_t k) const
325{
326 if ((n < 0) || (n >= NEntry()))
327 throw RangeCheckError("BaseDataTable::GetCell() out of range line index n");
328 if ((k < 0) || (n >= NVar()))
329 throw RangeCheckError("BaseDataTable::GetCell() out of range column index k");
330 double rv = BADVAL;
331 sa_size_t sk = mNames[k].ser;
332 sa_size_t bid = n/mSegSz;
333 sa_size_t off = n%mSegSz;
334 switch (mNames[k].type) {
335 case IntegerField :
336 rv = mIColsP[sk]->GetSegment(bid)[off];
337 break;
338 case LongField :
339 rv = mLColsP[sk]->GetSegment(bid)[off];
340 break;
341 case FloatField :
342 rv = mFColsP[sk]->GetSegment(bid)[off];
343 break;
344 case DoubleField :
345 rv = mDColsP[sk]->GetSegment(bid)[off];
346 break;
347 case StringField :
348 rv = atof(mSColsP[sk]->GetSegment(bid)[off].c_str());
349 break;
350 default:
351 rv = BADVAL;
352 break;
353 }
354 return rv ;
355}
356
357
358r_8 BaseDataTable::GetCell(sa_size_t n, string const& nom) const
359{
360 return GetCell(n, IndexNom(nom));
361}
362
363string BaseDataTable::GetCelltoString(sa_size_t n, sa_size_t k) const
364{
365 if ((n < 0) || (n >= NEntry()))
366 throw RangeCheckError("BaseDataTable::GetCell() out of range line index n");
367 if ((k < 0) || (n >= NVar()))
368 throw RangeCheckError("BaseDataTable::GetCell() out of range column index k");
369 MuTyV rv;;
370 sa_size_t sk = mNames[k].ser;
371 sa_size_t bid = n/mSegSz;
372 sa_size_t off = n%mSegSz;
373 switch (mNames[k].type) {
374 case IntegerField :
375 rv = mIColsP[sk]->GetSegment(bid)[off];
376 break;
377 case LongField :
378 rv = mLColsP[sk]->GetSegment(bid)[off];
379 break;
380 case FloatField :
381 rv = mFColsP[sk]->GetSegment(bid)[off];
382 break;
383 case DoubleField :
384 rv = mDColsP[sk]->GetSegment(bid)[off];
385 break;
386 case StringField :
387 rv = atof(mSColsP[sk]->GetSegment(bid)[off].c_str());
388 break;
389 default:
390 rv = " ";
391 break;
392 }
393 return (string)rv ;
394}
395
396void BaseDataTable::GetMinMax(sa_size_t k, double& min, double& max) const
397{
398 min = 9E39 ; max = -9E39 ;
399 if ((k < 0) || (k >= NVar()))
400 throw RangeCheckError("BaseDataTable::GetCell() out of range column index k");
401 if (mMinMaxNEnt.size() < NVar()) {
402 mMin.clear();
403 mMax.clear();
404 mMinMaxNEnt.clear();
405 for(size_t kk=0; kk<NVar(); kk++) {
406 mMin.push_back(0.);
407 mMax.push_back(0.);
408 mMinMaxNEnt.push_back(0);
409 }
410 }
411 if (mMinMaxNEnt[k] == mNEnt) {
412 min = mMin[k];
413 max = mMax[k];
414 return;
415 }
416 sa_size_t sk = mNames[k].ser;
417
418 sa_size_t cnt = 0;
419 switch (mNames[k].type) {
420 case IntegerField :
421 for(size_t is=0; is<mIColsP[sk]->NbSegments(); is++) {
422 int_4* sp = mIColsP[sk]->GetSegment(is);
423 for(size_t n=0; n<mIColsP[sk]->SegmentSize(); n++) {
424 if (cnt >= NEntry()) break;
425 if (sp[n] > max) max = sp[n];
426 if (sp[n] < min) min = sp[n];
427 cnt++;
428 }
429 }
430
431 break;
432 case LongField :
433 for(size_t is=0; is<mLColsP[sk]->NbSegments(); is++) {
434 int_8* sp = mLColsP[sk]->GetSegment(is);
435 for(size_t n=0; n<mLColsP[sk]->SegmentSize(); n++) {
436 if (cnt >= NEntry()) break;
437 if (sp[n] > max) max = sp[n];
438 if (sp[n] < min) min = sp[n];
439 cnt++;
440 }
441 }
442 break;
443 case FloatField :
444 for(size_t is=0; is<mFColsP[sk]->NbSegments(); is++) {
445 r_4* sp = mFColsP[sk]->GetSegment(is);
446 for(size_t n=0; n<mFColsP[sk]->SegmentSize(); n++) {
447 if (cnt >= NEntry()) break;
448 if (sp[n] > max) max = sp[n];
449 if (sp[n] < min) min = sp[n];
450 cnt++;
451 }
452 }
453 break;
454 case DoubleField :
455 for(size_t is=0; is<mDColsP[sk]->NbSegments(); is++) {
456 r_8* sp = mDColsP[sk]->GetSegment(is);
457 for(size_t n=0; n<mDColsP[sk]->SegmentSize(); n++) {
458 if (cnt >= NEntry()) break;
459 if (sp[n] > max) max = sp[n];
460 if (sp[n] < min) min = sp[n];
461 cnt++;
462 }
463 }
464 break;
465 case StringField :
466 return;
467 break;
468 default:
469 return;
470 break;
471 }
472
473 mMinMaxNEnt[k] = cnt;
474 mMin[k] = min;
475 mMax[k] = max;
476 return ;
477}
478
479
480void BaseDataTable::GetMinMax(string const & nom, double& min, double& max) const
481{
482 GetMinMax(IndexNom(nom), min, max) ;
483}
484
485
486sa_size_t BaseDataTable::ColumnIndex(string const& nom) const
487{
488 return IndexNom(nom) ;
489}
490
491
492string BaseDataTable::ColumnName(sa_size_t k) const
493{
494 return NomIndex(k) ;
495}
496
497
498string BaseDataTable::VarList_C(const char* nomx) const
499{
500 string rets="";
501 sa_size_t i;
502 for(i=0; i<NVar(); i++) {
503 if ( (i%5 == 0) && (i > 0) ) rets += ";";
504 if (i%5 == 0) rets += "\ndouble ";
505 else rets += ",";
506 rets += mNames[i].nom;
507 }
508 rets += "; \n";
509 if (nomx) {
510 char buff[256];
511 for(i=0; i<NVar(); i++) {
512 rets += mNames[i].nom;
513 rets += '=';
514
515 sprintf(buff,"%s[%ld]; ", nomx, (long)i);
516 rets += buff;
517 if ( (i%3 == 0) && (i > 0) ) rets += "\n";
518 }
519 }
520 return(rets);
521}
522
523
524string BaseDataTable::LineHeaderToString() const
525{
526 char buff[32];
527 string rets=" Num ";
528 for(int i=0; i<NVar(); i++) {
529 sprintf(buff, "%8s ", NomIndex(i).c_str() );
530 rets += buff;
531 }
532 rets += '\n';
533 return(rets);
534}
535
536
537string BaseDataTable::LineToString(sa_size_t n) const
538{
539 if ((n < 0) || (n >= NEntry()))
540 throw RangeCheckError("BaseDataTable::GetCell() out of range line index n");
541 string rs;
542 MuTyV rv;;
543 sa_size_t bid = n/mSegSz;
544 sa_size_t off = n%mSegSz;
545 for(sa_size_t k=0; k<NVar(); k++) {
546 sa_size_t sk = mNames[k].ser;
547 switch (mNames[k].type) {
548 case IntegerField :
549 rv = mIColsP[sk]->GetSegment(bid)[off];
550 break;
551 case LongField :
552 rv = mLColsP[sk]->GetSegment(bid)[off];
553 break;
554 case FloatField :
555 rv = mFColsP[sk]->GetSegment(bid)[off];
556 break;
557 case DoubleField :
558 rv = mDColsP[sk]->GetSegment(bid)[off];
559 break;
560 case StringField :
561 rv = atof(mSColsP[sk]->GetSegment(bid)[off].c_str());
562 break;
563 default:
564 rv = " ";
565 break;
566 }
567 rs += " ";
568 rs += (string)rv;
569 }
570 return rs;
571}
572
Note: See TracBrowser for help on using the repository browser.