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 = 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,char* symname,TGeoHMatrix *m,Int_t nsv,UShort_t *volidsv) :
\r
88 fParOffs(kMaxParGeom),
\r
94 fSensVolVolumeID(0),
\r
96 fSensVolMatrix(NULL),
\r
97 fSensVolModifMatrix(NULL),
\r
101 /// void constructor
\r
102 fMatrix = new TGeoHMatrix;
\r
103 fSensVolMatrix = new TGeoHMatrix;
\r
104 fSensVolModifMatrix = new TGeoHMatrix;
\r
105 fSigmaFactor[0]=fSigmaFactor[1]=fSigmaFactor[2]=1.0;
\r
106 for (int i=kMaxParGeom;i--;) fParOffs[i] = -1;
\r
107 if (Set(index,volid,symname,m,nsv,volidsv)) {
\r
108 AliInfo("Error in AliITSAlignMille2Module::Set() - initializing void supermodule...");
\r
113 //-------------------------------------------------------------
\r
114 AliITSAlignMille2Module::AliITSAlignMille2Module(UShort_t volid) :
\r
122 fParOffs(kMaxParGeom),
\r
128 fSensVolVolumeID(0),
\r
130 fSensVolMatrix(NULL),
\r
131 fSensVolModifMatrix(NULL),
\r
135 /// simple constructor building a supermodule from a single sensitive volume
\r
136 fMatrix = new TGeoHMatrix;
\r
137 fSensVolMatrix = new TGeoHMatrix;
\r
138 fSensVolModifMatrix = new TGeoHMatrix;
\r
139 // temporary align object, just use the rotation...
\r
140 fSensVolIndex.Set(1);
\r
141 fSensVolVolumeID.Set(1);
\r
142 fSigmaFactor[0]=fSigmaFactor[1]=fSigmaFactor[2]=1.0;
\r
143 for (int i=kMaxParGeom;i--;) fParOffs[i] = -1;
\r
145 fIndex = GetIndexFromVolumeID(volid);
\r
146 if (fIndex>=0 && gGeoManager) { // good sensitive module and geometry loaded
\r
147 SetName(AliGeomManager::SymName(volid));
\r
149 AddSensitiveVolume(volid);
\r
150 SetSensorsProvided(kTRUE);
\r
151 if (SensVolMatrix(volid, fMatrix))
\r
152 AliInfo("Matrix not defined");
\r
155 AliInfo("Wrong VolumeID or Geometry not loaded - initializing void supermodule...");
\r
161 //_____________________________________________________________________________
\r
162 AliITSAlignMille2Module::AliITSAlignMille2Module(const AliITSAlignMille2Module &m) :
\r
164 fNSensVol(m.fNSensVol),
\r
166 fDetType(m.fDetType),
\r
167 fVolumeID(m.fVolumeID),
\r
168 fNParTot(m.fNParTot),
\r
169 fNParFree(m.fNParFree),
\r
170 fParOffs(m.fNParTot),
\r
175 fSensVolIndex(m.fSensVolIndex),
\r
176 fSensVolVolumeID(m.fSensVolVolumeID),
\r
177 fMatrix(new TGeoHMatrix(*m.GetMatrix())),
\r
178 fSensVolMatrix(new TGeoHMatrix),
\r
179 fSensVolModifMatrix(new TGeoHMatrix),
\r
180 fParent(m.fParent),
\r
183 // Copy constructor
\r
184 fSensVolIndex = m.fSensVolIndex;
\r
185 fSensVolVolumeID = m.fSensVolVolumeID;
\r
186 for (int i=m.fNParTot;i--;) fParOffs[i] = m.fParOffs[i];
\r
187 for (int i=3;i--;) fSigmaFactor[i] = m.fSigmaFactor[i];
\r
189 fParVals = new Float_t[fNParTot];
\r
190 fParErrs = new Float_t[fNParTot];
\r
191 fParCstr = new Float_t[fNParTot];
\r
192 for (int i=fNParTot;i--;) {
\r
193 fParVals[i] = m.fParVals[i];
\r
194 fParErrs[i] = m.fParErrs[i];
\r
195 fParCstr[i] = m.fParCstr[i];
\r
200 //_____________________________________________________________________________
\r
201 AliITSAlignMille2Module& AliITSAlignMille2Module::operator=(const AliITSAlignMille2Module &m)
\r
205 if(this==&m) return *this;
\r
206 ((TNamed *)this)->operator=(m);
\r
208 fNSensVol=m.fNSensVol;
\r
210 fDetType = m.fDetType;
\r
211 fVolumeID=m.fVolumeID;
\r
212 fNParTot = m.fNParTot;
\r
213 fNParFree = m.fNParFree;
\r
214 delete[] fParVals; fParVals = 0;
\r
215 delete[] fParErrs; fParErrs = 0;
\r
216 delete[] fParCstr; fParCstr = 0;
\r
219 fParVals = new Float_t[fNParTot];
\r
220 fParErrs = new Float_t[fNParTot];
\r
221 for (int i=m.GetNParTot();i--;) {
\r
222 fParVals[i] = m.fParVals[i];
\r
223 fParErrs[i] = m.fParErrs[i];
\r
224 fParCstr[i] = m.fParCstr[i];
\r
228 fParOffs.Set(fNParTot);
\r
229 for (int i=0;i<fNParTot;i++) fParOffs[i] = m.fParOffs[i];
\r
230 for (int i=3;i--;) fSigmaFactor[i] = m.fSigmaFactor[i];
\r
231 if (fMatrix) delete fMatrix;
\r
232 fMatrix=new TGeoHMatrix(*m.GetMatrix());
\r
233 fSensVolIndex = m.fSensVolIndex;
\r
234 fSensVolVolumeID = m.fSensVolVolumeID;
\r
235 fParent = m.fParent;
\r
237 for (int i=0;i<m.GetNChildren();i++) fChildren.Add(m.GetChild(i));
\r
242 //-------------------------------------------------------------
\r
243 AliITSAlignMille2Module::~AliITSAlignMille2Module() {
\r
246 delete fSensVolMatrix;
\r
247 delete fSensVolModifMatrix;
\r
254 //-------------------------------------------------------------
\r
255 Int_t AliITSAlignMille2Module::Set(Int_t index, UShort_t volid, char* symname, TGeoHMatrix *m, Int_t nsv, UShort_t *volidsv)
\r
257 // initialize a custom supermodule
\r
258 // index, volid, symname and matrix must be given
\r
259 // if (volidsv) add nsv sensitive volumes to the supermodules
\r
260 // return 0 if success
\r
263 AliInfo("Index must be >= 2198");
\r
267 AliInfo("VolumeID must be >= 14336");
\r
271 if (!symname) return -3;
\r
272 for (Int_t i=0; i<2198; i++) {
\r
273 if (!strcmp(symname,AliITSgeomTGeo::GetSymName(i))) {
\r
274 AliInfo("Symname already used by a Sensitive Volume");
\r
281 // can initialize needed stuffs
\r
288 fSensVolIndex.Set(nsv);
\r
289 fSensVolVolumeID.Set(nsv);
\r
290 // add sensitive volumes
\r
291 for (Int_t i=0; i<nsv; i++) AddSensitiveVolume(volidsv[i]);
\r
296 //-------------------------------------------------------------
\r
297 void AliITSAlignMille2Module::SetFreeDOF(Int_t dof,Double_t cstr)
\r
299 if (cstr>0) fParCstr[dof] = fgkDummyConstraint+1.; // the parameter is free and unconstrained
\r
300 else if (cstr<0) fParCstr[dof] = -cstr; // the parameter is free but constrained
\r
301 else fParCstr[dof] = 0; // fixed parameter
\r
304 //-------------------------------------------------------------
\r
305 Bool_t AliITSAlignMille2Module::IsSensor(UShort_t voluid)
\r
307 // Does this volid correspond to sensor ?
\r
308 AliGeomManager::ELayerID layId = AliGeomManager::VolUIDToLayerSafe(voluid);
\r
309 if (layId>0 && layId<7) {
\r
310 Int_t mId = Int_t(voluid & 0x7ff);
\r
311 if( mId>=0 && mId<AliGeomManager::LayerSize(layId)) return kTRUE;
\r
316 //-------------------------------------------------------------
\r
317 Int_t AliITSAlignMille2Module::GetIndexFromVolumeID(UShort_t voluid) {
\r
318 /// index from volume ID
\r
319 AliGeomManager::ELayerID lay = AliGeomManager::VolUIDToLayer(voluid);
\r
320 if (lay<1|| lay>6) return -1;
\r
321 Int_t idx=Int_t(voluid)-2048*lay;
\r
322 if (idx>=AliGeomManager::LayerSize(lay)) return -1;
\r
323 for (Int_t ilay=1; ilay<lay; ilay++)
\r
324 idx += AliGeomManager::LayerSize(ilay);
\r
328 //-------------------------------------------------------------
\r
329 void AliITSAlignMille2Module::AddSensitiveVolume(UShort_t voluid)
\r
331 /// add a sensitive volume to this supermodule
\r
332 if (GetIndexFromVolumeID(voluid)<0) return; // bad volid
\r
334 // in principle, the correct size of fSensVol... arrays was set outside but check anyway
\r
335 if (fSensVolVolumeID.GetSize()<fNSensVol) {
\r
336 fSensVolVolumeID.Set(fNSensVol+1);
\r
337 fSensVolIndex.Set(fNSensVol+1);
\r
340 fSensVolVolumeID[fNSensVol] = Short_t(voluid);
\r
341 fSensVolIndex[fNSensVol] = GetIndexFromVolumeID(voluid);
\r
345 //-------------------------------------------------------------
\r
346 void AliITSAlignMille2Module::DelSensitiveVolume(Int_t at)
\r
348 // Suppress sensor at position "at"
\r
349 // in fact we are swapping with the last valid one
\r
350 int lastValid = --fNSensVol;
\r
351 int tmpv = fSensVolIndex[at];
\r
352 fSensVolIndex[at] = fSensVolIndex[lastValid];
\r
353 tmpv = fSensVolVolumeID[at];
\r
354 fSensVolVolumeID[at] = fSensVolVolumeID[lastValid];
\r
355 fSensVolVolumeID[lastValid] = tmpv;
\r
359 //-------------------------------------------------------------
\r
360 Bool_t AliITSAlignMille2Module::IsIn(UShort_t voluid) const
\r
362 /// check if voluid is defined
\r
363 if (!voluid) return kFALSE; // only positive voluid are accepted
\r
364 for (Int_t i=0; i<fNSensVol; i++) if (UShort_t(fSensVolVolumeID[i])==voluid) return kTRUE;
\r
368 //-------------------------------------------------------------
\r
369 Bool_t AliITSAlignMille2Module::BelongsTo(AliITSAlignMille2Module* parent) const
\r
371 /// check if parent contains the sensors of this volume
\r
372 if (fNSensVol<1 || fNSensVol>=parent->GetNSensitiveVolumes()) return kFALSE;
\r
373 return parent->IsIn( fSensVolVolumeID[0] );
\r
376 //-------------------------------------------------------------
\r
377 TGeoHMatrix *AliITSAlignMille2Module::GetSensitiveVolumeModifiedMatrix(UShort_t voluid, Double_t *delta,Bool_t local)
\r
379 // modify the original TGeoHMatrix of the sensitive module 'voluid' according
\r
380 // with a delta transform. applied to the supermodule matrix
\r
381 // return NULL if error
\r
383 if (!IsIn(voluid)) return NULL;
\r
384 if (!gGeoManager) return NULL;
\r
386 // prepare the TGeoHMatrix
\r
387 Double_t tr[3],ang[3];
\r
388 tr[0]=delta[0]; // in centimeter
\r
391 ang[0]=delta[3]; // psi (X) in deg
\r
392 ang[1]=delta[4]; // theta (Y)
\r
393 ang[2]=delta[5]; // phi (Z)
\r
395 fgTempAlignObj.SetRotation(ang[0],ang[1],ang[2]);
\r
396 fgTempAlignObj.SetTranslation(tr[0],tr[1],tr[2]);
\r
397 AliDebug(3,Form("Delta angles: psi=%f theta=%f phi=%f",ang[0],ang[1],ang[2]));
\r
399 fgTempAlignObj.GetMatrix(hm);
\r
400 //printf("\n0: delta matrix\n");hm.Print();
\r
402 // 1) start setting fSensVolModif = fSensVol
\r
403 if (SensVolMatrix(voluid, fSensVolModifMatrix)) return NULL;
\r
406 // 2) set fSensVolModif = SensVolRel
\r
407 fSensVolModifMatrix->MultiplyLeft( &fMatrix->Inverse() );
\r
408 // 3) multiply left by delta
\r
409 fSensVolModifMatrix->MultiplyLeft( &hm );
\r
410 // 4) multiply left by fMatrix
\r
411 fSensVolModifMatrix->MultiplyLeft( fMatrix );
\r
413 else fSensVolModifMatrix->MultiplyLeft( &hm );
\r
415 return fSensVolModifMatrix;
\r
418 //-------------------------------------------------------------
\r
419 AliAlignObjParams *AliITSAlignMille2Module::GetSensitiveVolumeMisalignment(UShort_t voluid, Double_t *deltalocal)
\r
421 // calculate misalignment of sens.vol. 'voluid' according with a displacement 'deltalocal'
\r
422 // of the mother volume. The misalignment is returned as AliAlignObjParams object
\r
424 if (!IsIn(voluid)) return NULL;
\r
425 if (!gGeoManager) return NULL;
\r
427 // prepare the TGeoHMatrix
\r
428 Double_t tr[3],ang[3];
\r
429 tr[0]=deltalocal[0]; // in centimeter
\r
430 tr[1]=deltalocal[1];
\r
431 tr[2]=deltalocal[2];
\r
432 ang[0]=deltalocal[3]; // psi (X) in deg
\r
433 ang[1]=deltalocal[4]; // theta (Y)
\r
434 ang[2]=deltalocal[5]; // phi (Z)
\r
436 fgTempAlignObj.SetRotation(ang[0],ang[1],ang[2]);
\r
437 fgTempAlignObj.SetTranslation(tr[0],tr[1],tr[2]);
\r
438 AliDebug(3,Form("Delta angles: psi=%f theta=%f phi=%f",ang[0],ang[1],ang[2]));
\r
440 return GetSensitiveVolumeMisalignment(voluid,&fgTempAlignObj);
\r
443 //-------------------------------------------------------------
\r
444 AliAlignObjParams *AliITSAlignMille2Module::GetSensitiveVolumeMisalignment(UShort_t voluid, AliAlignObjParams *a)
\r
446 // return the misalignment of the sens. vol. 'voluid' corresponding with
\r
447 // a misalignment 'a' in the mother volume
\r
448 // return NULL if error
\r
450 // Gsv = Gg * Gg-1 * Gsv -> Lsv,g = Gg-1 * Gsv
\r
451 // G'sv = Gg * Dg * Lsv,g === Gsv * Dsv
\r
452 // Gg * Dg * Gg-1 * Gsv = Gsv * Gsv-1 * Gg * Dg * Gg-1 * Gsv
\r
454 // => Dsv = (Gsv-1 * Gg * Dg * Gg-1 * Gsv)
\r
457 if (!IsIn(voluid)) return NULL;
\r
458 if (!gGeoManager) return NULL;
\r
462 // prepare the Delta matrix Dg
\r
467 // 1) start setting fSensVolModif = Gsv
\r
468 if (SensVolMatrix(voluid, fSensVolModifMatrix)) return NULL;
\r
469 //printf("\n1: modif=orig del sensvol\n");fSensVolModifMatrix->Print();
\r
471 // 2) set fSensVolModif = Gg-1 * Gsv
\r
472 fSensVolModifMatrix->MultiplyLeft( &fMatrix->Inverse() );
\r
473 //printf("\n2: modif=relative del sensvol\n");fSensVolModifMatrix->Print();
\r
475 // 3) set fSensVolModif = Dg * Gg-1 * Gsv
\r
476 fSensVolModifMatrix->MultiplyLeft( &dg );
\r
477 //printf("\n3: modif= delta*relative\n");fSensVolModifMatrix->Print();
\r
479 // 4) set fSensVolModif = Gg * Dg * Gg-1 * Gsv
\r
480 fSensVolModifMatrix->MultiplyLeft( fMatrix );
\r
481 //printf("\n4: modif=quasi,manca il Gsv-1...\n");fSensVolModifMatrix->Print();
\r
483 // 5) set fSensVolModif = Gsv-1 * Gg * Dg * Gg-1 * Gsv
\r
484 if (SensVolMatrix(voluid, &dg)) return NULL;
\r
485 fSensVolModifMatrix->MultiplyLeft( &dg.Inverse() );
\r
486 //printf("\n5: modif=finale\n");fSensVolModifMatrix->Print();
\r
489 // 6) mo' fSensVolModif dovrebbe essere la Dsv(loc) t.c. G'sv = Gsv*Dsv(loc)
\r
490 // per trasformarla in Dsv(loc rispetto al Gsv0, non modificato) dovrebbe essere:
\r
491 // Dsv(loc) -> Dpre * Dsv(loc) * Dpre-1
\r
492 //TGeoHMatrix dpre; // dpre = Gsv0-1*Gsv
\r
493 //if (SensVolOrigGlobalMatrix(voluid, &dg)) return NULL;
\r
494 //if (SensVolMatrix(voluid, &dpre)) return NULL;
\r
495 //dpre.MultiplyLeft( &dg.Inverse() );
\r
496 //fSensVolModifMatrix->Multiply( &dpre.Inverse() );
\r
497 //fSensVolModifMatrix->MultiplyLeft( &dpre );
\r
498 // direi che NON FUNZIONA!!!!
\r
502 // reset align object (may not be needed...)
\r
503 fgTempAlignObj.SetVolUID(0);
\r
504 fgTempAlignObj.SetSymName("");
\r
505 fgTempAlignObj.SetTranslation(0,0,0);
\r
506 fgTempAlignObj.SetRotation(0,0,0);
\r
510 // correction for SPD y-shift
\r
511 if (voluid>=2048 && voluid<4256) {
\r
512 TGeoHMatrix deltay;
\r
513 double dy[3]={0.,0.0081,0.};
\r
514 deltay.SetTranslation(dy);
\r
515 fSensVolModifMatrix->MultiplyLeft( &deltay );
\r
516 fSensVolModifMatrix->Multiply( &deltay.Inverse() );
\r
520 if (!fgTempAlignObj.SetMatrix(*fSensVolModifMatrix)) return NULL;
\r
521 fgTempAlignObj.SetVolUID(voluid);
\r
522 fgTempAlignObj.SetSymName(AliGeomManager::SymName(voluid));
\r
524 return &fgTempAlignObj;
\r
528 //-------------------------------------------------------------
\r
529 AliAlignObjParams *AliITSAlignMille2Module::GetSensitiveVolumeTotalMisalignment(UShort_t voluid, Double_t *deltalocal)
\r
531 // calculate misalignment of sens.vol. 'voluid' according with a displacement 'deltalocal'
\r
532 // of the mother volume. The misalignment is returned as AliAlignObjParams object including
\r
533 // the (evenctual) prealignment => no merging needed
\r
535 if (!IsIn(voluid)) return NULL;
\r
536 if (!gGeoManager) return NULL;
\r
538 // prepare the TGeoHMatrix
\r
539 Double_t tr[3],ang[3];
\r
540 tr[0]=deltalocal[0]; // in centimeter
\r
541 tr[1]=deltalocal[1];
\r
542 tr[2]=deltalocal[2];
\r
543 ang[0]=deltalocal[3]; // psi (X) in deg
\r
544 ang[1]=deltalocal[4]; // theta (Y)
\r
545 ang[2]=deltalocal[5]; // phi (Z)
\r
547 // reset align object (may not be needed...)
\r
548 fgTempAlignObj.SetVolUID(0);
\r
549 fgTempAlignObj.SetSymName("");
\r
550 fgTempAlignObj.SetRotation(ang[0],ang[1],ang[2]);
\r
551 fgTempAlignObj.SetTranslation(tr[0],tr[1],tr[2]);
\r
552 AliDebug(3,Form("Delta angles: psi=%f theta=%f phi=%f",ang[0],ang[1],ang[2]));
\r
554 // Gsv = Gg * Gg-1 * Gsv -> Lsv,g = Gg-1 * Gsv
\r
555 // G'sv = Gg * Dg * Lsv,g === DGsv * Gsv
\r
557 // => Dsv = (G0sv-1 * Gg * Dg * Gg-1 * GMsv) //
\r
560 // prepare the Delta matrix Dg
\r
562 fgTempAlignObj.GetMatrix(dg);
\r
565 // 1) start setting fSensVolModif = Gsv
\r
566 if (SensVolMatrix(voluid, fSensVolModifMatrix)) return NULL;
\r
567 //printf("\n1: modif=orig del sensvol\n");fSensVolModifMatrix->Print();
\r
569 // 2) set fSensVolModif = Gg-1 * Gsv
\r
570 fSensVolModifMatrix->MultiplyLeft( &fMatrix->Inverse() );
\r
571 //printf("\n2: modif=relative del sensvol\n");fSensVolModifMatrix->Print();
\r
573 // 3) set fSensVolModif = Dg * Gg-1 * Gsv
\r
574 fSensVolModifMatrix->MultiplyLeft( &dg );
\r
575 //printf("\n3: modif= delta*relative\n");fSensVolModifMatrix->Print();
\r
577 // 4) set fSensVolModif = Gg * Dg * Gg-1 * Gsv
\r
578 fSensVolModifMatrix->MultiplyLeft( fMatrix );
\r
579 //printf("\n4: modif=quasi,manca il Gsv-1...\n");fSensVolModifMatrix->Print();
\r
581 // 5) set fSensVolModif = G0sv-1 * Gg * Dg * Gg-1 * Gsv
\r
582 // qui usa l'orig anziche' la prealigned...
\r
583 if (SensVolOrigGlobalMatrix(voluid, &dg)) return NULL;
\r
584 fSensVolModifMatrix->MultiplyLeft( &dg.Inverse() );
\r
585 //printf("\n5: modif=finale\n");fSensVolModifMatrix->Print();
\r
587 // reset align object (may not be needed...)
\r
588 fgTempAlignObj.SetVolUID(0);
\r
589 fgTempAlignObj.SetSymName("");
\r
590 fgTempAlignObj.SetTranslation(0,0,0);
\r
591 fgTempAlignObj.SetRotation(0,0,0);
\r
594 // correction for SPD y-shift
\r
595 if (voluid>=2048 && voluid<4256) {
\r
596 TGeoHMatrix deltay;
\r
597 double dy[3]={0.,0.0081,0.};
\r
598 deltay.SetTranslation(dy);
\r
599 fSensVolModifMatrix->MultiplyLeft( &deltay );
\r
600 fSensVolModifMatrix->Multiply( &deltay.Inverse() );
\r
603 if (!fgTempAlignObj.SetMatrix(*fSensVolModifMatrix)) return NULL;
\r
604 fgTempAlignObj.SetVolUID(voluid);
\r
605 fgTempAlignObj.SetSymName(AliGeomManager::SymName(voluid));
\r
608 //fgTempAlignObj.Print("");
\r
610 return &fgTempAlignObj;
\r
612 //-------------------------------------------------------------
\r
614 //-------------------------------------------------------------
\r
615 AliAlignObjParams *AliITSAlignMille2Module::GetSensitiveVolumeGlobalMisalignment(UShort_t voluid, Double_t *deltalocal)
\r
617 // calculate misalignment of sens.vol. 'voluid' according with a displacement 'deltalocal'
\r
618 // of the mother volume. The misalignment is returned as AliAlignObjParams object
\r
620 if (!IsIn(voluid)) return NULL;
\r
621 if (!gGeoManager) return NULL;
\r
623 // prepare the TGeoHMatrix
\r
624 Double_t tr[3],ang[3];
\r
625 tr[0]=deltalocal[0]; // in centimeter
\r
626 tr[1]=deltalocal[1];
\r
627 tr[2]=deltalocal[2];
\r
628 ang[0]=deltalocal[3]; // psi (X) in deg
\r
629 ang[1]=deltalocal[4]; // theta (Y)
\r
630 ang[2]=deltalocal[5]; // phi (Z)
\r
632 // reset align object (may not be needed...)
\r
633 fgTempAlignObj.SetTranslation(0,0,0);
\r
634 fgTempAlignObj.SetRotation(0,0,0);
\r
636 fgTempAlignObj.SetRotation(ang[0],ang[1],ang[2]);
\r
637 fgTempAlignObj.SetTranslation(tr[0],tr[1],tr[2]);
\r
638 AliDebug(3,Form("Delta angles: psi=%f theta=%f phi=%f",ang[0],ang[1],ang[2]));
\r
640 // Gsv = Gg * Gg-1 * Gsv -> Lsv,g = Gg-1 * Gsv
\r
641 // G'sv = Gg * Dg * Lsv,g === DGsv * Gsv
\r
643 // => DGsv = (Gg * Dg * Gg-1)
\r
646 // prepare the Delta matrix Dg
\r
648 fgTempAlignObj.GetMatrix(dg);
\r
651 dg.MultiplyLeft( fMatrix );
\r
652 dg.Multiply( &fMatrix->Inverse() );
\r
654 // reset align object (may not be needed...)
\r
655 fgTempAlignObj.SetTranslation(0,0,0);
\r
656 fgTempAlignObj.SetRotation(0,0,0);
\r
658 fgTempAlignObj.SetVolUID(voluid);
\r
659 fgTempAlignObj.SetSymName(AliGeomManager::SymName(voluid));
\r
661 if (!fgTempAlignObj.SetMatrix(dg)) return NULL;
\r
663 //fgTempAlignObj.Print("");
\r
665 return &fgTempAlignObj;
\r
669 //-------------------------------------------------------------
\r
670 TGeoHMatrix *AliITSAlignMille2Module::GetSensitiveVolumeMatrix(UShort_t voluid)
\r
672 // return TGeoHMatrix of the sens.vol. 'voluid' in the current geometry
\r
673 if (SensVolMatrix(voluid,fSensVolMatrix)) return NULL;
\r
674 return fSensVolMatrix;
\r
677 //-------------------------------------------------------------
\r
678 TGeoHMatrix *AliITSAlignMille2Module::GetSensitiveVolumeOrigGlobalMatrix(UShort_t voluid)
\r
680 // return original ideal position (from AliGeomManager::GetOrigGlobalMatrix())
\r
681 if (SensVolOrigGlobalMatrix(voluid,fSensVolMatrix)) return NULL;
\r
682 return fSensVolMatrix;
\r
684 //-------------------------------------------------------------
\r
685 Int_t AliITSAlignMille2Module::SensVolMatrix(UShort_t volid, TGeoHMatrix *m)
\r
687 // set matrix for sensitive modules (SPD corrected)
\r
688 // return 0 if success
\r
690 Int_t idx=GetIndexFromVolumeID(volid);
\r
691 if (idx<0) return -1;
\r
692 if (!AliITSgeomTGeo::GetRotation(idx,rot)) return -2;
\r
693 m->SetRotation(rot);
\r
694 Double_t oLoc[3]={0,0,0};
\r
695 Double_t oGlo[3]={0,0,0};
\r
696 if (!AliITSgeomTGeo::LocalToGlobal(idx,oLoc,oGlo)) return -3;
\r
697 m->SetTranslation(oGlo);
\r
701 //-------------------------------------------------------------
\r
702 Int_t AliITSAlignMille2Module::SensVolOrigGlobalMatrix(UShort_t volid, TGeoHMatrix *m)
\r
704 // set original global matrix for sensitive modules (SPD corrected)
\r
705 // return 0 if success
\r
706 Int_t idx=GetIndexFromVolumeID(volid);
\r
707 if (idx<0) return -1;
\r
709 if (!AliGeomManager::GetOrigGlobalMatrix(AliGeomManager::SymName(volid),mo)) return -1;
\r
713 // SPD y-shift by 81 mu
\r
715 Double_t oLoc[3]={0.0,0.0081,0.0};
\r
716 Double_t oGlo[3]={0,0,0};
\r
717 m->LocalToMaster(oLoc,oGlo);
\r
718 m->SetTranslation(oGlo);
\r
724 //-------------------------------------------------------------
\r
725 UShort_t AliITSAlignMille2Module::GetVolumeIDFromSymname(const Char_t *symname) {
\r
726 /// volume ID from symname
\r
727 if (!symname) return 0;
\r
729 for (UShort_t voluid=2000; voluid<13300; voluid++) {
\r
731 AliGeomManager::ELayerID layerId = AliGeomManager::VolUIDToLayer(voluid,modId);
\r
732 if (layerId>0 && layerId<7 && modId>=0 && modId<AliGeomManager::LayerSize(layerId)) {
\r
733 if (!strcmp(symname,AliGeomManager::SymName(layerId,modId))) return voluid;
\r
740 //-------------------------------------------------------------
\r
741 UShort_t AliITSAlignMille2Module::GetVolumeIDFromIndex(Int_t index) {
\r
742 /// volume ID from index
\r
743 if (index<0 || index>2197) return 0;
\r
744 return GetVolumeIDFromSymname(AliITSgeomTGeo::GetSymName(index));
\r
747 //-------------------------------------------------------------
\r
748 void AliITSAlignMille2Module::Print(Option_t*) const
\r
751 const char* typeName[] = {"SPD","SDD","SSD"};
\r
752 printf("*** ITS SuperModule for AliITSAlignMille ***\n");
\r
753 printf("symname : %s (type: %s)\n",GetName(),fDetType<0 ? "N/A":typeName[fDetType]);
\r
754 printf("parent : %s | %d children\n",fParent ? fParent->GetName() : "N/A",GetNChildren());
\r
755 printf("volumeID : %4d | index : %4d | Geom.Params are %s\n",fVolumeID,fIndex,
\r
756 GeomParamsGlobal() ? "Global":"Local");
\r
757 printf("Factors : X=%.2f Y=%.2f Z=%.2f\n"
\r
758 "DOF: %cTx:%5d| %cTy:%5d| %cTz:%5d| %cPsi:%5d| %cTheta:%5d| %cPhi:%5d|",
\r
759 fSigmaFactor[0],fSigmaFactor[1],fSigmaFactor[2],
\r
760 IsFreeDOF(kDOFTX) ? '+':'-',fParOffs[kDOFTX],IsFreeDOF(kDOFTY) ? '+':'-',fParOffs[kDOFTY],
\r
761 IsFreeDOF(kDOFTZ) ? '+':'-',fParOffs[kDOFTZ],IsFreeDOF(kDOFPS) ? '+':'-',fParOffs[kDOFPS],
\r
762 IsFreeDOF(kDOFTH) ? '+':'-',fParOffs[kDOFTH],IsFreeDOF(kDOFPH) ? '+':'-',fParOffs[kDOFPH]);
\r
763 if (IsSDD()) printf("%cT0:%5d| %cDV:%5d|",IsFreeDOF(kDOFT0)?'+':'-',fParOffs[kDOFT0],
\r
764 IsFreeDOF(kDOFDV)?'+':'-',fParOffs[kDOFDV]);
\r
767 printf("%4d Sensitive volumes | %6d Processed Points\n",fNSensVol,fNProcPoints);
\r
768 for (Int_t i=0; i<fNSensVol; i++) printf(" voluid[%d] = %d\n",i,UShort_t(fSensVolVolumeID[i]));
\r
771 //-------------------------------------------------------------
\r
772 Bool_t AliITSAlignMille2Module::IsAlignable() const
\r
774 TGeoManager* geoManager = AliGeomManager::GetGeometry();
\r
776 AliInfo("Couldn't initialize geometry");
\r
779 return geoManager->GetAlignableEntry(GetName())!=0;
\r
782 //-------------------------------------------------------------
\r
783 void AliITSAlignMille2Module::GetLocalMatrix(TGeoHMatrix &mat) const
\r
785 // return the local matrix for transformation to its parent
\r
787 if (fParent) mat.MultiplyLeft( &fParent->GetMatrix()->Inverse() );
\r
790 //-------------------------------------------------------------
\r
791 void AliITSAlignMille2Module::AssignDetType()
\r
793 TString tp = GetName();
\r
794 if (tp.Contains("SPD",TString::kIgnoreCase)) fDetType = kSPD;
\r
795 else if (tp.Contains("SDD",TString::kIgnoreCase)) fDetType = kSDD;
\r
796 else if (tp.Contains("SSD",TString::kIgnoreCase)) fDetType = kSSD;
\r
797 else fDetType = -1;
\r
798 fNParTot = IsSDD() ? 8:6;
\r
800 fParVals = new Float_t[fNParTot];
\r
801 fParErrs = new Float_t[fNParTot];
\r
802 fParCstr = new Float_t[fNParTot];
\r
803 if (fParOffs.GetSize()<fNParTot) fParOffs.Set(fNParTot);
\r
804 for (int i=fNParTot;i--;) {
\r
805 fParVals[i] = fParErrs[i] = 0.;
\r
811 //-------------------------------------------------------------
\r
812 void AliITSAlignMille2Module::EvaluateDOF()
\r
815 for (int i=fNParTot;i--;) if (IsFreeDOF(i)) fNParFree++;
\r
818 //-------------------------------------------------------------
\r
819 void AliITSAlignMille2Module::GetSensVolGlobalParams(UShort_t volid,Double_t *t, Double_t *r)
\r
821 // return global parameters of the sensor volid
\r
822 for (int i=3;i--;) t[i] = r[i] = 0.;
\r
823 if (SensVolMatrix(volid,fSensVolMatrix)) return;
\r
824 fgTempAlignObj.SetMatrix(*fSensVolMatrix);
\r
825 fgTempAlignObj.GetPars(t,r);
\r
828 //-------------------------------------------------------------
\r
829 void AliITSAlignMille2Module::GetSensVolLocalParams(UShort_t volid,Double_t *t, Double_t *r)
\r
831 // return parameters of the sensor volid in the current module
\r
832 for (int i=3;i--;) t[i] = r[i] = 0.;
\r
833 if (SensVolMatrix(volid,fSensVolMatrix)) return;
\r
834 fSensVolMatrix->MultiplyLeft( &fMatrix->Inverse() );
\r
835 fgTempAlignObj.SetMatrix(*fSensVolMatrix);
\r
836 fgTempAlignObj.GetPars(t,r);
\r
839 //-------------------------------------------------------------
\r
840 void AliITSAlignMille2Module::GetSensVolGlobalParams(UShort_t volid,Double_t* loct,Double_t* locr,Double_t *t, Double_t *r)
\r
842 // return global parameters of the sensor volid modified by the localDelta params
\r
843 for (int i=3;i--;) t[i] = r[i] = 0.;
\r
844 if (SensVolMatrix(volid,fSensVolMatrix)) return;
\r
845 fgTempAlignObj.SetTranslation(loct[0],loct[1],loct[2]);
\r
846 fgTempAlignObj.SetRotation(locr[0],locr[1],locr[2]);
\r
848 fgTempAlignObj.GetMatrix(*fSensVolModifMatrix); // obtain local delta
\r
849 fSensVolModifMatrix->MultiplyLeft( fSensVolMatrix ); // obtain global delta
\r
850 fgTempAlignObj.SetMatrix(*fSensVolModifMatrix);
\r
851 fgTempAlignObj.GetPars(t,r); // obtain global params
\r
854 //-------------------------------------------------------------
\r
855 void AliITSAlignMille2Module::GetSensVolLocalParams(UShort_t volid,Double_t* loct,Double_t* locr,Double_t *t, Double_t *r)
\r
857 // return parameters of the sensor volid (modified by the localDelta params) in the current volume
\r
858 for (int i=3;i--;) t[i] = r[i] = 0.;
\r
859 if (SensVolMatrix(volid,fSensVolMatrix)) return;
\r
860 fgTempAlignObj.SetTranslation(loct[0],loct[1],loct[2]);
\r
861 fgTempAlignObj.SetRotation(locr[0],locr[1],locr[2]);
\r
863 fgTempAlignObj.GetMatrix(*fSensVolModifMatrix); // obtain local delta
\r
864 fSensVolModifMatrix->MultiplyLeft( fSensVolMatrix ); // obtain global delta
\r
865 fSensVolModifMatrix->MultiplyLeft( &fMatrix->Inverse() ); // obtain delta in current volume
\r
866 fgTempAlignObj.SetMatrix(*fSensVolModifMatrix);
\r
867 fgTempAlignObj.GetPars(t,r); // obtain params
\r
870 //-------------------------------------------------------------
\r
871 void AliITSAlignMille2Module::SetParVals(Double_t *vl,Int_t npar)
\r
873 for (int i=TMath::Min(npar,(Int_t)fNParTot);i--;) fParVals[i] = vl[i];
\r
876 //-------------------------------------------------------------
\r
877 void AliITSAlignMille2Module::GetGeomParamsGlo(Double_t *pars)
\r
879 // recompute parameters from local to global frame
\r
881 // is there anything to do?
\r
882 if (GeomParamsGlobal()) {for (int i=kMaxParGeom;i--;) pars[i] = fParVals[i]; return;}
\r
884 // IMPORTANT: It is assumed that the parents params are defined in a same way (local or global)
\r
885 // as for the current module. Since in the mp2 the modules are stored from parents to children,
\r
886 // it is safe to call this method in loop staring from the lowest level child, i.e. from the end
\r
887 // of the modules array.
\r
889 // DeltaGlobal = (ModifParents)*DeltaLocal*(ModifParents)^-1
\r
891 *fSensVolMatrix = *fMatrix; // current global matrix
\r
892 AliITSAlignMille2Module* parent = GetParent();
\r
894 if (parent->GeomParamsGlobal()) {
\r
895 AliError("Cannot convert params to Global when the parents are already Global\n");
\r
896 for (int i=kMaxParGeom;i--;) pars[i] = 0;
\r
899 fSensVolMatrix->MultiplyLeft( &parent->GetMatrix()->Inverse() ); // Local Matrix
\r
900 Float_t *parpar = parent->GetParVals();
\r
901 fgTempAlignObj.SetTranslation(parpar[0],parpar[1],parpar[2]);
\r
902 fgTempAlignObj.SetRotation(parpar[3],parpar[4],parpar[5]);
\r
903 fgTempAlignObj.GetMatrix(*fSensVolModifMatrix);
\r
904 fSensVolMatrix->MultiplyLeft(fSensVolModifMatrix);
\r
905 fSensVolMatrix->MultiplyLeft(parent->GetMatrix()); // global matrix after parents modifications
\r
906 parent = parent->GetParent();
\r
909 fgTempAlignObj.SetTranslation(fParVals[0],fParVals[1],fParVals[2]);
\r
910 fgTempAlignObj.SetRotation(fParVals[3],fParVals[4],fParVals[5]);
\r
911 fgTempAlignObj.GetMatrix(*fSensVolModifMatrix); // local delta matrix
\r
912 fSensVolModifMatrix->Multiply( &fSensVolMatrix->Inverse() );
\r
913 fSensVolModifMatrix->MultiplyLeft( fSensVolMatrix );
\r
914 fgTempAlignObj.SetMatrix( *fSensVolModifMatrix ); // global delta matrix
\r
915 fgTempAlignObj.GetPars(pars,pars+3);
\r
919 //-------------------------------------------------------------
\r
920 void AliITSAlignMille2Module::GetGeomParamsLoc(Double_t *pars)
\r
922 // recompute parameters from global to local frame
\r
924 // is there anything to do?
\r
925 if (!GeomParamsGlobal()) {for (int i=kMaxParGeom;i--;) pars[i] = fParVals[i]; return;}
\r
927 // IMPORTANT: It is assumed that the parents params are defined in a same way (local or global)
\r
928 // as for the current module. Since in the mp2 the modules are stored from parents to children,
\r
929 // it is safe to call this method in loop staring from the lowest level child, i.e. from the end
\r
930 // of the modules array.
\r
932 // DeltaLocal = (DeltaParents*GlobalMat)^-1*DeltaGlobal*(DeltaParents*GlobalMat)
\r
934 AliITSAlignMille2Module* parent = GetParent();
\r
935 fgTempAlignObj.SetTranslation(0.,0.,0.);
\r
936 fgTempAlignObj.SetRotation(0.,0.,0.);
\r
937 fgTempAlignObj.GetMatrix(*fSensVolMatrix); // get no-shift matrix
\r
939 while (parent) { // accumulate the product of parents global modifications
\r
940 if (!parent->GeomParamsGlobal()) {
\r
941 AliError("Cannot convert params to Local when the parents are already Local\n");
\r
942 for (int i=kMaxParGeom;i--;) pars[i] = 0;
\r
945 Float_t *parpar = parent->GetParVals();
\r
946 fgTempAlignObj.SetTranslation(parpar[0],parpar[1],parpar[2]);
\r
947 fgTempAlignObj.SetRotation(parpar[3],parpar[4],parpar[5]);
\r
948 fgTempAlignObj.GetMatrix(*fSensVolModifMatrix);
\r
949 fSensVolMatrix->Multiply(fSensVolModifMatrix);
\r
950 parent = parent->GetParent();
\r
952 // global matrix after parents modifications
\r
953 fSensVolMatrix->Multiply(fMatrix);
\r
955 fgTempAlignObj.SetTranslation(fParVals[0],fParVals[1],fParVals[2]);
\r
956 fgTempAlignObj.SetRotation(fParVals[3],fParVals[4],fParVals[5]);
\r
957 fgTempAlignObj.GetMatrix(*fSensVolModifMatrix); // global delta matrix
\r
958 fSensVolModifMatrix->MultiplyLeft( &fSensVolMatrix->Inverse() );
\r
959 fSensVolModifMatrix->Multiply( fSensVolMatrix );
\r
960 fgTempAlignObj.SetMatrix( *fSensVolModifMatrix ); // local delta matrix
\r
961 fgTempAlignObj.GetPars(pars,pars+3);
\r
965 //-------------------------------------------------------------
\r
966 void AliITSAlignMille2Module::CalcDerivGloLoc(Int_t idx,Double_t *deriv)
\r
968 // calculate derivative of global params vs local param idx: deriv[j] = dParGlo[j]/dParLoc[idx]
\r
969 Double_t lpar[kMaxParGeom];
\r
970 for (int i=kMaxParGeom;i--;) lpar[i] = 0.;
\r
971 // using f(x+h),f(x-h),f(x+h/2),f(x-h2)...
\r
972 Double_t par1[kMaxParGeom]; // f(x-h)
\r
973 Double_t par2[kMaxParGeom]; // f(x-h/2)
\r
974 Double_t par3[kMaxParGeom]; // f(x+h/2)
\r
975 Double_t par4[kMaxParGeom]; // f(x+h)
\r
977 const Double_t dpar = 1e-3;
\r
981 GetGlobalParams(lpar,lpar+3, par1,par1+3);
\r
984 lpar[idx] += dpar/2;
\r
985 GetGlobalParams(lpar,lpar+3, par2,par2+3);
\r
989 GetGlobalParams(lpar,lpar+3, par3,par3+3);
\r
992 lpar[idx] += dpar/2;
\r
993 GetGlobalParams(lpar,lpar+3, par4,par4+3);
\r
995 Double_t h2 = 1./(2.*dpar);
\r
996 for (int i=kMaxParGeom;i--;) {
\r
997 Double_t d0 = par4[i]-par1[i];
\r
998 Double_t d2 = 2.*(par3[i]-par2[i]);
\r
999 deriv[i] = h2*(4*d2 - d0)/3.;
\r
1000 if (TMath::Abs(deriv[i]) < 1.0e-9) deriv[i] = 0.0;
\r
1005 //-------------------------------------------------------------
\r
1006 void AliITSAlignMille2Module::CalcDerivLocGlo(Double_t *deriv)
\r
1008 // calculate derivative of local params vs global params: deriv[i][j] = dParLoc[i]/dParGlo[j]
\r
1009 Double_t gpar[kMaxParGeom];
\r
1010 for (int i=kMaxParGeom;i--;) gpar[i] = 0.;
\r
1011 // using f(x+h),f(x-h),f(x+h/2),f(x-h2)...
\r
1012 Double_t par1[kMaxParGeom]; // f(x-h)
\r
1013 Double_t par2[kMaxParGeom]; // f(x-h/2)
\r
1014 Double_t par3[kMaxParGeom]; // f(x+h/2)
\r
1015 Double_t par4[kMaxParGeom]; // f(x+h)
\r
1017 const Double_t dpar = 1e-3;
\r
1019 for (int ig=kMaxParGeom;ig--;) {
\r
1022 GetLocalParams(gpar,gpar+3, par1,par1+3);
\r
1025 gpar[ig] += dpar/2;
\r
1026 GetLocalParams(gpar,gpar+3, par2,par2+3);
\r
1030 GetLocalParams(gpar,gpar+3, par3,par3+3);
\r
1033 gpar[ig] += dpar/2;
\r
1034 GetLocalParams(gpar,gpar+3, par4,par4+3);
\r
1036 Double_t h2 = 1./(2.*dpar);
\r
1037 for (int i=kMaxParGeom;i--;) {
\r
1038 Double_t d0 = par4[i]-par1[i];
\r
1039 Double_t d2 = 2.*(par3[i]-par2[i]);
\r
1040 int idig = i*kMaxParGeom + ig;
\r
1041 deriv[idig] = h2*(4*d2 - d0)/3.;
\r
1042 if (TMath::Abs(deriv[idig]) < 1.0e-9) deriv[idig] = 0.0;
\r
1048 //________________________________________________________________________________________________________
\r
1049 void AliITSAlignMille2Module::CalcDerivGloLoc(Int_t sensVol,Int_t paridx,Double_t* derivative)
\r
1051 /// calculate numerically the derivatives of global params vs local param paridx for sensor sensVol: dPglob/dPloc_paridx
\r
1053 Double_t lpar[kMaxParGeom];
\r
1054 for (int i=kMaxParGeom;i--;) lpar[i] = 0.;
\r
1055 // using f(x+h),f(x-h),f(x+h/2),f(x-h2)...
\r
1056 Double_t par1[kMaxParGeom]; // f(x-h)
\r
1057 Double_t par2[kMaxParGeom]; // f(x-h/2)
\r
1058 Double_t par3[kMaxParGeom]; // f(x+h/2)
\r
1059 Double_t par4[kMaxParGeom]; // f(x+h)
\r
1061 const Double_t dpar = 1e-3;
\r
1064 lpar[paridx] -= dpar;
\r
1065 GetSensVolGlobalParams(sensVol,lpar,lpar+3, par1,par1+3);
\r
1068 lpar[paridx] += dpar/2;
\r
1069 GetSensVolGlobalParams(sensVol,lpar,lpar+3, par2,par2+3);
\r
1072 lpar[paridx] += dpar;
\r
1073 GetSensVolGlobalParams(sensVol,lpar,lpar+3, par3,par3+3);
\r
1076 lpar[paridx] += dpar/2;
\r
1077 GetSensVolGlobalParams(sensVol,lpar,lpar+3, par4,par4+3);
\r
1079 Double_t h2 = 1./(2.*dpar);
\r
1080 for (int i=kMaxParGeom;i--;) {
\r
1081 Double_t d0 = par4[i]-par1[i];
\r
1082 Double_t d2 = 2.*(par3[i]-par2[i]);
\r
1083 derivative[i] = h2*(4*d2 - d0)/3.;
\r
1084 if (TMath::Abs(derivative[i]) < 1.0e-9) derivative[i] = 0.0;
\r
1089 //________________________________________________________________________________________________________
\r
1090 void AliITSAlignMille2Module::CalcDerivCurLoc(Int_t sensVol,Int_t paridx,Double_t* derivative)
\r
1092 /// calculate numerically the derivatives of sensor params in the current volume vs sensor local param paridx
\r
1094 Double_t lpar[kMaxParGeom];
\r
1095 for (int i=kMaxParGeom;i--;) lpar[i] = 0.;
\r
1096 // using f(x+h),f(x-h),f(x+h/2),f(x-h2)...
\r
1097 Double_t par1[kMaxParGeom]; // f(x-h)
\r
1098 Double_t par2[kMaxParGeom]; // f(x-h/2)
\r
1099 Double_t par3[kMaxParGeom]; // f(x+h/2)
\r
1100 Double_t par4[kMaxParGeom]; // f(x+h)
\r
1102 const Double_t dpar = 1e-3;
\r
1105 lpar[paridx] -= dpar;
\r
1106 GetSensVolLocalParams(sensVol,lpar,lpar+3, par1,par1+3);
\r
1109 lpar[paridx] += dpar/2;
\r
1110 GetSensVolLocalParams(sensVol,lpar,lpar+3, par2,par2+3);
\r
1113 lpar[paridx] += dpar;
\r
1114 GetSensVolLocalParams(sensVol,lpar,lpar+3, par3,par3+3);
\r
1117 lpar[paridx] += dpar/2;
\r
1118 GetSensVolLocalParams(sensVol,lpar,lpar+3, par4,par4+3);
\r
1120 Double_t h2 = 1./(2.*dpar);
\r
1121 for (int i=kMaxParGeom;i--;) {
\r
1122 Double_t d0 = par4[i]-par1[i];
\r
1123 Double_t d2 = 2.*(par3[i]-par2[i]);
\r
1124 derivative[i] = h2*(4*d2 - d0)/3.;
\r
1125 if (TMath::Abs(derivative[i]) < 1.0e-9) derivative[i] = 0.0;
\r
1131 //-------------------------------------------------------------
\r
1132 void AliITSAlignMille2Module::GetGlobalParams(Double_t *t, Double_t *r)
\r
1134 // global parameters of the module
\r
1135 fgTempAlignObj.SetMatrix( *fMatrix );
\r
1136 fgTempAlignObj.GetPars(t,r);
\r
1139 //-------------------------------------------------------------
\r
1140 void AliITSAlignMille2Module::GetGlobalParams(const Double_t* loct, const Double_t* locr, Double_t *t, Double_t *r)
\r
1142 // global parameters of the module after the modification by local loct,locr
\r
1143 fgTempAlignObj.SetTranslation(loct[0],loct[1],loct[2]);
\r
1144 fgTempAlignObj.SetRotation(locr[0],locr[1],locr[2]);
\r
1145 fgTempAlignObj.GetMatrix(*fSensVolModifMatrix);
\r
1146 *fSensVolMatrix = *fMatrix;
\r
1147 fSensVolMatrix->Multiply(fSensVolModifMatrix);
\r
1148 fgTempAlignObj.SetMatrix(*fSensVolMatrix);
\r
1149 fgTempAlignObj.GetPars(t,r);
\r
1152 //-------------------------------------------------------------
\r
1153 void AliITSAlignMille2Module::GetLocalParams(const Double_t* glot, const Double_t* glor, Double_t *t, Double_t *r)
\r
1155 // obtain local delta parameters from global delta params
\r
1156 fgTempAlignObj.SetTranslation(glot[0],glot[1],glot[2]);
\r
1157 fgTempAlignObj.SetRotation(glor[0],glor[1],glor[2]);
\r
1158 fgTempAlignObj.GetMatrix(*fSensVolMatrix);
\r
1159 fSensVolMatrix->Multiply( fMatrix );
\r
1160 fSensVolMatrix->MultiplyLeft( &fMatrix->Inverse() );
\r
1161 fgTempAlignObj.SetMatrix(*fSensVolMatrix);
\r
1162 fgTempAlignObj.GetPars(t,r);
\r