File indexing completed on 2025-03-10 23:53:33
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #include <memory>
0015
0016 #include "TFile.h"
0017 #include "TString.h"
0018 #include "TTree.h"
0019 #include <map>
0020 #include <string>
0021 #include <vector>
0022
0023 #include "DQMServices/Core/interface/DQMStore.h"
0024 #include "DataFormats/Histograms/interface/DQMToken.h"
0025 #include "FWCore/ServiceRegistry/interface/Service.h"
0026
0027 #include "FWCore/Framework/interface/InputSource.h"
0028 #include "FWCore/Sources/interface/PuttableSourceBase.h"
0029 #include "FWCore/Catalog/interface/InputFileCatalog.h"
0030 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0031 #include "FWCore/Utilities/interface/ExceptionPropagate.h"
0032
0033 #include "FWCore/Framework/interface/RunPrincipal.h"
0034 #include "FWCore/Framework/interface/LuminosityBlockPrincipal.h"
0035
0036 #include "FWCore/Framework/interface/Run.h"
0037 #include "FWCore/Framework/interface/LuminosityBlock.h"
0038 #include "DataFormats/Provenance/interface/LuminosityBlockID.h"
0039 #include "DataFormats/Provenance/interface/LuminosityBlockRange.h"
0040 #include "DataFormats/Provenance/interface/ProcessHistoryRegistry.h"
0041
0042 #include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h"
0043 #include "FWCore/ParameterSet/interface/ParameterSetDescription.h"
0044
0045 #include "FWCore/Framework/interface/InputSourceMacros.h"
0046 #include "FWCore/Framework/interface/FileBlock.h"
0047
0048 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0049 #include "FWCore/MessageLogger/interface/JobReport.h"
0050 #include "FWCore/Utilities/interface/TimeOfDay.h"
0051
0052 #include "format.h"
0053
0054
0055
0056 struct DQMTTreeIO {
0057 typedef dqm::harvesting::MonitorElement MonitorElement;
0058 typedef dqm::harvesting::DQMStore DQMStore;
0059
0060
0061 class DQMMergeHelper {
0062 public:
0063
0064
0065 static bool CheckBinLabels(const TAxis* a1, const TAxis* a2) {
0066
0067 THashList* l1 = (const_cast<TAxis*>(a1))->GetLabels();
0068 THashList* l2 = (const_cast<TAxis*>(a2))->GetLabels();
0069
0070 if (!l1 && !l2)
0071 return true;
0072 if (!l1 || !l2) {
0073 return false;
0074 }
0075
0076
0077 if (l1->GetSize() != l2->GetSize()) {
0078 return false;
0079 }
0080
0081 for (int i = 1; i <= a1->GetNbins(); ++i) {
0082 std::string_view label1 = a1->GetBinLabel(i);
0083 std::string_view label2 = a2->GetBinLabel(i);
0084 if (label1 != label2) {
0085 return false;
0086 }
0087 }
0088
0089 return true;
0090 }
0091
0092
0093 static void mergeTogether(TH1* original, TH1* toAdd) {
0094 if (original->CanExtendAllAxes() && toAdd->CanExtendAllAxes()) {
0095 TList list;
0096 list.Add(toAdd);
0097 if (original->Merge(&list) == -1) {
0098 edm::LogError("MergeFailure") << "Failed to merge DQM element " << original->GetName();
0099 }
0100 } else {
0101
0102
0103 if (original->GetNbinsX() == toAdd->GetNbinsX() &&
0104 original->GetXaxis()->GetXmin() == toAdd->GetXaxis()->GetXmin() &&
0105 original->GetXaxis()->GetXmax() == toAdd->GetXaxis()->GetXmax() &&
0106 original->GetNbinsY() == toAdd->GetNbinsY() &&
0107 original->GetYaxis()->GetXmin() == toAdd->GetYaxis()->GetXmin() &&
0108 original->GetYaxis()->GetXmax() == toAdd->GetYaxis()->GetXmax() &&
0109 original->GetNbinsZ() == toAdd->GetNbinsZ() &&
0110 original->GetZaxis()->GetXmin() == toAdd->GetZaxis()->GetXmin() &&
0111 original->GetZaxis()->GetXmax() == toAdd->GetZaxis()->GetXmax() &&
0112 CheckBinLabels(original->GetXaxis(), toAdd->GetXaxis()) &&
0113 CheckBinLabels(original->GetYaxis(), toAdd->GetYaxis()) &&
0114 CheckBinLabels(original->GetZaxis(), toAdd->GetZaxis())) {
0115 original->Add(toAdd);
0116 } else {
0117 edm::LogError("MergeFailure") << "Found histograms with different axis limits or different labels '"
0118 << original->GetName() << "' not merged.";
0119 }
0120 }
0121 }
0122 };
0123
0124
0125
0126 struct FileMetadata {
0127 unsigned int m_run;
0128 unsigned int m_lumi;
0129 ULong64_t m_beginTime;
0130 ULong64_t m_endTime;
0131 ULong64_t m_firstIndex;
0132 ULong64_t m_lastIndex;
0133 unsigned int m_type;
0134 TFile* m_file;
0135
0136
0137 bool operator<(const FileMetadata& obj) const {
0138 if (m_run == obj.m_run)
0139 return m_lumi < obj.m_lumi;
0140 else
0141 return m_run < obj.m_run;
0142 }
0143
0144 void describe() {
0145 std::cout << "read r:" << m_run << " l:" << m_lumi << " bt:" << m_beginTime << " et:" << m_endTime
0146 << " fi:" << m_firstIndex << " li:" << m_lastIndex << " type:" << m_type << " file: " << m_file
0147 << std::endl;
0148 }
0149 };
0150
0151 class TreeReaderBase {
0152 public:
0153 TreeReaderBase(MonitorElementData::Kind kind, MonitorElementData::Scope rescope)
0154 : m_kind(kind), m_rescope(rescope) {}
0155 virtual ~TreeReaderBase() {}
0156
0157 MonitorElementData::Key makeKey(std::string const& fullname, int run, int lumi) {
0158 MonitorElementData::Key key;
0159 key.kind_ = m_kind;
0160 key.path_.set(fullname, MonitorElementData::Path::Type::DIR_AND_NAME);
0161 if (m_rescope == MonitorElementData::Scope::LUMI) {
0162
0163 key.scope_ = lumi == 0 ? MonitorElementData::Scope::RUN : MonitorElementData::Scope::LUMI;
0164 key.id_ = edm::LuminosityBlockID(run, lumi);
0165 } else if (m_rescope == MonitorElementData::Scope::RUN) {
0166
0167 key.scope_ = MonitorElementData::Scope::RUN;
0168 key.id_ = edm::LuminosityBlockID(run, 0);
0169 } else if (m_rescope == MonitorElementData::Scope::JOB) {
0170
0171 key.scope_ = MonitorElementData::Scope::JOB;
0172 key.id_ = edm::LuminosityBlockID(0, 0);
0173 } else {
0174 assert(!"Invalid Scope in rescope option.");
0175 }
0176 return key;
0177 }
0178 virtual void read(ULong64_t iIndex, DQMStore* dqmstore, int run, int lumi) = 0;
0179 virtual void setTree(TTree* iTree) = 0;
0180
0181 protected:
0182 MonitorElementData::Kind m_kind;
0183 MonitorElementData::Scope m_rescope;
0184 };
0185
0186 template <class T>
0187 class TreeObjectReader : public TreeReaderBase {
0188 public:
0189 TreeObjectReader(MonitorElementData::Kind kind, MonitorElementData::Scope rescope) : TreeReaderBase(kind, rescope) {
0190 assert(m_kind != MonitorElementData::Kind::INT);
0191 assert(m_kind != MonitorElementData::Kind::REAL);
0192 assert(m_kind != MonitorElementData::Kind::STRING);
0193 }
0194
0195 void read(ULong64_t iIndex, DQMStore* dqmstore, int run, int lumi) override {
0196
0197 try {
0198 m_tree->GetEntry(iIndex);
0199
0200 auto key = makeKey(*m_fullName, run, lumi);
0201 auto existing = dqmstore->findOrRecycle(key);
0202 if (existing) {
0203
0204 DQMMergeHelper::mergeTogether(existing->getTH1(), m_buffer);
0205 } else {
0206
0207 MonitorElementData meData;
0208 meData.key_ = key;
0209 meData.value_.object_ = std::unique_ptr<T>((T*)(m_buffer->Clone()));
0210 auto me = new MonitorElement(std::move(meData));
0211 dqmstore->putME(me);
0212 }
0213 } catch (cms::Exception& iExcept) {
0214 using namespace std::string_literals;
0215 iExcept.addContext("failed while reading "s + *m_fullName);
0216 throw;
0217 }
0218 }
0219
0220 void setTree(TTree* iTree) override {
0221 m_tree = iTree;
0222 m_tree->SetBranchAddress(kFullNameBranch, &m_fullName);
0223 m_tree->SetBranchAddress(kFlagBranch, &m_tag);
0224 m_tree->SetBranchAddress(kValueBranch, &m_buffer);
0225 }
0226
0227 private:
0228 TTree* m_tree = nullptr;
0229 std::string* m_fullName = nullptr;
0230 T* m_buffer = nullptr;
0231 uint32_t m_tag = 0;
0232 };
0233
0234 class TreeStringReader : public TreeReaderBase {
0235 public:
0236 TreeStringReader(MonitorElementData::Kind kind, MonitorElementData::Scope rescope) : TreeReaderBase(kind, rescope) {
0237 assert(m_kind == MonitorElementData::Kind::STRING);
0238 }
0239
0240 void read(ULong64_t iIndex, DQMStore* dqmstore, int run, int lumi) override {
0241
0242 m_tree->GetEntry(iIndex);
0243
0244 auto key = makeKey(*m_fullName, run, lumi);
0245 auto existing = dqmstore->findOrRecycle(key);
0246
0247 if (existing) {
0248 existing->Fill(*m_value);
0249 } else {
0250
0251 MonitorElementData meData;
0252 meData.key_ = key;
0253 meData.value_.scalar_.str = *m_value;
0254 auto me = new MonitorElement(std::move(meData));
0255 dqmstore->putME(me);
0256 }
0257 }
0258
0259 void setTree(TTree* iTree) override {
0260 m_tree = iTree;
0261 m_tree->SetBranchAddress(kFullNameBranch, &m_fullName);
0262 m_tree->SetBranchAddress(kFlagBranch, &m_tag);
0263 m_tree->SetBranchAddress(kValueBranch, &m_value);
0264 }
0265
0266 private:
0267 TTree* m_tree = nullptr;
0268 std::string* m_fullName = nullptr;
0269 std::string* m_value = nullptr;
0270 uint32_t m_tag = 0;
0271 };
0272
0273 template <class T>
0274 class TreeSimpleReader : public TreeReaderBase {
0275 public:
0276 TreeSimpleReader(MonitorElementData::Kind kind, MonitorElementData::Scope rescope) : TreeReaderBase(kind, rescope) {
0277 assert(m_kind == MonitorElementData::Kind::INT || m_kind == MonitorElementData::Kind::REAL);
0278 }
0279
0280 void read(ULong64_t iIndex, DQMStore* dqmstore, int run, int lumi) override {
0281
0282 m_tree->GetEntry(iIndex);
0283
0284 auto key = makeKey(*m_fullName, run, lumi);
0285 auto existing = dqmstore->findOrRecycle(key);
0286
0287 if (existing) {
0288 existing->Fill(m_buffer);
0289 } else {
0290
0291 MonitorElementData meData;
0292 meData.key_ = key;
0293 if (m_kind == MonitorElementData::Kind::INT)
0294 meData.value_.scalar_.num = m_buffer;
0295 else if (m_kind == MonitorElementData::Kind::REAL)
0296 meData.value_.scalar_.real = m_buffer;
0297 auto me = new MonitorElement(std::move(meData));
0298 dqmstore->putME(me);
0299 }
0300 }
0301
0302 void setTree(TTree* iTree) override {
0303 m_tree = iTree;
0304 m_tree->SetBranchAddress(kFullNameBranch, &m_fullName);
0305 m_tree->SetBranchAddress(kFlagBranch, &m_tag);
0306 m_tree->SetBranchAddress(kValueBranch, &m_buffer);
0307 }
0308
0309 private:
0310 TTree* m_tree = nullptr;
0311 std::string* m_fullName = nullptr;
0312 T m_buffer = 0;
0313 uint32_t m_tag = 0;
0314 };
0315 };
0316
0317 class DQMRootSource : public edm::PuttableSourceBase, DQMTTreeIO {
0318 public:
0319 DQMRootSource(edm::ParameterSet const&, const edm::InputSourceDescription&);
0320 DQMRootSource(const DQMRootSource&) = delete;
0321 ~DQMRootSource() override;
0322
0323
0324
0325 const DQMRootSource& operator=(const DQMRootSource&) = delete;
0326
0327
0328
0329
0330 static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
0331
0332 private:
0333 edm::InputSource::ItemTypeInfo getNextItemType() override;
0334
0335 std::shared_ptr<edm::FileBlock> readFile_() override;
0336 std::shared_ptr<edm::RunAuxiliary> readRunAuxiliary_() override;
0337 std::shared_ptr<edm::LuminosityBlockAuxiliary> readLuminosityBlockAuxiliary_() override;
0338 void readRun_(edm::RunPrincipal& rpCache) override;
0339 void readLuminosityBlock_(edm::LuminosityBlockPrincipal& lbCache) override;
0340 void readEvent_(edm::EventPrincipal&) override;
0341
0342
0343 void readElements();
0344
0345
0346
0347 bool isRunOrLumiTransition() const;
0348 void readNextItemType();
0349
0350
0351
0352 void beginRun(edm::Run& run) override;
0353 void beginLuminosityBlock(edm::LuminosityBlock& lumi) override;
0354
0355
0356
0357
0358
0359
0360 bool keepIt(edm::RunNumber_t, edm::LuminosityBlockNumber_t) const;
0361 void logFileAction(char const* msg, char const* fileName) const;
0362
0363
0364
0365
0366 bool m_skipBadFiles;
0367 unsigned int m_filterOnRun;
0368 edm::InputFileCatalog m_catalog;
0369 std::vector<edm::LuminosityBlockRange> m_lumisToProcess;
0370 MonitorElementData::Scope m_rescope;
0371
0372 edm::InputSource::ItemType m_nextItemType;
0373
0374 std::vector<std::shared_ptr<TreeReaderBase>> m_treeReaders;
0375
0376
0377 unsigned int m_currentIndex;
0378
0379
0380 struct OpenFileInfo {
0381 OpenFileInfo(TFile* file, edm::JobReport::Token jrToken) : m_file(file), m_jrToken(jrToken) {}
0382 ~OpenFileInfo() {
0383 edm::Service<edm::JobReport> jr;
0384 jr->inputFileClosed(edm::InputType::Primary, m_jrToken);
0385 }
0386
0387 OpenFileInfo(OpenFileInfo&&) = default;
0388 OpenFileInfo& operator=(OpenFileInfo&&) = default;
0389
0390 std::unique_ptr<TFile> m_file;
0391 edm::JobReport::Token m_jrToken;
0392 };
0393 std::vector<OpenFileInfo> m_openFiles;
0394
0395
0396 std::vector<FileMetadata> m_fileMetadatas;
0397 };
0398
0399
0400
0401
0402
0403
0404
0405
0406
0407 void DQMRootSource::fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
0408 edm::ParameterSetDescription desc;
0409 desc.addUntracked<std::vector<std::string>>("fileNames")->setComment("Names of files to be processed.");
0410 desc.addUntracked<unsigned int>("filterOnRun", 0)->setComment("Just limit the process to the selected run.");
0411 desc.addUntracked<std::string>("reScope", "JOB")
0412 ->setComment(
0413 "Accumulate histograms more coarsely."
0414 " Options: \"\": keep unchanged, \"RUN\": turn LUMI histograms into RUN histograms, \"JOB\": turn everything "
0415 "into JOB histograms.");
0416 desc.addUntracked<bool>("skipBadFiles", false)->setComment("Skip the file if it is not valid");
0417 desc.addUntracked<std::string>("overrideCatalog", std::string())
0418 ->setComment("An alternate file catalog to use instead of the standard site one.");
0419 std::vector<edm::LuminosityBlockRange> defaultLumis;
0420 desc.addUntracked<std::vector<edm::LuminosityBlockRange>>("lumisToProcess", defaultLumis)
0421 ->setComment("Skip any lumi inside the specified run:lumi range.");
0422
0423 descriptions.addDefault(desc);
0424 }
0425
0426
0427
0428
0429
0430 DQMRootSource::DQMRootSource(edm::ParameterSet const& iPSet, const edm::InputSourceDescription& iDesc)
0431 : edm::PuttableSourceBase(iPSet, iDesc),
0432 m_skipBadFiles(iPSet.getUntrackedParameter<bool>("skipBadFiles", false)),
0433 m_filterOnRun(iPSet.getUntrackedParameter<unsigned int>("filterOnRun", 0)),
0434 m_catalog(iPSet.getUntrackedParameter<std::vector<std::string>>("fileNames"),
0435 iPSet.getUntrackedParameter<std::string>("overrideCatalog")),
0436 m_lumisToProcess(iPSet.getUntrackedParameter<std::vector<edm::LuminosityBlockRange>>(
0437 "lumisToProcess", std::vector<edm::LuminosityBlockRange>())),
0438 m_rescope(std::map<std::string, MonitorElementData::Scope>{
0439 {"", MonitorElementData::Scope::LUMI},
0440 {"LUMI", MonitorElementData::Scope::LUMI},
0441 {"RUN", MonitorElementData::Scope::RUN},
0442 {"JOB", MonitorElementData::Scope::JOB}}[iPSet.getUntrackedParameter<std::string>("reScope", "JOB")]),
0443 m_nextItemType(edm::InputSource::ItemType::IsFile),
0444 m_treeReaders(kNIndicies, std::shared_ptr<TreeReaderBase>()),
0445 m_currentIndex(0),
0446 m_openFiles(std::vector<OpenFileInfo>()),
0447 m_fileMetadatas(std::vector<FileMetadata>()) {
0448 edm::sortAndRemoveOverlaps(m_lumisToProcess);
0449
0450 if (m_catalog.fileNames(0).empty()) {
0451 m_nextItemType = edm::InputSource::ItemType::IsStop;
0452 } else {
0453 m_treeReaders[kIntIndex] = std::make_shared<TreeSimpleReader<Long64_t>>(MonitorElementData::Kind::INT, m_rescope);
0454 m_treeReaders[kFloatIndex] = std::make_shared<TreeSimpleReader<double>>(MonitorElementData::Kind::REAL, m_rescope);
0455 m_treeReaders[kStringIndex] = std::make_shared<TreeStringReader>(MonitorElementData::Kind::STRING, m_rescope);
0456 m_treeReaders[kTH1FIndex] = std::make_shared<TreeObjectReader<TH1F>>(MonitorElementData::Kind::TH1F, m_rescope);
0457 m_treeReaders[kTH1SIndex] = std::make_shared<TreeObjectReader<TH1S>>(MonitorElementData::Kind::TH1S, m_rescope);
0458 m_treeReaders[kTH1DIndex] = std::make_shared<TreeObjectReader<TH1D>>(MonitorElementData::Kind::TH1D, m_rescope);
0459 m_treeReaders[kTH1IIndex] = std::make_shared<TreeObjectReader<TH1I>>(MonitorElementData::Kind::TH1I, m_rescope);
0460 m_treeReaders[kTH2FIndex] = std::make_shared<TreeObjectReader<TH2F>>(MonitorElementData::Kind::TH2F, m_rescope);
0461 m_treeReaders[kTH2SIndex] = std::make_shared<TreeObjectReader<TH2S>>(MonitorElementData::Kind::TH2S, m_rescope);
0462 m_treeReaders[kTH2DIndex] = std::make_shared<TreeObjectReader<TH2D>>(MonitorElementData::Kind::TH2D, m_rescope);
0463 m_treeReaders[kTH2PolyIndex] =
0464 std::make_shared<TreeObjectReader<TH2Poly>>(MonitorElementData::Kind::TH2Poly, m_rescope);
0465 m_treeReaders[kTH2IIndex] = std::make_shared<TreeObjectReader<TH2I>>(MonitorElementData::Kind::TH2I, m_rescope);
0466 m_treeReaders[kTH3FIndex] = std::make_shared<TreeObjectReader<TH3F>>(MonitorElementData::Kind::TH3F, m_rescope);
0467 m_treeReaders[kTProfileIndex] =
0468 std::make_shared<TreeObjectReader<TProfile>>(MonitorElementData::Kind::TPROFILE, m_rescope);
0469 m_treeReaders[kTProfile2DIndex] =
0470 std::make_shared<TreeObjectReader<TProfile2D>>(MonitorElementData::Kind::TPROFILE2D, m_rescope);
0471 }
0472
0473 produces<DQMToken, edm::Transition::BeginRun>("DQMGenerationRecoRun");
0474 produces<DQMToken, edm::Transition::BeginLuminosityBlock>("DQMGenerationRecoLumi");
0475 }
0476
0477 DQMRootSource::~DQMRootSource() {
0478 for (auto& file : m_openFiles) {
0479 if (file.m_file && file.m_file->IsOpen()) {
0480 logFileAction("Closed file", "");
0481 }
0482 }
0483 }
0484
0485
0486
0487
0488
0489 edm::InputSource::ItemTypeInfo DQMRootSource::getNextItemType() { return m_nextItemType; }
0490
0491
0492 std::shared_ptr<edm::FileBlock> DQMRootSource::readFile_() {
0493 const int numFiles = m_catalog.fileNames(0).size();
0494 m_openFiles.reserve(numFiles);
0495
0496 for (auto& fileitem : m_catalog.fileCatalogItems()) {
0497 TFile* file = nullptr;
0498 std::string pfn;
0499 std::string lfn;
0500 std::list<std::string> exInfo;
0501
0502 bool isGoodFile(true);
0503
0504 const std::vector<std::string>& fNames = fileitem.fileNames();
0505 for (std::vector<std::string>::const_iterator it = fNames.begin(); it != fNames.end(); ++it) {
0506
0507 try {
0508 file = TFile::Open(it->c_str());
0509
0510
0511 std::exception_ptr e = edm::threadLocalException::getException();
0512 if (e != std::exception_ptr()) {
0513 edm::threadLocalException::setException(std::exception_ptr());
0514 std::rethrow_exception(e);
0515 }
0516
0517 } catch (cms::Exception const& e) {
0518 file = nullptr;
0519 if (std::next(it) == fNames.end()) {
0520 if (!m_skipBadFiles) {
0521 edm::Exception ex(edm::errors::FileOpenError, "", e);
0522 ex.addContext("Opening DQM Root file");
0523 ex << "\nInput file " << *it << " was not found, could not be opened, or is corrupted.\n";
0524
0525 for (auto const& s : exInfo)
0526 ex.addAdditionalInfo(s);
0527 throw ex;
0528 }
0529 isGoodFile = false;
0530 }
0531
0532 for (auto const& s : e.additionalInfo())
0533 exInfo.push_back(s);
0534 }
0535
0536
0537 if (file && !file->IsZombie()) {
0538 logFileAction("Successfully opened file ", it->c_str());
0539 pfn = *it;
0540 lfn = fileitem.logicalFileName();
0541 break;
0542 } else {
0543 if (std::next(it) == fNames.end()) {
0544 if (!m_skipBadFiles) {
0545 edm::Exception ex(edm::errors::FileOpenError);
0546 ex << "Input file " << *it << " could not be opened.\n";
0547 ex.addContext("Opening DQM Root file");
0548
0549 for (auto const& s : exInfo)
0550 ex.addAdditionalInfo(s);
0551 throw ex;
0552 }
0553 isGoodFile = false;
0554 }
0555 if (file) {
0556 delete file;
0557 file = nullptr;
0558 }
0559 }
0560 }
0561
0562 if (!file || (!isGoodFile && m_skipBadFiles))
0563 continue;
0564
0565 std::unique_ptr<std::string> guid{file->Get<std::string>(kCmsGuid)};
0566 if (not guid) {
0567 guid = std::make_unique<std::string>(file->GetUUID().AsString());
0568 std::transform(guid->begin(), guid->end(), guid->begin(), (int (*)(int))std::toupper);
0569 }
0570
0571 edm::Service<edm::JobReport> jr;
0572 auto jrToken = jr->inputFileOpened(
0573 pfn, lfn, std::string(), std::string(), "DQMRootSource", "source", *guid, std::vector<std::string>());
0574 m_openFiles.emplace_back(file, jrToken);
0575
0576
0577 if (strcmp(file->GetTitle(), "1") != 0) {
0578 edm::Exception ex(edm::errors::FileReadError);
0579 ex << "Input file " << fNames[0] << " does not appear to be a DQM Root file.\n";
0580 }
0581
0582
0583 TTree* indicesTree = dynamic_cast<TTree*>(file->Get(kIndicesTree));
0584 assert(indicesTree != nullptr);
0585
0586 FileMetadata temp;
0587
0588 indicesTree->SetBranchAddress(kRunBranch, &temp.m_run);
0589 indicesTree->SetBranchAddress(kLumiBranch, &temp.m_lumi);
0590 indicesTree->SetBranchAddress(kBeginTimeBranch, &temp.m_beginTime);
0591 indicesTree->SetBranchAddress(kEndTimeBranch, &temp.m_endTime);
0592 indicesTree->SetBranchAddress(kTypeBranch, &temp.m_type);
0593 indicesTree->SetBranchAddress(kFirstIndex, &temp.m_firstIndex);
0594 indicesTree->SetBranchAddress(kLastIndex, &temp.m_lastIndex);
0595
0596 for (Long64_t index = 0; index != indicesTree->GetEntries(); ++index) {
0597 indicesTree->GetEntry(index);
0598 temp.m_file = file;
0599
0600 if (keepIt(temp.m_run, temp.m_lumi)) {
0601 m_fileMetadatas.push_back(temp);
0602 }
0603 }
0604
0605 }
0606
0607
0608 std::stable_sort(m_fileMetadatas.begin(), m_fileMetadatas.end());
0609
0610
0611 unsigned int run = 0;
0612 auto toadd = std::vector<FileMetadata>();
0613 for (auto& metadata : m_fileMetadatas) {
0614 if (run < metadata.m_run && metadata.m_lumi != 0) {
0615
0616 FileMetadata dummy{};
0617 dummy.m_run = metadata.m_run;
0618 dummy.m_lumi = 0;
0619 dummy.m_type = kNoTypesStored;
0620 toadd.push_back(dummy);
0621 }
0622 run = metadata.m_run;
0623 }
0624
0625 if (!toadd.empty()) {
0626
0627 m_fileMetadatas.insert(m_fileMetadatas.end(), toadd.begin(), toadd.end());
0628 std::stable_sort(m_fileMetadatas.begin(), m_fileMetadatas.end());
0629 }
0630
0631
0632
0633
0634
0635 if (m_fileMetadatas.empty())
0636 m_nextItemType = edm::InputSource::ItemType::IsStop;
0637 else
0638 m_nextItemType = edm::InputSource::ItemType::IsRun;
0639
0640
0641 return std::make_shared<edm::FileBlock>();
0642 }
0643
0644 std::shared_ptr<edm::RunAuxiliary> DQMRootSource::readRunAuxiliary_() {
0645 FileMetadata metadata = m_fileMetadatas[m_currentIndex];
0646 auto runAux =
0647 edm::RunAuxiliary(metadata.m_run, edm::Timestamp(metadata.m_beginTime), edm::Timestamp(metadata.m_endTime));
0648 return std::make_shared<edm::RunAuxiliary>(runAux);
0649 }
0650
0651 std::shared_ptr<edm::LuminosityBlockAuxiliary> DQMRootSource::readLuminosityBlockAuxiliary_() {
0652 FileMetadata metadata = m_fileMetadatas[m_currentIndex];
0653 auto lumiAux = edm::LuminosityBlockAuxiliary(edm::LuminosityBlockID(metadata.m_run, metadata.m_lumi),
0654 edm::Timestamp(metadata.m_beginTime),
0655 edm::Timestamp(metadata.m_endTime));
0656 return std::make_shared<edm::LuminosityBlockAuxiliary>(lumiAux);
0657 }
0658
0659 void DQMRootSource::readRun_(edm::RunPrincipal& rpCache) {
0660
0661 do {
0662 FileMetadata metadata = m_fileMetadatas[m_currentIndex];
0663 if (metadata.m_lumi == 0) {
0664 readElements();
0665 }
0666 m_currentIndex++;
0667 } while (!isRunOrLumiTransition());
0668
0669 readNextItemType();
0670
0671 edm::Service<edm::JobReport> jr;
0672 jr->reportInputRunNumber(rpCache.id().run());
0673 rpCache.fillRunPrincipal(processHistoryRegistryForUpdate());
0674 }
0675
0676 void DQMRootSource::readLuminosityBlock_(edm::LuminosityBlockPrincipal& lbCache) {
0677
0678 do {
0679 readElements();
0680 m_currentIndex++;
0681 } while (!isRunOrLumiTransition());
0682
0683 readNextItemType();
0684
0685 edm::Service<edm::JobReport> jr;
0686 jr->reportInputLumiSection(lbCache.id().run(), lbCache.id().luminosityBlock());
0687 lbCache.fillLuminosityBlockPrincipal(processHistoryRegistry().getMapped(lbCache.aux().processHistoryID()));
0688 }
0689
0690 void DQMRootSource::readEvent_(edm::EventPrincipal&) {}
0691
0692 void DQMRootSource::readElements() {
0693 FileMetadata metadata = m_fileMetadatas[m_currentIndex];
0694
0695 if (metadata.m_type != kNoTypesStored) {
0696 std::shared_ptr<TreeReaderBase> reader = m_treeReaders[metadata.m_type];
0697 TTree* tree = dynamic_cast<TTree*>(metadata.m_file->Get(kTypeNames[metadata.m_type]));
0698
0699
0700 tree->Refresh();
0701
0702 reader->setTree(tree);
0703
0704 ULong64_t index = metadata.m_firstIndex;
0705 ULong64_t endIndex = metadata.m_lastIndex + 1;
0706
0707 for (; index != endIndex; ++index) {
0708 reader->read(index, edm::Service<DQMStore>().operator->(), metadata.m_run, metadata.m_lumi);
0709 }
0710
0711
0712 tree->Reset();
0713 }
0714 }
0715
0716 bool DQMRootSource::isRunOrLumiTransition() const {
0717 if (m_currentIndex == 0) {
0718 return false;
0719 }
0720
0721 if (m_currentIndex > m_fileMetadatas.size() - 1) {
0722
0723 return true;
0724 }
0725
0726 FileMetadata previousMetadata = m_fileMetadatas[m_currentIndex - 1];
0727 FileMetadata metadata = m_fileMetadatas[m_currentIndex];
0728
0729 return previousMetadata.m_run != metadata.m_run || previousMetadata.m_lumi != metadata.m_lumi;
0730 }
0731
0732 void DQMRootSource::readNextItemType() {
0733 if (m_currentIndex == 0) {
0734 m_nextItemType = edm::InputSource::ItemType::IsRun;
0735 } else if (m_currentIndex > m_fileMetadatas.size() - 1) {
0736
0737 m_nextItemType = edm::InputSource::ItemType::IsStop;
0738 } else {
0739 FileMetadata previousMetadata = m_fileMetadatas[m_currentIndex - 1];
0740 FileMetadata metadata = m_fileMetadatas[m_currentIndex];
0741
0742 if (previousMetadata.m_run != metadata.m_run) {
0743 m_nextItemType = edm::InputSource::ItemType::IsRun;
0744 } else if (previousMetadata.m_lumi != metadata.m_lumi) {
0745 m_nextItemType = edm::InputSource::ItemType::IsLumi;
0746 }
0747 }
0748 }
0749
0750 void DQMRootSource::beginRun(edm::Run& run) {
0751 std::unique_ptr<DQMToken> product = std::make_unique<DQMToken>();
0752 run.put(std::move(product), "DQMGenerationRecoRun");
0753 }
0754
0755 void DQMRootSource::beginLuminosityBlock(edm::LuminosityBlock& lumi) {
0756 std::unique_ptr<DQMToken> product = std::make_unique<DQMToken>();
0757 lumi.put(std::move(product), "DQMGenerationRecoLumi");
0758 }
0759
0760 bool DQMRootSource::keepIt(edm::RunNumber_t run, edm::LuminosityBlockNumber_t lumi) const {
0761 if (m_filterOnRun != 0 && run != m_filterOnRun) {
0762 return false;
0763 }
0764
0765 if (m_lumisToProcess.empty()) {
0766 return true;
0767 }
0768
0769 for (edm::LuminosityBlockRange const& lumiToProcess : m_lumisToProcess) {
0770 if (run >= lumiToProcess.startRun() && run <= lumiToProcess.endRun()) {
0771 if (lumi >= lumiToProcess.startLumi() && lumi <= lumiToProcess.endLumi()) {
0772 return true;
0773 } else if (lumi == 0) {
0774 return true;
0775 }
0776 }
0777 }
0778 return false;
0779 }
0780
0781 void DQMRootSource::logFileAction(char const* msg, char const* fileName) const {
0782 edm::LogAbsolute("fileAction") << std::setprecision(0) << edm::TimeOfDay() << msg << fileName;
0783 edm::FlushMessageLog();
0784 }
0785
0786
0787
0788
0789
0790
0791
0792
0793 DEFINE_FWK_INPUT_SOURCE(DQMRootSource);