# 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

## 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 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 analsis 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
	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.