CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_1_8_patch13/src/DataFormats/Histograms/interface/MEtoEDMFormat.h

Go to the documentation of this file.
00001 #ifndef MEtoEDMFormat_h
00002 #define MEtoEDMFormat_h
00003 
00014 #include <TObject.h>
00015 #include <TH1F.h>
00016 #include <TH1S.h>
00017 #include <TH1D.h>
00018 #include <TH2F.h>
00019 #include <TH2S.h>
00020 #include <TH2D.h>
00021 #include <TH3F.h>
00022 #include <TProfile.h>
00023 #include <TProfile2D.h>
00024 #include <TObjString.h>
00025 #include <TString.h>
00026 #include <TList.h>
00027 
00028 #include <string>
00029 #include <vector>
00030 #include <memory>
00031 #include <map>
00032 #include <stdint.h>
00033 
00034 #define debug 0
00035 
00036 template <class T>
00037 class MEtoEDM
00038 {
00039  public:
00040   MEtoEDM() {}
00041   explicit MEtoEDM(size_t reservedSize) {
00042     MEtoEdmObject.reserve(reservedSize);
00043   }
00044   virtual ~MEtoEDM() {}
00045 
00046   typedef std::vector<uint32_t> TagList;
00047 
00048   struct MEtoEDMObject
00049   {
00050     std::string name;
00051     TagList     tags;
00052     T           object;
00053   };
00054 
00055   typedef std::vector<MEtoEDMObject> MEtoEdmObjectVector;
00056 
00057   void putMEtoEdmObject(const std::string &name,
00058                         const TagList &tags,
00059                         const T &object)
00060     {
00061       typename MEtoEdmObjectVector::value_type temp;
00062       MEtoEdmObject.push_back(temp);
00063       MEtoEdmObject.back().name = name;
00064       MEtoEdmObject.back().tags = tags;
00065       MEtoEdmObject.back().object = object;
00066     }
00067 
00068   const MEtoEdmObjectVector & getMEtoEdmObject() const
00069     { return MEtoEdmObject; }
00070 
00071   bool mergeProduct(const MEtoEDM<T> &newMEtoEDM) {
00072     const MEtoEdmObjectVector &newMEtoEDMObject = newMEtoEDM.getMEtoEdmObject();
00073     const size_t nObjects = newMEtoEDMObject.size();
00074     //  NOTE: we remember the present size since we will only add content
00075     //        from newMEtoEDMObject after this point
00076     const size_t nOldObjects = MEtoEdmObject.size();
00077 
00078    // if the old and new are not the same size, we want to report a problem
00079    if (nObjects != nOldObjects) {
00080      std::cout << "WARNING MEtoEDM::mergeProducts(): the lists of histograms to be merged have different sizes: new=" << nObjects << ", old=" << nOldObjects << std::endl;
00081    }
00082 
00083    for (unsigned int i = 0; i < nObjects; ++i) {
00084      unsigned int j = 0;
00085      // see if the name is already in the old container up to the point where
00086      // we may have added new entries in the container
00087      const std::string& name = newMEtoEDMObject[i].name;
00088      if (i < nOldObjects && (MEtoEdmObject[i].name == name)) {
00089        j = i;
00090      } else {
00091        j = 0;
00092        while (j <  nOldObjects && (MEtoEdmObject[j].name != name) ) ++j;
00093      }
00094      if (j >= nOldObjects) {
00095        // this value is only in the new container, not the old one
00096 #if debug
00097        std::cout << "WARNING MEtoEDM::mergeProducts(): adding new histogram '" << name << "'" << std::endl;
00098 #endif
00099        MEtoEdmObject.push_back(newMEtoEDMObject[i]);
00100      } else if (MEtoEdmObject[j].object.TestBit(TH1::kCanRebin) == true && newMEtoEDMObject[i].object.TestBit(TH1::kCanRebin) == true) {
00101        TList list;
00102        list.Add((TObject*)&newMEtoEDMObject[i].object);
00103        if (MEtoEdmObject[j].object.Merge(&list) == -1) {
00104          std::cout << "ERROR MEtoEDM::mergeProducts(): merge failed for '" << name << "'" <<  std::endl;
00105        }
00106      } else {
00107        // this value is also in the new container: add the two 
00108        if (MEtoEdmObject[j].object.GetNbinsX()           == newMEtoEDMObject[i].object.GetNbinsX()           &&
00109            MEtoEdmObject[j].object.GetXaxis()->GetXmin() == newMEtoEDMObject[i].object.GetXaxis()->GetXmin() &&
00110            MEtoEdmObject[j].object.GetXaxis()->GetXmax() == newMEtoEDMObject[i].object.GetXaxis()->GetXmax() &&
00111            MEtoEdmObject[j].object.GetNbinsY()           == newMEtoEDMObject[i].object.GetNbinsY()           &&
00112            MEtoEdmObject[j].object.GetYaxis()->GetXmin() == newMEtoEDMObject[i].object.GetYaxis()->GetXmin() &&
00113            MEtoEdmObject[j].object.GetYaxis()->GetXmax() == newMEtoEDMObject[i].object.GetYaxis()->GetXmax() &&
00114            MEtoEdmObject[j].object.GetNbinsZ()           == newMEtoEDMObject[i].object.GetNbinsZ()           &&
00115            MEtoEdmObject[j].object.GetZaxis()->GetXmin() == newMEtoEDMObject[i].object.GetZaxis()->GetXmin() &&
00116            MEtoEdmObject[j].object.GetZaxis()->GetXmax() == newMEtoEDMObject[i].object.GetZaxis()->GetXmax()) {
00117          MEtoEdmObject[j].object.Add(&newMEtoEDMObject[i].object);
00118        } else {
00119           std::cout << "ERROR MEtoEDM::mergeProducts(): found histograms with different axis limits, '" << name << "' not merged" <<  std::endl;
00120 #if debug
00121           std::cout << MEtoEdmObject[j].name                         << " " << newMEtoEDMObject[i].name                         << std::endl;
00122           std::cout << MEtoEdmObject[j].object.GetNbinsX()           << " " << newMEtoEDMObject[i].object.GetNbinsX()           << std::endl;
00123           std::cout << MEtoEdmObject[j].object.GetXaxis()->GetXmin() << " " << newMEtoEDMObject[i].object.GetXaxis()->GetXmin() << std::endl;
00124           std::cout << MEtoEdmObject[j].object.GetXaxis()->GetXmax() << " " << newMEtoEDMObject[i].object.GetXaxis()->GetXmax() << std::endl;
00125           std::cout << MEtoEdmObject[j].object.GetNbinsY()           << " " << newMEtoEDMObject[i].object.GetNbinsY()           << std::endl;
00126           std::cout << MEtoEdmObject[j].object.GetYaxis()->GetXmin() << " " << newMEtoEDMObject[i].object.GetYaxis()->GetXmin() << std::endl;
00127           std::cout << MEtoEdmObject[j].object.GetYaxis()->GetXmax() << " " << newMEtoEDMObject[i].object.GetYaxis()->GetXmax() << std::endl;
00128           std::cout << MEtoEdmObject[j].object.GetNbinsZ()           << " " << newMEtoEDMObject[i].object.GetNbinsZ()           << std::endl;
00129           std::cout << MEtoEdmObject[j].object.GetZaxis()->GetXmin() << " " << newMEtoEDMObject[i].object.GetZaxis()->GetXmin() << std::endl;
00130           std::cout << MEtoEdmObject[j].object.GetZaxis()->GetXmax() << " " << newMEtoEDMObject[i].object.GetZaxis()->GetXmax() << std::endl;
00131 #endif
00132        }
00133      }
00134    }
00135    return true;
00136   }
00137 
00138   void swap(MEtoEDM<T>& iOther) {
00139     MEtoEdmObject.swap(iOther.MEtoEdmObject);
00140   }
00141  private:
00142 
00143   MEtoEdmObjectVector MEtoEdmObject;
00144 
00145 }; // end class declaration
00146 
00147 template <>
00148 inline bool
00149 MEtoEDM<double>::mergeProduct(const MEtoEDM<double> &newMEtoEDM)
00150 {
00151   const MEtoEdmObjectVector &newMEtoEDMObject = newMEtoEDM.getMEtoEdmObject();
00152   const size_t nObjects = newMEtoEDMObject.size();
00153   //  NOTE: we remember the present size since we will only add content
00154   //        from newMEtoEDMObject after this point
00155   const size_t nOldObjects = MEtoEdmObject.size();
00156 
00157   // if the old and new are not the same size, we want to report a problem
00158   if (nObjects != nOldObjects) {
00159     std::cout << "WARNING MEtoEDM::mergeProducts(): the lists of histograms to be merged have different sizes: new=" << nObjects << ", old=" << nOldObjects << std::endl;
00160   }
00161 
00162   for (unsigned int i = 0; i < nObjects; ++i) {
00163     unsigned int j = 0;
00164     // see if the name is already in the old container up to the point where
00165     // we may have added new entries in the container
00166     const std::string& name = newMEtoEDMObject[i].name;
00167     if (i < nOldObjects && (MEtoEdmObject[i].name == name)) {
00168       j = i;
00169     } else {
00170       j = 0;
00171       while (j <  nOldObjects && (MEtoEdmObject[j].name != name) ) ++j;
00172     }
00173     if (j >= nOldObjects) {
00174       // this value is only in the new container, not the old one
00175 #if debug
00176       std::cout << "WARNING MEtoEDM::mergeProducts(): adding new histogram '" << name << "'" << std::endl;
00177 #endif
00178       MEtoEdmObject.push_back(newMEtoEDMObject[i]);
00179     }
00180   }
00181   return true;
00182 }
00183 
00184 template <>
00185 inline bool
00186 MEtoEDM<int>::mergeProduct(const MEtoEDM<int> &newMEtoEDM)
00187 {
00188   const MEtoEdmObjectVector &newMEtoEDMObject = newMEtoEDM.getMEtoEdmObject();
00189   const size_t nObjects = newMEtoEDMObject.size();
00190   //  NOTE: we remember the present size since we will only add content
00191   //        from newMEtoEDMObject after this point
00192   const size_t nOldObjects = MEtoEdmObject.size();
00193 
00194   // if the old and new are not the same size, we want to report a problem
00195   if (nObjects != nOldObjects) {
00196     std::cout << "WARNING MEtoEDM::mergeProducts(): the lists of histograms to be merged have different sizes: new=" << nObjects << ", old=" << nOldObjects << std::endl;
00197   }
00198 
00199   for (unsigned int i = 0; i < nObjects; ++i) {
00200     unsigned int j = 0;
00201     // see if the name is already in the old container up to the point where
00202     // we may have added new entries in the container
00203     const std::string& name = newMEtoEDMObject[i].name;
00204     if (i < nOldObjects && (MEtoEdmObject[i].name == name)) {
00205       j = i;
00206     } else {
00207       j = 0;
00208       while (j <  nOldObjects && (MEtoEdmObject[j].name != name) ) ++j;
00209     }
00210     if (j >= nOldObjects) {
00211       // this value is only in the new container, not the old one
00212 #if debug
00213       std::cout << "WARNING MEtoEDM::mergeProducts(): adding new histogram '" << name << "'" << std::endl;
00214 #endif
00215       MEtoEdmObject.push_back(newMEtoEDMObject[i]);
00216     } else {
00217       // this value is also in the new container: add the two
00218       if ( MEtoEdmObject[j].name.find("EventInfo/processedEvents") != std::string::npos ) {
00219         MEtoEdmObject[j].object += (newMEtoEDMObject[i].object);
00220       }
00221       if ( MEtoEdmObject[j].name.find("EventInfo/iEvent") != std::string::npos ||
00222            MEtoEdmObject[j].name.find("EventInfo/iLumiSection") != std::string::npos) {
00223         if (MEtoEdmObject[j].object < newMEtoEDMObject[i].object) {
00224           MEtoEdmObject[j].object = (newMEtoEDMObject[i].object);
00225         }
00226       }
00227     }
00228   }
00229   return true;
00230 }
00231 
00232 template <>
00233 inline bool
00234 MEtoEDM<long long>::mergeProduct(const MEtoEDM<long long> &newMEtoEDM)
00235 {
00236   const MEtoEdmObjectVector &newMEtoEDMObject = newMEtoEDM.getMEtoEdmObject();
00237   const size_t nObjects = newMEtoEDMObject.size();
00238   //  NOTE: we remember the present size since we will only add content
00239   //        from newMEtoEDMObject after this point
00240   const size_t nOldObjects = MEtoEdmObject.size();
00241 
00242   // if the old and new are not the same size, we want to report a problem
00243   if (nObjects != nOldObjects) {
00244     std::cout << "WARNING MEtoEDM::mergeProducts(): the lists of histograms to be merged have different sizes: new=" << nObjects << ", old=" << nOldObjects << std::endl;
00245   }
00246 
00247   for (unsigned int i = 0; i < nObjects; ++i) {
00248     unsigned int j = 0;
00249     // see if the name is already in the old container up to the point where
00250     // we may have added new entries in the container
00251     const std::string& name = newMEtoEDMObject[i].name;
00252     if (i < nOldObjects && (MEtoEdmObject[i].name == name)) {
00253       j = i;
00254     } else {
00255       j = 0;
00256       while (j <  nOldObjects && (MEtoEdmObject[j].name != name) ) ++j;
00257     }
00258     if (j >= nOldObjects) {
00259       // this value is only in the new container, not the old one
00260 #if debug
00261       std::cout << "WARNING MEtoEDM::mergeProducts(): adding new histogram '" << name << "'" << std::endl;
00262 #endif
00263       MEtoEdmObject.push_back(newMEtoEDMObject[i]);
00264     } else {
00265       // this value is also in the new container: add the two
00266       if ( MEtoEdmObject[j].name.find("EventInfo/processedEvents") != std::string::npos ) {
00267         MEtoEdmObject[j].object += (newMEtoEDMObject[i].object);
00268       }
00269       if ( MEtoEdmObject[j].name.find("EventInfo/iEvent") != std::string::npos ||
00270            MEtoEdmObject[j].name.find("EventInfo/iLumiSection") != std::string::npos) {
00271         if (MEtoEdmObject[j].object < newMEtoEDMObject[i].object) {
00272           MEtoEdmObject[j].object = (newMEtoEDMObject[i].object);
00273         }
00274       }
00275     }
00276   }
00277   return true;
00278 }
00279 
00280 template <>
00281 inline bool
00282 MEtoEDM<TString>::mergeProduct(const MEtoEDM<TString> &newMEtoEDM)
00283 {
00284   const MEtoEdmObjectVector &newMEtoEDMObject = newMEtoEDM.getMEtoEdmObject();
00285   const size_t nObjects = newMEtoEDMObject.size();
00286   //  NOTE: we remember the present size since we will only add content
00287   //        from newMEtoEDMObject after this point
00288   const size_t nOldObjects = MEtoEdmObject.size();
00289 
00290   // if the old and new are not the same size, we want to report a problem
00291   if (nObjects != nOldObjects) {
00292     std::cout << "WARNING MEtoEDM::mergeProducts(): the lists of histograms to be merged have different sizes: new=" << nObjects << ", old=" << nOldObjects << std::endl;
00293   }
00294 
00295   for (unsigned int i = 0; i < nObjects; ++i) {
00296     unsigned int j = 0;
00297     // see if the name is already in the old container up to the point where
00298     // we may have added new entries in the container
00299     const std::string& name = newMEtoEDMObject[i].name;
00300     if (i < nOldObjects && (MEtoEdmObject[i].name == name)) {
00301       j = i;
00302     } else {
00303       j = 0;
00304       while (j <  nOldObjects && (MEtoEdmObject[j].name != name) ) ++j;
00305     }
00306     if (j >= nOldObjects) {
00307       // this value is only in the new container, not the old one
00308 #if debug
00309       std::cout << "WARNING MEtoEDM::mergeProducts(): adding new histogram '" << name << "'" << std::endl;
00310 #endif
00311       MEtoEdmObject.push_back(newMEtoEDMObject[i]);
00312     }
00313   }
00314   return true;
00315 }
00316 
00317 #endif