# For SPMT commissioning (based on SNiPER) The software was intentionally designed to separate the data input and analysis tools. Similar to JUNO Offline, two main structures exist: one is named **`algorithm`**, and the other is named **`tool`**. Each of these structures has its own set of rules for definition. 1. **`algorithm`** can accept the input **arguments** and input **data** (only `ROOT` data can be accepted now). The **data** is input as a list written in a text file, **arguments** can be delivered to the **`algorithm`** by setting in the python script. Besides, the **`algorithm`** can call analysis **`tool`** to process the data. 2. **`tool`** contains the true analysis algorithm ## How to use existing method ```bash # The first time git clone https://code.ihep.ac.cn/wudr/SPMTOfflineForCommissioning.git cd SPMTOfflineForCommissioning source setup.sh ./build.sh ``` ```bash # If the software was already compiled, only need to config the environment source setup.sh # in the SPMTOfflineForCommissioning folder ``` ### Convert binary to ROOT ```bash python $SHAREROOT/convert.py --input [path of binary file list] --output [output path (folder only)] # example: python $SHAREROOT/convert.py --input ./rootList --output ./ROOT/ ``` ### Get charge spectrum ```bash python $SHAREROOT/getChargeSpec.py --input [path of ROOT file list] --output [output path (folder only)] ``` ### Get hit rate ```bash python $SHAREROOT/getHitRate.py --input [path of ROOT file list] --output [output path (folder only)] ``` ### Get hit rate distribution in xoy ```bash python $SHAREROOT/getHitRateDis.py --input [path of ROOT file list] --output [output path (folder only)] ``` ### Get time interval ```bash python $SHAREROOT/getTimeInterval.py --input [path of ROOT file list] --output [output path (folder only)] ``` ### Get noise per channel ```bash python $SHAREROOT/getNoise.py --input [path of ROOT file list] --output [output path (folder only)] ``` ## Create your own algorithm Create an **`algorithm`** named `ExampleAlg` in `./Analysis` ```bash cd Analysis mkdir ExampleAlg cd ExampleAlg mkdir src mkdir python mkdir python/ExampleAlg touch python/ExampleAlg/__init__.py touch CMakeLists.txt ``` In `python/ExampleAlg/__init__.py` ```python import Sniper as sn sn.loadDll("libExampleAlg.so") ``` In `CMakeLists.txt` ```cmake PKG(ExampleAlg DEPENDS AnaTool ) ``` An **`algorithm`** is defined as a `c++ class` like ```c++ // Similar to JUNO Offline, this line will register the algorithm DECLARE_ALGORITHM(ExampleAlg); // The *Alg class must inherit from AlgBase class ExampleAlg : public AlgBase { public: // necessary ExampleAlg(const string&); virtual ~ExampleAlg(); // initialize, execute, finalize will be called automatically bool initialize(); bool execute(); bool finalize(); // ... private: Params m_paras; vector<Anatool*> m_tools; //SPMTMap *m_spmtMap; // ... }; // The constructor of AlgBase must be called ExampleAlg::ExampleAlg(const string &name) : AlgBase(name) { // ... } ``` More detail can be found in `./Analysis/CommissioningAlg/`. ## Create your own analysis tool Similar to `ExampleAlg`, the folders, CMakeLists.txt and \_\_init\_\_.py should be created A **`tool`** is defined as a `c++ class` too. ```c++ DECLARE_TOOL(ExampleTool); class ExampleTool : public AnaTool, public ToolBase { public: ExampleTool(const string&); virtual ~ExampleTool(); bool configure(string, const SPMTMap*); bool analyze(const Params&); bool output(); private: // ... }; ExampleTool::ExampleTool(const string &name) : ToolBase(name) {} bool ExampleTool::configure(string outputDir, const SPMTMap *map) { // initialization return true; } bool ExampleTool::analyze(const Params& paras) { // output gcu ID // with paras.get("NAME_OF_PROPERTY") you can get the property you need // the properties aviliable you chan find in the CommissioningAlg.cc LogInfo << paras.get("GCU_ID") << endl; return true; } bool ExampleTool::output() { m_canvas->cd(); m_hist->Draw(); m_canvas->SaveAs("dir.pdf"); } ``` More detail can be found in `./Analysis/NoiseAnaTool/` ## How to compile ```bash source setup.sh ./build.sh ``` ## How to add your own algorithm or tool If the **`algorithm`** named `ExampleAlg` was created in `./Analysis`, the folder's name should be add in the `./Analysis/CMakeLists.txt` as ```cmake add_subdirectory(ExampleAlg) ``` ## How to run There is an example of python script name `run.py` in `./share/`. When you want to run a new **`tool`** or **`algorithm`**, you can add them into a copy of run.py like ```python import Sniper import CommissioningAlg # Initial task and algorithm # ======================================== task = Sniper.TopTask("spmtAna") alg = task.createAlg("CommissioningAlg") # ======================================== # Add new tool here import NoiseAnaTool # Add new tool here alg.createTool("NoiseAnaTool") # Set arguments # ======================================== alg.property("inputList").set(args.input) alg.property("outputDir").set(args.output) alg.property("evtMax").set(args.evtmax) alg.property("toolNameList").set(args.toollist) ``` And the name of the **`tool`** should be added into `./share/toolList` ```bash # python run.py --input [list of input] --output [output directory] --evtmax [the number of event will be processed for every ROOT file, -1 means all] --toollist [list of tool] python run.py --input ./listOfInput --output ./result/ --evtmax -1 --toollist ./toolList ``` ## Suggestions 1. The `CommissioningAlg` can read in the current version of ROOT file, only tools are needed for different tasks. 2. There is a standard method for converting from binary file to ROOT file.