#include #include #include "strutil.h" #include "perrors.h" #include "ntuple.h" #define BADVAL -1.e19 #define LENNAME 8 #define LENNAME1 (LENNAME+1) /*! \class SOPHYA::NTuple \ingroup HiStats Simple NTuple class (a Table or 2-D data set) with floating value columns. \sa SOPHYA::ObjFileIO \code #include "ntuple.h" // ... char * names[3] = {"XPos", "YPos", "Val"}; // NTuple (Table) creation with 3 columns NTuple nt(3, names); // Filling the NTuple r_4 x[3]; for(int i=0; i<63; i++) { x[0] = (i%9)-4.; x[1] = (i/9)-3.; x[2] = x[0]*x[0]+x[1]*x[1]; nt.Fill(x); } // Printing table info cout << nt ; // Saving object into a PPF file POutPersist po("nt.ppf"); po << nt ; \endcode */ //++ // Class NTuple // Lib Outils++ // include ntuple.h // // Classe de ntuples //-- //++ // Links Parents // PPersist // NTupleInterface //-- /* --Methode-- */ //! Default constructor //++ NTuple::NTuple() // // Createur par defaut //-- { mNVar = mNEnt = mBlk = mNBlk = 0; mVar = NULL; mVarD = NULL; mNames = NULL; mInfo = NULL; } //! Constructor with specification of number of columns and column name /*! \param nvar : Number of columns in the table \param noms : Array of column names (length(name) < 8 characters) \param blk : Optional argument specifying number of table lines in a given data block */ //++ NTuple::NTuple(int nvar, char** noms, int blk) // // Createur d'un ntuple de `nvar' variables dont les // noms sont dans le tableau de cahines de caracteres `noms' // avec `blk' d'evenements par blocks. //-- { mNVar = mNEnt = mBlk = mNBlk = 0; mVar = NULL; mVarD = NULL; mNames = NULL; mInfo = NULL; if (nvar <= 0) throw ParmError("NTuple::NTuple(nvar<=0) "); mNVar = nvar; mVar = new r_4[nvar]; mVarD = new r_8[nvar]; if (blk < 10) blk = 10; mBlk = blk; // On prend des noms de LENNAME char pour le moment mNames = new char[nvar*LENNAME1]; r_4* pt = new r_4[nvar*blk]; mNBlk = 1; mPtr.push_back(pt); int i; for(i=0; i fiont(this); fiont.Read(s); } /* --Methode-- */ NTuple::~NTuple() { Clean(); } /* --Methode-- */ //! Clear the data table definition and deletes the associated data void NTuple::Clean() { if (mVar) delete[] mVar; if (mVarD) delete[] mVarD; if (mNames) delete[] mNames; if (mInfo) delete mInfo; int i; if(mNBlk>0) for(i=0; i= mNBlk) { r_4* pt = new r_4[mNVar*mBlk]; mNBlk++; mPtr.push_back(pt); } int offb = mNEnt-numb*mBlk; memcpy((mPtr[numb]+offb*mNVar), x, mNVar*sizeof(r_4)); mNEnt++; return; } /* --Methode-- */ //++ float NTuple::GetVal(int n, int k) const // // Retourne la valeur de la variable `k' de l'evenement `n'. //-- { if (n >= mNEnt) return(BADVAL); if ( (k < 0) || (k >= mNVar) ) return(BADVAL); int numb = n/mBlk; int offb = n-numb*mBlk; return(*(mPtr[numb]+offb*mNVar+k)); } /* --Methode-- */ //++ int NTuple::IndexNom(const char* nom) const // // Retourne le numero de la variable de nom `nom'. //-- { int i; for(i=0; i= 0) && (k < mNVar)) strcpy(nomretour, mNames+k*LENNAME1); return(nomretour); } /* --Methode-- */ //++ r_4* NTuple::GetVec(int n, r_4* ret) const // // Retourne l'evenement `n' dans le vecteur `ret'. //-- { int i; if (ret == NULL) ret = mVar; if (n >= mNEnt) { for(i=0; i mNEnt) nmax = mNEnt; for(i=num; i= 0) { if (posb < 0) posb = postab; else if (postab < posb) posb = postab; } if (posb >= 0) ccp[posb] = '\0'; if ( isdigit(line[0]) || (line[0] == '+') || (line[0] == '-') || (line[0] == '.') ) xv[kk] = atof(ccp); if (posb < 0) break; ccp += posb+1; j = 0; while ( (ccp[j] != '\0') && ((ccp[j] == ' ') || (ccp[j] == '\t')) ) j++; ccp += j; } Fill(xv); nlread++; } delete[] xv; cout << "NTuple::FillFromASCIIFile( " << fn << ") " << nlread << " fill from file " << endl; return(nlread); } // ------- Implementation de l interface NTuple --------- /* --Methode-- */ uint_4 NTuple::NbLines() const { return(NEntry()); } /* --Methode-- */ uint_4 NTuple::NbColumns() const { return(NVar()); } /* --Methode-- */ r_8 * NTuple::GetLineD(int n) const { return(GetVecD(n)); } /* --Methode-- */ r_8 NTuple::GetCell(int n, int k) const { return(GetVal(n, k)); } /* --Methode-- */ r_8 NTuple::GetCell(int n, string const & nom) const { return(GetVal(n, nom.c_str())); } /* --Methode-- */ //++ void NTuple::GetMinMax(int k, double& min, double& max) const // // Retourne le minimum et le maximum de la variable `k'. //-- { min = 9.e19; max = -9.e19; if ( (k < 0) || (k >= mNVar) ) return; int jb,ib,i; double x; i=0; for(jb=0; jb< mNBlk; jb++) for(ib=0; ib< mBlk; ib++) { if (i >= mNEnt) break; i++; x = *(mPtr[jb]+ib*mNVar+k); if(i==1) {min = x; max = x;} if (x < min) min = x; if (x > max) max = x; } return; } /* --Methode-- */ void NTuple::GetMinMax(string const & nom, double& min, double& max) const { GetMinMax(IndexNom(nom.c_str()), min, max); } /* --Methode-- */ int NTuple::ColumnIndex(string const & nom) const { return(IndexNom(nom.c_str())); } /* --Methode-- */ string NTuple::ColumnName(int k) const { return(NomIndex(k)); } /* --Methode-- */ //++ string NTuple::VarList_C(const char* nomx) const // // Retourne une chaine de caracteres avec la declaration des noms de // variables. si "nomx!=NULL" , des instructions d'affectation // a partir d'un tableau "nomx[i]" sont ajoutees. //-- { string rets=""; int i; for(i=0; i 0) ) rets += ";"; if (i%5 == 0) rets += "\ndouble "; else rets += ","; rets += mNames+i*LENNAME1; } rets += "; \n"; if (nomx) { char buff[256]; for(i=0; i 0) ) rets += "\n"; } } return(rets); } /* --Methode-- */ //++ string NTuple::LineHeaderToString() const // Retourne une chaine de caracteres avec la liste des noms de // variables, utilisables pour une impression //-- { char buff[32]; string rets=" Num "; for(int i=0; i \ingroup HiStats Persistence (serialisation) handler for class NTuple */ /* --Methode-- */ //++ DECL_TEMP_SPEC /* equivalent a template <> , pour SGI-CC en particulier */ void ObjFileIO::WriteSelf(POutPersist& s) const // // Ecriture ppersist du ntuple. //-- { if (dobj == NULL) return; // On ecrit cette chaine pour compatibilite avec l'ancienne version string strg = "NTuple"; s.Put(strg); // On ecrit 3 uint_4 .... // 0: Numero de version, 1 : non nul -> has info, 2 : reserve uint_4 itab[3]; itab[0] = 2; // Numero de version a 1 itab[1] = itab[2] = 0; if (dobj->mInfo) itab[1] = 1; s.Put(itab, 3); s.Put(dobj->mNVar); s.PutBytes(dobj->mNames, dobj->mNVar*LENNAME1); s.Put(dobj->mNEnt); s.Put(dobj->mBlk); s.Put(dobj->mNBlk); if (dobj->mInfo) s << (*(dobj->mInfo)); int jb; for(jb=0; jbmNBlk; jb++) s.Put(dobj->mPtr[jb], dobj->mNVar*dobj->mBlk); return; } /* --Methode-- */ //++ DECL_TEMP_SPEC /* equivalent a template <> , pour SGI-CC en particulier */ void ObjFileIO::ReadSelf(PInPersist& s) // // Lecture ppersist du ntuple. //-- { if (dobj == NULL) dobj = new NTuple; else dobj->Clean(); bool hadinfo = false; string strg; s.Get(strg); if (strg == "NTuple") { uint_4 itab[3]; s.Get(itab, 3); if (itab[1] != 0) hadinfo = true; } else { // Ancienne version de PPF NTuple - Pour savoir s'il y avait un DVList Info associe char buff[256]; strcpy(buff, strg.c_str()); if (strncmp(buff+strlen(buff)-7, "HasInfo", 7) == 0) hadinfo = true; } s.Get(dobj->mNVar); dobj->mNames = new char[dobj->mNVar*LENNAME1]; dobj->mVar = new r_4[dobj->mNVar]; dobj->mVarD = new r_8[dobj->mNVar]; s.GetBytes(dobj->mNames, dobj->mNVar*LENNAME1); s.Get(dobj->mNEnt); s.Get(dobj->mBlk); s.Get(dobj->mNBlk); if (hadinfo) { // Lecture eventuelle du DVList Info if (dobj->mInfo == NULL) dobj->mInfo = new DVList; s >> (*(dobj->mInfo)); } int jb; for(jb=0; jbmNBlk; jb++) { r_4* pt = new r_4[dobj->mNVar*dobj->mBlk]; dobj->mPtr.push_back(pt); s.Get(dobj->mPtr[jb], dobj->mNVar*dobj->mBlk); } } #ifdef __CXX_PRAGMA_TEMPLATES__ #pragma define_template ObjFileIO #endif #if defined(ANSI_TEMPLATES) || defined(GNU_TEMPLATES) template class ObjFileIO; #endif