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, 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 for (int i=m.GetNParTot();i--;) {
\r
223 fParVals[i] = m.fParVals[i];
\r
224 fParErrs[i] = m.fParErrs[i];
\r
225 fParCstr[i] = m.fParCstr[i];
\r
229 fParOffs.Set(fNParTot);
\r
230 for (int i=0;i<fNParTot;i++) fParOffs[i] = m.fParOffs[i];
\r
231 for (int i=3;i--;) fSigmaFactor[i] = m.fSigmaFactor[i];
\r
232 if (fMatrix) delete fMatrix;
\r
233 fMatrix=new TGeoHMatrix(*m.GetMatrix());
\r
234 fSensVolIndex = m.fSensVolIndex;
\r
235 fSensVolVolumeID = m.fSensVolVolumeID;
\r
236 fParent = m.fParent;
\r
238 for (int i=0;i<m.GetNChildren();i++) fChildren.Add(m.GetChild(i));
\r
243 //-------------------------------------------------------------
\r
244 AliITSAlignMille2Module::~AliITSAlignMille2Module() {
\r
247 delete fSensVolMatrix;
\r
248 delete fSensVolModifMatrix;
\r
255 //-------------------------------------------------------------
\r
256 Int_t AliITSAlignMille2Module::Set(Int_t index, UShort_t volid, const char* symname,
\r
257 const TGeoHMatrix *m, Int_t nsv, const UShort_t *volidsv)
\r
259 // initialize a custom supermodule
\r
260 // index, volid, symname and matrix must be given
\r
261 // if (volidsv) add nsv sensitive volumes to the supermodules
\r
262 // return 0 if success
\r
265 AliInfo("Index must be >= 2198");
\r
269 AliInfo("VolumeID must be >= 14336");
\r
273 if (!symname) return -3;
\r
274 for (Int_t i=0; i<2198; i++) {
\r
275 if (!strcmp(symname,AliITSgeomTGeo::GetSymName(i))) {
\r
276 AliInfo("Symname already used by a Sensitive Volume");
\r
283 // can initialize needed stuffs
\r
290 fSensVolIndex.Set(nsv);
\r
291 fSensVolVolumeID.Set(nsv);
\r
292 // add sensitive volumes
\r
293 for (Int_t i=0; i<nsv; i++) AddSensitiveVolume(volidsv[i]);
\r
298 //-------------------------------------------------------------
\r
299 void AliITSAlignMille2Module::SetFreeDOF(Int_t dof,Double_t cstr)
\r
301 if (cstr>0) fParCstr[dof] = fgkDummyConstraint+1.; // the parameter is free and unconstrained
\r
302 else if (cstr<0) fParCstr[dof] = -cstr; // the parameter is free but constrained
\r
303 else fParCstr[dof] = 0; // fixed parameter
\r
306 //-------------------------------------------------------------
\r
307 Bool_t AliITSAlignMille2Module::IsSensor(UShort_t voluid)
\r
309 // Does this volid correspond to sensor ?
\r
310 AliGeomManager::ELayerID layId = AliGeomManager::VolUIDToLayerSafe(voluid);
\r
311 if (layId>0 && layId<7) {
\r
312 Int_t mId = Int_t(voluid & 0x7ff);
\r
313 if( mId>=0 && mId<AliGeomManager::LayerSize(layId)) return kTRUE;
\r
318 //-------------------------------------------------------------
\r
319 Int_t AliITSAlignMille2Module::GetIndexFromVolumeID(UShort_t voluid) {
\r
320 /// index from volume ID
\r
321 AliGeomManager::ELayerID lay = AliGeomManager::VolUIDToLayer(voluid);
\r
322 if (lay<1|| lay>6) return -1;
\r
323 Int_t idx=Int_t(voluid)-2048*lay;
\r
324 if (idx>=AliGeomManager::LayerSize(lay)) return -1;
\r
325 for (Int_t ilay=1; ilay<lay; ilay++)
\r
326 idx += AliGeomManager::LayerSize(ilay);
\r
330 //-------------------------------------------------------------
\r
331 void AliITSAlignMille2Module::AddSensitiveVolume(UShort_t voluid)
\r
333 /// add a sensitive volume to this supermodule
\r
334 if (GetIndexFromVolumeID(voluid)<0) return; // bad volid
\r
336 // in principle, the correct size of fSensVol... arrays was set outside but check anyway
\r
337 if (fSensVolVolumeID.GetSize()<fNSensVol) {
\r
338 fSensVolVolumeID.Set(fNSensVol+1);
\r
339 fSensVolIndex.Set(fNSensVol+1);
\r
342 fSensVolVolumeID[fNSensVol] = Short_t(voluid);
\r
343 fSensVolIndex[fNSensVol] = GetIndexFromVolumeID(voluid);
\r
347 //-------------------------------------------------------------
\r
348 void AliITSAlignMille2Module::DelSensitiveVolume(Int_t at)
\r
350 // Suppress sensor at position "at"
\r
351 // in fact we are swapping with the last valid one
\r
352 int lastValid = --fNSensVol;
\r
353 int tmpv = fSensVolIndex[at];
\r
354 fSensVolIndex[at] = fSensVolIndex[lastValid];
\r
355 tmpv = fSensVolVolumeID[at];
\r
356 fSensVolVolumeID[at] = fSensVolVolumeID[lastValid];
\r
357 fSensVolVolumeID[lastValid] = tmpv;
\r
361 //-------------------------------------------------------------
\r
362 Bool_t AliITSAlignMille2Module::IsIn(UShort_t voluid) const
\r
364 /// check if voluid is defined
\r
365 if (!voluid) return kFALSE; // only positive voluid are accepted
\r
366 for (Int_t i=0; i<fNSensVol; i++) if (UShort_t(fSensVolVolumeID[i])==voluid) return kTRUE;
\r
370 //-------------------------------------------------------------
\r
371 Bool_t AliITSAlignMille2Module::BelongsTo(AliITSAlignMille2Module* parent) const
\r
373 /// check if parent contains the sensors of this volume
\r
374 if (fNSensVol<1 || fNSensVol>=parent->GetNSensitiveVolumes()) return kFALSE;
\r
375 return parent->IsIn( fSensVolVolumeID[0] );
\r
378 //-------------------------------------------------------------
\r
379 TGeoHMatrix *AliITSAlignMille2Module::GetSensitiveVolumeModifiedMatrix(UShort_t voluid, Double_t *delta,Bool_t local)
\r
381 // modify the original TGeoHMatrix of the sensitive module 'voluid' according
\r
382 // with a delta transform. applied to the supermodule matrix
\r
383 // return NULL if error
\r
385 if (!IsIn(voluid)) return NULL;
\r
386 if (!gGeoManager) return NULL;
\r
388 // prepare the TGeoHMatrix
\r
389 Double_t tr[3],ang[3];
\r
390 tr[0]=delta[0]; // in centimeter
\r
393 ang[0]=delta[3]; // psi (X) in deg
\r
394 ang[1]=delta[4]; // theta (Y)
\r
395 ang[2]=delta[5]; // phi (Z)
\r
397 fgTempAlignObj.SetRotation(ang[0],ang[1],ang[2]);
\r
398 fgTempAlignObj.SetTranslation(tr[0],tr[1],tr[2]);
\r
399 AliDebug(3,Form("Delta angles: psi=%f theta=%f phi=%f",ang[0],ang[1],ang[2]));
\r
401 fgTempAlignObj.GetMatrix(hm);
\r
402 //printf("\n0: delta matrix\n");hm.Print();
\r
404 // 1) start setting fSensVolModif = fSensVol
\r
405 if (SensVolMatrix(voluid, fSensVolModifMatrix)) return NULL;
\r
408 // 2) set fSensVolModif = SensVolRel
\r
409 fSensVolModifMatrix->MultiplyLeft( &fMatrix->Inverse() );
\r
410 // 3) multiply left by delta
\r
411 fSensVolModifMatrix->MultiplyLeft( &hm );
\r
412 // 4) multiply left by fMatrix
\r
413 fSensVolModifMatrix->MultiplyLeft( fMatrix );
\r
415 else fSensVolModifMatrix->MultiplyLeft( &hm );
\r
417 return fSensVolModifMatrix;
\r
420 //-------------------------------------------------------------
\r
421 AliAlignObjParams *AliITSAlignMille2Module::GetSensitiveVolumeMisalignment(UShort_t voluid, Double_t *deltalocal)
\r
423 // calculate misalignment of sens.vol. 'voluid' according with a displacement 'deltalocal'
\r
424 // of the mother volume. The misalignment is returned as AliAlignObjParams object
\r
426 if (!IsIn(voluid)) return NULL;
\r
427 if (!gGeoManager) return NULL;
\r
429 // prepare the TGeoHMatrix
\r
430 Double_t tr[3],ang[3];
\r
431 tr[0]=deltalocal[0]; // in centimeter
\r
432 tr[1]=deltalocal[1];
\r
433 tr[2]=deltalocal[2];
\r
434 ang[0]=deltalocal[3]; // psi (X) in deg
\r
435 ang[1]=deltalocal[4]; // theta (Y)
\r
436 ang[2]=deltalocal[5]; // phi (Z)
\r
438 fgTempAlignObj.SetRotation(ang[0],ang[1],ang[2]);
\r
439 fgTempAlignObj.SetTranslation(tr[0],tr[1],tr[2]);
\r
440 AliDebug(3,Form("Delta angles: psi=%f theta=%f phi=%f",ang[0],ang[1],ang[2]));
\r
442 return GetSensitiveVolumeMisalignment(voluid,&fgTempAlignObj);
\r
445 //-------------------------------------------------------------
\r
446 AliAlignObjParams *AliITSAlignMille2Module::GetSensitiveVolumeMisalignment(UShort_t voluid, AliAlignObjParams *a)
\r
448 // return the misalignment of the sens. vol. 'voluid' corresponding with
\r
449 // a misalignment 'a' in the mother volume
\r
450 // return NULL if error
\r
452 // Gsv = Gg * Gg-1 * Gsv -> Lsv,g = Gg-1 * Gsv
\r
453 // G'sv = Gg * Dg * Lsv,g === Gsv * Dsv
\r
454 // Gg * Dg * Gg-1 * Gsv = Gsv * Gsv-1 * Gg * Dg * Gg-1 * Gsv
\r
456 // => Dsv = (Gsv-1 * Gg * Dg * Gg-1 * Gsv)
\r
459 if (!IsIn(voluid)) return NULL;
\r
460 if (!gGeoManager) return NULL;
\r
464 // prepare the Delta matrix Dg
\r
469 // 1) start setting fSensVolModif = Gsv
\r
470 if (SensVolMatrix(voluid, fSensVolModifMatrix)) return NULL;
\r
471 //printf("\n1: modif=orig del sensvol\n");fSensVolModifMatrix->Print();
\r
473 // 2) set fSensVolModif = Gg-1 * Gsv
\r
474 fSensVolModifMatrix->MultiplyLeft( &fMatrix->Inverse() );
\r
475 //printf("\n2: modif=relative del sensvol\n");fSensVolModifMatrix->Print();
\r
477 // 3) set fSensVolModif = Dg * Gg-1 * Gsv
\r
478 fSensVolModifMatrix->MultiplyLeft( &dg );
\r
479 //printf("\n3: modif= delta*relative\n");fSensVolModifMatrix->Print();
\r
481 // 4) set fSensVolModif = Gg * Dg * Gg-1 * Gsv
\r
482 fSensVolModifMatrix->MultiplyLeft( fMatrix );
\r
483 //printf("\n4: modif=quasi,manca il Gsv-1...\n");fSensVolModifMatrix->Print();
\r
485 // 5) set fSensVolModif = Gsv-1 * Gg * Dg * Gg-1 * Gsv
\r
486 if (SensVolMatrix(voluid, &dg)) return NULL;
\r
487 fSensVolModifMatrix->MultiplyLeft( &dg.Inverse() );
\r
488 //printf("\n5: modif=finale\n");fSensVolModifMatrix->Print();
\r
491 // 6) mo' fSensVolModif dovrebbe essere la Dsv(loc) t.c. G'sv = Gsv*Dsv(loc)
\r
492 // per trasformarla in Dsv(loc rispetto al Gsv0, non modificato) dovrebbe essere:
\r
493 // Dsv(loc) -> Dpre * Dsv(loc) * Dpre-1
\r
494 //TGeoHMatrix dpre; // dpre = Gsv0-1*Gsv
\r
495 //if (SensVolOrigGlobalMatrix(voluid, &dg)) return NULL;
\r
496 //if (SensVolMatrix(voluid, &dpre)) return NULL;
\r
497 //dpre.MultiplyLeft( &dg.Inverse() );
\r
498 //fSensVolModifMatrix->Multiply( &dpre.Inverse() );
\r
499 //fSensVolModifMatrix->MultiplyLeft( &dpre );
\r
500 // direi che NON FUNZIONA!!!!
\r
504 // reset align object (may not be needed...)
\r
505 fgTempAlignObj.SetVolUID(0);
\r
506 fgTempAlignObj.SetSymName("");
\r
507 fgTempAlignObj.SetTranslation(0,0,0);
\r
508 fgTempAlignObj.SetRotation(0,0,0);
\r
512 // correction for SPD y-shift
\r
513 if (voluid>=2048 && voluid<4256) {
\r
514 TGeoHMatrix deltay;
\r
515 double dy[3]={0.,0.0081,0.};
\r
516 deltay.SetTranslation(dy);
\r
517 fSensVolModifMatrix->MultiplyLeft( &deltay );
\r
518 fSensVolModifMatrix->Multiply( &deltay.Inverse() );
\r
522 if (!fgTempAlignObj.SetMatrix(*fSensVolModifMatrix)) return NULL;
\r
523 fgTempAlignObj.SetVolUID(voluid);
\r
524 fgTempAlignObj.SetSymName(AliGeomManager::SymName(voluid));
\r
526 return &fgTempAlignObj;
\r
530 //-------------------------------------------------------------
\r
531 AliAlignObjParams *AliITSAlignMille2Module::GetSensitiveVolumeTotalMisalignment(UShort_t voluid, Double_t *deltalocal)
\r
533 // calculate misalignment of sens.vol. 'voluid' according with a displacement 'deltalocal'
\r
534 // of the mother volume. The misalignment is returned as AliAlignObjParams object including
\r
535 // the (evenctual) prealignment => no merging needed
\r
537 if (!IsIn(voluid)) return NULL;
\r
538 if (!gGeoManager) return NULL;
\r
540 // prepare the TGeoHMatrix
\r
541 Double_t tr[3],ang[3];
\r
542 tr[0]=deltalocal[0]; // in centimeter
\r
543 tr[1]=deltalocal[1];
\r
544 tr[2]=deltalocal[2];
\r
545 ang[0]=deltalocal[3]; // psi (X) in deg
\r
546 ang[1]=deltalocal[4]; // theta (Y)
\r
547 ang[2]=deltalocal[5]; // phi (Z)
\r
549 // reset align object (may not be needed...)
\r
550 fgTempAlignObj.SetVolUID(0);
\r
551 fgTempAlignObj.SetSymName("");
\r
552 fgTempAlignObj.SetRotation(ang[0],ang[1],ang[2]);
\r
553 fgTempAlignObj.SetTranslation(tr[0],tr[1],tr[2]);
\r
554 AliDebug(3,Form("Delta angles: psi=%f theta=%f phi=%f",ang[0],ang[1],ang[2]));
\r
556 // Gsv = Gg * Gg-1 * Gsv -> Lsv,g = Gg-1 * Gsv
\r
557 // G'sv = Gg * Dg * Lsv,g === DGsv * Gsv
\r
559 // => Dsv = (G0sv-1 * Gg * Dg * Gg-1 * GMsv) //
\r
562 // prepare the Delta matrix Dg
\r
564 fgTempAlignObj.GetMatrix(dg);
\r
567 // 1) start setting fSensVolModif = Gsv
\r
568 if (SensVolMatrix(voluid, fSensVolModifMatrix)) return NULL;
\r
569 //printf("\n1: modif=orig del sensvol\n");fSensVolModifMatrix->Print();
\r
571 // 2) set fSensVolModif = Gg-1 * Gsv
\r
572 fSensVolModifMatrix->MultiplyLeft( &fMatrix->Inverse() );
\r
573 //printf("\n2: modif=relative del sensvol\n");fSensVolModifMatrix->Print();
\r
575 // 3) set fSensVolModif = Dg * Gg-1 * Gsv
\r
576 fSensVolModifMatrix->MultiplyLeft( &dg );
\r
577 //printf("\n3: modif= delta*relative\n");fSensVolModifMatrix->Print();
\r
579 // 4) set fSensVolModif = Gg * Dg * Gg-1 * Gsv
\r
580 fSensVolModifMatrix->MultiplyLeft( fMatrix );
\r
581 //printf("\n4: modif=quasi,manca il Gsv-1...\n");fSensVolModifMatrix->Print();
\r
583 // 5) set fSensVolModif = G0sv-1 * Gg * Dg * Gg-1 * Gsv
\r
584 // qui usa l'orig anziche' la prealigned...
\r
585 if (SensVolOrigGlobalMatrix(voluid, &dg)) return NULL;
\r
586 fSensVolModifMatrix->MultiplyLeft( &dg.Inverse() );
\r
587 //printf("\n5: modif=finale\n");fSensVolModifMatrix->Print();
\r
589 // reset align object (may not be needed...)
\r
590 fgTempAlignObj.SetVolUID(0);
\r
591 fgTempAlignObj.SetSymName("");
\r
592 fgTempAlignObj.SetTranslation(0,0,0);
\r
593 fgTempAlignObj.SetRotation(0,0,0);
\r
596 // correction for SPD y-shift
\r
597 if (voluid>=2048 && voluid<4256) {
\r
598 TGeoHMatrix deltay;
\r
599 double dy[3]={0.,0.0081,0.};
\r
600 deltay.SetTranslation(dy);
\r
601 fSensVolModifMatrix->MultiplyLeft( &deltay );
\r
602 fSensVolModifMatrix->Multiply( &deltay.Inverse() );
\r
605 if (!fgTempAlignObj.SetMatrix(*fSensVolModifMatrix)) return NULL;
\r
606 fgTempAlignObj.SetVolUID(voluid);
\r
607 fgTempAlignObj.SetSymName(AliGeomManager::SymName(voluid));
\r
610 //fgTempAlignObj.Print("");
\r
612 return &fgTempAlignObj;
\r
614 //-------------------------------------------------------------
\r
616 //-------------------------------------------------------------
\r
617 AliAlignObjParams *AliITSAlignMille2Module::GetSensitiveVolumeGlobalMisalignment(UShort_t voluid, Double_t *deltalocal)
\r
619 // calculate misalignment of sens.vol. 'voluid' according with a displacement 'deltalocal'
\r
620 // of the mother volume. The misalignment is returned as AliAlignObjParams object
\r
622 if (!IsIn(voluid)) return NULL;
\r
623 if (!gGeoManager) return NULL;
\r
625 // prepare the TGeoHMatrix
\r
626 Double_t tr[3],ang[3];
\r
627 tr[0]=deltalocal[0]; // in centimeter
\r
628 tr[1]=deltalocal[1];
\r
629 tr[2]=deltalocal[2];
\r
630 ang[0]=deltalocal[3]; // psi (X) in deg
\r
631 ang[1]=deltalocal[4]; // theta (Y)
\r
632 ang[2]=deltalocal[5]; // phi (Z)
\r
634 // reset align object (may not be needed...)
\r
635 fgTempAlignObj.SetTranslation(0,0,0);
\r
636 fgTempAlignObj.SetRotation(0,0,0);
\r
638 fgTempAlignObj.SetRotation(ang[0],ang[1],ang[2]);
\r
639 fgTempAlignObj.SetTranslation(tr[0],tr[1],tr[2]);
\r
640 AliDebug(3,Form("Delta angles: psi=%f theta=%f phi=%f",ang[0],ang[1],ang[2]));
\r
642 // Gsv = Gg * Gg-1 * Gsv -> Lsv,g = Gg-1 * Gsv
\r
643 // G'sv = Gg * Dg * Lsv,g === DGsv * Gsv
\r
645 // => DGsv = (Gg * Dg * Gg-1)
\r
648 // prepare the Delta matrix Dg
\r
650 fgTempAlignObj.GetMatrix(dg);
\r
653 dg.MultiplyLeft( fMatrix );
\r
654 dg.Multiply( &fMatrix->Inverse() );
\r
656 // reset align object (may not be needed...)
\r
657 fgTempAlignObj.SetTranslation(0,0,0);
\r
658 fgTempAlignObj.SetRotation(0,0,0);
\r
660 fgTempAlignObj.SetVolUID(voluid);
\r
661 fgTempAlignObj.SetSymName(AliGeomManager::SymName(voluid));
\r
663 if (!fgTempAlignObj.SetMatrix(dg)) return NULL;
\r
665 //fgTempAlignObj.Print("");
\r
667 return &fgTempAlignObj;
\r
671 //-------------------------------------------------------------
\r
672 TGeoHMatrix *AliITSAlignMille2Module::GetSensitiveVolumeMatrix(UShort_t voluid)
\r
674 // return TGeoHMatrix of the sens.vol. 'voluid' in the current geometry
\r
675 if (SensVolMatrix(voluid,fSensVolMatrix)) return NULL;
\r
676 return fSensVolMatrix;
\r
679 //-------------------------------------------------------------
\r
680 TGeoHMatrix *AliITSAlignMille2Module::GetSensitiveVolumeOrigGlobalMatrix(UShort_t voluid)
\r
682 // return original ideal position (from AliGeomManager::GetOrigGlobalMatrix())
\r
683 if (SensVolOrigGlobalMatrix(voluid,fSensVolMatrix)) return NULL;
\r
684 return fSensVolMatrix;
\r
686 //-------------------------------------------------------------
\r
687 Int_t AliITSAlignMille2Module::SensVolMatrix(UShort_t volid, TGeoHMatrix *m)
\r
689 // set matrix for sensitive modules (SPD corrected)
\r
690 // return 0 if success
\r
692 Int_t idx=GetIndexFromVolumeID(volid);
\r
693 if (idx<0) return -1;
\r
694 if (!AliITSgeomTGeo::GetRotation(idx,rot)) return -2;
\r
695 m->SetRotation(rot);
\r
696 Double_t oLoc[3]={0,0,0};
\r
697 Double_t oGlo[3]={0,0,0};
\r
698 if (!AliITSgeomTGeo::LocalToGlobal(idx,oLoc,oGlo)) return -3;
\r
699 m->SetTranslation(oGlo);
\r
703 //-------------------------------------------------------------
\r
704 Int_t AliITSAlignMille2Module::SensVolOrigGlobalMatrix(UShort_t volid, TGeoHMatrix *m)
\r
706 // set original global matrix for sensitive modules (SPD corrected)
\r
707 // return 0 if success
\r
708 Int_t idx=GetIndexFromVolumeID(volid);
\r
709 if (idx<0) return -1;
\r
711 if (!AliGeomManager::GetOrigGlobalMatrix(AliGeomManager::SymName(volid),mo)) return -1;
\r
715 // SPD y-shift by 81 mu
\r
717 Double_t oLoc[3]={0.0,0.0081,0.0};
\r
718 Double_t oGlo[3]={0,0,0};
\r
719 m->LocalToMaster(oLoc,oGlo);
\r
720 m->SetTranslation(oGlo);
\r
726 //-------------------------------------------------------------
\r
727 UShort_t AliITSAlignMille2Module::GetVolumeIDFromSymname(const Char_t *symname) {
\r
728 /// volume ID from symname
\r
729 if (!symname) return 0;
\r
731 for (UShort_t voluid=2000; voluid<13300; voluid++) {
\r
733 AliGeomManager::ELayerID layerId = AliGeomManager::VolUIDToLayer(voluid,modId);
\r
734 if (layerId>0 && layerId<7 && modId>=0 && modId<AliGeomManager::LayerSize(layerId)) {
\r
735 if (!strcmp(symname,AliGeomManager::SymName(layerId,modId))) return voluid;
\r
742 //-------------------------------------------------------------
\r
743 UShort_t AliITSAlignMille2Module::GetVolumeIDFromIndex(Int_t index) {
\r
744 /// volume ID from index
\r
745 if (index<0 || index>2197) return 0;
\r
746 return GetVolumeIDFromSymname(AliITSgeomTGeo::GetSymName(index));
\r
749 //-------------------------------------------------------------
\r
750 void AliITSAlignMille2Module::Print(Option_t*) const
\r
753 const char* typeName[] = {"SPD","SDD","SSD"};
\r
754 printf("*** ITS SuperModule for AliITSAlignMille ***\n");
\r
755 printf("symname : %s (type: %s)\n",GetName(),fDetType<0 ? "N/A":typeName[fDetType]);
\r
756 printf("parent : %s | %d children\n",fParent ? fParent->GetName() : "N/A",GetNChildren());
\r
757 printf("volumeID : %4d | index : %4d | Geom.Params are %s\n",fVolumeID,fIndex,
\r
758 GeomParamsGlobal() ? "Global":"Local");
\r
759 printf("Factors : X=%.2f Y=%.2f Z=%.2f\n"
\r
760 "DOF: %cTx:%5d| %cTy:%5d| %cTz:%5d| %cPsi:%5d| %cTheta:%5d| %cPhi:%5d|",
\r
761 fSigmaFactor[0],fSigmaFactor[1],fSigmaFactor[2],
\r
762 IsFreeDOF(kDOFTX) ? '+':'-',fParOffs[kDOFTX],IsFreeDOF(kDOFTY) ? '+':'-',fParOffs[kDOFTY],
\r
763 IsFreeDOF(kDOFTZ) ? '+':'-',fParOffs[kDOFTZ],IsFreeDOF(kDOFPS) ? '+':'-',fParOffs[kDOFPS],
\r
764 IsFreeDOF(kDOFTH) ? '+':'-',fParOffs[kDOFTH],IsFreeDOF(kDOFPH) ? '+':'-',fParOffs[kDOFPH]);
\r
765 if (IsSDD()) printf("%cT0:%5d| %cDV:%5d|",IsFreeDOF(kDOFT0)?'+':'-',fParOffs[kDOFT0],
\r
766 IsFreeDOF(kDOFDV)?'+':'-',fParOffs[kDOFDV]);
\r
769 printf("%4d Sensitive volumes | %6d Processed Points\n",fNSensVol,fNProcPoints);
\r
770 for (Int_t i=0; i<fNSensVol; i++) printf(" voluid[%d] = %d\n",i,UShort_t(fSensVolVolumeID[i]));
\r
773 //-------------------------------------------------------------
\r
774 Bool_t AliITSAlignMille2Module::IsAlignable() const
\r
776 TGeoManager* geoManager = AliGeomManager::GetGeometry();
\r
778 AliInfo("Couldn't initialize geometry");
\r
781 return geoManager->GetAlignableEntry(GetName())!=0;
\r
784 //-------------------------------------------------------------
\r
785 void AliITSAlignMille2Module::GetLocalMatrix(TGeoHMatrix &mat) const
\r
787 // return the local matrix for transformation to its parent
\r
789 if (fParent) mat.MultiplyLeft( &fParent->GetMatrix()->Inverse() );
\r
792 //-------------------------------------------------------------
\r
793 void AliITSAlignMille2Module::AssignDetType()
\r
795 TString tp = GetName();
\r
796 if (tp.Contains("SPD",TString::kIgnoreCase)) fDetType = kSPD;
\r
797 else if (tp.Contains("SDD",TString::kIgnoreCase)) fDetType = kSDD;
\r
798 else if (tp.Contains("SSD",TString::kIgnoreCase)) fDetType = kSSD;
\r
799 else fDetType = -1;
\r
800 fNParTot = IsSDD() ? 8:6;
\r
802 fParVals = new Float_t[fNParTot];
\r
803 fParErrs = new Float_t[fNParTot];
\r
804 fParCstr = new Float_t[fNParTot];
\r
805 if (fParOffs.GetSize()<fNParTot) fParOffs.Set(fNParTot);
\r
806 for (int i=fNParTot;i--;) {
\r
807 fParVals[i] = fParErrs[i] = 0.;
\r
813 //-------------------------------------------------------------
\r
814 void AliITSAlignMille2Module::EvaluateDOF()
\r
817 for (int i=fNParTot;i--;) if (IsFreeDOF(i)) fNParFree++;
\r
820 //-------------------------------------------------------------
\r
821 void AliITSAlignMille2Module::GetSensVolGlobalParams(UShort_t volid,Double_t *t, Double_t *r)
\r
823 // return global parameters of the sensor volid
\r
824 for (int i=3;i--;) t[i] = r[i] = 0.;
\r
825 if (SensVolMatrix(volid,fSensVolMatrix)) return;
\r
826 fgTempAlignObj.SetMatrix(*fSensVolMatrix);
\r
827 fgTempAlignObj.GetPars(t,r);
\r
830 //-------------------------------------------------------------
\r
831 void AliITSAlignMille2Module::GetSensVolLocalParams(UShort_t volid,Double_t *t, Double_t *r)
\r
833 // return parameters of the sensor volid in the current module
\r
834 for (int i=3;i--;) t[i] = r[i] = 0.;
\r
835 if (SensVolMatrix(volid,fSensVolMatrix)) return;
\r
836 fSensVolMatrix->MultiplyLeft( &fMatrix->Inverse() );
\r
837 fgTempAlignObj.SetMatrix(*fSensVolMatrix);
\r
838 fgTempAlignObj.GetPars(t,r);
\r
841 //-------------------------------------------------------------
\r
842 void AliITSAlignMille2Module::GetSensVolGlobalParams(UShort_t volid,Double_t* loct,Double_t* locr,Double_t *t, Double_t *r)
\r
844 // return global parameters of the sensor volid modified by the localDelta params
\r
845 for (int i=3;i--;) t[i] = r[i] = 0.;
\r
846 if (SensVolMatrix(volid,fSensVolMatrix)) return;
\r
847 fgTempAlignObj.SetTranslation(loct[0],loct[1],loct[2]);
\r
848 fgTempAlignObj.SetRotation(locr[0],locr[1],locr[2]);
\r
850 fgTempAlignObj.GetMatrix(*fSensVolModifMatrix); // obtain local delta
\r
851 fSensVolModifMatrix->MultiplyLeft( fSensVolMatrix ); // obtain global delta
\r
852 fgTempAlignObj.SetMatrix(*fSensVolModifMatrix);
\r
853 fgTempAlignObj.GetPars(t,r); // obtain global params
\r
856 //-------------------------------------------------------------
\r
857 void AliITSAlignMille2Module::GetSensVolLocalParams(UShort_t volid,Double_t* loct,Double_t* locr,Double_t *t, Double_t *r)
\r
859 // return parameters of the sensor volid (modified by the localDelta params) in the current volume
\r
860 for (int i=3;i--;) t[i] = r[i] = 0.;
\r
861 if (SensVolMatrix(volid,fSensVolMatrix)) return;
\r
862 fgTempAlignObj.SetTranslation(loct[0],loct[1],loct[2]);
\r
863 fgTempAlignObj.SetRotation(locr[0],locr[1],locr[2]);
\r
865 fgTempAlignObj.GetMatrix(*fSensVolModifMatrix); // obtain local delta
\r
866 fSensVolModifMatrix->MultiplyLeft( fSensVolMatrix ); // obtain global delta
\r
867 fSensVolModifMatrix->MultiplyLeft( &fMatrix->Inverse() ); // obtain delta in current volume
\r
868 fgTempAlignObj.SetMatrix(*fSensVolModifMatrix);
\r
869 fgTempAlignObj.GetPars(t,r); // obtain params
\r
872 //-------------------------------------------------------------
\r
873 void AliITSAlignMille2Module::SetParVals(Double_t *vl,Int_t npar)
\r
875 for (int i=TMath::Min(npar,(Int_t)fNParTot);i--;) fParVals[i] = vl[i];
\r
878 //-------------------------------------------------------------
\r
879 void AliITSAlignMille2Module::GetGeomParamsGlo(Double_t *pars)
\r
881 // recompute parameters from local to global frame
\r
883 // is there anything to do?
\r
884 if (GeomParamsGlobal()) {for (int i=kMaxParGeom;i--;) pars[i] = fParVals[i]; return;}
\r
886 // IMPORTANT: It is assumed that the parents params are defined in a same way (local or global)
\r
887 // as for the current module. Since in the mp2 the modules are stored from parents to children,
\r
888 // it is safe to call this method in loop staring from the lowest level child, i.e. from the end
\r
889 // of the modules array.
\r
891 // DeltaGlobal = (ModifParents)*DeltaLocal*(ModifParents)^-1
\r
893 *fSensVolMatrix = *fMatrix; // current global matrix
\r
894 AliITSAlignMille2Module* parent = GetParent();
\r
896 if (parent->GeomParamsGlobal()) {
\r
897 AliError("Cannot convert params to Global when the parents are already Global\n");
\r
898 for (int i=kMaxParGeom;i--;) pars[i] = 0;
\r
901 fSensVolMatrix->MultiplyLeft( &parent->GetMatrix()->Inverse() ); // Local Matrix
\r
902 Float_t *parpar = parent->GetParVals();
\r
903 fgTempAlignObj.SetTranslation(parpar[0],parpar[1],parpar[2]);
\r
904 fgTempAlignObj.SetRotation(parpar[3],parpar[4],parpar[5]);
\r
905 fgTempAlignObj.GetMatrix(*fSensVolModifMatrix);
\r
906 fSensVolMatrix->MultiplyLeft(fSensVolModifMatrix);
\r
907 fSensVolMatrix->MultiplyLeft(parent->GetMatrix()); // global matrix after parents modifications
\r
908 parent = parent->GetParent();
\r
911 fgTempAlignObj.SetTranslation(fParVals[0],fParVals[1],fParVals[2]);
\r
912 fgTempAlignObj.SetRotation(fParVals[3],fParVals[4],fParVals[5]);
\r
913 fgTempAlignObj.GetMatrix(*fSensVolModifMatrix); // local delta matrix
\r
914 fSensVolModifMatrix->Multiply( &fSensVolMatrix->Inverse() );
\r
915 fSensVolModifMatrix->MultiplyLeft( fSensVolMatrix );
\r
916 fgTempAlignObj.SetMatrix( *fSensVolModifMatrix ); // global delta matrix
\r
917 fgTempAlignObj.GetPars(pars,pars+3);
\r
921 //-------------------------------------------------------------
\r
922 void AliITSAlignMille2Module::GetGeomParamsLoc(Double_t *pars)
\r
924 // recompute parameters from global to local frame
\r
926 // is there anything to do?
\r
927 if (!GeomParamsGlobal()) {for (int i=kMaxParGeom;i--;) pars[i] = fParVals[i]; return;}
\r
929 // IMPORTANT: It is assumed that the parents params are defined in a same way (local or global)
\r
930 // as for the current module. Since in the mp2 the modules are stored from parents to children,
\r
931 // it is safe to call this method in loop staring from the lowest level child, i.e. from the end
\r
932 // of the modules array.
\r
934 // DeltaLocal = (DeltaParents*GlobalMat)^-1*DeltaGlobal*(DeltaParents*GlobalMat)
\r
936 AliITSAlignMille2Module* parent = GetParent();
\r
937 fgTempAlignObj.SetTranslation(0.,0.,0.);
\r
938 fgTempAlignObj.SetRotation(0.,0.,0.);
\r
939 fgTempAlignObj.GetMatrix(*fSensVolMatrix); // get no-shift matrix
\r
941 while (parent) { // accumulate the product of parents global modifications
\r
942 if (!parent->GeomParamsGlobal()) {
\r
943 AliError("Cannot convert params to Local when the parents are already Local\n");
\r
944 for (int i=kMaxParGeom;i--;) pars[i] = 0;
\r
947 Float_t *parpar = parent->GetParVals();
\r
948 fgTempAlignObj.SetTranslation(parpar[0],parpar[1],parpar[2]);
\r
949 fgTempAlignObj.SetRotation(parpar[3],parpar[4],parpar[5]);
\r
950 fgTempAlignObj.GetMatrix(*fSensVolModifMatrix);
\r
951 fSensVolMatrix->Multiply(fSensVolModifMatrix);
\r
952 parent = parent->GetParent();
\r
954 // global matrix after parents modifications
\r
955 fSensVolMatrix->Multiply(fMatrix);
\r
957 fgTempAlignObj.SetTranslation(fParVals[0],fParVals[1],fParVals[2]);
\r
958 fgTempAlignObj.SetRotation(fParVals[3],fParVals[4],fParVals[5]);
\r
959 fgTempAlignObj.GetMatrix(*fSensVolModifMatrix); // global delta matrix
\r
960 fSensVolModifMatrix->MultiplyLeft( &fSensVolMatrix->Inverse() );
\r
961 fSensVolModifMatrix->Multiply( fSensVolMatrix );
\r
962 fgTempAlignObj.SetMatrix( *fSensVolModifMatrix ); // local delta matrix
\r
963 fgTempAlignObj.GetPars(pars,pars+3);
\r
968 //-------------------------------------------------------------
\r
969 void AliITSAlignMille2Module::CalcDerivDPosDPar(Int_t sensVol,const Double_t* pl, Double_t *deriv)
\r
971 // calculate jacobian of the global position vs Parameters (dPos/dParam)
\r
972 // for the point in the sensor sensVol
\r
973 const double kDel = 0.01;
\r
974 double pos0[3],pos1[3],pos2[3],pos3[3];
\r
975 double delta[kMaxParGeom];
\r
977 for (int ip=kMaxParGeom;ip--;) delta[ip] = 0;
\r
979 for (int ip=kMaxParGeom;ip--;) {
\r
982 GetSensitiveVolumeModifiedMatrix(sensVol,delta,!GeomParamsGlobal())->LocalToMaster(pl,pos0);
\r
983 delta[ip] += kDel/2;
\r
984 GetSensitiveVolumeModifiedMatrix(sensVol,delta,!GeomParamsGlobal())->LocalToMaster(pl,pos1);
\r
986 GetSensitiveVolumeModifiedMatrix(sensVol,delta,!GeomParamsGlobal())->LocalToMaster(pl,pos2);
\r
987 delta[ip] += kDel/2;
\r
988 GetSensitiveVolumeModifiedMatrix(sensVol,delta,!GeomParamsGlobal())->LocalToMaster(pl,pos3);
\r
991 double *curd = deriv + ip*3;
\r
992 for (int i=3;i--;) curd[i] = (8.*(pos2[i]-pos1[i]) - (pos3[i]-pos0[i]))/6./kDel;
\r
997 //-------------------------------------------------------------
\r
998 void AliITSAlignMille2Module::CalcDerivGloLoc(Int_t idx,Double_t *deriv)
\r
1000 // calculate derivative of global params vs local param idx: deriv[j] = dParGlo[j]/dParLoc[idx]
\r
1001 Double_t lpar[kMaxParGeom];
\r
1002 for (int i=kMaxParGeom;i--;) lpar[i] = 0.;
\r
1003 // using f(x+h),f(x-h),f(x+h/2),f(x-h2)...
\r
1004 Double_t par1[kMaxParGeom]; // f(x-h)
\r
1005 Double_t par2[kMaxParGeom]; // f(x-h/2)
\r
1006 Double_t par3[kMaxParGeom]; // f(x+h/2)
\r
1007 Double_t par4[kMaxParGeom]; // f(x+h)
\r
1009 const Double_t dpar = 1e-3;
\r
1012 lpar[idx] -= dpar;
\r
1013 GetGlobalParams(lpar,lpar+3, par1,par1+3);
\r
1016 lpar[idx] += dpar/2;
\r
1017 GetGlobalParams(lpar,lpar+3, par2,par2+3);
\r
1020 lpar[idx] += dpar;
\r
1021 GetGlobalParams(lpar,lpar+3, par3,par3+3);
\r
1024 lpar[idx] += dpar/2;
\r
1025 GetGlobalParams(lpar,lpar+3, par4,par4+3);
\r
1027 Double_t h2 = 1./(2.*dpar);
\r
1028 for (int i=kMaxParGeom;i--;) {
\r
1029 Double_t d0 = par4[i]-par1[i];
\r
1030 Double_t d2 = 2.*(par3[i]-par2[i]);
\r
1031 deriv[i] = h2*(4*d2 - d0)/3.;
\r
1032 if (TMath::Abs(deriv[i]) < 1.0e-9) deriv[i] = 0.0;
\r
1037 //-------------------------------------------------------------
\r
1038 void AliITSAlignMille2Module::CalcDerivLocGlo(Double_t *deriv)
\r
1040 // calculate derivative of local params vs global params: deriv[i][j] = dParLoc[i]/dParGlo[j]
\r
1041 Double_t gpar[kMaxParGeom];
\r
1042 for (int i=kMaxParGeom;i--;) gpar[i] = 0.;
\r
1043 // using f(x+h),f(x-h),f(x+h/2),f(x-h2)...
\r
1044 Double_t par1[kMaxParGeom]; // f(x-h)
\r
1045 Double_t par2[kMaxParGeom]; // f(x-h/2)
\r
1046 Double_t par3[kMaxParGeom]; // f(x+h/2)
\r
1047 Double_t par4[kMaxParGeom]; // f(x+h)
\r
1049 const Double_t dpar = 1e-3;
\r
1051 for (int ig=kMaxParGeom;ig--;) {
\r
1054 GetLocalParams(gpar,gpar+3, par1,par1+3);
\r
1057 gpar[ig] += dpar/2;
\r
1058 GetLocalParams(gpar,gpar+3, par2,par2+3);
\r
1062 GetLocalParams(gpar,gpar+3, par3,par3+3);
\r
1065 gpar[ig] += dpar/2;
\r
1066 GetLocalParams(gpar,gpar+3, par4,par4+3);
\r
1068 Double_t h2 = 1./(2.*dpar);
\r
1069 for (int i=kMaxParGeom;i--;) {
\r
1070 Double_t d0 = par4[i]-par1[i];
\r
1071 Double_t d2 = 2.*(par3[i]-par2[i]);
\r
1072 int idig = i*kMaxParGeom + ig;
\r
1073 deriv[idig] = h2*(4*d2 - d0)/3.;
\r
1074 if (TMath::Abs(deriv[idig]) < 1.0e-9) deriv[idig] = 0.0;
\r
1080 //________________________________________________________________________________________________________
\r
1081 void AliITSAlignMille2Module::CalcDerivGloLoc(Int_t sensVol,Int_t paridx,Double_t* derivative)
\r
1083 /// calculate numerically the derivatives of global params vs local param paridx for sensor sensVol: dPglob/dPloc_paridx
\r
1085 Double_t lpar[kMaxParGeom];
\r
1086 for (int i=kMaxParGeom;i--;) lpar[i] = 0.;
\r
1087 // using f(x+h),f(x-h),f(x+h/2),f(x-h2)...
\r
1088 Double_t par1[kMaxParGeom]; // f(x-h)
\r
1089 Double_t par2[kMaxParGeom]; // f(x-h/2)
\r
1090 Double_t par3[kMaxParGeom]; // f(x+h/2)
\r
1091 Double_t par4[kMaxParGeom]; // f(x+h)
\r
1093 const Double_t dpar = 1e-3;
\r
1096 lpar[paridx] -= dpar;
\r
1097 GetSensVolGlobalParams(sensVol,lpar,lpar+3, par1,par1+3);
\r
1100 lpar[paridx] += dpar/2;
\r
1101 GetSensVolGlobalParams(sensVol,lpar,lpar+3, par2,par2+3);
\r
1104 lpar[paridx] += dpar;
\r
1105 GetSensVolGlobalParams(sensVol,lpar,lpar+3, par3,par3+3);
\r
1108 lpar[paridx] += dpar/2;
\r
1109 GetSensVolGlobalParams(sensVol,lpar,lpar+3, par4,par4+3);
\r
1111 Double_t h2 = 1./(2.*dpar);
\r
1112 for (int i=kMaxParGeom;i--;) {
\r
1113 Double_t d0 = par4[i]-par1[i];
\r
1114 Double_t d2 = 2.*(par3[i]-par2[i]);
\r
1115 derivative[i] = h2*(4*d2 - d0)/3.;
\r
1116 if (TMath::Abs(derivative[i]) < 1.0e-9) derivative[i] = 0.0;
\r
1121 //________________________________________________________________________________________________________
\r
1122 void AliITSAlignMille2Module::CalcDerivCurLoc(Int_t sensVol,Int_t paridx,Double_t* derivative)
\r
1124 /// calculate numerically the derivatives of sensor params in the current volume vs sensor local param paridx
\r
1126 Double_t lpar[kMaxParGeom];
\r
1127 for (int i=kMaxParGeom;i--;) lpar[i] = 0.;
\r
1128 // using f(x+h),f(x-h),f(x+h/2),f(x-h2)...
\r
1129 Double_t par1[kMaxParGeom]; // f(x-h)
\r
1130 Double_t par2[kMaxParGeom]; // f(x-h/2)
\r
1131 Double_t par3[kMaxParGeom]; // f(x+h/2)
\r
1132 Double_t par4[kMaxParGeom]; // f(x+h)
\r
1134 const Double_t dpar = 1e-3;
\r
1137 lpar[paridx] -= dpar;
\r
1138 GetSensVolLocalParams(sensVol,lpar,lpar+3, par1,par1+3);
\r
1141 lpar[paridx] += dpar/2;
\r
1142 GetSensVolLocalParams(sensVol,lpar,lpar+3, par2,par2+3);
\r
1145 lpar[paridx] += dpar;
\r
1146 GetSensVolLocalParams(sensVol,lpar,lpar+3, par3,par3+3);
\r
1149 lpar[paridx] += dpar/2;
\r
1150 GetSensVolLocalParams(sensVol,lpar,lpar+3, par4,par4+3);
\r
1152 Double_t h2 = 1./(2.*dpar);
\r
1153 for (int i=kMaxParGeom;i--;) {
\r
1154 Double_t d0 = par4[i]-par1[i];
\r
1155 Double_t d2 = 2.*(par3[i]-par2[i]);
\r
1156 derivative[i] = h2*(4*d2 - d0)/3.;
\r
1157 if (TMath::Abs(derivative[i]) < 1.0e-9) derivative[i] = 0.0;
\r
1163 //-------------------------------------------------------------
\r
1164 void AliITSAlignMille2Module::GetGlobalParams(Double_t *t, Double_t *r)
\r
1166 // global parameters of the module
\r
1167 fgTempAlignObj.SetMatrix( *fMatrix );
\r
1168 fgTempAlignObj.GetPars(t,r);
\r
1171 //-------------------------------------------------------------
\r
1172 void AliITSAlignMille2Module::GetGlobalParams(const Double_t* loct, const Double_t* locr, Double_t *t, Double_t *r)
\r
1174 // global parameters of the module after the modification by local loct,locr
\r
1175 fgTempAlignObj.SetTranslation(loct[0],loct[1],loct[2]);
\r
1176 fgTempAlignObj.SetRotation(locr[0],locr[1],locr[2]);
\r
1177 fgTempAlignObj.GetMatrix(*fSensVolModifMatrix);
\r
1178 *fSensVolMatrix = *fMatrix;
\r
1179 fSensVolMatrix->Multiply(fSensVolModifMatrix);
\r
1180 fgTempAlignObj.SetMatrix(*fSensVolMatrix);
\r
1181 fgTempAlignObj.GetPars(t,r);
\r
1184 //-------------------------------------------------------------
\r
1185 void AliITSAlignMille2Module::GetLocalParams(const Double_t* glot, const Double_t* glor, Double_t *t, Double_t *r)
\r
1187 // obtain local delta parameters from global delta params
\r
1188 fgTempAlignObj.SetTranslation(glot[0],glot[1],glot[2]);
\r
1189 fgTempAlignObj.SetRotation(glor[0],glor[1],glor[2]);
\r
1190 fgTempAlignObj.GetMatrix(*fSensVolMatrix);
\r
1191 fSensVolMatrix->Multiply( fMatrix );
\r
1192 fSensVolMatrix->MultiplyLeft( &fMatrix->Inverse() );
\r
1193 fgTempAlignObj.SetMatrix(*fSensVolMatrix);
\r
1194 fgTempAlignObj.GetPars(t,r);
\r