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

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

correction petit bug + ajout const lies a DataTableRow - 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> const& 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 DataTableRow row(nms);
211 return row;
212}
213
214//
215// A quel index correspond mon nom ?
216//
217sa_size_t BaseDataTable::IndexNom(char const* nom) const
218{
219 for(sa_size_t k=0; k<NVar(); k++)
220 if ( mNames[k].nom == nom ) return k;
221 return -1;
222 // Reza:Avril 2005 : PINtuple se base sur le renvoi de -1 et pas d'une exception
223 // throw NotFoundExc("BaseDataTable::IndexNom() : column name not found ");
224}
225
226string BaseDataTable::NomIndex(sa_size_t k) const
227{
228 if ((k < 0) || (k >= NVar()))
229 throw RangeCheckError("BaseDataTable::NomIndex() out of range column index k");
230 return mNames[k].nom ;
231}
232
233//! Adds a row (or line) to the table with r_8* inout data
234/*!
235 The data to be added is provided as an array (vector) of double (r_8).
236 The necessary data conversion is performed, depending on each
237 column's data typeconverted to the data type.
238 Return the new number of table rows (lines / entries)
239 \param data : Data for each cell of the row to be appended
240 (data[k] k=0..NbColumns())
241*/
242sa_size_t BaseDataTable::AddRow(const r_8* data)
243{
244 if (NVar() == 0)
245 throw ParmError("BaseDataTable::AddRow(const r_8*) Table has no column !");
246 if (NEntry() == SegmentSize()*NbSegments()) Extend();
247 sa_size_t n = NEntry();
248 sa_size_t bid = n/mSegSz;
249 sa_size_t off = n%mSegSz;
250 for(sa_size_t k=0; k<mIColsP.size(); k++)
251 mIColsP[k]->GetSegment(bid)[off] = (int_4)data[mIColIdx[k]];
252 for(sa_size_t k=0; k<mLColsP.size(); k++)
253 mLColsP[k]->GetSegment(bid)[off] = (int_8)data[mLColIdx[k]];
254 for(sa_size_t k=0; k<mFColsP.size(); k++)
255 mFColsP[k]->GetSegment(bid)[off] = (r_4)data[mFColIdx[k]];
256 for(sa_size_t k=0; k<mDColsP.size(); k++)
257 mDColsP[k]->GetSegment(bid)[off] = data[mDColIdx[k]];
258 for(sa_size_t k=0; k<mYColsP.size(); k++)
259 mYColsP[k]->GetSegment(bid)[off] = complex<r_4>(data[mYColIdx[k]],0.);
260 for(sa_size_t k=0; k<mZColsP.size(); k++)
261 mZColsP[k]->GetSegment(bid)[off] = complex<r_8>(data[mZColIdx[k]],0.);
262 for(sa_size_t k=0; k<mSColsP.size(); k++)
263 mSColsP[k]->GetSegment(bid)[off] = (string)MuTyV(data[mSColIdx[k]]);
264
265 mNEnt++;
266 return mNEnt;
267}
268
269//! Adds a row (or line) to the table with input data as an array of MuTyV
270/*!
271 The data to be added is provided as an array (vector) of MuTyV.
272 The MuTyV class conversion operators are used to match against each
273 cell data type.
274 Return the new number of table rows (lines / entries)
275 \param data : Data (MuTyV*) for each cell of the row to be appended
276 (data[k] k=0..NbColumns())
277*/
278sa_size_t BaseDataTable::AddRow(const MuTyV* data)
279{
280 if (NVar() == 0)
281 throw ParmError("BaseDataTable::AddRow(const MuTyV*) Table has no column !");
282 if (NEntry() == SegmentSize()*NbSegments()) Extend();
283 sa_size_t n = NEntry();
284 sa_size_t bid = n/mSegSz;
285 sa_size_t off = n%mSegSz;
286 for(sa_size_t k=0; k<mIColsP.size(); k++)
287 mIColsP[k]->GetSegment(bid)[off] = (int_4)data[mIColIdx[k]];
288 for(sa_size_t k=0; k<mLColsP.size(); k++)
289 mLColsP[k]->GetSegment(bid)[off] = (int_8)data[mLColIdx[k]];
290 for(sa_size_t k=0; k<mSColsP.size(); k++)
291 mSColsP[k]->GetSegment(bid)[off] = (string)data[mSColIdx[k]];
292 for(sa_size_t k=0; k<mFColsP.size(); k++)
293 mFColsP[k]->GetSegment(bid)[off] = (r_4)data[mFColIdx[k]];
294 for(sa_size_t k=0; k<mDColsP.size(); k++)
295 mDColsP[k]->GetSegment(bid)[off] = (r_8)data[mDColIdx[k]];
296 for(sa_size_t k=0; k<mYColsP.size(); k++)
297 mYColsP[k]->GetSegment(bid)[off] =
298 complex<r_4>(data[mYColIdx[k]].GetRealPart(), data[mYColIdx[k]].GetImagPart());
299 for(sa_size_t k=0; k<mZColsP.size(); k++)
300 mZColsP[k]->GetSegment(bid)[off] =
301 complex<r_8>(data[mZColIdx[k]].GetRealPart(), data[mZColIdx[k]].GetImagPart());
302
303 mNEnt++;
304 return mNEnt;
305}
306//! Adds a row (or line) to the table with input data as DataTableRow object
307/*!
308 The internal MuTyV array of the object contains the date and the
309 MuTyV class conversion operators are used to match against each
310 cell data type.
311 Only the size of the input data object is checked.
312 Return the new number of table rows (lines / entries)
313 \param data : Data for each cell of the row to be appended
314 (data[k] k=0..NbColumns())
315*/
316sa_size_t BaseDataTable::AddRow(DataTableRow const& data)
317{
318 if ( data.Size() != NCols() )
319 throw SzMismatchError(" BaseDataTable::AddRow() - data.Size() != NCols() ");
320 return AddRow(data.MTVPtr());
321}
322
323/*!
324 Extends the table (in the row direction). This method is called automatically when needed.
325*/
326sa_size_t BaseDataTable::Extend()
327{
328 for(sa_size_t k=0; k<mIColsP.size(); k++)
329 mIColsP[k]->Extend();
330 for(sa_size_t k=0; k<mLColsP.size(); k++)
331 mLColsP[k]->Extend();
332 for(sa_size_t k=0; k<mFColsP.size(); k++)
333 mFColsP[k]->Extend();
334 for(sa_size_t k=0; k<mDColsP.size(); k++)
335 mDColsP[k]->Extend();
336 for(sa_size_t k=0; k<mYColsP.size(); k++)
337 mYColsP[k]->Extend();
338 for(sa_size_t k=0; k<mZColsP.size(); k++)
339 mZColsP[k]->Extend();
340 for(sa_size_t k=0; k<mSColsP.size(); k++)
341 mSColsP[k]->Extend();
342 mNSeg++;
343 return mNSeg;
344}
345
346/*!
347 Fills the input \b row object with the content of row \b n.
348 Return a reference to the input \b row object.
349 Generate an exception if the input \b row object has the wrong size.
350 This method is slower(less efficient) than the GetRow(n) method.
351*/
352DataTableRow& BaseDataTable::GetRow(sa_size_t n, DataTableRow& row) const
353{
354 if ( row.Size() != NCols() )
355 throw SzMismatchError(" BaseDataTable::GetRow(n, row) - row.Size() != NCols() ");
356 MuTyV* rmtv = GetRow(n);
357 for(sa_size_t k=0; k<NCols(); k++)
358 row[k] = rmtv[k];
359 return row;
360}
361
362MuTyV* BaseDataTable::GetRow(sa_size_t n) const
363{
364 if ((n < 0) || (n >= NEntry()))
365 throw RangeCheckError("BaseDataTable::GetRow() out of range line index n");
366 if (mVarMTV == NULL) mVarMTV = new MuTyV[NVar()];
367
368 sa_size_t bid = n/mSegSz;
369 sa_size_t off = n%mSegSz;
370 for(sa_size_t k=0; k<mIColsP.size(); k++)
371 mVarMTV[mIColIdx[k]] = mIColsP[k]->GetCstSegment(bid)[off];
372 for(sa_size_t k=0; k<mLColsP.size(); k++)
373 mVarMTV[mLColIdx[k]] = mLColsP[k]->GetCstSegment(bid)[off];
374 for(sa_size_t k=0; k<mFColsP.size(); k++)
375 mVarMTV[mFColIdx[k]] = mFColsP[k]->GetCstSegment(bid)[off];
376 for(sa_size_t k=0; k<mDColsP.size(); k++)
377 mVarMTV[mDColIdx[k]] = mDColsP[k]->GetCstSegment(bid)[off];
378 for(sa_size_t k=0; k<mYColsP.size(); k++)
379 mVarMTV[mYColIdx[k]] = mYColsP[k]->GetCstSegment(bid)[off];
380 for(sa_size_t k=0; k<mZColsP.size(); k++)
381 mVarMTV[mZColIdx[k]] = mZColsP[k]->GetCstSegment(bid)[off];
382 for(sa_size_t k=0; k<mSColsP.size(); k++)
383 mVarMTV[mSColIdx[k]] = atof(mSColsP[k]->GetCstSegment(bid)[off].c_str());
384
385 return mVarMTV;
386}
387
388#define BADVAL -1.e39
389
390TVector<r_8> BaseDataTable::GetColumnD(sa_size_t k) const
391{
392 if ((k < 0) || (k >= NVar()))
393 throw RangeCheckError("BaseDataTable::GetColumnD() out of range column index k");
394 sa_size_t sk = mNames[k].ser;
395 sa_size_t i = 0;
396 TVector<r_8> rv(NEntry());
397
398 for (sa_size_t is=0; is<NbSegments(); is++) {
399 switch (mNames[k].type) {
400 case IntegerField :
401 for(sa_size_t j=0; j<SegmentSize(); j++,i++)
402 rv(i) = mIColsP[sk]->GetCstSegment(is)[j];
403 break;
404 case LongField :
405 for(sa_size_t j=0; j<SegmentSize(); j++,i++)
406 rv(i) = mLColsP[sk]->GetCstSegment(is)[j];
407 break;
408 case FloatField :
409 for(sa_size_t j=0; j<SegmentSize(); j++,i++)
410 rv(i) = mFColsP[sk]->GetCstSegment(is)[j];
411 break;
412 case DoubleField :
413 case DateTimeField :
414 for(sa_size_t j=0; j<SegmentSize(); j++,i++)
415 rv(i) = mDColsP[sk]->GetCstSegment(is)[j];
416 break;
417 case ComplexField :
418 for(sa_size_t j=0; j<SegmentSize(); j++,i++)
419 rv(i) = mYColsP[sk]->GetCstSegment(is)[j].real();
420 break;
421 case DoubleComplexField :
422 for(sa_size_t j=0; j<SegmentSize(); j++,i++)
423 rv(i) = mZColsP[sk]->GetCstSegment(is)[j].real();
424 break;
425 case StringField :
426 for(sa_size_t j=0; j<SegmentSize(); j++,i++)
427 rv = atof(mSColsP[sk]->GetCstSegment(is)[j].c_str());
428 break;
429 default:
430 for(sa_size_t j=0; j<SegmentSize(); j++,i++) rv(i) = BADVAL;
431 break;
432 }
433 }
434 return rv ;
435}
436
437void BaseDataTable::CopyMerge(BaseDataTable const& a, bool cp)
438{
439 if (cp && (NEntry() > 0) )
440 throw ParmError("BaseDataTable::CopyMerge(a) Table has entries already");
441 if (a.NVar() == 0) throw ParmError("BaseDataTable::CopyMerge(a) Table a has no column");
442 if (NVar() == 0) CopyStructure(a);
443 else if (!CompareStructure(a))
444 throw SzMismatchError("BaseDataTable::CopyMerge(a) (this,a) have different table structure");
445 if (a.NEntry() == 0) {
446 cout << " BaseDataTable::CopyMerge(a)/Warning : table a has zero (0) entry ! " << endl;
447 return;
448 }
449 for(sa_size_t kk=0; kk<a.NEntry(); kk++)
450 AddRow(a.GetLine(kk));
451}
452
453
454//! Returns the associated DVList object
455DVList& BaseDataTable::Info() const
456{
457 if (mInfo == NULL) mInfo = new DVList;
458 return(*mInfo);
459}
460
461/*!
462 Formatted (text) output of the table, for lines lstart <= l_index < lend , with step lstep
463 \param os : output stream (formatted output)
464 \param lstart : start row (line) index
465 \param lend : end row (line) index
466 \param lstep : row index increment
467*/
468ostream& BaseDataTable::Print(ostream& os, sa_size_t lstart, sa_size_t lend, sa_size_t lstep) const
469{
470 os << "##### BaseDataTable::Print() - Table(NRow=" << NEntry() << " , NCol="
471 << NVar() << ") ##### " << endl;
472 os << "#! " ;
473 for (size_t i=0; i<NVar(); i++) {
474 string nom = mNames[i].nom;
475 nom += ':'; nom += ColTypeToString(mNames[i].type);
476 os << setw(12) << nom << " ";
477 }
478 os << endl;
479 os << "##########################################################################" << endl;
480 for (sa_size_t l=lstart; l<lend; l+=lstep)
481 os << TableRowToString(l, true) << endl;
482 return os;
483}
484
485/*! In addition to printing the number of entries and column names,
486 this method prints also minimum/maximum value for each column.
487 This information might be computed when the Show() method is called.
488 This may take some time for tables with large number of entries (>~ 10^6)
489*/
490void BaseDataTable::Show(ostream& os) const
491{
492 os << "BaseDataTable: NVar= " << NVar() << " NEnt= " << NEntry()
493 << " ( SegSize= " << SegmentSize() << " NbSegments= "
494 << NbSegments() << " )" << endl;
495 os << "--------------------------------------------------------------------" << endl;
496 os << setw(3) << "i" << ":" << setw(20) << " Name" << " ("
497 << setw(4) << "Type" << ") | "
498 << setw(15) << " Min " << " | " << setw(15) << " Max " << endl;
499 os << "--------------------------------------------------------------------" << endl;
500 r_8 min, max ;
501 for(sa_size_t i = 0 ; i < NVar() ; i++) {
502 GetMinMax(i, min, max) ;
503 string nom;
504 if (mNames[i].nom.length() > 20)
505 nom = mNames[i].nom.substr(20);
506 else nom = mNames[i].nom;
507 os << setw(3) << i << ":" << setw(20) << nom << " ("
508 << setw(4) << ColTypeToString(mNames[i].type) << ") | "
509 << setw(15) << min << " | " << setw(15) << max << endl;
510 }
511 os << "--------------------------------------------------------------------" << endl;
512 return;
513}
514
515//! Fills table from an ascii (text) file
516/*
517 Return number of non empt lines (added to table)
518 \param is : input ascii (text) stream
519 \param clm : Lines starting with clm are ignored (comments)
520 \param sep : separator between different fields (columns)
521*/
522sa_size_t BaseDataTable::FillFromASCIIFile(istream& is, char clm, const char* sep)
523{
524 string str;
525 if (mVarMTV == NULL) mVarMTV = new MuTyV[NVar()];
526 sa_size_t iv, nl;
527 nl = 0;
528 while (!is.eof()) {
529 str = "";
530 getline(is, str);
531 if (is.good() || is.eof()) {
532 size_t l = str.length();
533 if ((l == 0) || (str[0]==clm)) continue;
534 for(iv=0; iv<NVar(); iv++) mVarMTV[iv] = 0.;
535 iv = 0;
536 size_t q = 0;
537 size_t p = 0;
538 while ( (q < l) && (iv < NVar()) ) {
539 p = str.find_first_not_of(sep,q);
540 if (p >= l) break;
541 if (str[p] == '\'') { // Decodage d'un string
542 q = str.find('\'',p+1);
543 if (q < l) {
544 mVarMTV[iv] = str.substr(p+1,q-p-1);
545 q++;
546 }
547 else mVarMTV[iv] = str.substr(p+1,l-p-1);
548 iv++;
549 }
550 else {
551 q = str.find_first_of(sep,p);
552 if (q > l) q = l;
553 mVarMTV[iv] = str.substr(p,q-p);
554 iv++;
555 }
556 if (mNames[iv-1].type == DateTimeField) {
557 string tts = (string)mVarMTV[iv-1];
558 mVarMTV[iv-1] = TimeStamp(tts);
559 }
560 }
561 AddRow(mVarMTV);
562 nl++;
563 }
564 } // Fin boucle lignes fichier
565 cout << "BaseDataTable::FillFromASCIIFile()/Info: " << nl << " lines decoded from stream " << endl;
566 return(nl);
567}
568
569
570
571//
572// ------------------------------------
573// ------- Interface NTuple -----------
574// ------------------------------------
575//
576sa_size_t BaseDataTable::NbLines() const
577{
578 return(NEntry());
579}
580
581sa_size_t BaseDataTable::NbColumns() const
582{
583 return(NVar());
584}
585
586r_8* BaseDataTable::GetLineD(sa_size_t n) const
587{
588 if ((n < 0) || (n >= NEntry()))
589 throw RangeCheckError("BaseDataTable::GetLineD() out of range line index n");
590 if (mVarD == NULL) mVarD = new r_8[NVar()];
591
592 sa_size_t bid = n/mSegSz;
593 sa_size_t off = n%mSegSz;
594 for(sa_size_t k=0; k<mIColsP.size(); k++)
595 mVarD[mIColIdx[k]] = mIColsP[k]->GetCstSegment(bid)[off];
596 for(sa_size_t k=0; k<mLColsP.size(); k++)
597 mVarD[mLColIdx[k]] = mLColsP[k]->GetCstSegment(bid)[off];
598 for(sa_size_t k=0; k<mFColsP.size(); k++)
599 mVarD[mFColIdx[k]] = mFColsP[k]->GetCstSegment(bid)[off];
600 for(sa_size_t k=0; k<mDColsP.size(); k++)
601 mVarD[mDColIdx[k]] = mDColsP[k]->GetCstSegment(bid)[off];
602 for(sa_size_t k=0; k<mYColsP.size(); k++)
603 mVarD[mYColIdx[k]] = mYColsP[k]->GetCstSegment(bid)[off].real();
604 for(sa_size_t k=0; k<mZColsP.size(); k++)
605 mVarD[mZColIdx[k]] = mZColsP[k]->GetCstSegment(bid)[off].real();
606 for(sa_size_t k=0; k<mSColsP.size(); k++)
607 mVarD[mSColIdx[k]] = atof(mSColsP[k]->GetCstSegment(bid)[off].c_str());
608
609 return mVarD;
610}
611
612
613r_8 BaseDataTable::GetCell(sa_size_t n, sa_size_t k) const
614{
615 if ((n < 0) || (n >= NEntry()))
616 throw RangeCheckError("BaseDataTable::GetCell() out of range line index n");
617 if ((k < 0) || (k >= NVar()))
618 throw RangeCheckError("BaseDataTable::GetCell() out of range column index k");
619 double rv = BADVAL;
620 sa_size_t sk = mNames[k].ser;
621 sa_size_t bid = n/mSegSz;
622 sa_size_t off = n%mSegSz;
623
624 switch (mNames[k].type) {
625 case IntegerField :
626 rv = mIColsP[sk]->GetCstSegment(bid)[off];
627 break;
628 case LongField :
629 rv = mLColsP[sk]->GetCstSegment(bid)[off];
630 break;
631 case FloatField :
632 rv = mFColsP[sk]->GetCstSegment(bid)[off];
633 break;
634 case DoubleField :
635 case DateTimeField :
636 rv = mDColsP[sk]->GetCstSegment(bid)[off];
637 break;
638 case ComplexField :
639 rv = mYColsP[sk]->GetCstSegment(bid)[off].real();
640 break;
641 case DoubleComplexField :
642 rv = mZColsP[sk]->GetCstSegment(bid)[off].real();
643 break;
644 case StringField :
645 rv = atof(mSColsP[sk]->GetCstSegment(bid)[off].c_str());
646 break;
647 default:
648 rv = BADVAL;
649 break;
650 }
651 return rv ;
652}
653
654
655r_8 BaseDataTable::GetCell(sa_size_t n, string const& nom) const
656{
657 return GetCell(n, IndexNom(nom));
658}
659
660string BaseDataTable::GetCelltoString(sa_size_t n, sa_size_t k) const
661{
662 if ((n < 0) || (n >= NEntry()))
663 throw RangeCheckError("BaseDataTable::GetCell() out of range line index n");
664 if ((k < 0) || (k >= NVar()))
665 throw RangeCheckError("BaseDataTable::GetCell() out of range column index k");
666 MuTyV rv;;
667 sa_size_t sk = mNames[k].ser;
668 sa_size_t bid = n/mSegSz;
669 sa_size_t off = n%mSegSz;
670 switch (mNames[k].type) {
671 case IntegerField :
672 rv = mIColsP[sk]->GetCstSegment(bid)[off];
673 break;
674 case LongField :
675 rv = mLColsP[sk]->GetCstSegment(bid)[off];
676 break;
677 case FloatField :
678 rv = mFColsP[sk]->GetCstSegment(bid)[off];
679 break;
680 case DoubleField :
681 rv = mDColsP[sk]->GetCstSegment(bid)[off];
682 break;
683 case ComplexField :
684 rv = mYColsP[sk]->GetCstSegment(bid)[off];
685 break;
686 case DoubleComplexField :
687 rv = mZColsP[sk]->GetCstSegment(bid)[off];
688 break;
689 case StringField :
690 rv = mSColsP[sk]->GetCstSegment(bid)[off];
691 break;
692 case DateTimeField :
693 rv = TimeStamp(mDColsP[sk]->GetCstSegment(bid)[off]);
694 break;
695 default:
696 rv = " ";
697 break;
698 }
699 return (string)rv ;
700}
701
702void BaseDataTable::GetMinMax(sa_size_t k, double& min, double& max) const
703{
704 min = 9E39 ; max = -9E39 ;
705 if ((k < 0) || (k >= NVar()))
706 throw RangeCheckError("BaseDataTable::GetCell() out of range column index k");
707 if (mMinMaxNEnt.size() < NVar()) {
708 mMin.clear();
709 mMax.clear();
710 mMinMaxNEnt.clear();
711 for(size_t kk=0; kk<NVar(); kk++) {
712 mMin.push_back(0.);
713 mMax.push_back(0.);
714 mMinMaxNEnt.push_back(0);
715 }
716 }
717 if (mMinMaxNEnt[k] == mNEnt) {
718 min = mMin[k];
719 max = mMax[k];
720 return;
721 }
722 sa_size_t sk = mNames[k].ser;
723
724 sa_size_t cnt = 0;
725 switch (mNames[k].type) {
726 case IntegerField :
727 for(size_t is=0; is<mIColsP[sk]->NbSegments(); is++) {
728 const int_4* sp = mIColsP[sk]->GetCstSegment(is);
729 for(size_t n=0; n<mIColsP[sk]->SegmentSize(); n++) {
730 if (cnt >= NEntry()) break;
731 if (sp[n] > max) max = sp[n];
732 if (sp[n] < min) min = sp[n];
733 cnt++;
734 }
735 }
736
737 break;
738 case LongField :
739 for(size_t is=0; is<mLColsP[sk]->NbSegments(); is++) {
740 const int_8* sp = mLColsP[sk]->GetCstSegment(is);
741 for(size_t n=0; n<mLColsP[sk]->SegmentSize(); n++) {
742 if (cnt >= NEntry()) break;
743 if (sp[n] > max) max = sp[n];
744 if (sp[n] < min) min = sp[n];
745 cnt++;
746 }
747 }
748 break;
749 case FloatField :
750 for(size_t is=0; is<mFColsP[sk]->NbSegments(); is++) {
751 const r_4* sp = mFColsP[sk]->GetCstSegment(is);
752 for(size_t n=0; n<mFColsP[sk]->SegmentSize(); n++) {
753 if (cnt >= NEntry()) break;
754 if (sp[n] > max) max = sp[n];
755 if (sp[n] < min) min = sp[n];
756 cnt++;
757 }
758 }
759 break;
760 case DoubleField :
761 case DateTimeField :
762 for(size_t is=0; is<mDColsP[sk]->NbSegments(); is++) {
763 const r_8* sp = mDColsP[sk]->GetCstSegment(is);
764 for(size_t n=0; n<mDColsP[sk]->SegmentSize(); n++) {
765 if (cnt >= NEntry()) break;
766 if (sp[n] > max) max = sp[n];
767 if (sp[n] < min) min = sp[n];
768 cnt++;
769 }
770 }
771 break;
772 case ComplexField :
773 for(size_t is=0; is<mYColsP[sk]->NbSegments(); is++) {
774 const complex<r_4> * sp = mYColsP[sk]->GetCstSegment(is);
775 for(size_t n=0; n<mYColsP[sk]->SegmentSize(); n++) {
776 if (cnt >= NEntry()) break;
777 if (sp[n].real() > max) max = sp[n].real();
778 if (sp[n].real() < min) min = sp[n].real();
779 cnt++;
780 }
781 }
782 break;
783 case DoubleComplexField :
784 for(size_t is=0; is<mZColsP[sk]->NbSegments(); is++) {
785 const complex<r_8> * sp = mZColsP[sk]->GetCstSegment(is);
786 for(size_t n=0; n<mZColsP[sk]->SegmentSize(); n++) {
787 if (cnt >= NEntry()) break;
788 if (sp[n].real() > max) max = sp[n].real();
789 if (sp[n].real() < min) min = sp[n].real();
790 cnt++;
791 }
792 }
793 break;
794 case StringField :
795 return;
796 break;
797 default:
798 return;
799 break;
800 }
801
802 mMinMaxNEnt[k] = cnt;
803 mMin[k] = min;
804 mMax[k] = max;
805 return ;
806}
807
808
809void BaseDataTable::GetMinMax(string const & nom, double& min, double& max) const
810{
811 GetMinMax(IndexNom(nom), min, max) ;
812}
813
814
815sa_size_t BaseDataTable::ColumnIndex(string const& nom) const
816{
817 return IndexNom(nom) ;
818}
819
820
821string BaseDataTable::ColumnName(sa_size_t k) const
822{
823 return NomIndex(k) ;
824}
825
826
827string BaseDataTable::VarList_C(const char* nomx) const
828{
829 string rets="";
830 sa_size_t i;
831 for(i=0; i<NVar(); i++) {
832 if ( (i%5 == 0) && (i > 0) ) rets += ";";
833 if (i%5 == 0) rets += "\ndouble ";
834 else rets += ",";
835 rets += mNames[i].nom;
836 }
837 rets += "; \n";
838 if (nomx) {
839 char buff[256];
840 for(i=0; i<NVar(); i++) {
841 rets += mNames[i].nom;
842 rets += '=';
843
844 sprintf(buff,"%s[%ld]; ", nomx, (long)i);
845 rets += buff;
846 if ( (i%3 == 0) && (i > 0) ) rets += "\n";
847 }
848 }
849 return(rets);
850}
851
852
853string BaseDataTable::LineHeaderToString() const
854{
855 string rets,s;
856
857 for(int i=0; i<NVar(); i++) {
858 s = mNames[i].nom;
859 size_t l = s.length();
860 for(size_t ii=l; ii<12; ii++) s += ' ';
861 if (i > 0) rets += ' ';
862 rets += s;
863 }
864 return(rets);
865}
866
867/*!
868 Return a table row (line) as a string
869 \sa TableRowToString()
870*/
871string BaseDataTable::LineToString(sa_size_t n) const
872{
873 return TableRowToString(n, false);
874}
875
876/*!
877 \param n : table row index ( 0 ... NEntry()-1)
878 \param qstr : if true , enclose strings in quotes ''
879 \param sep : separates fields using \b sep
880 \param fw : minimum field width
881 */
882string BaseDataTable::TableRowToString(sa_size_t n, bool qstr,
883 const char* sep, int fw) const
884{
885 if ((n < 0) || (n >= NEntry()))
886 throw RangeCheckError("BaseDataTable::GetCell() out of range line index n");
887 string rs;
888 MuTyV rv;;
889 sa_size_t bid = n/mSegSz;
890 sa_size_t off = n%mSegSz;
891 for(sa_size_t k=0; k<NVar(); k++) {
892 sa_size_t sk = mNames[k].ser;
893 switch (mNames[k].type) {
894 case IntegerField :
895 rv = mIColsP[sk]->GetCstSegment(bid)[off];
896 break;
897 case LongField :
898 rv = mLColsP[sk]->GetCstSegment(bid)[off];
899 break;
900 case FloatField :
901 rv = mFColsP[sk]->GetCstSegment(bid)[off];
902 break;
903 case DoubleField :
904 rv = mDColsP[sk]->GetCstSegment(bid)[off];
905 break;
906 case ComplexField :
907 rv = mYColsP[sk]->GetCstSegment(bid)[off];
908 break;
909 case DoubleComplexField :
910 rv = mZColsP[sk]->GetCstSegment(bid)[off];
911 break;
912 case StringField :
913 rv = mSColsP[sk]->GetCstSegment(bid)[off];
914 break;
915 case DateTimeField :
916 rv = TimeStamp(mDColsP[sk]->GetCstSegment(bid)[off]);
917 break;
918 default:
919 rv = " ";
920 break;
921 }
922 string s;
923 if ( (mNames[k].type == StringField) && (qstr) ) {
924 s = '\''; s += (string)rv; s += '\'';
925 }
926 else s= (string)rv;
927 size_t l = s.length();
928 for(size_t ii=l; ii<fw; ii++) s += ' ';
929 if (k > 0) rs += sep;
930 rs += s;
931 }
932 return rs;
933}
934
Note: See TracBrowser for help on using the repository browser.