Newer
Older
TB_Chris / Kepler / options / .svn / text-base / TbTrackingWithKalman.cpp.svn-base
  1. // Gaudi
  2. #include "GaudiKernel/PhysicalConstants.h"
  3. #include "GaudiKernel/AlgFactory.h"
  4. #include "GaudiUtils/Aida2ROOT.h"
  5. #include "GaudiUtils/HistoLabels.h"
  6.  
  7. // Tb/TbKernel
  8. #include "TbKernel/TbFunctors.h"
  9.  
  10. // ROOT
  11. #include "TMath.h"
  12.  
  13. #include <iostream>
  14. #include <math.h>
  15.  
  16. // Local
  17. #include "TbTracking.h"
  18. #include <algorithm>
  19.  
  20. DECLARE_ALGORITHM_FACTORY(TbTracking)
  21.  
  22. //=============================================================================
  23. // Standard constructor
  24. //=============================================================================
  25. TbTracking::TbTracking(const std::string& name, ISvcLocator* pSvcLocator)
  26. : TbAlgorithm(name, pSvcLocator),
  27. m_tracks(NULL),
  28. m_trackFit(NULL),
  29. m_clusterFinder(NULL) {
  30.  
  31. lowR = -0.2;
  32. highR = 0.2;
  33. binsR = 500;
  34. lowS = -0.02;
  35. highS = 0.02;
  36.  
  37. // Declare algorithm properties - see header for description.
  38. declareProperty("ClusterLocation",
  39. m_clusterLocation = LHCb::TbClusterLocation::Default);
  40. declareProperty("Monitoring", m_monitoring = false);
  41. declareProperty("HitError2", m_hiterror2 = 1.6e-5);
  42. declareProperty("Scat2", m_scat2 = 1.2e-8);
  43. declareProperty("TimeWindow", m_twindow = 150. * Gaudi::Units::ns);
  44. declareProperty("MinNClusters", m_MinNClusters = 7);
  45. declareProperty("SearchRadius", m_vol_radius = 1 * Gaudi::Units::mm);
  46. declareProperty("SearchRadiusY", m_vol_radiusY = 1 * Gaudi::Units::mm);
  47. declareProperty("MaxChi2", m_ChiSqRedCut = 20000.);
  48. declareProperty("SearchVolume", m_search_3vol = "diabolo");
  49. declareProperty("VolumeAngle", m_vol_theta = 0.015);
  50. declareProperty("VolumeAngleY", m_vol_thetaY = 0.005);
  51. declareProperty("SearchVolumeFillAlgorithm",
  52. m_ClusterFinderSearchAlgorithm = "adap_seq");
  53. declareProperty("nComboCut", m_nComboCut = 300);
  54. declareProperty("SearchPlanes", m_PlaneSearchOrder = {4, 3, 5});
  55. }
  56.  
  57. //=============================================================================
  58. // Destructor
  59. //=============================================================================
  60. TbTracking::~TbTracking() {
  61.  
  62. if (m_clusterFinder) delete m_clusterFinder;
  63. }
  64.  
  65. //=============================================================================
  66. // Initialization
  67. //=============================================================================
  68. StatusCode TbTracking::initialize() {
  69.  
  70. // Initialise the base class.
  71. StatusCode sc = TbAlgorithm::initialize();
  72. if (sc.isFailure()) return sc;
  73. // Setup the track fit tool.
  74. m_trackFit = tool<ITbTrackFit>("TbTrackFit", "Fitter", this);
  75. // Set up the cluster finder.
  76. m_clusterFinder =
  77. new TbClusterFinder(m_ClusterFinderSearchAlgorithm, m_nPlanes);
  78. // setup Kalman histos
  79. setup_hists();
  80. return StatusCode::SUCCESS;
  81. }
  82.  
  83. //=============================================================================
  84. // Main execution
  85. //=============================================================================
  86. StatusCode TbTracking::execute() {
  87.  
  88. for (unsigned int i = 0; i < m_nPlanes; ++i) {
  89. const std::string clusterLocation = m_clusterLocation + std::to_string(i);
  90. LHCb::TbClusters* clusters = getIfExists<LHCb::TbClusters>(clusterLocation);
  91. if (!clusters) {
  92. error() << "No clusters in " << clusterLocation << endmsg;
  93. return StatusCode::FAILURE;
  94. }
  95. // Store the cluster iterators in the cluster finder.
  96. m_clusterFinder->setClusters(clusters, i);
  97. }
  98. // Clear Kalman track container
  99. ktracks_vec.clear();
  100.  
  101.  
  102. // Create a track container and transfer its ownership to the TES.
  103. m_tracks = new LHCb::TbTracks();
  104. put(m_tracks, LHCb::TbTrackLocation::Default);
  105.  
  106. // Do the tracking and time order.
  107. performTracking();
  108. timeOrderTracks();
  109.  
  110. // fill the histos with the Kalman fit results
  111. fill_khists(ktracks_vec);
  112.  
  113. counter("NumberOfTracks") += m_tracks->size();
  114.  
  115. return StatusCode::SUCCESS;
  116. }
  117.  
  118. //=============================================================================
  119. // Actual tracking
  120. //=============================================================================
  121. void TbTracking::performTracking() {
  122. // The working of this algorithm is similar to the cluster maker, such that:
  123. // - Loop over some set of seed clusters (those on the m_SeedPlanes).
  124. // - Create a container (TbTrackVolume) centered on each seed cluster
  125. // (in space and time).
  126. // - Impose the condition that any formed track must contain this seed.
  127. // - Evaluate that 4-volume, to see if it contained a track.
  128. // - If a choice (e.g. more than one possible combination of clusters),
  129. // take the best fitting. Priority is given to more complete tracks.
  130. // - If another track happened to be in the 4volume, but not
  131. // containing this seed, then it will be found later.
  132.  
  133. // Iterate over planes in the specified order.
  134. for (const auto& plane : m_PlaneSearchOrder) {
  135. // Iterate over this planes' clusters - first check for any.
  136. if (masked(plane) || m_clusterFinder->empty(plane)) continue;
  137. auto ic = m_clusterFinder->first(plane);
  138. const auto end = m_clusterFinder->end(plane);
  139. for (; ic != end; ++ic) {
  140.  
  141. // Check if the seed has already been used.
  142. if ((*ic)->tracked()) continue;
  143. // Form the TbTrackVolume container, and fill with clusters that fall
  144. // in its space-time volume.
  145. TbTrackVolume* track_volume =
  146. new TbTrackVolume((*ic), m_search_3vol, m_nPlanes, m_twindow,
  147. m_vol_radius, m_vol_radiusY, m_vol_theta,
  148. m_vol_thetaY, m_MinNClusters);
  149. fillATrackVolume(track_volume);
  150.  
  151. // Look for a track - automatically keeps if suitable.
  152. evaluateTrackVolume(track_volume);
  153. // PoorMansEvaluation(track_volume); // Alternative evaluator.
  154.  
  155. delete track_volume;
  156. }
  157. }
  158. }
  159.  
  160. //=============================================================================
  161. // Fill 4volume.
  162. //=============================================================================
  163. void TbTracking::fillATrackVolume(TbTrackVolume* track_volume) {
  164. // Fills the given TbTrackVolume (that has a particular space-time volume)
  165. // with clusters from all planes (ie m_clusters) that fall in this space-time
  166. // volume.
  167.  
  168. for (unsigned int iplane = 0; iplane < m_nPlanes; iplane++) {
  169. // Check for any clusters, or track contains seed condition.
  170. if (m_clusterFinder->empty(iplane) ||
  171. iplane == track_volume->seed()->plane() || masked(iplane))
  172. continue;
  173.  
  174. // Create an iterator and find the appropriate cluster on the ith plane
  175. // whose TOA is at the start of this TbTrackVolumes' time window.
  176. auto ic = m_clusterFinder->getIterator(track_volume->t_lower(), iplane);
  177. const auto end = m_clusterFinder->end(iplane);
  178. // Loop until the TOA reaches the end of this TbTrackVolumes' time window.
  179. // (dummy end condition used in the for loop).
  180. for (; ic != end; ++ic) {
  181. // Add cluster if inside and not already tracked.
  182. track_volume->consider_cluster((*ic));
  183. // Stop if too far ahead in time.
  184. if ((*ic)->htime() > track_volume->t_upper()) break;
  185. }
  186. }
  187. }
  188.  
  189. //=============================================================================
  190. // Finding the best tracks
  191. //=============================================================================
  192. void TbTracking::evaluateTrackVolume(TbTrackVolume* track_volume) {
  193. // CURRENTLY, finds the most likely track containing either clusters on all
  194. // planes,
  195. // or tracks with one cluster missing.
  196.  
  197. // Declare some variables to be used.
  198. LHCb::TbTrack* best_track = NULL;
  199. double best_chi_dof = -1; // Something unphysical.
  200.  
  201. // Get the number of combinations to check (depends on the size of the track
  202. // to be formed).
  203. int ncombos = track_volume->nCombos();
  204.  
  205. track_volume->ResetComboCounters();
  206. // Do the search over this number of combinations - the TbTrackVolume has
  207. // methods
  208. // to retrive a particular combination of clusters forming a track (specified
  209. // by icombo).
  210. for (int icombo = 0; icombo < ncombos && icombo < m_nComboCut; icombo++) {
  211.  
  212. // Get the icombo'th track and fit.
  213. LHCb::TbTrack* trial_track = track_volume->get_track_combo();
  214. // Sort the clusters by z-position.
  215. SmartRefVector<LHCb::TbCluster>& clusters =
  216. const_cast<SmartRefVector<LHCb::TbCluster>&>(trial_track->clusters());
  217. std::sort(clusters.begin(), clusters.end(),
  218. TbFunctors::LessByZ<const LHCb::TbCluster*>());
  219. m_trackFit->fit(trial_track);
  220.  
  221. // Evaluate this track.
  222. const double chi2_per_dof = trial_track->chi2PerNdof();
  223.  
  224. // First combination tried case.
  225. if (icombo == 0) {
  226. best_chi_dof = chi2_per_dof;
  227. best_track = trial_track;
  228. track_volume->update_best(); // TbTrackVolumes keep a record of the best
  229. // fitting combination of clusters internally.
  230. } else if (chi2_per_dof < best_chi_dof) {
  231. // Case of better combination.
  232. delete best_track;
  233. best_chi_dof = chi2_per_dof;
  234. best_track = trial_track;
  235. track_volume->update_best();
  236. } else
  237. delete trial_track;
  238. // Prepare for next combination.
  239. track_volume->increment_combo_counters();
  240. }
  241.  
  242. if (best_track) {
  243. // At this point, found the best fitting track in the volume. Apply chi cut,
  244. // and save.
  245. if (best_chi_dof < m_ChiSqRedCut) {
  246.  
  247. SmartRefVector<LHCb::TbCluster>& clusters =
  248. const_cast<SmartRefVector<LHCb::TbCluster>&>(best_track->clusters());
  249. auto earliest_hit = std::min_element(clusters.begin(), clusters.end(),
  250. TbFunctors::LessByTime<const LHCb::TbCluster*>());
  251.  
  252. if( timingSvc()->beforeOverlap( (*earliest_hit)->time() ) ){
  253.  
  254. track_volume->set_tracked_clusters();
  255. m_tracks->insert(best_track);
  256. // =========================== Kalman code =======================================
  257. // create a fit track object (which is actually also a TbTrack)
  258. LHCb::TbKalmanTrack* ktrack = new LHCb::TbKalmanTrack(*best_track, m_hiterror2, m_scat2) ;
  259. // fit it
  260. ktrack->fit() ;
  261. // store the ktrack in the track vector
  262. ktracks_vec.push_back(ktrack);
  263. // ===============================================================================
  264. best_track->setTime(timingSvc()->localToGlobal(best_track->htime()));
  265. if (m_monitoring) {
  266. plot(track_volume->nCombos(), "nComboDist_of_TrackVolumes",
  267. "nComboDist_of_TrackVolumes", 0., 1100., 1100);
  268. plot(track_volume->nclusters(), "nCluster_in_TrackVolumes",
  269. "nCluster_in_TrackVolumes", 0., 100., 100);
  270. }
  271. }
  272. else{
  273. // info() << "Earliest track time is within overlap, deleting" << endmsg;
  274. // info() << *best_track << endmsg;
  275. delete best_track;
  276. }
  277. }
  278. else delete best_track;
  279. }
  280. }
  281.  
  282. //=============================================================================
  283. /// Poor mans tracker (useful for testing). - only finds complete tracks.
  284. //=============================================================================
  285. void TbTracking::poorMansEvaluation(TbTrackVolume* track_volume) {
  286. // Only accept tracks with at least one cluster on each plane.
  287. bool one_per_plane = true; // Assumed, now checked.
  288. for (unsigned int i = 0; i < m_nPlanes; i++) {
  289. if (track_volume->m_clusters[i].size() == 0) {
  290. one_per_plane = false;
  291. break;
  292. }
  293. }
  294.  
  295. if (one_per_plane) {
  296. double t = 0.0;
  297. // We have a track!
  298. LHCb::TbTrack* track = new LHCb::TbTrack();
  299. for (unsigned int i = 0; i < m_nPlanes; ++i) {
  300. LHCb::TbCluster* c = track_volume->nearest_cluster(i);
  301. t += c->htime();
  302. c->setAssociated(true);
  303. track->addToClusters(c);
  304. }
  305. t /= (double)m_nPlanes;
  306. m_trackFit->fit(track);
  307. m_tracks->insert(track);
  308. track->setTime(timingSvc()->localToGlobal(t));
  309. }
  310. }
  311.  
  312. //=============================================================================
  313. // Track time ordering - honeycomb
  314. //=============================================================================
  315. void TbTracking::timeOrderTracks() {
  316.  
  317. const double s_factor = 1.3;
  318. LHCb::TbTrack* track1;
  319. LHCb::TbTrack* track2;
  320. unsigned int gap = m_tracks->size() / s_factor;
  321. bool swapped = false;
  322.  
  323. // Start the swap loops.
  324. while (gap > 1 || swapped) {
  325. if (gap > 1) gap /= s_factor;
  326. swapped = false; // Reset per swap loop.
  327.  
  328. // Do the swaps.
  329. LHCb::TbTracks::iterator itt;
  330. for (itt = m_tracks->begin(); itt < m_tracks->end() - gap; ++itt) {
  331. track1 = *itt;
  332. track2 = *(itt + gap);
  333. if (track1->time() > track2->time()) {
  334. // Do the swap.
  335. std::iter_swap(itt, itt + gap);
  336. swapped = true;
  337. }
  338. }
  339. }
  340. }
  341.  
  342. //=============================================================================
  343. /// Fill Histograms for TbKalmanTracks
  344. //=============================================================================
  345. void TbTracking::fill_khists(std::vector<LHCb::TbKalmanTrack*>& ktracks) {
  346. std::vector<LHCb::TbKalmanTrack*>::iterator icktra;
  347. for (icktra = ktracks.begin(); icktra != ktracks.end(); icktra++) {
  348. // Fill the track histos
  349. m_Kfit_chi2->Fill((*icktra)->chi2());
  350. m_Kfit_prob->Fill( TMath::Prob((*icktra)->chi2(), (*icktra)->ndof()) );
  351. // Get the nodes of this TbKalmanTrack
  352. //const std::vector<LHCb::TbKalmanNode*>& knodes = (*icktra)->nodes();
  353. // Loop through the nodes of this TbKalmanTrack
  354. for( auto node : (*icktra)->nodes() ) {
  355. auto pixnode = dynamic_cast< LHCb::TbKalmanPixelMeasurement*>( node) ;
  356. if( pixnode ) {
  357. int ichip = pixnode->cluster().plane();
  358. // Fill unbiased residuals
  359. m_XunresKfit[ichip]->Fill( pixnode->residualX() * pixnode->covX() / pixnode->residualCovX() );
  360. m_YunresKfit[ichip]->Fill( pixnode->residualY() * pixnode->covY() / pixnode->residualCovY() );
  361. // Fill biased residuals
  362. m_XresKfit[ichip]->Fill( pixnode->residualX() );
  363. m_YresKfit[ichip]->Fill( pixnode->residualY() );
  364. // Fill biased residuals on X,Y
  365. m_XresKfitOnX[ichip]->Fill( pixnode->cluster().x() , pixnode->residualX() );
  366. m_XresKfitOnY[ichip]->Fill( pixnode->cluster().y(), pixnode->residualX() );
  367. m_YresKfitOnY[ichip]->Fill( pixnode->cluster().y() , pixnode->residualY() );
  368. m_YresKfitOnX[ichip]->Fill( pixnode->cluster().x(), pixnode->residualY() );
  369. // Fill biased residuals on X,Y slopes
  370. m_XresKfitOnTX[ichip]->Fill( pixnode->state().tx() , pixnode->residualX() );
  371. m_XresKfitOnTY[ichip]->Fill( pixnode->state().ty() , pixnode->residualX() );
  372. m_YresKfitOnTY[ichip]->Fill( pixnode->state().ty() , pixnode->residualY() );
  373. m_YresKfitOnTX[ichip]->Fill( pixnode->state().tx() , pixnode->residualY() );
  374. // Fill residual errors
  375. m_XreserrKfit[ichip]->Fill( std::sqrt(pixnode->residualCovX()) );
  376. m_YreserrKfit[ichip]->Fill( std::sqrt(pixnode->residualCovY()) );
  377. // Fill residual pulls
  378. m_XrespullKfit[ichip]->Fill( pixnode->residualX() / std::sqrt(pixnode->residualCovX() ) );
  379. m_YrespullKfit[ichip]->Fill( pixnode->residualY() / std::sqrt(pixnode->residualCovY() ) );
  380. // Fill chi2 quality histos :
  381. // take the chi2 of the track..
  382. LHCb::ChiSquare chi2 ( (*icktra)->chi2(), (*icktra)->ndof() ) ;
  383. // we should add a proper function to KalmanTrack, or store it
  384. // ..now calculate and subtract the chi2 of this hit: should become a function of node as well
  385. double resX = pixnode->residualX() ;
  386. double resY = pixnode->residualY() ;
  387. int nd = 2 * ( (*icktra)->nodes().size() -1 ) - 4;
  388. LHCb::ChiSquare chi2hit ( resX*resX / pixnode->residualCovX() + resY*resY / pixnode->residualCovY() , nd );
  389. chi2 -= chi2hit;
  390. // apply quality check
  391. if (chi2.chi2()/chi2.nDoF()<4) {
  392. // Fill quality biased residuals for this hit
  393. m_qXresKfit[ichip]->Fill( pixnode->residualX() );
  394. m_qYresKfit[ichip]->Fill( pixnode->residualY() );
  395. // Fill quality residual pulls for this hit
  396. m_qXrespullKfit[ichip]->Fill( pixnode->residualX() / std::sqrt(pixnode->residualCovX() ) );
  397. m_qYrespullKfit[ichip]->Fill( pixnode->residualY() / std::sqrt(pixnode->residualCovY() ) );
  398. }
  399. } // end of node check
  400. } // end of node loop
  401. } // end of Ktrack loop
  402. }
  403.  
  404.  
  405. //=============================================================================
  406. /// Setup Histograms
  407. //=============================================================================
  408. void TbTracking::setup_hists() {
  409. // TbKalmanTrack parameters plots
  410. m_Kfit_chi2 = Gaudi::Utils::Aida2ROOT::aida2root(
  411. book1D("KalmanFit/chi2", "Chi2", -0.5, 49.5, 100));
  412. m_Kfit_prob = Gaudi::Utils::Aida2ROOT::aida2root(
  413. book1D("KalmanFit/probability", "Chi2 prob of K fit", 0.0, 1.0, 100));
  414. // Kalman fit plots
  415. std::string hist_name;
  416. for (unsigned int i = 0; i < m_nPlanes; i++) {
  417. std::stringstream ss_chip;
  418. ss_chip << i;
  419. hist_name = "KalmanFit/UnbiasedResidualsX/plane_" + ss_chip.str();
  420. m_XunresKfit.push_back(Gaudi::Utils::Aida2ROOT::aida2root(
  421. book1D(hist_name.c_str(), hist_name.c_str(), lowR, highR, binsR)));
  422. hist_name = "KalmanFit/UnbiasedResidualsY/plane_" + ss_chip.str();
  423. m_YunresKfit.push_back(Gaudi::Utils::Aida2ROOT::aida2root(
  424. book1D(hist_name.c_str(), hist_name.c_str(), lowR, highR, binsR)));
  425. //
  426. hist_name = "KalmanFit/BiasedResidualsX/plane_" + ss_chip.str();
  427. m_XresKfit.push_back(Gaudi::Utils::Aida2ROOT::aida2root(
  428. book1D(hist_name.c_str(), hist_name.c_str(), lowR, highR, binsR)));
  429. hist_name = "KalmanFit/BiasedResidualsY/plane_" + ss_chip.str();
  430. m_YresKfit.push_back(Gaudi::Utils::Aida2ROOT::aida2root(
  431. book1D(hist_name.c_str(), hist_name.c_str(), lowR, highR, binsR)));
  432. //
  433. hist_name = "KalmanFit/ResidualsX_on_X/plane_" + ss_chip.str();
  434. m_XresKfitOnX.push_back(Gaudi::Utils::Aida2ROOT::aida2root(
  435. book2D(hist_name.c_str(), hist_name.c_str(), -20., 20., 200, lowR, highR, binsR)));
  436. hist_name = "KalmanFit/ResidualsX_on_Y/plane_" + ss_chip.str();
  437. m_XresKfitOnY.push_back(Gaudi::Utils::Aida2ROOT::aida2root(
  438. book2D(hist_name.c_str(), hist_name.c_str(), -20., 20., 200, lowR, highR, binsR)));
  439. hist_name = "KalmanFit/ResidualsY_on_Y/plane_" + ss_chip.str();
  440. m_YresKfitOnY.push_back(Gaudi::Utils::Aida2ROOT::aida2root(
  441. book2D(hist_name.c_str(), hist_name.c_str(), -20., 20., 200, lowR, highR, binsR)));
  442. hist_name = "KalmanFit/ResidualsY_on_X/plane_" + ss_chip.str();
  443. m_YresKfitOnX.push_back(Gaudi::Utils::Aida2ROOT::aida2root(
  444. book2D(hist_name.c_str(), hist_name.c_str(), -20., 20., 200, lowR, highR, binsR)));
  445. //
  446. hist_name = "KalmanFit/ResidualsX_on_slopeX/plane_" + ss_chip.str();
  447. m_XresKfitOnTX.push_back(Gaudi::Utils::Aida2ROOT::aida2root(
  448. book2D(hist_name.c_str(), hist_name.c_str(), lowS, highS, binsR, lowR, highR, binsR)));
  449. hist_name = "KalmanFit/ResidualsX_on_slopeY/plane_" + ss_chip.str();
  450. m_XresKfitOnTY.push_back(Gaudi::Utils::Aida2ROOT::aida2root(
  451. book2D(hist_name.c_str(), hist_name.c_str(), lowS, highS, binsR, lowR, highR, binsR)));
  452. hist_name = "KalmanFit/ResidualsY_on_slopeY/plane_" + ss_chip.str();
  453. m_YresKfitOnTY.push_back(Gaudi::Utils::Aida2ROOT::aida2root(
  454. book2D(hist_name.c_str(), hist_name.c_str(), lowS, highS, binsR, lowR, highR, binsR)));
  455. hist_name = "KalmanFit/ResidualsY_on_slopeX/plane_" + ss_chip.str();
  456. m_YresKfitOnTX.push_back(Gaudi::Utils::Aida2ROOT::aida2root(
  457. book2D(hist_name.c_str(), hist_name.c_str(), lowS, highS, binsR, lowR, highR, binsR)));
  458. //
  459. hist_name = "KalmanFit/Residual_errors_on_X/plane_" + ss_chip.str();
  460. m_XreserrKfit.push_back(Gaudi::Utils::Aida2ROOT::aida2root(
  461. book1D(hist_name.c_str(), hist_name.c_str(), 0., 5.e-3, 1000)));
  462. hist_name = "KalmanFit/Residual_errors_on_Y/plane_" + ss_chip.str();
  463. m_YreserrKfit.push_back(Gaudi::Utils::Aida2ROOT::aida2root(
  464. book1D(hist_name.c_str(), hist_name.c_str(), 0., 5.e-3, 1000)));
  465. hist_name = "KalmanFit/ResidualPull_on_X/plane_" + ss_chip.str();
  466. m_XrespullKfit.push_back(Gaudi::Utils::Aida2ROOT::aida2root(
  467. book1D(hist_name.c_str(), hist_name.c_str(), -10., 10., 100)));
  468. hist_name = "KalmanFit/ResidualPull_on_Y/plane_" + ss_chip.str();
  469. m_YrespullKfit.push_back(Gaudi::Utils::Aida2ROOT::aida2root(
  470. book1D(hist_name.c_str(), hist_name.c_str(), -10., 10., 100)));
  471. //
  472. hist_name = "KalmanFit/BiasedResidualsX_after_chi2_cut/plane_" + ss_chip.str();
  473. m_qXresKfit.push_back(Gaudi::Utils::Aida2ROOT::aida2root(
  474. book1D(hist_name.c_str(), hist_name.c_str(), lowR, highR, binsR)));
  475. hist_name = "KalmanFit/BiasedResidualsY_after_chi2_cut/plane_" + ss_chip.str();
  476. m_qYresKfit.push_back(Gaudi::Utils::Aida2ROOT::aida2root(
  477. book1D(hist_name.c_str(), hist_name.c_str(), lowR, highR, binsR)));
  478. //
  479. hist_name = "KalmanFit/ResidualPull_on_X_after_chi2_cut/plane_" + ss_chip.str();
  480. m_qXrespullKfit.push_back(Gaudi::Utils::Aida2ROOT::aida2root(
  481. book1D(hist_name.c_str(), hist_name.c_str(), -10., 10., 100)));
  482. hist_name = "KalmanFit/ResidualPull_on_Y_after_chi2_cut/plane_" + ss_chip.str();
  483. m_qYrespullKfit.push_back(Gaudi::Utils::Aida2ROOT::aida2root(
  484. book1D(hist_name.c_str(), hist_name.c_str(), -10., 10., 100)));
  485. }
  486. }
  487.