Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2025-03-10 23:53:23

0001 #ifndef MEtoEDMFormat_h
0002 #define MEtoEDMFormat_h
0003 
0004 /** \class MEtoEDM
0005  *  
0006  *  DataFormat class to hold the information from a ME tranformed into
0007  *  ROOT objects as appropriate
0008  *
0009  *  \author M. Strang SUNY-Buffalo
0010  */
0011 
0012 #include <TClass.h>
0013 #include <TObject.h>
0014 #include <TH1F.h>
0015 #include <TH1S.h>
0016 #include <TH1D.h>
0017 #include <TH2F.h>
0018 #include <TH2S.h>
0019 #include <TH2D.h>
0020 #include <TH2Poly.h>
0021 #include <TH3F.h>
0022 #include <TProfile.h>
0023 #include <TProfile2D.h>
0024 #include <TObjString.h>
0025 #include <TString.h>
0026 #include <THashList.h>
0027 #include <TList.h>
0028 
0029 #include <iostream>
0030 #include <string>
0031 #include <vector>
0032 #include <memory>
0033 #include <map>
0034 #include <cstdint>
0035 
0036 #define METOEDMFORMAT_DEBUG 0
0037 
0038 template <class T>
0039 class MEtoEDM {
0040 public:
0041   MEtoEDM() {}
0042   explicit MEtoEDM(size_t reservedSize) { MEtoEdmObject.reserve(reservedSize); }
0043   virtual ~MEtoEDM() {}
0044 
0045   typedef std::vector<uint32_t> TagList;
0046 
0047   struct MEtoEDMObject {
0048     std::string name;
0049     TagList tags;
0050     T object;
0051   };
0052 
0053   typedef std::vector<MEtoEDMObject> MEtoEdmObjectVector;
0054 
0055   void putMEtoEdmObject(const std::string &name, const T &object) {
0056     typename MEtoEdmObjectVector::value_type temp;
0057     MEtoEdmObject.push_back(temp);
0058     MEtoEdmObject.back().name = name;
0059     MEtoEdmObject.back().object = object;
0060   }
0061 
0062   const MEtoEdmObjectVector &getMEtoEdmObject() const { return MEtoEdmObject; }
0063 
0064   bool CheckBinLabels(const TAxis *a1, const TAxis *a2) {
0065     // check that axis have same labels
0066     THashList *l1 = (const_cast<TAxis *>(a1))->GetLabels();
0067     THashList *l2 = (const_cast<TAxis *>(a2))->GetLabels();
0068 
0069     if (!l1 && !l2)
0070       return true;
0071     if (!l1 || !l2) {
0072       return false;
0073     }
0074     // check now labels sizes  are the same
0075     if (l1->GetSize() != l2->GetSize()) {
0076       return false;
0077     }
0078     for (int i = 1; i <= a1->GetNbins(); ++i) {
0079       TString label1 = a1->GetBinLabel(i);
0080       TString label2 = a2->GetBinLabel(i);
0081       if (label1 != label2) {
0082         return false;
0083       }
0084     }
0085     return true;
0086   }
0087 
0088   bool mergeProduct(const MEtoEDM<T> &newMEtoEDM) {
0089     const MEtoEdmObjectVector &newMEtoEDMObject = newMEtoEDM.getMEtoEdmObject();
0090     const size_t nObjects = newMEtoEDMObject.size();
0091     //  NOTE: we remember the present size since we will only add content
0092     //        from newMEtoEDMObject after this point
0093     const size_t nOldObjects = MEtoEdmObject.size();
0094 
0095     // if the old and new are not the same size, we want to report a problem
0096     if (nObjects != nOldObjects) {
0097       std::cout << "WARNING MEtoEDM::mergeProducts(): the lists of histograms to be merged have different sizes: new="
0098                 << nObjects << ", old=" << nOldObjects << std::endl;
0099     }
0100 
0101     for (unsigned int i = 0; i < nObjects; ++i) {
0102       unsigned int j = 0;
0103       // see if the name is already in the old container up to the point where
0104       // we may have added new entries in the container
0105       const std::string &name = newMEtoEDMObject[i].name;
0106       if (i < nOldObjects && (MEtoEdmObject[i].name == name)) {
0107         j = i;
0108       } else {
0109         j = 0;
0110         while (j < nOldObjects && (MEtoEdmObject[j].name != name))
0111           ++j;
0112       }
0113       if (j >= nOldObjects) {
0114         // this value is only in the new container, not the old one
0115 #if METOEDMFORMAT_DEBUG
0116         std::cout << "WARNING MEtoEDM::mergeProducts(): adding new histogram '" << name << "'" << std::endl;
0117 #endif
0118         MEtoEdmObject.push_back(newMEtoEDMObject[i]);
0119       } else if (MEtoEdmObject[j].object.CanExtendAllAxes() && newMEtoEDMObject[i].object.CanExtendAllAxes()) {
0120         TList list;
0121         list.Add((TObject *)&newMEtoEDMObject[i].object);
0122         if (MEtoEdmObject[j].object.Merge(&list) == -1) {
0123           std::cout << "ERROR MEtoEDM::mergeProducts(): merge failed for '" << name << "'" << std::endl;
0124         }
0125       } else {
0126         // this value is also in the new container: add the two
0127         if (MEtoEdmObject[j].object.GetNbinsX() == newMEtoEDMObject[i].object.GetNbinsX() &&
0128             MEtoEdmObject[j].object.GetXaxis()->GetXmin() == newMEtoEDMObject[i].object.GetXaxis()->GetXmin() &&
0129             MEtoEdmObject[j].object.GetXaxis()->GetXmax() == newMEtoEDMObject[i].object.GetXaxis()->GetXmax() &&
0130             MEtoEdmObject[j].object.GetNbinsY() == newMEtoEDMObject[i].object.GetNbinsY() &&
0131             MEtoEdmObject[j].object.GetYaxis()->GetXmin() == newMEtoEDMObject[i].object.GetYaxis()->GetXmin() &&
0132             MEtoEdmObject[j].object.GetYaxis()->GetXmax() == newMEtoEDMObject[i].object.GetYaxis()->GetXmax() &&
0133             MEtoEdmObject[j].object.GetNbinsZ() == newMEtoEDMObject[i].object.GetNbinsZ() &&
0134             MEtoEdmObject[j].object.GetZaxis()->GetXmin() == newMEtoEDMObject[i].object.GetZaxis()->GetXmin() &&
0135             MEtoEdmObject[j].object.GetZaxis()->GetXmax() == newMEtoEDMObject[i].object.GetZaxis()->GetXmax() &&
0136             CheckBinLabels((TAxis *)MEtoEdmObject[j].object.GetXaxis(),
0137                            (TAxis *)newMEtoEDMObject[i].object.GetXaxis()) &&
0138             CheckBinLabels((TAxis *)MEtoEdmObject[j].object.GetYaxis(),
0139                            (TAxis *)newMEtoEDMObject[i].object.GetYaxis()) &&
0140             CheckBinLabels((TAxis *)MEtoEdmObject[j].object.GetZaxis(),
0141                            (TAxis *)newMEtoEDMObject[i].object.GetZaxis())) {
0142           MEtoEdmObject[j].object.Add(&newMEtoEDMObject[i].object, 1.);
0143         } else {
0144           std::cout
0145               << "ERROR MEtoEDM::mergeProducts(): found histograms with different axis limits or different labels, '"
0146               << name << "' not merged" << std::endl;
0147 #if METOEDMFORMAT_DEBUG
0148           std::cout << MEtoEdmObject[j].name << " " << newMEtoEDMObject[i].name << std::endl;
0149           std::cout << MEtoEdmObject[j].object.GetNbinsX() << " " << newMEtoEDMObject[i].object.GetNbinsX()
0150                     << std::endl;
0151           std::cout << MEtoEdmObject[j].object.GetXaxis()->GetXmin() << " "
0152                     << newMEtoEDMObject[i].object.GetXaxis()->GetXmin() << std::endl;
0153           std::cout << MEtoEdmObject[j].object.GetXaxis()->GetXmax() << " "
0154                     << newMEtoEDMObject[i].object.GetXaxis()->GetXmax() << std::endl;
0155           std::cout << MEtoEdmObject[j].object.GetNbinsY() << " " << newMEtoEDMObject[i].object.GetNbinsY()
0156                     << std::endl;
0157           std::cout << MEtoEdmObject[j].object.GetYaxis()->GetXmin() << " "
0158                     << newMEtoEDMObject[i].object.GetYaxis()->GetXmin() << std::endl;
0159           std::cout << MEtoEdmObject[j].object.GetYaxis()->GetXmax() << " "
0160                     << newMEtoEDMObject[i].object.GetYaxis()->GetXmax() << std::endl;
0161           std::cout << MEtoEdmObject[j].object.GetNbinsZ() << " " << newMEtoEDMObject[i].object.GetNbinsZ()
0162                     << std::endl;
0163           std::cout << MEtoEdmObject[j].object.GetZaxis()->GetXmin() << " "
0164                     << newMEtoEDMObject[i].object.GetZaxis()->GetXmin() << std::endl;
0165           std::cout << MEtoEdmObject[j].object.GetZaxis()->GetXmax() << " "
0166                     << newMEtoEDMObject[i].object.GetZaxis()->GetXmax() << std::endl;
0167 #endif
0168         }
0169       }
0170     }
0171     return true;
0172   }
0173 
0174   void swap(MEtoEDM<T> &iOther) { MEtoEdmObject.swap(iOther.MEtoEdmObject); }
0175 
0176 private:
0177   MEtoEdmObjectVector MEtoEdmObject;
0178 
0179 };  // end class declaration
0180 
0181 template <>
0182 inline bool MEtoEDM<double>::mergeProduct(const MEtoEDM<double> &newMEtoEDM) {
0183   const MEtoEdmObjectVector &newMEtoEDMObject = newMEtoEDM.getMEtoEdmObject();
0184   const size_t nObjects = newMEtoEDMObject.size();
0185   //  NOTE: we remember the present size since we will only add content
0186   //        from newMEtoEDMObject after this point
0187   const size_t nOldObjects = MEtoEdmObject.size();
0188 
0189   // if the old and new are not the same size, we want to report a problem
0190   if (nObjects != nOldObjects) {
0191     std::cout << "WARNING MEtoEDM::mergeProducts(): the lists of histograms to be merged have different sizes: new="
0192               << nObjects << ", old=" << nOldObjects << std::endl;
0193   }
0194 
0195   for (unsigned int i = 0; i < nObjects; ++i) {
0196     unsigned int j = 0;
0197     // see if the name is already in the old container up to the point where
0198     // we may have added new entries in the container
0199     const std::string &name = newMEtoEDMObject[i].name;
0200     if (i < nOldObjects && (MEtoEdmObject[i].name == name)) {
0201       j = i;
0202     } else {
0203       j = 0;
0204       while (j < nOldObjects && (MEtoEdmObject[j].name != name))
0205         ++j;
0206     }
0207     if (j >= nOldObjects) {
0208       // this value is only in the new container, not the old one
0209 #if METOEDMFORMAT_DEBUG
0210       std::cout << "WARNING MEtoEDM::mergeProducts(): adding new histogram '" << name << "'" << std::endl;
0211 #endif
0212       MEtoEdmObject.push_back(newMEtoEDMObject[i]);
0213     }
0214   }
0215   return true;
0216 }
0217 
0218 template <>
0219 inline bool MEtoEDM<int>::mergeProduct(const MEtoEDM<int> &newMEtoEDM) {
0220   const MEtoEdmObjectVector &newMEtoEDMObject = newMEtoEDM.getMEtoEdmObject();
0221   const size_t nObjects = newMEtoEDMObject.size();
0222   //  NOTE: we remember the present size since we will only add content
0223   //        from newMEtoEDMObject after this point
0224   const size_t nOldObjects = MEtoEdmObject.size();
0225 
0226   // if the old and new are not the same size, we want to report a problem
0227   if (nObjects != nOldObjects) {
0228     std::cout << "WARNING MEtoEDM::mergeProducts(): the lists of histograms to be merged have different sizes: new="
0229               << nObjects << ", old=" << nOldObjects << std::endl;
0230   }
0231 
0232   for (unsigned int i = 0; i < nObjects; ++i) {
0233     unsigned int j = 0;
0234     // see if the name is already in the old container up to the point where
0235     // we may have added new entries in the container
0236     const std::string &name = newMEtoEDMObject[i].name;
0237     if (i < nOldObjects && (MEtoEdmObject[i].name == name)) {
0238       j = i;
0239     } else {
0240       j = 0;
0241       while (j < nOldObjects && (MEtoEdmObject[j].name != name))
0242         ++j;
0243     }
0244     if (j >= nOldObjects) {
0245       // this value is only in the new container, not the old one
0246 #if METOEDMFORMAT_DEBUG
0247       std::cout << "WARNING MEtoEDM::mergeProducts(): adding new histogram '" << name << "'" << std::endl;
0248 #endif
0249       MEtoEdmObject.push_back(newMEtoEDMObject[i]);
0250     } else {
0251       // this value is also in the new container: add the two
0252       if (MEtoEdmObject[j].name.find("EventInfo/processedEvents") != std::string::npos) {
0253         MEtoEdmObject[j].object += (newMEtoEDMObject[i].object);
0254       }
0255       if (MEtoEdmObject[j].name.find("EventInfo/iEvent") != std::string::npos ||
0256           MEtoEdmObject[j].name.find("EventInfo/iLumiSection") != std::string::npos) {
0257         if (MEtoEdmObject[j].object < newMEtoEDMObject[i].object) {
0258           MEtoEdmObject[j].object = (newMEtoEDMObject[i].object);
0259         }
0260       }
0261     }
0262   }
0263   return true;
0264 }
0265 
0266 template <>
0267 inline bool MEtoEDM<long long>::mergeProduct(const MEtoEDM<long long> &newMEtoEDM) {
0268   const MEtoEdmObjectVector &newMEtoEDMObject = newMEtoEDM.getMEtoEdmObject();
0269   const size_t nObjects = newMEtoEDMObject.size();
0270   //  NOTE: we remember the present size since we will only add content
0271   //        from newMEtoEDMObject after this point
0272   const size_t nOldObjects = MEtoEdmObject.size();
0273 
0274   // if the old and new are not the same size, we want to report a problem
0275   if (nObjects != nOldObjects) {
0276     std::cout << "WARNING MEtoEDM::mergeProducts(): the lists of histograms to be merged have different sizes: new="
0277               << nObjects << ", old=" << nOldObjects << std::endl;
0278   }
0279 
0280   for (unsigned int i = 0; i < nObjects; ++i) {
0281     unsigned int j = 0;
0282     // see if the name is already in the old container up to the point where
0283     // we may have added new entries in the container
0284     const std::string &name = newMEtoEDMObject[i].name;
0285     if (i < nOldObjects && (MEtoEdmObject[i].name == name)) {
0286       j = i;
0287     } else {
0288       j = 0;
0289       while (j < nOldObjects && (MEtoEdmObject[j].name != name))
0290         ++j;
0291     }
0292     if (j >= nOldObjects) {
0293       // this value is only in the new container, not the old one
0294 #if METOEDMFORMAT_DEBUG
0295       std::cout << "WARNING MEtoEDM::mergeProducts(): adding new histogram '" << name << "'" << std::endl;
0296 #endif
0297       MEtoEdmObject.push_back(newMEtoEDMObject[i]);
0298     } else {
0299       // this value is also in the new container: add the two
0300       if (MEtoEdmObject[j].name.find("EventInfo/processedEvents") != std::string::npos) {
0301         MEtoEdmObject[j].object += (newMEtoEDMObject[i].object);
0302       }
0303       if (MEtoEdmObject[j].name.find("EventInfo/iEvent") != std::string::npos ||
0304           MEtoEdmObject[j].name.find("EventInfo/iLumiSection") != std::string::npos) {
0305         if (MEtoEdmObject[j].object < newMEtoEDMObject[i].object) {
0306           MEtoEdmObject[j].object = (newMEtoEDMObject[i].object);
0307         }
0308       }
0309     }
0310   }
0311   return true;
0312 }
0313 
0314 template <>
0315 inline bool MEtoEDM<TString>::mergeProduct(const MEtoEDM<TString> &newMEtoEDM) {
0316   const MEtoEdmObjectVector &newMEtoEDMObject = newMEtoEDM.getMEtoEdmObject();
0317   const size_t nObjects = newMEtoEDMObject.size();
0318   //  NOTE: we remember the present size since we will only add content
0319   //        from newMEtoEDMObject after this point
0320   const size_t nOldObjects = MEtoEdmObject.size();
0321 
0322   // if the old and new are not the same size, we want to report a problem
0323   if (nObjects != nOldObjects) {
0324     std::cout << "WARNING MEtoEDM::mergeProducts(): the lists of histograms to be merged have different sizes: new="
0325               << nObjects << ", old=" << nOldObjects << std::endl;
0326   }
0327 
0328   for (unsigned int i = 0; i < nObjects; ++i) {
0329     unsigned int j = 0;
0330     // see if the name is already in the old container up to the point where
0331     // we may have added new entries in the container
0332     const std::string &name = newMEtoEDMObject[i].name;
0333     if (i < nOldObjects && (MEtoEdmObject[i].name == name)) {
0334       j = i;
0335     } else {
0336       j = 0;
0337       while (j < nOldObjects && (MEtoEdmObject[j].name != name))
0338         ++j;
0339     }
0340     if (j >= nOldObjects) {
0341       // this value is only in the new container, not the old one
0342 #if METOEDMFORMAT_DEBUG
0343       std::cout << "WARNING MEtoEDM::mergeProducts(): adding new histogram '" << name << "'" << std::endl;
0344 #endif
0345       MEtoEdmObject.push_back(newMEtoEDMObject[i]);
0346     }
0347   }
0348   return true;
0349 }
0350 
0351 #endif