Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:04:21

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