#include <map>
#include <TGraphErrors.h>
#include <TAxis.h>
#include "TFTable.h"
#include "TFColumn.h"
#include "TFError.h"
#ifndef TF_CLASS_IMP
#define TF_CLASS_IMP
ClassImp(TFTable)
ClassImp(TFColIter)
#endif // TF_CLASS_IMP
TFTable * TFReadTable(const char * fileName, const char * name,
UInt_t cycle, FMode mode)
{
TFIOElement * element = TFRead(fileName, name, cycle, mode, TFTable::Class());
TFTable * table = dynamic_cast<TFTable *>(element);
if (table == NULL)
delete element;
return table;
}
TFTable::TFTable()
{
fNumRows = 0;
fReadAll = kFALSE;
fAlreadyRead = 0;
}
TFTable::TFTable(TTree * tree)
: TFIOElement(tree->GetName())
{
fNumRows = 0;
fReadAll = kFALSE;
fAlreadyRead = 0;
UInt_t rows;
if (tree->GetEntries() > TF_MAX_ROWS)
rows = TF_MAX_ROWS;
else
rows = (UInt_t)(tree->GetEntries() + 0.5);
InsertRows(rows);
TFErrorType prevErrType = TFError::GetErrorType();
TFError::SetErrorType(kAllErr);
tree->SetBranchStatus("*", 0);
TObjArray * branches = tree->GetListOfBranches();
for (int brLoop = 0; brLoop < branches->GetEntriesFast(); brLoop++)
{
TBranch * branch = (TBranch*)((*branches)[brLoop]);
if (branch == NULL) continue;
const char * leaf = branch->GetTitle();
const char * pos;
if (strchr(leaf, ':') == NULL &&
(pos = strchr(leaf, '/')) != NULL )
{
void * branchBuffer;
try
{
const char * array = strchr(leaf, '[');
if (array != NULL)
{
int size = atoi(array+1);
if (size == 0)
continue;
switch (*(pos+1))
{
case 'C' : {
TFStringCol & col = AddColumn(branch->GetName(), TFStringCol::Class());
branchBuffer = col.GetStringBranchBuffer(size);
}
break;
case 'b' : {
TFUCharArrCol & col = AddColumn(branch->GetName(), TFUCharArrCol::Class());
col.SetNumBins(size);
branchBuffer = col.GetBranchBuffer();
}
break;
case 'B' : {
TFCharArrCol & col = AddColumn(branch->GetName(), TFCharArrCol::Class());
col.SetNumBins(size);
branchBuffer = col.GetBranchBuffer();
}
break;
case 's' : {
TFUShortArrCol & col = AddColumn(branch->GetName(), TFUShortArrCol::Class());
col.SetNumBins(size);
branchBuffer = col.GetBranchBuffer();
}
break;
case 'S' : {
TFShortArrCol & col = AddColumn(branch->GetName(), TFShortArrCol::Class());
col.SetNumBins(size);
branchBuffer = col.GetBranchBuffer();
}
break;
case 'i' : {
TFUIntArrCol & col = AddColumn(branch->GetName(), TFUIntArrCol::Class());
col.SetNumBins(size);
branchBuffer = col.GetBranchBuffer();
}
break;
case 'I' : {
TFIntArrCol & col = AddColumn(branch->GetName(), TFIntArrCol::Class());
col.SetNumBins(size);
branchBuffer = col.GetBranchBuffer();
}
break;
case 'D' : {
TFDoubleArrCol & col = AddColumn(branch->GetName(), TFDoubleArrCol::Class());
col.SetNumBins(size);
branchBuffer = col.GetBranchBuffer();
}
break;
case 'F' : {
TFFloatArrCol & col = AddColumn(branch->GetName(), TFFloatArrCol::Class());
col.SetNumBins(size);
branchBuffer = col.GetBranchBuffer();
}
break;
default:
continue;
}
}
else
{
switch (*(pos+1))
{
case 'b' :
branchBuffer = AddColumn(branch->GetName(), TFUCharCol::Class()).GetBranchBuffer();
break;
case 'B' :
branchBuffer = AddColumn(branch->GetName(), TFCharCol::Class()).GetBranchBuffer();
break;
case 's' :
branchBuffer = AddColumn(branch->GetName(), TFUShortCol::Class()).GetBranchBuffer();
break;
case 'S' :
branchBuffer = AddColumn(branch->GetName(), TFShortCol::Class()).GetBranchBuffer();
break;
case 'i' :
branchBuffer = AddColumn(branch->GetName(), TFUIntCol::Class()).GetBranchBuffer();
break;
case 'I' :
branchBuffer = AddColumn(branch->GetName(), TFIntCol::Class()).GetBranchBuffer();
break;
case 'D' :
branchBuffer = AddColumn(branch->GetName(), TFDoubleCol::Class()).GetBranchBuffer();
break;
case 'F' :
branchBuffer = AddColumn(branch->GetName(), TFFloatCol::Class()).GetBranchBuffer();
break;
default:
continue;
}
}
}
catch (TFException)
{ continue; }
tree->SetBranchStatus(branch->GetName(), 1);
branch->SetAddress(branchBuffer);
}
}
TFError::SetErrorType(prevErrType);
for (UInt_t row = 0; row < fNumRows; row++)
{
tree->GetEntry(row);
for (I_ColList i_c = fColumns.begin(); i_c != fColumns.end(); i_c++)
i_c->GetCol().CopyBranchBuffer(row);
}
for (I_ColList i_c = fColumns.begin(); i_c != fColumns.end(); i_c++)
i_c->GetCol().ClearBranchBuffer();
}
TFTable::TFTable(const char * name, UInt_t numRows)
: TFIOElement(name)
{
fNumRows = numRows;
fReadAll = kFALSE;
fAlreadyRead = 0;
}
TFTable::TFTable(const char * name, const char * fileName)
: TFIOElement(name, fileName)
{
fNumRows = 0;
fReadAll = kFALSE;
fAlreadyRead = 0;
if (fio)
fio->CreateElement();
}
TFTable::TFTable(const TFTable & table)
: TFIOElement(table)
{
fNumRows = table.fNumRows;
TObject * col;
table.ReadAllCol();
for (I_ColList i_c = table.fColumns.begin(); i_c != table.fColumns.end(); i_c++)
fColumns.insert(TFColWrapper((TFBaseCol&)*i_c->GetCol().Clone()));
fReadAll = kFALSE;
}
TFTable::~TFTable()
{
for (I_ColList i_c = fColumns.begin(); i_c != fColumns.end(); i_c++)
delete &i_c->GetCol();
}
TFTable & TFTable::operator=(const TFTable & table)
{
if (this != &table)
{
TFIOElement::operator=(table);
for (I_ColList i_c = fColumns.begin(); i_c != fColumns.end(); i_c++)
delete &i_c->GetCol();
fColumns.clear();
fNumRows = table.fNumRows;
fReadAll = kFALSE;
fAlreadyRead = 0;
table.ReadAllCol();
for (I_ColList i_c = table.fColumns.begin(); i_c != table.fColumns.end(); i_c++)
fColumns.insert(TFColWrapper((TFBaseCol&)*i_c->GetCol().Clone()));
}
return *this;
}
bool TFTable::operator == (const TFHeader & ioelement) const
{
if (TFIOElement::operator==(ioelement) == false ||
IsA() != ioelement.IsA() )
return false;
TFTable & table = (TFTable&)ioelement;
if (fNumRows != table.fNumRows ||
GetNumColumns() != table.GetNumColumns() )
return false;
if (GetNumColumns() == 0)
return true;
TFColIter i_col1 = MakeColIterator();
TFColIter i_col2 = table.MakeColIterator();
while (i_col1.Next() && i_col2.Next())
if (!(*i_col1 == *i_col2) )
return false;
return true;
}
Int_t TFTable::AddColumn(TFBaseCol * column, Bool_t replace)
{
I_ColList i_col;
if ((i_col = fColumns.find(TFColWrapper(*column))) != fColumns.end() ||
(i_col = ReadCol(column->GetName())) != fColumns.end() )
{
if (replace)
{
delete &i_col->GetCol();
fColumns.erase(i_col);
}
else
{
TFError::SetError("TFTable::AddColumn",
"Column %s already exist in table %s. New column rejected",
column->GetName(), GetName() );
return -1;
}
}
UInt_t prevNumRows = column->GetNumRows();
if (prevNumRows < fNumRows)
column->InsertRows(fNumRows - prevNumRows, prevNumRows);
else if (column->GetNumRows() > fNumRows)
column->DeleteRows(column->GetNumRows() - fNumRows, fNumRows);
fColumns.insert(TFColWrapper(*column));
return 0;
}
TFBaseCol & TFTable::AddColumn(const char * name, TClass * colDataType,
Bool_t replace)
{
I_ColList i_col;
TNamed tmp(name, "");
if ((i_col = fColumns.find(TFColWrapper(tmp))) != fColumns.end() ||
(i_col = ReadCol(name)) != fColumns.end() )
{
if (replace)
{
delete &i_col->GetCol();
fColumns.erase(i_col);
}
else
{
TFError::SetError("TFTable::AddColumn",
"Column %s already exist in table %s. New column rejected",
name, GetName() );
return i_col->GetCol();
}
}
TFBaseCol * column = (TFBaseCol*)colDataType->New();
column->SetName(name);
column->InsertRows(fNumRows, 0);
fColumns.insert(TFColWrapper(*column));
return *column;
}
void TFTable::DeleteColumn(const char * name)
{
I_ColList i_col;
Bool_t fileDel = kFALSE;
Bool_t memDel = kFALSE;
TNamed tmp(name, "");
if ((i_col = fColumns.find(TFColWrapper(tmp))) != fColumns.end())
{
delete &i_col->GetCol();
fColumns.erase(i_col);
memDel = kTRUE;
}
if ( fio )
fileDel = fio->DeleteColumn(name) == 0;
if(memDel && fileDel && fAlreadyRead > 0)
fAlreadyRead--;
}
TFBaseCol & TFTable::GetColumn(const char * name) const
{
TNamed tmp(name, "");
I_ColList i_col = fColumns.find(TFColWrapper(tmp));
if (i_col != fColumns.end())
return i_col->GetCol();
i_col = ReadCol(name);
if (i_col == fColumns.end())
{
TFError::SetError("TFTable::GetColumn",
"Column %s does not exist in table %s.",
name, GetName() );
return *((TFBaseCol*)0);
}
return i_col->GetCol();
}
TFColIter TFTable::MakeColIterator() const
{
ReadAllCol();
return TFColIter(&fColumns);
}
TFRowIter TFTable::MakeRowIterator() const
{
return TFRowIter(this);
}
void TFTable::InsertRows(UInt_t numRows, UInt_t pos)
{
TFBaseCol * col;
ReadAllCol();
if (pos > fNumRows)
pos = fNumRows;
for (I_ColList i_c = fColumns.begin(); i_c != fColumns.end(); i_c++)
i_c->GetCol().InsertRows(numRows, pos);
fNumRows += numRows;
}
void TFTable::DeleteRows(UInt_t numRows, UInt_t pos)
{
TFBaseCol * col;
if (pos == TF_MAX_ROWS)
{
if(numRows < fNumRows)
pos = fNumRows - numRows;
else
pos = 0;
}
if (pos >= fNumRows)
return;
if (pos + numRows > fNumRows)
numRows = fNumRows - pos;
ReadAllCol();
for (I_ColList i_c = fColumns.begin(); i_c != fColumns.end(); i_c++)
i_c->GetCol().DeleteRows(numRows, pos);
fNumRows -= numRows;
}
UInt_t TFTable::GetNumColumns() const
{
UInt_t num = 0;
if (!fReadAll && fio)
num = fio->GetNumColumns() - fAlreadyRead;
return fColumns.size() + num;
}
void TFTable::Reserve(UInt_t rows)
{
ReadAllCol();
for (I_ColList i_c = fColumns.begin(); i_c != fColumns.end(); i_c++)
i_c->GetCol().Reserve(rows);
}
I_ColList TFTable::ReadCol(const char * name) const
{
I_ColList i_c = fColumns.end();
if (!fReadAll && fio)
{
TFBaseCol * col = fio->ReadCol(name);
if (col)
{
i_c = fColumns.insert(TFColWrapper(*col)).first;
fAlreadyRead++;
}
}
return i_c;
}
void TFTable::ReadAllCol() const
{
if (!fReadAll && fio)
{
fio->ReadAllCol(fColumns);
fReadAll = kTRUE;
}
}
Int_t TFTable::SaveElement(const char * fileName, Int_t compLevel)
{
if (TFIOElement::SaveElement(fileName, compLevel) != 0)
return -1;
Int_t err = 0;
if (fio && fFileAccess == kFReadWrite )
{
err = fio->SaveColumns(fColumns, compLevel);
fAlreadyRead = fColumns.size();
}
return err;
}
Int_t TFTable::DeleteElement(Bool_t updateMemory)
{
if (updateMemory)
ReadAllCol();
return TFIOElement::DeleteElement();
}
TTree * TFTable::MakeTree(TFNameConvert * nameConvert) const
{
if (nameConvert == NULL)
nameConvert = new TFNameConvert();
TTree * tree= new TTree(nameConvert->Conv(GetName()), nameConvert->Conv(GetName()) );
ReadAllCol();
for (I_ColList i_c = fColumns.begin(); i_c != fColumns.end(); i_c++)
i_c->GetCol().MakeBranch(tree, nameConvert);
for (UInt_t row = 0; row < fNumRows; row++)
{
for (I_ColList i_c = fColumns.begin(); i_c != fColumns.end(); i_c++)
i_c->GetCol().FillBranchBuffer(row);
tree->Fill();
}
for (I_ColList i_c = fColumns.begin(); i_c != fColumns.end(); i_c++)
i_c->GetCol().ClearBranchBuffer();
delete nameConvert;
return tree;
}
TGraphErrors * TFTable::MakeGraph(const char * xCol, const char * yCol,
const char * xErrCol, const char * yErrCol,
TGraphErrors * graph)
{
if (graph == NULL)
{
if (GetNumRows() < 2)
{
TFError::SetError("TFTable::MakeGraph",
"Number of rows (%u) of table %s is too small to"
" create a TGraphError.", GetNumRows(), GetName());
return NULL;
}
graph = new TGraphErrors(GetNumRows());
graph->SetTitle(GetName());
}
TFErrorType prevErrType = TFError::GetErrorType();
TFError::SetErrorType(kAllErr);
UInt_t numRows = GetNumRows() < graph->GetN() ? GetNumRows() : graph->GetN();
if (xCol != NULL && xCol[0] != 0)
{
try
{
const TFBaseCol & col = GetColumn(xCol);
double * axis = graph->GetX();
for (UInt_t row = 0; row < numRows; row++)
axis[row] = col[row];
TFNullIter i_null = col.MakeNullIterator();
while (i_null.Next())
axis[*i_null] = 0;
}
catch (TFException) { }
}
if (yCol != NULL && yCol[0] != 0)
{
try
{
const TFBaseCol & col = GetColumn(yCol);
double * axis = graph->GetY();
for (UInt_t row = 0; row < numRows; row++)
axis[row] = col[row];
TFNullIter i_null = col.MakeNullIterator();
while (i_null.Next())
axis[*i_null] = 0;
}
catch (TFException) { }
}
if (xErrCol != NULL && xErrCol[0] != 0)
{
try
{
const TFBaseCol & col = GetColumn(xErrCol);
double * axis = graph->GetEX();
for (UInt_t row = 0; row < numRows; row++)
axis[row] = col[row];
TFNullIter i_null = col.MakeNullIterator();
while (i_null.Next())
axis[*i_null] = 0;
}
catch (TFException) { }
}
if (yErrCol != NULL && yErrCol[0] != 0)
{
try
{
const TFBaseCol & col = GetColumn(yErrCol);
double * axis = graph->GetEY();
for (UInt_t row = 0; row < numRows; row++)
axis[row] = col[row];
TFNullIter i_null = col.MakeNullIterator();
while (i_null.Next())
axis[*i_null] = 0;
}
catch (TFException) { }
}
TFError::SetErrorType(prevErrType);
if (xCol != NULL && xCol[0] != 0 &&
yCol != NULL && yCol[0] != 0 )
{
TAxis * axis = graph->GetXaxis();
if (axis) axis->SetTitle(xCol);
axis = graph->GetYaxis();
if (axis) axis->SetTitle(yCol);
}
return graph;
}
void TFTable::Print(const Option_t* option) const
{
TFIOElement::Print(option);
printf("\n number of rows: %u number of columns: %u\n",
GetNumRows(), GetNumColumns() );
if (option[0] != 0 &&
strchr(option, 'c') == NULL &&
strchr(option, 'C') == NULL )
return;
std::map<TString, TNamed> columns;
for (I_ColList i_c = fColumns.begin(); i_c != fColumns.end(); i_c++)
columns[i_c->GetCol().GetName()] = TNamed(i_c->GetCol().GetColTypeName(),
i_c->GetCol().GetTypeName() );
if (fio)
fio->GetColNames(columns);
std::map<TString, TString> typedefNames;
typedefNames[TFBoolArrCol::Class()->GetName()] = "TFBoolArrCol";
typedefNames[TFCharArrCol::Class()->GetName()] = "TFCharArrCol";
typedefNames[TFUCharArrCol::Class()->GetName()] = "TFUCharArrCol";
typedefNames[TFShortArrCol::Class()->GetName()] = "TFShortArrCol";
typedefNames[TFUShortArrCol::Class()->GetName()] = "TFUShortArrCol";
typedefNames[TFIntArrCol::Class()->GetName()] = "TFIntArrCol";
typedefNames[TFUIntArrCol::Class()->GetName()] = "TFUIntArrCol";
typedefNames[TFFloatArrCol::Class()->GetName()] = "TFFloatArrCol";
typedefNames[TFDoubleArrCol::Class()->GetName()] = "TFDoubleArrCol";
typedefNames[TFBoolCol::Class()->GetName()] = "TFBoolCol";
typedefNames[TFCharCol::Class()->GetName()] = "TFCharCol";
typedefNames[TFUCharCol::Class()->GetName()] = "TFUCharCol";
typedefNames[TFShortCol::Class()->GetName()] = "TFShortCol";
typedefNames[TFUShortCol::Class()->GetName()] = "TFUShortCol";
typedefNames[TFIntCol::Class()->GetName()] = "TFIntCol";
typedefNames[TFUIntCol::Class()->GetName()] = "TFUIntCol";
typedefNames[TFFloatCol::Class()->GetName()] = "TFFloatCol";
typedefNames[TFDoubleCol::Class()->GetName()] = "TFDoubleCol";
std::map<TString, TNamed>::const_iterator i_col;
for (i_col = columns.begin(); i_col != columns.end(); i_col++)
if (typedefNames.find(i_col->second.GetName()) == typedefNames.end())
printf("%-20s %-40s %16s %s\n",
i_col->first.Data(), i_col->second.GetName(), "", i_col->second.GetTitle());
else
printf("%-20s %-40s %-16s %s\n",
i_col->first.Data(),
i_col->second.GetName(),
typedefNames[i_col->second.GetName()].Data(),
i_col->second.GetTitle());
}
Last update: Fri Mar 14 13:55:11 2008
This page has been automatically generated. If you have any comments or suggestions about the page layout send a mail to ROOT support, or contact the developers with any questions or problems regarding ROOT.