#include "THaCut.h"
#include "THaNamedList.h"
#include "THaCutList.h"
#include "THaPrintOption.h"
#include "TError.h"
#include "TList.h"
#include "TString.h"
#include <iostream>
#include <fstream>
#include <iomanip>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <cctype>
using namespace std;
const char* const THaCutList::kDefaultBlockName = "Default";
const char* const THaCutList::kDefaultCutFile = "default.cuts";
void THaHashList::PrintOpt( Option_t* opt ) const
{
TIter next(this);
TObject* object;
while((object = next()))
object->Print(opt);
}
THaCutList::THaCutList() : fVarList(NULL)
{
fCuts = new THaHashList();
fBlocks = new THaHashList();
}
THaCutList::THaCutList( const THaVarList* lst ) : fVarList(lst)
{
fCuts = new THaHashList();
fBlocks = new THaHashList();
}
THaCutList::~THaCutList()
{
fCuts->Clear();
fBlocks->Delete();
delete fCuts;
delete fBlocks;
}
void THaCutList::Clear( Option_t* )
{
fBlocks->Delete();
fCuts->Delete();
}
void THaCutList::ClearAll( Option_t* )
{
TIter next( fCuts );
while( THaCut* pcut = static_cast<THaCut*>( next() ))
pcut->ClearResult();
}
void THaCutList::ClearBlock( const char* block, Option_t* )
{
TIter next( FindBlock(block) );
while( THaCut* pcut = static_cast<THaCut*>( next() ))
pcut->ClearResult();
}
void THaCutList::Compile()
{
TList* bad_cuts = NULL;
bool have_bad = false;
TIter next( fCuts );
while( THaCut* pcut = static_cast<THaCut*>( next() )) {
pcut->Compile();
if( pcut->IsError() ) {
Error( "Compile", "expression error, cut removed: %s %s block: %s",
pcut->GetName(), pcut->GetTitle(), pcut->GetBlockname() );
if( !bad_cuts ) bad_cuts = new TList;
bad_cuts->Add( new TNamed( *pcut ));
have_bad = true;
}
}
if( have_bad ) {
TIter next_bad( bad_cuts );
while( TNamed* pbad = static_cast<TNamed*>( next_bad() )) {
Remove( pbad->GetName() );
}
bad_cuts->Delete();
}
delete bad_cuts;
}
Int_t THaCutList::Define( const char* cutname, const char* expr,
const char* block )
{
if( !fVarList ) {
Error( "Define", "no variable list set, cut not created" );
return -1;
}
return Define( cutname, expr, fVarList, block );
}
Int_t THaCutList::Define( const char* cutname, const char* expr,
const THaVarList* lst, const char* block )
{
static const char* here = "THaCutList::Define";
if( !cutname || !*cutname || (strspn(cutname," ")==strlen(cutname)) ) {
Error( here, "empty cut name, cut not created" );
return -4;
}
if( !expr || !*expr || (strspn(expr," ")==strlen(expr)) ) {
Error( here, "empty expression string, cut not created: %s", cutname );
return -5;
}
if( !block || !*block || (strspn(block," ")==strlen(block)) ) {
Error( here, "empty block name, cut not created: %s %s", cutname, expr );
return -6;
}
if( strpbrk(cutname,"\"'` ") ) {
Error( here, "illegal character(s) in cut name, cut not created: "
"%s %s block: %s", cutname, expr, block );
return -7;
}
if( fCuts->FindObject(cutname) ) {
Error( here, "duplicate cut name, cut not created: %s %s block: %s",
cutname, expr, block );
return -8;
}
THaCut* pcut = new THaCut( cutname, expr, block, lst, this );
if( !pcut ) return -2;
if( pcut->IsError() ) {
Error( here, "expression error, cut not created: %s %s block: %s",
cutname, expr, block );
delete pcut;
return -3;
}
THaNamedList* plist = FindBlock( block );
if( !plist ) {
plist = new THaNamedList( block );
fBlocks->Add( plist );
}
fCuts->AddLast( pcut );
plist->AddLast( pcut );
return 0;
}
Int_t THaCutList::Eval()
{
Int_t i = 0;
TIter next( fBlocks );
while( THaNamedList* plist = static_cast<THaNamedList*>( next() ))
i += EvalBlock( plist );
return i;
}
Int_t THaCutList::EvalBlock( const TList* plist )
{
if( !plist ) return -1;
Int_t i = 0;
TIter next( plist );
while( THaCut* pcut = static_cast<THaCut*>( next() )) {
pcut->EvalCut();
i++;
}
return i;
}
Int_t THaCutList::EvalBlock( const char* block )
{
return EvalBlock( FindBlock( block ) );
}
static inline bool IsEnd( const char* s )
{
return ( !*s || *s == '#' || (*s == '/' && *(s+1) == '/' ));
}
Int_t THaCutList::Load( const char* filename )
{
static const char* const here = "THaCutList::Load";
static const char* const whtspc = " \t";
if( !filename || !*filename || strspn(filename," ") == strlen(filename) ) {
Error( here, "invalid file name, no cuts loaded" );
return -1;
}
ifstream ifile( filename );
if( !ifile ) {
Error( here, "error opening input file %s, no cuts loaded",
filename );
return -2;
}
const unsigned LEN = 256;
unsigned line_size = LEN;
char* line = new char[ line_size ];
char block[ LEN ];
strcpy( block, kDefaultBlockName );
Int_t nlines_read = 0, nlines_ok = 0;
while( !ifile.eof() ) {
streampos pos = ifile.tellg();
ifile.getline( line, line_size );
if( (unsigned)ifile.gcount() == line_size-1 ) {
ifile.clear();
ifile.seekg( pos );
delete [] line;
line_size += LEN;
line = new char[ line_size ];
continue;
}
size_t i = strspn( line, whtspc );
if( IsEnd(line+i) ) continue;
nlines_read++;
const char* arg1 = line+i, *arg2 = 0;
while( line[i] && !isspace(line[i]) ) i++;
if( line[i] == '\0' ) goto noexpr;
line[i++] = '\0';
while( isspace(line[i])) i++;
if( IsEnd(line+i) ) goto noexpr;
arg2 = line+i;
i++;
while( !IsEnd(line+i) ) i++;
while( isspace(line[i-1]) ) i--;
line[i] = '\0';
if( !strcmp( arg1, "Block:" ) ) {
if( strlen(arg2) >= LEN ) {
Error( here, "block name too long, aborting: %s", arg2 );
return -3;
}
strcpy( block, arg2 );
nlines_ok++;
continue;
}
if( strlen(arg1) >= LEN ) {
Error( here, "cut name too long, cut not loaded: %s %s",
arg1, arg2 );
continue;
}
if( !Define( arg1, arg2, block ) ) nlines_ok++;
continue;
noexpr:
Warning( here, "ignoring label without expression, %s", arg1 );
continue;
}
ifile.close();
delete [] line;
Int_t nbad = nlines_read-nlines_ok;
if( nbad>0 ) Warning( here, "%d cut(s) could not be defined, check input "
"file %s", nbad, filename );
return nbad;
}
void THaCutList::MakePrintOption( THaPrintOption& opt, const TList* plist )
{
const int NF = 4;
if( opt.IsLine() && !strcmp(opt.GetOption(1),"") ) {
UInt_t width[NF] = { 0, 0, 0, 0 };
TIter next( plist );
while( THaCut* pcut = (THaCut*)next() ) {
width[0] = max( width[0], static_cast<UInt_t>
(strlen(pcut->GetName())) );
width[1] = max( width[1], static_cast<UInt_t>
(strlen(pcut->GetTitle())) );
width[2] = max( width[2], static_cast<UInt_t>
(strlen(pcut->GetBlockname())) );
width[3] = max( width[3], IntDigits( static_cast<Int_t>
(pcut->GetNPassed()) ));
}
TString newopt = opt.GetOption(0);
for( int i=0; i<NF; i++ ) {
newopt += ",";
newopt += width[i];
}
opt = newopt;
}
}
void THaCutList::Print( Option_t* option ) const
{
THaPrintOption opt(option);
if( !strcmp(opt.GetOption(0),"") ) opt = kPRINTLINE;
MakePrintOption( opt, fCuts );
PrintHeader( opt );
if( opt.IsLine() ) {
TIter next( fBlocks );
while( THaNamedList* plist = static_cast<THaNamedList*>( next() )) {
bool is_stats = !strcmp( opt.GetOption(0), kPRINTSTATS );
if( is_stats && strlen( plist->GetName() ) )
cout << "BLOCK: " << plist->GetName() << endl;
plist->PrintOpt( opt.Data() );
if ( is_stats ) cout << endl;
}
} else
fCuts->PrintOpt( opt.Data() );
}
void THaCutList::PrintBlock( const char* block, Option_t* option ) const
{
THaNamedList* plist = FindBlock( block );
if( !plist ) return;
THaPrintOption opt(option);
if( !strcmp(opt.GetOption(0),"") ) opt = kPRINTLINE;
MakePrintOption( opt, plist );
PrintHeader( opt );
plist->PrintOpt( opt.Data() );
}
void THaCutList::PrintCut( const char* cutname, Option_t* option ) const
{
THaCut* pcut = static_cast<THaCut*>( fCuts->FindObject( cutname ));
if( !pcut ) return;
pcut->Print( option );
}
void THaCutList::PrintHeader( const THaPrintOption& opt ) const
{
if( !opt.IsLine() ) return;
cout.flags( ios::left );
cout << setw( opt.GetValue(1) ) << "Name" << " "
<< setw( opt.GetValue(2) ) << "Def" << " ";
if( !strcmp( opt.GetOption(), kPRINTLINE )) {
cout << setw(1) << "T" << " "
<< setw( opt.GetValue(3) ) << "Block" << " ";
}
cout << setw(9) << "Called" << " "
<< "Passed" << endl;
int len = max( opt.GetValue(1) + opt.GetValue(2)
+ opt.GetValue(4) + 24, 30 );
if( !strcmp( opt.GetOption(), kPRINTLINE ))
len += max( opt.GetValue(3) + 5, 10 );
char* line = new char[ len+1 ];
for( int i=0; i<len; i++ ) line[i] = '-';
line[len] = '\0';
cout << line << endl;
delete [] line;
}
void THaCutList::Reset()
{
TIter next( fCuts );
while( THaCut* pcut = static_cast<THaCut*>( next() ))
pcut->Reset();
}
Int_t THaCutList::Result( const char* cutname, EWarnMode mode )
{
THaCut* pcut = static_cast<THaCut*>( fCuts->FindObject( cutname ));
if( !pcut ) {
if( mode == kWarn )
Warning("Result", "No such cut: %s", cutname );
return -1;
}
return static_cast<Int_t>( pcut->GetResult() );
}
Int_t THaCutList::Remove( const char* cutname )
{
THaCut* pcut = static_cast<THaCut*>( fCuts->FindObject( cutname ));
if ( !pcut ) return 0;
const char* block = pcut->GetBlockname();
THaNamedList* plist = static_cast<THaNamedList*>(fBlocks->FindObject( block ));
if ( plist ) plist->Remove( pcut );
fCuts->Remove( pcut );
delete pcut;
return 1;
}
Int_t THaCutList::RemoveBlock( const char* block )
{
THaNamedList* plist = FindBlock( block );
if( !plist ) return -1;
Int_t i = 0;
TObjLink* lnk = plist->FirstLink();
while( lnk ) {
THaCut* pcut = static_cast<THaCut*>( lnk->GetObject() );
if( pcut ) i++;
lnk = lnk->Next();
fCuts->Remove( pcut );
}
plist->Delete();
fBlocks->Remove( plist );
delete plist;
return i;
}
void THaCutList::SetList( THaVarList* lst )
{
fVarList = lst;
}
UInt_t IntDigits( Int_t n )
{
if( n == 0 ) return 1;
int j = 0;
if( n<0 ) {
j++;
n *= -1;
}
while( n>0 ) {
n /= 10;
j++;
}
return j;
}
ClassImp(THaCutList)
ClassImp(THaHashList)
Last change: Sat Nov 7 21:26:44 2009
Last generated: 2009-11-07 21:26
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.