// //////////////////////////////////////////////////////////////////////////// // // File: TFColumn.h // // Version: 1.0 // // Author: Reiner Rohlfs (GADC) // // History: 1.0 18.07.03 first released version // // //////////////////////////////////////////////////////////////////////////// #ifndef ROOT_TFColumn #define ROOT_TFColumn #ifndef ROOT_TTree #include "TTree.h" #endif #ifndef ROOT_TFHeader #include "TFHeader.h" #endif #ifndef ROOT_TFColWrapper #include "TFColWrapper.h" #endif #ifndef ROOT_TFTable #include "TFTable.h" #endif #ifndef ROOT_TFNameConvert #include "TFNameConvert.h" #endif #include #include using namespace std; class TFNullIter; class TFTable; template class TFColumn; template class TFArrColumn; class TFStringCol; //_____________________________________________________________________________ class TFSetDbl { TFBaseCol * fCol; UInt_t fRow; public: TFSetDbl(TFBaseCol * col, UInt_t row) {fCol = col; fRow = row;} Double_t operator = (Double_t val); operator Double_t (); ClassDef(TFSetDbl, 0) // internal class, not to be used by an application }; //_____________________________________________________________________________ class TFBaseCol : public TNamed, public TFHeader { protected: set fNull; // set of (row,bins) which are NULL values public: TFBaseCol(); TFBaseCol(const TFBaseCol & col); TFBaseCol(const char * name); TFBaseCol(const TString &name); virtual ~TFBaseCol() {}; virtual TObject * Clone(const char * name="") const = 0; virtual TFBaseCol & operator = (const TFBaseCol & col); virtual bool operator == (const TFHeader & col) const; virtual Bool_t IsNull(UInt_t row, UInt_t bin = 0) const {return fNull.find(((ULong64_t)row << 32) + bin) != fNull.end();} virtual void SetNull(UInt_t row, UInt_t bin = 0) {fNull.insert(((ULong64_t)row << 32) + bin);} virtual void ClearNull(UInt_t row, UInt_t bin = 0) {fNull.erase(((ULong64_t)row << 32) + bin);} virtual Bool_t HasNull() const {return !fNull.empty();} TFNullIter MakeNullIterator() const; virtual int CompareRows(UInt_t row1, UInt_t row2) const = 0; virtual Int_t GetNumBins() const {return 1;} virtual void SetNumBins(UInt_t bins) {} // default does nothing virtual UInt_t GetNumRows() const = 0; virtual size_t GetWidth() const = 0; virtual const char * GetUnit() const {return fTitle.Data();} virtual void SetUnit(const char * unit) {fTitle = unit;} virtual void Reserve(UInt_t rows) = 0; virtual char * GetStringValue(UInt_t row, Int_t bin, char * str, Int_t width = 0, const char * format = NULL) const = 0; virtual void SetString(UInt_t row, Int_t bin, const char * str) = 0; virtual const char * GetTypeName() const = 0; virtual const char * GetColTypeName() const = 0; virtual void MakeBranch(TTree* tree, TFNameConvert * nameConvert) const = 0; virtual void * GetBranchBuffer() = 0; virtual void FillBranchBuffer(UInt_t row) const = 0; virtual void CopyBranchBuffer(UInt_t row) = 0; virtual void ClearBranchBuffer() const = 0; Double_t operator[](UInt_t row) const {return ToDouble(row);} TFSetDbl operator[](UInt_t row) {return TFSetDbl(this, row);} operator TFColumn & (); operator TFColumn & (); operator TFColumn & (); operator TFColumn & (); operator TFColumn & (); operator TFColumn & (); operator TFColumn & (); operator TFColumn & (); operator TFColumn & (); operator TFStringCol & (); operator TFArrColumn & (); operator TFArrColumn & (); operator TFArrColumn & (); operator TFArrColumn & (); operator TFArrColumn & (); operator TFArrColumn & (); operator TFArrColumn & (); operator TFArrColumn & (); operator TFArrColumn & (); protected: virtual void InsertRows(UInt_t numRows, UInt_t pos); virtual void DeleteRows(UInt_t numRows = 1, UInt_t pos = TF_MAX_ROWS); virtual void SetDouble(Double_t val, UInt_t row) = 0; virtual Double_t ToDouble(UInt_t row) const = 0; friend Int_t TFTable::AddColumn(TFBaseCol * column, Bool_t replace); friend TFBaseCol & TFTable::AddColumn(const char * name, TClass * colDataType, Bool_t replace); friend void TFTable::InsertRows(UInt_t numRows, UInt_t pos); friend void TFTable::DeleteRows(UInt_t numRows, UInt_t pos); friend Double_t TFSetDbl::operator=(Double_t); friend TFSetDbl::operator Double_t (); ClassDef(TFBaseCol,1) // Abstract base column of TFTable }; //_____________________________________________________________________________ class TFNullIndex { ULong64_t fNull; public: TFNullIndex() {fNull = 0;} TFNullIndex(ULong64_t null) {fNull = null;} TFNullIndex & operator = (ULong64_t nullIndex) {fNull = nullIndex; return *this;} TFNullIndex & operator = (UInt_t row) {fNull = (ULong64_t)row << 32; return *this;} operator UInt_t() const {return (UInt_t)(fNull >> 32);} UInt_t Row() const {return (UInt_t)(fNull >> 32);} UInt_t Bin() const {return (UInt_t)(fNull);} }; //_____________________________________________________________________________ class TFNullIter { std::set::const_iterator fIter; // next NULL iterator of a column std::set::const_iterator fBegin; // first NULL iterator of a column std::set::const_iterator fEnd; // last NULL iterator of a column TFNullIndex fNull; // the actual row index of this iterator TFNullIter(std::set::const_iterator begin, std::set::const_iterator end) {fBegin = fIter = begin; fEnd = end;} public: TFNullIter(const TFNullIter & nullIter) { fIter = nullIter.fIter; fBegin = nullIter.fBegin; fEnd = nullIter.fEnd; fNull = nullIter.fNull; } TFNullIter & operator = (const TFNullIter & nullIter); Bool_t Next() {if (fIter == fEnd) return kFALSE; fNull = *fIter; ++fIter; return kTRUE;} TFNullIndex & operator * () {return fNull;} TFNullIndex * operator -> () {return &fNull;} void Reset() {fIter = fBegin;} friend TFNullIter TFBaseCol::MakeNullIterator() const; ClassDef(TFNullIter,0) // An iterator for NULL values of columns }; //_____________________________________________________________________________ template > class TFColumn : public TFBaseCol { protected: std::vector fData; // all Data of this column mutable T treeBuffer; //! buffer to fill a TTree public: typedef T value_type; TFColumn() {} TFColumn(const char * name, int numRows = 0) : TFBaseCol(name) , fData(numRows) {} TFColumn(const TFColumn & column) : TFBaseCol(column) {fData = column.fData;} virtual TFColumn & operator = (const TFColumn & col) { if (&col != this) { TFBaseCol::operator=(col); fData = col.fData; } return *this; } virtual bool operator == (const TFHeader & col) const { return TFBaseCol::operator==(col) && IsA() == col.IsA() && fData == ((TFColumn&)col).fData;} virtual TObject * Clone(const char * name="") const {return new TFColumn(*this);} int CompareRows(UInt_t row1, UInt_t row2) const {return (fData[row1] < fData[row2]) ? -1 : (fData[row2] < fData[row1]) ? 1 : 0;} typename std::vector::const_reference operator[](UInt_t row) const {return fData[row];} typename std::vector::reference operator[](UInt_t row) {return fData[row];} UInt_t GetNumRows() const {return fData.size();} size_t GetWidth() const {return sizeof(T);} void Reserve(UInt_t rows) {fData.reserve(rows);} char * GetStringValue(UInt_t row, Int_t bin, char * str, Int_t width = 0, const char * format = NULL) const {return F::Format(str, width, format, fData[row]);} void SetString(UInt_t row, Int_t bin, const char * str) {F::SetString(str, fData[row]); } const char * GetTypeName() const {return F::GetTypeName();} const char * GetColTypeName() const {return Class_Name();} void MakeBranch(TTree* tree, TFNameConvert * nameConvert) const { if (F::GetBranchType()[0]) { char branch[80]; sprintf(branch, "%s%s", nameConvert->Conv(GetName()), F::GetBranchType()); tree->Branch(nameConvert->Conv(GetName()), &treeBuffer, (const char*)branch); } } void * GetBranchBuffer() {return &treeBuffer;} void FillBranchBuffer(UInt_t row) const {treeBuffer = fData[row];} void CopyBranchBuffer(UInt_t row) {fData[row] = treeBuffer;} void ClearBranchBuffer() const {}; protected: virtual void InsertRows(UInt_t numRows, UInt_t pos){ fData.insert(fData.begin() + pos, numRows, T()); TFBaseCol::InsertRows(numRows, pos); } virtual void DeleteRows(UInt_t numRows, UInt_t pos) { fData.erase(fData.begin() + pos, fData.begin() + pos + numRows); TFBaseCol::DeleteRows(numRows, pos); } virtual Double_t ToDouble(UInt_t row) const {return F::ToDouble(fData[row]);} virtual void SetDouble(Double_t val, UInt_t row) { T b; F::SetDouble(val, b); fData[row]= b;} ClassDef(TFColumn, 1) // A column of TFTable }; //_____________________________________________________________________________ class TFStringCol : public TFColumn { mutable char * fCharBuffer; //! buffer to fill a TTree mutable UInt_t fLength; //! max length of the TStrings public: TFStringCol() {} TFStringCol(const char * name, int numRows = 0) : TFColumn(name, numRows) {fCharBuffer = NULL;} TFStringCol(const TString & name, int numRows = 0) : TFColumn(name, numRows) {fCharBuffer = NULL;} TFStringCol(const TFStringCol & column) : TFColumn(column) {fCharBuffer = NULL;} const char * GetColTypeName() const {return Class_Name();} void MakeBranch(TTree* tree, TFNameConvert * nameConvert) const; void CopyBranchBuffer(UInt_t row) {fData[row] = fCharBuffer;} void * GetStringBranchBuffer(UInt_t lenght); void FillBranchBuffer(UInt_t row) const; void ClearBranchBuffer() const {delete [] fCharBuffer; fCharBuffer = NULL;}; ClassDef(TFStringCol, 1) // A column of TFTable for strings }; //_____________________________________________________________________________ template class TFBinVector { protected: std::vector fData; public: TFBinVector() {} TFBinVector(Int_t num) : fData(num) {} TFBinVector(const TFBinVector & bv) : fData(bv.fData) {} TFBinVector & operator= (const TFBinVector & bv) {fData = bv.fData; return *this;} bool operator == (const TFBinVector & bv) const {return fData == bv.fData;} void resize(Int_t num) {fData.resize(num);} Int_t size() const {return fData.size();} typename std::vector::const_reference operator[](UInt_t row) const {return fData[row];} typename std::vector::reference operator[](UInt_t row) {return fData[row];} ClassDef(TFBinVector, 1) // Internal class of an array column }; //_____________________________________________________________________________ template > class TFArrColumn : public TFBaseCol { protected: std::vector > fData; // all Data of this column Int_t fBins; // number of bins per row // < 0 : variable bin number mutable T * treeBuffer; //! buffer to fill a TTree public: typedef T value_type; TFArrColumn() {fBins = 0; treeBuffer = NULL;} TFArrColumn(const char * name, int numRows = 0) : TFBaseCol(name), fData(numRows) {fBins = 0; treeBuffer = NULL;} TFArrColumn(const TFArrColumn & column) {fData = column.fData; fBins = column.fBins; treeBuffer = NULL;} virtual TObject * Clone(const char * name="") const {return new TFArrColumn(*this);} virtual TFArrColumn & operator = (const TFArrColumn & col) { if (&col != this) { TFBaseCol::operator=(col); fData = col.fData; fBins = col.fBins; } return *this; } virtual bool operator == (const TFHeader & col) const { return TFBaseCol::operator==(col) && IsA() == col.IsA() && fBins == ((TFArrColumn&)col).fBins && fData == ((TFArrColumn&)col).fData;} int CompareRows(UInt_t row1, UInt_t row2) const {return (fData[row1][0] < fData[row2][0]) ? -1 : (fData[row2][0] < fData[row1][0]) ? 1 : 0;} typename std::vector >::const_reference operator[](UInt_t row) const {return fData[row];} typename std::vector >::reference operator[](UInt_t row) {return fData[row];} Int_t GetNumBins() const {return fBins;} void SetNumBins(UInt_t bins) {if (bins > 0) for (int row = 0; row < fData.size(); row++) fData[row].resize(bins); fBins = bins; } void Reserve(UInt_t rows) {fData.reserve(rows);} UInt_t GetNumRows() const {return fData.size();} size_t GetWidth() const {return sizeof(T);} const char * GetTypeName() const {return F::GetTypeName();} const char * GetColTypeName() const {return Class_Name();} void MakeBranch(TTree* tree, TFNameConvert * nameConvert) const { if (F::GetBranchType()[0] && fBins > 0) { treeBuffer = new T[fBins]; char branch[80]; sprintf(branch, "%s[%d]%s", nameConvert->Conv(GetName()), fBins, F::GetBranchType()); tree->Branch(nameConvert->Conv(GetName()), (void*)treeBuffer, (const char*)branch); } } void * GetBranchBuffer() {treeBuffer = new T[fBins]; return treeBuffer;} void FillBranchBuffer(UInt_t row) const { if (F::GetBranchType()[0] && fBins > 0) { for (Int_t num = 0; num < fBins; num++) treeBuffer[num] = fData[row][num]; } } void CopyBranchBuffer(UInt_t row) { for (Int_t num = 0; num < fBins; num++) fData[row][num] = treeBuffer[num]; } void ClearBranchBuffer() const {delete [] treeBuffer; treeBuffer = NULL;}; char * GetStringValue(UInt_t row, Int_t bin, char * str, Int_t width = 0, const char * format = NULL) const {return F::Format(str, width, format, fData[row][bin]);} void SetString(UInt_t row, Int_t bin, const char * str) {F::SetString(str, fData[row][bin]); } protected: virtual void InsertRows(UInt_t numRows, UInt_t pos) { fData.insert(fData.begin() + pos, numRows, TFBinVector(fBins >= 0 ? fBins : 0)); TFBaseCol::InsertRows(numRows, pos); } virtual void DeleteRows(UInt_t numRows, UInt_t pos) { fData.erase(fData.begin() + pos, fData.begin() + pos + numRows); TFBaseCol::DeleteRows(numRows, pos); } virtual Double_t ToDouble(UInt_t row) const {return 0.0;} virtual void SetDouble(Double_t val, UInt_t row) {}; ClassDef(TFArrColumn, 1) // An array column of TFTable (each bin is an array) }; //_____________________________________________________________________________ //_____________________________________________________________________________ typedef TFColumn TFBoolCol; typedef TFColumn TFCharCol; typedef TFColumn TFUCharCol; typedef TFColumn TFShortCol; typedef TFColumn TFUShortCol; typedef TFColumn TFIntCol; typedef TFColumn TFUIntCol; typedef TFColumn TFFloatCol; typedef TFColumn TFDoubleCol; typedef TFArrColumn TFBoolArrCol; typedef TFArrColumn TFCharArrCol; typedef TFArrColumn TFUCharArrCol; typedef TFArrColumn TFShortArrCol; typedef TFArrColumn TFUShortArrCol; typedef TFArrColumn TFIntArrCol; typedef TFArrColumn TFUIntArrCol; typedef TFArrColumn TFFloatArrCol; typedef TFArrColumn TFDoubleArrCol; //_____________________________________________________________________________ //_____________________________________________________________________________ inline Double_t TFSetDbl::operator = (Double_t val) {fCol->SetDouble(val, fRow); return val;} inline TFSetDbl::operator Double_t () {return fCol->ToDouble(fRow);} inline TFNullIter TFBaseCol::MakeNullIterator() const {return TFNullIter(fNull.begin(), fNull.end());} inline TFBaseCol::operator TFColumn & () {return dynamic_cast &>(*this);} inline TFBaseCol::operator TFColumn & () {return dynamic_cast &>(*this);} inline TFBaseCol::operator TFColumn & () {return dynamic_cast &>(*this);} inline TFBaseCol::operator TFColumn & () {return dynamic_cast &>(*this);} inline TFBaseCol::operator TFColumn & () {return dynamic_cast &>(*this);} inline TFBaseCol::operator TFColumn & () {return dynamic_cast &>(*this);} inline TFBaseCol::operator TFColumn & () {return dynamic_cast &>(*this);} inline TFBaseCol::operator TFColumn & () {return dynamic_cast &>(*this);} inline TFBaseCol::operator TFColumn & () {return dynamic_cast &>(*this);} inline TFBaseCol::operator TFStringCol & () {return dynamic_cast (*this);} inline TFBaseCol::operator TFArrColumn & () {return dynamic_cast &>(*this);} inline TFBaseCol::operator TFArrColumn & () {return dynamic_cast &>(*this);} inline TFBaseCol::operator TFArrColumn & () {return dynamic_cast &>(*this);} inline TFBaseCol::operator TFArrColumn & () {return dynamic_cast &>(*this);} inline TFBaseCol::operator TFArrColumn & () {return dynamic_cast &>(*this);} inline TFBaseCol::operator TFArrColumn & () {return dynamic_cast &>(*this);} inline TFBaseCol::operator TFArrColumn & () {return dynamic_cast &>(*this);} inline TFBaseCol::operator TFArrColumn & () {return dynamic_cast &>(*this);} inline TFBaseCol::operator TFArrColumn & () {return dynamic_cast &>(*this);} inline TFNullIter & TFNullIter::operator = (const TFNullIter & nullIter) { fIter = nullIter.fIter; fBegin = nullIter.fBegin; fEnd = nullIter.fEnd; fNull = nullIter.fNull; return *this; } #endif