Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
f0551e4
Add .gitignore
maxgalli Oct 27, 2020
e670060
Start refactoring Python-pkg style - Move everything in legacy and ca…
maxgalli Feb 9, 2021
9587174
Add setup.py file
maxgalli Oct 27, 2020
254864b
Change all calls to 'print' to instances og logger.info, in order to …
maxgalli Oct 27, 2020
bf405cd
Add tmva subpackage, install it and fix relative imports
maxgalli Feb 9, 2021
eb038b5
Add plotting subpackage and install to setup.py
maxgalli Feb 9, 2021
570aedb
Add syst subpackage and install it, fix relative imports
maxgalli Feb 9, 2021
68988ab
Add convert subpackage and install
maxgalli Feb 9, 2021
563c5a3
Change syntax for py2 style prints in tmva. Updated to logger.info.
maxgalli Oct 27, 2020
84b14f3
Switch to uproot to get pandas dataframes from root files for perform…
maxgalli Oct 28, 2020
4a8080d
Change deprecated pandas.ix to pandas.iloc
maxgalli Oct 28, 2020
1dfa66a
Add suffix '_Sc' to tagPhiWidth and tagEtaWidth
maxgalli Oct 28, 2020
9df6cbb
Add absolute path safety check for workDir and allow weightsDir to be…
maxgalli Oct 29, 2020
651796d
Py2->Py3: xrange->range
maxgalli Feb 9, 2021
7750255
Add quantiles to API
maxgalli Nov 11, 2020
9681d0c
Change IOError to FileNotFoundError
maxgalli Jan 7, 2021
50868dc
Fixes that broke final part
maxgalli Jan 15, 2021
76a2ed9
Add Ray as backend for Joblib
maxgalli Feb 9, 2021
fdd7503
Add utils for 1 - tnp ntuples production
maxgalli Feb 10, 2021
a34c4e6
Add files to setup Ray on SLURM + documentation
maxgalli Feb 17, 2021
2eb13eb
Add utils for 2 - pandas dataframes production
maxgalli Feb 17, 2021
b94a4c5
Add utils for 3 - data training
maxgalli Feb 17, 2021
1f7e72b
Add utils for 4 - train MC shapes
maxgalli Feb 23, 2021
0ee57de
Add utils for 5 - Bayesian Optimization
maxgalli Feb 23, 2021
9c8271e
Add utils for 6 - Final Training and IdMVA
maxgalli Feb 23, 2021
c1ef7b5
Add utils for 7 - Plots
maxgalli Feb 23, 2021
b9cb24c
Add utils for 9 - Convert format
maxgalli Feb 23, 2021
2a93209
Fix import errors form produce_systematics.py
maxgalli Feb 24, 2021
0a1c048
Add utils for 8 - Systematics
maxgalli Feb 24, 2021
63b6638
Add documentation for main and 1
maxgalli Feb 24, 2021
a76f87c
Py2 -> Py3 in Pandas: loc -> reindex
maxgalli Apr 13, 2021
c203619
Forgotten changes to be cherry-picked in TO_MERGE branch
maxgalli Apr 13, 2021
34e0869
Add forgotten script to run data training for all systematics
maxgalli May 12, 2021
f223950
Add files for Preshower: 3 - Data training
maxgalli May 12, 2021
d3c94c0
Add files for Preshower: 4 - MC training
maxgalli May 12, 2021
b526d37
Add files for Preshower - Final training
maxgalli May 13, 2021
76f921e
Add files for Preshower - Plotting
maxgalli May 13, 2021
ab46dff
Add files for Preshower - Sistematics
maxgalli May 13, 2021
e9c0ab5
Add readme for 10 - Preshower
maxgalli May 13, 2021
a84faf1
Revert previous change in plot_base since it didn't seem to work with…
maxgalli May 13, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 59 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]

# C extensions
*.so

# Distribution / packaging
bin/
build/
develop-eggs/
dist/
eggs/
lib/
lib64/
parts/
sdist/
var/
*.egg-info/
.installed.cfg
*.egg

# Installer logs
pip-log.txt
pip-delete-this-directory.txt

# Unit test / coverage reports
.tox/
.coverage
.cache
nosetests.xml
coverage.xml

# Translations
*.mo

# Mr Developer
.mr.developer.cfg
.project
.pydevproject

# Rope
.ropeproject

# Django stuff:
*.log
*.pot

# Sphinx documentation
docs/_build/

# vim
*.swp
*.swo

