From 8c4aaabb5d0a082a944ab79a5dfa442a7b70ebb4 Mon Sep 17 00:00:00 2001 From: Florian Uhlig <f.uhlig@gsi.de> Date: Wed, 30 Sep 2020 10:35:27 +0200 Subject: [PATCH] Allow as input ROOT file from ZIP archives Since the size of a single PLUTO file is very small the preferred storage solution for them is to store a large number of them in a archive. ROOT is able to handle ROOT files stored in a ZIP archive so the file handling in the class was adapted for the ZIP file usage. --- .../generators/CbmPlutoGenerator.cxx | 82 ++++++++++++++++--- sim/transport/generators/CbmPlutoGenerator.h | 2 +- 2 files changed, 73 insertions(+), 11 deletions(-) diff --git a/sim/transport/generators/CbmPlutoGenerator.cxx b/sim/transport/generators/CbmPlutoGenerator.cxx index e110b5f93f..1e3559a465 100644 --- a/sim/transport/generators/CbmPlutoGenerator.cxx +++ b/sim/transport/generators/CbmPlutoGenerator.cxx @@ -11,6 +11,7 @@ #include "PParticle.h" // for PParticle #include "PStaticData.h" // for PStaticData +#include "TArchiveFile.h" // for TArchiveFile #include "TChain.h" // for TChain #include "TClonesArray.h" // for TClonesArray #include "TDatabasePDG.h" // for TDatabasePDG @@ -47,10 +48,15 @@ CbmPlutoGenerator::CbmPlutoGenerator(const Char_t* fileName) , fParticles(new TClonesArray("PParticle", 100)) , fPDGmanual(0) { fInputChain = new TChain("data"); - CheckFileExist(fileName); - fInputChain->Add(fileName); - fInputChain->SetBranchAddress("Particles", &fParticles); + if (CheckFileExist(fileName)) { + fInputChain->Add(fileName); + fInputChain->SetBranchAddress("Particles", &fParticles); + LOG(info) << "CbmPlutoGenerator: Add file " << fileName + << " to input chain"; + } else { + LOG(fatal) << "Problem opening file " << fileName; + } } // ------------------------------------------------------------------------ @@ -66,9 +72,14 @@ CbmPlutoGenerator::CbmPlutoGenerator(std::vector<std::string> fileNames) , fPDGmanual(0) { fInputChain = new TChain("data"); for (auto& name : fileNames) { - CheckFileExist(name); - fInputChain->Add(name.c_str()); + if (CheckFileExist(name)) { + fInputChain->Add(name.c_str()); + LOG(info) << "CbmPlutoGenerator: Add file " << name << " to input chain"; + } else { + LOG(fatal) << "Problem opening file " << name; + } } + fInputChain->SetBranchAddress("Particles", &fParticles); } @@ -178,14 +189,65 @@ void CbmPlutoGenerator::CloseInput() { } // ------------------------------------------------------------------------ -void CbmPlutoGenerator::CheckFileExist(std::string filename) { +Bool_t CbmPlutoGenerator::CheckFileExist(std::string filename) { + + // In case the filename contains a hash (e.g. multi.zip#file.root) assume that the hash + // separates the name of a zipfile (multi.zip) which contains the real root file + // (file.root). Split the filename at the # in the name of the zipfile and + // the name of the contained root file. + std::string checkFilename {""}; + std::string membername {""}; + std::size_t found = filename.find("#"); + if (found != std::string::npos) { + checkFilename = filename.substr(0, found); + membername = filename.substr(found + 1); + } else { + checkFilename = filename; + } + + Bool_t wasfound = kFALSE; + + // Check if the file exist + // In case of a root file contained in a zip archive check if the zip file + // exist struct stat buffer; - if (stat(filename.c_str(), &buffer) == 0) { - LOG(info) << "CbmPlutoGenerator: Add file " << filename - << " to input chain"; + if (stat(checkFilename.c_str(), &buffer) == 0) { + wasfound = kTRUE; } else { - LOG(fatal) << "Input File " << filename << " not found"; + wasfound = kFALSE; + LOG(error) << "Input File " << checkFilename << " not found"; } + + // In case of a zip archive check if the archive contains the root file + if (membername.compare("") != 0) { + TFile* fzip = TFile::Open(checkFilename.c_str()); + if (fzip->IsOpen()) { + TArchiveFile* archive = fzip->GetArchive(); + if (archive) { + TObjArray* members = archive->GetMembers(); + if (members->FindObject(membername.c_str()) == 0) { + LOG(error) << "File " << membername << " not found in zipfile " + << checkFilename; + wasfound = kFALSE; + } else { + LOG(info) << "File " << membername << " found in zipfile " + << checkFilename; + wasfound = kTRUE; + } + } else { + LOG(error) << "Zipfile " << checkFilename + << " does not contain an archive"; + wasfound = kFALSE; + } + fzip->Close(); + delete fzip; + } else { + LOG(error) << "Could not open zipfile " << checkFilename; + wasfound = kFALSE; + } + } + + return wasfound; } ClassImp(CbmPlutoGenerator) diff --git a/sim/transport/generators/CbmPlutoGenerator.h b/sim/transport/generators/CbmPlutoGenerator.h index db1424da9d..0589e45f03 100644 --- a/sim/transport/generators/CbmPlutoGenerator.h +++ b/sim/transport/generators/CbmPlutoGenerator.h @@ -78,7 +78,7 @@ private: void CloseInput(); /** Check if file exists. Break fatal when it doesn't exist **/ - void CheckFileExist(std::string filename); + Bool_t CheckFileExist(std::string filename); ClassDef(CbmPlutoGenerator, 4); }; -- GitLab