#include "basedtable.h" #include #include "sopnamsp.h" #include "pexceptions.h" /*! \class SOPHYA::BaseDataTable \ingroup HiStats Base class for data tables. Each line represent a record and the column contains a given data type. */ string BaseDataTable::ColTypeToString(FieldType ft, bool fgl) { string rs; switch (ft) { case IntegerField : if (fgl) rs = "Integer"; else rs = "I"; break; case LongField : if (fgl) rs = "Long Integer"; else rs = "L"; break; case FloatField : if (fgl) rs = "Float"; else rs = "F"; break; case DoubleField : if (fgl) rs = "Double"; else rs = "D"; break; case ComplexField : if (fgl) rs = "Complex"; else rs = "Zx4"; break; case DoubleComplexField : if (fgl) rs = "DoubleComplex"; else rs = "Zx8"; break; case StringField : if (fgl) rs = "String"; else rs = "S"; break; case DateField : if (fgl) rs = "DateTime"; else rs = "T"; break; default: rs = "??"; break; } return rs; } /* Constructeur */ BaseDataTable::BaseDataTable(sa_size_t segsz) { mNEnt = 0; mSegSz = (segsz > 0) ? segsz : 16; mNSeg = 0; mVarD = NULL; mVarMTV = NULL; mInfo = NULL; } BaseDataTable::~BaseDataTable() { if (mVarD) delete[] mVarD; if (mVarMTV) delete[] mVarMTV; if (mInfo) delete mInfo; } sa_size_t BaseDataTable::CopyStructure(BaseDataTable const & a) { if (NVar() > 0) throw ParmError("BaseDataTable::CopyStructure() Table already has columns"); if (a.NVar() == 0) { cout << "BaseDataTable::CopyStructure(a)/Warning Table a is not initialized" << endl; return 0; } for (size_t kk=0; kk= NVar())) throw RangeCheckError("BaseDataTable::NomIndex() out of range column index k"); return mNames[k].nom ; } //! Adds a line (or row to the table) with r_8* inout data /*! The data to be added is provided as an array (vector) of double (r_8). The necessary data conversion is performed, depending on each column's data typeconverted to the data type. Return the new number of table rows (lines / entries) \param data : Data for each cell of the row to be appended (data[k] k=0..NbColumns()) */ sa_size_t BaseDataTable::AddLine(const r_8* data) { if (NVar() == 0) throw ParmError("BaseDataTable::AddLine(const r_8*) Table has no column !"); if (NEntry() == SegmentSize()*NbSegments()) Extend(); sa_size_t n = NEntry(); sa_size_t bid = n/mSegSz; sa_size_t off = n%mSegSz; for(sa_size_t k=0; kGetSegment(bid)[off] = (int_4)data[mIColIdx[k]]; for(sa_size_t k=0; kGetSegment(bid)[off] = (int_8)data[mLColIdx[k]]; for(sa_size_t k=0; kGetSegment(bid)[off] = (r_4)data[mFColIdx[k]]; for(sa_size_t k=0; kGetSegment(bid)[off] = data[mDColIdx[k]]; for(sa_size_t k=0; kGetSegment(bid)[off] = complex(data[mYColIdx[k]],0.); for(sa_size_t k=0; kGetSegment(bid)[off] = complex(data[mZColIdx[k]],0.); for(sa_size_t k=0; kGetSegment(bid)[off] = (string)MuTyV(data[mSColIdx[k]]); mNEnt++; return mNEnt; } //! Adds a line (or row to the table) with input data as an array of MuTyV /*! The data to be added is provided as an array (vector) of MuTyV. The MuTyV class conversion operators are used to match against each cell data type. Return the new number of table rows (lines / entries) \param data : Data (MuTyV*) for each cell of the row to be appended (data[k] k=0..NbColumns()) */ sa_size_t BaseDataTable::AddLine(const MuTyV* data) { if (NVar() == 0) throw ParmError("BaseDataTable::AddLine(const MuTyV*) Table has no column !"); if (NEntry() == SegmentSize()*NbSegments()) Extend(); sa_size_t n = NEntry(); sa_size_t bid = n/mSegSz; sa_size_t off = n%mSegSz; for(sa_size_t k=0; kGetSegment(bid)[off] = (int_4)data[mIColIdx[k]]; for(sa_size_t k=0; kGetSegment(bid)[off] = (int_8)data[mLColIdx[k]]; for(sa_size_t k=0; kGetSegment(bid)[off] = (string)data[mSColIdx[k]]; for(sa_size_t k=0; kGetSegment(bid)[off] = (r_4)data[mFColIdx[k]]; for(sa_size_t k=0; kGetSegment(bid)[off] = (r_8)data[mDColIdx[k]]; for(sa_size_t k=0; kGetSegment(bid)[off] = complex(data[mYColIdx[k]].GetRealPart(), data[mYColIdx[k]].GetImagPart()); for(sa_size_t k=0; kGetSegment(bid)[off] = complex(data[mZColIdx[k]].GetRealPart(), data[mZColIdx[k]].GetImagPart()); mNEnt++; return mNEnt; } sa_size_t BaseDataTable::Extend() { for(sa_size_t k=0; kExtend(); for(sa_size_t k=0; kExtend(); for(sa_size_t k=0; kExtend(); for(sa_size_t k=0; kExtend(); for(sa_size_t k=0; kExtend(); for(sa_size_t k=0; kExtend(); for(sa_size_t k=0; kExtend(); mNSeg++; return mNSeg; } MuTyV* BaseDataTable::GetLine(sa_size_t n) const { if ((n < 0) || (n >= NEntry())) throw RangeCheckError("BaseDataTable::GetLine() out of range line index n"); if (mVarMTV == NULL) mVarMTV = new MuTyV[NVar()]; sa_size_t bid = n/mSegSz; sa_size_t off = n%mSegSz; for(sa_size_t k=0; kGetCstSegment(bid)[off]; for(sa_size_t k=0; kGetCstSegment(bid)[off]; for(sa_size_t k=0; kGetCstSegment(bid)[off]; for(sa_size_t k=0; kGetCstSegment(bid)[off]; for(sa_size_t k=0; kGetCstSegment(bid)[off]; for(sa_size_t k=0; kGetCstSegment(bid)[off]; for(sa_size_t k=0; kGetCstSegment(bid)[off].c_str()); return mVarMTV; } void BaseDataTable::CopyMerge(BaseDataTable const& a, bool cp) { if (cp && (NEntry() > 0) ) throw ParmError("BaseDataTable::CopyMerge(a) Table has entries already"); if (a.NVar() == 0) throw ParmError("BaseDataTable::CopyMerge(a) Table a has no column"); if (NVar() == 0) CopyStructure(a); else if (!CompareStructure(a)) throw SzMismatchError("BaseDataTable::CopyMerge(a) (this,a) have different table structure"); if (a.NEntry() == 0) { cout << " BaseDataTable::CopyMerge(a)/Warning : table a has zero (0) entry ! " << endl; return; } for(sa_size_t kk=0; kk~ 10^6) */ void BaseDataTable::Show(ostream& os) const { os << "BaseDataTable: NVar= " << NVar() << " NEnt= " << NEntry() << " ( SegSize= " << SegmentSize() << " NbSegments= " << NbSegments() << " )" << endl; os << "--------------------------------------------------------------------" << endl; os << setw(3) << "i" << ":" << setw(20) << " Name" << " (" << setw(4) << "Type" << ") | " << setw(15) << " Min " << " | " << setw(15) << " Max " << endl; os << "--------------------------------------------------------------------" << endl; r_8 min, max ; for(sa_size_t i = 0 ; i < NVar() ; i++) { GetMinMax(i, min, max) ; string nom; if (mNames[i].nom.length() > 20) nom = mNames[i].nom.substr(20); else nom = mNames[i].nom; os << setw(3) << i << ":" << setw(20) << nom << " (" << setw(4) << ColTypeToString(mNames[i].type) << ") | " << setw(15) << min << " | " << setw(15) << max << endl; } os << "--------------------------------------------------------------------" << endl; return; } //! NOT YET IMPLEMENTED ! - Fills table from an ascii file int BaseDataTable::FillFromASCIIFile(string const& fn) // Remplit le ntuple a partir d'un fichier ASCII. // Renvoie le nombre de lignes ajoutees. { // a faire return(0); } // // ------------------------------------ // ------- Interface NTuple ----------- // ------------------------------------ // sa_size_t BaseDataTable::NbLines() const { return(NEntry()); } sa_size_t BaseDataTable::NbColumns() const { return(NVar()); } r_8* BaseDataTable::GetLineD(sa_size_t n) const { if ((n < 0) || (n >= NEntry())) throw RangeCheckError("BaseDataTable::GetLineD() out of range line index n"); if (mVarD == NULL) mVarD = new r_8[NVar()]; sa_size_t bid = n/mSegSz; sa_size_t off = n%mSegSz; for(sa_size_t k=0; kGetCstSegment(bid)[off]; for(sa_size_t k=0; kGetCstSegment(bid)[off]; for(sa_size_t k=0; kGetCstSegment(bid)[off]; for(sa_size_t k=0; kGetCstSegment(bid)[off]; for(sa_size_t k=0; kGetCstSegment(bid)[off].real(); for(sa_size_t k=0; kGetCstSegment(bid)[off].real(); for(sa_size_t k=0; kGetCstSegment(bid)[off].c_str()); return mVarD; } #define BADVAL -1.e39 r_8 BaseDataTable::GetCell(sa_size_t n, sa_size_t k) const { if ((n < 0) || (n >= NEntry())) throw RangeCheckError("BaseDataTable::GetCell() out of range line index n"); if ((k < 0) || (k >= NVar())) throw RangeCheckError("BaseDataTable::GetCell() out of range column index k"); double rv = BADVAL; sa_size_t sk = mNames[k].ser; sa_size_t bid = n/mSegSz; sa_size_t off = n%mSegSz; switch (mNames[k].type) { case IntegerField : rv = mIColsP[sk]->GetCstSegment(bid)[off]; break; case LongField : rv = mLColsP[sk]->GetCstSegment(bid)[off]; break; case FloatField : rv = mFColsP[sk]->GetCstSegment(bid)[off]; break; case DoubleField : case DateField : rv = mDColsP[sk]->GetCstSegment(bid)[off]; break; case ComplexField : rv = mYColsP[sk]->GetCstSegment(bid)[off].real(); break; case DoubleComplexField : rv = mZColsP[sk]->GetCstSegment(bid)[off].real(); break; case StringField : rv = atof(mSColsP[sk]->GetCstSegment(bid)[off].c_str()); break; default: rv = BADVAL; break; } return rv ; } r_8 BaseDataTable::GetCell(sa_size_t n, string const& nom) const { return GetCell(n, IndexNom(nom)); } string BaseDataTable::GetCelltoString(sa_size_t n, sa_size_t k) const { if ((n < 0) || (n >= NEntry())) throw RangeCheckError("BaseDataTable::GetCell() out of range line index n"); if ((k < 0) || (k >= NVar())) throw RangeCheckError("BaseDataTable::GetCell() out of range column index k"); MuTyV rv;; sa_size_t sk = mNames[k].ser; sa_size_t bid = n/mSegSz; sa_size_t off = n%mSegSz; switch (mNames[k].type) { case IntegerField : rv = mIColsP[sk]->GetCstSegment(bid)[off]; break; case LongField : rv = mLColsP[sk]->GetCstSegment(bid)[off]; break; case FloatField : rv = mFColsP[sk]->GetCstSegment(bid)[off]; break; case DoubleField : rv = mDColsP[sk]->GetCstSegment(bid)[off]; break; case ComplexField : rv = mYColsP[sk]->GetCstSegment(bid)[off]; break; case DoubleComplexField : rv = mZColsP[sk]->GetCstSegment(bid)[off]; break; case StringField : rv = mSColsP[sk]->GetCstSegment(bid)[off]; break; default: rv = " "; break; } return (string)rv ; } void BaseDataTable::GetMinMax(sa_size_t k, double& min, double& max) const { min = 9E39 ; max = -9E39 ; if ((k < 0) || (k >= NVar())) throw RangeCheckError("BaseDataTable::GetCell() out of range column index k"); if (mMinMaxNEnt.size() < NVar()) { mMin.clear(); mMax.clear(); mMinMaxNEnt.clear(); for(size_t kk=0; kkNbSegments(); is++) { const int_4* sp = mIColsP[sk]->GetCstSegment(is); for(size_t n=0; nSegmentSize(); n++) { if (cnt >= NEntry()) break; if (sp[n] > max) max = sp[n]; if (sp[n] < min) min = sp[n]; cnt++; } } break; case LongField : for(size_t is=0; isNbSegments(); is++) { const int_8* sp = mLColsP[sk]->GetCstSegment(is); for(size_t n=0; nSegmentSize(); n++) { if (cnt >= NEntry()) break; if (sp[n] > max) max = sp[n]; if (sp[n] < min) min = sp[n]; cnt++; } } break; case FloatField : for(size_t is=0; isNbSegments(); is++) { const r_4* sp = mFColsP[sk]->GetCstSegment(is); for(size_t n=0; nSegmentSize(); n++) { if (cnt >= NEntry()) break; if (sp[n] > max) max = sp[n]; if (sp[n] < min) min = sp[n]; cnt++; } } break; case DoubleField : for(size_t is=0; isNbSegments(); is++) { const r_8* sp = mDColsP[sk]->GetCstSegment(is); for(size_t n=0; nSegmentSize(); n++) { if (cnt >= NEntry()) break; if (sp[n] > max) max = sp[n]; if (sp[n] < min) min = sp[n]; cnt++; } } break; case ComplexField : for(size_t is=0; isNbSegments(); is++) { const complex * sp = mYColsP[sk]->GetCstSegment(is); for(size_t n=0; nSegmentSize(); n++) { if (cnt >= NEntry()) break; if (sp[n].real() > max) max = sp[n].real(); if (sp[n].real() < min) min = sp[n].real(); cnt++; } } break; case DoubleComplexField : for(size_t is=0; isNbSegments(); is++) { const complex * sp = mZColsP[sk]->GetCstSegment(is); for(size_t n=0; nSegmentSize(); n++) { if (cnt >= NEntry()) break; if (sp[n].real() > max) max = sp[n].real(); if (sp[n].real() < min) min = sp[n].real(); cnt++; } } break; case StringField : return; break; default: return; break; } mMinMaxNEnt[k] = cnt; mMin[k] = min; mMax[k] = max; return ; } void BaseDataTable::GetMinMax(string const & nom, double& min, double& max) const { GetMinMax(IndexNom(nom), min, max) ; } sa_size_t BaseDataTable::ColumnIndex(string const& nom) const { return IndexNom(nom) ; } string BaseDataTable::ColumnName(sa_size_t k) const { return NomIndex(k) ; } string BaseDataTable::VarList_C(const char* nomx) const { string rets=""; sa_size_t i; for(i=0; i 0) ) rets += ";"; if (i%5 == 0) rets += "\ndouble "; else rets += ","; rets += mNames[i].nom; } rets += "; \n"; if (nomx) { char buff[256]; for(i=0; i 0) ) rets += "\n"; } } return(rets); } string BaseDataTable::LineHeaderToString() const { string rets,s; for(int i=0; i= NEntry())) throw RangeCheckError("BaseDataTable::GetCell() out of range line index n"); string rs; MuTyV rv;; sa_size_t bid = n/mSegSz; sa_size_t off = n%mSegSz; for(sa_size_t k=0; kGetCstSegment(bid)[off]; break; case LongField : rv = mLColsP[sk]->GetCstSegment(bid)[off]; break; case FloatField : rv = mFColsP[sk]->GetCstSegment(bid)[off]; break; case DoubleField : rv = mDColsP[sk]->GetCstSegment(bid)[off]; break; case ComplexField : rv = mYColsP[sk]->GetCstSegment(bid)[off]; break; case DoubleComplexField : rv = mZColsP[sk]->GetCstSegment(bid)[off]; break; case StringField : rv = mSColsP[sk]->GetCstSegment(bid)[off]; break; default: rv = " "; break; } string s = (string)rv; s += ' '; size_t l = s.length(); for(size_t ii=l; ii<10; ii++) s += ' '; rs += s; } return rs; }