# config files and scripts
*.sh
*.yml
*.yaml
101 changes: 26 additions & 75 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,77 +1,28 @@
# Chained quantile regression
This repo contains the code to do data/MC correction using chained quantile regression and stochastic matching.
The class `quantileRegression_chain` can be used to correct a set of continious variables differentially and
while keeping their correlations. The class `quantileRegression_chain_disc` can be used to correct discontinious variables.
## Training BDTs for quantiles
To train the BDTs that will be used to extract the conditional pdf the functions `trainOnData` for data and `trainOnMC`
for MC have to be used. For example:
```python
import quantileRegression_chain as qRegC
qRC = qRegC.quantileRegression_chain(year,EBEE,workDir,variables)
qRC.loadDataDF(df_name,0,stop,rsh,columns)
qRC.trainOnData(variable,weightsDir)
```
# Scripts for training
The strategy to train on a large dataset is the following
1. Train on data

To train on data use `scripts/run_qRC_training.sh`
```bash
./run_qRC_training.sh <config_file_ShowerShapes>.yaml <config_file_PhotonIso>.yaml <config_file_ChargedIsos>.yaml <n_evts> <EB/EE>
```
This will submit one job per quantile per variable to the SGE queue via qub. BEWARE: There is a hard coded path in this script. Change it accordingly

2. Train Shower Shapes on MC

To train the shower shape correction for MC use `training/train_qRC_MC.py`. Before starting the training on MC, the training on Data needs to be finished completely
```bash
python train_qRC_MC.py -c <config_file_ShowerShapes>.yaml -N <n_evts> -E <EB/EE> -B <cluster_profile> -i <cluster_id>
```

3. Train Isolations on MC

To train the shower shape correction for MC use `training/train_qRC_MC.py`
```bash
python train_qRC_I_MC.py -c <config_file_(PhotonIso/ChargedIsos)>.yaml -N <n_evts> -E <EB/EE> -B <cluster_profile> -i <cluster_id>
```

## Final corrections training

After validating the initial training, one can train the final single regressors that can be used to apply the corrections to the simulation in production. To do so, follow these steps:

1. Train the final shower shape corrections

To train the final shower shape correction use `training/train_final_Reg_SS.py`
```bash
python train_final_Reg_SS.py -c <config_file_ShowerShapes>.yaml -N <n_evts> -E <EB/EE> -B <ipython_cluster_profile> -i <cluster_id> -n 21
```
2. Train final charged Iso corrections

To train the final correction for the charged isolations use `training/train_final_Reg_Iso.py`
```bash
python train_final_Reg_Iso.py -c <config_file_(ChargedIsos)>.yaml -N <n_evts> -E <EB/EE> -B <ipython_cluster_profile> -i <cluster_id> -n 21
```

3. Train final photon Iso corrections

To train the final correction for the photon isolation use `training/train_final_Reg_Iso.py`
```bash
python train_final_Reg_Iso.py -c <config_file_(PhotonIso)>.yaml -N <n_evts> -E <EB/EE> -B <ipython_cluster_profile> -i <cluster_id> -n 21
```

The only difference between the command for charged and photon Iso are the config files

### Note on config files

In general the config files for the training for data and simulation for the initial and final training have the same format. Examples can be found in `examples`. The following keywords should be used

| Keyword | Used for |
|------------|----------------------------------------------------------------------------|
| Dataframes | `(data/mc)_(EB/EE)` for the dataframe for data/MC in EB/EE |
| variables | The list of variables to be corrected. The order here is important |
| year | The year of data-taking the relevant datasets are from |
| workDir | the path to the working dir, dataframes and weightsDir need to be in there |
| weightsDir | directory to store the weights. Create before training |
| outDir | directory to store the final weight. Create before training |
# Quantile Regression Chain for Data/MC Corrections

## Motivation
TODO

## Installation
After cloning the repository and entering it, run:
```bash
$ python setup.py install
```
to install the package.
All the dependencies should be handled by the ```setup.py``` script itself.

