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

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

Correction bug ds GetRow() - Reza 21/11/2005

File size: 27.4 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 if (GetColumType(mDColIdx[k]) == DateTimeField)
378 mVarMTV[mDColIdx[k]] = TimeStamp(mDColsP[k]->GetCstSegment(bid)[off]);
379 else mVarMTV[mDColIdx[k]] = mDColsP[k]->GetCstSegment(bid)[off];
380 }
381 for(sa_size_t k=0; k<mYColsP.size(); k++)
382 mVarMTV[mYColIdx[k]] = mYColsP[k]->GetCstSegment(bid)[off];
383 for(sa_size_t k=0; k<mZColsP.size(); k++)
384 mVarMTV[mZColIdx[k]] = mZColsP[k]->GetCstSegment(bid)[off];
385 for(sa_size_t k=0; k<mSColsP.size(); k++)
386 mVarMTV[mSColIdx[k]] = mSColsP[k]->GetCstSegment(bid)[off];
387
388 return mVarMTV;
389}
390
391#define BADVAL -1.e39
392
393TVector<r_8> BaseDataTable::GetColumnD(sa_size_t k) const
394{
395 if ((k < 0) || (k >= NVar()))
396 throw RangeCheckError("BaseDataTable::GetColumnD() out of range column index k");
397 sa_size_t sk = mNames[k].ser;
398 sa_size_t i = 0;
399 TVector<r_8> rv(NEntry());
400
401 for (sa_size_t is=0; is<NbSegments(); is++) {
402 switch (mNames[k].type) {
403 case IntegerField :
404 for(sa_size_t j=0; j<SegmentSize(); j++,i++)
405 rv(i) = mIColsP[sk]->GetCstSegment(is)[j];
406 break;
407 case LongField :
408 for(sa_size_t j=0; j<SegmentSize(); j++,i++)
409 rv(i) = mLColsP[sk]->GetCstSegment(is)[j];
410 break;
411 case FloatField :
412 for(sa_size_t j=0; j<SegmentSize(); j++,i++)
413 rv(i) = mFColsP[sk]->GetCstSegment(is)[j];
414 break;
415 case DoubleField :
416 case DateTimeField :
417 for(sa_size_t j=0; j<SegmentSize(); j++,i++)
418 rv(i) = mDColsP[sk]->GetCstSegment(is)[j];
419 break;
420 case ComplexField :
421 for(sa_size_t j=0; j<SegmentSize(); j++,i++)
422 rv(i) = mYColsP[sk]->GetCstSegment(is)[j].real();
423 break;
424 case DoubleComplexField :
425 for(sa_size_t j=0; j<SegmentSize(); j++,i++)
426 rv(i) = mZColsP[sk]->GetCstSegment(is)[j].real();
427 break;
428 case StringField :
429 for(sa_size_t j=0; j<SegmentSize(); j++,i++)
430 rv = atof(mSColsP[sk]->GetCstSegment(is)[j].c_str());
431 break;
432 default:
433 for(sa_size_t j=0; j<SegmentSize(); j++,i++) rv(i) = BADVAL;
434 break;
435 }
436 }
437 return rv ;
438}
439
440void BaseDataTable::CopyMerge(BaseDataTable const& a, bool cp)
441{
442 if (cp && (NEntry() > 0) )
443 throw ParmError("BaseDataTable::CopyMerge(a) Table has entries already");
444 if (a.NVar() == 0) throw ParmError("BaseDataTable::CopyMerge(a) Table a has no column");
445 if (NVar() == 0) CopyStructure(a);
446 else if (!CompareStructure(a))
447 throw SzMismatchError("BaseDataTable::CopyMerge(a) (this,a) have different table structure");
448 if (a.NEntry() == 0) {
449 cout << " BaseDataTable::CopyMerge(a)/Warning : table a has zero (0) entry ! " << endl;
450 return;
451 }
452 for(sa_size_t kk=0; kk<a.NEntry(); kk++)
453 AddRow(a.GetLine(kk));
454}
455
456
457//! Returns the associated DVList object
458DVList& BaseDataTable::Info() const
459{
460 if (mInfo == NULL) mInfo = new DVList;
461 return(*mInfo);
462}
463
464/*!
465 Formatted (text) output of the table, for lines lstart <= l_index < lend , with step lstep
466 \param os : output stream (formatted output)
467 \param lstart : start row (line) index
468 \param lend : end row (line) index
469 \param lstep : row index increment
470*/
471ostream& BaseDataTable::Print(ostream& os, sa_size_t lstart, sa_size_t lend, sa_size_t lstep) const
472{
473 os << "##### BaseDataTable::Print() - Table(NRow=" << NEntry() << " , NCol="
474 << NVar() << ") ##### " << endl;
475 os << "#! " ;
476 for (size_t i=0; i<NVar(); i++) {
477 string nom = mNames[i].nom;
478 nom += ':'; nom += ColTypeToString(mNames[i].type);
479 os << setw(12) << nom << " ";
480 }
481 os << endl;
482 os << "##########################################################################" << endl;
483 for (sa_size_t l=lstart; l<lend; l+=lstep)
484 os << TableRowToString(l, true) << endl;
485 return os;
486}
487
488/*! In addition to printing the number of entries and column names,
489 this method prints also minimum/maximum value for each column.
490 This information might be computed when the Show() method is called.
491 This may take some time for tables with large number of entries (>~ 10^6)
492*/
493void BaseDataTable::Show(ostream& os) const
494{
495 os << "BaseDataTable: NVar= " << NVar() << " NEnt= " << NEntry()
496 << " ( SegSize= " << SegmentSize() << " NbSegments= "
497 << NbSegments() << " )" << endl;
498 os << "--------------------------------------------------------------------" << endl;
499 os << setw(3) << "i" << ":" << setw(20) << " Name" << " ("
500 << setw(4) << "Type" << ") | "
501 << setw(15) << " Min " << " | " << setw(15) << " Max " << endl;
502 os << "--------------------------------------------------------------------" << endl;
503 r_8 min, max ;
504 for(sa_size_t i = 0 ; i < NVar() ; i++) {
505 GetMinMax(i, min, max) ;
506 string nom;
507 if (mNames[i].nom.length() > 20)
508 nom = mNames[i].nom.substr(20);
509 else nom = mNames[i].nom;
510 os << setw(3) << i << ":" << setw(20) << nom << " ("
511 << setw(4) << ColTypeToString(mNames[i].type) << ") | "
512 << setw(15) << min << " | " << setw(15) << max << endl;
513 }
514 os << "--------------------------------------------------------------------" << endl;
515 return;
516}
517
518//! Fills table from an ascii (text) file
519/*
520 Return number of non empt lines (added to table)
521 \param is : input ascii (text) stream
522 \param clm : Lines starting with clm are ignored (comments)
523 \param sep : separator between different fields (columns)
524*/
525sa_size_t BaseDataTable::FillFromASCIIFile(istream& is, char clm, const char* sep)
526{
527 string str;
528 if (mVarMTV == NULL) mVarMTV = new MuTyV[NVar()];
529 sa_size_t iv, nl;
530 nl = 0;
531 while (!is.eof()) {
532 str = "";
533 getline(is, str);
534 if (is.good() || is.eof()) {
535 size_t l = str.length();
536 if ((l == 0) || (str[0]==clm)) continue;
537 for(iv=0; iv<NVar(); iv++) mVarMTV[iv] = 0.;
538 iv = 0;
539 size_t q = 0;
540 size_t p = 0;
541 while ( (q < l) && (iv < NVar()) ) {
542 p = str.find_first_not_of(sep,q);
543 if (p >= l) break;
544 if (str[p] == '\'') { // Decodage d'un string
545 q = str.find('\'',p+1);
546 if (q < l) {
547 mVarMTV[iv] = str.substr(p+1,q-p-1);
548 q++;
549 }
550 else mVarMTV[iv] = str.substr(p+1,l-p-1);
551 iv++;
552 }
553 else {
554 q = str.find_first_of(sep,p);
555 if (q > l) q = l;
556 mVarMTV[iv] = str.substr(p,q-p);
557 iv++;
558 }
559 if (mNames[iv-1].type == DateTimeField) {
560 string tts = (string)mVarMTV[iv-1];
561 mVarMTV[iv-1] = TimeStamp(tts);
562 }
563 }
564 AddRow(mVarMTV);
565 nl++;
566 }
567 } // Fin boucle lignes fichier
568 cout << "BaseDataTable::FillFromASCIIFile()/Info: " << nl << " lines decoded from stream " << endl;
569 return(nl);
570}
571
572
573
574//
575// ------------------------------------
576// ------- Interface NTuple -----------
577// ------------------------------------
578//
579sa_size_t BaseDataTable::NbLines() const
580{
581 return(NEntry());
582}
583
584sa_size_t BaseDataTable::NbColumns() const
585{
586 return(NVar());
587}
588
589r_8* BaseDataTable::GetLineD(sa_size_t n) const
590{
591 if ((n < 0) || (n >= NEntry()))
592 throw RangeCheckError("BaseDataTable::GetLineD() out of range line index n");
593 if (mVarD == NULL) mVarD = new r_8[NVar()];
594
595 sa_size_t bid = n/mSegSz;
596 sa_size_t off = n%mSegSz;
597 for(sa_size_t k=0; k<mIColsP.size(); k++)
598 mVarD[mIColIdx[k]] = mIColsP[k]->GetCstSegment(bid)[off];
599 for(sa_size_t k=0; k<mLColsP.size(); k++)
600 mVarD[mLColIdx[k]] = mLColsP[k]->GetCstSegment(bid)[off];
601 for(sa_size_t k=0; k<mFColsP.size(); k++)
602 mVarD[mFColIdx[k]] = mFColsP[k]->GetCstSegment(bid)[off];
603 for(sa_size_t k=0; k<mDColsP.size(); k++)
604 mVarD[mDColIdx[k]] = mDColsP[k]->GetCstSegment(bid)[off];
605 for(sa_size_t k=0; k<mYColsP.size(); k++)
606 mVarD[mYColIdx[k]] = mYColsP[k]->GetCstSegment(bid)[off].real();
607 for(sa_size_t k=0; k<mZColsP.size(); k++)
608 mVarD[mZColIdx[k]] = mZColsP[k]->GetCstSegment(bid)[off].real();
609 for(sa_size_t k=0; k<mSColsP.size(); k++)
610 mVarD[mSColIdx[k]] = atof(mSColsP[k]->GetCstSegment(bid)[off].c_str());
611
612 return mVarD;
613}
614
615
616r_8 BaseDataTable::GetCell(sa_size_t n, sa_size_t k) const
617{
618 if ((n < 0) || (n >= NEntry()))
619 throw RangeCheckError("BaseDataTable::GetCell() out of range line index n");
620 if ((k < 0) || (k >= NVar()))
621 throw RangeCheckError("BaseDataTable::GetCell() out of range column index k");
622 double rv = BADVAL;
623 sa_size_t sk = mNames[k].ser;
624 sa_size_t bid = n/mSegSz;
625 sa_size_t off = n%mSegSz;
626
627 switch (mNames[k].type) {
628 case IntegerField :
629 rv = mIColsP[sk]->GetCstSegment(bid)[off];
630 break;
631 case LongField :
632 rv = mLColsP[sk]->GetCstSegment(bid)[off];
633 break;
634 case FloatField :
635 rv = mFColsP[sk]->GetCstSegment(bid)[off];
636 break;
637 case DoubleField :
638 case DateTimeField :
639 rv = mDColsP[sk]->GetCstSegment(bid)[off];
640 break;
641 case ComplexField :
642 rv = mYColsP[sk]->GetCstSegment(bid)[off].real();
643 break;
644 case DoubleComplexField :
645 rv = mZColsP[sk]->GetCstSegment(bid)[off].real();
646 break;
647 case StringField :
648 rv = atof(mSColsP[sk]->GetCstSegment(bid)[off].c_str());
649 break;
650 default:
651 rv = BADVAL;
652 break;
653 }
654 return rv ;
655}
656
657
658r_8 BaseDataTable::GetCell(sa_size_t n, string const& nom) const
659{
660 return GetCell(n, IndexNom(nom));
661}
662
663string BaseDataTable::GetCelltoString(sa_size_t n, sa_size_t k) const
664{
665 if ((n < 0) || (n >= NEntry()))
666 throw RangeCheckError("BaseDataTable::GetCell() out of range line index n");
667 if ((k < 0) || (k >= NVar()))
668 throw RangeCheckError("BaseDataTable::GetCell() out of range column index k");
669 MuTyV rv;;
670 sa_size_t sk = mNames[k].ser;
671 sa_size_t bid = n/mSegSz;
672 sa_size_t off = n%mSegSz;
673 switch (mNames[k].type) {
674 case IntegerField :
675 rv = mIColsP[sk]->GetCstSegment(bid)[off];
676 break;
677 case LongField :
678 rv = mLColsP[sk]->GetCstSegment(bid)[off];
679 break;
680 case FloatField :
681 rv = mFColsP[sk]->GetCstSegment(bid)[off];
682 break;
683 case DoubleField :
684 rv = mDColsP[sk]->GetCstSegment(bid)[off];
685 break;
686 case ComplexField :
687 rv = mYColsP[sk]->GetCstSegment(bid)[off];
688 break;
689 case DoubleComplexField :
690 rv = mZColsP[sk]->GetCstSegment(bid)[off];
691 break;
692 case StringField :
693 rv = mSColsP[sk]->GetCstSegment(bid)[off];
694 break;
695 case DateTimeField :
696 rv = TimeStamp(mDColsP[sk]->GetCstSegment(bid)[off]);
697 break;
698 default:
699 rv = " ";
700 break;
701 }
702 return (string)rv ;
703}
704
705void BaseDataTable::GetMinMax(sa_size_t k, double& min, double& max) const
706{
707 min = 9E39 ; max = -9E39 ;
708 if ((k < 0) || (k >= NVar()))
709 throw RangeCheckError("BaseDataTable::GetCell() out of range column index k");
710 if (mMinMaxNEnt.size() < NVar()) {
711 mMin.clear();
712 mMax.clear();
713 mMinMaxNEnt.clear();
714 for(size_t kk=0; kk<NVar(); kk++) {
715 mMin.push_back(0.);
716 mMax.push_back(0.);
717 mMinMaxNEnt.push_back(0);
718 }
719 }
720 if (mMinMaxNEnt[k] == mNEnt) {
721 min = mMin[k];
722 max = mMax[k];
723 return;
724 }
725 sa_size_t sk = mNames[k].ser;
726
727 sa_size_t cnt = 0;
728 switch (mNames[k].type) {
729 case IntegerField :
730 for(size_t is=0; is<mIColsP[sk]->NbSegments(); is++) {
731 const int_4* sp = mIColsP[sk]->GetCstSegment(is);
732 for(size_t n=0; n<mIColsP[sk]->SegmentSize(); n++) {
733 if (cnt >= NEntry()) break;
734 if (sp[n] > max) max = sp[n];
735 if (sp[n] < min) min = sp[n];
736 cnt++;
737 }
738 }
739
740 break;
741 case LongField :
742 for(size_t is=0; is<mLColsP[sk]->NbSegments(); is++) {
743 const int_8* sp = mLColsP[sk]->GetCstSegment(is);
744 for(size_t n=0; n<mLColsP[sk]->SegmentSize(); n++) {
745 if (cnt >= NEntry()) break;
746 if (sp[n] > max) max = sp[n];
747 if (sp[n] < min) min = sp[n];
748 cnt++;
749 }
750 }
751 break;
752 case FloatField :
753 for(size_t is=0; is<mFColsP[sk]->NbSegments(); is++) {
754 const r_4* sp = mFColsP[sk]->GetCstSegment(is);
755 for(size_t n=0; n<mFColsP[sk]->SegmentSize(); n++) {
756 if (cnt >= NEntry()) break;
757 if (sp[n] > max) max = sp[n];
758 if (sp[n] < min) min = sp[n];
759 cnt++;
760 }
761 }
762 break;
763 case DoubleField :
764 case DateTimeField :
765 for(size_t is=0; is<mDColsP[sk]->NbSegments(); is++) {
766 const r_8* sp = mDColsP[sk]->GetCstSegment(is);
767 for(size_t n=0; n<mDColsP[sk]->SegmentSize(); n++) {
768 if (cnt >= NEntry()) break;
769 if (sp[n] > max) max = sp[n];
770 if (sp[n] < min) min = sp[n];
771 cnt++;
772 }
773 }
774 break;
775 case ComplexField :
776 for(size_t is=0; is<mYColsP[sk]->NbSegments(); is++) {
777 const complex<r_4> * sp = mYColsP[sk]->GetCstSegment(is);
778 for(size_t n=0; n<mYColsP[sk]->SegmentSize(); n++) {
779 if (cnt >= NEntry()) break;
780 if (sp[n].real() > max) max = sp[n].real();
781 if (sp[n].real() < min) min = sp[n].real();
782 cnt++;
783 }
784 }
785 break;
786 case DoubleComplexField :
787 for(size_t is=0; is<mZColsP[sk]->NbSegments(); is++) {
788 const complex<r_8> * sp = mZColsP[sk]->GetCstSegment(is);
789 for(size_t n=0; n<mZColsP[sk]->SegmentSize(); n++) {
790 if (cnt >= NEntry()) break;
791 if (sp[n].real() > max) max = sp[n].real();
792 if (sp[n].real() < min) min = sp[n].real();
793 cnt++;
794 }
795 }
796 break;
797 case StringField :
798 return;
799 break;
800 default:
801 return;
802 break;
803 }
804
805 mMinMaxNEnt[k] = cnt;
806 mMin[k] = min;
807 mMax[k] = max;
808 return ;
809}
810
811
812void BaseDataTable::GetMinMax(string const & nom, double& min, double& max) const
813{
814 GetMinMax(IndexNom(nom), min, max) ;
815}
816
817
818sa_size_t BaseDataTable::ColumnIndex(string const& nom) const
819{
820 return IndexNom(nom) ;
821}
822
823
824string BaseDataTable::ColumnName(sa_size_t k) const
825{
826 return NomIndex(k) ;
827}
828
829
830string BaseDataTable::VarList_C(const char* nomx) const
831{
832 string rets="";
833 sa_size_t i;
834 for(i=0; i<NVar(); i++) {
835 if ( (i%5 == 0) && (i > 0) ) rets += ";";
836 if (i%5 == 0) rets += "\ndouble ";
837 else rets += ",";
838 rets += mNames[i].nom;
839 }
840 rets += "; \n";
841 if (nomx) {
842 char buff[256];
843 for(i=0; i<NVar(); i++) {
844 rets += mNames[i].nom;
845 rets += '=';
846
847 sprintf(buff,"%s[%ld]; ", nomx, (long)i);
848 rets += buff;
849 if ( (i%3 == 0) && (i > 0) ) rets += "\n";
850 }
851 }
852 return(rets);
853}
854
855
856string BaseDataTable::LineHeaderToString() const
857{
858 string rets,s;
859
860 for(int i=0; i<NVar(); i++) {
861 s = mNames[i].nom;
862 size_t l = s.length();
863 for(size_t ii=l; ii<12; ii++) s += ' ';
864 if (i > 0) rets += ' ';
865 rets += s;
866 }
867 return(rets);
868}
869
870/*!
871 Return a table row (line) as a string
872 \sa TableRowToString()
873*/
874string BaseDataTable::LineToString(sa_size_t n) const
875{
876 return TableRowToString(n, false);
877}
878
879/*!
880 \param n : table row index ( 0 ... NEntry()-1)
881 \param qstr : if true , enclose strings in quotes ''
882 \param sep : separates fields using \b sep
883 \param fw : minimum field width
884 */
885string BaseDataTable::TableRowToString(sa_size_t n, bool qstr,
886 const char* sep, int fw) const
887{
888 if ((n < 0) || (n >= NEntry()))
889 throw RangeCheckError("BaseDataTable::GetCell() out of range line index n");
890 string rs;
891 MuTyV rv;;
892 sa_size_t bid = n/mSegSz;
893 sa_size_t off = n%mSegSz;
894 for(sa_size_t k=0; k<NVar(); k++) {
895 sa_size_t sk = mNames[k].ser;
896 switch (mNames[k].type) {
897 case IntegerField :
898 rv = mIColsP[sk]->GetCstSegment(bid)[off];
899 break;
900 case LongField :
901 rv = mLColsP[sk]->GetCstSegment(bid)[off];
902 break;
903 case FloatField :
904 rv = mFColsP[sk]->GetCstSegment(bid)[off];
905 break;
906 case DoubleField :
907 rv = mDColsP[sk]->GetCstSegment(bid)[off];
908 break;
909 case ComplexField :
910 rv = mYColsP[sk]->GetCstSegment(bid)[off];
911 break;
912 case DoubleComplexField :
913 rv = mZColsP[sk]->GetCstSegment(bid)[off];
914 break;
915 case StringField :
916 rv = mSColsP[sk]->GetCstSegment(bid)[off];
917 break;
918 case DateTimeField :
919 rv = TimeStamp(mDColsP[sk]->GetCstSegment(bid)[off]);
920 break;
921 default:
922 rv = " ";
923 break;
924 }
925 string s;
926 if ( (mNames[k].type == StringField) && (qstr) ) {
927 s = '\''; s += (string)rv; s += '\'';
928 }
929 else s= (string)rv;
930 size_t l = s.length();
931 for(size_t ii=l; ii<fw; ii++) s += ' ';
932 if (k > 0) rs += sep;
933 rs += s;
934 }
935 return rs;
936}
937
Note: See TracBrowser for help on using the repository browser.