ConfigurationSettings.cxx 55.2 KB
Newer Older
1
/*
2
   Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
Tomas Dado's avatar
Tomas Dado committed
3
 */
4
5
6
7
8
9
10
11
12
13
14
15
16

#include "TopConfiguration/ConfigurationSettings.h"

#include <algorithm>
#include <cstdlib>
#include <fstream>
#include <sstream>
#include <iomanip>
#include <iostream>
#include <boost/algorithm/string.hpp>
#include <boost/algorithm/string/trim_all.hpp>

namespace top {
Tomas Dado's avatar
Tomas Dado committed
17
  ConfigurationSettings* ConfigurationSettings::m_instance = 0;
18

Tomas Dado's avatar
Tomas Dado committed
19
  ConfigurationSettings::ConfigurationSettings() : m_configured(false) {
20
    registerParameter("ElectronCollectionName", "Name of the Electron container");
21
    registerParameter("FwdElectronCollectionName", "Name of the Forward Electrons container, ForwardElectrons or None (default)", "None");
22
23
24
25
    registerParameter("MuonCollectionName", "Name of the Muon container");
    registerParameter("PhotonCollectionName", "Name of the Photon container");
    registerParameter("JetCollectionName", "Name of the Jet container");
    registerParameter("LargeJetCollectionName", "Name of the large-R Jet container");
26
    registerParameter("LargeJetSubstructure", "Setup to use when applying grooming on the large-R jet", "None");
Tomas Dado's avatar
Tomas Dado committed
27
    registerParameter("TrackJetCollectionName", "Name of the track Jet container", "None");
28
    registerParameter("TauCollectionName", "Name of the Tau container");
29
    registerParameter("JetGhostTrackDecoName", "Name of the jet decoration that holds the ghost-associated track.", "None");
30
31

    registerParameter("TruthCollectionName", "Name of the Truth container");
Tomas Dado's avatar
Tomas Dado committed
32
    registerParameter("TruthElectronCollectionName", "Name of the Truth Electron container", "TruthElectrons");
33
34
35
36
37
    registerParameter("TruthMuonCollectionName", "Name of the Truth Muon container", "TruthMuons");
    registerParameter("TruthPhotonCollectionName", "Name of the Truth Photon container", "None");
    registerParameter("TruthMETCollectionName", "Name of the Truth MET container", "MET_Truth");
    registerParameter("TruthJetCollectionName", "Name of the Truth Jet container");
    registerParameter("TruthLargeRJetCollectionName", "Name of the Truth Large R Jet container", "None");
38
    registerParameter("TruthTauCollectionName", "Name of the Truth tau container", "None");
39
40

    registerParameter("applyTTVACut", "Decide if to apply lepton z0/d0 cuts", "True");
41

Tomas Dado's avatar
Tomas Dado committed
42
43
    registerParameter("GRLDir", "Location of GRL File", "TopAnalysis");
    registerParameter("GRLFile", "Name of GRL File", " ");
44

Tomas Dado's avatar
Tomas Dado committed
45
46
    registerParameter("TDPPath", "Path to TopDataPreparation file (accessible via PathResolver)",
                      "dev/AnalysisTop/TopDataPreparation/XSection-MC16-13TeV.data");
47

Tomas Dado's avatar
Tomas Dado committed
48
49
50
51
    registerParameter("DumpBtagSystsInSystTrees",
                      "Dump systematics-shifted b-tagging SFs in systematic TTrees, True or False (default: False)",
                      "False");
    registerParameter("StorePerJetBtagSFs", "Store per-jet btag SFs", "False");
52

Tomas Dado's avatar
Tomas Dado committed
53
54
55
    registerParameter("ElectronID", "Type of electron. Likelihood LooseAndBLayerLH, MediumLH, TightLH", "TightLH");
    registerParameter("ElectronIDLoose",
                      "Type of electron for background. Likelihood LooseAndBLayerLH, MediumLH, TightLH", "MediumLH");
56
    registerParameter("ElectronPt", "Electron pT cut for object selection (in MeV). Default 25 GeV.", "25000.");
Tomas Dado's avatar
Tomas Dado committed
57
58
59
60
61
62
63
64
65
66
67
    registerParameter("EgammaSystematicModel", "Egamma Calibration Systematic model : FULL_v1 , 1NP_v1 (default)",
                      "1NP_v1");
    registerParameter("ElectronEfficiencySystematicModel",
                      "Electron Efficiency Systematic model : FULL, SIMPLIFIED, TOTAL (default)", "TOTAL");
    registerParameter("ElectronEfficiencySystematicModelEtaBinning",
                      "Electron Efficiency Systematic model eta binning (option for SIMPLIFIED model, do not specify to use default; format XXX:YYY:ZZZ, e.g. 0.0:1.37:4.9)",
                      "default");
    registerParameter("ElectronEfficiencySystematicModelEtBinning",
                      "Electron Efficiency Systematic model E_T binning (option for SIMPLIFIED model, do not specify to use default; format XXX:YYY:ZZZ. e.g. 4000:7000:10000:15000:13000000)",
                      "default");
    registerParameter("ElectronIsolation",
68
                      "Isolation to use : Gradient, FCLoose, FCTight, FCHighPtCaloOnly, (EXPERIMENTAL: HighPtCaloOnly, Loose, Tight, TightTrackOnly, TightTrackOnly_FixedRad, PLVTight, PLVLoose), (DANGEROUS: PflowTight, PflowLoose), None",
Tomas Dado's avatar
Tomas Dado committed
69
70
                      "Gradient");
    registerParameter("ElectronIsolationLoose",
71
                      "Isolation to use : Gradient, FCLoose, FCTight, FCHighPtCaloOnly, (EXPERIMENTAL: HighPtCaloOnly, Loose, Tight, TightTrackOnly, TightTrackOnly_FixedRad, PLVTight, PLVLoose), (DANGEROUS: PflowTight, PflowLoose), None",
Tomas Dado's avatar
Tomas Dado committed
72
                      "None");
73
74
    registerParameter("ElectronIsolationSF", "Force electron isolation SF (e.g. None). EXPERIMENTAL!", " ");
    registerParameter("ElectronIsolationSFLoose", "Force electron isolation SF (e.g. None). EXPERIMENTAL!", " ");
Tomas Dado's avatar
Tomas Dado committed
75
76
77
78
79
    registerParameter("ElectronVetoLArCrack", "True/False. Set to False to disable LAr crack veto (not recommended).",
                      "True");
    registerParameter("UseElectronChargeIDSelection",
                      "True/False. Switch on/off electron charge ID selection (Default False).", "False");
    registerParameter("UseEgammaLeakageCorrection",
80
                      "True/False. Switch on/off leakage correction -- REQUIRES ptag>p3947 (Default True).", "True");
81
82
    registerParameter("EnablePromptLeptonImprovedVetoStudies",
		      "True/False. Adds the (many!) variables necessary to validate the PromptLeptonImprovedVeto electron+muon isolation -- TEMPORARY, for studies only (Default False).", "False");
Tomas Dado's avatar
Tomas Dado committed
83
84
85

    registerParameter("FwdElectronID", "Type of fwd electron. Loose, Medium, Tight (default)", "Tight");
    registerParameter("FwdElectronIDLoose", "Type of fwd loose electrons. Loose, Medium, Tight (default)", "Tight");
86
87
88
    registerParameter("FwdElectronPt", "Fwd Electron pT cut for object selection (in MeV). Default 25 GeV.", "25000.");
    registerParameter("FwdElectronMinEta", "Fwd Electron lower |eta| cut for object selection. Default 2.5", "2.5");
    registerParameter("FwdElectronMaxEta", "Fwd Electron upper |eta| cut for object selection. Default 4.9", "4.9");
Tomas Dado's avatar
Tomas Dado committed
89
90
91
    registerParameter("FwdElectronBCIDCleaningRunRange",
                      "Specify run range for which the BCID cleaning must be applied for fwd el. in data: \"XXX:YYY\"; the cleaning will be applied for XXX<=runNumber<=YYY",
                      "266904:311481");
92

93
94
95

    registerParameter("PhotonPt", "Photon pT cut for object selection (in MeV). Default 25 GeV.", "25000.");
    registerParameter("PhotonEta", "Absolute Photon eta cut for object selection. Default 2.5.", "2.5");
Tomas Dado's avatar
Tomas Dado committed
96
97
98
99
100
101
102
103
104
105
106
    registerParameter("PhotonID", "Type of photon. Definition to use : Tight, Loose and None.", "Tight");
    registerParameter("PhotonIDLoose", "Type of photon for background. Definition to use : Tight, Loose, None.",
                      "Loose");
    registerParameter("PhotonIsolation",
                      "Isolation to use : FixedCutTightCaloOnly, FixedCutTight, FixedCutLoose, (EXPERIMENTAL: TightCaloOnly, Tight, Loose), None.",
                      "FixedCutTight");
    registerParameter("PhotonIsolationLoose",
                      "Isolation to use : FixedCutTightCaloOnly, FixedCutTight, FixedCutLoose, (EXPERIMENTAL: TightCaloOnly, Tight, Loose), None.",
                      "FixedCutLoose");
    registerParameter("PhotonUseRadiativeZ", "True/False. Set to True to enable photon radiative Z up to 100 GeV.",
                      "False");
107
108

    registerParameter("MuonPt", "Muon pT cut for object selection (in MeV). Default 25 GeV.", "25000");
Tomas Dado's avatar
Tomas Dado committed
109
110
111
112
113
114
115
    registerParameter("MuonEta", "Absolute Muon eta cut for object selection. Default 2.5.", "2.5");
    registerParameter("MuonQuality",
                      "Muon quality cut for object selection. Options are VeryLoose, Loose, Medium (default) and Tight",
                      "Medium");
    registerParameter("MuonQualityLoose",
                      "Muon quality cut for object selection. Options are VeryLoose, Loose, Medium (default) and Tight",
                      "Medium");
116
    registerParameter("MuonUseMVALowPt",
117
118
		      "Turn on MVA for low-pT muons (only for LowPt WP). Optimized to improve efficiency and hadron rejection. - Default: False",
		      "False");
119
    registerParameter("MuonUse2stationHighPt",
120
121
		      "Allows muon reconstruction using 2-station muons with missing inner MS station for |eta|<1.3 - Default: True (only for HighPt)",
		      "True");
122
    registerParameter("MuonUseMVALowPtLoose",
123
124
		      "Turn on MVA for low-pT muons (only for LowPt WP) for Loose tree. Optimized to improve efficiency and hadron rejection. - Default: False",
		      "False");
125
    registerParameter("MuonUse2stationHighPtLoose",
126
127
		      "Allows muon reconstruction using 2-station muons with missing inner MS station for |eta|<1.3 for Loose tree - Default: True (only for HighPt)",
		      "True");
Tomas Dado's avatar
Tomas Dado committed
128
    registerParameter("MuonIsolation",
129
130
                      "Isolation to use : PflowTight_VarRad, PflowTight_FixedRad, PflowLoose_VarRad, PflowLoose_FixedRad, HighPtTrackOnly, TightTrackOnly_VarRad, TightTrackOnly_FixedRad, PLVTight, PLVLoose, Tight_VarRad, Tight_FixedRad, Loose_VarRad, Loose_FixedRad, FCTight, FCLoose, FCTightTrackOnly, FCTightTrackOnly_FixedRad, FCLoose_FixedRad, FCTight_FixedRad, FixedCutPflowTight, FixedCutPflowLoose, FCTight_FixedRad, None",
		      "PflowTight_FixedRad");
Tomas Dado's avatar
Tomas Dado committed
131
    registerParameter("MuonIsolationLoose",
132
133
                      "Isolation to use : PflowTight_VarRad, PflowTight_FixedRad, PflowLoose_VarRad, PflowLoose_FixedRad, HighPtTrackOnly, TightTrackOnly_VarRad, TightTrackOnly_FixedRad, PLVTight, PLVLoose, Tight_VarRad, Tight_FixedRad, Loose_VarRad, Loose_FixedRad, FCTight, FCLoose, FCTightTrackOnly, FCTightTrackOnly_FixedRad, FCLoose_FixedRad, FCTight_FixedRad, FixedCutPflowTight, FixedCutPflowLoose, FCTight_FixedRad, None",
		      "None");
134
135
    registerParameter("MuonIsolationSF", "Force muon isolation SF (e.g. None). EXPERIMENTAL!", " ");
    registerParameter("MuonIsolationSFLoose", "Force muon isolation SF (e.g. None). EXPERIMENTAL!", " ");
136
137
    registerParameter("MuonDoSmearing2stationHighPt", "True/False, to turn on/off spacial corrections for 2-station muons reconstruction with missing inner MS station allowed for abs(eta)<1.3, only with MuonQuality HighPt. - Default: True", "True");
    registerParameter("MuonDoExtraSmearingHighPt", "True/False, To be used by analyses willing to check their sensitivity to momentum resolution effects at large muon momenta. - Default: false", "false");
138
    registerParameter("UseAntiMuons", "Use AntiMuons for fake estimate. Default: false", "false");
Tomas Dado's avatar
Tomas Dado committed
139
    registerParameter("UseSoftMuons", "True to use soft muons, False (default) otherwise", "False");
140
    registerParameter("SoftMuonPt", "Soft Muon pT cut for object selection (in MeV). Default 4 GeV.", "4000");
Tomas Dado's avatar
Tomas Dado committed
141
142
143
144
    registerParameter("SoftMuonEta", "Absolute Soft Muon eta cut for object selection. Default 2.5.", "2.5");
    registerParameter("SoftMuonQuality",
                      "Soft Muon quality cut for object selection. Options are Loose, Medium, Tight (default), LowPt",
                      "Tight");
145
    registerParameter("SoftMuonUseMVALowPt",
146
147
		      "Turn on MVA for low-pT soft muons (only for LowPt WP). Optimized to improve efficiency and hadron rejection. - Default: False",
		      "False");
Tomas Dado's avatar
Tomas Dado committed
148
149
150
    registerParameter("SoftMuonDRJet",
                      "Soft Muon maximum dR wrt nearest selected jet. Can be set to 999. to keep all soft muons. Default 0.4",
                      "0.4");
151
152
153
154
155
156
157
158
159
    registerParameter("SoftMuonAdditionalTruthInfo",
                      "Decide if you want to store additional truth information on the particle-level origin for soft muons (see TopParticleLevel/TruthTools.h): True or False (default)",
                      "False");
    registerParameter("SoftMuonAdditionalTruthInfoCheckPartonOrigin",
                      "Decide if you want to store additional truth information on the parton-level origin for soft muons (see TopParticleLevel/TruthTools.h, this makes sense only if also SoftMuonAdditionalTruthInfo is True) : True or False (default)",
                      "False");
    registerParameter("SoftMuonAdditionalTruthInfoDoVerbose",
                      "Debug output for soft muon addition information: True or False (default)",
                      "False");
160
161

    registerParameter("JetPt", "Jet pT cut for object selection (in MeV). Default 25 GeV.", "25000.");
Tomas Dado's avatar
Tomas Dado committed
162
    registerParameter("JetEta", "Absolute Jet eta cut for object selection. Default 2.5.", "2.5");
163
164
165
166
167
168
    //    registerParameter("FwdJetAndMET", "Forward jet selection and corresponding MET calculation."
    //                                  "Default (does nothing on forward jets), fJVT (No longer recommended), fJVTTight(apply tight fJVT cut if pT<60GeV and |eta|>2.5), Tight (requires pT>30GeV if |eta|>2.5).",
    //                  "Default"); JJJJJJJJ
    registerParameter("ForwardJVTWP", "Set fJVT Working Point for selecting forward jets (|eta|>2.5 & 20GeV<pT<120GeV)"
		      "\'Default\': No fJVT (doesn't run tool for selection) - use this if you don't have forward jets in your selection or if using using PFlow jets with a derivation older than p4173, \'Tight\' (fJVT<0.4, recommended), \'Medium\': (fJVT<0.5, if combined with ForwardJVTinMETCalculation this will set MET WP to Tenacious with stricter JVTinMET requirements",
// , \'None\': Doesn't run fJVT tool for selection OR MET - Use only if you don't have forward jets in your selection AND don't want the fJVT decision to be used in MET calculation, or alternatively if you are using using PFlow jets with derivation before XXX",
Tomas Dado's avatar
Tomas Dado committed
169
                      "Default");
170
171
172
    registerParameter("ForwardJVTinMETCalculation",
                      "Use fJVT cut on forward jets to improve resolution in the MET recalculation? \'False\' (default - must set false if using pflow jets with derivations older than P4173), or \'True\'", "False");
    registerParameter("SaveFailForwardJVTJets", "Save the jets that failed the fJVT cut? \'False\' (default), or \'True\'", "False");
Tomas Dado's avatar
Tomas Dado committed
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
    registerParameter("JetPtGhostTracks",
                      "Jet pT threshold for ghost track systematic variations calculation (in MeV). Default 19 GeV.",
                      "19000.");
    registerParameter("JetUncertainties_NPModel",
                      "AllNuisanceParameters, CategoryReduction (default), GlobalReduction, StrongReduction - for JetUncertainties",
                      "CategoryReduction");
    registerParameter("JetUncertainties_QGFracFile", "To specify a root file with quark/gluon fractions,"
                                                     " in order to reduce FlavourComposition and response uncertainties."
                                                     " Default: None (i.e. no file is used and default flat 50+/-50% fraction is used).",
                      "None");
    registerParameter("JetUncertainties_QGHistPatterns", "To specify a pattern for the name of the quark/gluon fractions histograms, or a list of DSIDs which will have their specific histogram."
                                                         " Two syntaxes are possible, either a single string or a list of DSIDs separated by commas:"
                                                         "   \"MyQGHisto\" (the histograms with \"MyQGHisto\" in their names will be used for all DSIDs),"
                                                         "   \"410470,410472,345873,345874,345875\" (for the listed DSIDs, histograms with the processed DSID will be used, while the flat 50+/-50% fraction will be used for the other DSIDs)."
                                                         " Default: None (i.e. no specific pattern is looked for in the name of the provided histograms).",
                      "None");
    registerParameter("JetJERSmearingModel",
                      "All (inc. data smearing), All_PseudoData (use MC as pseudo-data), Full (inc. data smearing), Full_PseudoData (use MC as pseudo-data) or Simple (MC only - default)",
                      "Simple");
    registerParameter("JetCalibSequence", "Jet calibaration sequence, GSC (default) or JMS", "GSC");
    registerParameter("StoreJetTruthLabels", "Flag to store truth labels for jets - True (default) or False", "True");
    registerParameter("JVTinMETCalculation",
                      "Perfom a JVT cut on the jets in the MET recalculation? True (default) or False.", "True");
    registerParameter("SaveFailJVTJets", "Save the jets that failed the JVT cut? False (default) or True.", "False");
    registerParameter("JVTWP", "Set JVT WP, default is set to \'Default\' (Tight for PFlow and Medium for Topo).",
                      "Default");

    registerParameter("JSF", "Used for top mass analysis, default is 1.0", "1.0");
201
202
203
    registerParameter("bJSF", "Used for top mass analysis, default is 1.0", "1.0");

    registerParameter("LargeRJetPt", "Track Jet pT cut for object selection (in MeV). Default 7 GeV.", "25000.");
Tomas Dado's avatar
Tomas Dado committed
204
205
206
207
    registerParameter("LargeRJetEta", "Absolute large-R jet eta cut for object selection. Default 2.0.", "2.0");
    registerParameter("LargeRJetUncertainties_NPModel",
                      "AllNuisanceParameters, CategoryReduction (default), GlobalReduction, - for LCTopo Large-R Jet Uncertainties or Scale_TCC_all - for TCC Large-R Jet Uncertainties",
                      "CategoryReduction");
208
    registerParameter("AdvancedUsage_LargeRJetUncertaintiesConfigDir",
209
210
                      "Path to directory containing large-R jet uncertainties config",
                      "rel21/Summer2019");
211
    registerParameter("LargeRJESJMSConfig",
212
                      "Calibration for large-R JES/JMS. CombMass, CaloMass or TCCMass (default CombMass).",
213
                      "CombMass");
214
215
216
217
    registerParameter("BoostedJetTagging",
                      "Boosted jet taggers to use in the analysis, separated by commas or white spaces."
                      " By default, no tagger is used.",
                      " ");
218

219
    registerParameter("TrackJetPt", "Track Jet pT cut for object selection (in MeV). Default 10 GeV.", "10000.");
Tomas Dado's avatar
Tomas Dado committed
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
    registerParameter("TrackJetEta", "Absolute Track Jet eta cut for object selection. Default 2.5.", "2.5");

    registerParameter("RCJetPt", "Reclustered Jet pT cut for object selection (in MeV). Default 100000 MeV.",
                      "100000.");
    registerParameter("RCJetEta", "Reclustered Jet eta cut for object selection. Default 2.0.", "2.0");
    registerParameter("RCJetTrim", "Reclustered Jet trimming cut for object selection. Default 0.05.", "0.05");
    registerParameter("RCJetRadius", "Reclustered Jet radius for object selection. Default 1.0", "1.0");
    registerParameter("UseRCJetSubstructure", "Calculate Reclustered Jet Substructure Variables. Default False",
                      "False");
    registerParameter("UseRCJetAdditionalSubstructure",
                      "Calculate Additional Reclustered Jet Substructure Variables. Default False", "False");

    registerParameter("UseRCJets", "Use Reclustered Jets. Default False.", "False");

    registerParameter("VarRCJetPt",
                      "Reclustered Jet (variable-R) pT cut for object selection (in MeV). Default 100000 MeV.",
                      "100000.");
    registerParameter("VarRCJetEta", "Reclustered Jet (variable-R) eta cut for object selection. Default 2.0.", "2.0");
    registerParameter("VarRCJetTrim", "Reclustered Jet (variable-R) trimming cut for object selection. Default 0.05.",
                      "0.05");
    registerParameter("VarRCJetMaxRadius",
                      "Reclustered Jet (variable-R) max. radius cut for object selection. Default 1.0", "1.0");
    registerParameter("VarRCJetRho", "Reclustered Jet (variable-R) list of rho values (). Default 2.", "2");
    registerParameter("VarRCJetMassScale",
                      "Reclustered Jet (variable-R) list of mass scale values (m_w,m_z,m_h,m_t). By default use all.",
                      "m_w,m_z,m_h,m_t");
    registerParameter("UseVarRCJets", "Use Reclustered Jets (Variable-R Jets). Default False.", "False");
    registerParameter("UseVarRCJetSubstructure",
                      "Calculate Variable-R Reclustered Jet Substructure Variables. Default False", "False");
    registerParameter("UseVarRCJetAdditionalSubstructure",
                      "Calculate Additional Variable-R Reclustered Jet Substructure Variables. Default False", "False");
251
252

    registerParameter("TauPt",
Tomas Dado's avatar
Tomas Dado committed
253
254
255
                      "Pt cut applied to both tight and loose taus (in MeV)."
                      "Default 25 GeV.",
                      "25000");
256
    registerParameter("TauJetIDWP",
257
258
                      "Tau jet IDWP (None, Loose, Medium, Tight, LooseNotMedium, LooseNotTight, MediumNotTight, NotLoose, RNNLoose, RNNMedium, RNNTight)."
                      "Default RNNMedium.",
259
                      "RNNMedium");
260
    registerParameter("TauJetIDWPLoose",
Tomas Dado's avatar
Tomas Dado committed
261
                      "Loose Tau jet IDWP (None, Loose, Medium, Tight, LooseNotMedium, LooseNotTight, MediumNotTight, NotLoose)."
262
263
                      "Default RNNLoose.",
                      "RNNLoose");
264
    registerParameter("TauEleBDTWP",
265
                      "Tau electron BDT WP (None, Loose, Medium, Tight, OldLoose, OldMedium)."
266
267
268
                      "Default Loose.",
                      "Loose");
    registerParameter("TauEleBDTWPLoose",
269
                      "Loose Tau electron BDT WP (None, Loose, Medium, Tight, OldLoose, OldMedium)."
270
271
272
                      "Default Loose.",
                      "Loose");
    registerParameter("TauEleOLR",
Tomas Dado's avatar
Tomas Dado committed
273
274
275
                      "Apply tau-electron overlap removal (True/False)."
                      "Default False",
                      "False");
276
    registerParameter("TauEleOLRLoose",
Tomas Dado's avatar
Tomas Dado committed
277
278
279
                      "Apply loose tau-electron overlap removal (True/False)."
                      "Default False",
                      "False");
280
    registerParameter("TauJetConfigFile",
Tomas Dado's avatar
Tomas Dado committed
281
282
283
284
285
                      "Config file to configure tau selection. "
                      "If anything other than 'Default'"
                      "then all cuts are taken from the "
                      "config file rather than other options.",
                      "Default");
286
    registerParameter("TauJetConfigFileLoose",
Tomas Dado's avatar
Tomas Dado committed
287
288
289
290
291
                      "Config file to configure loose tau selection. "
                      "If anything other than 'Default'"
                      "then all cuts are taken from the "
                      "config file rather than other options.",
                      "Default");
292
    registerParameter("ApplyTauMVATES",
293
294
                      "Apply new Tau energy calibration based on substructure information and regression. Must be True. Deprecated.",
                      "True");
295
296
297
298
299
300
    registerParameter("TauSFDoRNNID",
                      "Save SF for RNN tau ID True/False",
                      "True");
    registerParameter("TauSFDoBDTID",
                      "Save SF for BDT tau ID True/False",
                      "False");
301

Tomas Dado's avatar
Tomas Dado committed
302
    registerParameter("Systematics", "What to run? Nominal (just the nominal), All(do all systematics) ", "Nominal");
303
304

    registerParameter("LibraryNames", "Names of any libraries that need loading");
305
    registerParameter("UseAodMetaData", "Whether to read xAOD meta-data from input files (default: True)", "True");
Tomas Dado's avatar
Tomas Dado committed
306
307
    registerParameter("WriteTrackingData", "Whether to generate and store analysis-tracking data (default: True)",
                      "True");
308
309
    registerParameter("ObjectSelectionName", "Code used to define objects, e.g. ObjectLoaderStandardCuts");
    registerParameter("OutputFormat", "Format, can be user defined, e.g. top::EventSaverFlatNtuple");
Tomas Dado's avatar
Tomas Dado committed
310
311
    registerParameter("OutputEvents",
                      "AllEvents (saves all events + decison bits), SelectedEvents (saves only the events passing your cuts)");
312
    registerParameter("OutputFilename", "The file that will contain the output histograms and trees");
Tomas Dado's avatar
Tomas Dado committed
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
    registerParameter("OutputFileSetAutoFlushZero",
                      "setAutoFlush(0) on EventSaverFlatNtuple for ANALYSISTO-44 workaround. (default: False)",
                      "False");
    registerParameter("OutputFileNEventAutoFlush",
                      "Set the number of events after which the TTree cache is optimised, ie setAutoFlush(nEvents). (default: 1000)",
                      "1000");
    registerParameter("OutputFileBasketSizePrimitive",
                      "Set the TTree basket size for primitive objects (int, float, ...). (default: 4096)", "4096");
    registerParameter("OutputFileBasketSizeVector", "Set the TTree basket size for vector objects. (default: 40960)",
                      "40960");
    registerParameter("RecomputeCPVariables",
                      "Run the CP tools to force computation of variables that may already exist in derivations? (default: True)",
                      "True");
    registerParameter("EventVariableSaveList", "The list of event variables to save (EventSaverxAODNext only).",
                      "runNumber.eventNumber.eventTypeBitmask.averageInteractionsPerCrossing");
    registerParameter("PhotonVariableSaveList", "The list of photon variables to save (EventSaverxAODNext only).",
                      "pt.eta.phi.m.charge.ptvarcone20.topoetcone20.passPreORSelection");
    registerParameter("ElectronVariableSaveList", "The list of electron variables to save (EventSaverxAODNext only).",
                      "pt.eta.phi.m.charge.ptvarcone20.topoetcone20.passPreORSelection");
    registerParameter("MuonVariableSaveList", "The list of muon variables to save (EventSaverxAODNext only).",
                      "pt.eta.phi.m.author.charge.ptvarcone30.topoetcone20.muonType.passPreORSelection");
    registerParameter("TauVariableSaveList", "The list of tau variables to save (EventSaverxAODNext only).",
                      "pt.eta.phi.m.charge.passPreORSelection");
    registerParameter("JetVariableSaveList", "The list of jet variables to save (EventSaverxAODNext only).",
                      "pt.eta.phi.m.passPreORSelection.btaggingLink.HadronConeExclTruthLabelID");
    registerParameter("BTagVariableSaveList", "The list of b-tag variables to save (EventSaverxAODNext only).",
                      "MV2c20_discriminant");

    registerParameter("NEvents",
                      "The number of events that you want to run on (for testing). If 0 then all events are run.", "0");
    registerParameter("FirstEvent",
                      "The number of events that you want to skip (for testing). If 0 then no events are skipped.",
                      "0");
    registerParameter("PerfStats", " I/O Performance printouts. None, Summary or Full", "None");
347
    registerParameter("IsAFII", "Define if you are running over a fastsim sample: True or False", " ");
Tomas Dado's avatar
Tomas Dado committed
348
349
    registerParameter("FilterBranches",
                      "Comma separated list of names of the branches that will be removed from the output", " ");
350
351
352
353
    registerParameter("FilterPartonLevelBranches",
                      "Comma separated list of names of the parton-level branches that will be removed from the output", " ");
    registerParameter("FilterParticleLevelBranches",
                      "Comma separated list of names of the particle-level branches that will be removed from the output", " ");
354
355
    registerParameter("FilterTrees",
                      "Comma separated list of names of the trees that will be removed from the output", " ");
356

Tomas Dado's avatar
Tomas Dado committed
357
358
359
    registerParameter("FakesMMWeightsIFF",
                      "Calculate matrix-method weights for fake leptons estimate using FakeBkgTools from IFF: True (calculate weights), False (does nothing)",
                      "False");
360
    registerParameter("FakesMMConfigIFF",
Tomas Dado's avatar
Tomas Dado committed
361
362
363
364
365
                      "Configurations for fake leptons estimate using FakeBkgTools from IFF: - default is $ROOTCOREBIN/data/TopFakes/efficiencies.xml:1T:1F[T]. Use as \n <ROOT/XML FILE>:<DEFNINITION>:<PROCESS>;<ROOT/XML FILE 2>:<DEFNINITION 2>:<PROCESS 2>; ...",
                      "$ROOTCOREBIN/data/TopFakes/efficiencies.xml:1T:1F[T]");
    registerParameter("FakesMMIFFDebug",
                      "Enables debug mode for matrix-method weight calculation using FakeBkgTools from IFF: True, False (default)",
                      "False");
366

Tomas Dado's avatar
Tomas Dado committed
367
368
369
370
    registerParameter("DoTight", "Dumps the normal non-\"*_Loose\" trees : Data, MC, Both (default), False", "Both");
    registerParameter("DoLoose", "Run Loose selection and dumps the Loose trees : Data (default), MC, Both, False",
                      "Data");
    registerParameter("DoSysts", "Run systematics on given selection: Both (default), Tight, Loose", "Both");
371

Tomas Dado's avatar
Tomas Dado committed
372
373
374
375
376
377
    registerParameter("OverlapRemovalLeptonDef",
                      "Special: run overlap removal on : Tight (top default) or Loose (not top default) lepton definitions",
                      "Tight");
    registerParameter("ApplyTightSFsInLooseTree",
                      "Special: in Loose trees, calculate lepton SFs with tight leptons only, and considering they are tight: True or False (default)",
                      "False");
378

Tomas Dado's avatar
Tomas Dado committed
379
380
    registerParameter("ApplyElectronInJetSubtraction",
                      "Subtract electrons close to jets for boosted analysis : True or False(top default)", "False");
381
    registerParameter("TopPartonHistory", "ttbar, tb, Wtb, ttz, ttgamma, tHqtautau, False (default)", "False");
382
383
384
    registerParameter("TopPartonLevel", "Perform parton level analysis (stored in truth tree)? True or False", "True");
    
    registerParameter("TopParticleLevel", "Perform particle level selection (stored in particleLevel tree)? True or False", "False");
385
386
387
388
    registerParameter("DoParticleLevelOverlapRemoval",
                      "Perform overlap removal at particle level? True (default), False, or any combination (comma separated) of MuonJet, ElectronJet, JetPhoton",
                      "True");

Tomas Dado's avatar
Tomas Dado committed
389
390
391
392
393
394
    registerParameter("PDFInfo",
                      "Do you want the PDF info? True (in truth tree), Nominal (save to the nominal tree if passes selection) or False (nothing, default)",
                      "False");
    registerParameter("MCGeneratorWeights",
                      "Do you want the OTF-computed MC generator weights (if available)? True (in truth tree), Nominal (save to the nominal tree if passes selection) or False (nothing, default)",
                      "False");
395
396
    registerParameter("NominalWeightNames",
                      "List of nominal weight names to attempt to retrieve. Attempts are made in the order as specified. If none of the names can be found, we will crash with error message. Use index instead in such case.",
397
                      "\" nominal \",\"nominal\",\"Default\",\"Weight\",\"1001\",\" muR=0.10000E+01 muF=0.10000E+01 \",\"\",\" \",\" dyn=   3 muR=0.10000E+01 muF=0.10000E+01 \",\" mur=1 muf=1 \"");
398
399
400
    registerParameter("NominalWeightFallbackIndex",
                      "Index of nominal weight in MC weights vector. This option is only used in case the MC sample has broken metadata. (Default: -1 means no fallback index specified, rely on metadata and crash if metadata cannot be read)",
                      "-1");
401
402
403
    registerParameter("ForceNominalWeightFallbackIndex",
                      "Force usage of NominalWeightFallbackIndex, even if MC sample metadata is correct. (Default: False)",
                      "False");
404

Tomas Dado's avatar
Tomas Dado committed
405
    registerParameter("TruthBlockInfo", "Do you want to dump the full Truth block info? True or False", "False");
406

Tomas Dado's avatar
Tomas Dado committed
407
408
409
410
411
    registerParameter("TruthElectronPt",
                      "Electron pT cut for [Particle Level / Truth] object selection (in MeV). Default 25 GeV.",
                      "25000");
    registerParameter("TruthElectronEta",
                      "Absolute electron eta cut for [Particle Level / Truth] object selection. Default 2.5.", "2.5");
412

Tomas Dado's avatar
Tomas Dado committed
413
414
415
416
    registerParameter("TruthMuonPt",
                      "Muon pT cut for [Particle Level / Truth] object selection (in MeV). Default 25 GeV.", "25000");
    registerParameter("TruthMuonEta",
                      "Absolute Muon eta cut for [Particle Level / Truth] object selection. Default 2.5.", "2.5");
417
418
419
420
421
422

    registerParameter("TruthPhotonPt",
                      "Photon pT cut for [Particle Level / Truth] object selection (in MeV). Default 25 GeV.",
                      "25000");
    registerParameter("TruthPhotonEta",
                      "Absolute Photon eta cut for [Particle Level / Truth] object selection. Default 2.5.",
Tomas Dado's avatar
Tomas Dado committed
423
                      "2.5");
424
425
    registerParameter("TruthPhotonOrigin",
                      "Potential origin of [Particle Level / Truth] photons. Comma separated list of particle origin values as given by MCTruthClassifier (string names).",
Tomas Dado's avatar
Tomas Dado committed
426
                      "WBoson,ZBoson,SinglePhot,Higgs,HiggsMSSM,WZMSSM,PromptPhot,SUSY,UndrPhot,FSRPhot");
427
428
429
430
431
    registerParameter("TruthPhotonIsolation",
                      "Configuration option for isolation applied to [Particle Level / Truth] photons. "
                      "This can be False / None (isolation requirement disabled), "
                      "True (use default isolation), "
                      "or a configuration in the format `VAR CUT`, where VAR is one of the isolation variables and CUT is the cut applied as `VAR / pt < CUT`.",
432
                      "ptcone20 0.1");
433
434


Tomas Dado's avatar
Tomas Dado committed
435
436
437
438
    registerParameter("TruthJetPt",
                      "Jet pT cut for [Particle Level / Truth] object selection (in MeV). Default 25 GeV.", "25000");
    registerParameter("TruthJetEta", "Absolute Jet eta cut for [Particle Level / Truth] object selection. Default 2.5.",
                      "2.5");
439

Tomas Dado's avatar
Tomas Dado committed
440
441
442
443
444
445
    registerParameter("TruthLargeRJetPt",
                      "Large R Jet pT cut for [Particle Level / Truth] object selection (in MeV). Default 25 GeV.",
                      "25000");
    registerParameter("TruthLargeRJetEta",
                      "Absolute Large R Jet eta cut for [Particle Level / Truth] object selection. Default 2.5.",
                      "2.5");
446

Tomas Dado's avatar
Tomas Dado committed
447
448
449
    registerParameter("TruthTauPt",
                      "Tau pT cut for [Particle Level / Truth] object selection (in MeV). Default 25 GeV.", "25000");
    registerParameter("TruthTauEta", "Tau eta cut for [Particle Level / Truth] object selection. Default 2.5.", "2.5");
450

Tomas Dado's avatar
Tomas Dado committed
451
452
453
454
455
456
457
458
459
460
    registerParameter("LHAPDFSets",
                      "List of PDF sets to calculate weights for, seperated by spaces, use LHAPDF names e.g CT10nlo NNPDF30_nlo_as_0118 MMHT2014nlo68cl",
                      " ");
    registerParameter("LHAPDFEventWeights",
                      "Save per event weights for all PDF sets/members: True (lots of info in truth tree!), Nominal (save to the nominal tree if passes selection) or False (nothing, default).",
                      "False");
    registerParameter("LHAPDFBaseSet",
                      "Base PDF set used to recalculate XF1,XF2 values if they are zero. Will be added to LHAPDFSets.",
                      " ");
    registerParameter("BTagCDIPath", "Path to the b-tagging CDI file. Default: Using the hardcoded path.", "Default");
461
462

    registerParameter("BTaggingWP",
463
464
465
466
467
468
                      "b-tagging WPs to use in the analysis, separated by commas."
                      " The format should follow the convention of the b-tagging CP group, e.g. FixedCutBEff_60, FlatBEff_77, Continuous, etc."
                      " For fixed-cut WPs, the simpler format 60%, instead of FixedCutBEff_60, is also tolerated."
                      " The specified WPs which are calibrated for all flavours will have scale-factors computed."
                      " By default, no WP is used.",
                      " ");
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488

    registerParameter("BTaggingSystExcludedFromEV",
                      "User-defined list of b-tagging systematics to be dextracted from eigenvector decomposition, separated by semi-colons (none by default)",
                      "none");

    registerParameter("BTaggingCalibrationB",
                      "The calibration to use for the b-tagging SFs (B-jets)."
                      " Default 'default'",
                      "default");

    registerParameter("BTaggingCalibrationC",
                      "The calibration to use for the b-tagging SFs (C- and T-jets)."
                      " Default 'default'",
                      "default");

    registerParameter("BTaggingCalibrationLight",
                      "The calibration to use for the b-tagging SFs (Light-jets)."
                      " Default 'default'",
                      "default");

Tomas Dado's avatar
Tomas Dado committed
489
490
491
492
493
494
495
496
497
498
499
500
501
502
    registerParameter("PRWConfigFiles",
                      "List of PU config files, seperated by spaces (nothing by default) - Not compatible with FS/AF options",
                      " ");
    registerParameter("PRWConfigFiles_FS",
                      "List of PU config files only for full sim samples, seperated by spaces (nothing by default)",
                      " ");
    registerParameter("PRWConfigFiles_AF",
                      "List of PU config files only for fast sim samples, seperated by spaces (nothing by default)",
                      " ");
    registerParameter("PRWActualMu_FS",
                      "List of actual mu files for full sim samples, seperated by spaces (nothing by default)", " ");
    registerParameter("PRWActualMu_AF",
                      "List of actual mu files only for fast sim samples, seperated by spaces (nothing by default)",
                      " ");
503
504
505
506
507
508
    registerParameter("PRWLumiCalcFiles", "List of PU lumicalc files, seperated by spaces (nothing by default)", " ");
    registerParameter("PRWUseGRLTool", "Pass the GRL tool to the PU reweighting tool (False by default)", "False");
    registerParameter("PRWMuDependent",
                      "Use mu dependent random run numbers for MC. "
                      "True or False (default True)",
                      "True");
509
510
511
512
513
    registerParameter("PRWCustomScaleFactor",
                      "Specify custom scale-factor and up/down variations, for specific studies."
                      "Format is \'nominal:up:down\'."
                      "If nothing is set, the default values will be used (recommended).",
                      " ");
Tomas Dado's avatar
Tomas Dado committed
514
515
516
517
518
519
    registerParameter("PRWUnrepresentedDataTolerance",
                      "Specify value between 0 and 1 to represent acceptable fraction of unrepresented data in PRW [default: 0.05]",
                      "0.05");
    registerParameter("PRWPeriodAssignments",
                      "Specify period number assignments to run numbers ranges in this form: \"XXX:XXX:XXX\", where XXX are runnumbers, first number is the associated run number, second number is the period block start, the third number is the period block end. You can pass any number of these sets (total number of provided RunNumbers needs to be divisible by 3). Default is used if not specified",
                      " ");
520
521

    registerParameter("MuonTriggerSF", "Muon trigger SFs to calculate", "HLT_mu20_iloose_L1MU15_OR_HLT_mu50");
522

Tomas Dado's avatar
Tomas Dado committed
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
    registerParameter("KLFitterTransferFunctionsPath", "Select the transfer functions to use", "mc12a/akt4_LCtopo_PP6");
    registerParameter("KLFitterOutput", "Select the KLFitter output (FULL, FITTEDTOPS_ONLY, JETPERM_ONLY)", "FULL");
    registerParameter("KLFitterJetSelectionMode",
                      "kLeadingThree , kLeadingFour , kLeadingFive , kLeadingSix , kLeadingSeven , kLeadingEight , kBtagPriorityThreeJets , kBtagPriorityFourJets , kBtagPriorityFiveJets, kBtagPrioritySixJets , kBtagPrioritySevenJets , kBtagPriorityEightJets",
                      "kBtagPriorityFourJets");
    registerParameter("KLFitterBTaggingMethod", "Recommend use kNotag or kVetoNoFit - see KLFitter TWiki", "kNotag");
    registerParameter("KLFitterLH",
                      "Select likelihood depending on signal, ttbar, ttbar_angles, ttH, ttZTrilepton, ttbar_AllHadronic, ttbar_BoostedLJets",
                      "ttbar");
    registerParameter("KLFitterTopMassFixed", "Fix the mass of the top quark? True or False", "True");
    registerParameter("KLFitterSaveAllPermutations",
                      "Save All permutations to the output file (False will save only the best)", "False");
    registerParameter("KLFitterFailOnLessThanXJets",
                      "Fail if kLeadingX or kBtagPriorityXJets is set and the number of jets in the event is less than X (Default is False)",
                      "False");
538
539
540
541

    registerParameter("DynamicKeys", "Additional dynamic key list seperated by ,", "");

    registerParameter("OverlapRemovalProcedure", "Overlap removal procedure to be used. Options include:"
Tomas Dado's avatar
Tomas Dado committed
542
543
                                                 " recommended [default], jetmuApplyRelPt, harmonized,"
                                                 " Boosted, BoostedSlidingDREl, BoostedSlidingDRMu, BoostedSlidingDRElMu, noTauJetOLR",
544
                      "recommended"
Tomas Dado's avatar
Tomas Dado committed
545
                      );
546

Tomas Dado's avatar
Tomas Dado committed
547
548
549
550
    registerParameter("OverlapRemovalSlidingInnerDRel",
                      "Overlap removal inner radius to be used for electron SlidingDR ,", "0.2");
    registerParameter("OverlapRemovalSlidingInnerDRmu", "Overlap removal inner radius to be used for muon SlidingDR ,",
                      "0.2");
551

Tomas Dado's avatar
Tomas Dado committed
552
553
    registerParameter("LargeJetOverlapRemoval",
                      "Perform overlap removal including large-R jets. True or False (default: False).", "False");
554
555

    registerParameter("HLLHC",
Tomas Dado's avatar
Tomas Dado committed
556
557
558
                      "Set to run HL-LHC studies,"
                      "True or False (default False)",
                      "False");
559

560
561
562
563
564
    registerParameter("HLLHCFakes",
                      "Set to enable Fakes HL-LHC studies,"
                      "True or False (default False)",
                      "False");

565
    registerParameter("SaveBootstrapWeights", "Set to true in order to save Poisson bootstrap weights,"
Tomas Dado's avatar
Tomas Dado committed
566
                                              "True or False (default False)", "False");
567

568
    registerParameter("NumberOfBootstrapReplicas", "Define integer number of replicas to be stored with bootstrapping, "
Tomas Dado's avatar
Tomas Dado committed
569
                                                   "Default 100", "100");
570

571
    registerParameter("UseBadBatmanCleaning", "Switch to turn on BadBatman cleanig.", "False");
Tomas Dado's avatar
Tomas Dado committed
572
573
574
575
576
577
    registerParameter("BadBatmanCleaningRange",
                      "Set a range of RunNumbers where the cleaning is applied in the form of XXXXX:YYYYY",
                      "276262:311481");
    registerParameter("UseEventLevelJetCleaningTool",
                      "Switch to turn on event-level jet cleaning tool (for testing), True or False (default False)",
                      "False");
578

Tomas Dado's avatar
Tomas Dado committed
579
580
581
582
583
584
585
586
587
588
589
590
591
    registerParameter("UseGlobalLeptonTriggerSF",
                      "Switch to activate event-level trigger scale factors allowing multiple OR of single-, di-, tri- lepton triggers, True or False (default False)",
                      "False");
    registerParameter("GlobalTriggers",
                      "Trigger list for GlobalLeptonTriggerSF - Format as 2015@trig1,trig2 2016@trig3,trig4 : Separate periods defined with @ using whitespace, triggers with comma (default: None)",
                      "None");
    registerParameter("GlobalTriggersLoose",
                      "Trigger list for GlobalLeptonTriggerSF - Format as 2015@trig1,trig2 2016@trig3,trig4 : Separate periods defined with @ using whitespace, triggers with comma (default: None)",
                      "None");
    registerParameter("ElectronTriggers", "Deprecated, use GlobalTriggers instead.", "None");
    registerParameter("ElectronTriggersLoose", "Deprecated, use GlobalTriggersLoose instead.", "None");
    registerParameter("MuonTriggers", "Deprecated, use GlobalTriggers instead.", "None");
    registerParameter("MuonTriggersLoose", "Deprecated, use GlobalTriggersLoose instead.", "None");
592

593
594
    registerParameter("DemandPrimaryVertex", "Wether at least one primary vertex in event is required. Default True. For debugging purposes only!", "True");

595
    registerParameter("KillExperimental", "Disable some specific experimental feature.", " ");
596
    registerParameter("RedefineMCMCMap", "Dictionary for translating the shower names from TopDataPreparation. Format: \"shower1:shower2,shower3:shower4\".", " ");
Tomas Dado's avatar
Tomas Dado committed
597
  }
598

Tomas Dado's avatar
Tomas Dado committed
599
600
  ConfigurationSettings* ConfigurationSettings::get() {
    if (!m_instance) m_instance = new ConfigurationSettings();
601
602

    return m_instance;
Tomas Dado's avatar
Tomas Dado committed
603
  }
604

Tomas Dado's avatar
Tomas Dado committed
605
  void ConfigurationSettings::loadFromFile(const std::string& filename) {
606
607
608
    std::ifstream input(filename.c_str());

    if (!input) {
609
      throw std::runtime_error("Configuration file does not exist: " + filename);
610
611
612
    }

    struct SelectionData {
Tomas Dado's avatar
Tomas Dado committed
613
614
615
      std::string name;
      bool isSub;
      std::vector<std::string> cuts;
616
617
618
619
620
    };
    std::string line;
    std::vector<SelectionData> selections;

    //for the key-value pairs
Tomas Dado's avatar
Tomas Dado committed
621
622
623
    while (std::getline(input, line)) {
      std::string newstring(line);

624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
      // search for '#' character to discard commented-out part of line
      // however ignore '\#' -- used to be able to type # in our config
      // and not be recognized as commenting character
      size_t commentpos = size_t(-1);
      while (true) {
        // find next occurence of '#' -- after the already scanned chars
        commentpos = newstring.find("#", commentpos+1);
        if (commentpos == std::string::npos)
          break;
        if (commentpos == 0) { // the whole line is a comment, to be ignored
          newstring = "";
          break;
        }
        // if it's '\#', then do not erase this part, but remove the '\'
        if (newstring.compare(commentpos-1, 1, "\\") == 0) {
            newstring.erase(commentpos-1, 1);
            --commentpos; // the position of the '#' shifted after removing '\'
            continue;
        } else {
          newstring = newstring.substr(0, commentpos);
          break;
        }
      }
Tomas Dado's avatar
Tomas Dado committed
647
648

      // remove (multiple) spaces hanging around relevant information
yili's avatar
yili committed
649
650
651
652
      // if a pair of "" appears, the spaces in "" won't be touched
      bool hasquote = (newstring.find("\"",0) != std::string::npos);
      if (!hasquote) boost::algorithm::trim_all(newstring);
      else { 
yili's avatar
yili committed
653
654
655
656
657
        //split the string into segments, separated by pairs of quotes
        //e.g. the string "abc \"def\" ghi"
        //     becomes a vector of 3 strings: "abc", "\"def\"", "ghi"
        std::vector<std::string> segments;
        std::vector<bool> segments_isquote;
yili's avatar
yili committed
658
659
        std::size_t strsize = newstring.size();
        std::size_t tmppos = 0;
yili's avatar
yili committed
660
661
662
        bool leftquote = true;
        while (tmppos <= strsize-1) {
          // find the position of the 1st quote after newstring[tmppos]
yili's avatar
yili committed
663
          std::size_t tmppos2 = newstring.find_first_of("\"",tmppos);
yili's avatar
yili committed
664
665
          
	  // when the quote found has \ ahead of it, jump over and update tmppos2
yili's avatar
yili committed
666
	  std::size_t tmppos3 = newstring.find_first_of("\\\"",tmppos);
yili's avatar
yili committed
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
          while (tmppos2 == tmppos3+1) {
	    tmppos3 = newstring.find_first_of("\\\"",tmppos2+1);
            tmppos2 = newstring.find_first_of("\"",tmppos2+1);
          }

          // when no more quote found, save the segment from the last rightquote to the end, then quit the loop
          if (tmppos2 == std::string::npos) {
            segments.push_back(newstring.substr(tmppos,strsize-tmppos));
            segments_isquote.push_back(false);
            break;
          }

          // check it's a left quote or right quote
          if (leftquote) {
            segments.push_back(newstring.substr(tmppos,tmppos2-tmppos));
            segments_isquote.push_back(false);

            // update the position indicator and leftquote flag
            tmppos = tmppos2+1;
            leftquote = false;
          } else {
            segments.push_back(newstring.substr(tmppos-1,tmppos2-(tmppos-1)+1)); // have to include the two quotes, which is why +/-1 adjustment is introduced
            segments_isquote.push_back(true);

            // update the position indicator and leftquote flag
            tmppos = tmppos2+1;
            leftquote = true;
          }
        }

        // sanity check: if leftquote = false after the loop, it means a left quote is found but not its associated rightquote
        // in this case, crash the code
        if (!leftquote) {
yili's avatar
yili committed
700
701
702
          std::string message = "Problematic configuration line\n";
          message.append(newstring.c_str());
          throw std::invalid_argument(message);
yili's avatar
yili committed
703
        }
yili's avatar
yili committed
704

yili's avatar
yili committed
705
        //run the original trim_all for each segment that is NOT a quote
yili's avatar
yili committed
706
        for (uint i = 0; i < segments.size(); i++) {
yili's avatar
yili committed
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
          std::string seg = segments.at(i);
          if (seg.size() == 0) continue;
          if (segments_isquote.at(i)) continue;
          boost::algorithm::trim_all(seg);

          // if the segment has a space in the end and it's not the last segment, add the space back
          if (i+1 != segments.size()) {
            if (segments.at(i).at(segments.at(i).size()-1) == ' ') {
              seg += " ";
            }
          }
          // if the segment has a space in the head and it's not the first segment, add the space back
          if (i != 0) {
            if (segments.at(i).at(0) == ' ') {
              seg = " " + seg;
            }
          }

          // update the segment
          segments.at(i) = seg;
        }

        // combine the segments back to newstring
        newstring = "";
yili's avatar
yili committed
731
        for (uint i = 0; i < segments.size(); i++) {
yili's avatar
yili committed
732
733
          newstring += segments.at(i);
        }
yili's avatar
yili committed
734
735
      }

Tomas Dado's avatar
Tomas Dado committed
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
      if (newstring.empty()) continue;

      // handle start of a (sub)selection (implies end of key-value section)
      if (boost::algorithm::starts_with(newstring, "SELECTION ")) {
        selections.push_back({newstring.substr(10), false, {}});
        continue;
      }
      if (boost::algorithm::starts_with(newstring, "SUB ")) {
        selections.push_back({newstring.substr(4), true, {}});
        continue;
      }

      if (!selections.empty()) {
        // read body of (sub)selection
        auto& sel = selections.back();
        if (boost::algorithm::starts_with(newstring, ". ")) {
          // source another (sub)selection here
          auto subselName = newstring.substr(2);
          auto subselIt = std::find_if(selections.rbegin(), selections.rend(),
                                       [subselName](SelectionData const& sel) {
            return(subselName == sel.name);
          });
          if (subselIt == selections.rend()) throw std::invalid_argument(
                    "ConfigurationSettings: unknown selection: " + subselName);
          sel.cuts.insert(sel.cuts.end(), subselIt->cuts.begin(), subselIt->cuts.end());
        } else {
          sel.cuts.push_back(newstring);
763
        }
Tomas Dado's avatar
Tomas Dado committed
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
        continue;
      }

      // parse key-value pair
      std::istringstream liness(newstring);
      std::string key;
      std::string value;

      std::getline(liness, key, ' '); //to the space
      std::getline(liness, value); //to the end of the line

      auto its = strings_.find(key);
      if (its != strings_.end()) {
        its->second.m_data = value;
        its->second.m_set = true;
      }

      //// add dynamic keys
      if ("DynamicKeys" == key) {
        std::vector<std::string> listofkeys;
        std::string separator = ",";
        std::string::size_type start = 0, end = 0;
        while ((end = value.find(separator, start)) != std::string::npos) {
          std::string token = value.substr(start, end - start);
          if (token.size()) listofkeys.push_back(token);
          start = end + 1;
790
791
        }

Tomas Dado's avatar
Tomas Dado committed
792
793
        std::string lasttoken = value.substr(start);
        if (lasttoken.size()) listofkeys.push_back(lasttoken);
794

Tomas Dado's avatar
Tomas Dado committed
795
796
        for (auto par : listofkeys) {
          registerParameter(par, "Dynamic parameter", "");
797
        }
Tomas Dado's avatar
Tomas Dado committed
798
      }
799
800
    }

Tomas Dado's avatar
Tomas Dado committed
801
802
803
    for (auto& sel : selections) {
      if (sel.isSub) continue;
      m_selections.push_back({sel.name, sel.cuts});
804
805
    }

806
    {
Tomas Dado's avatar
Tomas Dado committed
807
808
809
810
811
812
813
      auto const& it = strings_.find("KillExperimental");
      m_killedFeatures.clear();
      if (it != strings_.end() && it->second.m_set) {
        std::string strValue(it->second.m_data);
        boost::trim(strValue);
        boost::split(m_killedFeatures, strValue, boost::is_any_of(" "));
      }
814
815
    }

816
817
    input.close();
    m_configured = true;
Tomas Dado's avatar
Tomas Dado committed
818
  }
819

Tomas Dado's avatar
Tomas Dado committed
820
821
  void ConfigurationSettings::registerParameter(const std::string& name, const std::string& message,
                                                const std::string& default_val) {
822
    StringData data;
Tomas Dado's avatar
Tomas Dado committed
823

824
825
826
827
    data.m_data = default_val;
    data.m_human_explanation = message;
    data.m_set = (default_val.empty() ? false : true);
    strings_[name] = data;
Tomas Dado's avatar
Tomas Dado committed
828
  }
829

Tomas Dado's avatar
Tomas Dado committed
830
  const std::string& ConfigurationSettings::value(const std::string& key) const {
831
832
    //This class never has loadFromFile called
    if (!m_configured) {
Tomas Dado's avatar
Tomas Dado committed
833
834
835
836
      std::string message = "ConfigurationSettings: Not correctly configured\n";
      message.append("You need to call top::ConfigurationSettings::get()->loadFromFile(filename)\n");
      message.append("Early in your program\n");
      throw std::invalid_argument(message);
837
838
839
840
841
    }

    std::map<std::string, StringData>::const_iterator its = strings_.find(key);
    //The string is not in the map
    if (its == strings_.end()) {
Tomas Dado's avatar
Tomas Dado committed
842
      throw std::invalid_argument("ConfigurationSettings: The variable doesn't exist in the code " + key);
843
844
845
846
    }

    //In the map, but never set to anything
    if (!its->second.m_set) {
Tomas Dado's avatar
Tomas Dado committed
847
      throw std::invalid_argument("ConfigurationSettings: You never set a value for " + key);
848
849
850
    }

    return its->second.m_data;
Tomas Dado's avatar
Tomas Dado committed
851
  }
852

Tomas Dado's avatar
Tomas Dado committed
853
  bool ConfigurationSettings::configured() const {
854
    return m_configured;
Tomas Dado's avatar
Tomas Dado committed
855
  }
856

Tomas Dado's avatar
Tomas Dado committed
857
  const std::map<std::string, StringData>& ConfigurationSettings::stringData() const {
858
    return strings_;
Tomas Dado's avatar
Tomas Dado committed
859
  }
860

Tomas Dado's avatar
Tomas Dado committed
861
  const std::vector<SelectionConfigurationData> ConfigurationSettings::selections() const {
862
    return m_selections;
Tomas Dado's avatar
Tomas Dado committed
863
  }
864

865
  void ConfigurationSettings::retrieve(std::string const& key, bool& value) const {
866
867
868
869
870
    using boost::trim;
    using boost::equals;
    using boost::iequals;
    auto stringValue = ConfigurationSettings::get()->value(key);
    trim(stringValue);
871

Tomas Dado's avatar
Tomas Dado committed
872
873
874
875
    if (iequals(stringValue, "false") or iequals(stringValue, "0") or iequals(stringValue, "n") or iequals(stringValue,
                                                                                                           "no") or
        iequals(stringValue, "off")) {
      value = false;
876
      return;
877
    }
Tomas Dado's avatar
Tomas Dado committed
878
879
880
881
    if (iequals(stringValue, "true") or iequals(stringValue, "1") or iequals(stringValue, "y") or iequals(stringValue,
                                                                                                          "yes") or
        iequals(stringValue, "on")) {
      value = true;
882
      return;
883
884
    }
    throw std::invalid_argument(std::string("expected boolean value for configuration setting ") + key);
Tomas Dado's avatar
Tomas Dado committed
885
886
887
888
889
890
891
892
893
  }

