tracking_eff.cpp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377
  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. vector<string> seedTypes =
  20. {"initialStepSeeds",
  21. "highPtTripletStepSeeds",
  22. "mixedTripletStepSeeds",
  23. "pixelLessStepSeeds",
  24. "tripletElectronSeeds",
  25. "pixelPairElectronSeeds",
  26. "stripPairElectronSeeds"};
  27. enum class HitType {
  28. Pixel = 0,
  29. Strip = 1,
  30. Glued = 2,
  31. Invalid = 3,
  32. Phase2OT = 4,
  33. Unknown = 99
  34. };
  35. SeedCollection seeds;
  36. SimTrackCollection sim_tracks;
  37. SimHitCollection sim_hits;
  38. SimVertexCollection sim_vertices;
  39. TrackCollection gsf_tracks;
  40. PixRecHitCollection pixrec_hits;
  41. void register_objects(TrackingDataSet& tds){
  42. seeds.init(tds);
  43. sim_tracks.init(tds);
  44. sim_hits.init(tds);
  45. sim_vertices.init(tds);
  46. gsf_tracks.init(tds);
  47. pixrec_hits.init(tds);
  48. }
  49. float rad(const float& x, const float& y) {
  50. return sqrt(x*x + y*y);
  51. }
  52. struct {
  53. Value<float>* x;
  54. Value<float>* y;
  55. Value<float>* z;
  56. Value<float>* sigma_x;
  57. Value<float>* sigma_y;
  58. Value<float>* sigma_z;
  59. } bs;
  60. bool in_lum_region(const SimVertex& vertex) {
  61. /* Here approximate the luminous region as a cylinder with length 5*\sigma_z and radius
  62. * sqrt(\simga_x^2 + \sigma_y^2) centered as beamspot position.
  63. */
  64. float dx = vertex.x() - bs.x->get_value();
  65. float dy = vertex.y() - bs.y->get_value();
  66. float dz = vertex.z() - bs.z->get_value();
  67. float radius = 5*sqrt(pow(bs.sigma_x->get_value(), 2) + pow(bs.sigma_y->get_value(), 2));
  68. float half_len = 5*bs.sigma_z->get_value();
  69. return sqrt(dx*dx + dy*dy) < radius and abs(dz) < half_len;
  70. };
  71. bool is_good_sim(size_t simTrkIdx) {
  72. const auto& track = sim_tracks[simTrkIdx];
  73. const auto& vertex = sim_vertices[track.parentVtxIdx()];
  74. return abs(track.pdgId()) == 11 and in_lum_region(vertex);
  75. };
  76. void run_analysis(const vector<fv::util::DataFileDescriptor>& dfds, const string output_filename, bool silent){
  77. TrackingDataSet tds(output_filename, dfds, "trackingNtuple/tree");
  78. register_objects(tds);
  79. bs = {
  80. tds.track_branch<float>("bsp_x"),
  81. tds.track_branch<float>("bsp_y"),
  82. tds.track_branch<float>("bsp_z"),
  83. tds.track_branch<float>("bsp_sigmax"),
  84. tds.track_branch<float>("bsp_sigmay"),
  85. tds.track_branch<float>("bsp_sigmaz")
  86. };
  87. // Indices of prompt-ish sim electrons
  88. auto good_sim_electrons = func_value<vector<size_t>>("good_sim_electrons",
  89. FUNC(([](){
  90. vector<size_t> idxs;
  91. for(const auto& sim_track : sim_tracks) {
  92. if (is_good_sim(sim_track.idx)) idxs.push_back(sim_track.idx);
  93. }
  94. return idxs;
  95. })));
  96. // Indices of prompt-ish sim electrons that have a matched seed
  97. function<bool(size_t)> with_seed = [](const size_t& e_idx) {
  98. return seeds.size() != 0 and sim_tracks[e_idx].seedIdx().size() != 0;
  99. };
  100. // Indices of prompt-ish sim electrons that have a matched gsftrack
  101. function<bool(size_t)> with_track = [](const size_t& e_idx) {
  102. return sim_tracks[e_idx].trkIdx().size() > 0;
  103. };
  104. function<float(size_t)> sim_pt = [](const size_t& sim_idx) {
  105. return sim_tracks[sim_idx].pt();
  106. };
  107. function<float(size_t)> sim_eta = [](const size_t& sim_idx) {
  108. return sim_tracks[sim_idx].eta();
  109. };
  110. function<float(size_t)> sim_phi = [](const size_t& sim_idx) {
  111. return sim_tracks[sim_idx].phi();
  112. };
  113. float pt_cut = 20; // GeV
  114. float eta_cut = 2.4;
  115. function<bool(size_t)> sim_in_pt = [pt_cut](size_t sim_idx) {
  116. return sim_tracks[sim_idx].pt() > pt_cut;
  117. };
  118. function<bool(size_t)> sim_in_eta = [eta_cut](size_t sim_idx) {
  119. return abs(sim_tracks[sim_idx].eta()) < eta_cut;
  120. };
  121. function<bool(size_t)> sim_in_eta_and_pt = [eta_cut, pt_cut](size_t sim_idx) {
  122. return abs(sim_tracks[sim_idx].eta()) < eta_cut and
  123. sim_tracks[sim_idx].pt() > pt_cut;
  124. };
  125. tds.register_container<EfficiencyContainer<size_t>>("seed_eff_v_pt",
  126. good_sim_electrons, TH1Params::lookup("eff_v_pt"), &sim_in_eta, &with_seed, &sim_pt);
  127. tds.register_container<EfficiencyContainer<size_t>>("seed_eff_v_eta",
  128. good_sim_electrons, TH1Params::lookup("eff_v_eta"), &sim_in_pt, &with_seed, &sim_eta);
  129. tds.register_container<EfficiencyContainer<size_t>>("seed_eff_v_phi",
  130. good_sim_electrons, TH1Params::lookup("eff_v_phi"), &sim_in_eta_and_pt, &with_seed, &sim_phi);
  131. tds.register_container<EfficiencyContainer<size_t>>("track_eff_v_pt",
  132. good_sim_electrons, TH1Params::lookup("eff_v_pt"), &sim_in_eta, &with_track, &sim_pt);
  133. tds.register_container<EfficiencyContainer<size_t>>("track_eff_v_eta",
  134. good_sim_electrons, TH1Params::lookup("eff_v_eta"), &sim_in_pt, &with_track, &sim_eta);
  135. tds.register_container<EfficiencyContainer<size_t>>("track_eff_v_phi",
  136. good_sim_electrons, TH1Params::lookup("eff_v_phi"), &sim_in_eta_and_pt, &with_track, &sim_phi);
  137. // Indices of ecal-driven seeds
  138. auto ecal_seeds = func_value<vector<size_t>>("ecal_seeds",
  139. FUNC(([](){
  140. vector<size_t> idxs;
  141. for (const auto& seed : seeds) {
  142. if (seed.ecalDriven())
  143. idxs.push_back(seed.idx);
  144. }
  145. return idxs;
  146. })));
  147. function<bool(size_t)> seed_with_sim_electron = [](const size_t& seed_idx) {
  148. for (const int& simTrkIdx : seeds[seed_idx].simTrkIdx()) {
  149. if (is_good_sim(simTrkIdx)) return true;
  150. }
  151. return false;
  152. };
  153. function<float(size_t)> seed_pt = [](const size_t& seed_idx) {
  154. return seeds[seed_idx].pt();
  155. };
  156. function<float(size_t)> seed_eta = [](const size_t& seed_idx) {
  157. return seeds[seed_idx].eta();
  158. };
  159. function<float(size_t)> seed_phi = [](const size_t& seed_idx) {
  160. return seeds[seed_idx].phi();
  161. };
  162. function<bool(size_t)> seed_in_pt = [pt_cut](size_t seed_idx) {
  163. return seeds[seed_idx].pt() > pt_cut;
  164. };
  165. function<bool(size_t)> seed_in_eta = [eta_cut](size_t seed_idx) {
  166. return abs(seeds[seed_idx].eta()) < eta_cut;
  167. };
  168. function<bool(size_t)> seed_in_eta_and_pt = [eta_cut, pt_cut](size_t seed_idx) {
  169. return abs(seeds[seed_idx].eta()) < eta_cut and
  170. seeds[seed_idx].pt() > pt_cut;
  171. };
  172. tds.register_container<EfficiencyContainer<size_t>>("seed_pur_v_pt",
  173. ecal_seeds, TH1Params::lookup("pur_v_pt"), &seed_in_eta, &seed_with_sim_electron, &seed_pt);
  174. tds.register_container<EfficiencyContainer<size_t>>("seed_pur_v_eta",
  175. ecal_seeds, TH1Params::lookup("pur_v_eta"), &seed_in_pt, &seed_with_sim_electron, &seed_eta);
  176. tds.register_container<EfficiencyContainer<size_t>>("seed_pur_v_phi",
  177. ecal_seeds, TH1Params::lookup("pur_v_phi"), &seed_in_eta_and_pt, &seed_with_sim_electron, &seed_phi);
  178. // Indices of ecal-driven gsf-tracks
  179. auto ecal_tracks = func_value<vector<size_t>>("ecal_tracks",
  180. FUNC(([](){
  181. vector<size_t> idxs;
  182. for (const auto& track : gsf_tracks) {
  183. const auto& seed = seeds[track.seedIdx()];
  184. if (seed.ecalDriven())
  185. idxs.push_back(track.idx);
  186. }
  187. return idxs;
  188. })));
  189. function<bool(size_t)> gsf_track_with_sim_electron = [](const size_t& track_idx) {
  190. for (const int& simTrkIdx : gsf_tracks[track_idx].simTrkIdx()) {
  191. if (is_good_sim(simTrkIdx)) return true;
  192. }
  193. return false;
  194. };
  195. function<float(size_t)> track_pt = [](const size_t& track_idx) {
  196. return gsf_tracks[track_idx].pt();
  197. };
  198. function<float(size_t)> track_eta = [](const size_t& track_idx) {
  199. return gsf_tracks[track_idx].eta();
  200. };
  201. function<float(size_t)> track_phi = [](const size_t& track_idx) {
  202. return gsf_tracks[track_idx].phi();
  203. };
  204. function<bool(size_t)> track_in_pt = [pt_cut](size_t track_idx) {
  205. return gsf_tracks[track_idx].pt() > pt_cut;
  206. };
  207. function<bool(size_t)> track_in_eta = [eta_cut](size_t track_idx) {
  208. return abs(gsf_tracks[track_idx].eta()) < eta_cut;
  209. };
  210. function<bool(size_t)> track_in_eta_and_pt = [eta_cut, pt_cut](size_t track_idx) {
  211. return abs(gsf_tracks[track_idx].eta()) < eta_cut and
  212. gsf_tracks[track_idx].pt() > pt_cut;
  213. };
  214. tds.register_container<EfficiencyContainer<size_t>>("track_pur_v_pt",
  215. ecal_tracks, TH1Params::lookup("pur_v_pt"), &track_in_eta, &gsf_track_with_sim_electron, &track_pt);
  216. tds.register_container<EfficiencyContainer<size_t>>("track_pur_v_eta",
  217. ecal_tracks, TH1Params::lookup("pur_v_eta"), &track_in_pt, &gsf_track_with_sim_electron, &track_eta);
  218. tds.register_container<EfficiencyContainer<size_t>>("track_pur_v_phi",
  219. ecal_tracks, TH1Params::lookup("pur_v_phi"), &track_in_eta_and_pt, &gsf_track_with_sim_electron, &track_phi);
  220. auto simpixlay_v_eta = func_value<std::pair<vector<float>,vector<float>>>("sim_pixlay_v_eta",
  221. FUNC(([](){
  222. vector<float> etas;
  223. vector<float> nLays;
  224. for(const auto& sim_track : sim_tracks) {
  225. if(sim_track.pt() > 20 and is_good_sim(sim_track.idx)) {
  226. bool hasLHit[] = {false, false, false, false, // <- 4 barrel layers
  227. false, false, false}; // <- 3 fwd layers
  228. for(const auto& sim_hit_idx : sim_track.simHitIdx()) {
  229. const auto& sim_hit = sim_hits[sim_hit_idx];
  230. if (sim_hit.subdet() == 1) hasLHit[sim_hit.layer()-1] = true;
  231. if (sim_hit.subdet() == 2) hasLHit[sim_hit.layer()+3] = true;
  232. }
  233. int layers = 0;
  234. for(size_t i=0; i<7; i++) {
  235. if (hasLHit[i]) layers++;
  236. }
  237. etas.push_back(sim_track.eta());
  238. nLays.push_back(layers);
  239. }
  240. }
  241. return std::make_pair(etas, nLays);
  242. })));
  243. auto recpixlay_v_eta = func_value<std::pair<vector<float>,vector<float>>>("recpixlay_v_eta",
  244. FUNC(([](){
  245. vector<float> etas;
  246. vector<float> nLays;
  247. for(const auto& gsf_track : gsf_tracks) {
  248. if(gsf_track.pt() > 20) {
  249. bool hasLHit[] = {false, false, false, false, // <- 4 barrel layers
  250. false, false, false}; // <- 3 fwd layers
  251. const auto& hitIdx = gsf_track.hitIdx();
  252. const auto& hitType = gsf_track.hitType();
  253. size_t nHits = hitIdx.size();
  254. for(size_t i=0; i<nHits; i++) {
  255. if (HitType(hitType[i]) != HitType::Pixel) continue;
  256. const auto& pixrec_hit = pixrec_hits[hitIdx[i]];
  257. if (pixrec_hit.subdet() == 1) hasLHit[pixrec_hit.layer()-1] = true;
  258. if (pixrec_hit.subdet() == 2) hasLHit[pixrec_hit.layer()+3] = true;
  259. }
  260. int layers = 0;
  261. for(size_t i=0; i<7; i++) {
  262. if (hasLHit[i]) layers++;
  263. }
  264. etas.push_back(gsf_track.eta());
  265. nLays.push_back(layers);
  266. }
  267. }
  268. return std::make_pair(etas, nLays);
  269. })));
  270. tds.register_container<ContainerTH2Many<float>>("simpixlay_v_eta", simpixlay_v_eta, "simpixlay_v_eta",
  271. TH2Params::lookup("n_hit_v_eta"));
  272. tds.register_container<ContainerTH2Many<float>>("recpixlay_v_eta", recpixlay_v_eta, "recpixlay_v_eta",
  273. TH2Params::lookup("n_hit_v_eta"));
  274. // auto simtrack_hits = func_value<int>("simtrack_hits",
  275. // FUNC(([](){
  276. // vector<float> etas;
  277. // vector<float> nhits;
  278. // for(const auto& sim_track : sim_tracks) {
  279. // if(sim_track.pt() < 20 or !is_good_sim(sim_track.idx)) continue;
  280. // cout << "New Track: nPixel=" << sim_track.nPixel() << endl;
  281. // for(const auto& sim_hit_idx : sim_track.simHitIdx()) {
  282. // const auto& sim_hit = sim_hits[sim_hit_idx];
  283. // if (sim_hit.subdet() > 2) continue;
  284. // cout << " Hit: " << sim_hit_idx << endl
  285. // << " pos: " << sim_hit.x() << " " << sim_hit.y() << " " << sim_hit.z() << endl
  286. // << " subdet: " << sim_hit.subdet() << endl
  287. // << " layler: " << sim_hit.layer() << endl;
  288. // }
  289. // }
  290. // return 0;
  291. // })));
  292. //
  293. // ofstream out("blah.txt");
  294. // tds.register_container<Printer<int>>("blah", simtrack_hits, &out);
  295. tds.process(silent);
  296. tds.save_all();
  297. }
  298. int main(int argc, char * argv[]){
  299. using namespace fv::util;
  300. ArgParser args(argc, argv);
  301. bool silent = args.cmdOptionExists("-s");
  302. if(args.cmdOptionExists("-c")) {
  303. init_config(args.getCmdOption("-c"));
  304. auto output_filename = the_config->get_output_filename();
  305. if (output_filename == "") return -1;
  306. init_log(fv::util::LogPriority::kLogInfo);
  307. gSystem->Load("libfilval.so");
  308. auto file_list = the_config->get_source_files();
  309. run_analysis(file_list, output_filename, silent);
  310. } else {
  311. cout << "Usage: ./tracking_eff (-s) -c config_file.yaml" << endl;
  312. }
  313. return 0;
  314. }