1 /**************************************************************************
\r
2 * Copyright(c) 2007-2009, ALICE Experiment at CERN, All rights reserved. *
\r
4 * Author: The ALICE Off-line Project. *
\r
5 * Contributors are mentioned in the code where appropriate. *
\r
7 * Permission to use, copy, modify and distribute this software and its *
\r
8 * documentation strictly for non-commercial purposes is hereby granted *
\r
9 * without fee, provided that the above copyright notice appears in all *
\r
10 * copies and that both the copyright notice and this permission notice *
\r
11 * appear in the supporting documentation. The authors make no claims *
\r
12 * about the suitability of this software for any purpose. It is *
\r
13 * provided "as is" without express or implied warranty. *
\r
14 **************************************************************************/
\r
17 //-----------------------------------------------------------------------------
\r
18 /// \class AliITSAlignMille2Module
\r
19 /// Alignment class for the ALICE ITS detector
\r
21 /// This class is used by AliITSAlignMille to build custom supermodules
\r
22 /// made of ITS sensitive modules. These supermodules are then aligned
\r
24 /// Custom supermodules must have VolumeID > 14335
\r
26 /// \author M. Lunardon
\r
27 //-----------------------------------------------------------------------------
\r
29 #include <TGeoManager.h>
\r
30 #include <TGeoMatrix.h>
\r
32 #include "AliITSAlignMille2Module.h"
\r
33 #include "AliITSgeomTGeo.h"
\r
34 #include "AliGeomManager.h"
\r
35 #include "AliAlignObjParams.h"
\r
36 #include "AliLog.h"
\r
37 #include "AliITSAlignMille2.h"
\r
40 ClassImp(AliITSAlignMille2Module)
\r
45 AliAlignObjParams AliITSAlignMille2Module::fgTempAlignObj;
\r
46 const Float_t AliITSAlignMille2Module::fgkDummyConstraint = 1e-2;//1.E3;
\r
48 //-------------------------------------------------------------
\r
49 AliITSAlignMille2Module::AliITSAlignMille2Module() :
\r
63 fSensVolVolumeID(0),
\r
65 fSensVolMatrix(NULL),
\r
66 fSensVolModifMatrix(NULL),
\r
70 /// void constructor
\r
71 fMatrix = new TGeoHMatrix;
\r
72 fSensVolMatrix = new TGeoHMatrix;
\r
73 fSensVolModifMatrix = new TGeoHMatrix;
\r
74 fSensVolIndex.Set(1);
\r
75 fSensVolVolumeID.Set(1);
\r
76 fSigmaFactor[0]=fSigmaFactor[1]=fSigmaFactor[2]=1.0;
\r
79 //-------------------------------------------------------------
\r
80 AliITSAlignMille2Module::AliITSAlignMille2Module(Int_t index, UShort_t volid, const char* symname,
\r
81 const TGeoHMatrix *m, Int_t nsv, const UShort_t *volidsv) :
\r
89 fParOffs(kMaxParGeom),
\r
95 fSensVolVolumeID(0),
\r
97 fSensVolMatrix(NULL),
\r
98 fSensVolModifMatrix(NULL),
\r
102 /// void constructor
\r
103 fMatrix = new TGeoHMatrix;
\r
104 fSensVolMatrix = new TGeoHMatrix;
\r
105 fSensVolModifMatrix = new TGeoHMatrix;
\r
106 fSigmaFactor[0]=fSigmaFactor[1]=fSigmaFactor[2]=1.0;
\r
107 for (int i=kMaxParGeom;i--;) fParOffs[i] = -1;
\r
108 if (Set(index,volid,symname,m,nsv,volidsv)) {
\r
109 AliInfo("Error in AliITSAlignMille2Module::Set() - initializing void supermodule...");
\r
114 //-------------------------------------------------------------
\r
115 AliITSAlignMille2Module::AliITSAlignMille2Module(UShort_t volid) :
\r
123 fParOffs(kMaxParGeom),
\r
129 fSensVolVolumeID(0),
\r
131 fSensVolMatrix(NULL),
\r
132 fSensVolModifMatrix(NULL),
\r
136 /// simple constructor building a supermodule from a single sensitive volume
\r
137 fMatrix = new TGeoHMatrix;
\r
138 fSensVolMatrix = new TGeoHMatrix;
\r
139 fSensVolModifMatrix = new TGeoHMatrix;
\r
140 // temporary align object, just use the rotation...
\r
141 fSensVolIndex.Set(1);
\r
142 fSensVolVolumeID.Set(1);
\r
143 fSigmaFactor[0]=fSigmaFactor[1]=fSigmaFactor[2]=1.0;
\r
144 for (int i=kMaxParGeom;i--;) fParOffs[i] = -1;
\r
146 fIndex = GetIndexFromVolumeID(volid);
\r
147 if (fIndex>=0 && gGeoManager) { // good sensitive module and geometry loaded
\r
148 SetName(AliGeomManager::SymName(volid));
\r
150 AddSensitiveVolume(volid);
\r
151 SetSensorsProvided(kTRUE);
\r
152 if (SensVolMatrix(volid, fMatrix))
\r
153 AliInfo("Matrix not defined");
\r
156 AliInfo("Wrong VolumeID or Geometry not loaded - initializing void supermodule...");
\r
162 //_____________________________________________________________________________
\r
163 AliITSAlignMille2Module::AliITSAlignMille2Module(const AliITSAlignMille2Module &m) :
\r
165 fNSensVol(m.fNSensVol),
\r
167 fDetType(m.fDetType),
\r
168 fVolumeID(m.fVolumeID),
\r
169 fNParTot(m.fNParTot),
\r
170 fNParFree(m.fNParFree),
\r
171 fParOffs(m.fNParTot),
\r
176 fSensVolIndex(m.fSensVolIndex),
\r
177 fSensVolVolumeID(m.fSensVolVolumeID),
\r
178 fMatrix(new TGeoHMatrix(*m.GetMatrix())),
\r
179 fSensVolMatrix(new TGeoHMatrix),
\r
180 fSensVolModifMatrix(new TGeoHMatrix),
\r
181 fParent(m.fParent),
\r
184 // Copy constructor
\r
185 fSensVolIndex = m.fSensVolIndex;
\r
186 fSensVolVolumeID = m.fSensVolVolumeID;
\r
187 for (int i=m.fNParTot;i--;) fParOffs[i] = m.fParOffs[i];
\r
188 for (int i=3;i--;) fSigmaFactor[i] = m.fSigmaFactor[i];
\r
190 fParVals = new Float_t[fNParTot];
\r
191 fParErrs = new Float_t[fNParTot];
\r
192 fParCstr = new Float_t[fNParTot];
\r
193 for (int i=fNParTot;i--;) {
\r
194 fParVals[i] = m.fParVals[i];
\r
195 fParErrs[i] = m.fParErrs[i];
\r
196 fParCstr[i] = m.fParCstr[i];
\r
201 //_____________________________________________________________________________
\r
202 AliITSAlignMille2Module& AliITSAlignMille2Module::operator=(const AliITSAlignMille2Module &m)
\r
206 if(this==&m) return *this;
\r
207 ((TNamed *)this)->operator=(m);
\r
209 fNSensVol=m.fNSensVol;
\r
211 fDetType = m.fDetType;
\r
212 fVolumeID=m.fVolumeID;
\r
213 fNParTot = m.fNParTot;
\r
214 fNParFree = m.fNParFree;
\r
215 delete[] fParVals; fParVals = 0;
\r
216 delete[] fParErrs; fParErrs = 0;
\r
217 delete[] fParCstr; fParCstr = 0;
\r
220 fParVals = new Float_t[fNParTot];
\r
221 fParErrs = new Float_t[fNParTot];
\r
222 fParCstr = new Float_t[fNParTot];
\r
223 for (int i=m.GetNParTot();i--;) {
\r
224 fParVals[i] = m.fParVals[i];
\r
225 fParErrs[i] = m.fParErrs[i];
\r
226 fParCstr[i] = m.fParCstr[i];
\r
230 fParOffs.Set(fNParTot);
\r
231 for (int i=0;i<fNParTot;i++) fParOffs[i] = m.fParOffs[i];
\r
232 for (int i=3;i--;) fSigmaFactor[i] = m.fSigmaFactor[i];
\r
233 if (fMatrix) delete fMatrix;
\r
234 fMatrix=new TGeoHMatrix(*m.GetMatrix());
\r
235 fSensVolIndex = m.fSensVolIndex;
\r
236 fSensVolVolumeID = m.fSensVolVolumeID;
\r
237 fParent = m.fParent;
\r
239 for (int i=0;i<m.GetNChildren();i++) fChildren.Add(m.GetChild(i));
\r
244 //-------------------------------------------------------------
\r
245 AliITSAlignMille2Module::~AliITSAlignMille2Module() {
\r
248 delete fSensVolMatrix;
\r
249 delete fSensVolModifMatrix;
\r
256 //-------------------------------------------------------------
\r
257 Int_t AliITSAlignMille2Module::Set(Int_t index, UShort_t volid, const char* symname,
\r
258 const TGeoHMatrix *m, Int_t nsv, const UShort_t *volidsv)
\r
260 // initialize a custom supermodule
\r
261 // index, volid, symname and matrix must be given
\r
262 // if (volidsv) add nsv sensitive volumes to the supermodules
\r
263 // return 0 if success
\r
266 AliInfo("Index must be >= 2198");
\r
270 AliInfo("VolumeID must be >= 14336");
\r
274 if (!symname) return -3;
\r
275 for (Int_t i=0; i<2198; i++) {
\r
276 if (!strcmp(symname,AliITSgeomTGeo::GetSymName(i))) {
\r
277 AliInfo("Symname already used by a Sensitive Volume");
\r
284 // can initialize needed stuffs
\r
291 fSensVolIndex.Set(nsv);
\r
292 fSensVolVolumeID.Set(nsv);
\r
293 // add sensitive volumes
\r
294 for (Int_t i=0; i<nsv; i++) AddSensitiveVolume(volidsv[i]);
\r
299 //-------------------------------------------------------------
\r
300 void AliITSAlignMille2Module::SetFreeDOF(Int_t dof,Double_t cstr)
\r
302 if (AliITSAlignMille2::IsZero(cstr)) fParCstr[dof] = 0; // fixed parameter
\r
303 else if (cstr>0) fParCstr[dof] = fgkDummyConstraint+1.; // the parameter is free and unconstrained
\r
304 else fParCstr[dof] = -cstr; // the parameter is free but constrained
\r
307 //-------------------------------------------------------------
\r
308 Bool_t AliITSAlignMille2Module::IsSensor(UShort_t voluid)
\r
310 // Does this volid correspond to sensor ?
\r
311 AliGeomManager::ELayerID layId = AliGeomManager::VolUIDToLayerSafe(voluid);
\r
312 if (layId>0 && layId<7) {
\r
313 Int_t mId = Int_t(voluid & 0x7ff);
\r
314 if( mId>=0 && mId<AliGeomManager::LayerSize(layId)) return kTRUE;
\r
319 //-------------------------------------------------------------
\r
320 Int_t AliITSAlignMille2Module::GetIndexFromVolumeID(UShort_t voluid) {
\r
321 /// index from volume ID
\r
322 AliGeomManager::ELayerID lay = AliGeomManager::VolUIDToLayer(voluid);
\r
323 if (lay<1|| lay>6) return -1;
\r
324 Int_t idx=Int_t(voluid)-2048*lay;
\r
325 if (idx>=AliGeomManager::LayerSize(lay)) return -1;
\r
326 for (Int_t ilay=1; ilay<lay; ilay++)
\r
327 idx += AliGeomManager::LayerSize(ilay);
\r
331 //-------------------------------------------------------------
\r
332 void AliITSAlignMille2Module::AddSensitiveVolume(UShort_t voluid)
\r
334 /// add a sensitive volume to this supermodule
\r
335 if (GetIndexFromVolumeID(voluid)<0) return; // bad volid
\r
337 // in principle, the correct size of fSensVol... arrays was set outside but check anyway
\r
338 if (fSensVolVolumeID.GetSize()<fNSensVol+1) {
\r
339 fSensVolVolumeID.Set(fNSensVol+1);
\r
340 fSensVolIndex.Set(fNSensVol+1);
\r
343 fSensVolVolumeID[fNSensVol] = Short_t(voluid);
\r
344 fSensVolIndex[fNSensVol] = GetIndexFromVolumeID(voluid);
\r
348 //-------------------------------------------------------------
\r
349 void AliITSAlignMille2Module::DelSensitiveVolume(Int_t at)
\r
351 // Suppress sensor at position "at"
\r
352 // in fact we are swapping with the last valid one
\r
353 int lastValid = --fNSensVol;
\r
354 int tmpv = fSensVolIndex[at];
\r
355 fSensVolIndex[at] = fSensVolIndex[lastValid];
\r
356 tmpv = fSensVolVolumeID[at];
\r
357 fSensVolVolumeID[at] = fSensVolVolumeID[lastValid];
\r
358 fSensVolVolumeID[lastValid] = tmpv;
\r
362 //-------------------------------------------------------------
\r
363 Bool_t AliITSAlignMille2Module::IsIn(UShort_t voluid) const
\r
365 /// check if voluid is defined
\r
366 if (!voluid) return kFALSE; // only positive voluid are accepted
\r
367 for (Int_t i=0; i<fNSensVol; i++) if (UShort_t(fSensVolVolumeID[i])==voluid) return kTRUE;
\r
371 //-------------------------------------------------------------
\r
372 Bool_t AliITSAlignMille2Module::BelongsTo(AliITSAlignMille2Module* parent) const
\r
374 /// check if parent contains the sensors of this volume
\r
375 if (fNSensVol<1 || fNSensVol>=parent->GetNSensitiveVolumes()) return kFALSE;
\r
376 return parent->IsIn( fSensVolVolumeID[0] );
\r
379 //-------------------------------------------------------------
\r
380 TGeoHMatrix *AliITSAlignMille2Module::GetSensitiveVolumeModifiedMatrix(UShort_t voluid, Double_t *delta,Bool_t local)
\r
382 // modify the original TGeoHMatrix of the sensitive module 'voluid' according
\r
383 // with a delta transform. applied to the supermodule matrix
\r
384 // return NULL if error
\r
386 if (!IsIn(voluid)) return NULL;
\r
387 if (!gGeoManager) return NULL;
\r
389 // prepare the TGeoHMatrix
\r
390 Double_t tr[3],ang[3];
\r
391 tr[0]=delta[0]; // in centimeter
\r
394 ang[0]=delta[3]; // psi (X) in deg
\r
395 ang[1]=delta[4]; // theta (Y)
\r
396 ang[2]=delta[5]; // phi (Z)
\r
398 fgTempAlignObj.SetRotation(ang[0],ang[1],ang[2]);
\r
399 fgTempAlignObj.SetTranslation(tr[0],tr[1],tr[2]);
\r
400 AliDebug(3,Form("Delta angles: psi=%f theta=%f phi=%f",ang[0],ang[1],ang[2]));
\r
402 fgTempAlignObj.GetMatrix(hm);
\r
403 //printf("\n0: delta matrix\n");hm.Print();
\r
405 // 1) start setting fSensVolModif = fSensVol
\r
406 if (SensVolMatrix(voluid, fSensVolModifMatrix)) return NULL;
\r
409 // 2) set fSensVolModif = SensVolRel
\r
410 fSensVolModifMatrix->MultiplyLeft( &fMatrix->Inverse() );
\r
411 // 3) multiply left by delta
\r
412 fSensVolModifMatrix->MultiplyLeft( &hm );
\r
413 // 4) multiply left by fMatrix
\r
414 fSensVolModifMatrix->MultiplyLeft( fMatrix );
\r
416 else fSensVolModifMatrix->MultiplyLeft( &hm );
\r
418 return fSensVolModifMatrix;
\r
421 //-------------------------------------------------------------
\r
422 AliAlignObjParams *AliITSAlignMille2Module::GetSensitiveVolumeMisalignment(UShort_t voluid, Double_t *deltalocal)
\r
424 // calculate misalignment of sens.vol. 'voluid' according with a displacement 'deltalocal'
\r
425 // of the mother volume. The misalignment is returned as AliAlignObjParams object
\r
427 if (!IsIn(voluid)) return NULL;
\r
428 if (!gGeoManager) return NULL;
\r
430 // prepare the TGeoHMatrix
\r
431 Double_t tr[3],ang[3];
\r
432 tr[0]=deltalocal[0]; // in centimeter
\r
433 tr[1]=deltalocal[1];
\r
434 tr[2]=deltalocal[2];
\r
435 ang[0]=deltalocal[3]; // psi (X) in deg
\r
436 ang[1]=deltalocal[4]; // theta (Y)
\r
437 ang[2]=deltalocal[5]; // phi (Z)
\r
439 fgTempAlignObj.SetRotation(ang[0],ang[1],ang[2]);
\r
440 fgTempAlignObj.SetTranslation(tr[0],tr[1],tr[2]);
\r
441 AliDebug(3,Form("Delta angles: psi=%f theta=%f phi=%f",ang[0],ang[1],ang[2]));
\r
443 return GetSensitiveVolumeMisalignment(voluid,&fgTempAlignObj);
\r
446 //-------------------------------------------------------------
\r
447 AliAlignObjParams *AliITSAlignMille2Module::GetSensitiveVolumeMisalignment(UShort_t voluid, AliAlignObjParams *a)
\r
449 // return the misalignment of the sens. vol. 'voluid' corresponding with
\r
450 // a misalignment 'a' in the mother volume
\r
451 // return NULL if error
\r
453 // Gsv = Gg * Gg-1 * Gsv -> Lsv,g = Gg-1 * Gsv
\r
454 // G'sv = Gg * Dg * Lsv,g === Gsv * Dsv
\r
455 // Gg * Dg * Gg-1 * Gsv = Gsv * Gsv-1 * Gg * Dg * Gg-1 * Gsv
\r
457 // => Dsv = (Gsv-1 * Gg * Dg * Gg-1 * Gsv)
\r
460 if (!IsIn(voluid)) return NULL;
\r
461 if (!gGeoManager) return NULL;
\r
465 // prepare the Delta matrix Dg
\r
470 // 1) start setting fSensVolModif = Gsv
\r
471 if (SensVolMatrix(voluid, fSensVolModifMatrix)) return NULL;
\r
472 //printf("\n1: modif=orig del sensvol\n");fSensVolModifMatrix->Print();
\r
474 // 2) set fSensVolModif = Gg-1 * Gsv
\r
475 fSensVolModifMatrix->MultiplyLeft( &fMatrix->Inverse() );
\r
476 //printf("\n2: modif=relative del sensvol\n");fSensVolModifMatrix->Print();
\r
478 // 3) set fSensVolModif = Dg * Gg-1 * Gsv
\r
479 fSensVolModifMatrix->MultiplyLeft( &dg );
\r
480 //printf("\n3: modif= delta*relative\n");fSensVolModifMatrix->Print();
\r
482 // 4) set fSensVolModif = Gg * Dg * Gg-1 * Gsv
\r
483 fSensVolModifMatrix->MultiplyLeft( fMatrix );
\r
484 //printf("\n4: modif=quasi,manca il Gsv-1...\n");fSensVolModifMatrix->Print();
\r
486 // 5) set fSensVolModif = Gsv-1 * Gg * Dg * Gg-1 * Gsv
\r
487 if (SensVolMatrix(voluid, &dg)) return NULL;
\r
488 fSensVolModifMatrix->MultiplyLeft( &dg.Inverse() );
\r
489 //printf("\n5: modif=finale\n");fSensVolModifMatrix->Print();
\r
492 // 6) mo' fSensVolModif dovrebbe essere la Dsv(loc) t.c. G'sv = Gsv*Dsv(loc)
\r
493 // per trasformarla in Dsv(loc rispetto al Gsv0, non modificato) dovrebbe essere:
\r
494 // Dsv(loc) -> Dpre * Dsv(loc) * Dpre-1
\r
495 //TGeoHMatrix dpre; // dpre = Gsv0-1*Gsv
\r
496 //if (SensVolOrigGlobalMatrix(voluid, &dg)) return NULL;
\r
497 //if (SensVolMatrix(voluid, &dpre)) return NULL;
\r
498 //dpre.MultiplyLeft( &dg.Inverse() );
\r
499 //fSensVolModifMatrix->Multiply( &dpre.Inverse() );
\r
500 //fSensVolModifMatrix->MultiplyLeft( &dpre );
\r
501 // direi che NON FUNZIONA!!!!
\r
505 // reset align object (may not be needed...)
\r
506 fgTempAlignObj.SetVolUID(0);
\r
507 fgTempAlignObj.SetSymName("");
\r
508 fgTempAlignObj.SetTranslation(0,0,0);
\r
509 fgTempAlignObj.SetRotation(0,0,0);
\r
513 // correction for SPD y-shift
\r
514 if (voluid>=2048 && voluid<4256) {
\r
515 TGeoHMatrix deltay;
\r
516 double dy[3]={0.,0.0081,0.};
\r
517 deltay.SetTranslation(dy);
\r
518 fSensVolModifMatrix->MultiplyLeft( &deltay );
\r
519 fSensVolModifMatrix->Multiply( &deltay.Inverse() );
\r
523 if (!fgTempAlignObj.SetMatrix(*fSensVolModifMatrix)) return NULL;
\r
524 fgTempAlignObj.SetVolUID(voluid);
\r
525 fgTempAlignObj.SetSymName(AliGeomManager::SymName(voluid));
\r
527 return &fgTempAlignObj;
\r
531 //-------------------------------------------------------------
\r
532 AliAlignObjParams *AliITSAlignMille2Module::GetSensitiveVolumeTotalMisalignment(UShort_t voluid, Double_t *deltalocal)
\r
534 // calculate misalignment of sens.vol. 'voluid' according with a displacement 'deltalocal'
\r
535 // of the mother volume. The misalignment is returned as AliAlignObjParams object including
\r
536 // the (evenctual) prealignment => no merging needed
\r
538 if (!IsIn(voluid)) return NULL;
\r
539 if (!gGeoManager) return NULL;
\r
541 // prepare the TGeoHMatrix
\r
542 Double_t tr[3],ang[3];
\r
543 tr[0]=deltalocal[0]; // in centimeter
\r
544 tr[1]=deltalocal[1];
\r
545 tr[2]=deltalocal[2];
\r
546 ang[0]=deltalocal[3]; // psi (X) in deg
\r
547 ang[1]=deltalocal[4]; // theta (Y)
\r
548 ang[2]=deltalocal[5]; // phi (Z)
\r
550 // reset align object (may not be needed...)
\r
551 fgTempAlignObj.SetVolUID(0);
\r
552 fgTempAlignObj.SetSymName("");
\r
553 fgTempAlignObj.SetRotation(ang[0],ang[1],ang[2]);
\r
554 fgTempAlignObj.SetTranslation(tr[0],tr[1],tr[2]);
\r
555 AliDebug(3,Form("Delta angles: psi=%f theta=%f phi=%f",ang[0],ang[1],ang[2]));
\r
557 // Gsv = Gg * Gg-1 * Gsv -> Lsv,g = Gg-1 * Gsv
\r
558 // G'sv = Gg * Dg * Lsv,g === DGsv * Gsv
\r
560 // => Dsv = (G0sv-1 * Gg * Dg * Gg-1 * GMsv) //
\r
563 // prepare the Delta matrix Dg
\r
565 fgTempAlignObj.GetMatrix(dg);
\r
568 // 1) start setting fSensVolModif = Gsv
\r
569 if (SensVolMatrix(voluid, fSensVolModifMatrix)) return NULL;
\r
570 //printf("\n1: modif=orig del sensvol\n");fSensVolModifMatrix->Print();
\r
572 // 2) set fSensVolModif = Gg-1 * Gsv
\r
573 fSensVolModifMatrix->MultiplyLeft( &fMatrix->Inverse() );
\r
574 //printf("\n2: modif=relative del sensvol\n");fSensVolModifMatrix->Print();
\r
576 // 3) set fSensVolModif = Dg * Gg-1 * Gsv
\r
577 fSensVolModifMatrix->MultiplyLeft( &dg );
\r
578 //printf("\n3: modif= delta*relative\n");fSensVolModifMatrix->Print();
\r
580 // 4) set fSensVolModif = Gg * Dg * Gg-1 * Gsv
\r
581 fSensVolModifMatrix->MultiplyLeft( fMatrix );
\r
582 //printf("\n4: modif=quasi,manca il Gsv-1...\n");fSensVolModifMatrix->Print();
\r
584 // 5) set fSensVolModif = G0sv-1 * Gg * Dg * Gg-1 * Gsv
\r
585 // qui usa l'orig anziche' la prealigned...
\r
586 if (SensVolOrigGlobalMatrix(voluid, &dg)) return NULL;
\r
587 fSensVolModifMatrix->MultiplyLeft( &dg.Inverse() );
\r
588 //printf("\n5: modif=finale\n");fSensVolModifMatrix->Print();
\r
590 // reset align object (may not be needed...)
\r
591 fgTempAlignObj.SetVolUID(0);
\r
592 fgTempAlignObj.SetSymName("");
\r
593 fgTempAlignObj.SetTranslation(0,0,0);
\r
594 fgTempAlignObj.SetRotation(0,0,0);
\r
597 // correction for SPD y-shift
\r
598 if (voluid>=2048 && voluid<4256) {
\r
599 TGeoHMatrix deltay;
\r
600 double dy[3]={0.,0.0081,0.};
\r
601 deltay.SetTranslation(dy);
\r
602 fSensVolModifMatrix->MultiplyLeft( &deltay );
\r
603 fSensVolModifMatrix->Multiply( &deltay.Inverse() );
\r
606 if (!fgTempAlignObj.SetMatrix(*fSensVolModifMatrix)) return NULL;
\r
607 fgTempAlignObj.SetVolUID(voluid);
\r
608 fgTempAlignObj.SetSymName(AliGeomManager::SymName(voluid));
\r
611 //fgTempAlignObj.Print("");
\r
613 return &fgTempAlignObj;
\r
615 //-------------------------------------------------------------
\r
617 //-------------------------------------------------------------
\r
618 AliAlignObjParams *AliITSAlignMille2Module::GetSensitiveVolumeGlobalMisalignment(UShort_t voluid, Double_t *deltalocal)
\r
620 // calculate misalignment of sens.vol. 'voluid' according with a displacement 'deltalocal'
\r
621 // of the mother volume. The misalignment is returned as AliAlignObjParams object
\r
623 if (!IsIn(voluid)) return NULL;
\r
624 if (!gGeoManager) return NULL;
\r
626 // prepare the TGeoHMatrix
\r
627 Double_t tr[3],ang[3];
\r
628 tr[0]=deltalocal[0]; // in centimeter
\r
629 tr[1]=deltalocal[1];
\r
630 tr[2]=deltalocal[2];
\r
631 ang[0]=deltalocal[3]; // psi (X) in deg
\r
632 ang[1]=deltalocal[4]; // theta (Y)
\r
633 ang[2]=deltalocal[5]; // phi (Z)
\r
635 // reset align object (may not be needed...)
\r
636 fgTempAlignObj.SetTranslation(0,0,0);
\r
637 fgTempAlignObj.SetRotation(0,0,0);
\r
639 fgTempAlignObj.SetRotation(ang[0],ang[1],ang[2]);
\r
640 fgTempAlignObj.SetTranslation(tr[0],tr[1],tr[2]);
\r
641 AliDebug(3,Form("Delta angles: psi=%f theta=%f phi=%f",ang[0],ang[1],ang[2]));
\r
643 // Gsv = Gg * Gg-1 * Gsv -> Lsv,g = Gg-1 * Gsv
\r
644 // G'sv = Gg * Dg * Lsv,g === DGsv * Gsv
\r
646 // => DGsv = (Gg * Dg * Gg-1)
\r
649 // prepare the Delta matrix Dg
\r
651 fgTempAlignObj.GetMatrix(dg);
\r
654 dg.MultiplyLeft( fMatrix );
\r
655 dg.Multiply( &fMatrix->Inverse() );
\r
657 // reset align object (may not be needed...)
\r
658 fgTempAlignObj.SetTranslation(0,0,0);
\r
659 fgTempAlignObj.SetRotation(0,0,0);
\r
661 fgTempAlignObj.SetVolUID(voluid);
\r
662 fgTempAlignObj.SetSymName(AliGeomManager::SymName(voluid));
\r
664 if (!fgTempAlignObj.SetMatrix(dg)) return NULL;
\r
666 //fgTempAlignObj.Print("");
\r
668 return &fgTempAlignObj;
\r
672 //-------------------------------------------------------------
\r
673 TGeoHMatrix *AliITSAlignMille2Module::GetSensitiveVolumeMatrix(UShort_t voluid)
\r
675 // return TGeoHMatrix of the sens.vol. 'voluid' in the current geometry
\r
676 if (SensVolMatrix(voluid,fSensVolMatrix)) return NULL;
\r
677 return fSensVolMatrix;
\r
680 //-------------------------------------------------------------
\r
681 TGeoHMatrix *AliITSAlignMille2Module::GetSensitiveVolumeOrigGlobalMatrix(UShort_t voluid)
\r
683 // return original ideal position (from AliGeomManager::GetOrigGlobalMatrix())
\r
684 if (SensVolOrigGlobalMatrix(voluid,fSensVolMatrix)) return NULL;
\r
685 return fSensVolMatrix;
\r
687 //-------------------------------------------------------------
\r
688 Int_t AliITSAlignMille2Module::SensVolMatrix(UShort_t volid, TGeoHMatrix *m)
\r
690 // set matrix for sensitive modules (SPD corrected)
\r
691 // return 0 if success
\r
693 Int_t idx=GetIndexFromVolumeID(volid);
\r
694 if (idx<0) return -1;
\r
695 if (!AliITSgeomTGeo::GetRotation(idx,rot)) return -2;
\r
696 m->SetRotation(rot);
\r
697 Double_t oLoc[3]={0,0,0};
\r
698 Double_t oGlo[3]={0,0,0};
\r
699 if (!AliITSgeomTGeo::LocalToGlobal(idx,oLoc,oGlo)) return -3;
\r
700 m->SetTranslation(oGlo);
\r
704 //-------------------------------------------------------------
\r
705 Int_t AliITSAlignMille2Module::SensVolOrigGlobalMatrix(UShort_t volid, TGeoHMatrix *m)
\r
707 // set original global matrix for sensitive modules (SPD corrected)
\r
708 // return 0 if success
\r
709 Int_t idx=GetIndexFromVolumeID(volid);
\r
710 if (idx<0) return -1;
\r
712 if (!AliGeomManager::GetOrigGlobalMatrix(AliGeomManager::SymName(volid),mo)) return -1;
\r
716 // SPD y-shift by 81 mu
\r
718 Double_t oLoc[3]={0.0,0.0081,0.0};
\r
719 Double_t oGlo[3]={0,0,0};
\r
720 m->LocalToMaster(oLoc,oGlo);
\r
721 m->SetTranslation(oGlo);
\r
727 //-------------------------------------------------------------
\r
728 UShort_t AliITSAlignMille2Module::GetVolumeIDFromSymname(const Char_t *symname) {
\r
729 /// volume ID from symname
\r
730 if (!symname) return 0;
\r
732 for (UShort_t voluid=2000; voluid<13300; voluid++) {
\r
734 AliGeomManager::ELayerID layerId = AliGeomManager::VolUIDToLayer(voluid,modId);
\r
735 if (layerId>0 && layerId<7 && modId>=0 && modId<AliGeomManager::LayerSize(layerId)) {
\r
736 if (!strcmp(symname,AliGeomManager::SymName(layerId,modId))) return voluid;
\r
743 //-------------------------------------------------------------
\r
744 UShort_t AliITSAlignMille2Module::GetVolumeIDFromIndex(Int_t index) {
\r
745 /// volume ID from index
\r
746 if (index<0 || index>2197) return 0;
\r
747 return GetVolumeIDFromSymname(AliITSgeomTGeo::GetSymName(index));
\r
750 //-------------------------------------------------------------
\r
751 void AliITSAlignMille2Module::Print(Option_t*) const
\r
754 const char* typeName[] = {"SPD","SDD","SSD"};
\r
755 printf("*** ITS SuperModule for AliITSAlignMille ***\n");
\r
756 printf("symname : %s (type: %s)\n",GetName(),fDetType<0 ? "N/A":typeName[fDetType]);
\r
757 printf("parent : %s | %d children\n",fParent ? fParent->GetName() : "N/A",GetNChildren());
\r
758 printf("volumeID : %4d | index : %4d | Geom.Params are %s\n",fVolumeID,fIndex,
\r
759 GeomParamsGlobal() ? "Global":"Local");
\r
760 printf("Factors : X=%.2f Y=%.2f Z=%.2f\n"
\r
761 "DOF: %cTx:%5d| %cTy:%5d| %cTz:%5d| %cPsi:%5d| %cTheta:%5d| %cPhi:%5d|",
\r
762 fSigmaFactor[0],fSigmaFactor[1],fSigmaFactor[2],
\r
763 IsFreeDOF(kDOFTX) ? '+':'-',GetParOffset(kDOFTX),IsFreeDOF(kDOFTY) ? '+':'-',GetParOffset(kDOFTY),
\r
764 IsFreeDOF(kDOFTZ) ? '+':'-',GetParOffset(kDOFTZ),IsFreeDOF(kDOFPS) ? '+':'-',GetParOffset(kDOFPS),
\r
765 IsFreeDOF(kDOFTH) ? '+':'-',GetParOffset(kDOFTH),IsFreeDOF(kDOFPH) ? '+':'-',GetParOffset(kDOFPH));
\r
767 printf("%cT0:%5d| %cDVl:%5d| %cDVr:%5d|",IsFreeDOF(kDOFT0)?'+':'-',GetParOffset(kDOFT0),
\r
768 IsFreeDOF(kDOFDVL)?'+':'-',GetParOffset(kDOFDVL),IsFreeDOF(kDOFDVR)?'+':'-',GetParOffset(kDOFDVR));
\r
769 if (IsVDriftLRSame()) printf("(dVL=dVR)");
\r
773 printf("%4d Sensitive volumes | %6d Processed Points\n",fNSensVol,fNProcPoints);
\r
774 for (Int_t i=0; i<fNSensVol; i++) printf(" voluid[%d] = %d\n",i,UShort_t(fSensVolVolumeID[i]));
\r
777 //-------------------------------------------------------------
\r
778 Bool_t AliITSAlignMille2Module::IsAlignable() const
\r
780 TGeoManager* geoManager = AliGeomManager::GetGeometry();
\r
782 AliInfo("Couldn't initialize geometry");
\r
785 return geoManager->GetAlignableEntry(GetName())!=0;
\r
788 //-------------------------------------------------------------
\r
789 void AliITSAlignMille2Module::GetLocalMatrix(TGeoHMatrix &mat) const
\r
791 // return the local matrix for transformation to its parent
\r
793 if (fParent) mat.MultiplyLeft( &fParent->GetMatrix()->Inverse() );
\r
796 //-------------------------------------------------------------
\r
797 void AliITSAlignMille2Module::AssignDetType()
\r
799 TString tp = GetName();
\r
800 if (tp.Contains("SPD",TString::kIgnoreCase)) fDetType = kSPD;
\r
801 else if (tp.Contains("SDD",TString::kIgnoreCase)) fDetType = kSDD;
\r
802 else if (tp.Contains("SSD",TString::kIgnoreCase)) fDetType = kSSD;
\r
803 else fDetType = -1;
\r
804 fNParTot = IsSDD() ? kMaxParTot:kMaxParGeom;
\r
806 fParVals = new Float_t[fNParTot];
\r
807 fParErrs = new Float_t[fNParTot];
\r
808 fParCstr = new Float_t[fNParTot];
\r
809 if (fParOffs.GetSize()<fNParTot) fParOffs.Set(fNParTot);
\r
810 for (int i=fNParTot;i--;) {
\r
811 fParVals[i] = fParErrs[i] = 0.;
\r
817 //-------------------------------------------------------------
\r
818 void AliITSAlignMille2Module::EvaluateDOF()
\r
821 for (int i=fNParTot;i--;) if (IsFreeDOF(i)) fNParFree++;
\r
824 //-------------------------------------------------------------
\r
825 void AliITSAlignMille2Module::GetSensVolGlobalParams(UShort_t volid,Double_t *t, Double_t *r)
\r
827 // return global parameters of the sensor volid
\r
828 for (int i=3;i--;) t[i] = r[i] = 0.;
\r
829 if (SensVolMatrix(volid,fSensVolMatrix)) return;
\r
830 fgTempAlignObj.SetMatrix(*fSensVolMatrix);
\r
831 fgTempAlignObj.GetPars(t,r);
\r
834 //-------------------------------------------------------------
\r
835 void AliITSAlignMille2Module::GetSensVolLocalParams(UShort_t volid,Double_t *t, Double_t *r)
\r
837 // return parameters of the sensor volid in the current module
\r
838 for (int i=3;i--;) t[i] = r[i] = 0.;
\r
839 if (SensVolMatrix(volid,fSensVolMatrix)) return;
\r
840 fSensVolMatrix->MultiplyLeft( &fMatrix->Inverse() );
\r
841 fgTempAlignObj.SetMatrix(*fSensVolMatrix);
\r
842 fgTempAlignObj.GetPars(t,r);
\r
845 //-------------------------------------------------------------
\r
846 void AliITSAlignMille2Module::GetSensVolGlobalParams(UShort_t volid,Double_t* loct,Double_t* locr,Double_t *t, Double_t *r)
\r
848 // return global parameters of the sensor volid modified by the localDelta params
\r
849 for (int i=3;i--;) t[i] = r[i] = 0.;
\r
850 if (SensVolMatrix(volid,fSensVolMatrix)) return;
\r
851 fgTempAlignObj.SetTranslation(loct[0],loct[1],loct[2]);
\r
852 fgTempAlignObj.SetRotation(locr[0],locr[1],locr[2]);
\r
854 fgTempAlignObj.GetMatrix(*fSensVolModifMatrix); // obtain local delta
\r
855 fSensVolModifMatrix->MultiplyLeft( fSensVolMatrix ); // obtain global delta
\r
856 fgTempAlignObj.SetMatrix(*fSensVolModifMatrix);
\r
857 fgTempAlignObj.GetPars(t,r); // obtain global params
\r
860 //-------------------------------------------------------------
\r
861 void AliITSAlignMille2Module::GetSensVolLocalParams(UShort_t volid,Double_t* loct,Double_t* locr,Double_t *t, Double_t *r)
\r
863 // return parameters of the sensor volid (modified by the localDelta params) in the current volume
\r
864 for (int i=3;i--;) t[i] = r[i] = 0.;
\r
865 if (SensVolMatrix(volid,fSensVolMatrix)) return;
\r
866 fgTempAlignObj.SetTranslation(loct[0],loct[1],loct[2]);
\r
867 fgTempAlignObj.SetRotation(locr[0],locr[1],locr[2]);
\r
869 fgTempAlignObj.GetMatrix(*fSensVolModifMatrix); // obtain local delta
\r
870 fSensVolModifMatrix->MultiplyLeft( fSensVolMatrix ); // obtain global delta
\r
871 fSensVolModifMatrix->MultiplyLeft( &fMatrix->Inverse() ); // obtain delta in current volume
\r
872 fgTempAlignObj.SetMatrix(*fSensVolModifMatrix);
\r
873 fgTempAlignObj.GetPars(t,r); // obtain params
\r
876 //-------------------------------------------------------------
\r
877 void AliITSAlignMille2Module::SetParVals(Double_t *vl,Int_t npar)
\r
879 for (int i=TMath::Min(npar,(Int_t)fNParTot);i--;) fParVals[i] = vl[i];
\r
882 //-------------------------------------------------------------
\r
883 void AliITSAlignMille2Module::GetGeomParamsGlo(Double_t *pars)
\r
885 // recompute parameters from local to global frame
\r
887 // is there anything to do?
\r
888 if (GeomParamsGlobal()) {for (int i=kMaxParGeom;i--;) pars[i] = fParVals[i]; return;}
\r
890 // IMPORTANT: It is assumed that the parents params are defined in a same way (local or global)
\r
891 // as for the current module. Since in the mp2 the modules are stored from parents to children,
\r
892 // it is safe to call this method in loop staring from the lowest level child, i.e. from the end
\r
893 // of the modules array.
\r
895 // DeltaGlobal = (ModifParents)*DeltaLocal*(ModifParents)^-1
\r
897 *fSensVolMatrix = *fMatrix; // current global matrix
\r
898 AliITSAlignMille2Module* parent = GetParent();
\r
900 if (parent->GeomParamsGlobal()) {
\r
901 AliError("Cannot convert params to Global when the parents are already Global\n");
\r
902 for (int i=kMaxParGeom;i--;) pars[i] = 0;
\r
905 fSensVolMatrix->MultiplyLeft( &parent->GetMatrix()->Inverse() ); // Local Matrix
\r
906 Float_t *parpar = parent->GetParVals();
\r
907 fgTempAlignObj.SetTranslation(parpar[0],parpar[1],parpar[2]);
\r
908 fgTempAlignObj.SetRotation(parpar[3],parpar[4],parpar[5]);
\r
909 fgTempAlignObj.GetMatrix(*fSensVolModifMatrix);
\r
910 fSensVolMatrix->MultiplyLeft(fSensVolModifMatrix);
\r
911 fSensVolMatrix->MultiplyLeft(parent->GetMatrix()); // global matrix after parents modifications
\r
912 parent = parent->GetParent();
\r
915 fgTempAlignObj.SetTranslation(fParVals[0],fParVals[1],fParVals[2]);
\r
916 fgTempAlignObj.SetRotation(fParVals[3],fParVals[4],fParVals[5]);
\r
917 fgTempAlignObj.GetMatrix(*fSensVolModifMatrix); // local delta matrix
\r
918 fSensVolModifMatrix->Multiply( &fSensVolMatrix->Inverse() );
\r
919 fSensVolModifMatrix->MultiplyLeft( fSensVolMatrix );
\r
920 fgTempAlignObj.SetMatrix( *fSensVolModifMatrix ); // global delta matrix
\r
921 fgTempAlignObj.GetPars(pars,pars+3);
\r
925 //-------------------------------------------------------------
\r
926 void AliITSAlignMille2Module::GetGeomParamsLoc(Double_t *pars)
\r
928 // recompute parameters from global to local frame
\r
930 // is there anything to do?
\r
931 if (!GeomParamsGlobal()) {for (int i=kMaxParGeom;i--;) pars[i] = fParVals[i]; return;}
\r
933 // IMPORTANT: It is assumed that the parents params are defined in a same way (local or global)
\r
934 // as for the current module. Since in the mp2 the modules are stored from parents to children,
\r
935 // it is safe to call this method in loop staring from the lowest level child, i.e. from the end
\r
936 // of the modules array.
\r
938 // DeltaLocal = (DeltaParents*GlobalMat)^-1*DeltaGlobal*(DeltaParents*GlobalMat)
\r
940 AliITSAlignMille2Module* parent = GetParent();
\r
941 fgTempAlignObj.SetTranslation(0.,0.,0.);
\r
942 fgTempAlignObj.SetRotation(0.,0.,0.);
\r
943 fgTempAlignObj.GetMatrix(*fSensVolMatrix); // get no-shift matrix
\r
945 while (parent) { // accumulate the product of parents global modifications
\r
946 if (!parent->GeomParamsGlobal()) {
\r
947 AliError("Cannot convert params to Local when the parents are already Local\n");
\r
948 for (int i=kMaxParGeom;i--;) pars[i] = 0;
\r
951 Float_t *parpar = parent->GetParVals();
\r
952 fgTempAlignObj.SetTranslation(parpar[0],parpar[1],parpar[2]);
\r
953 fgTempAlignObj.SetRotation(parpar[3],parpar[4],parpar[5]);
\r
954 fgTempAlignObj.GetMatrix(*fSensVolModifMatrix);
\r
955 fSensVolMatrix->Multiply(fSensVolModifMatrix);
\r
956 parent = parent->GetParent();
\r
958 // global matrix after parents modifications
\r
959 fSensVolMatrix->Multiply(fMatrix);
\r
961 fgTempAlignObj.SetTranslation(fParVals[0],fParVals[1],fParVals[2]);
\r
962 fgTempAlignObj.SetRotation(fParVals[3],fParVals[4],fParVals[5]);
\r
963 fgTempAlignObj.GetMatrix(*fSensVolModifMatrix); // global delta matrix
\r
964 fSensVolModifMatrix->MultiplyLeft( &fSensVolMatrix->Inverse() );
\r
965 fSensVolModifMatrix->Multiply( fSensVolMatrix );
\r
966 fgTempAlignObj.SetMatrix( *fSensVolModifMatrix ); // local delta matrix
\r
967 fgTempAlignObj.GetPars(pars,pars+3);
\r
972 //-------------------------------------------------------------
\r
973 void AliITSAlignMille2Module::CalcDerivDPosDPar(Int_t sensVol,const Double_t* pl, Double_t *deriv)
\r
975 // calculate jacobian of the global position vs Parameters (dPos/dParam)
\r
976 // for the point in the sensor sensVol
\r
977 const double kDel = 0.01;
\r
978 double pos0[3],pos1[3],pos2[3],pos3[3];
\r
979 double delta[kMaxParGeom];
\r
981 for (int ip=kMaxParGeom;ip--;) delta[ip] = 0;
\r
983 for (int ip=kMaxParGeom;ip--;) {
\r
986 GetSensitiveVolumeModifiedMatrix(sensVol,delta,!GeomParamsGlobal())->LocalToMaster(pl,pos0);
\r
987 delta[ip] += kDel/2;
\r
988 GetSensitiveVolumeModifiedMatrix(sensVol,delta,!GeomParamsGlobal())->LocalToMaster(pl,pos1);
\r
990 GetSensitiveVolumeModifiedMatrix(sensVol,delta,!GeomParamsGlobal())->LocalToMaster(pl,pos2);
\r
991 delta[ip] += kDel/2;
\r
992 GetSensitiveVolumeModifiedMatrix(sensVol,delta,!GeomParamsGlobal())->LocalToMaster(pl,pos3);
\r
995 double *curd = deriv + ip*3;
\r
996 for (int i=3;i--;) curd[i] = (8.*(pos2[i]-pos1[i]) - (pos3[i]-pos0[i]))/6./kDel;
\r
1001 //-------------------------------------------------------------
\r
1002 void AliITSAlignMille2Module::CalcDerivGloLoc(Int_t idx,Double_t *deriv)
\r
1004 // calculate derivative of global params vs local param idx: deriv[j] = dParGlo[j]/dParLoc[idx]
\r
1005 Double_t lpar[kMaxParGeom];
\r
1006 for (int i=kMaxParGeom;i--;) lpar[i] = 0.;
\r
1007 // using f(x+h),f(x-h),f(x+h/2),f(x-h2)...
\r
1008 Double_t par1[kMaxParGeom]; // f(x-h)
\r
1009 Double_t par2[kMaxParGeom]; // f(x-h/2)
\r
1010 Double_t par3[kMaxParGeom]; // f(x+h/2)
\r
1011 Double_t par4[kMaxParGeom]; // f(x+h)
\r
1013 const Double_t dpar = 1e-3;
\r
1016 lpar[idx] -= dpar;
\r
1017 GetGlobalParams(lpar,lpar+3, par1,par1+3);
\r
1020 lpar[idx] += dpar/2;
\r
1021 GetGlobalParams(lpar,lpar+3, par2,par2+3);
\r
1024 lpar[idx] += dpar;
\r
1025 GetGlobalParams(lpar,lpar+3, par3,par3+3);
\r
1028 lpar[idx] += dpar/2;
\r
1029 GetGlobalParams(lpar,lpar+3, par4,par4+3);
\r
1031 Double_t h2 = 1./(2.*dpar);
\r
1032 for (int i=kMaxParGeom;i--;) {
\r
1033 Double_t d0 = par4[i]-par1[i];
\r
1034 Double_t d2 = 2.*(par3[i]-par2[i]);
\r
1035 deriv[i] = h2*(4*d2 - d0)/3.;
\r
1036 if (TMath::Abs(deriv[i]) < 1.0e-9) deriv[i] = 0.0;
\r
1041 //-------------------------------------------------------------
\r
1042 void AliITSAlignMille2Module::CalcDerivLocGlo(Double_t *deriv)
\r
1044 // calculate derivative of local params vs global params: deriv[i][j] = dParLoc[i]/dParGlo[j]
\r
1045 Double_t gpar[kMaxParGeom];
\r
1046 for (int i=kMaxParGeom;i--;) gpar[i] = 0.;
\r
1047 // using f(x+h),f(x-h),f(x+h/2),f(x-h2)...
\r
1048 Double_t par1[kMaxParGeom]; // f(x-h)
\r
1049 Double_t par2[kMaxParGeom]; // f(x-h/2)
\r
1050 Double_t par3[kMaxParGeom]; // f(x+h/2)
\r
1051 Double_t par4[kMaxParGeom]; // f(x+h)
\r
1053 const Double_t dpar = 1e-3;
\r
1055 for (int ig=kMaxParGeom;ig--;) {
\r
1058 GetLocalParams(gpar,gpar+3, par1,par1+3);
\r
1061 gpar[ig] += dpar/2;
\r
1062 GetLocalParams(gpar,gpar+3, par2,par2+3);
\r
1066 GetLocalParams(gpar,gpar+3, par3,par3+3);
\r
1069 gpar[ig] += dpar/2;
\r
1070 GetLocalParams(gpar,gpar+3, par4,par4+3);
\r
1072 Double_t h2 = 1./(2.*dpar);
\r
1073 for (int i=kMaxParGeom;i--;) {
\r
1074 Double_t d0 = par4[i]-par1[i];
\r
1075 Double_t d2 = 2.*(par3[i]-par2[i]);
\r
1076 int idig = i*kMaxParGeom + ig;
\r
1077 deriv[idig] = h2*(4*d2 - d0)/3.;
\r
1078 if (TMath::Abs(deriv[idig]) < 1.0e-9) deriv[idig] = 0.0;
\r
1084 //________________________________________________________________________________________________________
\r
1085 void AliITSAlignMille2Module::CalcDerivGloLoc(Int_t sensVol,Int_t paridx,Double_t* derivative)
\r
1087 /// calculate numerically the derivatives of global params vs local param paridx for sensor sensVol: dPglob/dPloc_paridx
\r
1089 Double_t lpar[kMaxParGeom];
\r
1090 for (int i=kMaxParGeom;i--;) lpar[i] = 0.;
\r
1091 // using f(x+h),f(x-h),f(x+h/2),f(x-h2)...
\r
1092 Double_t par1[kMaxParGeom]; // f(x-h)
\r
1093 Double_t par2[kMaxParGeom]; // f(x-h/2)
\r
1094 Double_t par3[kMaxParGeom]; // f(x+h/2)
\r
1095 Double_t par4[kMaxParGeom]; // f(x+h)
\r
1097 const Double_t dpar = 1e-3;
\r
1100 lpar[paridx] -= dpar;
\r
1101 GetSensVolGlobalParams(sensVol,lpar,lpar+3, par1,par1+3);
\r
1104 lpar[paridx] += dpar/2;
\r
1105 GetSensVolGlobalParams(sensVol,lpar,lpar+3, par2,par2+3);
\r
1108 lpar[paridx] += dpar;
\r
1109 GetSensVolGlobalParams(sensVol,lpar,lpar+3, par3,par3+3);
\r
1112 lpar[paridx] += dpar/2;
\r
1113 GetSensVolGlobalParams(sensVol,lpar,lpar+3, par4,par4+3);
\r
1115 Double_t h2 = 1./(2.*dpar);
\r
1116 for (int i=kMaxParGeom;i--;) {
\r
1117 Double_t d0 = par4[i]-par1[i];
\r
1118 Double_t d2 = 2.*(par3[i]-par2[i]);
\r
1119 derivative[i] = h2*(4*d2 - d0)/3.;
\r
1120 if (TMath::Abs(derivative[i]) < 1.0e-9) derivative[i] = 0.0;
\r
1125 //________________________________________________________________________________________________________
\r
1126 void AliITSAlignMille2Module::CalcDerivCurLoc(Int_t sensVol,Int_t paridx,Double_t* derivative)
\r
1128 /// calculate numerically the derivatives of sensor params in the current volume vs sensor local param paridx
\r
1130 Double_t lpar[kMaxParGeom];
\r
1131 for (int i=kMaxParGeom;i--;) lpar[i] = 0.;
\r
1132 // using f(x+h),f(x-h),f(x+h/2),f(x-h2)...
\r
1133 Double_t par1[kMaxParGeom]; // f(x-h)
\r
1134 Double_t par2[kMaxParGeom]; // f(x-h/2)
\r
1135 Double_t par3[kMaxParGeom]; // f(x+h/2)
\r
1136 Double_t par4[kMaxParGeom]; // f(x+h)
\r
1138 const Double_t dpar = 1e-3;
\r
1141 lpar[paridx] -= dpar;
\r
1142 GetSensVolLocalParams(sensVol,lpar,lpar+3, par1,par1+3);
\r
1145 lpar[paridx] += dpar/2;
\r
1146 GetSensVolLocalParams(sensVol,lpar,lpar+3, par2,par2+3);
\r
1149 lpar[paridx] += dpar;
\r
1150 GetSensVolLocalParams(sensVol,lpar,lpar+3, par3,par3+3);
\r
1153 lpar[paridx] += dpar/2;
\r
1154 GetSensVolLocalParams(sensVol,lpar,lpar+3, par4,par4+3);
\r
1156 Double_t h2 = 1./(2.*dpar);
\r
1157 for (int i=kMaxParGeom;i--;) {
\r
1158 Double_t d0 = par4[i]-par1[i];
\r
1159 Double_t d2 = 2.*(par3[i]-par2[i]);
\r
1160 derivative[i] = h2*(4*d2 - d0)/3.;
\r
1161 if (TMath::Abs(derivative[i]) < 1.0e-9) derivative[i] = 0.0;
\r
1167 //-------------------------------------------------------------
\r
1168 void AliITSAlignMille2Module::GetGlobalParams(Double_t *t, Double_t *r)
\r
1170 // global parameters of the module
\r
1171 fgTempAlignObj.SetMatrix( *fMatrix );
\r
1172 fgTempAlignObj.GetPars(t,r);
\r
1175 //-------------------------------------------------------------
\r
1176 void AliITSAlignMille2Module::GetGlobalParams(const Double_t* loct, const Double_t* locr, Double_t *t, Double_t *r)
\r
1178 // global parameters of the module after the modification by local loct,locr
\r
1179 fgTempAlignObj.SetTranslation(loct[0],loct[1],loct[2]);
\r
1180 fgTempAlignObj.SetRotation(locr[0],locr[1],locr[2]);
\r
1181 fgTempAlignObj.GetMatrix(*fSensVolModifMatrix);
\r
1182 *fSensVolMatrix = *fMatrix;
\r
1183 fSensVolMatrix->Multiply(fSensVolModifMatrix);
\r
1184 fgTempAlignObj.SetMatrix(*fSensVolMatrix);
\r
1185 fgTempAlignObj.GetPars(t,r);
\r
1188 //-------------------------------------------------------------
\r
1189 void AliITSAlignMille2Module::GetLocalParams(const Double_t* glot, const Double_t* glor, Double_t *t, Double_t *r)
\r
1191 // obtain local delta parameters from global delta params
\r
1192 fgTempAlignObj.SetTranslation(glot[0],glot[1],glot[2]);
\r
1193 fgTempAlignObj.SetRotation(glor[0],glor[1],glor[2]);
\r
1194 fgTempAlignObj.GetMatrix(*fSensVolMatrix);
\r
1195 fSensVolMatrix->Multiply( fMatrix );
\r
1196 fSensVolMatrix->MultiplyLeft( &fMatrix->Inverse() );
\r
1197 fgTempAlignObj.SetMatrix(*fSensVolMatrix);
\r
1198 fgTempAlignObj.GetPars(t,r);
\r