CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_5_3_1/src/DQM/CSCMonitorModule/src/CSCDQM_Collection.cc

Go to the documentation of this file.
00001 /*  =====================================================================================
00002  *
00003  *       Filename:  CSCDQM_Collection.cc
00004  *
00005  *    Description:  Histogram booking code
00006  *
00007  *        Version:  1.0
00008  *        Created:  04/18/2008 03:39:49 PM
00009  *       Revision:  none
00010  *       Compiler:  gcc
00011  *
00012  *         Author:  Valdas Rapsevicius (VR), Valdas.Rapsevicius@cern.ch
00013  *        Company:  CERN, CH
00014  *
00015  *  =====================================================================================
00016  */
00017 
00018 #include "DQM/CSCMonitorModule/interface/CSCDQM_Collection.h"
00019 #include <cstdio>
00020 
00021 namespace cscdqm {
00022 
00027   Collection::Collection(Configuration* const p_config) {
00028     config = p_config;
00029   }
00030 
00031   
00036   void Collection::load() {
00037 
00038     LOG_INFO << "Reading histograms from " << config->getBOOKING_XML_FILE();
00039 
00040     if (config->getBOOKING_XML_FILE().empty()) {
00041       return;
00042     }
00043 
00044     try {
00045 
00046       XMLPlatformUtils::Initialize();
00047 
00048       {
00049 
00050         XercesDOMParser parser;
00051 
00052         parser.setValidationScheme(XercesDOMParser::Val_Always);
00053         parser.setDoNamespaces(true);
00054         parser.setDoSchema(true);
00055         parser.setExitOnFirstFatalError(true);
00056         parser.setValidationConstraintFatal(true);
00057         XMLFileErrorHandler eh;
00058         parser.setErrorHandler(&eh);
00059 
00060         parser.parse(config->getBOOKING_XML_FILE().c_str());
00061         DOMDocument *doc = parser.getDocument();
00062         DOMNode *docNode = (DOMNode*) doc->getDocumentElement();
00063   
00064         DOMNodeList *itemList = docNode->getChildNodes();
00065 
00066         CoHisto definitions;
00067         for (uint32_t i = 0; i < itemList->getLength(); i++) {
00068   
00069           DOMNode* node = itemList->item(i);
00070           if (node->getNodeType() != DOMNode::ELEMENT_NODE) { continue; }
00071 
00072           std::string nodeName = XMLString::transcode(node->getNodeName());
00073 
00077           if (nodeName.compare(XML_BOOK_DEFINITION) == 0) {
00078 
00079             CoHistoProps dp;
00080             getNodeProperties(node, dp);
00081 
00082             DOMElement* el = dynamic_cast<DOMElement*>(node);
00083             std::string id(XMLString::transcode(el->getAttribute(XMLString::transcode(XML_BOOK_DEFINITION_ID))));
00084             definitions.insert(make_pair(id, dp));
00085 
00086           } else
00087 
00091           if (nodeName.compare(XML_BOOK_HISTOGRAM) == 0) {
00092   
00093             CoHistoProps hp;
00094 
00095             DOMElement* el = dynamic_cast<DOMElement*>(node);
00096             if (el->hasAttribute(XMLString::transcode(XML_BOOK_DEFINITION_REF))) {
00097               std::string id(XMLString::transcode(el->getAttribute(XMLString::transcode(XML_BOOK_DEFINITION_REF))));
00098               CoHistoProps d = definitions[id];
00099               for (CoHistoProps::iterator it = d.begin(); it != d.end(); it++) {
00100                 hp[it->first] = it->second;
00101               }
00102             }
00103 
00104             getNodeProperties(node, hp);
00105 
00106             std::string name   = hp[XML_BOOK_HISTO_NAME];
00107             std::string prefix = hp[XML_BOOK_HISTO_PREFIX];
00108 
00109             // Check if this histogram is an ON DEMAND histogram?
00110             hp[XML_BOOK_ONDEMAND] = (Utility::regexMatch(REGEXP_ONDEMAND, name) ? XML_BOOK_ONDEMAND_TRUE : XML_BOOK_ONDEMAND_FALSE );
00111 
00112             LOG_DEBUG << "[Collection::load] loading " << prefix << "::" << name << " XML_BOOK_ONDEMAND = " << hp[XML_BOOK_ONDEMAND]; 
00113   
00114             CoHistoMap::iterator it = collection.find(prefix);
00115             if (it == collection.end()) {
00116               CoHisto h;
00117               h[name] = hp;
00118               collection[prefix] = h; 
00119             } else {
00120               it->second.insert(make_pair(name, hp));
00121             }
00122 
00123           }
00124         }
00125 
00126       }
00127 
00128       XMLPlatformUtils::Terminate();
00129 
00130     } catch (XMLException& e) {
00131       char* message = XMLString::transcode(e.getMessage());
00132       throw Exception(message);
00133     }
00134 
00135     for (CoHistoMap::const_iterator i = collection.begin(); i != collection.end(); i++) {
00136       LOG_INFO << i->second.size() << " " << i->first << " histograms defined";
00137     }
00138     
00139   }
00140   
00148   void Collection::getNodeProperties(DOMNode*& node, CoHistoProps& p) {
00149     DOMNodeList *props  = node->getChildNodes();
00150     for(uint32_t j = 0; j < props->getLength(); j++) {
00151       DOMNode* node = props->item(j);
00152       if (node->getNodeType() != DOMNode::ELEMENT_NODE) { continue; }
00153       std::string name  = XMLString::transcode(node->getNodeName());
00154       std::string value = XMLString::transcode(node->getTextContent());
00155       DOMNamedNodeMap* attributes = node->getAttributes();
00156       if (attributes) {
00157         for (uint32_t i = 0; i < attributes->getLength(); i++) {
00158           DOMNode* attribute = attributes->item(i);
00159           std::string aname  = XMLString::transcode(attribute->getNodeName());
00160           std::string avalue = XMLString::transcode(attribute->getNodeValue());
00161           p[name + "_" + aname] = avalue;
00162         }
00163       }
00164       p[name] = value;
00165     }
00166   }
00167 
00175   const bool Collection::checkHistoValue(const CoHistoProps& h, const std::string& name, std::string& value) {
00176     CoHistoProps::const_iterator i = h.find(name);
00177     if(i == h.end()) {
00178       return false;
00179     }
00180     value = i->second;
00181     return true;
00182   }
00183   
00191   const bool Collection::checkHistoValue(const CoHistoProps& h, const std::string& name, int& value) {
00192     CoHistoProps::const_iterator i = h.find(name);
00193     if(i == h.end()) {
00194       return false;
00195     } 
00196     if(EOF == std::sscanf(i->second.c_str(), "%d", &value)) {
00197       return false;
00198     }
00199     return true;
00200   }
00201   
00210   const bool Collection::checkHistoValue(const CoHistoProps& h, const std::string name, double& value) {
00211     CoHistoProps::const_iterator i = h.find(name);
00212     if(i == h.end()) {
00213       return false;
00214     }
00215     if(EOF == std::sscanf(i->second.c_str(), "%lf", &value)) {
00216       return false;
00217     }
00218     return true;
00219   }
00220   
00229   std::string& Collection::getHistoValue(const CoHistoProps& h, const std::string& name, std::string& value, const std::string& def_value) {
00230     if (!checkHistoValue(h, name, value)) {
00231       value = def_value;
00232     }
00233     return value;
00234   }
00235   
00244   int& Collection::getHistoValue(const CoHistoProps& h, const std::string& name, int& value, const int& def_value) {
00245     if (!checkHistoValue(h, name, value)) {
00246       value = def_value;
00247     }
00248     return value;
00249   }
00250   
00259   double& Collection::getHistoValue(const CoHistoProps& h, const std::string name, double& value, const int def_value) {
00260     if (!checkHistoValue(h, name, value)) {
00261       value = def_value;
00262     }
00263     return value;
00264   }
00265   
00272   const int Collection::ParseAxisLabels(const std::string& s, std::map<int, std::string>& labels) {
00273     std::string tmp = s;
00274     std::string::size_type pos = tmp.find("|");
00275     char* stopstring = NULL;
00276   
00277     while (pos != std::string::npos) {
00278       std::string label_pair = tmp.substr(0, pos);
00279       tmp.replace(0, pos + 1, "");
00280       if (label_pair.find("=") != std::string::npos) {
00281         int nbin = strtol(label_pair.substr(0, label_pair.find("=")).c_str(), &stopstring, 10);
00282         std::string label = label_pair.substr(label_pair.find("=") + 1, label_pair.length());
00283         while (label.find("\'") != std::string::npos) {
00284           label.erase(label.find("\'"), 1);
00285         }
00286         labels[nbin] = label;
00287       }
00288       pos = tmp.find("|");
00289     }
00290     return labels.size();
00291   }
00292   
00297   void Collection::bookEMUHistos() const {
00298     CoHistoMap::const_iterator i = collection.find("EMU");
00299     if (i != collection.end()) {
00300       const CoHisto hs = i->second;
00301       for (CoHisto::const_iterator j = hs.begin(); j != hs.end(); j++) {
00302         std::string s = "";
00303         if (getHistoValue(j->second, XML_BOOK_ONDEMAND, s, XML_BOOK_ONDEMAND_FALSE) == XML_BOOK_ONDEMAND_FALSE) {
00304           HistoId hid = 0;
00305           if (HistoDef::getHistoIdByName(j->first, hid)) {
00306             EMUHistoDef hdef(hid);
00307             book(hdef, j->second, config->getFOLDER_EMU());
00308           }
00309         }
00310       }
00311     }
00312   }
00313 
00319   void Collection::bookFEDHistos(const HwId fedId) const {
00320     CoHistoMap::const_iterator i = collection.find("FED");
00321     if (i != collection.end()) {
00322       const CoHisto hs = i->second;
00323       for (CoHisto::const_iterator j = hs.begin(); j != hs.end(); j++) {
00324         std::string s = "";
00325         if (getHistoValue(j->second, XML_BOOK_ONDEMAND, s, XML_BOOK_ONDEMAND_FALSE) == XML_BOOK_ONDEMAND_FALSE) {
00326           HistoId hid = 0;
00327           if (HistoDef::getHistoIdByName(j->first, hid)) {
00328             FEDHistoDef hdef(hid, fedId);
00329             book(hdef, j->second, config->getFOLDER_FED());
00330           }
00331         }
00332       }
00333     }
00334   }   
00335 
00341   void Collection::bookDDUHistos(const HwId dduId) const {
00342     CoHistoMap::const_iterator i = collection.find("DDU");
00343     if (i != collection.end()) {
00344       const CoHisto hs = i->second;
00345       for (CoHisto::const_iterator j = hs.begin(); j != hs.end(); j++) {
00346         std::string s = "";
00347         if (getHistoValue(j->second, XML_BOOK_ONDEMAND, s, XML_BOOK_ONDEMAND_FALSE) == XML_BOOK_ONDEMAND_FALSE) {
00348           HistoId hid = 0;
00349           if (HistoDef::getHistoIdByName(j->first, hid)) {
00350             DDUHistoDef hdef(hid, dduId);
00351             book(hdef, j->second, config->getFOLDER_DDU());
00352           }
00353         }
00354       }
00355     }
00356   }
00357 
00364   void Collection::bookCSCHistos(const HwId crateId, const HwId dmbId) const {
00365     CoHistoMap::const_iterator i = collection.find("CSC");
00366     if (i != collection.end()) {
00367       const CoHisto hs = i->second;
00368       for (CoHisto::const_iterator j = hs.begin(); j != hs.end(); j++) {
00369         std::string s = "";
00370         HistoId hid = 0;
00371         if (HistoDef::getHistoIdByName(j->first, hid)) {
00372           if (getHistoValue(j->second, XML_BOOK_ONDEMAND, s, XML_BOOK_ONDEMAND_FALSE) == XML_BOOK_ONDEMAND_FALSE) {
00373             CSCHistoDef hdef(hid, crateId, dmbId);
00374             book(hdef, j->second, config->getFOLDER_CSC());
00375           } else {
00376             int from = 0, to = 0;
00377             if (checkHistoValue(j->second, XML_BOOK_NAME_FROM, from) && checkHistoValue(j->second, XML_BOOK_NAME_TO, to)) {
00378               for (int k = from; k <= to; k++) {
00379                 CSCHistoDef hdef(hid, crateId, dmbId, k);
00380                 book(hdef, j->second, config->getFOLDER_CSC());
00381               }
00382             }
00383           }
00384         }
00385       }
00386     }
00387   }
00388 
00397   void Collection::bookCSCHistos(const HistoId hid, const HwId crateId, const HwId dmbId, const HwId addId) const {
00398     CoHistoMap::const_iterator i = collection.find("CSC");
00399     if (i != collection.end()) {
00400       CoHisto::const_iterator j = i->second.find(h::names[hid]);
00401       if (j != i->second.end()) {
00402         CSCHistoDef hdef(hid, crateId, dmbId, addId);
00403         book(hdef, j->second, config->getFOLDER_CSC());
00404       }
00405     }
00406   }
00407 
00415   void Collection::book(const HistoDef& h, const CoHistoProps& p, const std::string& folder) const {
00416 
00417     MonitorObject* me = NULL;
00418     std::string name = h.getName(), type, title, s;
00419 
00421     if (!config->needBookMO(h.getFullPath())) {
00422       LOG_INFO << "MOFilter excluded " << name << " from booking"; 
00423       config->fnPutHisto(h, me);
00424       return;
00425     }
00426 
00427     int i1, i2, i3;
00428     double d1, d2, d3, d4, d5, d6;
00429     bool ondemand = (getHistoValue(p, XML_BOOK_ONDEMAND, s, XML_BOOK_ONDEMAND_FALSE) == XML_BOOK_ONDEMAND_TRUE ? true : false);
00430       
00431     if (!checkHistoValue(p, XML_BOOK_HISTO_TYPE, type))   { throw Exception("Histogram does not have type!"); }
00432     checkHistoValue(p, XML_BOOK_HISTO_TITLE, title);
00433 
00434     if (ondemand) {
00435       title = h.processTitle(title);
00436     }
00437 
00438     if (type == "h1") {
00439       me = config->fnBook(
00440         HistoBookRequest(h, H1D, type, folder, title,
00441           getHistoValue(p, "XBins", i1, 1),
00442           getHistoValue(p, "XMin",  d1, 0),
00443           getHistoValue(p, "XMax",  d2, 1)));
00444     } else
00445     if(type == "h2") {
00446       me = config->fnBook(
00447         HistoBookRequest(h, H2D, type, folder, title,
00448           getHistoValue(p, "XBins", i1, 1),
00449           getHistoValue(p, "XMin",  d1, 0),
00450           getHistoValue(p, "XMax",  d2, 1),
00451           getHistoValue(p, "YBins", i2, 1),
00452           getHistoValue(p, "YMin",  d3, 0),
00453           getHistoValue(p, "YMax",  d4, 1)));
00454     } else
00455     if(type == "h3") {
00456       me = config->fnBook(
00457         HistoBookRequest(h, H3D, type, folder, title,
00458           getHistoValue(p, "XBins", i1, 1),
00459           getHistoValue(p, "XMin",  d1, 0),
00460           getHistoValue(p, "XMax",  d2, 1),
00461           getHistoValue(p, "YBins", i2, 1),
00462           getHistoValue(p, "YMin",  d3, 0),
00463           getHistoValue(p, "YMax",  d4, 1),
00464           getHistoValue(p, "ZBins", i3, 1),
00465           getHistoValue(p, "ZMin",  d5, 0),
00466           getHistoValue(p, "ZMax",  d6, 1)));
00467     } else
00468     if(type == "hp") {
00469       me = config->fnBook(
00470         HistoBookRequest(h, PROFILE, type, folder, title,
00471           getHistoValue(p, "XBins", i1, 1),
00472           getHistoValue(p, "XMin",  d1, 0),
00473           getHistoValue(p, "XMax",  d2, 1)));
00474         /*
00475         HistoBookRequest(h, PROFILE, type, folder, title,
00476           getHistoValue(p, "XBins", i1, 1),
00477           getHistoValue(p, "XMin",  d1, 0),
00478           getHistoValue(p, "XMax",  d2, 1),
00479           getHistoValue(p, "YBins", i2, 1),
00480           getHistoValue(p, "YMin",  d3, 0),
00481           getHistoValue(p, "YMax",  d4, 1)));
00482         */
00483     } else
00484     if(type == "hp2") {
00485       me = config->fnBook(
00486         HistoBookRequest(h, PROFILE2D, type, folder, title,
00487           getHistoValue(p, "XBins", i1, 1),
00488           getHistoValue(p, "XMin",  d1, 0),
00489           getHistoValue(p, "XMax",  d2, 1),
00490           getHistoValue(p, "YBins", i2, 1),
00491           getHistoValue(p, "YMin",  d3, 0),
00492           getHistoValue(p, "YMax",  d4, 1),
00493           getHistoValue(p, "ZBins", i3, 1),
00494           getHistoValue(p, "ZMin",  d5, 0),
00495           getHistoValue(p, "ZMax",  d6, 1)));
00496     } else { 
00497       throw Exception("Can not book histogram with type: " + type);
00498     }
00499 
00500     if(me != NULL) {
00501 
00502       LockType lock(me->mutex);
00503       TH1 *th = me->getTH1Lock();
00504 
00505       if(checkHistoValue(p, "XTitle", s)) {
00506         if (ondemand) {
00507           s = h.processTitle(s);
00508         }
00509         me->setAxisTitle(s, 1);
00510       }
00511 
00512       if(checkHistoValue(p, "YTitle", s)) {
00513         if (ondemand) {
00514           s = h.processTitle(s);
00515         }
00516         me->setAxisTitle(s, 2);
00517       }
00518 
00519       if(checkHistoValue(p, "ZTitle", s)) {
00520         if (ondemand) {
00521           s = h.processTitle(s);
00522         }
00523           me->setAxisTitle(s, 3);
00524         }
00525 
00526       if(checkHistoValue(p, "SetOption", s)) th->SetOption(s.c_str());
00527       if(checkHistoValue(p, "SetStats", i1)) th->SetStats(i1);
00528       th->SetFillColor(getHistoValue(p, "SetFillColor", i1, DEF_HISTO_COLOR));
00529       if(checkHistoValue(p, "SetXLabels", s)) {
00530         std::map<int, std::string> labels;
00531         ParseAxisLabels(s, labels);
00532         for (std::map<int, std::string>::iterator l_itr = labels.begin(); l_itr != labels.end(); ++l_itr) {
00533           th->GetXaxis()->SetBinLabel(l_itr->first, l_itr->second.c_str());
00534         }
00535       }
00536       if(checkHistoValue(p, "SetYLabels", s)) {
00537         std::map<int, std::string> labels;
00538         ParseAxisLabels(s, labels);
00539         for (std::map<int, std::string>::iterator l_itr = labels.begin(); l_itr != labels.end(); ++l_itr) {
00540           th->GetYaxis()->SetBinLabel(l_itr->first, l_itr->second.c_str());
00541         }
00542       }
00543       if(checkHistoValue(p, "LabelOption", s)) {
00544         std::vector<std::string> v;
00545         if(2 == Utility::tokenize(s, v, ",")) {
00546           th->LabelsOption(v[0].c_str(), v[1].c_str());
00547         }
00548       }
00549       if(checkHistoValue(p, "SetLabelSize", s)) {
00550         std::vector<std::string> v;
00551         if(2 == Utility::tokenize(s, v, ",")) {
00552           th->SetLabelSize((double) atof(v[0].c_str()), v[1].c_str());
00553         }
00554       }
00555       if(checkHistoValue(p, "SetTitleOffset", s)) {
00556         std::vector<std::string> v;
00557         if(2 == Utility::tokenize(s, v, ",")) {
00558           th->SetTitleOffset((double) atof(v[0].c_str()), v[1].c_str());
00559         }
00560       }
00561       if(checkHistoValue(p, "SetMinimum", d1)) th->SetMinimum(d1);
00562       if(checkHistoValue(p, "SetMaximum", d1)) me->SetMaximum(d1);
00563       if(checkHistoValue(p, "SetNdivisionsX", i1)) {
00564         th->SetNdivisions(i1, "X");
00565         th->GetXaxis()->CenterLabels(true);
00566       }
00567       if(checkHistoValue(p, "SetNdivisionsY", i1)) {
00568         th->SetNdivisions(i1, "Y");
00569         th->GetYaxis()->CenterLabels(true);
00570       }
00571       if(checkHistoValue(p, "SetTickLengthX", d1)) th->SetTickLength(d1, "X");
00572       if(checkHistoValue(p, "SetTickLengthY", d1)) th->SetTickLength(d1, "Y");
00573       if(checkHistoValue(p, "SetLabelSizeX", d1)) th->SetLabelSize(d1, "X");
00574       if(checkHistoValue(p, "SetLabelSizeY", d1)) th->SetLabelSize(d1, "Y");
00575       if(checkHistoValue(p, "SetLabelSizeZ", d1)) th->SetLabelSize(d1, "Z");
00576       if(checkHistoValue(p, "SetErrorOption", s)) reinterpret_cast<TProfile*>(th)->SetErrorOption(s.c_str());
00577 
00578       lock.unlock();
00579 
00580     }
00581 
00582     LOG_DEBUG << "[Collection::book] booked " << h.getFullPath() << " (" << me << ")"; 
00583 
00585     config->fnPutHisto(h, me);
00586 
00587   }
00588 
00594   const bool Collection::isOnDemand(const HistoName& name) const {
00595     CoHistoMap::const_iterator i = collection.find("CSC");
00596     if (i != collection.end()) {
00597       CoHisto hs  = i->second;
00598       CoHisto::const_iterator j = hs.find(name);
00599       if (j != hs.end()) { 
00600         std::string s;
00601         return (getHistoValue(j->second, XML_BOOK_ONDEMAND, s, XML_BOOK_ONDEMAND_FALSE) == XML_BOOK_ONDEMAND_TRUE);
00602       }
00603     }
00604     return false;
00605   }
00606 
00611   void Collection::printCollection() const{
00612 
00613     std::ostringstream buffer;
00614     for(CoHistoMap::const_iterator hdmi = collection.begin(); hdmi != collection.end(); hdmi++) {
00615       buffer << hdmi->first << " [" << std::endl;
00616       for(CoHisto::const_iterator hdi = hdmi->second.begin(); hdi != hdmi->second.end(); hdi++) {
00617         buffer << "   " << hdi->first << " [" << std::endl;
00618         for(CoHistoProps::const_iterator hi = hdi->second.begin(); hi != hdi->second.end(); hi++) {
00619           buffer << "     " << hi->first << " = " << hi->second << std::endl;
00620         }
00621         buffer << "   ]" << std::endl;
00622       }
00623       buffer << " ]" << std::endl;
00624     }
00625     LOG_INFO << buffer.str();
00626   }
00627 
00628 }