1 #include "AnalysisSettings.h" 3 #include "TObjString.h" 8 #include "TDataMember.h" 9 #include "TMethodCall.h" 14 const char* default_filename =
"AcclaimSettings.conf";
16 Acclaim::AnalysisSettings::AnalysisSettings(
const char* fName) : fileName(fName) {
22 void Acclaim::AnalysisSettings::write(TFile* f)
const{
25 std::cerr <<
"Error in " << __PRETTY_FUNCTION__
26 <<
", got NULL pointer to TFile. Cannot save AnalysisSettings." << std::endl;
31 std::cerr <<
"Error in " << __PRETTY_FUNCTION__ <<
", TFile " << f->GetName()
32 <<
" is not writable. Cannot save AnalysisSettings." << std::endl;
37 std::cerr <<
"Error in " << __PRETTY_FUNCTION__ <<
", TFile " << f->GetName()
38 <<
" is not open. Cannot save AnalysisSettings." << std::endl;
44 TObjArray* tokens = fileName.Tokenize(
"/");
45 TString shortFileName = ((TObjString*) tokens->Last())->GetString();
47 TNamed* tn =
new TNamed(shortFileName, parsedFileCopy);
54 void Acclaim::AnalysisSettings::print()
const{
56 std::cout << __PRETTY_FUNCTION__ << std::endl;
58 SectionMap_t::const_iterator sit = sectionMap.begin();
59 for(; sit!= sectionMap.end(); ++sit){
60 VariableMap_t* vm = sit->second;
61 std::cout <<
"[" << sit->first <<
"]" << std::endl;
63 VariableMap_t::iterator vit = vm->begin();
64 for(; vit!=vm->end(); ++vit){
65 std::cout << vit->first <<
"=" << vit->second << std::endl;
68 std::cout << std::endl;
75 void Acclaim::AnalysisSettings::apply(TObject* obj)
const {
78 std::cerr <<
"Warning in " << __PRETTY_FUNCTION__ <<
", got NULL TObject pointer. Doing nothing." << std::endl;
82 TString className = obj->ClassName();
84 SectionMap_t::const_iterator sit = sectionMap.find(className);
85 if(sit==sectionMap.end()){
86 std::cerr <<
"Fatal error in " << __PRETTY_FUNCTION__ <<
", found no settings for " << className
88 throw std::runtime_error(
"Missing settings");
91 VariableMap_t* varMap = sit->second;
92 TClass* cl = obj->IsA();
94 VariableMap_t::iterator vit = varMap->begin();
95 for(; vit!= varMap->end(); ++vit){
96 TDataMember *dm = cl->GetDataMember(vit->first);
99 std::cerr <<
"Error in " << __PRETTY_FUNCTION__ <<
", unable to find data member for " 100 << className <<
"." << vit->first <<
"." << std::endl;
101 throw std::runtime_error(
"Missing data member");
104 TMethodCall *sm = dm->SetterMethod(cl);
106 std::cerr <<
"Error in " << __PRETTY_FUNCTION__ <<
", unable to find setter method for " 107 << className <<
"." << vit->first <<
". Skipping this setting." << std::endl;
108 throw std::runtime_error(
"Missing Setter function");
111 sm->Execute(obj, vit->second);
119 Bool_t Acclaim::AnalysisSettings::stringIsKeyValuePair(
const TString& commentStrippedLine, TString& key, TString& value)
const{
123 Bool_t isKeyValuePair =
false;
125 TObjArray* tokens = commentStrippedLine.Tokenize(
"=");
126 int nTokens = tokens->GetEntries();
130 key = ((TObjString*) tokens->At(0))->GetString();
131 key.Strip().String();
132 value = ((TObjString*) tokens->At(1))->GetString();
133 value.Strip().String();
134 isKeyValuePair =
true;
137 return isKeyValuePair;
141 Bool_t Acclaim::AnalysisSettings::stringIsAlphaNumeric(
const TString& str)
const{
143 TRegexp reggie(
"[a-zA-Z0-9]");
144 Ssiz_t len = str.Length();
146 Bool_t isAlphaNumeric = reggie.Index(str, &len) != -1;
147 return isAlphaNumeric;
152 Bool_t Acclaim::AnalysisSettings::stringIsSection(
const TString& commentStrippedLine, TString& secName)
const{
155 Bool_t isSection =
false;
156 Ssiz_t len = commentStrippedLine.Length();
159 TString firstChar = TString(commentStrippedLine(0,1));
160 if(firstChar.Contains(
"[") && commentStrippedLine.Contains(
"]")){
162 TObjArray* tokens = TString(commentStrippedLine(1, len)).Tokenize(
"]");
163 int nTokens = tokens->GetEntries();
164 TString secNameMaybe = ((TObjString*) tokens->At(0))->GetString();
167 Bool_t trailingGood =
true;
169 TString trailing = ((TObjString*) tokens->At(1))->GetString();
170 if(stringIsAlphaNumeric(trailing)){
171 trailingGood =
false;
175 secName = secNameMaybe;
186 Acclaim::AnalysisSettings::VariableMap_t* Acclaim::AnalysisSettings::handleSection(
const TString& section){
190 SectionMap_t::iterator it = sectionMap.find(section);
191 VariableMap_t* variableMap = NULL;
192 if(it!=sectionMap.end()){
193 variableMap = it->second;
196 variableMap =
new VariableMap_t();
197 sectionMap[section] = variableMap;
203 void Acclaim::AnalysisSettings::handleKeyValue(VariableMap_t* variableMap,
const TString& key,
const TString& value){
205 if(variableMap==NULL){
206 std::cerr <<
"Error in " << __PRETTY_FUNCTION__ <<
" found variable " << key <<
" with value " << value <<
" but has no section! Variables must have a section. Skipping this entry." << std::endl;
210 VariableMap_t::iterator it = variableMap->find(key);
211 if(it!=variableMap->end()){
214 SectionMap_t::iterator it2 = sectionMap.begin();
215 for(; it2 != sectionMap.end(); ++it2){
216 if(variableMap==it2->second){
217 sectionName = it2->first;
221 std::cerr <<
"Warning in " << __PRETTY_FUNCTION__ <<
", while parsing section " << sectionName \
222 <<
"I found a duplicate entry for " << key << std::endl;
223 std::cerr <<
"The original value is " << it->second <<
", the duplicated value is " << value << std::endl;
224 std::cerr <<
"Ignoring the second value." << std::endl;
227 (*variableMap)[key] = value;
232 Bool_t Acclaim::AnalysisSettings::tryFile(
const char* fName){
233 Bool_t openedFile =
false;
236 if(n.Length() > 0 && n[n.Length()-1] ==
'/'){
237 std::cerr <<
"Info in " << __PRETTY_FUNCTION__ <<
", interpreting forward slash terminated input as directory, appending " << default_filename << std::endl;
238 n += TString::Format(
"%s", default_filename);
241 std::cout <<
"Info in " << __PRETTY_FUNCTION__ <<
", trying "<< n.Data() << std::endl;
243 std::ifstream a(n.Data());
251 void Acclaim::AnalysisSettings::findFile(){
253 if(fileName.Length()!=0){
255 if(tryFile(fileName)){
263 const char* fName = default_filename;
265 fileName = TString(fName);
269 const char* anitaUtilInstallDir = getenv(
"ANITA_UTIL_INSTALL_DIR");
270 if(!anitaUtilInstallDir){
272 std::cerr <<
"Error in " << __PRETTY_FUNCTION__ <<
", ANITA_UTIL_INSTALL_DIR not set." << std::endl;
275 TString fName2 = TString::Format(
"%s/share/Acclaim/%s", anitaUtilInstallDir, default_filename);
276 if(tryFile(fName2.Data())){
277 fileName = TString(fName2);
282 std::cerr <<
"Error in " << __PRETTY_FUNCTION__ <<
", couldn't find any settings files! Giving up." << std::endl;
288 void Acclaim::AnalysisSettings::parseSettingsFile(){
291 std::cout <<
"After Acclaim::AnalysisSettings::findFile(), fileName = " << fileName << std::endl;
293 std::ifstream settingsFile(fileName);
295 if(!settingsFile.is_open()){
297 std::cerr <<
"Error in " << __PRETTY_FUNCTION__ <<
", couldn't find settings file " << fileName
298 <<
". Giving up." << std::endl;
299 throw "Acclaim::AnalysisSettings Error";
304 VariableMap_t* varMap = NULL;
306 while(!settingsFile.eof()){
308 std::string thisLine;
309 std::getline(settingsFile, thisLine);
311 parsedFileCopy.Append(thisLine);
312 parsedFileCopy.Append(
"\n");
315 std::size_t found = thisLine.find(
"#");
318 TString thisLineCommentsRemoved(thisLine.substr(0, found));
321 Bool_t isSection = stringIsSection(thisLineCommentsRemoved, section);
324 varMap = handleSection(section);
328 Bool_t isKeyValuePair = stringIsKeyValuePair(thisLineCommentsRemoved, key, value);
330 handleKeyValue(varMap, key, value);
333 Bool_t isAlphaNumeric = stringIsAlphaNumeric(thisLineCommentsRemoved);
335 std::cerr <<
"Warning in " << __PRETTY_FUNCTION__
336 <<
". I couldn't parse line " << lineNum
337 <<
" in " << fileName <<
". It said: " << std::endl;
338 std::cerr << thisLine << std::endl;
374 TString setting = settingName;
376 for(SectionMap_t::const_iterator it=sectionMap.begin(); it!= sectionMap.end(); ++it){
378 int secLen = it->first.Length();
379 if(secLen <= setting.Length() && setting(0, secLen)==it->first){
381 std::cout <<
"Setting " << setting <<
", found a match with section " << it->first << std::endl;
384 setting.Replace(0, secLen,
"");
387 Bool_t goodMemberIdentifier =
false;
389 if(setting(0, 2)==
"::" || setting(0, 2) ==
"->"){
390 setting.Replace(0, 2,
"");
391 goodMemberIdentifier =
true;
393 else if(setting(0, 1)==
"."){
394 setting.Replace(0, 1,
"");
395 goodMemberIdentifier =
true;
397 std::cout <<
"Now reduced to " << setting << std::endl;
399 if(goodMemberIdentifier){
401 const VariableMap_t* vars = it->second;
403 VariableMap_t::const_iterator it2 = vars->find(setting);
404 if(it2 != vars->end()){
405 settingVal = it2->second;
409 std::cerr <<
"Error in " << __PRETTY_FUNCTION__ <<
", couldn't find variable " 410 << setting <<
" in config file section " << it->first << std::endl;
415 std::cerr <<
"Error in " << __PRETTY_FUNCTION__ <<
", malformed member identifer! Acceptable formats are:" << std::endl;
416 std::cerr <<
" Acclaim::Class::member" << std::endl;
417 std::cerr <<
" Acclaim::Class->member" << std::endl;
418 std::cerr <<
" Acclaim::Class.member" << std::endl;
424 std::cerr <<
"Error in " << __PRETTY_FUNCTION__ <<
", unable to find a class to match input " << setting << std::endl;
443 Bool_t foundSetting = getSetting(settingName, boolAsInt);
445 settingVal = settingVal = boolAsInt;
462 Bool_t foundSetting = getSetting(settingName, valAsString);
464 settingVal = atoi(valAsString.Data());
480 Bool_t foundSetting = getSetting(settingName, valAsString);
482 settingVal = atof(valAsString.Data());
Bool_t getSetting(const char *settingName, Bool_t &settingVal) const