00001
00002
00003
00004 #include <cmath>
00005 #include <cstdlib>
00006 #include <iostream>
00007 #include <iomanip>
00008
00009
00010 #include "Util/UtilString.h"
00011
00012
00013 #include "TH1.h"
00014 #include "TH2.h"
00015 #include "TProfile.h"
00016
00017
00018 #include "PhysicsNtuple/Default.h"
00019
00020
00021 #include "HistMan.h"
00022 #include "tinyxml.h"
00023
00024
00025
00026
00027 Anp::HistMan *Anp::HistMan::fgInstance = 0;
00028 Anp::Mutex Anp::HistMan::fMutex;
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 Anp::HistMan& Anp::HistMan::Instance()
00039 {
00040 if(!fgInstance)
00041 {
00042 Anp::Lock<Mutex> lock(fMutex);
00043
00044 if(!fgInstance)
00045 {
00046 fgInstance = new Anp::HistMan();
00047 }
00048 }
00049
00050 return *fgInstance;
00051 }
00052
00053 using namespace std;
00054
00055
00056 Anp::HistMan::HistMan()
00057 :fNMiss(0),
00058 fKeyWidth(4)
00059 {
00060 }
00061
00062
00063 Anp::HistMan::~HistMan()
00064 {
00065 }
00066
00067
00068 bool Anp::HistMan::ReadFile(const string file)
00069 {
00070
00071
00072
00073
00074
00075
00076
00077 Anp::Lock<Mutex> lock(fMutex);
00078
00079 TiXmlDocument doc(file.c_str());
00080 const bool loadok = doc.LoadFile();
00081 if(!loadok)
00082 {
00083 cerr << "HistMan::ReadFile - failed to load: " << file << endl;
00084 return false;
00085 }
00086
00087 for(TiXmlNode *pChild = doc.FirstChild(); pChild != 0; pChild = pChild -> NextSibling())
00088 {
00089 if(!pChild)
00090 {
00091 cerr << "HistMan::ReadFile - null child..." << endl;
00092 continue;
00093 }
00094
00095 if(pChild -> Type() != TiXmlNode::ELEMENT)
00096 {
00097 continue;
00098 }
00099
00100 if(pChild -> Value() && strcmp(pChild -> Value(), "histograms"))
00101 {
00102 continue;
00103 }
00104
00105 TiXmlElement* pHist = pChild -> ToElement();
00106 if(pHist)
00107 {
00108 ReadHistogramBlock(*pHist);
00109 }
00110 else
00111 {
00112 cerr << "HistMan::ReadFile - failed to cast root element for histograms" << endl;
00113 continue;
00114 }
00115 }
00116
00117 return true;
00118 }
00119
00120
00121 bool Anp::HistMan::ReadHistogramBlock(TiXmlElement &block)
00122 {
00123 InfoMap hmap;
00124 vector<vector<int> > basevec;
00125 vector<string> dirvec;
00126
00127 for(TiXmlNode *pChild = block.FirstChild(); pChild != 0; pChild = pChild -> NextSibling())
00128 {
00129 if(!pChild)
00130 {
00131 cerr << "HistMan::ReadFile - null child..." << endl;
00132 continue;
00133 }
00134
00135 if(pChild -> Type() != TiXmlNode::ELEMENT)
00136 {
00137 continue;
00138 }
00139
00140 TiXmlElement* hist = pChild -> ToElement();
00141 if(!hist)
00142 {
00143 cerr << "HistMan::ReadFile - failed to cast xml node to element..." << endl;
00144 continue;
00145 }
00146
00147 if(!hist -> Value())
00148 {
00149 cerr << "HistMan::ReadFile - node has no value" << endl;
00150 continue;
00151 }
00152
00153 if(strcmp(hist -> Value(), "keybase") == 0 && hist -> Attribute("keys"))
00154 {
00155 const vector<int> ivec = GetIntVec(hist -> Attribute("keys"));
00156 if(!ivec.empty())
00157 {
00158 basevec.push_back(ivec);
00159 }
00160
00161 continue;
00162 }
00163
00164 if(strcmp(hist -> Value(), "dirbase") == 0 && hist -> Attribute("dirs"))
00165 {
00166 const vector<string> svec = GetStringVec(hist -> Attribute("dirs"));
00167 if(!svec.empty())
00168 {
00169 dirvec.insert(dirvec.end(), svec.begin(), svec.end());
00170 }
00171
00172 continue;
00173 }
00174
00175 HistInfo info;
00176 if(strcmp(hist -> Value(), "h1d") != 0 || !ReadHistogram(*hist, info))
00177 {
00178 continue;
00179 }
00180
00181 if(!hmap.insert(InfoMap::value_type(info.GetKey(), info)).second)
00182 {
00183 cerr << "HistMan::ReadFile - histogram key " << info.GetKey() << " already exists" << endl;
00184 }
00185
00186 const int intkey = std::atoi(info.GetKey().c_str());
00187 if(intkey != 0)
00188 {
00189 const unsigned int width = ComputeWidth(intkey);
00190 fKeyWidth = max<int>(width, fKeyWidth);
00191
00192 if(width != info.GetKey().size())
00193 {
00194 cerr << "HistMan::ReadFile - integer width and string size are not equal for key " <<info.GetKey()<<" "<<info.GetTitle()<< endl;
00195 }
00196 }
00197 }
00198
00199 vector<int> allvec;
00200 for(vector<vector<int> >::const_iterator bit = basevec.begin(); bit != basevec.end(); ++bit)
00201 {
00202 const vector<int> prevvec = allvec;
00203 const vector<int> &currvec = *bit;
00204
00205 for(vector<int>::const_iterator cit = currvec.begin(); cit != currvec.end(); ++cit)
00206 {
00207 if(prevvec.empty())
00208 {
00209 allvec.push_back(*cit);
00210 }
00211 else
00212 {
00213 for(vector<int>::const_iterator pit = prevvec.begin(); pit != prevvec.end(); ++pit)
00214 {
00215 allvec.push_back(*cit + *pit);
00216 }
00217 }
00218 }
00219 }
00220
00221 InfoMap nmap = hmap;
00222
00223 for(vector<int>::const_iterator it = allvec.begin(); it != allvec.end(); ++it)
00224 {
00225 const int base = *it;
00226
00227 for(InfoMap::const_iterator hit = hmap.begin(); hit != hmap.end(); ++hit)
00228 {
00229 const int oldkey = std::atoi((hit -> first).c_str());
00230 if(oldkey == 0)
00231 {
00232 continue;
00233 }
00234
00235 const int newkey = base + oldkey;
00236 HistInfo info = hit -> second;
00237
00238 stringstream strkey;
00239 strkey << newkey;
00240 info.fKey = strkey.str();
00241
00242 if(!nmap.insert(InfoMap::value_type(info.GetKey(), info)).second)
00243 {
00244 cerr << "HistMan::ReadFile - histogram key " << info.GetKey() << " already exists" << endl;
00245 }
00246
00247 const unsigned int width = ComputeWidth(newkey);
00248 fKeyWidth = max<int>(width, fKeyWidth);
00249
00250 if(width != info.GetKey().size())
00251 {
00252 cerr << "HistMan::ReadFile - integer width and string size are not equal" << endl;
00253 }
00254 }
00255 }
00256
00257 if(dirvec.empty())
00258 {
00259 dirvec.push_back(".");
00260 }
00261
00262 for(vector<string>::const_iterator dit = dirvec.begin(); dit != dirvec.end(); ++dit)
00263 {
00264 InfoMap &imap = fDirMap[*dit];
00265
00266 for(InfoMap::const_iterator nit = nmap.begin(); nit != nmap.end(); ++nit)
00267 {
00268 if(!imap.insert(InfoMap::value_type(*nit)).second)
00269 {
00270 cerr << "HistMan::ReadFile - failed to add " << nit -> first << " to " << *dit << endl;
00271 }
00272 }
00273 }
00274
00275 return true;
00276 }
00277
00278
00279 bool Anp::HistMan::ReadHistogram(const TiXmlElement &hist, HistInfo &info)
00280 {
00281 if(hist.Value() && strcmp(hist.Value(), "h1d") != 0)
00282 {
00283 return false;
00284 }
00285
00286 AxisInfo xaxis, yaxis;
00287
00288 bool axis1dok = false, axis2dok = false;
00289 for(const TiXmlNode *pChild = hist.FirstChild(); pChild != 0; pChild = pChild -> NextSibling())
00290 {
00291 if(!pChild)
00292 {
00293 cerr << "Null child..." << endl;
00294 continue;
00295 }
00296
00297 if(pChild -> Type() != TiXmlNode::ELEMENT)
00298 {
00299 continue;
00300 }
00301
00302 const TiXmlElement* axis = pChild -> ToElement();
00303 if(!axis)
00304 {
00305 cerr << "Failed to cast xml node to element..." << endl;
00306 continue;
00307 }
00308
00309 if(!axis -> Value())
00310 {
00311 cerr << "Node has no value" << endl;
00312 continue;
00313 }
00314
00315 if(strcmp(axis -> Value(), "axis1d") == 0 && ReadAxis(*axis, xaxis))
00316 {
00317 axis1dok = true;
00318 }
00319 if(strcmp(axis -> Value(), "axis2d") == 0 && ReadAxis(*axis, yaxis))
00320 {
00321 axis2dok = true;
00322 }
00323 }
00324
00325 if(!axis1dok)
00326 {
00327 cerr << "Failed to read 1d axis info" << endl;
00328 return false;
00329 }
00330 else
00331 {
00332 info.fXaxis = xaxis;
00333 }
00334
00335 if(axis2dok)
00336 {
00337 info.fYaxis = yaxis;
00338 }
00339
00340 const char *key = hist.Attribute("key");
00341 if(key)
00342 {
00343 info.fKey = string(key);
00344 }
00345 else
00346 {
00347 cerr << "HistMan::ReadHistogram() - key string is empty" << endl;
00348 return false;
00349 }
00350
00351 const char *name = hist.Attribute("name");
00352 if(name)
00353 {
00354 info.fName = name;
00355 }
00356
00357 const char *title = hist.Attribute("title");
00358 if(title)
00359 {
00360 info.fTitle = title;
00361 }
00362
00363 const char *axis = hist.Attribute("axis");
00364 if(axis)
00365 {
00366 info.fXaxis.fTitle = axis;
00367 }
00368
00369 return true;
00370 }
00371
00372
00373 bool Anp::HistMan::ReadAxis(const TiXmlElement &axis, AxisInfo &info)
00374 {
00375 bool read_bin = false, read_bins = false;
00376
00377 int bin = 0;
00378 float min = 0.0, max = 0.0;
00379
00380 if(axis.QueryIntAttribute("bin", &bin) == TIXML_SUCCESS &&
00381 axis.QueryFloatAttribute("min", &min) == TIXML_SUCCESS &&
00382 axis.QueryFloatAttribute("max", &max) == TIXML_SUCCESS)
00383 {
00384 read_bin = true;
00385 }
00386
00387 const char *xtitle = axis.Attribute("title");
00388 if(xtitle)
00389 {
00390 info.fTitle = xtitle;
00391 }
00392
00393 vector<double> bvec;
00394
00395 const char *bins = axis.Attribute("bins");
00396 if(bins)
00397 {
00398 vector<string> datavec;
00399 UtilString::StringTok(datavec, bins, ", ");
00400
00401 for(vector<string>::const_iterator sit = datavec.begin(); sit != datavec.end(); ++sit)
00402 {
00403 if(sit -> size() > 0)
00404 {
00405 bvec.push_back(std::atof(sit -> c_str()));
00406 }
00407 }
00408
00409 std::sort(bvec.begin(), bvec.end());
00410
00411
00412
00413
00414
00415
00416 if(!bvec.empty())
00417 {
00418 read_bins = true;
00419 }
00420 }
00421
00422 if(read_bin)
00423 {
00424 info.fNbins = bin;
00425 info.fMin = min;
00426 info.fMax = max;
00427 info.fValid = true;
00428 }
00429 else if(read_bins)
00430 {
00431 info.fBins = bvec;
00432 }
00433
00434 return true;
00435 }
00436
00437
00438 bool Anp::HistMan::KeyExists(const int key, const string &dir) const
00439 {
00440 return HistMan::KeyExists(HistMan::Convert(key), dir);
00441 }
00442
00443
00444 bool Anp::HistMan::KeyExists(const string &key, const string &dir) const
00445 {
00446 Anp::Lock<Mutex> lock(fMutex);
00447
00448 DirIter dit = fDirMap.find(dir);
00449 if(dit == fDirMap.end())
00450 {
00451 return false;
00452 }
00453
00454 const InfoMap &imap = dit -> second;
00455
00456 return (imap.find(key) != imap.end());
00457 }
00458
00459
00460 const Anp::Hist1d<double> Anp::HistMan::CreateHist1d(const int key, const string &dir)
00461 {
00462 return HistMan::CreateHist1d(HistMan::Convert(key), dir);
00463 }
00464
00465
00466 const Anp::Hist1d<double> Anp::HistMan::CreateHist1d(const string &key, const string &dir)
00467 {
00468 Anp::Lock<Mutex> lock(fMutex);
00469
00470 DirIter dit = fDirMap.find(dir);
00471 if(dit == fDirMap.end())
00472 {
00473 ++fNMiss;
00474 return Hist1d<double>(0, 0.0, 0.0);
00475 }
00476
00477 const InfoMap &imap = dit -> second;
00478
00479 InfoIter hit = imap.find(key);
00480 if(hit == imap.end())
00481 {
00482 ++fNMiss;
00483 return Hist1d<double>(0, 0.0, 0.0);
00484 }
00485
00486 return HistMan::CreateHist1d(hit -> second);
00487 }
00488
00489
00490 TH1* Anp::HistMan::CreateTH1(const int key, const string &dir)
00491 {
00492 return HistMan::CreateTH1(HistMan::Convert(key), dir);
00493 }
00494
00495
00496 TH1* Anp::HistMan::CreateTH1(const string &key, const string &dir_)
00497 {
00498 Anp::Lock<Mutex> lock(fMutex);
00499
00500
00501
00502
00503 string opt;
00504 string dir = dir_;
00505 if (dir.find("profile") != string::npos) opt += "profile";
00506 else if(dir.find("float") != string::npos) opt += "float";
00507
00508 if(!opt.empty() && dir.find(opt.c_str()) != string::npos)
00509 {
00510 dir.erase(dir.find(opt.c_str()), opt.size());
00511 }
00512
00513 if(dir.empty())
00514 {
00515 dir = ".";
00516 }
00517
00518 DirIter dit = fDirMap.find(dir);
00519 if(dit == fDirMap.end())
00520 {
00521 ++fNMiss;
00522 return 0;
00523 }
00524
00525 const InfoMap &imap = dit -> second;
00526
00527 InfoIter hit = imap.find(key);
00528 if(hit == imap.end())
00529 {
00530 ++fNMiss;
00531 return 0;
00532 }
00533
00534 return HistMan::CreateTH1(hit -> second, opt);
00535 }
00536
00537
00538 TH2* Anp::HistMan::CreateTH2(const int key, const string &dir)
00539 {
00540 return HistMan::CreateTH2(Convert(key), dir);
00541 }
00542
00543
00544 TH2* Anp::HistMan::CreateTH2(const string &key, const string &dir_)
00545 {
00546 Anp::Lock<Mutex> lock(fMutex);
00547
00548
00549
00550
00551 string opt;
00552 string dir = dir_;
00553 if (dir.find("double") != string::npos) opt += "double";
00554
00555 if(!opt.empty() && dir.find(opt.c_str()) != string::npos)
00556 {
00557 dir.erase(dir.find(opt.c_str()), opt.size());
00558 }
00559
00560 if(dir.empty())
00561 {
00562 dir = ".";
00563 }
00564
00565
00566 DirIter dit = fDirMap.find(dir);
00567 if(dit == fDirMap.end())
00568 {
00569 ++fNMiss;
00570 return 0;
00571 }
00572
00573 const InfoMap &imap = dit -> second;
00574
00575 InfoIter hit = imap.find(key);
00576 if(hit == imap.end())
00577 {
00578 ++fNMiss;
00579 return 0;
00580 }
00581
00582 return HistMan::CreateTH2(hit -> second, opt);
00583 }
00584
00585
00586 TH2* Anp::HistMan::GetTH2(const int xkey, const int ykey, const string &dir)
00587 {
00588 return HistMan::GetTH2(Convert(xkey), HistMan::Convert(ykey), dir);
00589 }
00590
00591
00592 TH2* Anp::HistMan::GetTH2(const string &xkey, const string &ykey, const string &dir)
00593 {
00594 Anp::Lock<Mutex> lock(fMutex);
00595
00596 DirIter dit = fDirMap.find(dir);
00597 if(dit == fDirMap.end())
00598 {
00599 ++fNMiss;
00600 return 0;
00601 }
00602
00603 const InfoMap &imap = dit -> second;
00604
00605 InfoIter xhit = imap.find(xkey);
00606 if(xhit == imap.end())
00607 {
00608 ++fNMiss;
00609 return 0;
00610 }
00611
00612 InfoIter yhit = imap.find(ykey);
00613 if(yhit == imap.end())
00614 {
00615 ++fNMiss;
00616 return 0;
00617 }
00618
00619 const HistInfo &xinfo = xhit -> second;
00620 const HistInfo &yinfo = yhit -> second;
00621
00622 HistInfo info;
00623
00624 info.fKey = "keys_" + xinfo.GetKey() + "_and_" + yinfo.GetKey();
00625 info.fXaxis = xinfo.GetXaxis();
00626 info.fYaxis = yinfo.GetXaxis();
00627 info.fName = info.GetKey();
00628 info.fTitle = info.GetKey();
00629
00630 if(xinfo.GetYaxis().Valid())
00631 {
00632 info.fXaxis = xinfo.GetYaxis();
00633 }
00634 if(yinfo.GetYaxis().Valid())
00635 {
00636 info.fYaxis = yinfo.GetYaxis();
00637 }
00638
00639 return HistMan::CreateTH2(info);
00640 }
00641
00642
00643 const Anp::Hist1d<double> Anp::HistMan::CreateHist1d(const HistInfo &info)
00644 {
00645 const AxisInfo &xaxis = info.GetXaxis();
00646
00647 if(!xaxis.GetBins().empty())
00648 {
00649 return Hist1d<double>(xaxis.GetBins());
00650 }
00651
00652 return Hist1d<double>(xaxis.GetNbins(), xaxis.GetMin(), xaxis.GetMax());
00653 }
00654
00655
00656 TH1* Anp::HistMan::CreateTH1(const HistInfo &info, const string &opt)
00657 {
00658 string strkey = info.GetKey();
00659 string name = info.GetName();
00660 string title = info.GetTitle();
00661
00662 const int intkey = std::atoi(strkey.c_str());
00663 if(intkey != 0)
00664 {
00665 strkey = "key_" + Convert(intkey, fKeyWidth);
00666 }
00667 if(name.empty())
00668 {
00669 name = strkey;
00670 }
00671 if(title.empty())
00672 {
00673 title = info.GetName();
00674 }
00675
00676 const AxisInfo &xaxis = info.GetXaxis();
00677 const AxisInfo &yaxis = info.GetYaxis();
00678
00679 TH1 *h = 0;
00680 if(xaxis.GetBins().empty())
00681 {
00682 Anp::Lock<Anp::Mutex> lock(Anp::GetROOTMutex());
00683
00684 if(opt.find("profile") != string::npos)
00685 {
00686 h = new TProfile(name.c_str(), title.c_str(),
00687 xaxis.GetNbins(), xaxis.GetMin(), xaxis.GetMax());
00688 }
00689 else if(opt.find("float") != string::npos)
00690 {
00691 h = new TH1F(name.c_str(), title.c_str(),
00692 xaxis.GetNbins(), xaxis.GetMin(), xaxis.GetMax());
00693 }
00694 else
00695 {
00696 h = new TH1D(name.c_str(), title.c_str(),
00697 xaxis.GetNbins(), xaxis.GetMin(), xaxis.GetMax());
00698 }
00699 }
00700 else
00701 {
00702 Anp::Lock<Anp::Mutex> lock(Anp::GetROOTMutex());
00703
00704 const vector<double> &bvec = xaxis.GetBins();
00705
00706 double *darray = new double[bvec.size()];
00707
00708 for(unsigned int ibin = 0; ibin < bvec.size(); ++ibin)
00709 {
00710 darray[ibin] = bvec[ibin];
00711 }
00712
00713 if(opt.find("profile") != string::npos)
00714 {
00715 h = new TProfile(name.c_str(), title.c_str(), bvec.size() - 1, darray);
00716 }
00717 else if(opt.find("float") != string::npos)
00718 {
00719 h = new TH1F(name.c_str(), title.c_str(), bvec.size() - 1, darray);
00720 }
00721 else
00722 {
00723 h = new TH1D(name.c_str(), title.c_str(), bvec.size() - 1, darray);
00724 }
00725
00726 delete [] darray;
00727 }
00728
00729
00730
00731
00732 Anp::SetDir(h, 0);
00733
00734 if(xaxis.GetTitle().size() > 0)
00735 {
00736 h -> GetXaxis() -> SetTitle(xaxis.GetTitle().c_str());
00737 h -> GetXaxis() -> CenterTitle();
00738 }
00739 if(yaxis.GetTitle().size() > 0)
00740 {
00741 h -> GetYaxis() -> SetTitle(yaxis.GetTitle().c_str());
00742 h -> GetYaxis() -> CenterTitle();
00743 }
00744
00745 return h;
00746 }
00747
00748
00749 TH2* Anp::HistMan::CreateTH2(const HistInfo &info, const string &opt)
00750 {
00751 string strkey = info.GetKey();
00752 string name = info.GetName();
00753 string title = info.GetTitle();
00754
00755 const int intkey = std::atoi(strkey.c_str());
00756 if(intkey != 0)
00757 {
00758 strkey = Convert(intkey, fKeyWidth);
00759 }
00760 if(name.empty())
00761 {
00762 name = strkey;
00763 }
00764 if(title.empty())
00765 {
00766 title = info.GetName();
00767 }
00768
00769 const AxisInfo &xaxis = info.GetXaxis();
00770 const AxisInfo &yaxis = info.GetYaxis();
00771
00772 TH2 *h = 0;
00773 if(!name.empty())
00774 {
00775 Anp::Lock<Anp::Mutex> lock(Anp::GetROOTMutex());
00776
00777 if(opt.find("double") != string::npos)
00778 {
00779 h = new TH2D(name.c_str(), title.c_str(),
00780 xaxis.GetNbins(), xaxis.GetMin(), xaxis.GetMax(),
00781 yaxis.GetNbins(), yaxis.GetMin(), yaxis.GetMax());
00782
00783 }
00784 else
00785 {
00786 h = new TH2F(name.c_str(), title.c_str(),
00787 xaxis.GetNbins(), xaxis.GetMin(), xaxis.GetMax(),
00788 yaxis.GetNbins(), yaxis.GetMin(), yaxis.GetMax());
00789 }
00790
00791 if(xaxis.GetTitle().size() > 0)
00792 {
00793 h -> GetXaxis() -> SetTitle(xaxis.GetTitle().c_str());
00794 h -> GetXaxis() -> CenterTitle();
00795 }
00796 if(yaxis.GetTitle().size() > 0)
00797 {
00798 h -> GetYaxis() -> SetTitle(yaxis.GetTitle().c_str());
00799 h -> GetYaxis() -> CenterTitle();
00800 }
00801 }
00802
00803
00804
00805
00806 Anp::SetDir(h, 0);
00807
00808 return h;
00809 }
00810
00811
00812 const vector<int> Anp::HistMan::GetIntVec(const string &list) const
00813 {
00814 vector<string> namelist;
00815 UtilString::StringTok(namelist, list, ", ");
00816
00817 vector<int> ivec;
00818 for(vector<string>::const_iterator sit = namelist.begin(); sit != namelist.end(); ++sit)
00819 {
00820 const int newbase = std::atoi(sit -> c_str());
00821 if(newbase != 0)
00822 {
00823 ivec.push_back(newbase);
00824 }
00825 }
00826
00827 return ivec;
00828 }
00829
00830
00831 const vector<string> Anp::HistMan::GetStringVec(const string &list) const
00832 {
00833 vector<string> namelist;
00834 UtilString::StringTok(namelist, list, ", ");
00835
00836 vector<string> nvec;
00837 for(vector<string>::const_iterator sit = namelist.begin(); sit != namelist.end(); ++sit)
00838 {
00839 if(!sit -> empty())
00840 {
00841 nvec.push_back(*sit);
00842 }
00843 }
00844
00845 return nvec;
00846 }
00847
00848
00849 const string Anp::HistMan::Convert(const int key, const int width) const
00850 {
00851 stringstream strkey;
00852 if(width == 0)
00853 {
00854 strkey << setw(ComputeWidth(key)) << key;
00855 }
00856 else
00857 {
00858 strkey << setfill('0') << setw(width) << key;
00859 }
00860
00861 return strkey.str();
00862 }
00863
00864
00865 unsigned short Anp::HistMan::ComputeWidth(int key) const
00866 {
00867
00868
00869
00870 return static_cast<unsigned int>(std::floor(std::log10(double(std::abs(key) + 1)))) + 1;
00871 }
00872
00873
00874 unsigned int Anp::HistMan::NMiss() const
00875 {
00876 Anp::Lock<Mutex> lock(fMutex);
00877 return fNMiss;
00878 }
00879
00880
00881 void Anp::HistMan::Print(ostream& o) const
00882 {
00883 o << "HistMan::Print" << endl;
00884 for(DirIter dit = fDirMap.begin(); dit != fDirMap.end(); ++dit)
00885 {
00886 o << "Directory = " << dit -> first << endl;
00887 const InfoMap &imap = dit -> second;
00888
00889 for(InfoIter it = imap.begin(); it != imap.end(); ++it)
00890 {
00891 it -> second.Print(o);
00892 }
00893 }
00894 }
00895
00896
00897 Anp::HistInfo::HistInfo()
00898 :fKey(),
00899 fName(),
00900 fTitle(),
00901 fXaxis(),
00902 fYaxis()
00903 {
00904 }
00905
00906
00907 Anp::HistInfo::~HistInfo()
00908 {
00909 }
00910
00911
00912 const std::string& Anp::HistInfo::GetName() const
00913 {
00914 return fName;
00915 }
00916
00917
00918 const std::string& Anp::HistInfo::GetTitle() const
00919 {
00920 return fTitle;
00921 }
00922
00923
00924 const Anp::AxisInfo& Anp::HistInfo::GetXaxis() const
00925 {
00926 return fXaxis;
00927 }
00928
00929
00930 const Anp::AxisInfo& Anp::HistInfo::GetYaxis() const
00931 {
00932 return fYaxis;
00933 }
00934
00935
00936 const std::string& Anp::HistInfo::GetKey() const
00937 {
00938 return fKey;
00939 }
00940
00941
00942 bool Anp::HistInfo::operator<(const HistInfo &rhs) const
00943 {
00944 if(fKey < rhs.fKey)
00945 {
00946 return true;
00947 }
00948
00949 return false;
00950 }
00951
00952
00953 bool Anp::HistInfo::operator==(const HistInfo &rhs) const
00954 {
00955 if(fKey == rhs.fKey)
00956 {
00957 return true;
00958 }
00959
00960 return false;
00961 }
00962
00963
00964 void Anp::HistInfo::Print(ostream& o) const
00965 {
00966 o << "Printing HistInfo: key = " << GetKey() << std::endl
00967 << " name = " << GetName()
00968 << ", title = " << GetTitle()
00969 << " " << fXaxis
00970 << " " << fYaxis;
00971 }
00972
00973
00974 std::ostream& Anp::operator<<(ostream& o, const Anp::HistInfo &self)
00975 {
00976 self.Print(o);
00977 return o;
00978 }
00979
00980
00981 Anp::AxisInfo::AxisInfo()
00982 :fNbins(0),
00983 fMin(0),
00984 fMax(0),
00985 fValid(false),
00986 fTitle()
00987 {
00988 }
00989
00990
00991 Anp::AxisInfo::~AxisInfo()
00992 {
00993 }
00994
00995
00996 const std::string& Anp::AxisInfo::GetTitle() const
00997 {
00998 return fTitle;
00999 }
01000
01001
01002 double Anp::AxisInfo::GetMin() const
01003 {
01004 return fMin;
01005 }
01006
01007
01008 double Anp::AxisInfo::GetMax() const
01009 {
01010 return fMax;
01011 }
01012
01013
01014 int Anp::AxisInfo::GetNbins() const
01015 {
01016 return fNbins;
01017 }
01018
01019
01020 const std::vector<double>& Anp::AxisInfo::GetBins() const
01021 {
01022 return fBins;
01023 }
01024
01025
01026 bool Anp::AxisInfo::Valid() const
01027 {
01028 return fValid;
01029 }
01030
01031
01032 void Anp::AxisInfo::Print(std::ostream& o) const
01033 {
01034 o << "AxisInfo (" << fTitle << "): (nbin, min, max) = "
01035 << "(" << GetNbins() << ", " << GetMin() << ", " << GetMax() << ")" << std::endl;
01036 }
01037
01038
01039 ostream& Anp::operator<<(std::ostream& o, const Anp::AxisInfo &self)
01040 {
01041 self.Print(o);
01042 return o;
01043 }
01044
01045
01046 TH1* Anp::MakeTH1(const string &dir, TDirectory *dir_, const string &key)
01047 {
01048 TH1 *h = Anp::HistMan::Instance().CreateTH1(key, dir);
01049 if(h)
01050 {
01051 Anp::SetDir(h, dir_);
01052 }
01053
01054 return h;
01055 }
01056
01057
01058 TH2* Anp::MakeTH2(const string &dir, TDirectory *dir_, const string &key)
01059 {
01060 TH2 *h = Anp::HistMan::Instance().CreateTH2(key, dir);
01061 if(h)
01062 {
01063 Anp::SetDir(h, dir_);
01064 }
01065
01066 return h;
01067 }