#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 = "Date"; else rs = "Date"; 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 ; } 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] = (string)MuTyV(data[mSColIdx[k]]); mNEnt++; return mNEnt; } 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]]; 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(); 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; kGetSegment(bid)[off]; for(sa_size_t k=0; kGetSegment(bid)[off]; for(sa_size_t k=0; kGetSegment(bid)[off]; for(sa_size_t k=0; kGetSegment(bid)[off]; for(sa_size_t k=0; kGetSegment(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 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; kGetSegment(bid)[off]; for(sa_size_t k=0; kGetSegment(bid)[off]; for(sa_size_t k=0; kGetSegment(bid)[off]; for(sa_size_t k=0; kGetSegment(bid)[off]; for(sa_size_t k=0; kGetSegment(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) || (n >= 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]->GetSegment(bid)[off]; break; case LongField : rv = mLColsP[sk]->GetSegment(bid)[off]; break; case FloatField : rv = mFColsP[sk]->GetSegment(bid)[off]; break; case DoubleField : rv = mDColsP[sk]->GetSegment(bid)[off]; break; case StringField : rv = atof(mSColsP[sk]->GetSegment(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) || (n >= 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]->GetSegment(bid)[off]; break; case LongField : rv = mLColsP[sk]->GetSegment(bid)[off]; break; case FloatField : rv = mFColsP[sk]->GetSegment(bid)[off]; break; case DoubleField : rv = mDColsP[sk]->GetSegment(bid)[off]; break; case StringField : rv = atof(mSColsP[sk]->GetSegment(bid)[off].c_str()); 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++) { int_4* sp = mIColsP[sk]->GetSegment(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++) { int_8* sp = mLColsP[sk]->GetSegment(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++) { r_4* sp = mFColsP[sk]->GetSegment(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++) { r_8* sp = mDColsP[sk]->GetSegment(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 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 { char buff[32]; string rets=" Num "; 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; kGetSegment(bid)[off]; break; case LongField : rv = mLColsP[sk]->GetSegment(bid)[off]; break; case FloatField : rv = mFColsP[sk]->GetSegment(bid)[off]; break; case DoubleField : rv = mDColsP[sk]->GetSegment(bid)[off]; break; case StringField : rv = atof(mSColsP[sk]->GetSegment(bid)[off].c_str()); break; default: rv = " "; break; } rs += " "; rs += (string)rv; } return rs; }