File indexing completed on 2024-09-27 07:03:06
0001
0002 from sys import argv
0003 import subprocess
0004 import sys
0005 import os
0006
0007
0008
0009
0010 cmakelists_template = """
0011 #
0012 # EICrecon stand alone plugin
0013 #
0014 # This file was generated by the eicmkplugin.py script
0015 #
0016 # Before using this, make sure your environment is set up
0017 # for the EICrecon version you are using. The easiest way
0018 # to do this is to source the bin/eicrecon-this.(c)sh
0019 # script.
0020 #
0021
0022 cmake_minimum_required(VERSION 3.16)
0023 project({0}_project)
0024
0025 find_package(EICrecon REQUIRED)
0026 find_package(spdlog REQUIRED)
0027
0028 set(CMAKE_CXX_STANDARD ${{EICrecon_CXX_STANDARD}})
0029
0030 # Automatically determine source file list.
0031 file(GLOB mysourcefiles *.cpp *.cc *.c *.hpp *.hh *.h)
0032 set( {0}_PLUGIN_SOURCES ${{mysourcefiles}} )
0033
0034 # Create plugin
0035 add_library({0}_plugin SHARED ${{{0}_PLUGIN_SOURCES}})
0036 target_link_libraries({0}_plugin EICrecon::rootfile_plugin)
0037 set_target_properties({0}_plugin PROPERTIES PREFIX "" OUTPUT_NAME "{0}" SUFFIX ".so")
0038 target_compile_definitions({0}_plugin PUBLIC HAVE_PODIO)
0039
0040 # Install plugin USER_PLUGIN_OUTPUT_DIRECTORY is set depending on EICrecon_MY envar.
0041 install(TARGETS {0}_plugin DESTINATION ${{USER_PLUGIN_OUTPUT_DIRECTORY}} )
0042
0043 """
0044
0045 processor_sequentialroot_header_template = """
0046 //
0047 // Template for this file generated with eicmkplugin.py
0048 //
0049
0050 #include <JANA/JEventProcessorSequentialRoot.h>
0051 #include <TH2D.h>
0052 #include <TFile.h>
0053
0054 class {0}: public JEventProcessorSequentialRoot {{
0055 private:
0056
0057 // Declare histogram and tree pointers here. e.g.
0058 // TH1D* hEraw = nullptr;
0059 // TH2D* hEdigi = nullptr ;
0060
0061 public:
0062 {0}() {{ SetTypeName(NAME_OF_THIS); }}
0063
0064 void InitWithGlobalRootLock() override;
0065 void ProcessSequential(const std::shared_ptr<const JEvent>& event) override;
0066 void FinishWithGlobalRootLock() override;
0067 }};
0068 """
0069
0070 processor_sequentialroot_implementation_template = """
0071 //
0072 // Template for this file generated with eicmkplugin.py
0073 //
0074
0075 #include "{0}.h"
0076 #include "services/rootfile/RootFile_service.h"
0077
0078 // Include appropriate class headers. e.g.
0079 #include <edm4hep/SimCalorimeterHitCollection.h>
0080
0081 // The following just makes this a JANA plugin
0082 extern "C" {{
0083 void InitPlugin(JApplication *app) {{
0084 InitJANAPlugin(app);
0085 app->Add(new {0});
0086 }}
0087 }}
0088
0089 //-------------------------------------------
0090 // InitWithGlobalRootLock
0091 //-------------------------------------------
0092 void {0}::InitWithGlobalRootLock(){{
0093 auto rootfile_svc = GetApplication()->GetService<RootFile_service>();
0094 auto rootfile = rootfile_svc->GetHistFile();
0095 rootfile->mkdir("{1}")->cd();
0096
0097 // Create histograms here. e.g.
0098 // hEraw = new TH1D("Eraw", "BEMC hit energy (raw)", 100, 0, 0.075);
0099 // hEdigi = new TH2D("Edigi", "BEMC hit energy (digi) vs. raw", 200, 0, 2000.0, 100, 0, 0.075);
0100 }}
0101
0102 //-------------------------------------------
0103 // ProcessSequential
0104 //-------------------------------------------
0105 void {0}::ProcessSequential(const std::shared_ptr<const JEvent>& event) {{
0106 // Data objects we will need from JANA e.g.
0107 const auto &rawhits = *(event->GetCollection<edm4hep::SimCalorimeterHit>("EcalBarrelScFiHits"));
0108
0109 // Fill histograms here. e.g.
0110 // for (auto hit : rawhits) hEraw->Fill(hit.getEnergy());
0111 }}
0112
0113 //-------------------------------------------
0114 // FinishWithGlobalRootLock
0115 //-------------------------------------------
0116 void {0}::FinishWithGlobalRootLock() {{
0117
0118 // Do any final calculations here.
0119 }}
0120
0121 """
0122
0123 def print_usage():
0124 print("""
0125 Usage:
0126 eicmkplugin.py name
0127
0128 This will create a skeleton plugin for EICrecon with the given name. A directory with the
0129 given name will be created and some files placed there that can be used to build your custom
0130 plugin. The expected use case is to create plugins that create histograms or trees using the
0131 eicrecon executable.
0132
0133 The CMakeLists.txt file placed in the plugin directory will install the plugin either in
0134 the plugins directory relative to your EICrecon_ROOT environment variable when cmake is run
0135 or relative to the directory specified by your EICrecon_MY environment variable, if it is set.
0136 The intent of the EICrecon_MY environment variable is to allow you to build a custom plugin
0137 against a global build of EICrecon where you do not have write access.
0138
0139 Example usage:
0140
0141 eicmkplugin.py MyCustomPlugin
0142 cmake -S MyCustomPlugin -B MyCustomPlugin/build
0143 cmake --build MyCustomPlugin/build --target install
0144
0145 eicrecon -Pplugins=MyCustomPlugin file.root
0146
0147 """)
0148
0149
0150
0151 if len(argv) < 2:
0152 print_usage()
0153 sys.exit()
0154
0155 pluginName = argv[1]
0156 className = "{}Processor".format(pluginName)
0157
0158 os.mkdir(pluginName)
0159 with open(pluginName+"/CMakeLists.txt", 'w') as f:
0160 print( "Writing "+pluginName+"/CMakeLists.txt ...")
0161 f.write( cmakelists_template.format( pluginName) )
0162 f.close()
0163
0164 with open(pluginName+"/{}.h".format(className), 'w') as f:
0165 print( "Writing "+pluginName+"/{}.h".format(className) +" ...")
0166 f.write( processor_sequentialroot_header_template.format(className) )
0167 f.close()
0168
0169 with open(pluginName+"/{}.cc".format(className), 'w') as f:
0170 print( "Writing "+pluginName+"/{}.cc".format(className) +" ...")
0171 f.write( processor_sequentialroot_implementation_template.format(className, pluginName) )
0172 f.close()
0173
0174 print("""
0175 Created plugin {0}.
0176 Build with:
0177
0178 cmake -S {0} -B {0}/build
0179 cmake --build {0}/build --target install
0180 """.format(pluginName))