tracking_eff.cpp 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271
  1. #include <iostream>
  2. #include <vector>
  3. #include <map>
  4. #include <utility>
  5. #include <numeric>
  6. #include <limits>
  7. #include <cmath>
  8. #include <TSystem.h>
  9. #include "filval/filval.hpp"
  10. #include "filval/root/filval.hpp"
  11. #include <boost/range/combine.hpp>
  12. #include <boost/format.hpp>
  13. #include "analysis/TrackingNtuple.h"
  14. #include "analysis/TrackingNtupleObjs.hpp"
  15. #include "analysis/common.hpp"
  16. using namespace std;
  17. using namespace fv;
  18. using namespace fv::root;
  19. enum class HitType {
  20. Pixel = 0,
  21. Strip = 1,
  22. Glued = 2,
  23. Invalid = 3,
  24. Phase2OT = 4,
  25. Unknown = 99
  26. };
  27. SeedCollection seeds;
  28. SimTrackCollection sim_tracks;
  29. SimVertexCollection sim_vertices;
  30. TrackCollection gsf_tracks;
  31. void register_objects(TrackingDataSet& tds){
  32. seeds.init(tds);
  33. sim_tracks.init(tds);
  34. sim_vertices.init(tds);
  35. gsf_tracks.init(tds);
  36. }
  37. struct {
  38. Value<float>* x;
  39. Value<float>* y;
  40. Value<float>* z;
  41. Value<float>* sigma_x;
  42. Value<float>* sigma_y;
  43. Value<float>* sigma_z;
  44. } bs;
  45. bool in_lum_region(const SimVertex& vertex) {
  46. /* Here approximate the luminous region as a cylinder with length 5*\sigma_z and radius
  47. * sqrt(\simga_x^2 + \sigma_y^2) centered as beamspot position.
  48. */
  49. float dx = vertex.x() - bs.x->get_value();
  50. float dy = vertex.y() - bs.y->get_value();
  51. float dz = vertex.z() - bs.z->get_value();
  52. float radius = 5*sqrt(pow(bs.sigma_x->get_value(), 2) + pow(bs.sigma_y->get_value(), 2));
  53. float half_len = 5*bs.sigma_z->get_value();
  54. return sqrt(dx*dx + dy*dy) < radius and abs(dz) < half_len;
  55. };
  56. bool is_good_sim(size_t simTrkIdx) {
  57. const auto& track = sim_tracks[simTrkIdx];
  58. const auto& vertex = sim_vertices[track.parentVtxIdx()];
  59. return abs(track.pdgId()) == 11 and in_lum_region(vertex);
  60. };
  61. void run_analysis(const vector<fv::util::DataFileDescriptor>& dfds, const string output_filename, bool silent){
  62. TrackingDataSet tds(output_filename, dfds, "trackingNtuple/tree");
  63. register_objects(tds);
  64. bs = {
  65. tds.track_branch<float>("bsp_x"),
  66. tds.track_branch<float>("bsp_y"),
  67. tds.track_branch<float>("bsp_z"),
  68. tds.track_branch<float>("bsp_sigmax"),
  69. tds.track_branch<float>("bsp_sigmay"),
  70. tds.track_branch<float>("bsp_sigmaz")
  71. };
  72. // Indices of prompt-ish sim electrons
  73. auto good_sim_electrons = func_value<vector<size_t>>("good_sim_electrons",
  74. FUNC(([](){
  75. vector<size_t> idxs;
  76. for(const auto& sim_track : sim_tracks) {
  77. if (is_good_sim(sim_track.idx)) idxs.push_back(sim_track.idx);
  78. }
  79. return idxs;
  80. })));
  81. // Indices of prompt-ish sim electrons that have a matched seed
  82. function<bool(size_t)> with_seed = [](const size_t& e_idx) {
  83. return seeds.size() != 0 and sim_tracks[e_idx].seedIdx().size() != 0;
  84. };
  85. // Indices of prompt-ish sim electrons that have a matched gsftrack
  86. function<bool(size_t)> with_track = [](const size_t& e_idx) { return sim_tracks[e_idx].trkIdx().size() > 0; };
  87. function<float(size_t)> sim_pt = [](const size_t& sim_idx) { return sim_tracks[sim_idx].pt(); };
  88. function<float(size_t)> sim_eta = [](const size_t& sim_idx) { return sim_tracks[sim_idx].eta(); };
  89. function<float(size_t)> sim_phi = [](const size_t& sim_idx) { return sim_tracks[sim_idx].phi(); };
  90. float pt_cut = 20; // GeV
  91. float eta_cut = 2.4;
  92. function<bool(size_t)> sim_in_pt = [pt_cut](size_t sim_idx) {
  93. return sim_tracks[sim_idx].pt() > pt_cut;
  94. };
  95. function<bool(size_t)> sim_in_eta = [eta_cut](size_t sim_idx) {
  96. return abs(sim_tracks[sim_idx].eta()) < eta_cut;
  97. };
  98. function<bool(size_t)> sim_in_eta_and_pt = [eta_cut, pt_cut](size_t sim_idx) {
  99. return abs(sim_tracks[sim_idx].eta()) < eta_cut and
  100. sim_tracks[sim_idx].pt() > pt_cut;
  101. };
  102. tds.register_container<EfficiencyContainer<size_t>>("seed_eff_v_pt",
  103. good_sim_electrons, TH1Params::lookup("eff_v_pt"), &sim_in_eta, &with_seed, &sim_pt);
  104. tds.register_container<EfficiencyContainer<size_t>>("seed_eff_v_eta",
  105. good_sim_electrons, TH1Params::lookup("eff_v_eta"), &sim_in_pt, &with_seed, &sim_eta);
  106. tds.register_container<EfficiencyContainer<size_t>>("seed_eff_v_phi",
  107. good_sim_electrons, TH1Params::lookup("eff_v_phi"), &sim_in_eta_and_pt, &with_seed, &sim_phi);
  108. tds.register_container<EfficiencyContainer<size_t>>("track_eff_v_pt",
  109. good_sim_electrons, TH1Params::lookup("eff_v_pt"), &sim_in_eta, &with_track, &sim_pt);
  110. tds.register_container<EfficiencyContainer<size_t>>("track_eff_v_eta",
  111. good_sim_electrons, TH1Params::lookup("eff_v_eta"), &sim_in_pt, &with_track, &sim_eta);
  112. tds.register_container<EfficiencyContainer<size_t>>("track_eff_v_phi",
  113. good_sim_electrons, TH1Params::lookup("eff_v_phi"), &sim_in_eta_and_pt, &with_track, &sim_phi);
  114. // Indices of ecal-driven seeds
  115. auto ecal_seeds = func_value<vector<size_t>>("ecal_seeds",
  116. FUNC(([](){
  117. vector<size_t> idxs;
  118. for (const auto& seed : seeds) {
  119. idxs.push_back(seed.idx);
  120. }
  121. return idxs;
  122. })));
  123. function<bool(size_t)> seed_with_sim_electron = [](const size_t& seed_idx) {
  124. for (const int& simTrkIdx : seeds[seed_idx].simTrkIdx()) {
  125. if (is_good_sim(simTrkIdx)) return true;
  126. }
  127. return false;
  128. };
  129. function<float(size_t)> seed_pt = [](const size_t& seed_idx) { return seeds[seed_idx].pt(); };
  130. function<float(size_t)> seed_eta = [](const size_t& seed_idx) { return seeds[seed_idx].eta(); };
  131. function<float(size_t)> seed_phi = [](const size_t& seed_idx) { return seeds[seed_idx].phi(); };
  132. function<bool(size_t)> seed_in_pt = [pt_cut](size_t seed_idx) { return seeds[seed_idx].pt() > pt_cut; };
  133. function<bool(size_t)> seed_in_eta = [eta_cut](size_t seed_idx) { return abs(seeds[seed_idx].eta()) < eta_cut; };
  134. function<bool(size_t)> seed_in_eta_and_pt = [eta_cut, pt_cut](size_t seed_idx) {
  135. return abs(seeds[seed_idx].eta()) < eta_cut and
  136. seeds[seed_idx].pt() > pt_cut;
  137. };
  138. tds.register_container<EfficiencyContainer<size_t>>("seed_pur_v_pt",
  139. ecal_seeds, TH1Params::lookup("pur_v_pt"), &seed_in_eta, &seed_with_sim_electron, &seed_pt, true);
  140. tds.register_container<EfficiencyContainer<size_t>>("seed_pur_v_eta",
  141. ecal_seeds, TH1Params::lookup("pur_v_eta"), &seed_in_pt, &seed_with_sim_electron, &seed_eta, true);
  142. tds.register_container<EfficiencyContainer<size_t>>("seed_pur_v_phi",
  143. ecal_seeds, TH1Params::lookup("pur_v_phi"), &seed_in_eta_and_pt, &seed_with_sim_electron, &seed_phi, true);
  144. // Indices of gsf-tracks from ECAL-Driven Seeds
  145. auto ecal_tracks = func_value<vector<size_t>>("ecal_tracks",
  146. FUNC(([]() {
  147. vector<size_t> idxs;
  148. for (const auto& seed : seeds) {
  149. const int& trk_idx = seed.trkIdx();
  150. if (trk_idx >= 0) idxs.push_back(trk_idx);
  151. }
  152. return idxs;
  153. })));
  154. function<bool(size_t)> gsf_track_with_sim_electron = [](const size_t& track_idx) {
  155. for (const int& simTrkIdx : gsf_tracks[track_idx].simTrkIdx()) {
  156. if (is_good_sim(simTrkIdx)) return true;
  157. }
  158. return false;
  159. };
  160. function<float(size_t)> track_pt = [](const size_t& track_idx) { return gsf_tracks[track_idx].pt(); };
  161. function<float(size_t)> track_eta = [](const size_t& track_idx) { return gsf_tracks[track_idx].eta(); };
  162. function<float(size_t)> track_phi = [](const size_t& track_idx) { return gsf_tracks[track_idx].phi(); };
  163. function<bool(size_t)> track_in_pt = [pt_cut](size_t track_idx) { return gsf_tracks[track_idx].pt() > pt_cut; };
  164. function<bool(size_t)> track_in_eta = [eta_cut](size_t track_idx) { return abs(gsf_tracks[track_idx].eta()) < eta_cut; };
  165. function<bool(size_t)> track_in_eta_and_pt = [eta_cut, pt_cut](size_t track_idx) {
  166. return abs(gsf_tracks[track_idx].eta()) < eta_cut and gsf_tracks[track_idx].pt() > pt_cut;
  167. };
  168. tds.register_container<EfficiencyContainer<size_t>>("track_pur_v_pt",
  169. ecal_tracks, TH1Params::lookup("pur_v_pt"), &track_in_eta, &gsf_track_with_sim_electron, &track_pt, true);
  170. tds.register_container<EfficiencyContainer<size_t>>("track_pur_v_eta",
  171. ecal_tracks, TH1Params::lookup("pur_v_eta"), &track_in_pt, &gsf_track_with_sim_electron, &track_eta, true);
  172. tds.register_container<EfficiencyContainer<size_t>>("track_pur_v_phi",
  173. ecal_tracks, TH1Params::lookup("pur_v_phi"), &track_in_eta_and_pt, &gsf_track_with_sim_electron, &track_phi, true);
  174. auto residuals_rPhi = func<vector<float>(int, int, int)>("residuals_rPhi",
  175. FUNC(([](int detSel, int layerSel, int hitSel) {
  176. std::vector<float> residuals;
  177. for (const Seed& seed : seeds) {
  178. int nHits = seed.isBarrel().size();
  179. for (int idx_hit=0; idx_hit<nHits; idx_hit++) {
  180. if ((detSel==0 or detSel==seed.isBarrel()[idx_hit]) and
  181. (layerSel==0 or layerSel==seed.layerOrDiskNr()[idx_hit]) and
  182. (hitSel==0 or hitSel==(idx_hit+1))) {
  183. if (seed.isValidPos()[idx_hit]) {
  184. residuals.push_back(seed.dRZPos()[idx_hit]);
  185. }
  186. if (seed.isValidNeg()[idx_hit]) {
  187. residuals.push_back(seed.dRZNeg()[idx_hit]);
  188. }
  189. }
  190. }
  191. }
  192. return residuals;
  193. })));
  194. tds.register_container<ContainerTH1Many<float>>("residuals_all",
  195. tup_apply(residuals_rPhi, fv::tuple(constant("BPIX", 1), constant("ALL", 0), constant("ALL", 0))),
  196. TH1Params::lookup("residuals_all"));
  197. tds.process(silent);
  198. tds.save_all();
  199. }
  200. int main(int argc, char * argv[]){
  201. using namespace fv::util;
  202. ArgParser args(argc, argv);
  203. bool silent = args.cmdOptionExists("-s");
  204. if(args.cmdOptionExists("-c")) {
  205. init_config(args.getCmdOption("-c"));
  206. auto output_filename = the_config->get_output_filename();
  207. if (output_filename == "") return -1;
  208. init_log(fv::util::LogPriority::kLogInfo);
  209. gSystem->Load("libfilval.so");
  210. auto file_list = the_config->get_source_files();
  211. run_analysis(file_list, output_filename, silent);
  212. } else {
  213. cout << "Usage: ./tracking_eff (-s) -c config_file.yaml" << endl;
  214. }
  215. return 0;
  216. }