## Run
The process is rather long and involves submission of jobs on a cluster running [SLURM](https://slurm.schedmd.com/) and internal parallelization that can be performed either with [Ray](https://ray.io/) or [IPyParallel](https://ipyparallel.readthedocs.io/en/latest/#).
The ```utils``` directory contains directories numbered from 1 to 9 with the code and instructions to run, plus directory (```setup_ray```) with the scripts to setup a Ray cluster for the internal parallelization needed in some steps.

Following are the main steps:

1. TagAndProbe NTuples production
2. Pandas dataframes production
3. Data training
4. Montecarlo training
5. Bayesian optimization
6. Final training and IdMVA computation
7. Plot
8. Systematic uncertainties
9. Regressors conversion
1 change: 0 additions & 1 deletion __init__.py

This file was deleted.

77 changes: 77 additions & 0 deletions legacy/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
# Chained quantile regression
This repo contains the code to do data/MC correction using chained quantile regression and stochastic matching.
The class `quantileRegression_chain` can be used to correct a set of continious variables differentially and
while keeping their correlations. The class `quantileRegression_chain_disc` can be used to correct discontinious variables.
## Training BDTs for quantiles
To train the BDTs that will be used to extract the conditional pdf the functions `trainOnData` for data and `trainOnMC`
for MC have to be used. For example:
```python
import quantileRegression_chain as qRegC
qRC = qRegC.quantileRegression_chain(year,EBEE,workDir,variables)
qRC.loadDataDF(df_name,0,stop,rsh,columns)
qRC.trainOnData(variable,weightsDir)
```
# Scripts for training
The strategy to train on a large dataset is the following
1. Train on data

To train on data use `scripts/run_qRC_training.sh`
```bash
./run_qRC_training.sh <config_file_ShowerShapes>.yaml <config_file_PhotonIso>.yaml <config_file_ChargedIsos>.yaml <n_evts> <EB/EE>
```
This will submit one job per quantile per variable to the SGE queue via qub. BEWARE: There is a hard coded path in this script. Change it accordingly

2. Train Shower Shapes on MC

To train the shower shape correction for MC use `training/train_qRC_MC.py`. Before starting the training on MC, the training on Data needs to be finished completely
```bash
python train_qRC_MC.py -c <config_file_ShowerShapes>.yaml -N <n_evts> -E <EB/EE> -B <cluster_profile> -i <cluster_id>
```

3. Train Isolations on MC

To train the shower shape correction for MC use `training/train_qRC_MC.py`
```bash
python train_qRC_I_MC.py -c <config_file_(PhotonIso/ChargedIsos)>.yaml -N <n_evts> -E <EB/EE> -B <cluster_profile> -i <cluster_id>
```

## Final corrections training

After validating the initial training, one can train the final single regressors that can be used to apply the corrections to the simulation in production. To do so, follow these steps:

1. Train the final shower shape corrections

To train the final shower shape correction use `training/train_final_Reg_SS.py`
```bash
python train_final_Reg_SS.py -c <config_file_ShowerShapes>.yaml -N <n_evts> -E <EB/EE> -B <ipython_cluster_profile> -i <cluster_id> -n 21
```
2. Train final charged Iso corrections

To train the final correction for the charged isolations use `training/train_final_Reg_Iso.py`
```bash
python train_final_Reg_Iso.py -c <config_file_(ChargedIsos)>.yaml -N <n_evts> -E <EB/EE> -B <ipython_cluster_profile> -i <cluster_id> -n 21
```

3. Train final photon Iso corrections

To train the final correction for the photon isolation use `training/train_final_Reg_Iso.py`
```bash
python train_final_Reg_Iso.py -c <config_file_(PhotonIso)>.yaml -N <n_evts> -E <EB/EE> -B <ipython_cluster_profile> -i <cluster_id> -n 21
```

The only difference between the command for charged and photon Iso are the config files

### Note on config files

In general the config files for the training for data and simulation for the initial and final training have the same format. Examples can be found in `examples`. The following keywords should be used

| Keyword | Used for |
|------------|----------------------------------------------------------------------------|
| Dataframes | `(data/mc)_(EB/EE)` for the dataframe for data/MC in EB/EE |
| variables | The list of variables to be corrected. The order here is important |
| year | The year of data-taking the relevant datasets are from |
| workDir | the path to the working dir, dataframes and weightsDir need to be in there |
| weightsDir | directory to store the weights. Create before training |
| outDir | directory to store the final weight. Create before training |


File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
24 changes: 14 additions & 10 deletions tmva/xgboost2tmva.py → legacy/tmva/xgboost2tmva.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@
import xml.etree.cElementTree as ET
regex_float_pattern = r'[-+]?(\d+(\.\d*)?|\.\d+)([eE][-+]?\d+)?'

import logging
logger = logging.getLogger(__name__)


def build_tree(xgtree, base_xml_element, var_indices):
parent_element_dict = {'0':base_xml_element}
pos_dict = {'0':'s'}
Expand All @@ -13,7 +17,7 @@ def build_tree(xgtree, base_xml_element, var_indices):
#leaf node
result = re.match(r'(\t*)(\d+):leaf=({0})$'.format(regex_float_pattern), line)
if not result:
print(line)
logger.info(line)
depth = result.group(1).count('\t')
inode = result.group(2)
res = result.group(3)
Expand All @@ -23,7 +27,7 @@ def build_tree(xgtree, base_xml_element, var_indices):
#\t\t3:[var_topcand_mass<138.19] yes=7,no=8,missing=7
result = re.match(r'(\t*)([0-9]+):\[(?P<var>.+)<(?P<cut>{0})\]\syes=(?P<yes>\d+),no=(?P<no>\d+)'.format(regex_float_pattern),line)
if not result:
print(line)
logger.info(line)
depth = result.group(1).count('\t')
inode = result.group(2)
var = result.group('var')
Expand All @@ -37,12 +41,12 @@ def build_tree(xgtree, base_xml_element, var_indices):
cType="1", res="0.0e+00", rms="0.0e+00", purity="0.0e+00", nType="0")
parent_element_dict[lnode] = node_elementTree
parent_element_dict[rnode] = node_elementTree