  bool ConfigurationSettings::feature(std::string const& name) const {
    /* We search a list of strings, not a particularly efficient implementation.
     * If need be, we could abuse the aux registry and use integers instead of
     * strings. Anyhow, in most cases, the list should be empty. */
    return(m_killedFeatures.empty() ||
           std::find(m_killedFeatures.begin(), m_killedFeatures.end(), name) == m_killedFeatures.end());
  }
894

895
896
897
898
  std::ostream& operator << (std::ostream& os, const SelectionConfigurationData& data) {
    os << " - " << data.m_name << "\n";
    for (const auto& cutname : data.m_cutnames)
      os << "    " << cutname << "\n";
899

900
901
    return os;
  }
902

903
904
905
906
907
  std::ostream& operator << (std::ostream& os, const ConfigurationSettings& settings) {
    for (std::map<std::string, top::StringData >::const_iterator its = settings.stringData().begin();
         its != settings.stringData().end(); ++its) {
      std::stringstream s;
      s << "\"" << its->first << "\"";
908

909
910
911
912
913
      std::stringstream s2;
      s2 << "\"" << its->second.m_data << "\"";
      os << std::setw(40) << std::left << s.str() << " : " << std::setw(35) << s2.str() << " - " << std::right <<
        its->second.m_human_explanation << "\n";
    }
914

915
916
    //for (const auto& selection : settings.selections())
    //    os << selection << "\n";
917

918
919
    return os;
  }
920
}