00001 #include <string>
00002 #include <vector>
00003 #include <cassert>
00004 #include <iomanip>
00005 #include <iostream>
00006 #include <sstream>
00007 #include <fstream>
00008 #include <map>
00009 #include <cmath>
00010 #include <TFile.h>
00011 #include <TH1F.h>
00012 #include <TF1.h>
00013 #include <TStyle.h>
00014 #include <TMath.h>
00015
00016 void GetMPV(char name[100],TH1F* histo, TDirectory* Dir, double& peak, double& error, double& sigma, double& err_sigma);
00017 void GetMEAN(TH1F* histo, double& peak, double& error, double& sigma);
00018 void CalculateResponse(bool UseRatioForResponse, double x, double ex, double y, double ey, double& r, double& e);
00019 void CalculateCorrection(bool UseRatioForResponse, double x, double ex, double y, double ey, double& c, double& e);
00020 void Invert(TF1* f, double Min, double Max, double y, double& x);
00021 bool HistoExists(std::vector<std::string> LIST, std::string hname);
00022 int getBin(double x, std::vector<double> boundaries);
00023
00024 class CommandLine
00025 {
00026 public:
00027
00028
00029
00030 CommandLine();
00031 ~CommandLine();
00032
00033
00034
00035
00036 bool parse(int argc,char**argv);
00037 bool check();
00038 void print();
00039
00040 template <class T> T getValue(const std::string& name);
00041 template <class T> T getValue(const std::string& name, T default_value);
00042
00043 template <class T> std::vector<T> getVector(const std::string& name);
00044 template <class T> std::vector<T> getVector(const std::string& name,
00045 const std::string& default_as_string);
00046
00047 private:
00048 bool parse_file(const std::string& file_name);
00049
00050 private:
00051
00052
00053
00054 typedef std::map<std::string,std::pair<std::string,bool> > OptionMap_t;
00055 typedef std::vector<std::string> StrVec_t;
00056
00057
00058
00059
00060
00061 std::string _exe;
00062 OptionMap_t _options;
00063 StrVec_t _ordered_options;
00064 StrVec_t _unknowns;
00065
00066 };
00067
00068
00069
00070
00071
00072
00073 template <class T>
00074 T CommandLine::getValue(const std::string& name)
00075 {
00076 T result;
00077 OptionMap_t::iterator it=_options.find(name);
00078 if (it!=_options.end()) {
00079 it->second.second = true;
00080 _ordered_options.push_back(name);
00081 std::stringstream ss;
00082 ss<<it->second.first;
00083 ss>>result;
00084 return result;
00085 }
00086 _unknowns.push_back(name);
00087 return result;
00088 }
00089
00090
00091
00092 template <class T>
00093 T CommandLine::getValue(const std::string& name,T default_value)
00094 {
00095 OptionMap_t::const_iterator it=_options.find(name);
00096 if (it!=_options.end()) return getValue<T>(name);
00097 std::string default_as_string;
00098 std::stringstream ss;
00099 ss<<default_value;
00100 ss>>default_as_string;
00101 _options[name] = std::make_pair(default_as_string,true);
00102 _ordered_options.push_back(name);
00103 return default_value;
00104 }
00105
00106
00107
00108 template <>
00109 bool CommandLine::getValue<bool>(const std::string& name)
00110 {
00111 OptionMap_t::iterator it=_options.find(name);
00112 if (it!=_options.end()) {
00113 it->second.second = true;
00114 _ordered_options.push_back(name);
00115 std::string val_as_string = it->second.first;
00116 if (val_as_string=="true") return true;
00117 if (val_as_string=="false") return false;
00118 int val_as_int;
00119 std::stringstream ss;
00120 ss<<val_as_string;
00121 ss>>val_as_int;
00122 return val_as_int;
00123 }
00124 _unknowns.push_back(name);
00125 return false;
00126 }
00127
00128
00129
00130 template <>
00131 bool CommandLine::getValue(const std::string& name,bool default_value)
00132 {
00133 OptionMap_t::const_iterator it=_options.find(name);
00134 if (it!=_options.end()) return getValue<bool>(name);
00135 _options[name] = (default_value) ?
00136 std::make_pair("true",true) : std::make_pair("false",true);
00137 _ordered_options.push_back(name);
00138 return default_value;
00139 }
00140
00141
00142
00143 template <class T>
00144 std::vector<T> CommandLine::getVector(const std::string& name)
00145 {
00146 std::vector<T> result;
00147 OptionMap_t::iterator it=_options.find(name);
00148 if (it!=_options.end()) {
00149 it->second.second = true;
00150 _ordered_options.push_back(name);
00151 std::string tmp=it->second.first;
00152 std::string::size_type pos;
00153 if (!tmp.empty()) {
00154 do {
00155 pos = tmp.find(",");
00156 std::stringstream ss;
00157 ss<<tmp.substr(0,pos);
00158 tmp.erase(0,pos+1);
00159 T element;
00160 ss>>element;
00161 result.push_back(element);
00162 }
00163 while (pos!=std::string::npos);
00164 }
00165 }
00166 else {
00167 _unknowns.push_back(name);
00168 }
00169 return result;
00170 }
00171
00172
00173 template <class T>
00174 std::vector<T> CommandLine::getVector(const std::string& name,
00175 const std::string& default_as_string)
00176 {
00177 OptionMap_t::iterator it=_options.find(name);
00178 if (it==_options.end()) _options[name] = std::make_pair(default_as_string,false);
00179 return getVector<T>(name);
00180 }
00181
00183
00185
00186 CommandLine::CommandLine()
00187 {
00188
00189 }
00190
00191 CommandLine::~CommandLine()
00192 {
00193
00194 }
00196
00198
00199 bool CommandLine::parse(int argc,char**argv)
00200 {
00201 _exe = argv[0];
00202 _options.clear();
00203 _ordered_options.clear();
00204 _unknowns.clear();
00205
00206 for (int i=1;i<argc;i++) {
00207 std::string opt=argv[i];
00208 if(0!=opt.find("-")) {
00209 if (i==1) {
00210 bool success = parse_file(opt);
00211 if (!success) return false;
00212 continue;
00213 }
00214 else {
00215 std::cout<<"CommandLine ERROR: options must start with '-'!"<<std::endl;
00216 return false;
00217 }
00218 }
00219 opt.erase(0,1);
00220 std::string next=argv[i+1];
00221 if (i+1>=argc) {
00222 std::cout<<"ERROR: option '"<<opt<<"' requires value!"<<std::endl;
00223 return false;
00224 }
00225 _options[opt] = std::make_pair(next,false);
00226 i++;
00227 if (i<argc-1) {
00228 next=argv[i+1];
00229 while (next.find("-")!=0) {
00230 _options[opt].first += ","+next;
00231 i++;
00232 next = (i<argc-1) ? argv[i+1] : "-";
00233 }
00234 }
00235 }
00236
00237 return true;
00238 }
00239
00240 bool CommandLine::check()
00241 {
00242 bool result = true;
00243 OptionMap_t::const_iterator it;
00244 for (it = _options.begin();it!=_options.end();++it) {
00245 if (!it->second.second) {
00246 std::cout<<"CommandLine WARNING: unused option '"<<it->first<<"'!"<<std::endl;
00247 result = false;
00248 }
00249 }
00250
00251 if (_unknowns.size()>0) {
00252 result = false;
00253 std::cout<<"\nCommandLine WARNING: "<<_unknowns.size()
00254 <<" the followingparameters *must* be provided:"<<std::endl;
00255 for (StrVec_t::const_iterator it=_unknowns.begin();it!=_unknowns.end();++it)
00256 std::cout<<(*it)<<std::endl;
00257 std::cout<<std::endl;
00258 }
00259 return result;
00260 }
00261
00262 void CommandLine::print()
00263 {
00264 std::cout<<"------------------------------------------------------------"<<std::endl;
00265 std::cout<<_exe<<" options:"<<std::endl;
00266 std::cout<<"------------------------------------------------------------"<<std::endl;
00267 for (StrVec_t::const_iterator itvec=_ordered_options.begin();
00268 itvec!=_ordered_options.end();++itvec) {
00269 OptionMap_t::const_iterator it=_options.find(*itvec);
00270 assert(it!=_options.end());
00271 if (it->second.first.find(",")<std::string::npos) {
00272 std::string tmp=it->second.first;
00273 std::string::size_type length = tmp.length();
00274 std::string::size_type pos;
00275 do {
00276 pos = tmp.find(",");
00277 if (tmp.length()==length) {
00278 std::cout<<std::setiosflags(std::ios::left)<<std::setw(22)
00279 <<it->first
00280 <<std::resetiosflags(std::ios::left)
00281 <<std::setw(3)<<"="
00282 <<std::setiosflags(std::ios::right)<<std::setw(35)
00283 <<tmp.substr(0,pos)
00284 <<std::resetiosflags(std::ios::right)
00285 <<std::endl;
00286 }
00287 else {
00288 std::cout<<std::setiosflags(std::ios::right)<<std::setw(60)
00289 <<tmp.substr(0,pos)
00290 <<std::resetiosflags(std::ios::right)
00291 <<std::endl;
00292 }
00293 tmp.erase(0,pos+1);
00294 }
00295 while (pos!=std::string::npos);
00296 }
00297 else {
00298 std::cout<<std::setiosflags(std::ios::left)<<std::setw(22)
00299 <<it->first
00300 <<std::resetiosflags(std::ios::left)
00301 <<std::setw(3)<<"="
00302 <<std::setiosflags(std::ios::right)<<std::setw(35)
00303 <<it->second.first
00304 <<std::resetiosflags(std::ios::right)
00305 <<std::endl;
00306 }
00307 }
00308 std::cout<<"------------------------------------------------------------"<<std::endl;
00309 }
00310
00311 bool CommandLine::parse_file(const std::string& file_name)
00312 {
00313 ifstream fin(file_name.c_str());
00314 if (!fin.is_open()) {
00315 std::cout<<"Can't open configuration file "<<file_name<<std::endl;
00316 return false;
00317 }
00318
00319 std::stringstream ss;
00320 bool filter(false);
00321 while(!fin.eof()){
00322 char next;
00323 fin.get(next);
00324 if (!filter&&next=='$') filter=true;
00325 if(!filter) {
00326 if (next=='=') ss<<" "<<next<<" ";
00327 else ss<<next;
00328 }
00329 if (filter&&next=='\n') filter=false;
00330 }
00331
00332 std::string token,last_token,key,value;
00333 ss>>token;
00334 while (!ss.eof()) {
00335 if (token=="=") {
00336 if (key!=""&&value!="") _options[key] = std::make_pair(value,false);
00337 key=last_token;
00338 last_token="";
00339 value="";
00340 }
00341 else if (last_token!="") {
00342 if (last_token.find("\"")==0) {
00343 if (last_token.rfind("\"")==last_token.length()-1) {
00344 last_token=last_token.substr(1,last_token.length()-2);
00345 value+=(value!="")?","+last_token:last_token;
00346 last_token=token;
00347 }
00348 else last_token+=" "+token;
00349 }
00350 else {
00351 value+=(value!="")?","+last_token:last_token;
00352 last_token=(token=="=")?"":token;
00353 }
00354 }
00355 else last_token=(token=="=")?"":token;
00356 ss>>token;
00357 }
00358 if (last_token!="") {
00359 if (last_token.find("\"")==0&&last_token.rfind("\"")==last_token.length()-1)
00360 last_token=last_token.substr(1,last_token.length()-2);
00361 value+=(value!="")?","+last_token:last_token;
00362 }
00363 if (key!=""&&value!="") _options[key] = std::make_pair(value,false);
00364
00365 return true;
00366 }
00368 void GetMPV(char name[100],TH1F* histo, TDirectory* Dir, double& peak, double& error, double& sigma, double& err_sigma)
00369 {
00370 double norm,mean,rms,integral,lowlimit,highlimit,LowResponse,HighResponse,a;
00371 int k;
00372 LowResponse = histo->GetXaxis()->GetXmin();
00373 HighResponse = histo->GetXaxis()->GetXmax();
00374 Dir->cd();
00375 TF1 *g;
00376 TStyle *myStyle = new TStyle("mystyle","mystyle");
00377 myStyle->Reset();
00378 myStyle->SetOptFit(1111);
00379 myStyle->SetOptStat(2200);
00380 myStyle->SetStatColor(0);
00381 myStyle->SetTitleFillColor(0);
00382 myStyle->cd();
00383 integral = histo->Integral();
00384 mean = histo->GetMean();
00385 rms = histo->GetRMS();
00386 a = 1.5;
00387 if (integral>0)
00388 {
00389 lowlimit = TMath::Max(LowResponse,mean-a*rms);
00390 highlimit= TMath::Min(mean+a*rms,HighResponse);
00391 norm = histo->GetMaximumStored();
00392 peak = mean;
00393 sigma = rms;
00394 for (k=0; k<3; k++)
00395 {
00396 g = new TF1("g","gaus",lowlimit, highlimit);
00397 g->SetParNames("N","#mu","#sigma");
00398 g->SetParameter(0,norm);
00399 g->SetParameter(1,peak);
00400 g->SetParameter(2,sigma);
00401 lowlimit = TMath::Max(LowResponse,peak-a*sigma);
00402 highlimit= TMath::Min(peak+a*sigma,HighResponse);
00403 g->SetRange(lowlimit,highlimit);
00404 histo->Fit(g,"RQ");
00405 norm = g->GetParameter(0);
00406 peak = g->GetParameter(1);
00407 sigma = g->GetParameter(2);
00408 }
00409 if (g->GetNDF()>5)
00410 {
00411 peak = g->GetParameter(1);
00412 sigma = g->GetParameter(2);
00413 error = g->GetParError(1);
00414 err_sigma = g->GetParError(2);
00415 }
00416 else
00417 {
00418 std::cout<<"FIT FAILURE: histogram "<<name<<"...Using MEAN and RMS."<<std::endl;
00419 peak = mean;
00420 sigma = rms;
00421 error = histo->GetMeanError();
00422 err_sigma = histo->GetRMSError();
00423 }
00424 }
00425 else
00426 {
00427 peak = 0;
00428 sigma = 0;
00429 error = 0;
00430 err_sigma = 0;
00431 }
00432 histo->Write();
00433 }
00435 void GetMEAN(TH1F* histo, double& peak, double& error, double& sigma)
00436 {
00437 double N = histo->Integral();
00438 if (N>2)
00439 {
00440 peak = histo->GetMean();
00441 sigma = histo->GetRMS();
00442 error = histo->GetMeanError();
00443 }
00444 else
00445 {
00446 peak = 0;
00447 sigma = 0;
00448 error = 0;
00449 }
00450 }
00452 void CalculateResponse(bool UseRatioForResponse, double x, double ex, double y, double ey, double& r, double& e)
00453 {
00454 if (x>0 && fabs(y)>0)
00455 {
00456 if (UseRatioForResponse)
00457 {
00458 r = y;
00459 e = ey;
00460 }
00461 else
00462 {
00463 r = (x+y)/x;
00464 e = fabs(r-1.)*sqrt(pow(ey/y,2)+pow(ex/x,2));
00465 }
00466 }
00467 else
00468 {
00469 r = 0;
00470 e = 0;
00471 }
00472 }
00474 void CalculateCorrection(bool UseRatioForResponse, double x, double ex, double y, double ey, double& c, double& e)
00475 {
00476 if (x>0 && fabs(y)>0)
00477 {
00478 if (UseRatioForResponse)
00479 {
00480 c = 1./y;
00481 e = ey/(y*y);
00482 }
00483 else
00484 {
00485 c = x/(x+y);
00486 e = (fabs(x*y)/pow(x+y,2))*sqrt(pow(ey/y,2)+pow(ex/x,2));
00487 }
00488 }
00489 else
00490 {
00491 c = 0;
00492 e = 0;
00493 }
00494 }
00496 bool HistoExists(std::vector<std::string> LIST, std::string hname)
00497 {
00498 unsigned int i,N;
00499 bool found(false);
00500 N = LIST.size();
00501 if (N==0)
00502 std::cout<<"WARNING: empty file histogram list!!!!"<<std::endl;
00503 else
00504 for(i=0;i<N;i++)
00505 if (hname==LIST[i])
00506 found = true;
00507 if (!found)
00508 std::cout<<"Histogram: "<<hname<<" NOT FOUND!!! Check list of existing objects."<<std::endl;
00509 return found;
00510 }
00512 int getBin(double x, std::vector<double> boundaries)
00513 {
00514 int i;
00515 int n = boundaries.size()-1;
00516 if (n<=0) return -1;
00517 if (x<boundaries[0] || x>=boundaries[n])
00518 return -1;
00519 for(i=0;i<n;i++)
00520 {
00521 if (x>=boundaries[i] && x<boundaries[i+1])
00522 return i;
00523 }
00524 return 0;
00525 }