EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
EicTrackingDigiHitProducer.cxx
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file EicTrackingDigiHitProducer.cxx
1 //
2 // AYK (ayk@bnl.gov), 2013/06/12
3 //
4 // Tracking digi hit producer class;
5 //
6 
7 #include <assert.h>
8 #include <cmath>
9 
10 #include "TRandom.h"
11 
12 #include <KfMatrix.h>
13 #include <SensitiveVolume.h>
14 #include <EicRunDigi.h>
15 #include <EicTrackingDigiHit.h>
17 
18 // ---------------------------------------------------------------------------------------
19 
21  SmearingModel smearingModel):
22  EicDigiHitProducer(name),
23  //mOriginalSmearingModel (smearingModel),
24  mSmearingModel(smearingModel)
25  //, mForceRealHitSmearing(false)
26 {
27  // Check whether digitization pass was started under EicRunDigi rather than
28  // FairRunAna; also check, that hit file import was set up; change effective
29  // smearing model to NoAction if needed);
30 #if _LATER_
31  mDigiRun = dynamic_cast<EicRunDigi *>(EicRunDigi::Instance());
32 
33  mHitImportMode = mDigiRun && mDigiRun->HitImportMode() ? true : false;
34  if (mHitImportMode) {
35  if (mOriginalSmearingModel != EicDigiHitProducer::NoAction)
36  printf("-W- EicTrackingDigiHitProducer::EicTrackingDigiHitProducer() "
37  "-> effective smearing mode changed to 'NoAction'!\n");
38 
39  mEffectiveSmearingModel = EicDigiHitProducer::NoAction;
40  } //if
41 #endif
42 } // EicTrackingDigiHitProducer::EicTrackingDigiHitProducer()
43 
44 // -------------------------------------------------------------------------
45 
47 {
48  if (!mDigiHitClassName.IsNull()) {
49  // May want to move this stuff to EicDigiHitProducer::Init();
51 
52  mDigiHitArray = new TClonesArray(mDigiHitClassName);
53 
54  ioman->Register(mDetName->Name() + "TrackingDigiHit", mDetName->NAME(), mDigiHitArray, mPersistence);
55  } //if
56 
57  return kSUCCESS;
58 } // EicTrackingDigiHitProducer::ExtraInit()
59 
60 // ---------------------------------------------------------------------------------------
61 
63 {
64  // Yes, prefer to take middle point; NB: as of 2014/09/20 this point will be given to
65  // FairHit instead of a result of global->local->smear->global sequence; rationale:
66  // eg 1D detectors know nothing about other two coordinates, so why one should
67  // confuse say a track finder by artificially composed quantities;
68  TVector3 middle( 0.5 * (point->GetPosIn() + point->GetPosOut()) );
69  //TVector3 direction = (point->GetPosOut() - point->GetPosIn()).Unit();
70 
72  {
73  const EicGeoMap *fmap = mGptr->GetMapPtrViaHitMultiIndex(point->GetMultiIndex());
74 
75  // If map is not declared as "sensitive" (so its top-level volume is not sensitive)
76  // and energy deposit accouting is not requested, no reason to allocate a new cell;
77  if (!fmap || !fmap->IsSensitive()) return 0;
78  }
79 
80  // FIXME: do it better later; for now just prohibit using default HandleHit()
81  // for cases when custom resolution calculation is required;
83 
84  unsigned accu = 0;
85  for(unsigned nd=0; nd<mKfNodeTemplates.size(); nd++) {
86  EicKfNodeTemplate *kftmpl = mKfNodeTemplates[nd];
87 
88  // Coordinates in "node local" system (so not only master->local transformation,
89  // but local->node as well); yes, at most 3 components I guess; some sane direction
90  // vector for cases when it is not needed (let it be aligned with local Z axis);
91  double localCoord[3];//, localDirection[3] = {0.0, 0.0, 1.0};
92 
93 #if _LATER_
94  if (mHitImportMode) {
95  // This stuff is basically disabled; if ever want to use it, rework from scratch;
96  assert(0);
97  double sigma[3], *sigmaPtr = mForceRealHitSmearing ? 0 : sigma;
98  //memset(sigma, 0x00, sizeof(sigma));
99 
100  // FIXME: GetZ() is a bad idea here -> do it better later;
101  unsigned group = mGptr->GetZ(xy);
102 
103  // NB; after this call local[] component(s) are already in the
104  // "node local" coordinate system;
105  if (mDigiRun->GetDetectorHits(mDetName->NAME().Data(), group, accu,
106  kftmpl->GetMdim(), localCoord, sigma))
107  goto _next_node;
108 
109  kftmpl->PackDigiHit(mDigiHitArray, mOriginalSmearingModel, mEffectiveSmearingModel,
110  mDetName->Name(), point, nd, localCoord, localDirection, middle, sigmaPtr);
111  }
112  else
113 #endif
114  {
116  assert(node);
117 
118  // FIXME: redo invariant (through TVector3 passing);
119  double midarr[3] = {middle [0], middle [1], middle [2]};
120  //double dirarr[3] = {direction[0], direction[1], direction[2]};
121 
122  if (kftmpl->mNodeToSensitiveVolume) {
123  double buffer[3];
124 
125  node->mGeoMtx-> MasterToLocal(midarr, buffer);
126  kftmpl->mNodeToSensitiveVolume->MasterToLocal(buffer, localCoord);
127 
128  //node->mGeoMtx-> MasterToLocalVect(dirarr, buffer);
129  //kftmpl->mNodeToSensitiveVolume->MasterToLocalVect(buffer, localDirection);
130  }
131  else {
132  node->mGeoMtx-> MasterToLocal(midarr, localCoord);
133  //node->mGeoMtx->MasterToLocalVect(dirarr, localDirection);
134  } //if
135 
136  TVector3 local(localCoord);
137  kftmpl->StoreDigiHit(mDigiHitArray, mDetName->Name(), point, nd, middle,
138  local, mSmearingModel);
139  } //if
140 
141  _next_node:
142  accu += kftmpl->GetMdim();
143  } //for nd
144 
145  return 0;
146 } // EicTrackingDigiHitProducer::HandleHit()
147 
148 // ---------------------------------------------------------------------------------------
149 
150 //
151 // FIXME: re-incorporate this later (Calculate is of interest);
152 //
153 
154 #if _HTC_
156 {
157  // Yes, prefer to take middle point;
158  TVector3 middle( 0.5 * (point->GetPosIn() + point->GetPosOut()) );
159 
160  TVector3 local = fGeoH->MasterToLocalPath(middle, point->fVolumePath);
161 
162  // Do it better later; for now just prohibit using default HandleHit()
163  // for cases when custom resolution calculation is required;
164  //assert (_smearingModel != _CALCULATE_);
165 
166  double phi = 0.0, cov[6];
167  memset(cov, 0x00, sizeof(cov));
168 
169  // So then smear local coordinates;
170  switch (_smearingModel) {
171  case _SMEAR_:
172  {
173  for(int iq=0; iq<3; iq++)
174  if (_fResolution[iq])
175  local[iq] += gRandom->Gaus(0.0, _fResolution[iq]);
176  }
177  break;
178  case _QUANTIZE_:
179  {
180  for(int iq=0; iq<3; iq++)
181  if (_fPitch[iq])
182  // May make problem at small negative numbers -> fix later;
183  local[iq] = _fPitch[iq] * (int) floor (local[iq]/_fPitch[iq]);
184  }
185  break;
186  case _CALCULATE_:
187  {
188  // Get plane ID as encoded in tracker.C;
189  EicGeoMap *fmap = gptr->getMapPtrViaHitMultiIndex(point->fMultiIndex);
190  assert(fmap);
191  UGeo_t iz = (gptr->remapMultiIndex(point->fMultiIndex) & 0xFFFFFFFF) >> 16;
192  //printf("%d\n", iz);
193 
194  //
195  // A plain XY registering plane example;
196  //
197 #if _OFF_
198  {
199  double resolution = 0.002;
200 
201  // Keep alfa equal 0.0 for now; smear XY;
202  for(int iq=0; iq<2; iq++)
203  local[iq] += gRandom->Gaus(0.0, resolution);
204 
205  // Assume XY diagonal components (upper triangle of a 3x3 matrix);
206  cov[0] = cov[3] = resolution * resolution;
207  }
208 #endif
209 
210  //
211  // (r,phi) registering plane example;
212  //
213  {
214  // Convert (x,y) -> (r,phi) in the local wafer coordinate system;
215  // this should work for *any* wafer type with GEANT volume XY=(0,0)
216  // in the anticipated rotation center (so full circle as well as
217  // a sector shoul dwork the same);
218  double x = local[0], y = local[1], r = sqrt(x*x + y*y);
219 
220  phi = atan2(y, x);
221 
222  // Assign resolutions in (r,phi) system to whatever numbers needed
223  // based on wafer ID (see "iz" above), "r" value, etc; smear or quantize
224  // by hand (here gaussian smearing with constant resolutions used);
225  // rotate back to the local wafer GEANT volume coordinate system;
226  double dr = 0.010, dt = 0.002;
227 
228  TVector2 xq = TVector2(gRandom->Gaus(r, dr), gRandom->Gaus(0.0, dt)).Rotate(phi);
229  for(int ip=0; ip<2; ip++)
230  local[ip] = ip ? xq.Y() : xq.X();
231  //printf("@@@ %f: %f %f -> %f %f\n", phi, x, local[0], y, local[1]);
232 
233  // --> FIXME! Do I need to set fResolution to something meaningful?; hmm;
234 
235  // Assign covariance matrix in (r,phi) system; assume XY diagonal components
236  // in this example; [6]: upper triangle of a 3x3 matrix;
237  cov[0] = dr*dr; cov[3] = dt*dt;
238  }
239  }
240  break;
241  default:
242  assert(0);
243  } //switch
244 
245  // Make FairHit happy; do not want to change the meaning of those variables;
246  TVector3 global = fGeoH->LocalToMasterPath(local, point->fVolumePath);
247 
248  // Create hit;
249  new((*fDigiHitArray)[fDigiHitArray->GetEntriesFast()])
250  EicTrackingDigiHit(dname->cname(), _odim, point, local, global,
251  _smearingModel == _SMEAR_ ? _fResolution : _fPitchSqrt12,
252  phi, _smearingModel == _CALCULATE_ ? cov : 0);
253 
254  return 0;
255 } // EicTrackingDigiHitProducer::HandleHit()
256 #endif
257 
258 // ---------------------------------------------------------------------------------------
259 
260 //
261 // May want to unify with Calorimeter hit producer and move all this stuff
262 // to EicDigiHitProducer class;
263 //
264 
266 {
267  //FairRun *fRun = FairRun::Instance();
268 
269  // I guess there is no need to save/restore current directory here?;
270  //fRun->GetOutputFile()->cd();
271 
273 
274  // Yes, save under detector-specific pre-defined name;
275  //if (digi) digi->mergeIntoOutputFile(mDetName->Name() + "DigiParData");
276  if (digi) digi->mergeIntoOutputFile(mDetName->Name() + "TrackingDigiParData");
277 
278  // Save object itself;
279  //Write(mDetName->Name() + "DigiHitProducer");
280  Write(mDetName->Name() + "TrackingDigiHitProducer");
281 } // EicTrackingDigiHitProducer::Finish()
282 
283 // -----------------------------------------------------------------------------------------------
284 
285 //
286 // FIXME: clean up interface here; or better get rid of KfMatrix completely;
287 //
288 
290 {
291  static KfMatrix V = KfMatrix(1,1);
292 
293  //V.KFM(0,0) = hit->GetSigma(0) * hit->GetSigma(0);
294  V.KFM(0,0) = hit->GetCovariance(0,0);
295 
296  return &V;
297 } // EicKfNodeTemplate1D::GetMeasurementNoise()
298 
300 {
301  static KfMatrix V = KfMatrix(2,2);
302 
303  V.KFM(0,1) = V.KFM(1,0) = 0.0;
304  for(unsigned iq=0; iq<2; iq++)
305  //V.KFM(iq,iq) = hit->GetSigma(iq) * hit->GetSigma(iq);
306  V.KFM(iq,iq) = hit->GetCovariance(iq,iq);
307 
308  return &V;
309 } // EicKfNodeTemplateOrth2D::GetMeasurementNoise()
310 
312 {
313  assert(0);
314 
315  static KfMatrix V = KfMatrix(3,3);
316 
317  for(unsigned ip=0; ip<3; ip++)
318  for(unsigned iq=0; iq<3; iq++)
319  V.KFM(ip,iq) = ip == iq ? hit->GetCovariance(iq,iq) : 0.0;
320 
321  return &V;
322 } // EicKfNodeTemplateOrth3D::GetMeasurementNoise()
323 
324 #if _LATER_
325 KfMatrix *EicKfNodeTemplateAxial3D::GetMeasurementNoise(const EicTrackingDigiHit *hit) const
326 {
327  assert(0);
328 
329 #if _OLD_
330  static KfMatrix V = KfMatrix(2,2);
331 
332  V.KFM(0,1) = V.KFM(1,0) = 0.0;
333  for(unsigned iq=0; iq<2; iq++)
334  //V.KFM(iq,iq) = hit->GetSigma(iq) * hit->GetSigma(iq);
335  V.KFM(iq,iq) = hit->GetCovariance(iq,iq);
336 
337  return &V;
338 #endif
339 } // EicKfNodeTemplateAxial3D::GetMeasurementNoise()
340 #endif
341 
342 // -----------------------------------------------------------------------------------------------
343 
344 // FIXME: do it better later;
345 #define _DIM_ 4
346 
347 //
348 // FIXME: I guess this stuff can work only with scan axis being Z axis?;
349 //
350 
352  EicTrackingDigiHit *hit, double zRef,
353  KfMatrix *A, KfMatrix *b)
354 {
355 #if _TODAY_
356  // FIXME: need to apply local->node rotation as well; perhaps even something more tricky;
357  assert(GetMdim() == 2);
358 
359  for(unsigned ipp=0; ipp<GetMdim(); ipp++) {
360  KalmanNodeWrapper *wrapper = &sv->mKfNodeWrappers[hit->GetKfNodeID()];
361  double alfa = wrapper->GetAxisComponent(ipp,_X_), beta = wrapper->GetAxisComponent(ipp,_Y_);
362  double dz = wrapper->GetOrigin()[_Z_] - zRef, R[_DIM_] = {alfa, beta, alfa*dz, beta*dz};
363 
364  double xx = (wrapper->GetOrigin() + hit->GetCoord(ipp) *
365  (*wrapper->GetAxis(ipp))).Dot((*wrapper->GetAxis(ipp)));
366  //printf("%f %f\n", wrapper->GetOrigin()[_Z_], xx);
367  double rsqr = hit->GetSigma(ipp) * hit->GetSigma(ipp);
368 
369  for(int ip=0; ip<_DIM_; ip++)
370  for(int iq=0; iq<_DIM_; iq++)
371  A->KFM(ip,iq) += R[ip]*R[iq]/rsqr;
372 
373  for(int ip=0; ip<_DIM_; ip++)
374  b->KFV(ip) += R[ip]*xx/rsqr;
375  } //for ip
376 #endif
377 
378  return 0;
379 } // EicKfNodeTemplate::IncrementLinearTrackFitMatrices()
380 
381 // -----------------------------------------------------------------------------------------------
382 
393 //+ClassImp(EicKfNodeTemplateAxial3D)
394