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

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

Ajout de la classe DataTableRow , modifs/ajout interface BaseDataTable - Reza 21/11/2005

File size: 27.3 KB
Line 
1#include "basedtable.h"
2#include <ctype.h>
3#include "sopnamsp.h"
4#include "pexceptions.h"
5
6/*!
7 \class SOPHYA::DataTableRow
8 \ingroup HiStats
9 This class is intented to be used with datatable classes
10 (inheriting from BaseDataTable) for representing a row (line)
11 of the table.
12*/
13DataTableRow::DataTableRow( vector<string>& colnames )
14{
15 if (colnames.size() < 1)
16 throw ParmError("DataTableRow::DataTableRow(vector<string>& cn) cn.size()==0 ");
17 size_ = colnames.size();
18 mtv_ = new MuTyV[ size_ ];
19 for(sa_size_t k=0; k<size_; k++)
20 nm2idx_[colnames[k]] = k;
21}
22
23DataTableRow::DataTableRow(DataTableRow const & a )
24{
25 size_ = a.size_;
26 mtv_ = new MuTyV[ size_ ];
27 nm2idx_ = a.nm2idx_;
28}
29
30MuTyV DataTableRow::get(string const& colname) const
31{
32 map<string, sa_size_t>::const_iterator it = nm2idx_.find(colname);
33 if (it == nm2idx_.end()) {
34 string msg = "DataTableRow::get( " ;
35 msg += colname; msg += " ) Not found column name";
36 throw NotFoundExc(msg);
37 }
38 return mtv_[(*it).second];
39}
40
41MuTyV& DataTableRow::get(string const& colname)
42{
43 map<string, sa_size_t>::const_iterator it = nm2idx_.find(colname);
44 if (it == nm2idx_.end()) {
45 string msg = "DataTableRow::get( " ;
46 msg += colname; msg += " ) const - Not found column name";
47 throw NotFoundExc(msg);
48 }
49 return mtv_[(*it).second];
50}
51
52ostream& DataTableRow::Print(ostream& os) const
53{
54 for(sa_size_t k=0; k<size_; k++)
55 os << (string)mtv_[k] << " ";
56 return os;
57}
58
59/*!
60 \class SOPHYA::BaseDataTable
61 \ingroup HiStats
62 Base class for data tables. Each line represent a record
63 and the column contains a given data type.
64*/
65
66/*!
67 if fgl == true , return LongForm string
68 \verbatim
69 ----------------------------------------------
70 FieldType ShortForm LongForm
71 ----------------------------------------------
72 IntegerField I Integer
73 LongField L Long Integer
74 FloatField F Float
75 DoubleField D Double
76 ComplexField Zx4 Complex
77 DoubleComplexField Zx8 DoubleComplex
78 StringField S String
79 DateTimeField T DateTime
80 ----------------------------------------------
81 \endverbatim
82*/
83string BaseDataTable::ColTypeToString(FieldType ft, bool fgl)
84{
85 string rs;
86 switch (ft) {
87 case IntegerField :
88 if (fgl) rs = "Integer";
89 else rs = "I";
90 break;
91 case LongField :
92 if (fgl) rs = "Long Integer";
93 else rs = "L";
94 break;
95 case FloatField :
96 if (fgl) rs = "Float";
97 else rs = "F";
98 break;
99 case DoubleField :
100 if (fgl) rs = "Double";
101 else rs = "D";
102 break;
103 case ComplexField :
104 if (fgl) rs = "Complex";
105 else rs = "Zx4";
106 break;
107 case DoubleComplexField :
108 if (fgl) rs = "DoubleComplex";
109 else rs = "Zx8";
110 break;
111 case StringField :
112 if (fgl) rs = "String";
113 else rs = "S";
114 break;
115 case DateTimeField :
116 if (fgl) rs = "DateTime";
117 else rs = "T";
118 break;
119 default:
120 rs = "??";
121 break;
122 }
123 return rs;
124}
125
126BaseDataTable::FieldType BaseDataTable::StringToColType(string const & sctyp)
127{
128 if ( (sctyp == "Integer") || (sctyp == "I") ) return IntegerField;
129 else if ( (sctyp == "Long Integer") || (sctyp == "L") ) return LongField;
130 else if ( (sctyp == "Float") || (sctyp == "F") ) return FloatField;
131 else if ( (sctyp == "Double") || (sctyp == "D") ) return DoubleField;
132 else if ( (sctyp == "Complex") || (sctyp == "Zx4") ) return ComplexField;
133 else if ( (sctyp == "DoubleComplex") || (sctyp == "Zx8") || (sctyp == "Z") )
134 return DoubleComplexField;
135 else if ( (sctyp == "String") || (sctyp == "S") ) return StringField;
136 else if ( (sctyp == "DateTime") || (sctyp == "T") ) return DateTimeField;
137 else return DoubleField;
138}
139
140/* Constructeur */
141BaseDataTable::BaseDataTable(sa_size_t segsz)
142{
143 mNEnt = 0;
144 mSegSz = (segsz > 0) ? segsz : 16;
145 mNSeg = 0;
146 mVarD = NULL;
147 mVarMTV = NULL;
148 mInfo = NULL;
149}
150
151BaseDataTable::~BaseDataTable()
152{
153 if (mVarD) delete[] mVarD;
154 if (mVarMTV) delete[] mVarMTV;
155 if (mInfo) delete mInfo;
156}
157
158sa_size_t BaseDataTable::CopyStructure(BaseDataTable const & a)
159{
160 if (NVar() > 0)
161 throw ParmError("BaseDataTable::CopyStructure() Table already has columns");
162 if (a.NVar() == 0) {
163 cout << "BaseDataTable::CopyStructure(a)/Warning Table a is not initialized" << endl;
164 return 0;
165 }
166 for (size_t kk=0; kk<a.mNames.size(); kk++)
167 AddColumn(a.mNames[kk].type, a.mNames[kk].nom);
168 return NVar();
169}
170
171//! return true is same structure
172bool BaseDataTable::CompareStructure(BaseDataTable const & a)
173{
174 if (NVar() != a.NVar()) return false;
175 for (size_t kk=0; kk<mNames.size(); kk++)
176 if ( (mNames[kk].type != a.mNames[kk].type) ||
177 (mNames[kk].nom != a.mNames[kk].nom) ) return false;
178 return true;
179}
180
181bool BaseDataTable::CheckColName(string const & cnom)
182{
183 size_t l,k;
184 l = cnom.length();
185 if (l < 1)
186 throw ParmError("BaseDataTable::CheckColName() zero length column name");
187 if (!isalpha(cnom[0]))
188 throw ParmError("BaseDataTable::CheckColName() first character not alphabetical");
189 for(k=1; k<l; k++)
190 if ((!isalnum(cnom[k])) && (cnom[k] != '_'))
191 throw ParmError("BaseDataTable::CheckColName() Non alphanumeric char in name");
192 for(k=0; k<mNames.size(); k++)
193 if (cnom == mNames[k].nom)
194 throw ParmError("BaseDataTable::CheckColName() already existing name");
195 return true;
196}
197
198// Retourne une structure
199/*!
200 The returned BaseDataTable object can be used for subsequent call to
201 AddRow() or GetRow() methods.
202 Generate an exception if called for a table with no columns
203*/
204DataTableRow BaseDataTable::EmptyRow()
205{
206 if (NCols == 0)
207 throw ParmError("BaseDataTable::EmptyRow() Table has no column !");
208 vector<string> nms;
209 for(sa_size_t k=0; k<NVar(); k++) nms.push_back(mNames[k].nom);
210 return DataTableRow(nms);
211}
212
213//
214// A quel index correspond mon nom ?
215//
216sa_size_t BaseDataTable::IndexNom(char const* nom) const
217{
218 for(sa_size_t k=0; k<NVar(); k++)
219 if ( mNames[k].nom == nom ) return k;
220 return -1;
221 // Reza:Avril 2005 : PINtuple se base sur le renvoi de -1 et pas d'une exception
222 // throw NotFoundExc("BaseDataTable::IndexNom() : column name not found ");
223}
224
225string BaseDataTable::NomIndex(sa_size_t k) const
226{
227 if ((k < 0) || (k >= NVar()))
228 throw RangeCheckError("BaseDataTable::NomIndex() out of range column index k");
229 return mNames[k].nom ;
230}
231
232//! Adds a row (or line) to the table with r_8* inout data
233/*!
234 The data to be added is provided as an array (vector) of double (r_8).
235 The necessary data conversion is performed, depending on each
236 column's data typeconverted to the data type.
237 Return the new number of table rows (lines / entries)
238 \param data : Data for each cell of the row to be appended
239 (data[k] k=0..NbColumns())
240*/
241sa_size_t BaseDataTable::AddRow(const r_8* data)
242{
243 if (NVar() == 0)
244 throw ParmError("BaseDataTable::AddRow(const r_8*) Table has no column !");
245 if (NEntry() == SegmentSize()*NbSegments()) Extend();
246 sa_size_t n = NEntry();
247 sa_size_t bid = n/mSegSz;
248 sa_size_t off = n%mSegSz;
249 for(sa_size_t k=0; k<mIColsP.size(); k++)
250 mIColsP[k]->GetSegment(bid)[off] = (int_4)data[mIColIdx[k]];
251 for(sa_size_t k=0; k<mLColsP.size(); k++)
252 mLColsP[k]->GetSegment(bid)[off] = (int_8)data[mLColIdx[k]];
253 for(sa_size_t k=0; k<mFColsP.size(); k++)
254 mFColsP[k]->GetSegment(bid)[off] = (r_4)data[mFColIdx[k]];
255 for(sa_size_t k=0; k<mDColsP.size(); k++)
256 mDColsP[k]->GetSegment(bid)[off] = data[mDColIdx[k]];
257 for(sa_size_t k=0; k<mYColsP.size(); k++)
258 mYColsP[k]->GetSegment(bid)[off] = complex<r_4>(data[mYColIdx[k]],0.);
259 for(sa_size_t k=0; k<mZColsP.size(); k++)
260 mZColsP[k]->GetSegment(bid)[off] = complex<r_8>(data[mZColIdx[k]],0.);
261 for(sa_size_t k=0; k<mSColsP.size(); k++)
262 mSColsP[k]->GetSegment(bid)[off] = (string)MuTyV(data[mSColIdx[k]]);
263
264 mNEnt++;
265 return mNEnt;
266}
267
268//! Adds a row (or line) to the table with input data as an array of MuTyV
269/*!
270 The data to be added is provided as an array (vector) of MuTyV.
271 The MuTyV class conversion operators are used to match against each
272 cell data type.
273 Return the new number of table rows (lines / entries)
274 \param data : Data (MuTyV*) for each cell of the row to be appended
275 (data[k] k=0..NbColumns())
276*/
277sa_size_t BaseDataTable::AddRow(const MuTyV* data)
278{
279 if (NVar() == 0)
280 throw ParmError("BaseDataTable::AddRow(const MuTyV*) Table has no column !");
281 if (NEntry() == SegmentSize()*NbSegments()) Extend();
282 sa_size_t n = NEntry();
283 sa_size_t bid = n/mSegSz;
284 sa_size_t off = n%mSegSz;
285 for(sa_size_t k=0; k<mIColsP.size(); k++)
286 mIColsP[k]->GetSegment(bid)[off] = (int_4)data[mIColIdx[k]];
287 for(sa_size_t k=0; k<mLColsP.size(); k++)
288 mLColsP[k]->GetSegment(bid)[off] = (int_8)data[mLColIdx[k]];
289 for(sa_size_t k=0; k<mSColsP.size(); k++)
290 mSColsP[k]->GetSegment(bid)[off] = (string)data[mSColIdx[k]];
291 for(sa_size_t k=0; k<mFColsP.size(); k++)
292 mFColsP[k]->GetSegment(bid)[off] = (r_4)data[mFColIdx[k]];
293 for(sa_size_t k=0; k<mDColsP.size(); k++)
294 mDColsP[k]->GetSegment(bid)[off] = (r_8)data[mDColIdx[k]];
295 for(sa_size_t k=0; k<mYColsP.size(); k++)
296 mYColsP[k]->GetSegment(bid)[off] =
297 complex<r_4>(data[mYColIdx[k]].GetRealPart(), data[mYColIdx[k]].GetImagPart());
298 for(sa_size_t k=0; k<mZColsP.size(); k++)
299 mZColsP[k]->GetSegment(bid)[off] =
300 complex<r_8>(data[mZColIdx[k]].GetRealPart(), data[mZColIdx[k]].GetImagPart());
301
302 mNEnt++;
303 return mNEnt;
304}
305//! Adds a row (or line) to the table with input data as DataTableRow object
306/*!
307 The internal MuTyV array of the object contains the date and the
308 MuTyV class conversion operators are used to match against each
309 cell data type.
310 Only the size of the input data object is checked.
311 Return the new number of table rows (lines / entries)
312 \param data : Data for each cell of the row to be appended
313 (data[k] k=0..NbColumns())
314*/
315sa_size_t BaseDataTable::AddRow(DataTableRow const& data)
316{
317 if ( data.Size() != NCols() )
318 throw SzMismatchError(" BaseDataTable::AddRow() - data.Size() != NCols() ");
319 return AddRow(data.MTVPtr());
320}
321
322/*!
323 Extends the table (in the row direction). This method is called automatically when needed.
324*/
325sa_size_t BaseDataTable::Extend()
326{
327 for(sa_size_t k=0; k<mIColsP.size(); k++)
328 mIColsP[k]->Extend();
329 for(sa_size_t k=0; k<mLColsP.size(); k++)
330 mLColsP[k]->Extend();
331 for(sa_size_t k=0; k<mFColsP.size(); k++)
332 mFColsP[k]->Extend();
333 for(sa_size_t k=0; k<mDColsP.size(); k++)
334 mDColsP[k]->Extend();
335 for(sa_size_t k=0; k<mYColsP.size(); k++)
336 mYColsP[k]->Extend();
337 for(sa_size_t k=0; k<mZColsP.size(); k++)
338 mZColsP[k]->Extend();
339 for(sa_size_t k=0; k<mSColsP.size(); k++)
340 mSColsP[k]->Extend();
341 mNSeg++;
342 return mNSeg;
343}
344
345/*!
346 Fills the input \b row object with the content of row \b n.
347 Return a reference to the input \b row object.
348 Generate an exception if the input \b row object has the wrong size.
349 This method is slower(less efficient) than the GetRow(n) method.
350*/
351DataTableRow& BaseDataTable::GetRow(sa_size_t n, DataTableRow& row) const
352{
353 if ( row.Size() != NCols() )
354 throw SzMismatchError(" BaseDataTable::GetRow(n, row) - row.Size() != NCols() ");
355 MuTyV* rmtv = GetRow(n);
356 for(sa_size_t k=0; k<NCols(); k++)
357 row[k] = rmtv[k];
358 return row;
359}
360
361MuTyV* BaseDataTable::GetRow(sa_size_t n) const
362{
363 if ((n < 0) || (n >= NEntry()))
364 throw RangeCheckError("BaseDataTable::GetRow() out of range line index n");
365 if (mVarMTV == NULL) mVarMTV = new MuTyV[NVar()];
366
367 sa_size_t bid = n/mSegSz;
368 sa_size_t off = n%mSegSz;
369 for(sa_size_t k=0; k<mIColsP.size(); k++)
370 mVarMTV[mIColIdx[k]] = mIColsP[k]->GetCstSegment(bid)[off];
371 for(sa_size_t k=0; k<mLColsP.size(); k++)
372 mVarMTV[mLColIdx[k]] = mLColsP[k]->GetCstSegment(bid)[off];
373 for(sa_size_t k=0; k<mFColsP.size(); k++)
374 mVarMTV[mFColIdx[k]] = mFColsP[k]->GetCstSegment(bid)[off];
375 for(sa_size_t k=0; k<mDColsP.size(); k++)
376 mVarMTV[mDColIdx[k]] = mDColsP[k]->GetCstSegment(bid)[off];
377 for(sa_size_t k=0; k<mYColsP.size(); k++)
378 mVarMTV[mYColIdx[k]] = mYColsP[k]->GetCstSegment(bid)[off];
379 for(sa_size_t k=0; k<mZColsP.size(); k++)
380 mVarMTV[mZColIdx[k]] = mZColsP[k]->GetCstSegment(bid)[off];
381 for(sa_size_t k=0; k<mSColsP.size(); k++)
382 mVarMTV[mSColIdx[k]] = atof(mSColsP[k]->GetCstSegment(bid)[off].c_str());
383
384 return mVarMTV;
385}
386
387#define BADVAL -1.e39
388
389TVector<r_8> BaseDataTable::GetColumnD(sa_size_t k) const
390{
391 if ((k < 0) || (k >= NVar()))
392 throw RangeCheckError("BaseDataTable::GetColumnD() out of range column index k");
393 sa_size_t sk = mNames[k].ser;
394 sa_size_t i = 0;
395 TVector<r_8> rv(NEntry());
396
397 for (sa_size_t is=0; is<NbSegments(); is++) {
398 switch (mNames[k].type) {
399 case IntegerField :
400 for(sa_size_t j=0; j<SegmentSize(); j++,i++)
401 rv(i) = mIColsP[sk]->GetCstSegment(is)[j];
402 break;
403 case LongField :
404 for(sa_size_t j=0; j<SegmentSize(); j++,i++)
405 rv(i) = mLColsP[sk]->GetCstSegment(is)[j];
406 break;
407 case FloatField :
408 for(sa_size_t j=0; j<SegmentSize(); j++,i++)
409 rv(i) = mFColsP[sk]->GetCstSegment(is)[j];
410 break;
411 case DoubleField :
412 case DateTimeField :
413 for(sa_size_t j=0; j<SegmentSize(); j++,i++)
414 rv(i) = mDColsP[sk]->GetCstSegment(is)[j];
415 break;
416 case ComplexField :
417 for(sa_size_t j=0; j<SegmentSize(); j++,i++)
418 rv(i) = mYColsP[sk]->GetCstSegment(is)[j].real();
419 break;
420 case DoubleComplexField :
421 for(sa_size_t j=0; j<SegmentSize(); j++,i++)
422 rv(i) = mZColsP[sk]->GetCstSegment(is)[j].real();
423 break;
424 case StringField :
425 for(sa_size_t j=0; j<SegmentSize(); j++,i++)
426 rv = atof(mSColsP[sk]->GetCstSegment(is)[j].c_str());
427 break;
428 default:
429 for(sa_size_t j=0; j<SegmentSize(); j++,i++) rv(i) = BADVAL;
430 break;
431 }
432 }
433 return rv ;
434}
435
436void BaseDataTable::CopyMerge(BaseDataTable const& a, bool cp)
437{
438 if (cp && (NEntry() > 0) )
439 throw ParmError("BaseDataTable::CopyMerge(a) Table has entries already");
440 if (a.NVar() == 0) throw ParmError("BaseDataTable::CopyMerge(a) Table a has no column");
441 if (NVar() == 0) CopyStructure(a);
442 else if (!CompareStructure(a))
443 throw SzMismatchError("BaseDataTable::CopyMerge(a) (this,a) have different table structure");
444 if (a.NEntry() == 0) {
445 cout << " BaseDataTable::CopyMerge(a)/Warning : table a has zero (0) entry ! " << endl;
446 return;
447 }
448 for(sa_size_t kk=0; kk<a.NEntry(); kk++)
449 AddRow(a.GetLine(kk));
450}
451
452
453//! Returns the associated DVList object
454DVList& BaseDataTable::Info() const
455{
456 if (mInfo == NULL) mInfo = new DVList;
457 return(*mInfo);
458}
459
460/*!
461 Formatted (text) output of the table, for lines lstart <= l_index < lend , with step lstep
462 \param os : output stream (formatted output)
463 \param lstart : start row (line) index
464 \param lend : end row (line) index
465 \param lstep : row index increment
466*/
467ostream& BaseDataTable::Print(ostream& os, sa_size_t lstart, sa_size_t lend, sa_size_t lstep) const
468{
469 os << "##### BaseDataTable::Print() - Table(NRow=" << NEntry() << " , NCol="
470 << NVar() << ") ##### " << endl;
471 os << "#! " ;
472 for (size_t i=0; i<NVar(); i++) {
473 string nom = mNames[i].nom;
474 nom += ':'; nom += ColTypeToString(mNames[i].type);
475 os << setw(12) << nom << " ";
476 }
477 os << endl;
478 os << "##########################################################################" << endl;
479 for (sa_size_t l=lstart; l<lend; l+=lstep)
480 os << TableRowToString(l, true) << endl;
481 return os;
482}
483
484/*! In addition to printing the number of entries and column names,
485 this method prints also minimum/maximum value for each column.
486 This information might be computed when the Show() method is called.
487 This may take some time for tables with large number of entries (>~ 10^6)
488*/
489void BaseDataTable::Show(ostream& os) const
490{
491 os << "BaseDataTable: NVar= " << NVar() << " NEnt= " << NEntry()
492 << " ( SegSize= " << SegmentSize() << " NbSegments= "
493 << NbSegments() << " )" << endl;
494 os << "--------------------------------------------------------------------" << endl;
495 os << setw(3) << "i" << ":" << setw(20) << " Name" << " ("
496 << setw(4) << "Type" << ") | "
497 << setw(15) << " Min " << " | " << setw(15) << " Max " << endl;
498 os << "--------------------------------------------------------------------" << endl;
499 r_8 min, max ;
500 for(sa_size_t i = 0 ; i < NVar() ; i++) {
501 GetMinMax(i, min, max) ;
502 string nom;
503 if (mNames[i].nom.length() > 20)
504 nom = mNames[i].nom.substr(20);
505 else nom = mNames[i].nom;
506 os << setw(3) << i << ":" << setw(20) << nom << " ("
507 << setw(4) << ColTypeToString(mNames[i].type) << ") | "
508 << setw(15) << min << " | " << setw(15) << max << endl;
509 }
510 os << "--------------------------------------------------------------------" << endl;
511 return;
512}
513
514//! Fills table from an ascii (text) file
515/*
516 Return number of non empt lines (added to table)
517 \param is : input ascii (text) stream
518 \param clm : Lines starting with clm are ignored (comments)
519 \param sep : separator between different fields (columns)
520*/
521sa_size_t BaseDataTable::FillFromASCIIFile(istream& is, char clm, const char* sep)
522{
523 string str;
524 if (mVarMTV == NULL) mVarMTV = new MuTyV[NVar()];
525 sa_size_t iv, nl;
526 nl = 0;
527 while (!is.eof()) {
528 str = "";
529 getline(is, str);
530 if (is.good() || is.eof()) {
531 size_t l = str.length();
532 if ((l == 0) || (str[0]==clm)) continue;
533 for(iv=0; iv<NVar(); iv++) mVarMTV[iv] = 0.;
534 iv = 0;
535 size_t q = 0;
536 size_t p = 0;
537 while ( (q < l) && (iv < NVar()) ) {
538 p = str.find_first_not_of(sep,q);
539 if (p >= l) break;
540 if (str[p] == '\'') { // Decodage d'un string
541 q = str.find('\'',p+1);
542 if (q < l) {
543 mVarMTV[iv] = str.substr(p+1,q-p-1);
544 q++;
545 }
546 else mVarMTV[iv] = str.substr(p+1,l-p-1);
547 iv++;
548 }
549 else {
550 q = str.find_first_of(sep,p);
551 if (q > l) q = l;
552 mVarMTV[iv] = str.substr(p,q-p);
553 iv++;
554 }
555 if (mNames[iv-1].type == DateTimeField) {
556 string tts = (string)mVarMTV[iv-1];
557 mVarMTV[iv-1] = TimeStamp(tts);
558 }
559 }
560 AddRow(mVarMTV);
561 nl++;
562 }
563 } // Fin boucle lignes fichier
564 cout << "BaseDataTable::FillFromASCIIFile()/Info: " << nl << " lines decoded from stream " << endl;
565 return(nl);
566}
567
568
569
570//
571// ------------------------------------
572// ------- Interface NTuple -----------
573// ------------------------------------
574//
575sa_size_t BaseDataTable::NbLines() const
576{
577 return(NEntry());
578}
579
580sa_size_t BaseDataTable::NbColumns() const
581{
582 return(NVar());
583}
584
585r_8* BaseDataTable::GetLineD(sa_size_t n) const
586{
587 if ((n < 0) || (n >= NEntry()))
588 throw RangeCheckError("BaseDataTable::GetLineD() out of range line index n");
589 if (mVarD == NULL) mVarD = new r_8[NVar()];
590
591 sa_size_t bid = n/mSegSz;
592 sa_size_t off = n%mSegSz;
593 for(sa_size_t k=0; k<mIColsP.size(); k++)
594 mVarD[mIColIdx[k]] = mIColsP[k]->GetCstSegment(bid)[off];
595 for(sa_size_t k=0; k<mLColsP.size(); k++)
596 mVarD[mLColIdx[k]] = mLColsP[k]->GetCstSegment(bid)[off];
597 for(sa_size_t k=0; k<mFColsP.size(); k++)
598 mVarD[mFColIdx[k]] = mFColsP[k]->GetCstSegment(bid)[off];
599 for(sa_size_t k=0; k<mDColsP.size(); k++)
600 mVarD[mDColIdx[k]] = mDColsP[k]->GetCstSegment(bid)[off];
601 for(sa_size_t k=0; k<mYColsP.size(); k++)
602 mVarD[mYColIdx[k]] = mYColsP[k]->GetCstSegment(bid)[off].real();
603 for(sa_size_t k=0; k<mZColsP.size(); k++)
604 mVarD[mZColIdx[k]] = mZColsP[k]->GetCstSegment(bid)[off].real();
605 for(sa_size_t k=0; k<mSColsP.size(); k++)
606 mVarD[mSColIdx[k]] = atof(mSColsP[k]->GetCstSegment(bid)[off].c_str());
607
608 return mVarD;
609}
610
611
612r_8 BaseDataTable::GetCell(sa_size_t n, sa_size_t k) const
613{
614 if ((n < 0) || (n >= NEntry()))
615 throw RangeCheckError("BaseDataTable::GetCell() out of range line index n");
616 if ((k < 0) || (k >= NVar()))
617 throw RangeCheckError("BaseDataTable::GetCell() out of range column index k");
618 double rv = BADVAL;
619 sa_size_t sk = mNames[k].ser;
620 sa_size_t bid = n/mSegSz;
621 sa_size_t off = n%mSegSz;
622
623 switch (mNames[k].type) {
624 case IntegerField :
625 rv = mIColsP[sk]->GetCstSegment(bid)[off];
626 break;
627 case LongField :
628 rv = mLColsP[sk]->GetCstSegment(bid)[off];
629 break;
630 case FloatField :
631 rv = mFColsP[sk]->GetCstSegment(bid)[off];
632 break;
633 case DoubleField :
634 case DateTimeField :
635 rv = mDColsP[sk]->GetCstSegment(bid)[off];
636 break;
637 case ComplexField :
638 rv = mYColsP[sk]->GetCstSegment(bid)[off].real();
639 break;
640 case DoubleComplexField :
641 rv = mZColsP[sk]->GetCstSegment(bid)[off].real();
642 break;
643 case StringField :
644 rv = atof(mSColsP[sk]->GetCstSegment(bid)[off].c_str());
645 break;
646 default:
647 rv = BADVAL;
648 break;
649 }
650 return rv ;
651}
652
653
654r_8 BaseDataTable::GetCell(sa_size_t n, string const& nom) const
655{
656 return GetCell(n, IndexNom(nom));
657}
658
659string BaseDataTable::GetCelltoString(sa_size_t n, sa_size_t k) const
660{
661 if ((n < 0) || (n >= NEntry()))
662 throw RangeCheckError("BaseDataTable::GetCell() out of range line index n");
663 if ((k < 0) || (k >= NVar()))
664 throw RangeCheckError("BaseDataTable::GetCell() out of range column index k");
665 MuTyV rv;;
666 sa_size_t sk = mNames[k].ser;
667 sa_size_t bid = n/mSegSz;
668 sa_size_t off = n%mSegSz;
669 switch (mNames[k].type) {
670 case IntegerField :
671 rv = mIColsP[sk]->GetCstSegment(bid)[off];
672 break;
673 case LongField :
674 rv = mLColsP[sk]->GetCstSegment(bid)[off];
675 break;
676 case FloatField :
677 rv = mFColsP[sk]->GetCstSegment(bid)[off];
678 break;
679 case DoubleField :
680 rv = mDColsP[sk]->GetCstSegment(bid)[off];
681 break;
682 case ComplexField :
683 rv = mYColsP[sk]->GetCstSegment(bid)[off];
684 break;
685 case DoubleComplexField :
686 rv = mZColsP[sk]->GetCstSegment(bid)[off];
687 break;
688 case StringField :
689 rv = mSColsP[sk]->GetCstSegment(bid)[off];
690 break;
691 case DateTimeField :
692 rv = TimeStamp(mDColsP[sk]->GetCstSegment(bid)[off]);
693 break;
694 default:
695 rv = " ";
696 break;
697 }
698 return (string)rv ;
699}
700
701void BaseDataTable::GetMinMax(sa_size_t k, double& min, double& max) const
702{
703 min = 9E39 ; max = -9E39 ;
704 if ((k < 0) || (k >= NVar()))
705 throw RangeCheckError("BaseDataTable::GetCell() out of range column index k");
706 if (mMinMaxNEnt.size() < NVar()) {
707 mMin.clear();
708 mMax.clear();
709 mMinMaxNEnt.clear();
710 for(size_t kk=0; kk<NVar(); kk++) {
711 mMin.push_back(0.);
712 mMax.push_back(0.);
713 mMinMaxNEnt.push_back(0);
714 }
715 }
716 if (mMinMaxNEnt[k] == mNEnt) {
717 min = mMin[k];
718 max = mMax[k];
719 return;
720 }
721 sa_size_t sk = mNames[k].ser;
722
723 sa_size_t cnt = 0;
724 switch (mNames[k].type) {
725 case IntegerField :
726 for(size_t is=0; is<mIColsP[sk]->NbSegments(); is++) {
727 const int_4* sp = mIColsP[sk]->GetCstSegment(is);
728 for(size_t n=0; n<mIColsP[sk]->SegmentSize(); n++) {
729 if (cnt >= NEntry()) break;
730 if (sp[n] > max) max = sp[n];
731 if (sp[n] < min) min = sp[n];
732 cnt++;
733 }
734 }
735
736 break;
737 case LongField :
738 for(size_t is=0; is<mLColsP[sk]->NbSegments(); is++) {
739 const int_8* sp = mLColsP[sk]->GetCstSegment(is);
740 for(size_t n=0; n<mLColsP[sk]->SegmentSize(); n++) {
741 if (cnt >= NEntry()) break;
742 if (sp[n] > max) max = sp[n];
743 if (sp[n] < min) min = sp[n];
744 cnt++;
745 }
746 }
747 break;
748 case FloatField :
749 for(size_t is=0; is<mFColsP[sk]->NbSegments(); is++) {
750 const r_4* sp = mFColsP[sk]->GetCstSegment(is);
751 for(size_t n=0; n<mFColsP[sk]->SegmentSize(); n++) {
752 if (cnt >= NEntry()) break;
753 if (sp[n] > max) max = sp[n];
754 if (sp[n] < min) min = sp[n];
755 cnt++;
756 }
757 }
758 break;
759 case DoubleField :
760 case DateTimeField :
761 for(size_t is=0; is<mDColsP[sk]->NbSegments(); is++) {
762 const r_8* sp = mDColsP[sk]->GetCstSegment(is);
763 for(size_t n=0; n<mDColsP[sk]->SegmentSize(); n++) {
764 if (cnt >= NEntry()) break;
765 if (sp[n] > max) max = sp[n];
766 if (sp[n] < min) min = sp[n];
767 cnt++;
768 }
769 }
770 break;
771 case ComplexField :
772 for(size_t is=0; is<mYColsP[sk]->NbSegments(); is++) {
773 const complex<r_4> * sp = mYColsP[sk]->GetCstSegment(is);
774 for(size_t n=0; n<mYColsP[sk]->SegmentSize(); n++) {
775 if (cnt >= NEntry()) break;
776 if (sp[n].real() > max) max = sp[n].real();
777 if (sp[n].real() < min) min = sp[n].real();
778 cnt++;
779 }
780 }
781 break;
782 case DoubleComplexField :
783 for(size_t is=0; is<mZColsP[sk]->NbSegments(); is++) {
784 const complex<r_8> * sp = mZColsP[sk]->GetCstSegment(is);
785 for(size_t n=0; n<mZColsP[sk]->SegmentSize(); n++) {
786 if (cnt >= NEntry()) break;
787 if (sp[n].real() > max) max = sp[n].real();
788 if (sp[n].real() < min) min = sp[n].real();
789 cnt++;
790 }
791 }
792 break;
793 case StringField :
794 return;
795 break;
796 default:
797 return;
798 break;
799 }
800
801 mMinMaxNEnt[k] = cnt;
802 mMin[k] = min;
803 mMax[k] = max;
804 return ;
805}
806
807
808void BaseDataTable::GetMinMax(string const & nom, double& min, double& max) const
809{
810 GetMinMax(IndexNom(nom), min, max) ;
811}
812
813
814sa_size_t BaseDataTable::ColumnIndex(string const& nom) const
815{
816 return IndexNom(nom) ;
817}
818
819
820string BaseDataTable::ColumnName(sa_size_t k) const
821{
822 return NomIndex(k) ;
823}
824
825
826string BaseDataTable::VarList_C(const char* nomx) const
827{
828 string rets="";
829 sa_size_t i;
830 for(i=0; i<NVar(); i++) {
831 if ( (i%5 == 0) && (i > 0) ) rets += ";";
832 if (i%5 == 0) rets += "\ndouble ";
833 else rets += ",";
834 rets += mNames[i].nom;
835 }
836 rets += "; \n";
837 if (nomx) {
838 char buff[256];
839 for(i=0; i<NVar(); i++) {
840 rets += mNames[i].nom;
841 rets += '=';
842
843 sprintf(buff,"%s[%ld]; ", nomx, (long)i);
844 rets += buff;
845 if ( (i%3 == 0) && (i > 0) ) rets += "\n";
846 }
847 }
848 return(rets);
849}
850
851
852string BaseDataTable::LineHeaderToString() const
853{
854 string rets,s;
855
856 for(int i=0; i<NVar(); i++) {
857 s = mNames[i].nom;
858 size_t l = s.length();
859 for(size_t ii=l; ii<12; ii++) s += ' ';
860 if (i > 0) rets += ' ';
861 rets += s;
862 }
863 return(rets);
864}
865
866/*!
867 Return a table row (line) as a string
868 \sa TableRowToString()
869*/
870string BaseDataTable::LineToString(sa_size_t n) const
871{
872 return TableRowToString(n, false);
873}
874
875/*!
876 \param n : table row index ( 0 ... NEntry()-1)
877 \param qstr : if true , enclose strings in quotes ''
878 \param sep : separates fields using \b sep
879 \param fw : minimum field width
880 */
881string BaseDataTable::TableRowToString(sa_size_t n, bool qstr,
882 const char* sep, int fw) const
883{
884 if ((n < 0) || (n >= NEntry()))
885 throw RangeCheckError("BaseDataTable::GetCell() out of range line index n");
886 string rs;
887 MuTyV rv;;
888 sa_size_t bid = n/mSegSz;
889 sa_size_t off = n%mSegSz;
890 for(sa_size_t k=0; k<NVar(); k++) {
891 sa_size_t sk = mNames[k].ser;
892 switch (mNames[k].type) {
893 case IntegerField :
894 rv = mIColsP[sk]->GetCstSegment(bid)[off];
895 break;
896 case LongField :
897 rv = mLColsP[sk]->GetCstSegment(bid)[off];
898 break;
899 case FloatField :
900 rv = mFColsP[sk]->GetCstSegment(bid)[off];
901 break;
902 case DoubleField :
903 rv = mDColsP[sk]->GetCstSegment(bid)[off];
904 break;
905 case ComplexField :
906 rv = mYColsP[sk]->GetCstSegment(bid)[off];
907 break;
908 case DoubleComplexField :
909 rv = mZColsP[sk]->GetCstSegment(bid)[off];
910 break;
911 case StringField :
912 rv = mSColsP[sk]->GetCstSegment(bid)[off];
913 break;
914 case DateTimeField :
915 rv = TimeStamp(mDColsP[sk]->GetCstSegment(bid)[off]);
916 break;
917 default:
918 rv = " ";
919 break;
920 }
921 string s;
922 if ( (mNames[k].type == StringField) && (qstr) ) {
923 s = '\''; s += (string)rv; s += '\'';
924 }
925 else s= (string)rv;
926 size_t l = s.length();
927 for(size_t ii=l; ii<fw; ii++) s += ' ';
928 if (k > 0) rs += sep;
929 rs += s;
930 }
931 return rs;
932}
933
Note: See TracBrowser for help on using the repository browser.