// @(#)root/roostats:$Id: cranmer $
// Author: Kyle Cranmer, Akira Shibata
/*************************************************************************
* Copyright (C) 1995-2008, Rene Brun and Fons Rademakers. *
* All rights reserved. *
* *
* For the licensing terms see $ROOTSYS/LICENSE. *
* For the list of contributors see $ROOTSYS/README/CREDITS. *
*************************************************************************/
//_________________________________________________
/*
BEGIN_HTML
END_HTML
*/
//
#include "TDOMParser.h"
#include "RooStats/HistFactory/ConfigParser.h"
#include "RooStats/HistFactory/HistFactoryException.h"
#include "RooStats/HistFactory/Measurement.h"
#include "Helper.h"
using namespace RooStats;
using namespace HistFactory;
using namespace std;
std::vector< RooStats::HistFactory::Measurement > ConfigParser::GetMeasurementsFromXML( string input ) {
// Open an input "Driver" XML file (input),
// Parse that file and its channel files
// and return a vector filled with
// the listed measurements
// Create the list of measurements
// (This is what will be returned)
std::vector< HistFactory::Measurement > measurement_list;
try {
// Open the Driver XML File
TDOMParser xmlparser;
Int_t parseError = xmlparser.ParseFile( input.c_str() );
if( parseError ) {
std::cerr << "Loading of xml document \"" << input
<< "\" failed" << std::endl;
throw hf_exc();
}
// Read the Driver XML File
cout << "reading input : " << input << endl;
TXMLDocument* xmldoc = xmlparser.GetXMLDocument();
TXMLNode* rootNode = xmldoc->GetRootNode();
// Check that it is the proper DOCTYPE
if( rootNode->GetNodeName() != TString( "Combination" ) ){
std::cout << "Error: Driver DOCTYPE not equal to 'Combination'" << std::endl;
throw hf_exc();
}
// Loop over the Combination's attributes
std::string OutputFilePrefix;
TListIter attribIt = rootNode->GetAttributes();
TXMLAttr* curAttr = 0;
while( ( curAttr = dynamic_cast< TXMLAttr* >( attribIt() ) ) != 0 ) {
// Get the Name, Val of this node
TString attrName = curAttr->GetName();
std::string attrVal = curAttr->GetValue();
if( attrName == TString( "" ) ) {
std::cout << " Error: Attribute for 'Combination' with no name found" << std::endl;
throw hf_exc();
}
else if( attrName == TString( "OutputFilePrefix" ) ) {
OutputFilePrefix = string(curAttr->GetValue());
std::cout << "output file prefix is : " << OutputFilePrefix << endl;
}
/*
else if( attrName == TString( "InputFile" ) ) {
channel.InputFile = attrVal ;
}
*/
else {
std::cout << " Error: Unknown attribute for 'Combination' encountered: "
<< attrName << std::endl;
throw hf_exc();
}
// node = node->GetNextNode();
}
TXMLNode* node = NULL;
// Get the list of channel XML files to combine
// Do this first so we can quickly exit
// if no channels are found
std::vector< std::string > xml_channel_files;
node = rootNode->GetChildren();
while( node != 0 ) {
if( node->GetNodeName() == TString( "Input" ) ) {
if( node->GetText() == NULL ) {
std::cout << "Error: node: " << node->GetName()
<< " has no text." << std::endl;
throw hf_exc();
}
xml_channel_files.push_back(node->GetText());
}
node = node->GetNextNode();
}
// If no channel xml files are found, exit
if(xml_channel_files.empty()){
cerr << "no input channels found" << endl;
throw hf_exc();
//return measurement_list;
}
else {
std::cout << "Found Channels: ";
for( unsigned int i=0; i < xml_channel_files.size(); ++i ) std::cout << " " << xml_channel_files.at(i);
std::cout << std::endl;
}
// Get the list of functions
// These apply to all measurements, so we
// first create the list of preprocess functions
// (before we create the list of measurements)
// and then we add them to all measurements
// For now, we create this list twice
// simply for compatability
// std::vector< std::string > preprocessFunctions;
std::vector< RooStats::HistFactory::PreprocessFunction > functionObjects;
node = rootNode->GetChildren();
while( node != 0 ) {
if( node->GetNodeName() == TString( "Function" ) ) {
// For now, add both the objects itself and
// it's command string (for easy compatability)
RooStats::HistFactory::PreprocessFunction Func = ParseFunctionConfig( node );
// preprocessFunctions.push_back( Func.GetCommand() );
functionObjects.push_back( Func );
}
node = node->GetNextNode();
}
std::cout << std::endl;
// Fill the list of measurements
node = rootNode->GetChildren();
while( node != 0 ) {
if( node->GetNodeName() == TString( "" ) ) {
std::cout << "Error: Node found in Measurement Driver XML with no name" << std::endl;
throw hf_exc();
}
else if( node->GetNodeName() == TString( "Measurement" ) ) {
HistFactory::Measurement measurement = CreateMeasurementFromDriverNode( node );
// Set the prefix (obtained above)
measurement.SetOutputFilePrefix( OutputFilePrefix );
measurement_list.push_back( measurement );
}
else if( node->GetNodeName() == TString( "Function" ) ) {
// Already processed these (directly above)
;
}
else if( node->GetNodeName() == TString( "Input" ) ) {
// Already processed these (directly above)
;
}
else if( IsAcceptableNode( node ) ) { ; }
else {
std::cout << "Error: Unknown node found in Measurement Driver XML: "
<< node->GetNodeName() << std::endl;
throw hf_exc();
}
node = node->GetNextNode();
}
std::cout << "Done Processing Measurements" << std::endl;
if( measurement_list.size() == 0 ) {
std::cout << "Error: No Measurements found in XML Driver File" << std::endl;
throw hf_exc();
}
else {
std::cout << "Found Measurements: ";
for( unsigned int i=0; i < measurement_list.size(); ++i ) std::cout << " " << measurement_list.at(i).GetName();
std::cout << std::endl;
}
// Add the preprocessed functions to each measurement
// for( unsigned int i = 0; i < measurement_list.size(); ++i) {
// measurement_list.at(i).SetPreprocessFunctions( preprocessFunctions );
// }
// Add the preprocessed functions to each measurement
for( unsigned int i = 0; i < measurement_list.size(); ++i) {
measurement_list.at(i).SetFunctionObjects( functionObjects );
}
// Create an instance of the class
// that collects histograms
//HistCollector collector;
// Create the list of channels
// (Each of these will be added
// to every measurement)
std::vector< HistFactory::Channel > channel_list;
// Fill the list of channels
for( unsigned int i = 0; i < xml_channel_files.size(); ++i ) {
std::string channel_xml = xml_channel_files.at(i);
std::cout << "Parsing Channel: " << channel_xml << std::endl;
HistFactory::Channel channel = ParseChannelXMLFile( channel_xml );
// Get the histograms for the channel
//collector.CollectHistograms( channel );
//channel.CollectHistograms();
channel_list.push_back( channel );
}
// Finally, add the channels to the measurements:
for( unsigned int i = 0; i < measurement_list.size(); ++i) {
HistFactory::Measurement& measurement = measurement_list.at(i);
for( unsigned int j = 0; j < channel_list.size(); ++j ) {
measurement.GetChannels().push_back( channel_list.at(j) );
}
}
}
catch(std::exception& e)
{
std::cout << e.what() << std::endl;
throw hf_exc();
}
return measurement_list;
}
HistFactory::Measurement ConfigParser::CreateMeasurementFromDriverNode( TXMLNode* node ) {
HistFactory::Measurement measurement;
// Set the default values:
measurement.SetLumi( 1.0 );
measurement.SetLumiRelErr( .10 );
measurement.SetBinLow( 0 );
measurement.SetBinHigh( 1 );
measurement.SetExportOnly( false );
std::cout << "Creating new measurement: " << std::endl;
// First, get the attributes of the node
TListIter attribIt = node->GetAttributes();
TXMLAttr* curAttr = 0;
while( ( curAttr = dynamic_cast< TXMLAttr* >( attribIt() ) ) != 0 ) {
if( curAttr->GetName() == TString( "" ) ) {
std::cout << "Found XML attribute in Measurement with no name" << std::endl;
// ADD Output Here
throw hf_exc();
}
else if( curAttr->GetName() == TString( "Name" ) ) {
//rowTitle=curAttr->GetValue();
measurement.SetName( curAttr->GetValue() );
//measurement.OutputFileName = outputFileNamePrefix+"_"+rowTitle+".root";
}
else if( curAttr->GetName() == TString( "Lumi" ) ) {
measurement.SetLumi( atof(curAttr->GetValue()) );
}
else if( curAttr->GetName() == TString( "LumiRelErr" ) ) {
measurement.SetLumiRelErr( atof(curAttr->GetValue()) );
}
else if( curAttr->GetName() == TString( "BinLow" ) ) {
measurement.SetBinLow( atoi(curAttr->GetValue()) );
}
else if( curAttr->GetName() == TString( "BinHigh" ) ) {
measurement.SetBinHigh( atoi(curAttr->GetValue()) );
}
else if( curAttr->GetName() == TString( "Mode" ) ) {
cout <<"\n INFO: Mode attribute is deprecated, will ignore\n"<GetName() == TString( "ExportOnly" ) ) {
measurement.SetExportOnly( CheckTrueFalse(curAttr->GetValue(),"Measurement") );
}
else {
std::cout << "Found unknown XML attribute in Measurement: " << curAttr->GetName()
<< std::endl;
throw hf_exc();
}
} // End Loop over attributes
// Then, get the properties of the children nodes
TXMLNode* child = node->GetChildren();
while( child != 0 ) {
if( child->GetNodeName() == TString( "" ) ) {
std::cout << "Found XML child node of Measurement with no name" << std::endl;
throw hf_exc();
}
else if( child->GetNodeName() == TString( "POI" ) ) {
if( child->GetText() == NULL ) {
std::cout << "Error: node: " << child->GetName()
<< " has no text." << std::endl;
throw hf_exc();
}
//poi// measurement.SetPOI( child->GetText() );
AddSubStrings( measurement.GetPOIList(), child->GetText() );
}
else if( child->GetNodeName() == TString( "ParamSetting" ) ) {
TListIter paramIt = child->GetAttributes();
TXMLAttr* curParam = 0;
while( ( curParam = dynamic_cast< TXMLAttr* >( paramIt() ) ) != 0 ) {
if( curParam->GetName() == TString( "" ) ) {
std::cout << "Error: Found tag attribute with no name in ParamSetting" << std::endl;
throw hf_exc();
}
else if( curParam->GetName() == TString( "Const" ) ) {
if(curParam->GetValue()==TString("True")){
// Fix here...?
if( child->GetText() == NULL ) {
std::cout << "Error: node: " << child->GetName()
<< " has no text." << std::endl;
throw hf_exc();
}
AddSubStrings( measurement.GetConstantParams(), child->GetText() );
}
}
else if( curParam->GetName() == TString( "Val" ) ) {
double val = atof(curParam->GetValue());
if( child->GetText() == NULL ) {
std::cout << "Error: node: " << child->GetName()
<< " has no text." << std::endl;
throw hf_exc();
}
std::vector child_nodes = GetChildrenFromString(child->GetText());
for(unsigned int i = 0; i < child_nodes.size(); ++i) {
measurement.SetParamValue( child_nodes.at(i), val);
}
// AddStringValPairToMap( measurement.GetParamValues(), val, child->GetText() );
}
else {
std::cout << "Found tag attribute with unknown name in ParamSetting: "
<< curAttr->GetName() << std::endl;
throw hf_exc();
}
}
}
else if( child->GetNodeName() == TString( "Asimov" ) ) {
//std::string name;
//std::map fixedParams;
// Now, create and configure an asimov object
// and add it to the measurement
RooStats::HistFactory::Asimov asimov;
std::string ParamFixString;
// Loop over attributes
attribIt = child->GetAttributes();
curAttr = 0;
while( ( curAttr = dynamic_cast< TXMLAttr* >( attribIt() ) ) != 0 ) {
if( curAttr->GetName() == TString( "" ) ) {
std::cout << "Error: Found tag attribute with no name in ConstraintTerm" << std::endl;
throw hf_exc();
}
else if( curAttr->GetName() == TString( "Name" ) ) {
std::string name = curAttr->GetValue();
asimov.SetName( name );
}
else if( curAttr->GetName() == TString( "FixParams" ) ) {
ParamFixString = curAttr->GetValue();
//std::map fixedParams = ExtractParamMapFromString(FixParamList);
//asimov.GetFixedParams() = fixedParams;
}
else {
std::cout << "Found tag attribute with unknown name in ConstraintTerm: "
<< curAttr->GetName() << std::endl;
throw hf_exc();
}
}
// Add any parameters to the asimov dataset
// to be fixed during the fitting and dataset generation
if( ParamFixString=="" ) {
std::cout << "Warning: Asimov Dataset with name: " << asimov.GetName()
<< " added, but no parameters are set to be fixed" << std::endl;
}
else {
AddParamsToAsimov( asimov, ParamFixString );
}
measurement.AddAsimovDataset( asimov );
}
else if( child->GetNodeName() == TString( "ConstraintTerm" ) ) {
vector syst;
string type = "";
double rel = 0;
map gammaSyst;
map uniformSyst;
map logNormSyst;
// Get the list of parameters in this tag:
if( child->GetText() == NULL ) {
std::cout << "Error: node: " << child->GetName()
<< " has no text." << std::endl;
throw hf_exc();
}
AddSubStrings(syst, child->GetText());
// Now, loop over this tag's attributes
attribIt = child->GetAttributes();
curAttr = 0;
while( ( curAttr = dynamic_cast< TXMLAttr* >( attribIt() ) ) != 0 ) {
if( curAttr->GetName() == TString( "" ) ) {
std::cout << "Error: Found tag attribute with no name in ConstraintTerm" << std::endl;
throw hf_exc();
}
else if( curAttr->GetName() == TString( "Type" ) ) {
type = curAttr->GetValue();
}
else if( curAttr->GetName() == TString( "RelativeUncertainty" ) ) {
rel = atof(curAttr->GetValue());
}
else {
std::cout << "Found tag attribute with unknown name in ConstraintTerm: "
<< curAttr->GetName() << std::endl;
throw hf_exc();
}
} // End Loop over tag attributes
// Now, fill the maps, depending on the type:
// Check that the type is in the correct form:
if( ! (type=="Gamma" || type=="Uniform" ||
type=="LogNormal" || type=="NoConstraint") ) {
std::cout << "Error: Encountered unknown type for ConstraintTerm: " << type << std::endl;
throw hf_exc();
}
if (type=="Gamma" && rel!=0) {
for (vector::const_iterator it=syst.begin(); it!=syst.end(); it++) {
// Fix Here...?
measurement.GetGammaSyst()[(*it).c_str()] = rel;
}
}
if (type=="Uniform" && rel!=0) {
for (vector::const_iterator it=syst.begin(); it!=syst.end(); it++) {
// Fix Here...?
measurement.GetUniformSyst()[(*it).c_str()] = rel;
}
}
if (type=="LogNormal" && rel!=0) {
for (vector::const_iterator it=syst.begin(); it!=syst.end(); it++) {
// Fix Here...?
measurement.GetLogNormSyst()[(*it).c_str()] = rel;
}
}
if (type=="NoConstraint") {
for (vector::const_iterator it=syst.begin(); it!=syst.end(); it++) {
// Fix Here...?
measurement.GetNoSyst()[(*it).c_str()] = 1.0; // MB : dummy value
}
}
} // End adding of Constraint terms
else if( IsAcceptableNode( child ) ) { ; }
else {
std::cout << "Found XML child of Measurement with unknown name: " << child->GetNodeName()
<< std::endl;
throw hf_exc();
}
child = child->GetNextNode();
}
measurement.PrintTree();
std::cout << std::endl;
return measurement;
}
HistFactory::Channel ConfigParser::ParseChannelXMLFile( string filen ) {
/*
TString lumiStr;
lumiStr+=lumi;
lumiStr.ReplaceAll(' ', TString());
*/
std::cout << "Parsing file: " << filen ;
TDOMParser xmlparser;
// reading in the file and parse by DOM
Int_t parseError = xmlparser.ParseFile( filen.c_str() );
if( parseError ) {
std::cout << "Loading of xml document \"" << filen
<< "\" failed" << std::endl;
throw hf_exc();
}
TXMLDocument* xmldoc = xmlparser.GetXMLDocument();
TXMLNode* rootNode = xmldoc->GetRootNode();
// Check that is is a CHANNEL based on the DOCTYPE
if( rootNode->GetNodeName() != TString( "Channel" ) ){
std::cout << "Error: In parsing a Channel XML, "
<< "Encounterd XML with DOCTYPE: " << rootNode->GetNodeName()
<< std::endl;
std::cout << " DOCTYPE for channels must be 'Channel' "
<< " Check that your XML is properly written" << std::endl;
throw hf_exc();
}
// Now, create the channel,
// configure it based on the XML
// and return it
HistFactory::Channel channel;
// Set the default values:
channel.SetInputFile( "" );
channel.SetHistoPath( "" );
// Walk through the root node and
// get its attributes
TListIter attribIt = rootNode->GetAttributes();
TXMLAttr* curAttr = 0;
while( ( curAttr = dynamic_cast< TXMLAttr* >( attribIt() ) ) != 0 ) {
// Get the Name, Val of this node
TString attrName = curAttr->GetName();
std::string attrVal = curAttr->GetValue();
if( attrName == TString( "" ) ) {
std::cout << " Error: Attribute for 'Channel' with no name found" << std::endl;
throw hf_exc();
}
else if( attrName == TString( "Name" ) ) {
channel.SetName( attrVal );
std::cout << " : creating a channel named " << channel.GetName() << std::endl;
}
else if( attrName == TString( "InputFile" ) ) {
std::cout << "Setting InputFile for this channel: " << attrVal << std::endl;
channel.SetInputFile( attrVal );
// Set the current (cached) value
m_currentInputFile = attrVal;
}
else if( curAttr->GetName() == TString( "HistoPath" ) ) {
std::cout << "Setting HistoPath for this channel: " << attrVal << std::endl;
// Set the current (cached) value
channel.SetHistoPath( attrVal );
m_currentHistoPath = attrVal;
}
else if( curAttr->GetName() == TString( "HistoName" ) ) {
// Changed This:
std::cout << "Use of HistoName in Channel is deprecated" << std::endl;
std::cout << "This will be ignored" << std::endl;
}
else {
std::cout << " Error: Unknown attribute for 'Channel' encountered: "
<< attrName << std::endl;
throw hf_exc();
}
} // End loop over the channel tag's attributes
// Check that the channel was properly initiated:
if( channel.GetName() == "" ) {
std::cout << "Error: Channel created with no name" << std::endl;
throw hf_exc();
}
m_currentChannel = channel.GetName();
// Loop over the children nodes in the XML file
// and configure the channel based on them
TXMLNode* node = rootNode->GetChildren();
bool firstData=true;
while( node != 0 ) {
// Restore the Channel-Wide Defaults
m_currentInputFile = channel.GetInputFile();
m_currentHistoPath = channel.GetHistoPath();
if( node->GetNodeName() == TString( "" ) ) {
std::cout << "Error: Encountered node in Channel with no name" << std::endl;
throw hf_exc();
}
else if( node->GetNodeName() == TString( "Data" ) ) {
if( firstData ) {
RooStats::HistFactory::Data data = CreateDataElement(node);
if( data.GetName() != "" ) {
std::cout << "Error: You can only rename the datasets of additional data sets. "
<< " Remove the 'Name=" << data.GetName() << "' tag"
<< " from channel: " << channel.GetName() << std::endl;
throw hf_exc();
}
channel.SetData( data );
firstData=false;
}
else {
channel.AddAdditionalData( CreateDataElement(node) );
}
}
else if( node->GetNodeName() == TString( "StatErrorConfig" ) ) {
channel.SetStatErrorConfig( CreateStatErrorConfigElement(node) );
}
else if( node->GetNodeName() == TString( "Sample" ) ) {
channel.GetSamples().push_back( CreateSampleElement(node) );
}
else if( IsAcceptableNode( node ) ) { ; }
else {
std::cout << "Error: Encountered node in Channel with unknown name: " << node->GetNodeName() << std::endl;
throw hf_exc();
}
node = node->GetNextNode();
} // End loop over tags in this channel
std::cout << "Created Channel: " << std::endl;
channel.Print();
return channel;
}
HistFactory::Data ConfigParser::CreateDataElement( TXMLNode* node ) {
std::cout << "Creating Data Element" << std::endl;
HistFactory::Data data;
// Set the default values
data.SetInputFile( m_currentInputFile );
data.SetHistoPath( m_currentHistoPath );
//data.HistoName = m_currentHistoName;
// Now, set the attributes
TListIter attribIt = node->GetAttributes();
TXMLAttr* curAttr = 0;
while( ( curAttr = dynamic_cast< TXMLAttr* >( attribIt() ) ) != 0 ) {
// Get the Name, Val of this node
TString attrName = curAttr->GetName();
std::string attrVal = curAttr->GetValue();
if( attrName == TString( "" ) ) {
std::cout << " Error: Attribute for 'Data' with no name found" << std::endl;
throw hf_exc();
}
else if( attrName == TString( "Name" ) ) {
data.SetName( attrVal );
}
else if( attrName == TString( "InputFile" ) ) {
data.SetInputFile( attrVal );
}
else if( attrName == TString( "HistoName" ) ) {
data.SetHistoName( attrVal );
}
else if( attrName == TString( "HistoPath" ) ) {
data.SetHistoPath( attrVal );
}
else if( IsAcceptableNode( node ) ) { ; }
else {
std::cout << " Error: Unknown attribute for 'Data' encountered: " << attrName << std::endl;
throw hf_exc();
}
}
// Check the properties of the data node:
if( data.GetInputFile() == "" ) {
std::cout << "Error: Data Node has no InputFile" << std::endl;
throw hf_exc();
}
if( data.GetHistoName() == "" ) {
std::cout << "Error: Data Node has no HistoName" << std::endl;
throw hf_exc();
}
std::cout << "Created Data Node with"
<< " InputFile: " << data.GetInputFile()
<< " HistoName: " << data.GetHistoName()
<< " HistoPath: " << data.GetHistoPath();
if( data.GetName() != "") std::cout << " Name: " << data.GetName();
std::cout << std::endl;
// data.hist = GetHisto(data.FileName, data.HistoPath, data.HistoName);
return data;
}
HistFactory::StatErrorConfig ConfigParser::CreateStatErrorConfigElement( TXMLNode* node ) {
std::cout << "Creating StatErrorConfig Element" << std::endl;
HistFactory::StatErrorConfig config;
// Setup default values:
config.SetConstraintType( Constraint::Gaussian );
config.SetRelErrorThreshold( 0.05 ); // 5%
// Loop over the node's attributes
TListIter attribIt = node->GetAttributes();
TXMLAttr* curAttr = 0;
while( ( curAttr = dynamic_cast< TXMLAttr* >( attribIt() ) ) != 0 ) {
// Get the Name, Val of this node
TString attrName = curAttr->GetName();
std::string attrVal = curAttr->GetValue();
if( attrName == TString( "RelErrorThreshold" ) ) {
config.SetRelErrorThreshold( atof(attrVal.c_str()) );
}
if( attrName == TString( "ConstraintType" ) ) {
// Allowable Values: Gaussian
if( attrVal == "" ) {
std::cout << "Error: Bad Value for StatErrorConfig Constraint Type Found" << std::endl;
throw hf_exc();
}
else if( attrVal=="Gaussian" || attrVal=="Gauss" ) {
config.SetConstraintType( Constraint::Gaussian );
}
else if( attrVal=="Poisson" || attrVal=="Pois" ) {
config.SetConstraintType( Constraint::Poisson );
}
else if( IsAcceptableNode( node ) ) { ; }
else {
cout << "Invalid Stat Constraint Type: " << curAttr->GetValue() << endl;
throw hf_exc();
}
}
} // End: Loop Over Attributes
std::cout << "Created StatErrorConfig Element with"
<< " Constraint type: " << config.GetConstraintType()
<< " RelError Threshold: " << config.GetRelErrorThreshold()
<< std::endl;
return config;
}
HistFactory::Sample ConfigParser::CreateSampleElement( TXMLNode* node ) {
std::cout << "Creating Sample Element" << std::endl;
HistFactory::Sample sample;
// Set the default values
sample.SetInputFile( m_currentInputFile );
sample.SetHistoPath( m_currentHistoPath );
sample.SetChannelName( m_currentChannel );
sample.SetNormalizeByTheory( true );
//sample.HistoName = m_currentHistoName;
// Now, set the attributes
TListIter attribIt = node->GetAttributes();
TXMLAttr* curAttr = 0;
while( ( curAttr = dynamic_cast< TXMLAttr* >( attribIt() ) ) != 0 ) {
// Get the Name, Val of this node
TString attrName = curAttr->GetName();
std::string attrVal = curAttr->GetValue();
if( attrName == TString( "" ) ) {
std::cout << " Error: Attribute for 'Sample' with no name found" << std::endl;
throw hf_exc();
}
else if( attrName == TString( "Name" ) ) {
sample.SetName( attrVal );
}
else if( attrName == TString( "InputFile" ) ) {
sample.SetInputFile( attrVal );
m_currentInputFile = attrVal;
}
else if( attrName == TString( "HistoName" ) ) {
sample.SetHistoName( attrVal );
}
else if( attrName == TString( "HistoPath" ) ) {
sample.SetHistoPath( attrVal );
m_currentHistoPath = attrVal;
}
else if( attrName == TString( "NormalizeByTheory" ) ) {
sample.SetNormalizeByTheory( CheckTrueFalse(attrVal,"Sample") );
/*
if( attrVal == "" ) {
std::cout << "Error: Attribute 'NormalizeByTheory' in Sample has no value" << std::endl;
throw hf_exc();
}
else if ( attrVal == "True" || attrVal == "true" ) sample.NormalizeByTheory = true;
else if ( attrVal == "False" || attrVal == "false" ) sample.NormalizeByTheory = false;
else {
std::cout << "Error: Attribute 'NormalizeByTheory' in Sample has unknown value: " << attrVal << std::endl;
std::cout << "Value must be 'True' or 'False' " << std::endl;
throw hf_exc();
}
*/
}
else {
std::cout << " Error: Unknown attribute for 'Sample' encountered: " << attrName << std::endl;
throw hf_exc();
}
}
// Quickly check the properties of the Sample Node
if( sample.GetName() == "" ) {
std::cout << "Error: Sample Node has no Name" << std::endl;
throw hf_exc();
}
if( sample.GetInputFile() == "" ) {
std::cout << "Error: Sample Node has no InputFile" << std::endl;
throw hf_exc();
}
if( sample.GetHistoName() == "" ) {
std::cout << "Error: Sample Node has no HistoName" << std::endl;
throw hf_exc();
}
// Now, loop over the children and add the systematics
TXMLNode* child = node->GetChildren();
while( child != 0 ) {
if( child->GetNodeName() == TString( "" ) ) {
std::cout << "Error: Encountered node in Sample with no name" << std::endl;
throw hf_exc();
}
else if( child->GetNodeName() == TString( "NormFactor" ) ) {
sample.GetNormFactorList().push_back( MakeNormFactor( child ) );
}
else if( child->GetNodeName() == TString( "OverallSys" ) ) {
sample.GetOverallSysList().push_back( MakeOverallSys( child ) );
}
else if( child->GetNodeName() == TString( "HistoSys" ) ) {
sample.GetHistoSysList().push_back( MakeHistoSys( child ) );
}
else if( child->GetNodeName() == TString( "HistoFactor" ) ) {
std::cout << "WARNING: HistoFactor not yet supported" << std::endl;
//sample.GetHistoFactorList().push_back( MakeHistoFactor( child ) );
}
else if( child->GetNodeName() == TString( "ShapeSys" ) ) {
sample.GetShapeSysList().push_back( MakeShapeSys( child ) );
}
else if( child->GetNodeName() == TString( "ShapeFactor" ) ) {
sample.GetShapeFactorList().push_back( MakeShapeFactor( child ) );
}
else if( child->GetNodeName() == TString( "StatError" ) ) {
sample.SetStatError( ActivateStatError(child) );
}
else if( IsAcceptableNode( child ) ) { ; }
else {
std::cout << "Error: Encountered node in Sample with unknown name: " << child->GetNodeName() << std::endl;
throw hf_exc();
}
child=child->GetNextNode();
}
std::cout << "Created Sample Node with"
<< " Name: " << sample.GetName()
<< " InputFile: " << sample.GetInputFile()
<< " HistoName: " << sample.GetHistoName()
<< " HistoPath: " << sample.GetHistoPath()
<< std::endl;
// sample.hist = GetHisto(sample.FileName, sample.HistoPath, sample.HistoName);
return sample;
}
HistFactory::NormFactor ConfigParser::MakeNormFactor( TXMLNode* node ) {
std::cout << "Making NormFactor:" << std::endl;
HistFactory::NormFactor norm;
TListIter attribIt = node->GetAttributes();
TXMLAttr* curAttr = 0;
while( ( curAttr = dynamic_cast< TXMLAttr* >( attribIt() ) ) != 0 ) {
// Get the Name, Val of this node
TString attrName = curAttr->GetName();
std::string attrVal = curAttr->GetValue();
if( attrName == TString( "" ) ){
std::cout << "Error: Encountered Element in NormFactor with no name" << std::endl;
throw hf_exc();
}
else if( curAttr->GetName() == TString( "Name" ) ) {
norm.SetName( attrVal );
}
else if( curAttr->GetName() == TString( "Val" ) ) {
norm.SetVal( atof(attrVal.c_str()) );
}
else if( curAttr->GetName() == TString( "Low" ) ) {
norm.SetLow( atof(attrVal.c_str()) );
}
else if( curAttr->GetName() == TString( "High" ) ) {
norm.SetHigh( atof(attrVal.c_str()) );
}
else if( curAttr->GetName() == TString( "Const" ) ) {
norm.SetConst( CheckTrueFalse(attrVal,"NormFactor") );
}
else {
std::cout << "Error: Encountered Element in NormFactor with unknown name: "
<< attrName << std::endl;
throw hf_exc();
}
} // End loop over properties
if( norm.GetName() == "" ) {
std::cout << "Error: NormFactor Node has no Name" << std::endl;
throw hf_exc();
}
if( norm.GetLow() >= norm.GetHigh() ) {
std::cout << "Error: NormFactor: " << norm.GetName()
<< " has lower limit >= its upper limit: "
<< " Lower: " << norm.GetLow()
<< " Upper: " << norm.GetHigh()
<< ". Please Fix" << std::endl;
throw hf_exc();
}
if( norm.GetVal() > norm.GetHigh() || norm.GetVal() < norm.GetLow() ) {
std::cout << "Error: NormFactor: " << norm.GetName()
<< " has initial value not within its range: "
<< " Val: " << norm.GetVal()
<< " Lower: " << norm.GetLow()
<< " Upper: " << norm.GetHigh()
<< ". Please Fix" << std::endl;
throw hf_exc();
}
norm.Print();
return norm;
}
HistFactory::HistoFactor ConfigParser::MakeHistoFactor( TXMLNode* /*node*/ ) {
std::cout << "Making HistoFactor" << std::endl;
HistFactory::HistoFactor dummy;
dummy.SetInputFileLow( m_currentInputFile );
dummy.SetHistoPathLow( m_currentHistoPath );
dummy.SetInputFileHigh( m_currentInputFile );
dummy.SetHistoPathHigh( m_currentHistoPath );
std::cout << "Made HistoFactor" << std::endl;
return dummy;
}
HistFactory::HistoSys ConfigParser::MakeHistoSys( TXMLNode* node ) {
std::cout << "Making HistoSys:" << std::endl;
HistFactory::HistoSys histoSys;
// Set Default values
histoSys.SetInputFileLow( m_currentInputFile );
histoSys.SetHistoPathLow( m_currentHistoPath );
histoSys.SetInputFileHigh( m_currentInputFile );
histoSys.SetHistoPathHigh( m_currentHistoPath );
TListIter attribIt = node->GetAttributes();
TXMLAttr* curAttr = 0;
/*
string Name, histoPathHigh, histoPathLow,
histoNameLow, histoNameHigh, inputFileHigh, inputFileLow;
inputFileLow=inputFileName; inputFileHigh=inputFileName;
histoPathLow=histoPathName; histoPathHigh=histoPathName;
histoNameLow=histoName; histoNameHigh=histoName;
*/
while( ( curAttr = dynamic_cast< TXMLAttr* >( attribIt() ) ) != 0 ) {
// Get the Name, Val of this node
TString attrName = curAttr->GetName();
std::string attrVal = curAttr->GetValue();
if( attrName == TString( "" ) ){
std::cout << "Error: Encountered Element in HistoSys with no name" << std::endl;
throw hf_exc();
}
else if( curAttr->GetName() == TString( "Name" ) ) {
histoSys.SetName( attrVal );
}
else if( curAttr->GetName() == TString( "HistoFileHigh" ) ) {
histoSys.SetInputFileHigh( attrVal );
}
else if( curAttr->GetName() == TString( "HistoPathHigh" ) ) {
histoSys.SetHistoPathHigh( attrVal );
}
else if( curAttr->GetName() == TString( "HistoNameHigh" ) ) {
histoSys.SetHistoNameHigh( attrVal );
}
else if( curAttr->GetName() == TString( "HistoFileLow" ) ) {
histoSys.SetInputFileLow( attrVal );
}
else if( curAttr->GetName() == TString( "HistoPathLow" ) ) {
histoSys.SetHistoPathLow( attrVal );
}
else if( curAttr->GetName() == TString( "HistoNameLow" ) ) {
histoSys.SetHistoNameLow( attrVal );
}
else {
std::cout << "Error: Encountered Element in HistoSys with unknown name: "
<< attrName << std::endl;
throw hf_exc();
}
} // End loop over properties
if( histoSys.GetName() == "" ) {
std::cout << "Error: HistoSys Node has no Name" << std::endl;
throw hf_exc();
}
if( histoSys.GetInputFileHigh() == "" ) {
std::cout << "Error: HistoSysSample Node has no InputFileHigh" << std::endl;
throw hf_exc();
}
if( histoSys.GetInputFileLow() == "" ) {
std::cout << "Error: HistoSysSample Node has no InputFileLow" << std::endl;
throw hf_exc();
}
if( histoSys.GetHistoNameHigh() == "" ) {
std::cout << "Error: HistoSysSample Node has no HistoNameHigh" << std::endl;
throw hf_exc();
}
if( histoSys.GetHistoNameLow() == "" ) {
std::cout << "Error: HistoSysSample Node has no HistoNameLow" << std::endl;
throw hf_exc();
}
histoSys.Print();
return histoSys;
}
HistFactory::OverallSys ConfigParser::MakeOverallSys( TXMLNode* node ) {
std::cout << "Making OverallSys:" << std::endl;
HistFactory::OverallSys overallSys;
TListIter attribIt = node->GetAttributes();
TXMLAttr* curAttr = 0;
while( ( curAttr = dynamic_cast< TXMLAttr* >( attribIt() ) ) != 0 ) {
// Get the Name, Val of this node
TString attrName = curAttr->GetName();
std::string attrVal = curAttr->GetValue();
if( attrName == TString( "" ) ){
std::cout << "Error: Encountered Element in OverallSys with no name" << std::endl;
throw hf_exc();
}
else if( attrName == TString( "Name" ) ) {
overallSys.SetName( attrVal );
}
else if( attrName == TString( "High" ) ) {
overallSys.SetHigh( atof(attrVal.c_str()) );
}
else if( attrName == TString( "Low" ) ) {
overallSys.SetLow( atof(attrVal.c_str()) );
}
else {
std::cout << "Error: Encountered Element in OverallSys with unknown name: "
<< attrName << std::endl;
throw hf_exc();
}
}
if( overallSys.GetName() == "" ) {
std::cout << "Error: Encountered OverallSys with no name" << std::endl;
throw hf_exc();
}
overallSys.Print();
return overallSys;
}
HistFactory::ShapeFactor ConfigParser::MakeShapeFactor( TXMLNode* node ) {
std::cout << "Making ShapeFactor" << std::endl;
HistFactory::ShapeFactor shapeFactor;
TListIter attribIt = node->GetAttributes();
TXMLAttr* curAttr = 0;
// A Shape Factor may or may not include an initial shape
// This will be set by strings pointing to a histogram
// If we don't see a 'HistoName' attribute, we assume
// that an initial shape is not being set
std::string ShapeInputFile = m_currentInputFile;
std::string ShapeInputPath = m_currentHistoPath;
while( ( curAttr = dynamic_cast< TXMLAttr* >( attribIt() ) ) != 0 ) {
// Get the Name, Val of this node
TString attrName = curAttr->GetName();
std::string attrVal = curAttr->GetValue();
if( attrName == TString( "" ) ){
std::cout << "Error: Encountered Element in ShapeFactor with no name" << std::endl;
throw hf_exc();
}
else if( attrName == TString( "Name" ) ) {
shapeFactor.SetName( attrVal );
}
else if( attrName == TString( "Const" ) ) {
shapeFactor.SetConstant( CheckTrueFalse(attrVal, "ShapeFactor" ) );
}
else if( attrName == TString( "HistoName" ) ) {
shapeFactor.SetHistoName( attrVal );
}
else if( attrName == TString( "InputFile" ) ) {
ShapeInputFile = attrVal;
}
else if( attrName == TString( "HistoPath" ) ) {
ShapeInputPath = attrVal;
}
else {
std::cout << "Error: Encountered Element in ShapeFactor with unknown name: "
<< attrName << std::endl;
throw hf_exc();
}
}
if( shapeFactor.GetName() == "" ) {
std::cout << "Error: Encountered ShapeFactor with no name" << std::endl;
throw hf_exc();
}
// Set the Histogram name, path, and file
// if an InitialHist is set
if( shapeFactor.HasInitialShape() ) {
if( shapeFactor.GetHistoName() == "" ) {
std::cout << "Error: ShapeFactor: " << shapeFactor.GetName()
<< " is configured to have an initial shape, but "
<< "its histogram doesn't have a name"
<< std::endl;
throw hf_exc();
}
shapeFactor.SetHistoPath( ShapeInputPath );
shapeFactor.SetInputFile( ShapeInputFile );
}
shapeFactor.Print();
return shapeFactor;
}
HistFactory::ShapeSys ConfigParser::MakeShapeSys( TXMLNode* node ) {
std::cout << "Making ShapeSys" << std::endl;
HistFactory::ShapeSys shapeSys;
// Set the default values
shapeSys.SetConstraintType( Constraint::Gaussian );
shapeSys.SetInputFile( m_currentInputFile );
shapeSys.SetHistoPath( m_currentHistoPath );
TListIter attribIt = node->GetAttributes();
TXMLAttr* curAttr = 0;
//EstimateSummary::ConstraintType ConstraintType = EstimateSummary::Gaussian; //"Gaussian";
while( ( curAttr = dynamic_cast< TXMLAttr* >( attribIt() ) ) != 0 ) {
// Get the Name, Val of this node
TString attrName = curAttr->GetName();
std::string attrVal = curAttr->GetValue();
if( attrName == TString( "" ) ){
std::cout << "Error: Encountered Element in ShapeSys with no name" << std::endl;
throw hf_exc();
}
else if( attrName == TString( "Name" ) ) {
shapeSys.SetName( attrVal );
}
else if( attrName == TString( "HistoName" ) ) {
shapeSys.SetHistoName( attrVal );
}
else if( attrName == TString( "HistoPath" ) ) {
shapeSys.SetHistoPath( attrVal );
}
else if( attrName == TString( "InputFile" ) ) {
shapeSys.SetInputFile( attrVal );
}
else if( attrName == TString( "ConstraintType" ) ) {
if( attrVal=="" ) {
std::cout << "Error: ShapeSys Constraint type is empty" << std::endl;
throw hf_exc();
}
else if( attrVal=="Gaussian" || attrVal=="Gauss" ) {
shapeSys.SetConstraintType( Constraint::Gaussian );
}
else if( attrVal=="Poisson" || attrVal=="Pois" ) {
shapeSys.SetConstraintType( Constraint::Poisson );
}
else {
cout << "Error: Encountered unknown ShapeSys Constraint type: " << attrVal << endl;
throw hf_exc();
}
}
else {
std::cout << "Error: Encountered Element in ShapeSys with unknown name: "
<< attrName << std::endl;
throw hf_exc();
}
} // End loop over attributes
if( shapeSys.GetName() == "" ) {
std::cout << "Error: Encountered ShapeSys with no Name" << std::endl;
throw hf_exc();
}
if( shapeSys.GetInputFile() == "" ) {
std::cout << "Error: Encountered ShapeSys with no InputFile" << std::endl;
throw hf_exc();
}
if( shapeSys.GetHistoName() == "" ) {
std::cout << "Error: Encountered ShapeSys with no HistoName" << std::endl;
throw hf_exc();
}
shapeSys.Print();
return shapeSys;
}
HistFactory::StatError ConfigParser::ActivateStatError( TXMLNode* node ) {
std::cout << "Activating StatError" << std::endl;
// Set default values
HistFactory::StatError statError;
statError.Activate( false );
statError.SetUseHisto( false );
statError.SetHistoName( "" );
// Loop over the node's attributes
TListIter attribIt = node->GetAttributes();
TXMLAttr* curAttr = 0;
while( ( curAttr = dynamic_cast< TXMLAttr* >( attribIt() ) ) != 0 ) {
// Get the Name, Val of this node
TString attrName = curAttr->GetName();
std::string attrVal = curAttr->GetValue();
if( attrName == TString( "" ) ){
std::cout << "Error: Encountered Element in ActivateStatError with no name" << std::endl;
throw hf_exc();
}
else if( attrName == TString( "Activate" ) ) {
statError.Activate( CheckTrueFalse(attrVal,"ActivateStatError") );
}
else if( attrName == TString( "HistoName" ) ) {
statError.SetHistoName( attrVal );
}
else if( attrName == TString( "HistoPath" ) ) {
statError.SetHistoPath( attrVal );
}
else if( attrName == TString( "InputFile" ) ) {
statError.SetInputFile( attrVal );
}
else {
std::cout << "Error: Encountered Element in ActivateStatError with unknown name: "
<< attrName << std::endl;
throw hf_exc();
}
} // End: Loop Over Attributes
// Based on the input, determine
// if we should use a histogram or not:
// Logic: One turns on using a histogram
// by setting the attribute "HistoName"
// If this is set AND the InputFile or
// HistoPath aren't set, we set those
// to the current default values
if( statError.GetHistoName() != "" ) {
statError.SetUseHisto( true );
// Check that a file has been set
// (Possibly using the default)
if( statError.GetInputFile() == "" ) {
statError.SetInputFile( m_currentInputFile );
}
if( statError.GetHistoPath() == "" ) {
statError.SetHistoPath( m_currentHistoPath );
}
}
/*
if( statError.Activate ) {
if( statError.UseHisto ) {
}
else {
statError.InputFile = "";
statError.HistoName = "";
statError.HistoPath = "";
}
}
*/
statError.Print();
return statError;
}
RooStats::HistFactory::PreprocessFunction ConfigParser::ParseFunctionConfig( TXMLNode* functionNode ){
std::cout << "Parsing FunctionConfig" << std::endl;
//std::string name, expression, dependents;
TListIter attribIt = functionNode->GetAttributes();
TXMLAttr* curAttr = 0;
std::string Name = "";
std::string Expression = "";
std::string Dependents = "";
// Add protection to ensure that all parts are there
while( ( curAttr = dynamic_cast< TXMLAttr* >( attribIt() ) ) != 0 ) {
if( curAttr->GetName() == TString( "Name" ) ) {
Name = curAttr->GetValue();
//func.SetName( curAttr->GetValue() );
//name = curAttr->GetValue() ;
}
if( curAttr->GetName() == TString( "Expression" ) ) {
Expression = curAttr->GetValue();
//func.SetExpression( curAttr->GetValue() );
}
if( curAttr->GetName() == TString( "Dependents" ) ) {
Dependents = curAttr->GetValue();
//func.SetDependents( curAttr->GetValue() );
}
}
if( Name=="" ){
std::cout << "Error processing PreprocessFunction: Name attribute is empty" << std::endl;
throw hf_exc();
}
if( Expression=="" ){
std::cout << "Error processing PreprocessFunction: Expression attribute is empty" << std::endl;
throw hf_exc();
}
if( Dependents=="" ){
std::cout << "Error processing PreprocessFunction: Dependents attribute is empty" << std::endl;
throw hf_exc();
}
RooStats::HistFactory::PreprocessFunction func(Name, Expression, Dependents);
std::cout << "Created Preprocess Function: " << func.GetCommand() << std::endl;
//std::string command = "expr::"+func.GetName()+"('"+func.GetExpression()+"',{"+func.GetDependents()+"})";
//func.SetCommand( command );
// // cout << "will pre-process this line " << ret <GetNodeName() == TString( "text" ) ) {
return true;
}
if( node->GetNodeName() == TString( "comment" ) ) {
return true;
}
return false;
}
bool ConfigParser::CheckTrueFalse( std::string attrVal, std::string NodeTitle ) {
if( attrVal == "" ) {
std::cout << "Error: In " << NodeTitle
<< " Expected either 'True' or 'False' but found empty" << std::endl;
throw hf_exc();
}
else if ( attrVal == "True" || attrVal == "true" ) return true;
else if ( attrVal == "False" || attrVal == "false" ) return false;
else {
std::cout << "Error: In " << NodeTitle
<< " Expected either 'True' or 'False' but found: " << attrVal << std::endl;
throw hf_exc();
}
return false;
}
//ConfigParser