File indexing completed on 2024-06-01 07:07:32
0001
0002 #include <TDatabasePDG.h>
0003
0004 #include "DelphesConfig.h"
0005
0006 #define _ERROR_(message) { printf("\n\n %s\n", message); exit(1); }
0007
0008
0009
0010 DelphesConfig::DelphesConfig( void ):
0011
0012 m_DatabasePDG(0),
0013 m_EtaMin(0.0), m_EtaMax(0.0),
0014 m_MomentumMin(0.0), m_MomentumMax(0.0), m_EfficiencyContaminationMode(false),
0015
0016 m_PtMode(false)
0017 {
0018
0019
0020
0021
0022 }
0023
0024
0025
0026 DelphesConfig::DelphesConfig(const char *dname):
0027 m_Name(dname),
0028 m_EtaMin(0.0), m_EtaMax(0.0),
0029 m_MomentumMin(0.0), m_MomentumMax(0.0), m_EfficiencyContaminationMode(false),
0030
0031 m_PtMode(false)
0032 {
0033
0034 m_Name = dname;
0035 m_DatabasePDG = new TDatabasePDG();
0036
0037 }
0038
0039
0040
0041 MassHypothesis *DelphesConfig::AddMassHypothesisCore(TParticlePDG *pdg,
0042 double max_contamination_left,
0043 double max_contamination_right)
0044 {
0045
0046 if (!pdg) return 0;
0047 auto hypothesis = new MassHypothesis(pdg, max_contamination_left, max_contamination_right);
0048 if (!hypothesis) return 0;
0049
0050
0051 MassHypothesis *prev = m_MassHypotheses.size() ? m_MassHypotheses.back() : 0;
0052 if (prev && pdg->Mass() <= prev->Mass()) {
0053 printf("Particle masses are not in ascending order (%7.4f is followed by %7.4f)\n",
0054 prev->Mass(), pdg->Mass());
0055 exit(1);
0056 }
0057 m_MassHypotheses.push_back(hypothesis);
0058
0059
0060 if (max_contamination_left != 1.0 || max_contamination_right != 1.0)
0061 m_EfficiencyContaminationMode = true;
0062
0063 return hypothesis;
0064 }
0065
0066
0067
0068 MassHypothesis *DelphesConfig::AddMassHypothesis(int pdg,
0069 double max_contamination_left,
0070 double max_contamination_right)
0071 {
0072 return AddMassHypothesisCore(m_DatabasePDG->GetParticle(pdg),
0073 max_contamination_left, max_contamination_right);
0074 }
0075
0076
0077
0078 MassHypothesis *DelphesConfig::AddMassHypothesis(const char *pname,
0079 double max_contamination_left,
0080 double max_contamination_right)
0081 {
0082 return AddMassHypothesisCore(m_DatabasePDG->GetParticle(pname),
0083 max_contamination_left, max_contamination_right);
0084 }
0085
0086
0087
0088 MomentumRange *EtaRange::GetMomentumRange(double min, double max)
0089 {
0090 for(auto mrange: m_MomentumRanges)
0091 if (mrange->GetMin() == min && mrange->GetMax() == max)
0092 return mrange;
0093
0094 auto mrange = new MomentumRange(min, max);
0095 m_MomentumRanges.push_back(mrange);
0096
0097 return mrange;
0098 }
0099
0100
0101
0102 bool DelphesConfig::StoreSigmaEntry(MomentumRange *mrange, int pdg, double measurement,
0103 double sigma)
0104 {
0105
0106 unsigned mdim = mrange->GetSigmaCount();
0107
0108
0109 if (mdim == m_MassHypotheses.size()) return false;
0110
0111 if (pdg != m_MassHypotheses[mdim]->PdgCode()) return false;
0112
0113 mrange->AddSigmaValue(measurement, sigma);
0114
0115 return true;
0116 }
0117
0118
0119
0120 bool DelphesConfig::StoreSigmaEntry(MomentumRange *mrange, int pdg, double sigma)
0121 {
0122 return StoreSigmaEntry(mrange, pdg, 0.0, sigma);
0123 }
0124
0125
0126
0127 void DelphesConfig::AddZeroSigmaEntries( void )
0128 {
0129 for(auto erange: m_EtaRanges)
0130 for(auto mrange: erange->m_MomentumRanges) {
0131 unsigned mdim = mrange->GetSigmaCount();
0132
0133 for(unsigned iq=mdim; iq<m_MassHypotheses.size(); iq++)
0134 StoreSigmaEntry(mrange, m_MassHypotheses[iq]->PdgCode(), 0.0);
0135 }
0136
0137 DetermineThresholds();
0138 }
0139
0140
0141
0142 void DelphesConfig::DetermineThresholds( void )
0143 {
0144 for(unsigned ih=0; ih<m_MassHypotheses.size(); ih++) {
0145 auto hypo = m_MassHypotheses[ih];
0146
0147
0148 for(auto erange: m_EtaRanges)
0149 for(auto mrange: erange->m_MomentumRanges) {
0150 double min = mrange->GetMin();
0151
0152
0153 if (mrange->GetSigma(ih) && (!hypo->GetThreshold() || hypo->GetThreshold() > min))
0154 hypo->SetThreshold(min);
0155 }
0156
0157 printf("@T@ %d -> %7.2f\n", ih, hypo->GetThreshold());
0158 }
0159 }
0160
0161
0162
0163 void DelphesConfig::Print( void )
0164 {
0165 for(auto erange: m_EtaRanges) {
0166 printf("@D@ eta %4.2f .. %4.2f\n", erange->GetMin(), erange->GetMax());
0167
0168 for(auto mrange: erange->m_MomentumRanges) {
0169 printf("@D@ momentum %5.2f .. %5.2f -> sigma:",
0170 mrange->GetMin(), mrange->GetMax());
0171
0172 for(unsigned iq=0; iq<mrange->GetSigmaCount(); iq++)
0173 printf(" %5.2f (%4d)", mrange->GetSigma(iq), m_MassHypotheses[iq]->PdgCode());
0174 printf("\n");
0175 }
0176 }
0177 }
0178
0179
0180
0181 EtaRange *DelphesConfig::AddEtaRange(double min, double max)
0182 {
0183
0184 for(auto erange: m_EtaRanges)
0185 if (erange->GetMin() == min && erange->GetMax() == max)
0186 return erange;
0187
0188 auto erange = new EtaRange(min, max);
0189 auto prev = m_EtaRanges.size() ? m_EtaRanges.back() : 0;
0190 if (prev && min != prev->GetMax()){
0191 printf("Eta ranges sequence issue: %6.2f is followed by %6.2f\n",
0192 prev->GetMax(), min);
0193 return 0;
0194 }
0195 m_EtaRanges.push_back(erange);
0196
0197 return erange;
0198 }
0199
0200
0201
0202 int DelphesConfig::Check(bool rigorous)
0203 {
0204 if (m_EtaRanges.empty()) _ERROR_("No eta ranges defined!");
0205
0206
0207 m_EtaMin = m_EtaRanges.front()->GetMin();
0208 m_EtaMax = m_EtaRanges.back ()->GetMax();
0209
0210
0211
0212 for(auto erange: m_EtaRanges) {
0213 if (!erange->GetMomentumRangeCount()) _ERROR_("Empty eta range defined!");
0214
0215
0216 if (erange == m_EtaRanges.front()) {
0217 m_MomentumMin = erange->FirstMomentumRange()->GetMin();
0218 m_MomentumMax = erange->LastMomentumRange ()->GetMax();
0219
0220 continue;
0221 }
0222
0223
0224 if (erange->FirstMomentumRange()->GetMin() != m_MomentumMin ||
0225 erange->LastMomentumRange() ->GetMax() != m_MomentumMax)
0226 _ERROR_("Full momentum range should be the same in all eta ranges!");
0227
0228 if (rigorous)
0229 for(auto mrange: erange->m_MomentumRanges)
0230 if (mrange->GetSigmaCount() != m_MassHypotheses.size())
0231 _ERROR_("Momentum range entry has wrong number of sigma values!");
0232 }
0233
0234 return 0;
0235 }
0236
0237
0238
0239 void DelphesConfig::WriteMassHypothesis(FILE *fout, unsigned ih)
0240 {
0241 unsigned dim = m_MassHypotheses.size();
0242 const char *pstr = m_PtMode ? "pt" : "pt * cosh(eta)";
0243
0244 auto prev = ih ? m_MassHypotheses[ih-1] : 0;
0245 auto hypo = m_MassHypotheses[ih ];
0246 auto next = ih == m_MassHypotheses.size()-1 ? 0 : m_MassHypotheses[ih+1];
0247 MassHypothesis *arr[3] = {prev, hypo, next};
0248
0249 for(unsigned ip=0; ip<3; ip++) {
0250 auto hto = arr[ip];
0251
0252 if (hto) {
0253 fprintf(fout, "\n");
0254 fprintf(fout, " add EfficiencyFormula {%d} {%d} {\n", hypo->PdgCode(),
0255 hto->PdgCode());
0256
0257
0258 fprintf(fout, " (eta<%6.2f || eta>=%6.2f || %s < %7.2f || %s >= %7.2f) * ( 0.00 ) +\n",
0259 m_EtaMin, m_EtaMax, pstr, m_MomentumMin, pstr, m_MomentumMax);
0260
0261
0262 for(auto erange: m_EtaRanges) {
0263 double emin = erange->GetMin(), emax = erange->GetMax();
0264
0265 for(auto mrange: erange->m_MomentumRanges) {
0266 fprintf(fout, " (%6.2f <= eta && eta < %6.2f) * (%7.2f <= %s && %s < %7.2f) * (%8.6f)%s\n",
0267 emin, emax, mrange->GetMin(), pstr, pstr, mrange->GetMax(),
0268 mrange->m_Matrix[ih*dim + ih + ip - 1],
0269 erange == m_EtaRanges.back() && mrange == erange->m_MomentumRanges.back() ? "" : " +");
0270
0271 }
0272 }
0273
0274 fprintf(fout, " }\n");
0275 }
0276 }
0277 }
0278
0279
0280
0281 void DelphesConfig::WriteTcl(bool check)
0282 {
0283
0284 if (check && Check()) return;
0285 if (Calculate()) return;
0286
0287 auto fout = fopen((m_Name + ".tcl").c_str(), "w");
0288 if (!fout) {
0289 printf("Failed to open output file!\n");
0290 exit(1);
0291 }
0292
0293
0294 fprintf(fout, "module IdentificationMap %s {\n", m_Name.c_str());
0295 fprintf(fout, " set InputArray TrackMerger/tracks\n");
0296 fprintf(fout, " set OutputArray tracks\n");
0297
0298
0299
0300
0301 for(unsigned ih = 0; ih<m_MassHypotheses.size(); ih++)
0302 WriteMassHypothesis(fout, ih);
0303
0304
0305 fprintf(fout, "\n");
0306 fprintf(fout, " add EfficiencyFormula {0} {0} { 0.00 }\n");
0307 fprintf(fout, "}\n");
0308
0309 fclose(fout);
0310 }
0311
0312
0313
0314 MassHypothesis *DelphesConfig::GetMassHypothesis(int pdg, bool ignore_sign)
0315 {
0316 for(auto hypo: m_MassHypotheses)
0317 if (pdg == hypo->PdgCode() ||
0318 (ignore_sign && pdg == abs(hypo->PdgCode())))
0319 return hypo;
0320
0321 return 0;
0322 }
0323
0324