Commit 034d2384 authored by Erik Asbjørn Mikkelsen Jensen's avatar Erik Asbjørn Mikkelsen Jensen
Browse files

ROOTCON now prerequisite for example figure production

parent 055e17c1
...@@ -7,7 +7,6 @@ __pycache__ ...@@ -7,7 +7,6 @@ __pycache__
*.root *.root
# exectuable output # exectuable output
dataprinter
expand-nuchart-QEC expand-nuchart-QEC
expand-nuchart-QECp expand-nuchart-QECp
expand-nuchart-QEC2p expand-nuchart-QEC2p
......
...@@ -8,19 +8,18 @@ EXAMPLE_FIGURES = qec-all.pdf qec-no-estimates.pdf beta-delayed.pdf ...@@ -8,19 +8,18 @@ EXAMPLE_FIGURES = qec-all.pdf qec-no-estimates.pdf beta-delayed.pdf
EXAMPLE_DATAFILES = qec.dat beta-delayed.dat EXAMPLE_DATAFILES = qec.dat beta-delayed.dat
EXPANSION_DIR = expansion EXPANSION_DIR = expansion
EXPANSION_EXS = expand-nuchart-QEC expand-nuchart-QECp expand-nuchart-QEC2p expand-nuchart-QECa expand-nuchart-QB2n expand-nuchart-QBa EXPANSION_EXS = expand-nuchart-QEC expand-nuchart-QECp expand-nuchart-QEC2p expand-nuchart-QECa expand-nuchart-QB2n expand-nuchart-QBa
EXS = dataprinter
.PHONEY: default all example1 clean .PHONEY: default all example1 clean
default: nuchart.root dataprinter default: nuchart.root
all: default example1 example2 all: default example1 example2
nuchart.root: treemaker.py $(addprefix $(EXPANSION_DIR)/, $(EXPANSION_EXS)) nuchart.root: treemaker.py $(addprefix $(EXPANSION_DIR)/, $(EXPANSION_EXS))
ifeq ($(ROOTSYS), ) # source thisroot.sh if ROOTSYS is not defined ifeq ($(ROOTSYS), ) # source thisroot.sh if ROOTSYS is not defined
source $$(root-config --bindir)/thisroot.sh && python3 treemaker.py . thisroot.sh && python3 treemaker.py
else else
python3 treemaker.py python3 treemaker.py
endif endif
...@@ -31,23 +30,18 @@ example1: $(EXAMPLE_DIR)/graph-example-qec.py # PHONEY target avoids multiple ex ...@@ -31,23 +30,18 @@ example1: $(EXAMPLE_DIR)/graph-example-qec.py # PHONEY target avoids multiple ex
$(EXAMPLE_DIR)/graph-example-qec.py: $(EXAMPLE_DIR)/qec.dat $(EXAMPLE_DIR)/graph-example-qec.py: $(EXAMPLE_DIR)/qec.dat
$(EXAMPLE_DIR)/qec.dat: dataprinter nuchart.root Makefile $(EXAMPLE_DIR)/qec.dat: nuchart.root Makefile
./$< nuchart.root a A Z QEC QEC_est "A <= 70" "QEC > 0" > $@ # `Dataprinter` is available at gitlab.au.dk/ausa/erik/rootcon
Dataprinter $< a A Z QEC QEC_est "A <= 70" "QEC > 0" > $@
example2: $(EXAMPLE_DIR)/graph-example-beta-delayed.py example2: $(EXAMPLE_DIR)/graph-example-beta-delayed.py
python3 $< python3 $<
$(EXAMPLE_DIR)/graph-example-beta-delayed.py: $(EXAMPLE_DIR)/beta-delayed.dat $(EXAMPLE_DIR)/graph-example-beta-delayed.py: $(EXAMPLE_DIR)/beta-delayed.dat
$(EXAMPLE_DIR)/beta-delayed.dat: dataprinter nuchart.root Makefile $(EXAMPLE_DIR)/beta-delayed.dat: nuchart.root Makefile
./$< nuchart.root a Z N QECp QBn QEC2p QB2n QECa QBa QECp_est QBn_est QEC2p_est QB2n_est QECa_est QBa_est half_life_stbl "Z <= 50" "N <= 50" > $@ # `Dataprinter` is available at gitlab.au.dk/ausa/erik/rootcon
Dataprinter $< a Z N QECp QBn QEC2p QB2n QECa QBa QECp_est QBn_est QEC2p_est QB2n_est QECa_est QBa_est half_life_stbl "Z <= 50" "N <= 50" > $@
dataprinter: dataprinter.cxx
ifeq ($(ROOTSYS), ) # source thisroot.sh if ROOTSYS is not defined
source $$(root-config --bindir)/thisroot.sh && $(CXX) $(CXXFLAGS) -o $@ $< $(LDLIBS)
else
$(CXX) $(CXXFLAGS) -o $@ $< $(LDLIBS)
endif
$(EXPANSION_DIR)/expand-nuchart-QEC: $(EXPANSION_DIR)/expand-nuchart-QEC.cxx $(EXPANSION_DIR)/expand-nuchart-QEC: $(EXPANSION_DIR)/expand-nuchart-QEC.cxx
$(CXX) $(CXXFLAGS) -o $@ $< $(LDLIBS) $(CXX) $(CXXFLAGS) -o $@ $< $(LDLIBS)
...@@ -73,5 +67,5 @@ datagetter.py: $(DATATABLES) ...@@ -73,5 +67,5 @@ datagetter.py: $(DATATABLES)
clean: clean:
$(RM) -r __pycache__ $(RM) -r __pycache__
$(RM) nuchart.root $(addprefix $(EXPANSION_DIR)/, $(EXPANSION_EXS)) $(EXS) \ $(RM) nuchart.root $(addprefix $(EXPANSION_DIR)/, $(EXPANSION_EXS)) \
$(addprefix $(EXAMPLE_DIR)/, $(EXAMPLE_FIGURES)) $(addprefix $(EXAMPLE_DIR)/, $(EXAMPLE_DATAFILES)) $(addprefix $(EXAMPLE_DIR)/, $(EXAMPLE_FIGURES)) $(addprefix $(EXAMPLE_DIR)/, $(EXAMPLE_DATAFILES))
...@@ -16,33 +16,22 @@ This specific expansion, among others, is carried out in the C++ files in the ...@@ -16,33 +16,22 @@ This specific expansion, among others, is carried out in the C++ files in the
***expansion*** directory. ***expansion*** directory.
Those files serve as general templates for doing further user-specified expansions. Those files serve as general templates for doing further user-specified expansions.
As an added bonus, so to say, the ***dataprinter*** executable made in this project In the ***examples*** directory some figures are produced
can take any ROOT file containing a tree, and, given various parameters and as examples of the values one can extract from *Nuchart*.
conditions on the parameters, produce output in easily human- and machine-interpretable
ASCII format containing just the parameters fulfilling the given conditions.
This enables further manipulation/analysis of the data outside of ROOT.
***dataprinter*** is utilised in the ***examples*** directory (via the project
***Makefile***), in which some figures are produced (outside of ROOT, in python)
as examples of the values one can extract from *Nuchart*.
Please see ***dataprinter.cxx*** or perhaps the ***Makefile*** for further information
on how to use it.
### Prerequisites ### Prerequisites
The prerequisites for producing ***nuchart.root*** and ***dataprinter*** are The prerequisites for producing ***nuchart.root*** are
* GNU Make * GNU Make
* A fairly recent C++ compiler
* Python 3.0 or above * Python 3.0 or above
* ROOT with the PyROOT module installed * ROOT with the PyROOT module installed
In order to produce the example figures, the Python libraries NumPy and Matplotlib In order to produce the example figures, [ROOTCON](https://gitlab.au.dk/ausa/erik/rootcon)
are also required. as well as the Python libraries NumPy and Matplotlib are also required.
### Building ### Building
In order to build ***nuchart.root*** and ***dataprinter*** run In order to build ***nuchart.root*** run
```shell script ```shell script
make make
...@@ -58,15 +47,6 @@ make all ...@@ -58,15 +47,6 @@ make all
in the project's main directory. in the project's main directory.
If you are here only for the ***dataprinter*** run
```shell script
make dataprinter
```
in the project's main directory.
### Project status ### Project status
While the project is mostly ready to be used, there are still a few details that While the project is mostly ready to be used, there are still a few details that
need fixing or tweaking. need fixing or tweaking.
...@@ -80,7 +60,7 @@ These are listed below. ...@@ -80,7 +60,7 @@ These are listed below.
#### Done #### Done
* Everything prior * Everything prior
* Make generic script which writes desired values from root file to a text file * Make generic script which writes desired values from root file to a text file (became ROOTCON)
* Combine subprojects into one big project * Combine subprojects into one big project
* Make QEC example * Make QEC example
* Tidied root folder up * Tidied root folder up
......
/*
* This program prints an arbitrary number of variables (branches/leaves), stored in
* a ROOT tree in a ROOT file, along with an arbitrary number of criteria on the
* variables to stdout.
* The syntax for executing the program is:
* dataprinter filename treename [var1 var2 ... varN] [crt1 crt2 ... crtM]
* with 'filename' the name of the ROOT file,
* 'treename' the name of the tree in the ROOT file,
* 'var1', etc. the variables stored in the tree which are to be printed
* 'crt1', etc. the criteria on the variables (given as "C comparison strings").
* For example, given a ROOT file named 'nuchart.root' containing a tree named 'a' and
* with variables (among others) 'A', 'Z', 'QEC', 'QEC_est' we can run
* > dataprinter nuchart.root a A Z QEC QEC_est "A <= 70" "QEC >= 0"
* where the last two arguments, given as strings, makes it so the variables 'A', 'Z',
* 'QEC', 'QEC_est' are only printed to stdout for values of 'A' less than or equal to
* 70 and values of 'QEC' greater than or equal to zero.
*/
#include <iostream>
#include <string>
#include <vector>
#include <fstream>
#include <TFile.h>
#include <TTree.h>
using namespace std;
vector<string> comps{"==", "!=", "<", ">", "<=", ">="};
void modify_and_print(string filename) {
ifstream ifs(filename.c_str());
string line;
getline(ifs, line); // skip first line
getline(ifs, line);
line[0] = '#';
for (char& c : line) {
if (c == '*') c = ' ';
}
cout << line << endl;
getline(ifs, line); // skip third line
int flag = 0;
while (getline(ifs, line)) {
for (char& c : line) {
if (c == '*') c = ' ';
if (c == '=') flag = 1; // skip final line
}
if (flag == 0) cout << line << endl;
}
}
bool is_crit(string str) {
for (string q : comps) {
if (str.find(q) != string::npos) return true; // if string q is found in string str, str is a criterion
}
return false;
}
int main(int argc, char* argv[]) {
// Open the root-file, which is the first given argument, and access its tree with the name of the second given argument
TFile input(argv[1]);
TTree *t;
input.GetObject(argv[2], t);
// Separate out all other arguments as either parameters to be printed or criteria on the parameters (comparison statements)
vector<string> args(argv + 3, argv + argc);
vector<string> argtypes;
string printvars = "";
string selection = "";
for (string s : args) {
if (!is_crit(s)) {
if (!printvars.empty()) printvars += ":"; // printvars = "var1:var2:var3:...:varN" when we are done
printvars += s;
argtypes.emplace_back("var");
} else {
if (!selection.empty()) selection += " && "; // selection = "sel1 && sel2 && sel3 && ... && selM" when we are done
selection += s;
argtypes.emplace_back("sel");
}
}
/*
* TTree::Scan, used below, prints the parameters with the criteria we ask for, but it contains
* symbols, mainly lots of "*"'s, and lines which we need to replace or remove.
* More precisely, TTree::Scan prints the output via printf statements, and the only way to
* properly catch the output, modify the output and then print the modified output, as far as I
* can tell, is to redirect stdout (different from cout) to a file, then read the file, then
* modify its contents, etc.
* The temporary file will be deleted again when we are done.
*/
FILE* saved = stdout;
string tmpf = "tmp.dat";
stdout = fopen(tmpf.c_str(), "w"); // stdout redirected to temporary file
t->SetScanField(0); // print all data in one go (any int > 0 would print only that amount)
t->Scan(printvars.c_str(), selection.c_str());
fclose(stdout);
stdout = saved; // stdout back to normal
// Print a comment line showing the command which created the output
cout << "###### Output created with the following command ######" << endl;
cout << "# ";
int i;
for (i = 0; i < 3; i++) {
cout << argv[i] << " ";
}
for (string s : argtypes) {
if (s.compare("var") == 0) {
cout << argv[i] << " ";
i++;
} else if (s.compare("sel") == 0) {
cout << "\"" << argv[i] << "\" ";
i++;
}
}
cout << endl;
// Print output in suitable format
modify_and_print(tmpf);
remove(tmpf.c_str());
input.Close();
return EXIT_SUCCESS;
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment