File indexing completed on 2025-03-10 23:53:23
0001 #ifndef MEtoEDMFormat_h
0002 #define MEtoEDMFormat_h
0003
0004
0005
0006
0007
0008
0009
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
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
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
0092
0093 const size_t nOldObjects = MEtoEdmObject.size();
0094
0095
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
0104
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
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
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 };
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
0186
0187 const size_t nOldObjects = MEtoEdmObject.size();
0188
0189
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
0198
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
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
0223
0224 const size_t nOldObjects = MEtoEdmObject.size();
0225
0226
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
0235
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
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
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
0271
0272 const size_t nOldObjects = MEtoEdmObject.size();
0273
0274
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
0283
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
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
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
0319
0320 const size_t nOldObjects = MEtoEdmObject.size();
0321
0322
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
0331
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
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