Newer
Older
TB_Chris / TbAlignment / src / .svn / text-base / TbAlignmentMinuit2.cpp.svn-base
  1. #include <algorithm>
  2.  
  3. // Gaudi
  4. #include "GaudiKernel/PhysicalConstants.h"
  5.  
  6. // Tb/TbKernel
  7. #include "TbKernel/TbFunctors.h"
  8.  
  9. // Local
  10. #include "TbAlignmentMinuit2.h"
  11.  
  12. DECLARE_TOOL_FACTORY(TbAlignmentMinuit2)
  13.  
  14. //=============================================================================
  15. // Standard constructor, initializes variables
  16. //=============================================================================
  17. TbAlignmentMinuit2::TbAlignmentMinuit2(const std::string& type,
  18. const std::string& name,
  19. const IInterface* parent)
  20. : TbAlignmentMinuitBase(type, name, parent) {
  21.  
  22. declareProperty("ClusterLocation",
  23. m_clusterLocation = LHCb::TbClusterLocation::Default);
  24. declareProperty("DeviceToAlign", m_deviceToAlign = 999);
  25. declareProperty("IsDUT", m_isDUT = true);
  26. declareProperty("RefitTracks", m_refitTracks = false);
  27. declareProperty("TimeWindow", m_twindow = 200. * Gaudi::Units::ns);
  28. declareProperty("XWindow", m_xwindow = 1. * Gaudi::Units::mm);
  29. declareProperty("IgnoreEdge",m_ignoreEdge=1);
  30. m_dofsDefault = {true, true, true, true, true, true};
  31. }
  32.  
  33. //=============================================================================
  34. // Destructor
  35. //=============================================================================
  36. TbAlignmentMinuit2::~TbAlignmentMinuit2() {}
  37.  
  38. //=============================================================================
  39. // Collect the tracks and clusters to be used for the alignment.
  40. //=============================================================================
  41. StatusCode TbAlignmentMinuit2::execute(
  42. std::vector<TbAlignmentTrack*>& alignmentTracks) {
  43.  
  44. // Grab the tracks.
  45. LHCb::TbTracks* tracks = getIfExists<LHCb::TbTracks>(m_trackLocation);
  46. if (!tracks) {
  47. return Error("No tracks in " + m_trackLocation);
  48. }
  49. if (!m_isDUT) {
  50. // We want to align a plane which is included in the pattern recognition.
  51. for (LHCb::TbTrack* track : *tracks) {
  52. // Skip low-quality tracks.
  53. if (track->chi2() > m_maxChi2) continue;
  54. // Add a new alignment track (cloning track and clusters) to the store.
  55. alignmentTracks.emplace_back(new TbAlignmentTrack(track));
  56. }
  57. return StatusCode::SUCCESS;
  58. }
  59. // We want to align a plane which is not included in the pattern recognition.
  60. if (m_twindow < 0. && m_xwindow < 0.) {
  61. // Use the clusters which have been associated to the track.
  62. for (LHCb::TbTrack* track : *tracks) {
  63. // Skip low-quality tracks.
  64. if (track->chi2() > m_maxChi2) continue;
  65. auto clusters = track->associatedClusters();
  66. for (auto it = clusters.begin(), end = clusters.end(); it != end; ++it) {
  67. if ((*it)->plane() != m_deviceToAlign) continue;
  68. // Create a new alignment track (cloning the track).
  69. TbAlignmentTrack* alignmentTrack = new TbAlignmentTrack(track);
  70. // Clone the cluster and add it to the alignment track.
  71. LHCb::TbCluster* alignmentCluster = (*it)->clone();
  72. alignmentTrack->track()->addToAssociatedClusters(alignmentCluster);
  73. alignmentTrack->addToClusters(alignmentCluster);
  74. // Add the alignment track to the store.
  75. alignmentTracks.push_back(alignmentTrack);
  76. // Stop after the first valid cluster.
  77. break;
  78. }
  79. }
  80. return StatusCode::SUCCESS;
  81. }
  82. // We need to associate DUT clusters to the track.
  83. // Grab the clusters on the device to align.
  84. const std::string clusterLocation = m_clusterLocation + std::to_string(m_deviceToAlign);
  85. LHCb::TbClusters* clusters = getIfExists<LHCb::TbClusters>(clusterLocation);
  86. if (!clusters) {
  87. return Error("No clusters in " + clusterLocation);
  88. }
  89. unsigned int edgeRejected(0), spaceRejected(0);
  90.  
  91. for (LHCb::TbTrack* track : *tracks) {
  92. // Skip low-quality tracks.
  93. if (track->chi2PerNdof() > m_maxChi2) continue;
  94. // Calculate the track intercept on the device to align.
  95. const auto pGlobal = geomSvc()->intercept(track, m_deviceToAlign);
  96. const auto pLocal = geomSvc()->globalToLocal(pGlobal, m_deviceToAlign);
  97. // Calculate the time window.
  98. const double tMin = track->htime() - m_twindow;
  99. const double tMax = track->htime() + m_twindow;
  100. // Get the first cluster within the time window.
  101. LHCb::TbClusters::iterator end = clusters->end();
  102. LHCb::TbClusters::iterator begin = std::lower_bound(
  103. clusters->begin(), end, tMin, lowerBound<const LHCb::TbCluster*>());
  104. if (begin == clusters->end()) continue;
  105. // Loop over the clusters.
  106. for (LHCb::TbClusters::iterator it = begin; it != end; ++it) {
  107. // Stop when outside the time window.
  108. if ((*it)->htime() > tMax) break;
  109. // Skip clusters too far away from the track intercept.
  110. const double dx = (*it)->xloc() - pLocal.x();
  111. const double dy = (*it)->yloc() - pLocal.y();
  112. if (fabs(dx) > m_xwindow || fabs(dy) > m_xwindow){ spaceRejected++; continue; }
  113. // Skip clusters close to the edge of the sensor.
  114. if (isEdge(*it) && m_ignoreEdge ){edgeRejected++; continue;}
  115. // Create a new alignment track (cloning the track).
  116. TbAlignmentTrack* alignmentTrack = new TbAlignmentTrack(track);
  117. // Clone the cluster and add it to the alignment track.
  118. LHCb::TbCluster* alignmentCluster = (*it)->clone();
  119. alignmentTrack->track()->addToAssociatedClusters(alignmentCluster);
  120. alignmentTrack->addToClusters(alignmentCluster);
  121. // Add the alignment track to the store.
  122. alignmentTracks.push_back(alignmentTrack);
  123. // Stop after the first valid cluster.
  124. break;
  125. }
  126. }
  127. //info() << edgeRejected << " " << spaceRejected << " " << tracks->size() << endmsg;
  128.  
  129. return StatusCode::SUCCESS;
  130. }
  131.  
  132. //=============================================================================
  133. // Calculate the chi2.
  134. //=============================================================================
  135. void TbAlignmentMinuit2::chi2(double& f, double* par, double* /*g*/) {
  136.  
  137. const unsigned int offset = m_deviceToAlign * 6;
  138. // Check the z-position.
  139. const double z = m_modules[m_deviceToAlign]->z() + par[offset + 2];
  140. if (m_deviceToAlign > 0) {
  141. if (z <= m_modules[m_deviceToAlign - 1]->z()) {
  142. info() << "Z is below limit!" << endmsg;
  143. f = std::numeric_limits<double>::max();
  144. return;
  145. }
  146. }
  147. if (m_deviceToAlign < m_nPlanes - 1) {
  148. if (z >= m_modules[m_deviceToAlign + 1]->z()) {
  149. info() << "Z is above limit!" << endmsg;
  150. f = std::numeric_limits<double>::max();
  151. return;
  152. }
  153. }
  154.  
  155. m_modules[m_deviceToAlign]->setAlignment(par[offset + 0], par[offset + 1],
  156. par[offset + 2], par[offset + 3],
  157. par[offset + 4], par[offset + 5]);
  158. // Loop over the alignment tracks.
  159. f = 0.;
  160. for (auto it = m_tracks.begin(), end = m_tracks.end(); it != end; ++it) {
  161. // Form residuals with all clusters selected for alignment
  162. auto clusters = (*it)->clusters();
  163. for (auto ic = clusters.cbegin(), end = clusters.cend(); ic != end; ++ic) {
  164. if ((*ic)->plane() != m_deviceToAlign) continue;
  165. Gaudi::XYZPoint point = geomSvc()->localToGlobal(
  166. Gaudi::XYZPoint((*ic)->xloc(), (*ic)->yloc(), 0), m_deviceToAlign);
  167. Gaudi::XYZPoint intercept =
  168. geomSvc()->intercept((*it)->track(), m_deviceToAlign);
  169. // TODO: why not the local residual?
  170. const double xresidual = point.x() - intercept.x();
  171. // const double xresidual = (*ic)->xloc() - intercept.x();
  172. const double yresidual = point.y() - intercept.y();
  173. // const double yresidual = (*ic)->yloc() - intercept.y();
  174. f += xresidual * xresidual + yresidual * yresidual;
  175. }
  176. }
  177. }
  178.  
  179. //=============================================================================
  180. // Main alignment function.
  181. //=============================================================================
  182. void TbAlignmentMinuit2::align(
  183. std::vector<TbAlignmentTrack*>& alignmentTracks) {
  184.  
  185. TbAlignmentMinuitBase::align(alignmentTracks);
  186. info() << "Minuit technique 2. Aligning plane " << m_deviceToAlign << endmsg;
  187. for (unsigned int i = 0; i < m_nPlanes; ++i) {
  188. if (masked(i) || i == m_deviceToAlign)
  189. m_trackFit->maskPlane(i);
  190. else
  191. m_trackFit->unmaskPlane(i);
  192. }
  193.  
  194. for (auto alignmentTrack : m_tracks) m_trackFit->fit(alignmentTrack->track());
  195.  
  196. for (unsigned int iteration = 0; iteration < m_nIterations; ++iteration) {
  197. info() << "Iteration " << iteration + 1 << "/" << m_nIterations << endmsg;
  198. // Loop over detector modules
  199. for (unsigned int i = 0; i < m_nPlanes; ++i) {
  200. const unsigned int offset = 6 * i;
  201. if (i == m_deviceToAlign) {
  202. info() << "*** Wobbling detector " << i << endmsg;
  203. for (unsigned int j = 0; j < 6; ++j) {
  204. if (m_dofs[j]) {
  205. m_fitter->ReleaseParameter(offset + j);
  206. } else {
  207. m_fitter->FixParameter(offset + j);
  208. }
  209. }
  210. } else {
  211. m_fitter->FixParameter(offset + 0); // x
  212. m_fitter->FixParameter(offset + 1); // y
  213. m_fitter->FixParameter(offset + 2); // z
  214. m_fitter->FixParameter(offset + 3); // Rx
  215. m_fitter->FixParameter(offset + 4); // Ry
  216. m_fitter->FixParameter(offset + 5); // Rz
  217. }
  218. }
  219. // Execute minimization and calculate proper error matrix
  220. double arglist[2];
  221. arglist[0] = 10000;
  222. arglist[1] = 1.e-2;
  223. m_fitter->ExecuteCommand("MIGRAD", arglist, 2);
  224. m_fitter->ExecuteCommand("HESSE", arglist, 1);
  225. if (msgLevel(MSG::INFO)) m_fitter->ExecuteCommand("SHOW PARAMETERS", 0, 0);
  226. updateGeometry();
  227. }
  228.  
  229. if (m_refitTracks) {
  230. for (unsigned int i = 0; i < m_nPlanes; ++i) {
  231. if (masked(i))
  232. m_trackFit->maskPlane(i);
  233. else
  234. m_trackFit->unmaskPlane(i);
  235. }
  236. for (auto it : m_tracks) m_trackFit->fit(it->track());
  237. }
  238. }