00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00041 #include "TopQuarkAnalysis/TopHitFit/interface/Top_Fit.h"
00042 #include "TopQuarkAnalysis/TopHitFit/interface/Lepjets_Event.h"
00043 #include "TopQuarkAnalysis/TopHitFit/interface/Top_Decaykin.h"
00044 #include "TopQuarkAnalysis/TopHitFit/interface/Defaults.h"
00045 #include "TopQuarkAnalysis/TopHitFit/interface/Fit_Results.h"
00046 #include "TopQuarkAnalysis/TopHitFit/interface/fourvec.h"
00047 #include <iostream>
00048 #include <algorithm>
00049 #include <cmath>
00050 #include <cassert>
00051
00052 using std::cout;
00053 using std::endl;
00054 using std::abs;
00055 using std::next_permutation;
00056 using std::stable_sort;
00057 using std::vector;
00058 using std::ostream;
00059
00060
00061 namespace hitfit {
00062
00063
00064
00065
00066
00067
00068
00069 Top_Fit_Args::Top_Fit_Args (const Defaults& defs)
00070
00071
00072
00073
00074
00075
00076 : _print_event_flag (defs.get_bool ("print_event_flag")),
00077 _do_higgs_flag (defs.get_bool ("do_higgs_flag")),
00078 _jet_mass_cut (defs.get_float ("jet_mass_cut")),
00079 _mwhad_min_cut (defs.get_float ("mwhad_min_cut")),
00080 _mwhad_max_cut (defs.get_float ("mwhad_max_cut")),
00081 _mtdiff_max_cut (defs.get_float ("mtdiff_max_cut")),
00082 _nkeep (defs.get_int ("nkeep")),
00083 _solve_nu_tmass (defs.get_bool ("solve_nu_tmass")),
00084 _args (defs)
00085 {
00086 }
00087
00088
00089 bool Top_Fit_Args::print_event_flag () const
00090
00091
00092
00093
00094 {
00095 return _print_event_flag;
00096 }
00097
00098
00099 bool Top_Fit_Args::do_higgs_flag () const
00100
00101
00102
00103
00104 {
00105 return _do_higgs_flag;
00106 }
00107
00108
00109 double Top_Fit_Args::jet_mass_cut () const
00110
00111
00112
00113
00114 {
00115 return _jet_mass_cut;
00116 }
00117
00118
00119 double Top_Fit_Args::mwhad_min_cut () const
00120
00121
00122
00123
00124 {
00125 return _mwhad_min_cut;
00126 }
00127
00128
00129 double Top_Fit_Args::mwhad_max_cut () const
00130
00131
00132
00133
00134 {
00135 return _mwhad_max_cut;
00136 }
00137
00138
00139 double Top_Fit_Args::mtdiff_max_cut () const
00140
00141
00142
00143
00144 {
00145 return _mtdiff_max_cut;
00146 }
00147
00148
00149 int Top_Fit_Args::nkeep () const
00150
00151
00152
00153
00154 {
00155 return _nkeep;
00156 }
00157
00158
00159 bool Top_Fit_Args::solve_nu_tmass () const
00160
00161
00162
00163
00164 {
00165 return _solve_nu_tmass;
00166 }
00167
00168
00169 const Constrained_Top_Args& Top_Fit_Args::constrainer_args () const
00170
00171
00172
00173 {
00174 return _args;
00175 }
00176
00177
00178
00179
00180
00181
00182
00183
00184 namespace {
00185
00186
00201 bool test_for_bad_masses (const Lepjets_Event& ev,
00202 const Top_Fit_Args& args,
00203 double mwhad,
00204 double umthad,
00205 double umtlep)
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220 {
00221
00222
00223 if (ev.sum (lepb_label).m() > args.jet_mass_cut() ||
00224 ev.sum (hadb_label).m() > args.jet_mass_cut() ||
00225 ev.sum (hadw1_label).m() > args.jet_mass_cut() ||
00226 ev.sum (hadw2_label).m() > args.jet_mass_cut()) {
00227 return true;
00228 }
00229
00230
00231 if (mwhad < args.mwhad_min_cut()) {
00232 return true;
00233 }
00234
00235
00236 if (mwhad > args.mwhad_max_cut()) {
00237 return true;
00238 }
00239
00240
00241 if (abs (umthad - umtlep) > args.mtdiff_max_cut()) {
00242 return true;
00243 }
00244
00245
00246 return false;
00247 }
00248
00249
00259 vector<int> classify_jetperm (const vector<int>& jet_types,
00260 const Lepjets_Event& ev)
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272 {
00273
00274
00275
00276 vector<int> out (n_lists);
00277 out[all_list] = 1;
00278 out[noperm_list] = 1;
00279 out[semicorrect_list] = 1;
00280 out[limited_isr_list] = 1;
00281 out[topfour_list] = 1;
00282 out[btag_list] = 1;
00283 out[htag_list] = 1;
00284
00285
00286 assert (jet_types.size() == ev.njets());
00287 for (vector<int>::size_type i=0; i < jet_types.size(); i++)
00288 {
00289 {
00290 int t1 = jet_types[i];
00291 int t2 = ev.jet(i).type();
00292
00293
00294 if (t1 == hadw2_label) t1 = hadw1_label;
00295 if (t2 == hadw2_label) t2 = hadw1_label;
00296
00297
00298 if (t1 != t2) out[noperm_list] = 0;
00299
00300
00301
00302 if (t1 == hadw1_label) t1 = hadb_label;
00303 if (t2 == hadw1_label) t2 = hadb_label;
00304 if (t1 != t2) out[semicorrect_list] = 0;
00305 }
00306
00307 if (jet_types[i] == isr_label && i <= 2)
00308 out[limited_isr_list] = 0;
00309
00310 if ((jet_types[i] == isr_label && i <= 3) ||
00311 (jet_types[i] != isr_label && i >= 4))
00312 out[topfour_list] = 0;
00313
00314 if ((ev.jet(i).svx_tag() || ev.jet(i).slt_tag()) &&
00315 ! (jet_types[i] == hadb_label || jet_types[i] == lepb_label))
00316 out[btag_list] = 0;
00317
00318 if ((ev.jet(i).svx_tag() || ev.jet(i).slt_tag()) &&
00319 ! (jet_types[i] == hadb_label || jet_types[i] == lepb_label ||
00320 jet_types[i] == higgs_label))
00321 out[htag_list] = 0;
00322 }
00323 return out;
00324 }
00325
00326
00335 void set_jet_types (const vector<int>& jet_types,
00336 Lepjets_Event& ev)
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347 {
00348 assert (ev.njets() == jet_types.size());
00349 bool saw_hadw1 = false;
00350 for (vector<int>::size_type i=0; i < ev.njets(); i++) {
00351 int t = jet_types[i];
00352 if (t == hadw1_label) {
00353 if (saw_hadw1)
00354 t = hadw2_label;
00355 saw_hadw1 = true;
00356 }
00357 ev.jet (i).type() = t;
00358 }
00359 }
00360
00361
00362 }
00363
00364
00365
00366
00367
00368 Top_Fit::Top_Fit (const Top_Fit_Args& args,
00369 double lepw_mass,
00370 double hadw_mass,
00371 double top_mass)
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384 : _args (args),
00385 _constrainer (args.constrainer_args(),
00386 lepw_mass, hadw_mass, top_mass),
00387 _lepw_mass(lepw_mass),
00388 _hadw_mass (hadw_mass)
00389 {
00390 }
00391
00392
00393 double Top_Fit::fit_one_perm (Lepjets_Event& ev,
00394 bool& nuz,
00395 double& umwhad,
00396 double& utmass,
00397 double& mt,
00398 double& sigmt,
00399 Column_Vector& pullx,
00400 Column_Vector& pully)
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430 {
00431 mt = 0;
00432 sigmt = 0;
00433
00434
00435
00436
00437
00438 umwhad = Top_Decaykin::hadw (ev) . m();
00439 double umthad = Top_Decaykin::hadt (ev) . m();
00440 double nuz1, nuz2;
00441
00442 if (_args.solve_nu_tmass()) {
00443 Top_Decaykin::solve_nu_tmass (ev, umthad, nuz1, nuz2);
00444 }
00445 else {
00446 Top_Decaykin::solve_nu (ev, _lepw_mass, nuz1, nuz2);
00447 }
00448
00449
00450 if (!nuz) {
00451 ev.met().setZ(nuz1);
00452 }
00453 else {
00454 ev.met().setZ(nuz2);
00455 }
00456
00457
00458
00459
00460
00461
00462
00463
00464 adjust_e_for_mass(ev.met(),0);
00465
00466
00467 double umtlep = Top_Decaykin::lept (ev) . m();
00468 utmass = (umthad + umtlep) / 2;
00469
00470
00471 if (_args.print_event_flag()) {
00472 cout << "Top_Fit::fit_one_perm() : Before fit:\n";
00473 Top_Decaykin::dump_ev (cout, ev);
00474 }
00475
00476
00477 if (_hadw_mass > 0 && test_for_bad_masses (ev, _args, umwhad,
00478 umthad, umtlep))
00479 {
00480 cout << "Top_Fit: bad mass comb.\n";
00481 return -999;
00482 }
00483
00484
00485 double chisq = _constrainer.constrain (ev, mt, sigmt, pullx, pully);
00486
00487
00488 if (_args.print_event_flag()) {
00489 cout << "Top_Fit::fit_one_perm() : After fit:\n";
00490 cout << "chisq: " << chisq << " mt: " << mt << " ";
00491 Top_Decaykin::dump_ev (cout, ev);
00492 }
00493
00494
00495 return chisq;
00496 }
00497
00498
00499 Fit_Results Top_Fit::fit (const Lepjets_Event& ev)
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509 {
00510
00511 Fit_Results res (_args.nkeep(), n_lists);
00512
00513
00514 vector<int> jet_types (ev.njets(), isr_label);
00515 assert (ev.njets() >= 4);
00516 jet_types[0] = lepb_label;
00517 jet_types[1] = hadb_label;
00518 jet_types[2] = hadw1_label;
00519 jet_types[3] = hadw1_label;
00520
00521 if (_args.do_higgs_flag() && ev.njets() >= 6) {
00522 jet_types[4] = higgs_label;
00523 jet_types[5] = higgs_label;
00524 }
00525
00526
00527 stable_sort (jet_types.begin(), jet_types.end());
00528
00529 do {
00530
00531
00532 for (int nusol = 0 ; nusol != 2 ; nusol++) {
00533
00534
00535 bool nuz = bool(nusol);
00536
00537
00538 Lepjets_Event fev = ev;
00539
00540
00541 set_jet_types (jet_types, fev);
00542
00543
00544 vector<int> list_flags = classify_jetperm (jet_types, ev);
00545
00546
00547 double umwhad, utmass, mt, sigmt;
00548 Column_Vector pullx;
00549 Column_Vector pully;
00550 double chisq;
00551
00552
00553 cout << "Top_Fit::fit(): Before fit: (";
00554 for (vector<int>::size_type i=0; i < jet_types.size(); i++) {
00555 if (i) cout << " ";
00556 cout << jet_types[i];
00557 }
00558 cout << " nuz = " << nuz ;
00559 cout << ") " << std::endl;
00560
00561
00562 chisq = fit_one_perm (fev, nuz, umwhad, utmass, mt, sigmt, pullx, pully);
00563
00564
00565 if (_args.print_event_flag()) {
00566 cout << "Top_Fit::fit(): After fit:\n";
00567 char buf[256];
00568 sprintf (buf, "chisq: %8.3f mt: %6.2f pm %5.2f %c\n",
00569 chisq, mt, sigmt, (list_flags[noperm_list] ? '*' : ' '));
00570 cout << buf;
00571 }
00572
00573
00574 res.push (chisq, fev, pullx, pully, umwhad, utmass, mt, sigmt, list_flags);
00575
00576 }
00577
00578
00579 } while (next_permutation (jet_types.begin(), jet_types.end()));
00580
00581 return res;
00582 }
00583
00584
00593 std::ostream& operator<< (std::ostream& s, const Top_Fit& fitter)
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604 {
00605 return s << fitter._constrainer;
00606 }
00607
00608
00609 const Top_Fit_Args& Top_Fit::args() const
00610 {
00611 return _args;
00612 }
00613
00614 }