tracking_validation.cpp 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382
  1. #include <iostream>
  2. #include <vector>
  3. #include <utility>
  4. #include <numeric>
  5. #include <limits>
  6. #include <cmath>
  7. #include <TSystem.h>
  8. #include "filval/filval.hpp"
  9. #include "filval/root/filval.hpp"
  10. #include <boost/range/combine.hpp>
  11. #include <boost/format.hpp>
  12. #include "TrackingNtuple.h"
  13. #include "analysis/obj_types.cpp"
  14. using namespace std;
  15. using namespace fv;
  16. using namespace fv::root;
  17. using namespace std;
  18. typedef std::tuple<Seed, PixRecHit, Track, SimHit, SimTrack> MatchedTrack;
  19. typedef std::pair<std::vector<float>,std::vector<float>> pair_vec;
  20. #define HIT_TYPE_PIXEL 0
  21. #define HIT_TYPE_GLUED 1
  22. #define HIT_TYPE_STRIP 2
  23. #define PIXEL_BARREL 1
  24. #define PIXEL_ENDCAP 2
  25. vector<string> subdet_names = {"", "BPIX", "FPIX"};
  26. template<typename A, typename B>
  27. float displacement(const A& a, const B& b){
  28. return std::sqrt(pow(a.x-b.x, 2) +
  29. pow(a.x-b.x, 2) +
  30. pow(a.x-b.x, 2));
  31. }
  32. bool in_det(const MatchedTrack &mt, int &&det, int &&layer){
  33. auto& hit = std::get<PixRecHit>(mt);
  34. return hit.det == det && hit.lay == layer;
  35. };
  36. vector<string> seedTypes =
  37. {"initialStepSeeds",
  38. "highPtTripletStepSeeds",
  39. "mixedTripletStepSeeds",
  40. "pixelLessStepSeeds",
  41. "tripletElectronSeeds",
  42. "pixelPairElectronSeeds",
  43. "stripPairElectronSeeds"};
  44. Value<vector<Seed>>* seeds;
  45. Value<vector<PixRecHit>>* pixrec_hits;
  46. Value<vector<Track>>* tracks;
  47. Value<vector<SimHit>>* sim_hits;
  48. Value<vector<SimTrack>>* sim_tracks;
  49. void register_objects(TrackingDataSet& tds){
  50. seeds = register_seeds(tds);
  51. pixrec_hits = register_pixrec_hits(tds);
  52. tracks = register_tracks(tds);
  53. sim_hits = register_sim_hits(tds);
  54. sim_tracks = register_sim_tracks(tds);
  55. }
  56. void setup_first_hit_pairs(TrackingDataSet& tds){
  57. // Finds pairs of (rechit, simhit) where the rechit is the innermost hit on
  58. // a seed in a particular barrel layer.
  59. typedef std::tuple<PixRecHit, SimHit> HitPair;
  60. auto& matched_hits_in_layer =
  61. func<vector<HitPair>(vector<Seed>,
  62. vector<PixRecHit>,
  63. vector<SimHit>, int)>("find_matched_innermost_hits_in_layer",
  64. FUNC(([](const vector<Seed>& seeds,
  65. const vector<PixRecHit>& pixrec_hits,
  66. const vector<SimHit>& sim_hits,
  67. const int&& bpix_layer){
  68. vector<HitPair> matched_hits;
  69. for(const Seed &seed : seeds){
  70. if( seed.algoOriginal < 0 || seed.algoOriginal >= seedTypes.size()) continue;
  71. for(auto tup : boost::combine(seed.hitIdx, seed.hitType)){ //for hits in track's seed
  72. int hitIdx, hitType;
  73. boost::tie(hitIdx, hitType) = tup;
  74. if(hitType != HIT_TYPE_PIXEL) continue; // take only pixel hits for now
  75. const PixRecHit &rec_hit = pixrec_hits[hitIdx];
  76. if(rec_hit.det == PIXEL_BARREL && rec_hit.lay == bpix_layer){
  77. if(rec_hit.simHitIdx.size() > 0){
  78. matched_hits.push_back({rec_hit, sim_hits[rec_hit.simHitIdx[0]]});
  79. }
  80. }
  81. break;
  82. }
  83. }
  84. return matched_hits;
  85. })));
  86. auto first_hits_in_B1 = fv::apply(matched_hits_in_layer, fv::tuple(seeds, pixrec_hits, sim_hits, constant("1", 1)), "first_hits_in_B1");
  87. auto first_hits_in_B2 = fv::apply(matched_hits_in_layer, fv::tuple(seeds, pixrec_hits, sim_hits, constant("2", 2)), "first_hits_in_B2");
  88. auto& calc_dphi = func<float(HitPair)>("calc_dphi",
  89. FUNC(([](const HitPair& hit_pair){
  90. const auto &rec_hit = std::get<PixRecHit>(hit_pair);
  91. const auto &sim_hit = std::get<SimHit>(hit_pair);
  92. return atan2(rec_hit.x, rec_hit.y) - atan2(sim_hit.x, sim_hit.y);
  93. })));
  94. tds.register_container<ContainerTH1Many<float>>("matched_hits_from_B1", "Matched Hits dPhi - B1",
  95. fv::map(calc_dphi, first_hits_in_B1),
  96. 100, -0.001, 0.001,"dPhi(rad)");
  97. tds.register_container<ContainerTH1Many<float>>("matched_hits_from_B2", "Matched Hits dPhi - B2",
  98. fv::map(calc_dphi, first_hits_in_B2),
  99. 100, -0.001, 0.001,"dPhi(rad)");
  100. }
  101. void setup_matched_tracks(TrackingDataSet& tds){
  102. // Finds sets of (seed, rechit, track, simhit sim_track) where the cycle
  103. // track->seed->rec_hit->sim_hit->sim_track->track
  104. // is closed
  105. auto& find_matched_tracks =
  106. func<vector<MatchedTrack>(vector<Seed>,
  107. vector<PixRecHit>,
  108. vector<Track>,
  109. vector<SimHit>,
  110. vector<SimTrack>)>("find_matched_tracks",
  111. FUNC(([](const vector<Seed>& seeds,
  112. const vector<PixRecHit> pixrec_hits,
  113. const vector<Track>& tracks,
  114. const vector<SimHit> sim_hits,
  115. const vector<SimTrack> sim_tracks){
  116. INFO("New event");
  117. INFO(boost::format("Number of tracks is %d, number of seeds is %d, number of hits %d, number of simhits %d")
  118. % tracks.size() % seeds.size() % pixrec_hits.size() % sim_hits.size());
  119. vector<MatchedTrack> matched_tracks;
  120. for(const Track &track : tracks){
  121. const Seed& seed = seeds[track.seedIdx];
  122. if( seed.algoOriginal < 0 || seed.algoOriginal >= seedTypes.size()) continue;
  123. INFO(boost::format(" seed indx= %d algorithm= %d type %s\n")
  124. % track.seedIdx % seed.algoOriginal % seedTypes[seed.algoOriginal]);
  125. for(auto tup : boost::combine(seed.hitIdx, seed.hitType)){ //for hits in track's seed
  126. int hitIdx, hitType;
  127. boost::tie(hitIdx, hitType) = tup;
  128. if(hitType != HIT_TYPE_PIXEL) continue; // take only pixel hits for now
  129. const PixRecHit &rec_hit = pixrec_hits[hitIdx];
  130. TVector3 recoHitPoint;
  131. recoHitPoint.SetXYZ( rec_hit.x, rec_hit.y, rec_hit.z);
  132. float Rreco = recoHitPoint.Perp();
  133. INFO(boost::format(" hit= %d is in %s-L%d at radius= %f\n")
  134. % hitIdx % subdet_names[rec_hit.det] % rec_hit.lay % Rreco);
  135. for(const int& simHitIdx : rec_hit.simHitIdx){ // for sim-hits matching rec-hit
  136. const SimHit &sim_hit = sim_hits[simHitIdx];
  137. const SimTrack &sim_track = sim_tracks[sim_hit.simTrkIdx];
  138. for(const int &trkIdx : sim_track.trkIdx){ // for tracks matched to this sim_track
  139. if(trkIdx == track.idx){ // sim_track matches with our original track
  140. matched_tracks.push_back({seed, rec_hit, track, sim_hit, sim_track});
  141. break;
  142. }
  143. }
  144. }
  145. }
  146. }
  147. return matched_tracks;
  148. })));
  149. fv::apply(find_matched_tracks, fv::tuple(seeds, pixrec_hits, tracks, sim_hits, sim_tracks), "matched_tracks");
  150. }
  151. void setup_residuals(TrackingDataSet &tds){
  152. auto matched_tracks = lookup<vector<MatchedTrack>>("matched_tracks");
  153. // Break matched_tracks into catagories based on Barrel/Endcap and layer
  154. auto matched_tracks_B1 = filter(func<bool(MatchedTrack)>("matched_tracks_B1",
  155. FUNC(([](const MatchedTrack& matched_track){
  156. return in_det(matched_track, PIXEL_BARREL, 1);
  157. }))), matched_tracks);
  158. auto matched_tracks_B2 = filter(func<bool(MatchedTrack)>("matched_tracks_B2",
  159. FUNC(([](const MatchedTrack& matched_track){
  160. return in_det(matched_track, PIXEL_BARREL, 2);
  161. }))), matched_tracks);
  162. auto matched_tracks_B3 = filter(func<bool(MatchedTrack)>("matched_tracks_B3",
  163. FUNC(([](const MatchedTrack& matched_track){
  164. return in_det(matched_track, PIXEL_BARREL, 3);
  165. }))), matched_tracks);
  166. auto matched_tracks_B4 = filter(func<bool(MatchedTrack)>("matched_tracks_B4",
  167. FUNC(([](const MatchedTrack& matched_track){
  168. return in_det(matched_track, PIXEL_BARREL, 4);
  169. }))), matched_tracks);
  170. auto matched_tracks_F1 = filter(func<bool(MatchedTrack)>("matched_tracks_F1",
  171. FUNC(([](const MatchedTrack& matched_track){
  172. return in_det(matched_track, PIXEL_ENDCAP, 1);
  173. }))), matched_tracks);
  174. auto matched_tracks_F2 = filter(func<bool(MatchedTrack)>("matched_tracks_F2",
  175. FUNC(([](const MatchedTrack& matched_track){
  176. return in_det(matched_track, PIXEL_ENDCAP, 2);
  177. }))), matched_tracks);
  178. auto matched_tracks_F3 = filter(func<bool(MatchedTrack)>("matched_tracks_F3",
  179. FUNC(([](const MatchedTrack& matched_track){
  180. return in_det(matched_track, PIXEL_ENDCAP, 3);
  181. }))), matched_tracks);
  182. auto& calc_residuals_v_eta = func<pair_vec(vector<MatchedTrack>)>("matched_track_hit_residuals",
  183. FUNC(([](const vector<MatchedTrack>& matched_tracks){
  184. vector<float> residuals;
  185. vector<float> etas;
  186. for(auto matched_track : matched_tracks){
  187. auto& pixrec_hit = std::get<PixRecHit>(matched_track);
  188. auto& sim_hit = std::get<SimHit>(matched_track);
  189. auto& sim_track = std::get<SimTrack>(matched_track);
  190. residuals.push_back(displacement(pixrec_hit, sim_hit));
  191. etas.push_back(sim_track.eta);
  192. }
  193. return std::make_pair(etas, residuals);
  194. })));
  195. tds.register_container<ContainerTH2Many<float>>("matched_track_residuals_v_eta_all", "Matched Track Residuals - All",
  196. fv::apply(calc_residuals_v_eta, fv::tuple(matched_tracks)),
  197. 100, -4, 4, 100, 0, .01,"Eta","Residuals(cm)");
  198. tds.register_container<ContainerTH2Many<float>>("matched_track_residuals_v_eta_B1", "Matched Track Residuals - B1",
  199. fv::apply(calc_residuals_v_eta, fv::tuple(matched_tracks_B1)),
  200. 100, -4, 4, 100, 0, .01,"Eta","Residuals(cm)");
  201. tds.register_container<ContainerTH2Many<float>>("matched_track_residuals_v_eta_B2", "Matched Track Residuals - B2",
  202. fv::apply(calc_residuals_v_eta, fv::tuple(matched_tracks_B2)),
  203. 100, -4, 4, 100, 0, .01,"Eta","Residuals(cm)");
  204. tds.register_container<ContainerTH2Many<float>>("matched_track_residuals_v_eta_B3", "Matched Track Residuals - B3",
  205. fv::apply(calc_residuals_v_eta, fv::tuple(matched_tracks_B3)),
  206. 100, -4, 4, 100, 0, .01,"Eta","Residuals(cm)");
  207. tds.register_container<ContainerTH2Many<float>>("matched_track_residuals_v_eta_B4", "Matched Track Residuals - B4",
  208. fv::apply(calc_residuals_v_eta, fv::tuple(matched_tracks_B4)),
  209. 100, -4, 4, 100, 0, .01,"Eta","Residuals(cm)");
  210. tds.register_container<ContainerTH2Many<float>>("matched_track_residuals_v_eta_F1", "Matched Track Residuals - F1",
  211. fv::apply(calc_residuals_v_eta, fv::tuple(matched_tracks_F1)),
  212. 100, -4, 4, 100, 0, .01,"Eta","Residuals(cm)");
  213. tds.register_container<ContainerTH2Many<float>>("matched_track_residuals_v_eta_F2", "Matched Track Residuals - F2",
  214. fv::apply(calc_residuals_v_eta, fv::tuple(matched_tracks_F2)),
  215. 100, -4, 4, 100, 0, .01,"Eta","Residuals(cm)");
  216. tds.register_container<ContainerTH2Many<float>>("matched_track_residuals_v_eta_F3", "Matched Track Residuals - F3",
  217. fv::apply(calc_residuals_v_eta, fv::tuple(matched_tracks_F3)),
  218. 100, -4, 4, 100, 0, .01,"Eta","Residuals(cm)");
  219. auto& calc_dphi_v_eta = func<pair_vec(vector<MatchedTrack>)>("matched_track_hit_dphis",
  220. FUNC(([](const vector<MatchedTrack>& matched_tracks){
  221. vector<float> dphis;
  222. vector<float> etas;
  223. for(auto matched_track : matched_tracks){
  224. auto& pixrec_hit = std::get<PixRecHit>(matched_track);
  225. auto& sim_hit = std::get<SimHit>(matched_track);
  226. auto& sim_track = std::get<SimTrack>(matched_track);
  227. dphis.push_back(atan2(sim_hit.x, sim_hit.y) - atan2(pixrec_hit.x, pixrec_hit.y));
  228. etas.push_back(sim_track.eta);
  229. }
  230. return std::make_pair(etas, dphis);
  231. })));
  232. tds.register_container<ContainerTH2Many<float>>("matched_track_dphis_v_eta_all", "Matched Track dphis - All",
  233. fv::apply(calc_dphi_v_eta, fv::tuple(matched_tracks)),
  234. 100, -4, 4, 100, -.002, .002,"Eta","Residuals(rad)");
  235. tds.register_container<ContainerTH2Many<float>>("matched_track_dphis_v_eta_B1", "Matched Track dphis - B1",
  236. fv::apply(calc_dphi_v_eta, fv::tuple(matched_tracks_B1)),
  237. 100, -4, 4, 100, -.002, .002,"Eta","dphis(rad)");
  238. tds.register_container<ContainerTH2Many<float>>("matched_track_dphis_v_eta_B2", "Matched Track dphis - B2",
  239. fv::apply(calc_dphi_v_eta, fv::tuple(matched_tracks_B2)),
  240. 100, -4, 4, 100, -.002, .002,"Eta","dphis(rad)");
  241. tds.register_container<ContainerTH2Many<float>>("matched_track_dphis_v_eta_B3", "Matched Track dphis - B3",
  242. fv::apply(calc_dphi_v_eta, fv::tuple(matched_tracks_B3)),
  243. 100, -4, 4, 100, -.002, .002,"Eta","dphis(rad)");
  244. tds.register_container<ContainerTH2Many<float>>("matched_track_dphis_v_eta_B4", "Matched Track dphis - B4",
  245. fv::apply(calc_dphi_v_eta, fv::tuple(matched_tracks_B4)),
  246. 100, -4, 4, 100, -.002, .002,"Eta","dphis(rad)");
  247. tds.register_container<ContainerTH2Many<float>>("matched_track_dphis_v_eta_F1", "Matched Track dphis - F1",
  248. fv::apply(calc_dphi_v_eta, fv::tuple(matched_tracks_F1)),
  249. 100, -4, 4, 100, -.002, .002,"Eta","dphis(rad)");
  250. tds.register_container<ContainerTH2Many<float>>("matched_track_dphis_v_eta_F2", "Matched Track dphis - F2",
  251. fv::apply(calc_dphi_v_eta, fv::tuple(matched_tracks_F2)),
  252. 100, -4, 4, 100, -.002, .002,"Eta","dphis(rad)");
  253. tds.register_container<ContainerTH2Many<float>>("matched_track_dphis_v_eta_F3", "Matched Track dphis - F3",
  254. fv::apply(calc_dphi_v_eta, fv::tuple(matched_tracks_F3)),
  255. 100, -4, 4, 100, -.002, .002,"Eta","dphis(rad)");
  256. auto& calc_dz_v_eta = func<pair_vec(vector<MatchedTrack>)>("matched_track_hit_dphis",
  257. FUNC(([](const vector<MatchedTrack>& matched_tracks){
  258. vector<float> dzs;
  259. vector<float> etas;
  260. for(auto matched_track : matched_tracks){
  261. auto& pixrec_hit = std::get<PixRecHit>(matched_track);
  262. auto& sim_hit = std::get<SimHit>(matched_track);
  263. auto& sim_track = std::get<SimTrack>(matched_track);
  264. dzs.push_back(sim_hit.z - pixrec_hit.z);
  265. etas.push_back(sim_track.eta);
  266. }
  267. return std::make_pair(etas, dzs);
  268. })));
  269. tds.register_container<ContainerTH2Many<float>>("matched_track_dzs_v_eta_all", "Matched Track dz - All",
  270. fv::apply(calc_dz_v_eta, fv::tuple(matched_tracks)),
  271. 100, -4, 4, 100, -.002, .002,"Eta","dz(cm)");
  272. tds.register_container<ContainerTH2Many<float>>("matched_track_dzs_v_eta_B1", "Matched Track dz - B1",
  273. fv::apply(calc_dz_v_eta, fv::tuple(matched_tracks_B1)),
  274. 100, -4, 4, 100, -.002, .002,"Eta","dz(cm)");
  275. tds.register_container<ContainerTH2Many<float>>("matched_track_dzs_v_eta_B2", "Matched Track dz - B2",
  276. fv::apply(calc_dz_v_eta, fv::tuple(matched_tracks_B2)),
  277. 100, -4, 4, 100, -.002, .002,"Eta","dz(cm)");
  278. tds.register_container<ContainerTH2Many<float>>("matched_track_dzs_v_eta_B3", "Matched Track dz - B3",
  279. fv::apply(calc_dz_v_eta, fv::tuple(matched_tracks_B3)),
  280. 100, -4, 4, 100, -.002, .002,"Eta","dz(cm)");
  281. tds.register_container<ContainerTH2Many<float>>("matched_track_dzs_v_eta_B4", "Matched Track dz - B4",
  282. fv::apply(calc_dz_v_eta, fv::tuple(matched_tracks_B4)),
  283. 100, -4, 4, 100, -.002, .002,"Eta","dz(cm)");
  284. auto& calc_dr_v_eta = func<pair_vec(vector<MatchedTrack>)>("matched_track_hit_drs",
  285. FUNC(([](const vector<MatchedTrack>& matched_tracks){
  286. vector<float> drs;
  287. vector<float> etas;
  288. for(auto matched_track : matched_tracks){
  289. auto& rec_hit = std::get<PixRecHit>(matched_track);
  290. auto& sim_hit = std::get<SimHit>(matched_track);
  291. float sim_hit_r = sqrt(pow(sim_hit.x, 2) + pow(sim_hit.y, 2));
  292. float rec_hit_r = sqrt(pow(rec_hit.x, 2) + pow(rec_hit.y, 2));
  293. drs.push_back(sim_hit_r - rec_hit_r);
  294. etas.push_back(std::get<SimTrack>(matched_track).eta);
  295. }
  296. return std::make_pair(etas, drs);
  297. })));
  298. tds.register_container<ContainerTH2Many<float>>("matched_track_drs_v_eta_F1", "Matched Track dz - F1",
  299. fv::apply(calc_dr_v_eta, fv::tuple(matched_tracks_F1)),
  300. 100, -4, 4, 100, -.002, .002,"Eta","dr(cm)");
  301. tds.register_container<ContainerTH2Many<float>>("matched_track_drs_v_eta_F2", "Matched Track dz - F2",
  302. fv::apply(calc_dr_v_eta, fv::tuple(matched_tracks_F2)),
  303. 100, -4, 4, 100, -.002, .002,"Eta","dr(cm)");
  304. tds.register_container<ContainerTH2Many<float>>("matched_track_drs_v_eta_F3", "Matched Track dz - F3",
  305. fv::apply(calc_dr_v_eta, fv::tuple(matched_tracks_F3)),
  306. 100, -4, 4, 100, -.002, .002,"Eta","dr(cm)");
  307. }
  308. void run_analysis(const vector<fv::util::DataFileDescriptor>& dfds, const string output_filename, bool silent){
  309. gSystem->Load("libfilval.so");
  310. auto replace_suffix = [](const std::string& input, const std::string& new_suffix){
  311. return input.substr(0, input.find_last_of(".")) + new_suffix;
  312. };
  313. string log_filename = replace_suffix(output_filename, ".log");
  314. fv::util::Log::init_logger(log_filename, fv::util::LogPriority::kLogDebug);
  315. TrackingDataSet tds(output_filename, dfds, "trackingNtuple/tree");
  316. /* tds.set_max_events(10); */
  317. register_objects(tds);
  318. setup_matched_tracks(tds);
  319. setup_residuals(tds);
  320. setup_first_hit_pairs(tds);
  321. tds.process(silent);
  322. tds.save_all();
  323. }
  324. int main(int argc, char * argv[]){
  325. fv::util::ArgParser args(argc, argv);
  326. bool silent = args.cmdOptionExists("-s");
  327. string output_filename = args.cmdOptionExists("-o") ? args.getCmdOption("-o") : "output.root";
  328. if(args.cmdOptionExists("-F")){
  329. auto file_list = fv::util::read_input_list(args.getCmdOption("-F"));
  330. run_analysis(file_list, output_filename, silent);
  331. }else if(args.cmdOptionExists("-f")){
  332. string input_filename = args.getCmdOption("-f");
  333. string data_label = args.cmdOptionExists("-l") ? args.getCmdOption("-l") : "";
  334. fv::util::DataFileDescriptor dfd(input_filename, data_label);
  335. run_analysis(std::vector<fv::util::DataFileDescriptor>({dfd}), output_filename, silent);
  336. }else {
  337. cout << "Usage: ./tracking_validation (-s) {-o output_filename} -F datafiles.txt" << endl;
  338. cout << " ./tracking_validation (-s) {-l DATA_LABEL} {-o output_filename} -f treefile.root" << endl;
  339. }
  340. }