Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2024-11-15 09:00:00

0001 #pragma once
0002 
0003 
0004 #include <iostream>
0005 #include <vector>
0006 #include <string>
0007 #include <mutex>
0008 
0009 #include <JANA/JApplication.h>
0010 #include "services/log/Log_service.h"
0011 #include <JANA/Services/JGlobalRootLock.h>
0012 #include <JANA/Services/JServiceLocator.h>
0013 
0014 #include <TFile.h>
0015 
0016 /**
0017  * This Service centralizes creation of a root file for histograms
0018  */
0019 class RootFile_service : public JService
0020 {
0021 public:
0022     explicit RootFile_service(JApplication *app ):m_app(app){}
0023     ~RootFile_service() override { CloseHistFile(); }
0024 
0025     void acquire_services(JServiceLocator *locater) override {
0026         auto log_service = m_app->GetService<Log_service>();
0027         m_log = log_service->logger("RootFile");
0028     }
0029 
0030     /// This will return a pointer to the top-level directory of the
0031     /// common output root file for histograms. If create_if_needed
0032     /// is true and the root file has not already been created, then
0033     /// one will be created. If create_if_needed is false, the pointer
0034     /// to the existing file will be returned or nullptr if it does
0035     /// not already exist.
0036     ///
0037     /// NOTE: This should only be called by a thread already holding
0038     /// the global root lock. The root lock will already be held if
0039     /// calling from JEventProcessorSequentialRoot. For pretty much
0040     /// everyplace else, the lock should be acquired manually.
0041     /// e.g.
0042     ///
0043     ///    auto rootfile_service = japp->GetService<RootFile_service>();
0044     ///    auto globalRootLock = japp->GetService<JGlobalRootLock>();
0045     ///    globalRootLock->acquire_write_lock();
0046     ///    auto rootfile = rootfile_service->GetHistFile();
0047     ///    globalWriteLock->release_lock();
0048     ///
0049     /// \param create_if_needed create file if not already created
0050     /// \return
0051     TDirectory* GetHistFile(bool create_if_needed=true){
0052 
0053         if( create_if_needed ) {
0054             std::call_once(init_flag, &RootFile_service::CreateHistFile, this);
0055         }
0056         return m_histfile;
0057     }
0058 
0059     /// Close the histogram file. If no histogram file was opened,
0060     /// then this does nothing.
0061     ///
0062     /// This should generally never be called by anything other than
0063     /// the destructor so that it is
0064     /// automatically closed when the service is destructed at
0065     /// the end of processing. This is only here for use in
0066     /// execptional circumstances like the program is suffering
0067     /// a fatal crash and we want to try and save the work by
0068     /// closing the file cleanly.
0069     void CloseHistFile(){
0070         if( m_histfile){
0071             std::string filename = m_histfile->GetName();
0072             m_histfile->Write();
0073             delete m_histfile;
0074             m_log->info("Closed user histogram file: {}" , filename);
0075         }
0076         m_histfile = nullptr;
0077     }
0078 
0079 private:
0080 
0081     /// Create the output rootfile. This will be called only once
0082     /// which will happen the first time GetHistFile is called.
0083     void CreateHistFile(){
0084         // Get root file name
0085         std::string filename = "eicrecon.root";
0086         m_app->SetDefaultParameter("histsfile", filename,
0087                                    "Name of root file to be created for plugin histograms/trees");
0088         if (!m_histfile) {
0089             try {
0090                 m_histfile = new TFile(filename.c_str(), "RECREATE", "user histograms/trees");
0091                 m_log->info("Created file: {} for user histograms", filename);
0092             } catch (std::exception &ex) {
0093                 m_log->error("Problem opening root file for histograms: {}", ex.what());
0094                 throw ex;
0095             }
0096         }
0097     }
0098 
0099     RootFile_service()=default;
0100 
0101     JApplication *m_app=nullptr;
0102     std::shared_ptr<spdlog::logger> m_log;
0103     TFile *m_histfile = nullptr;
0104     std::once_flag init_flag;
0105 };