def convert_model(model, input_variables, output_xml):
NTrees = len(model)
var_list = input_variables
var_indices = {}

# <MethodSetup>
MethodSetup = ET.Element("MethodSetup", Method="BDT::BDT")

Expand All @@ -52,8 +56,8 @@ def convert_model(model, input_variables, output_xml):
name = val[0]
var_type = val[1]
var_indices[name] = ind
Variable = ET.SubElement(Variables, "Variable", VarIndex=str(ind), Type=val[1],
Expression=name, Label=name, Title=name, Unit="", Internal=name,
Variable = ET.SubElement(Variables, "Variable", VarIndex=str(ind), Type=val[1],
Expression=name, Label=name, Title=name, Unit="", Internal=name,
Min="0.0e+00", Max="0.0e+00")

# <GeneralInfo>
Expand All @@ -65,18 +69,18 @@ def convert_model(model, input_variables, output_xml):
Options = ET.SubElement(MethodSetup, "Options")
Option_NodePurityLimit = ET.SubElement(Options, "Option", name="NodePurityLimit", modified="No").text = "5.00e-01"
Option_BoostType = ET.SubElement(Options, "Option", name="BoostType", modified="Yes").text = "Grad"

# <Weights>
Weights = ET.SubElement(MethodSetup, "Weights", NTrees=str(NTrees), AnalysisType="1")

for itree in range(NTrees):
BinaryTree = ET.SubElement(Weights, "BinaryTree", type="DecisionTree", boostWeight="1.0e+00", itree=str(itree))
build_tree(model[itree], BinaryTree, var_indices)

tree = ET.ElementTree(MethodSetup)
tree.write(output_xml)
# format it with 'xmllint --format'

# example
# bst = xgb.train( param, d_train, num_round, watchlist );
# model = bst.get_dump()
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
1 change: 0 additions & 1 deletion python/__init__.py

This file was deleted.

12 changes: 6 additions & 6 deletions python/Corrector.py → quantile_regression_chain/Corrector.py
Original file line number Diff line number Diff line change
@@ -1,27 +1,27 @@
import numpy as np

class Corrector:

# store regressors
def __init__(self,mcclf,dataclf,X,Y,diz=False):
self.diz=diz #Flag for distribution with discrete 0, i.e. Isolation
self.mcqtls = np.array([clf.predict(X) for clf in mcclf])
self.dataqtls = np.array([clf.predict(X) for clf in dataclf])

self.Y = Y

# correction is actually done here
def correctEvent(self,iev):

mcqtls = self.mcqtls[:,iev]
dataqtls = self.dataqtls[:,iev]
Y = self.Y[iev]

if self.diz and Y == 0.:
return 0.

qmc =0

while qmc < len(mcqtls): # while + if, to avoid bumping the range
if mcqtls[qmc] < Y:
qmc+=1
Expand All @@ -38,11 +38,11 @@ def correctEvent(self,iev):
qmc_low,qdata_low = mcqtls[qmc-1],dataqtls[qmc-1]
qmc_high,qdata_high = mcqtls[len(mcqtls)-1]*1.2,dataqtls[len(dataqtls)-1]*1.2
# to set the value for the highest quantile 20% higher

return (qdata_high-qdata_low)/(qmc_high-qmc_low) * (Y - qmc_low) + qdata_low

def __call__(self):
return np.array([ self.correctEvent(iev) for iev in xrange(self.Y.size) ]).ravel()
return np.array([ self.correctEvent(iev) for iev in range(self.Y.size) ]).ravel()

def applyCorrection(mcclf,dataclf,X,Y,diz=False):
return Corrector(mcclf,dataclf,X,Y,diz)()
Loading