Belle II Software  release-08-01-10
AlignableCDCRecoHit.cc
1 /**************************************************************************
2  * basf2 (Belle II Analysis Software Framework) *
3  * Author: The Belle II Collaboration *
4  * *
5  * See git log for contributors and copyright holders. *
6  * This file is licensed under LGPL-3.0, see LICENSE.md. *
7  **************************************************************************/
8 
9 #include <alignment/reconstruction/AlignableCDCRecoHit.h>
10 
11 #include <alignment/GlobalLabel.h>
12 #include <alignment/GlobalDerivatives.h>
13 #include <cdc/dataobjects/WireID.h>
14 #include <cdc/dbobjects/CDCTimeZeros.h>
15 #include <cdc/dbobjects/CDCTimeWalks.h>
16 #include <cdc/geometry/CDCGeometryPar.h>
17 #include "Math/ChebyshevPol.h"
18 
19 using namespace std;
20 using namespace Belle2;
21 using namespace CDC;
22 using namespace alignment;
23 
24 bool AlignableCDCRecoHit::s_enableTrackT0LocalDerivative = true;
25 bool AlignableCDCRecoHit::s_enableWireSaggingGlobalDerivative = false;
26 bool AlignableCDCRecoHit::s_enableWireByWireAlignmentGlobalDerivatives = false;
27 
28 std::pair<std::vector<int>, TMatrixD> AlignableCDCRecoHit::globalDerivatives(const genfit::StateOnPlane* sop)
29 {
30  GlobalDerivatives globals;
31  unsigned short LR = (int(m_leftRight) > 0.) ? 1 : 0;
32 
33  const B2Vector3D& mom = sop->getMom();
34  const B2Vector3D& wirePositon = sop->getPlane()->getO();
35  const unsigned short layer = getWireID().getICLayer();
36 
37  CDCGeometryPar& cdcgeo = CDCGeometryPar::Instance();
38  double alpha = cdcgeo.getAlpha(wirePositon, mom);
39  double theta = cdcgeo.getTheta(mom);
40  const TVectorD& stateOnPlane = sop->getState();
41  const double driftLengthEstimate = std::abs(stateOnPlane(3));
42  const double driftTime = cdcgeo.getDriftTime(driftLengthEstimate, layer, LR, alpha, theta);
43  const double driftVelocity = cdcgeo.getDriftV(driftTime, layer, LR, alpha, theta);
44 
45  // CDC Calibration -------------------------------------------------
46 
47  // Time zero calibration (per wire)
48  if (driftTime > 20 && driftTime < 200 && fabs(driftVelocity) < 1.0e-2) {
49  globals.add(
50  GlobalLabel::construct<CDCTimeZeros>(getWireID(), 0),
51  driftVelocity * double(int(m_leftRight))
52  );
53  }
54 
55  // Time walk calibration (per board)
56  if (driftTime > 20 && driftTime < 200 && fabs(driftVelocity) < 1.0e-2 && m_adcCount < 400 && m_adcCount > 2) {
58  unsigned short board = CDCGeometryPar::Instance().getBoardID(getWireID());
59  const std::vector<float> param = tws->getTimeWalkParams(board);
60  globals.add(
61  GlobalLabel::construct<CDCTimeWalks>(board, 0),
62  -driftVelocity * exp(-param[1]* m_adcCount) * double(int(m_leftRight))
63  );
64  globals.add(
65  GlobalLabel::construct<CDCTimeWalks>(board, 1),
66  driftVelocity * m_adcCount * param[0]*exp(-param[1]* m_adcCount) * double(int(m_leftRight))
67  );
68  }
69 
70  // Space time relations calibration
71  if (driftTime > 20 && driftTime < 500 && fabs(driftVelocity) < 1.0e-2) {
72  // TODO: ugly to need to ask XTRelations for something here...
73  // Can't I get this CDCGeometryPar or sth. like this?
74 
75  theta = cdcgeo.getOutgoingTheta(alpha, theta);
76  alpha = cdcgeo.getOutgoingAlpha(alpha);
78  auto xtid = xts->getXtID(getWireID().getICLayer(), LR, (float)alpha, (float)theta);
79  const auto& par = xts->getXtParams(xtid);
80  auto boundary = par.at(6);
81  if (driftTime < boundary) {
82  globals.add(
83  GlobalLabel::construct<CDCXtRelations>(xtid, 0),
84  ROOT::Math::Chebyshev5(driftTime, 1, 0, 0, 0, 0, 0) * double(int(m_leftRight))
85  );
86  globals.add(
87  GlobalLabel::construct<CDCXtRelations>(xtid, 1),
88  ROOT::Math::Chebyshev5(driftTime, 0, 1, 0, 0, 0, 0) * double(int(m_leftRight))
89  );
90  globals.add(
91  GlobalLabel::construct<CDCXtRelations>(xtid, 2),
92  ROOT::Math::Chebyshev5(driftTime, 0, 0, 1, 0, 0, 0) * double(int(m_leftRight))
93  );
94  globals.add(
95  GlobalLabel::construct<CDCXtRelations>(xtid, 3),
96  ROOT::Math::Chebyshev5(driftTime, 0, 0, 0, 1, 0, 0) * double(int(m_leftRight))
97  );
98  globals.add(
99  GlobalLabel::construct<CDCXtRelations>(xtid, 4),
100  ROOT::Math::Chebyshev5(driftTime, 0, 0, 0, 0, 1, 0) * double(int(m_leftRight))
101  );
102  globals.add(
103  GlobalLabel::construct<CDCXtRelations>(xtid, 5),
104  ROOT::Math::Chebyshev5(driftTime, 0, 0, 0, 0, 0, 1) * double(int(m_leftRight))
105  );
106  } else {
107  globals.add(
108  GlobalLabel::construct<CDCXtRelations>(xtid, 7),
109  double(int(m_leftRight))
110  );
111  globals.add(
112  GlobalLabel::construct<CDCXtRelations>(xtid, 8),
113  (driftTime - boundary) * double(int(m_leftRight))
114  );
115  }
116  }
117 
118 
119  // CDC Alignment ---------------------------------------------------
120 
121  auto tdir = sop->getDir();
122  auto ndir = sop->getPlane()->getNormal();
123  auto udir = sop->getPlane()->getU();
124  auto vdir = sop->getPlane()->getV();
125  auto pos = sop->getPos();
126 
127  auto tn = tdir[0] * ndir[0] + tdir[1] * ndir[1] + tdir[2] * ndir [2];
128  // d residual / d measurement
129  auto drdm = TMatrixD(3, 3);
130  drdm.UnitMatrix();
131  for (int i = 0; i < 3; ++i) {
132  for (int j = 0; j < 3; ++j) {
133  drdm(i, j) -= tdir[i] * ndir[j] / tn;
134  }
135  }
136  // d measurement / d global rigid body param
137  auto dmdg = TMatrixD(3, 6);
138  dmdg.Zero();
139  dmdg[0][0] = 1.; dmdg[0][4] = -pos[2]; dmdg[0][5] = pos[1];
140  dmdg[1][1] = 1.; dmdg[1][3] = pos[2]; dmdg[1][5] = -pos[0];
141  dmdg[2][2] = 1.; dmdg[2][3] = -pos[1]; dmdg[2][4] = pos[0];
142  // d local residual / d global residual
143  auto drldrg = TMatrixD(3, 3);
144  for (int i = 0; i < 3; ++i) {
145  drldrg(0, i) = udir[i];
146  drldrg(1, i) = vdir[i];
147  drldrg(2, i) = ndir[i];
148  }
149  // d local residual / d global rigid body param
150  auto drldg = drldrg * (drdm * dmdg);
151 
152  // wire ends
153  const double zWireM = s_cdcGeometryTranslator->getWireBackwardPosition(getWireID(), CDCGeometryPar::c_Aligned)[2];
154  const double zWireP = s_cdcGeometryTranslator->getWireForwardPosition(getWireID(), CDCGeometryPar::c_Aligned)[2];
155  // relative Z position [0..1]
156  const double zRel = std::max(0., std::min(1., (pos[2] - zWireM) / (zWireP - zWireM)));
157 
158  // Layer alignment
159  // wire 511 = no wire (0 is reserved for existing wires) - this has to be compatible with code in CDCGeometryPar::setWirPosAlignParams
160  auto layerID = WireID(getWireID().getICLayer(), 511);
161 
162  // Alignment of layer X (bwd)
163  globals.add(
164  GlobalLabel::construct<CDCAlignment>(layerID, CDCAlignment::layerX),
165  drldg(0, 0)
166  );
167 
168  // Alignment of layer Y (bwd)
169  globals.add(
170  GlobalLabel::construct<CDCAlignment>(layerID, CDCAlignment::layerY),
171  drldg(0, 1)
172  );
173 
174  // Alignment of layer rotation (gamma) (bwd)
175  globals.add(
176  GlobalLabel::construct<CDCAlignment>(layerID, CDCAlignment::layerPhi),
177  drldg(0, 5)
178  );
179 
180  // Difference between wire ends (end plates)
181  // Alignment of layer dX, dX = foward - backward endplate
182  globals.add(
183  GlobalLabel::construct<CDCAlignment>(layerID, CDCAlignment::layerDx),
184  drldg(0, 0) * zRel
185  );
186 
187  // Alignment of layer dY, dY = foward - backward endplate
188  globals.add(
189  GlobalLabel::construct<CDCAlignment>(layerID, CDCAlignment::layerDy),
190  drldg(0, 1) * zRel
191  );
192 
193  // Alignment of layer rotation difference d(gamma or phi), dPhi = foward - backward endplate
194  globals.add(
195  GlobalLabel::construct<CDCAlignment>(layerID, CDCAlignment::layerDPhi),
196  drldg(0, 5) * zRel
197  );
198 
199  //WARNING: experimental (disabled by default)
200  // Wire-by-wire alignment
201  if (s_enableWireByWireAlignmentGlobalDerivatives) {
202  // How much shift (in X or Y) on BWD wire-end will change the residual at estimated track crossing
203  // with the wire (at relative z-position on wire = zRel)
204  double zRelM = fabs(1. - zRel);
205  // Same as above but for FWD wire-end (residual at zRel = zRel * delta(X or Y at FWD wire-end)
206  double zRelP = fabs(zRel - 0.);
207 
208  // Alignment of wires X in global coords at BWD wire-end
209  globals.add(
210  GlobalLabel::construct<CDCAlignment>(getWireID().getEWire(), CDCAlignment::wireBwdX),
211  drldg(0, 0) * zRelM
212  );
213  // Alignment of wires X in global coords at FWD wire-end
214  globals.add(
215  GlobalLabel::construct<CDCAlignment>(getWireID().getEWire(), CDCAlignment::wireFwdX),
216  drldg(0, 0) * zRelP
217  );
218 
219  // Alignment of wires Y in global coords at BWD wire-end
220  globals.add(
221  GlobalLabel::construct<CDCAlignment>(getWireID().getEWire(), CDCAlignment::wireBwdY),
222  drldg(0, 1) * zRelM
223  );
224  // Alignment of wires Y in global coords at FWD wire-end
225  globals.add(
226  GlobalLabel::construct<CDCAlignment>(getWireID().getEWire(), CDCAlignment::wireFwdY),
227  drldg(0, 1) * zRelP
228  );
229  }
230 
231  //WARNING: experimental (disabled by default)
232  //TODO: missing some factors (we do not align directly the wire-sag coefficient, but
233  // wire tension ... coef = pi * ro * r * r / 8 / tension
234  //TODO: need to get these numbers from CDCGeometryPar!
235  if (s_enableWireSaggingGlobalDerivative) {
236  globals.add(
237  GlobalLabel::construct<CDCAlignment>(getWireID().getEWire(), CDCAlignment::wireTension),
238  drldg(0, 1) * 4.0 * zRel * (1.0 - zRel)
239  );
240  }
241 
242 
243 
244  return globals;
245 }
246 
247 
248 TMatrixD AlignableCDCRecoHit::localDerivatives(const genfit::StateOnPlane* sop)
249 {
250  if (!s_enableTrackT0LocalDerivative)
251  return TMatrixD();
252 
253  unsigned short LR = (int(m_leftRight) > 0.) ? 1 : 0;
254 
255  const B2Vector3D& mom = sop->getMom();
256  const B2Vector3D& wirePositon = sop->getPlane()->getO();
257  const unsigned short layer = getWireID().getICLayer();
258 
259  CDCGeometryPar& cdcgeo = CDCGeometryPar::Instance();
260  const double alpha = cdcgeo.getAlpha(wirePositon, mom);
261  const double theta = cdcgeo.getTheta(mom);
262  const TVectorD& stateOnPlane = sop->getState();
263  const double driftLengthEstimate = std::abs(stateOnPlane(3));
264  const double driftTime = cdcgeo.getDriftTime(driftLengthEstimate, layer, LR, alpha, theta);
265  const double driftVelocity = cdcgeo.getDriftV(driftTime, layer, LR, alpha, theta);
266 
267  TMatrixD locals(2, 1);
268  if (driftTime > 20 && driftTime < 200 && fabs(driftVelocity) < 1.0e-2) {
269  locals(0, 0) = - double(int(m_leftRight)) * driftVelocity;
270  locals(1, 0) = 0.; // insesitive coordinate along wire
271  }
272 
273  return locals;
274 }
The Class for CDC Geometry Parameters.
double getTheta(const B2Vector3D &momentum) const
Returns track incident angle (theta in rad.).
double getAlpha(const B2Vector3D &posOnWire, const B2Vector3D &momentum) const
Returns track incident angle in rphi plane (alpha in rad.).
double getDriftV(double dt, unsigned short layer, unsigned short lr, double alpha=0., double theta=0.5 *M_PI) const
Get the realistic drift velocity.
double getOutgoingAlpha(const double alpha) const
Converts incoming- to outgoing-alpha.
double getOutgoingTheta(const double alpha, const double theta) const
Converts incoming- to outgoing-theta.
double getDriftTime(double dist, unsigned short layer, unsigned short lr, double alpha, double theta) const
Return the drift time to the sense wire.
Class for accessing objects in the database.
Definition: DBObjPtr.h:21
Class to identify a wire inside the CDC.
Definition: WireID.h:34
A state with arbitrary dimension defined in a DetPlane.
Definition: StateOnPlane.h:47
Abstract base class for different kinds of events.