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
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 this->TNamed::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 fNProcPoints = m.fNProcPoints;
\r
216 delete[] fParVals; fParVals = 0;
\r
217 delete[] fParErrs; fParErrs = 0;
\r
218 delete[] fParCstr; fParCstr = 0;
\r
221 fParVals = new Float_t[fNParTot];
\r
222 fParErrs = new Float_t[fNParTot];
\r
223 fParCstr = new Float_t[fNParTot];
\r
224 for (int i=m.GetNParTot();i--;) {
\r
225 fParVals[i] = m.fParVals[i];
\r
226 fParErrs[i] = m.fParErrs[i];
\r
227 fParCstr[i] = m.fParCstr[i];
\r
231 fParOffs.Set(fNParTot);
\r
232 for (int i=0;i<fNParTot;i++) fParOffs[i] = m.fParOffs[i];
\r
233 for (int i=0;i<3;i++) fSigmaFactor[i] = m.fSigmaFactor[i];
\r
234 if (fMatrix) delete fMatrix;
\r
235 fMatrix=new TGeoHMatrix(*m.GetMatrix());
\r
236 if(fSensVolMatrix) delete fSensVolMatrix;
\r
237 fSensVolMatrix = new TGeoHMatrix(*m.fSensVolMatrix);
\r
238 if(fSensVolModifMatrix) delete fSensVolModifMatrix;
\r
239 fSensVolModifMatrix = new TGeoHMatrix(*m.fSensVolModifMatrix);
\r
240 fSensVolIndex = m.fSensVolIndex;
\r
241 fSensVolVolumeID = m.fSensVolVolumeID;
\r
242 fParent = m.fParent;
\r
244 for (int i=0;i<m.GetNChildren();i++) fChildren.Add(m.GetChild(i));
\r
249 //-------------------------------------------------------------
\r
250 AliITSAlignMille2Module::~AliITSAlignMille2Module() {
\r
253 delete fSensVolMatrix;
\r
254 delete fSensVolModifMatrix;
\r
261 //-------------------------------------------------------------
\r
262 Int_t AliITSAlignMille2Module::Set(Int_t index, UShort_t volid, const char* symname,
\r
263 const TGeoHMatrix *m, Int_t nsv, const UShort_t *volidsv)
\r
265 // initialize a custom supermodule
\r
266 // index, volid, symname and matrix must be given
\r
267 // if (volidsv) add nsv sensitive volumes to the supermodules
\r
268 // return 0 if success
\r
271 AliInfo("Index must be >= 2198");
\r
275 AliInfo("VolumeID must be >= 14336");
\r
279 if (!symname) return -3;
\r
280 for (Int_t i=0; i<2198; i++) {
\r
281 if (!strcmp(symname,AliITSgeomTGeo::GetSymName(i))) {
\r
282 AliInfo("Symname already used by a Sensitive Volume");
\r
289 // can initialize needed stuffs
\r
296 fSensVolIndex.Set(nsv);
\r
297 fSensVolVolumeID.Set(nsv);
\r
298 // add sensitive volumes
\r
299 for (Int_t i=0; i<nsv; i++) AddSensitiveVolume(volidsv[i]);
\r
304 //-------------------------------------------------------------
\r
305 void AliITSAlignMille2Module::SetFreeDOF(Int_t dof,Double_t cstr)
\r
307 if (AliITSAlignMille2::IsZero(cstr)) fParCstr[dof] = 0; // fixed parameter
\r
308 else if (cstr>0) fParCstr[dof] = fgkDummyConstraint+1.; // the parameter is free and unconstrained
\r
309 else fParCstr[dof] = -cstr; // the parameter is free but constrained
\r
312 //-------------------------------------------------------------
\r
313 Bool_t AliITSAlignMille2Module::IsSensor(UShort_t voluid)
\r
315 // Does this volid correspond to sensor ?
\r
316 AliGeomManager::ELayerID layId = AliGeomManager::VolUIDToLayerSafe(voluid);
\r
317 if (layId>0 && layId<7) {
\r
318 Int_t mId = Int_t(voluid & 0x7ff);
\r
319 if( mId>=0 && mId<AliGeomManager::LayerSize(layId)) return kTRUE;
\r
324 //-------------------------------------------------------------
\r
325 Int_t AliITSAlignMille2Module::GetIndexFromVolumeID(UShort_t voluid) {
\r
326 /// index from volume ID
\r
327 AliGeomManager::ELayerID lay = AliGeomManager::VolUIDToLayer(voluid);
\r
328 if (lay<1|| lay>6) return -1;
\r
329 Int_t idx=Int_t(voluid)-2048*lay;
\r
330 if (idx>=AliGeomManager::LayerSize(lay)) return -1;
\r
331 for (Int_t ilay=1; ilay<lay; ilay++)
\r
332 idx += AliGeomManager::LayerSize(ilay);
\r
336 //-------------------------------------------------------------
\r
337 void AliITSAlignMille2Module::AddSensitiveVolume(UShort_t voluid)
\r
339 /// add a sensitive volume to this supermodule
\r
340 if (GetIndexFromVolumeID(voluid)<0) return; // bad volid
\r
342 // in principle, the correct size of fSensVol... arrays was set outside but check anyway
\r
343 if (fSensVolVolumeID.GetSize()<fNSensVol+1) {
\r
344 fSensVolVolumeID.Set(fNSensVol+1);
\r
345 fSensVolIndex.Set(fNSensVol+1);
\r
348 fSensVolVolumeID[fNSensVol] = Short_t(voluid);
\r
349 fSensVolIndex[fNSensVol] = GetIndexFromVolumeID(voluid);
\r
353 //-------------------------------------------------------------
\r
354 void AliITSAlignMille2Module::DelSensitiveVolume(Int_t at)
\r
356 // Suppress sensor at position "at"
\r
357 // in fact we are swapping with the last valid one
\r
358 int lastValid = --fNSensVol;
\r
359 int tmpv = fSensVolIndex[at];
\r
360 fSensVolIndex[at] = fSensVolIndex[lastValid];
\r
361 tmpv = fSensVolVolumeID[at];
\r
362 fSensVolVolumeID[at] = fSensVolVolumeID[lastValid];
\r
363 fSensVolVolumeID[lastValid] = tmpv;
\r
367 //-------------------------------------------------------------
\r
368 Bool_t AliITSAlignMille2Module::IsIn(UShort_t voluid) const
\r
370 /// check if voluid is defined
\r
371 if (!voluid) return kFALSE; // only positive voluid are accepted
\r
372 for (Int_t i=0; i<fNSensVol; i++) if (UShort_t(fSensVolVolumeID[i])==voluid) return kTRUE;
\r
376 //-------------------------------------------------------------
\r
377 Bool_t AliITSAlignMille2Module::BelongsTo(AliITSAlignMille2Module* parent) const
\r
379 /// check if parent contains the sensors of this volume
\r
380 if (fNSensVol<1 || fNSensVol>=parent->GetNSensitiveVolumes()) return kFALSE;
\r
381 return parent->IsIn( fSensVolVolumeID[0] );
\r
384 //-------------------------------------------------------------
\r
385 TGeoHMatrix *AliITSAlignMille2Module::GetSensitiveVolumeModifiedMatrix(UShort_t voluid, const Double_t *delta,Bool_t local)
\r
387 // modify the original TGeoHMatrix of the sensitive module 'voluid' according
\r
388 // with a delta transform. applied to the supermodule matrix
\r
389 // return NULL if error
\r
391 if (!IsIn(voluid)) return NULL;
\r
392 if (!gGeoManager) return NULL;
\r
394 // prepare the TGeoHMatrix
\r
395 Double_t tr[3],ang[3];
\r
396 tr[0]=delta[0]; // in centimeter
\r
399 ang[0]=delta[3]; // psi (X) in deg
\r
400 ang[1]=delta[4]; // theta (Y)
\r
401 ang[2]=delta[5]; // phi (Z)
\r
403 static AliAlignObjParams tempAlignObj;
\r
404 tempAlignObj.SetRotation(ang[0],ang[1],ang[2]);
\r
405 tempAlignObj.SetTranslation(tr[0],tr[1],tr[2]);
\r
406 AliDebug(3,Form("Delta angles: psi=%f theta=%f phi=%f",ang[0],ang[1],ang[2]));
\r
408 tempAlignObj.GetMatrix(hm);
\r
409 //printf("\n0: delta matrix\n");hm.Print();
\r
411 // 1) start setting fSensVolModif = fSensVol
\r
412 if (SensVolMatrix(voluid, fSensVolModifMatrix)) return NULL;
\r
415 // 2) set fSensVolModif = SensVolRel
\r
416 fSensVolModifMatrix->MultiplyLeft( &fMatrix->Inverse() );
\r
417 // 3) multiply left by delta
\r
418 fSensVolModifMatrix->MultiplyLeft( &hm );
\r
419 // 4) multiply left by fMatrix
\r
420 fSensVolModifMatrix->MultiplyLeft( fMatrix );
\r
422 else fSensVolModifMatrix->MultiplyLeft( &hm );
\r
424 return fSensVolModifMatrix;
\r
427 //-------------------------------------------------------------
\r
428 AliAlignObjParams *AliITSAlignMille2Module::GetSensitiveVolumeMisalignment(UShort_t voluid, const Double_t *deltalocal)
\r
430 // calculate misalignment of sens.vol. 'voluid' according with a displacement 'deltalocal'
\r
431 // of the mother volume. The misalignment is returned as AliAlignObjParams object
\r
433 if (!IsIn(voluid)) return NULL;
\r
434 if (!gGeoManager) return NULL;
\r
436 // prepare the TGeoHMatrix
\r
437 Double_t tr[3],ang[3];
\r
438 tr[0]=deltalocal[0]; // in centimeter
\r
439 tr[1]=deltalocal[1];
\r
440 tr[2]=deltalocal[2];
\r
441 ang[0]=deltalocal[3]; // psi (X) in deg
\r
442 ang[1]=deltalocal[4]; // theta (Y)
\r
443 ang[2]=deltalocal[5]; // phi (Z)
\r
445 static AliAlignObjParams tempAlignObj;
\r
446 tempAlignObj.SetRotation(ang[0],ang[1],ang[2]);
\r
447 tempAlignObj.SetTranslation(tr[0],tr[1],tr[2]);
\r
448 AliDebug(3,Form("Delta angles: psi=%f theta=%f phi=%f",ang[0],ang[1],ang[2]));
\r
450 return GetSensitiveVolumeMisalignment(voluid,&tempAlignObj);
\r
453 //-------------------------------------------------------------
\r
454 AliAlignObjParams *AliITSAlignMille2Module::GetSensitiveVolumeMisalignment(UShort_t voluid, const AliAlignObjParams *a)
\r
456 // return the misalignment of the sens. vol. 'voluid' corresponding with
\r
457 // a misalignment 'a' in the mother volume
\r
458 // return NULL if error
\r
460 // Gsv = Gg * Gg-1 * Gsv -> Lsv,g = Gg-1 * Gsv
\r
461 // G'sv = Gg * Dg * Lsv,g === Gsv * Dsv
\r
462 // Gg * Dg * Gg-1 * Gsv = Gsv * Gsv-1 * Gg * Dg * Gg-1 * Gsv
\r
464 // => Dsv = (Gsv-1 * Gg * Dg * Gg-1 * Gsv)
\r
467 if (!IsIn(voluid)) return NULL;
\r
468 if (!gGeoManager) return NULL;
\r
472 // prepare the Delta matrix Dg
\r
477 // 1) start setting fSensVolModif = Gsv
\r
478 if (SensVolMatrix(voluid, fSensVolModifMatrix)) return NULL;
\r
479 //printf("\n1: modif=orig del sensvol\n");fSensVolModifMatrix->Print();
\r
481 // 2) set fSensVolModif = Gg-1 * Gsv
\r
482 fSensVolModifMatrix->MultiplyLeft( &fMatrix->Inverse() );
\r
483 //printf("\n2: modif=relative del sensvol\n");fSensVolModifMatrix->Print();
\r
485 // 3) set fSensVolModif = Dg * Gg-1 * Gsv
\r
486 fSensVolModifMatrix->MultiplyLeft( &dg );
\r
487 //printf("\n3: modif= delta*relative\n");fSensVolModifMatrix->Print();
\r
489 // 4) set fSensVolModif = Gg * Dg * Gg-1 * Gsv
\r
490 fSensVolModifMatrix->MultiplyLeft( fMatrix );
\r
491 //printf("\n4: modif=quasi,manca il Gsv-1...\n");fSensVolModifMatrix->Print();
\r
493 // 5) set fSensVolModif = Gsv-1 * Gg * Dg * Gg-1 * Gsv
\r
494 if (SensVolMatrix(voluid, &dg)) return NULL;
\r
495 fSensVolModifMatrix->MultiplyLeft( &dg.Inverse() );
\r
496 //printf("\n5: modif=finale\n");fSensVolModifMatrix->Print();
\r
499 // 6) mo' fSensVolModif dovrebbe essere la Dsv(loc) t.c. G'sv = Gsv*Dsv(loc)
\r
500 // per trasformarla in Dsv(loc rispetto al Gsv0, non modificato) dovrebbe essere:
\r
501 // Dsv(loc) -> Dpre * Dsv(loc) * Dpre-1
\r
502 //TGeoHMatrix dpre; // dpre = Gsv0-1*Gsv
\r
503 //if (SensVolOrigGlobalMatrix(voluid, &dg)) return NULL;
\r
504 //if (SensVolMatrix(voluid, &dpre)) return NULL;
\r
505 //dpre.MultiplyLeft( &dg.Inverse() );
\r
506 //fSensVolModifMatrix->Multiply( &dpre.Inverse() );
\r
507 //fSensVolModifMatrix->MultiplyLeft( &dpre );
\r
508 // direi che NON FUNZIONA!!!!
\r
512 // reset align object (may not be needed...)
\r
513 static AliAlignObjParams tempAlignObj;
\r
514 tempAlignObj.SetVolUID(0);
\r
515 tempAlignObj.SetSymName("");
\r
516 tempAlignObj.SetTranslation(0,0,0);
\r
517 tempAlignObj.SetRotation(0,0,0);
\r
521 // correction for SPD y-shift
\r
522 if (voluid>=2048 && voluid<4256) {
\r
523 TGeoHMatrix deltay;
\r
524 double dy[3]={0.,0.0081,0.};
\r
525 deltay.SetTranslation(dy);
\r
526 fSensVolModifMatrix->MultiplyLeft( &deltay );
\r
527 fSensVolModifMatrix->Multiply( &deltay.Inverse() );
\r
531 if (!tempAlignObj.SetMatrix(*fSensVolModifMatrix)) return NULL;
\r
532 tempAlignObj.SetVolUID(voluid);
\r
533 tempAlignObj.SetSymName(AliGeomManager::SymName(voluid));
\r
535 return &tempAlignObj;
\r
539 //-------------------------------------------------------------
\r
540 AliAlignObjParams *AliITSAlignMille2Module::GetSensitiveVolumeTotalMisalignment(UShort_t voluid, const Double_t *deltalocal)
\r
542 // calculate misalignment of sens.vol. 'voluid' according with a displacement 'deltalocal'
\r
543 // of the mother volume. The misalignment is returned as AliAlignObjParams object including
\r
544 // the (evenctual) prealignment => no merging needed
\r
546 if (!IsIn(voluid)) return NULL;
\r
547 if (!gGeoManager) return NULL;
\r
549 // prepare the TGeoHMatrix
\r
550 Double_t tr[3],ang[3];
\r
551 tr[0]=deltalocal[0]; // in centimeter
\r
552 tr[1]=deltalocal[1];
\r
553 tr[2]=deltalocal[2];
\r
554 ang[0]=deltalocal[3]; // psi (X) in deg
\r
555 ang[1]=deltalocal[4]; // theta (Y)
\r
556 ang[2]=deltalocal[5]; // phi (Z)
\r
558 // reset align object (may not be needed...)
\r
559 static AliAlignObjParams tempAlignObj;
\r
560 tempAlignObj.SetVolUID(0);
\r
561 tempAlignObj.SetSymName("");
\r
562 tempAlignObj.SetRotation(ang[0],ang[1],ang[2]);
\r
563 tempAlignObj.SetTranslation(tr[0],tr[1],tr[2]);
\r
564 AliDebug(3,Form("Delta angles: psi=%f theta=%f phi=%f",ang[0],ang[1],ang[2]));
\r
566 // Gsv = Gg * Gg-1 * Gsv -> Lsv,g = Gg-1 * Gsv
\r
567 // G'sv = Gg * Dg * Lsv,g === DGsv * Gsv
\r
569 // => Dsv = (G0sv-1 * Gg * Dg * Gg-1 * GMsv) //
\r
572 // prepare the Delta matrix Dg
\r
574 tempAlignObj.GetMatrix(dg);
\r
577 // 1) start setting fSensVolModif = Gsv
\r
578 if (SensVolMatrix(voluid, fSensVolModifMatrix)) return NULL;
\r
579 //printf("\n1: modif=orig del sensvol\n");fSensVolModifMatrix->Print();
\r
581 // 2) set fSensVolModif = Gg-1 * Gsv
\r
582 fSensVolModifMatrix->MultiplyLeft( &fMatrix->Inverse() );
\r
583 //printf("\n2: modif=relative del sensvol\n");fSensVolModifMatrix->Print();
\r
585 // 3) set fSensVolModif = Dg * Gg-1 * Gsv
\r
586 fSensVolModifMatrix->MultiplyLeft( &dg );
\r
587 //printf("\n3: modif= delta*relative\n");fSensVolModifMatrix->Print();
\r
589 // 4) set fSensVolModif = Gg * Dg * Gg-1 * Gsv
\r
590 fSensVolModifMatrix->MultiplyLeft( fMatrix );
\r
591 //printf("\n4: modif=quasi,manca il Gsv-1...\n");fSensVolModifMatrix->Print();
\r
593 // 5) set fSensVolModif = G0sv-1 * Gg * Dg * Gg-1 * Gsv
\r
594 // qui usa l'orig anziche' la prealigned...
\r
595 if (SensVolOrigGlobalMatrix(voluid, &dg)) return NULL;
\r
596 fSensVolModifMatrix->MultiplyLeft( &dg.Inverse() );
\r
597 //printf("\n5: modif=finale\n");fSensVolModifMatrix->Print();
\r
599 // reset align object (may not be needed...)
\r
600 tempAlignObj.SetVolUID(0);
\r
601 tempAlignObj.SetSymName("");
\r
602 tempAlignObj.SetTranslation(0,0,0);
\r
603 tempAlignObj.SetRotation(0,0,0);
\r
606 // correction for SPD y-shift
\r
607 if (voluid>=2048 && voluid<4256) {
\r
608 TGeoHMatrix deltay;
\r
609 double dy[3]={0.,0.0081,0.};
\r
610 deltay.SetTranslation(dy);
\r
611 fSensVolModifMatrix->MultiplyLeft( &deltay );
\r
612 fSensVolModifMatrix->Multiply( &deltay.Inverse() );
\r
615 if (!tempAlignObj.SetMatrix(*fSensVolModifMatrix)) return NULL;
\r
616 tempAlignObj.SetVolUID(voluid);
\r
617 tempAlignObj.SetSymName(AliGeomManager::SymName(voluid));
\r
620 //tempAlignObj.Print("");
\r
622 return &tempAlignObj;
\r
624 //-------------------------------------------------------------
\r
626 //-------------------------------------------------------------
\r
627 AliAlignObjParams *AliITSAlignMille2Module::GetSensitiveVolumeGlobalMisalignment(UShort_t voluid, const Double_t *deltalocal)
\r
629 // calculate misalignment of sens.vol. 'voluid' according with a displacement 'deltalocal'
\r
630 // of the mother volume. The misalignment is returned as AliAlignObjParams object
\r
632 if (!IsIn(voluid)) return NULL;
\r
633 if (!gGeoManager) return NULL;
\r
635 // prepare the TGeoHMatrix
\r
636 Double_t tr[3],ang[3];
\r
637 tr[0]=deltalocal[0]; // in centimeter
\r
638 tr[1]=deltalocal[1];
\r
639 tr[2]=deltalocal[2];
\r
640 ang[0]=deltalocal[3]; // psi (X) in deg
\r
641 ang[1]=deltalocal[4]; // theta (Y)
\r
642 ang[2]=deltalocal[5]; // phi (Z)
\r
644 // reset align object (may not be needed...)
\r
645 static AliAlignObjParams tempAlignObj;
\r
646 tempAlignObj.SetTranslation(0,0,0);
\r
647 tempAlignObj.SetRotation(0,0,0);
\r
649 tempAlignObj.SetRotation(ang[0],ang[1],ang[2]);
\r
650 tempAlignObj.SetTranslation(tr[0],tr[1],tr[2]);
\r
651 AliDebug(3,Form("Delta angles: psi=%f theta=%f phi=%f",ang[0],ang[1],ang[2]));
\r
653 // Gsv = Gg * Gg-1 * Gsv -> Lsv,g = Gg-1 * Gsv
\r
654 // G'sv = Gg * Dg * Lsv,g === DGsv * Gsv
\r
656 // => DGsv = (Gg * Dg * Gg-1)
\r
659 // prepare the Delta matrix Dg
\r
661 tempAlignObj.GetMatrix(dg);
\r
664 dg.MultiplyLeft( fMatrix );
\r
665 dg.Multiply( &fMatrix->Inverse() );
\r
667 // reset align object (may not be needed...)
\r
668 tempAlignObj.SetTranslation(0,0,0);
\r
669 tempAlignObj.SetRotation(0,0,0);
\r
671 tempAlignObj.SetVolUID(voluid);
\r
672 tempAlignObj.SetSymName(AliGeomManager::SymName(voluid));
\r
674 if (!tempAlignObj.SetMatrix(dg)) return NULL;
\r
676 //tempAlignObj.Print("");
\r
678 return &tempAlignObj;
\r
682 //-------------------------------------------------------------
\r
683 TGeoHMatrix *AliITSAlignMille2Module::GetSensitiveVolumeMatrix(UShort_t voluid)
\r
685 // return TGeoHMatrix of the sens.vol. 'voluid' in the current geometry
\r
686 if (SensVolMatrix(voluid,fSensVolMatrix)) return NULL;
\r
687 return fSensVolMatrix;
\r
690 //-------------------------------------------------------------
\r
691 TGeoHMatrix *AliITSAlignMille2Module::GetSensitiveVolumeOrigGlobalMatrix(UShort_t voluid)
\r
693 // return original ideal position (from AliGeomManager::GetOrigGlobalMatrix())
\r
694 if (SensVolOrigGlobalMatrix(voluid,fSensVolMatrix)) return NULL;
\r
695 return fSensVolMatrix;
\r
697 //-------------------------------------------------------------
\r
698 Int_t AliITSAlignMille2Module::SensVolMatrix(UShort_t volid, TGeoHMatrix *m)
\r
700 // set matrix for sensitive modules (SPD corrected)
\r
701 // return 0 if success
\r
703 Int_t idx=GetIndexFromVolumeID(volid);
\r
704 if (idx<0) return -1;
\r
705 if (!AliITSgeomTGeo::GetRotation(idx,rot)) return -2;
\r
706 m->SetRotation(rot);
\r
707 Double_t oLoc[3]={0,0,0};
\r
708 Double_t oGlo[3]={0,0,0};
\r
709 if (!AliITSgeomTGeo::LocalToGlobal(idx,oLoc,oGlo)) return -3;
\r
710 m->SetTranslation(oGlo);
\r
714 //-------------------------------------------------------------
\r
715 Int_t AliITSAlignMille2Module::SensVolOrigGlobalMatrix(UShort_t volid, TGeoHMatrix *m)
\r
717 // set original global matrix for sensitive modules (SPD corrected)
\r
718 // return 0 if success
\r
719 Int_t idx=GetIndexFromVolumeID(volid);
\r
720 if (idx<0) return -1;
\r
722 if (!AliGeomManager::GetOrigGlobalMatrix(AliGeomManager::SymName(volid),mo)) return -1;
\r
726 // SPD y-shift by 81 mu
\r
728 Double_t oLoc[3]={0.0,0.0081,0.0};
\r
729 Double_t oGlo[3]={0,0,0};
\r
730 m->LocalToMaster(oLoc,oGlo);
\r
731 m->SetTranslation(oGlo);
\r
737 //-------------------------------------------------------------
\r
738 UShort_t AliITSAlignMille2Module::GetVolumeIDFromSymname(const Char_t *symname) {
\r
739 /// volume ID from symname
\r
740 if (!symname) return 0;
\r
742 for (UShort_t voluid=2000; voluid<13300; voluid++) {
\r
744 AliGeomManager::ELayerID layerId = AliGeomManager::VolUIDToLayer(voluid,modId);
\r
745 if (layerId>0 && layerId<7 && modId>=0 && modId<AliGeomManager::LayerSize(layerId)) {
\r
746 if (!strcmp(symname,AliGeomManager::SymName(layerId,modId))) return voluid;
\r
753 //-------------------------------------------------------------
\r
754 UShort_t AliITSAlignMille2Module::GetVolumeIDFromIndex(Int_t index) {
\r
755 /// volume ID from index
\r
756 if (index<0 || index>2197) return 0;
\r
757 return GetVolumeIDFromSymname(AliITSgeomTGeo::GetSymName(index));
\r
760 //-------------------------------------------------------------
\r
761 void AliITSAlignMille2Module::Print(Option_t*) const
\r
765 const char* typeName[] = {"SPD","SDD","SSD"};
\r
766 printf("*** ITS SuperModule for AliITSAlignMille ***\n");
\r
767 printf("symname : %s (type: %s)\n",GetName(),fDetType<0 ? "N/A":typeName[fDetType]);
\r
768 printf("parent : %s | %d children\n",fParent ? fParent->GetName() : "N/A",GetNChildren());
\r
769 printf("volumeID : %4d | index : %4d | Geom.Params are %s\n",fVolumeID,fIndex,
\r
770 GeomParamsGlobal() ? "Global":"Local");
\r
771 printf("Factors : X=%.2f Y=%.2f Z=%.2f\n"
\r
772 "DOF: %cTx:%5d| %cTy:%5d| %cTz:%5d| %cPsi:%5d| %cTheta:%5d| %cPhi:%5d|",
\r
773 fSigmaFactor[0],fSigmaFactor[1],fSigmaFactor[2],
\r
774 IsFreeDOF(kDOFTX) ? '+':'-',GetParOffset(kDOFTX),IsFreeDOF(kDOFTY) ? '+':'-',GetParOffset(kDOFTY),
\r
775 IsFreeDOF(kDOFTZ) ? '+':'-',GetParOffset(kDOFTZ),IsFreeDOF(kDOFPS) ? '+':'-',GetParOffset(kDOFPS),
\r
776 IsFreeDOF(kDOFTH) ? '+':'-',GetParOffset(kDOFTH),IsFreeDOF(kDOFPH) ? '+':'-',GetParOffset(kDOFPH));
\r
778 printf("%cT0:%5d| %cDVl:%5d| %cDVr:%5d|",IsFreeDOF(kDOFT0)?'+':'-',GetParOffset(kDOFT0),
\r
779 IsFreeDOF(kDOFDVL)?'+':'-',GetParOffset(kDOFDVL),IsFreeDOF(kDOFDVR)?'+':'-',GetParOffset(kDOFDVR));
\r
780 if (IsVDriftLRSame()) printf("(dVL=dVR)");
\r
784 printf("%4d Sensitive volumes | %6d Processed Points\n",fNSensVol,fNProcPoints);
\r
785 for (Int_t i=0; i<fNSensVol; i++) printf(" voluid[%d] = %d\n",i,UShort_t(fSensVolVolumeID[i]));
\r
788 //-------------------------------------------------------------
\r
789 Bool_t AliITSAlignMille2Module::IsAlignable() const
\r
791 // it it alignable?
\r
792 TGeoManager* geoManager = AliGeomManager::GetGeometry();
\r
794 AliInfo("Couldn't initialize geometry");
\r
797 return geoManager->GetAlignableEntry(GetName())!=0;
\r
800 //-------------------------------------------------------------
\r
801 void AliITSAlignMille2Module::GetLocalMatrix(TGeoHMatrix &mat) const
\r
803 // return the local matrix for transformation to its parent
\r
805 if (fParent) mat.MultiplyLeft( &fParent->GetMatrix()->Inverse() );
\r
808 //-------------------------------------------------------------
\r
809 void AliITSAlignMille2Module::AssignDetType()
\r
811 // assign the detector type
\r
812 TString tp = GetName();
\r
813 if (tp.Contains("SPD",TString::kIgnoreCase)) fDetType = kSPD;
\r
814 else if (tp.Contains("SDD",TString::kIgnoreCase)) fDetType = kSDD;
\r
815 else if (tp.Contains("SSD",TString::kIgnoreCase)) fDetType = kSSD;
\r
816 else fDetType = -1;
\r
817 fNParTot = IsSDD() ? kMaxParTot:kMaxParGeom;
\r
819 fParVals = new Float_t[fNParTot];
\r
820 fParErrs = new Float_t[fNParTot];
\r
821 fParCstr = new Float_t[fNParTot];
\r
822 if (fParOffs.GetSize()<fNParTot) fParOffs.Set(fNParTot);
\r
823 for (int i=fNParTot;i--;) {
\r
824 fParVals[i] = fParErrs[i] = 0.;
\r
830 //-------------------------------------------------------------
\r
831 void AliITSAlignMille2Module::EvaluateDOF()
\r
835 for (int i=fNParTot;i--;) if (IsFreeDOF(i)) fNParFree++;
\r
838 //-------------------------------------------------------------
\r
839 void AliITSAlignMille2Module::GetSensVolGlobalParams(UShort_t volid,Double_t *t, Double_t *r)
\r
841 // return global parameters of the sensor volid
\r
842 for (int i=3;i--;) t[i] = r[i] = 0.;
\r
843 if (SensVolMatrix(volid,fSensVolMatrix)) return;
\r
844 AliAlignObjParams tempAlignObj;
\r
845 tempAlignObj.SetMatrix(*fSensVolMatrix);
\r
846 tempAlignObj.GetPars(t,r);
\r
849 //-------------------------------------------------------------
\r
850 void AliITSAlignMille2Module::GetSensVolLocalParams(UShort_t volid,Double_t *t, Double_t *r)
\r
852 // return parameters of the sensor volid in the current module
\r
853 for (int i=3;i--;) t[i] = r[i] = 0.;
\r
854 if (SensVolMatrix(volid,fSensVolMatrix)) return;
\r
855 fSensVolMatrix->MultiplyLeft( &fMatrix->Inverse() );
\r
856 AliAlignObjParams tempAlignObj;
\r
857 tempAlignObj.SetMatrix(*fSensVolMatrix);
\r
858 tempAlignObj.GetPars(t,r);
\r
861 //-------------------------------------------------------------
\r
862 void AliITSAlignMille2Module::GetSensVolGlobalParams(UShort_t volid,const Double_t* loct, const Double_t* locr,Double_t *t, Double_t *r)
\r
864 // return global parameters of the sensor volid modified by the localDelta params
\r
865 for (int i=3;i--;) t[i] = r[i] = 0.;
\r
866 if (SensVolMatrix(volid,fSensVolMatrix)) return;
\r
867 AliAlignObjParams tempAlignObj;
\r
868 tempAlignObj.SetTranslation(loct[0],loct[1],loct[2]);
\r
869 tempAlignObj.SetRotation(locr[0],locr[1],locr[2]);
\r
871 tempAlignObj.GetMatrix(*fSensVolModifMatrix); // obtain local delta
\r
872 fSensVolModifMatrix->MultiplyLeft( fSensVolMatrix ); // obtain global delta
\r
873 tempAlignObj.SetMatrix(*fSensVolModifMatrix);
\r
874 tempAlignObj.GetPars(t,r); // obtain global params
\r
877 //-------------------------------------------------------------
\r
878 void AliITSAlignMille2Module::GetSensVolLocalParams(UShort_t volid,const Double_t* loct,const Double_t* locr,Double_t *t, Double_t *r)
\r
880 // return parameters of the sensor volid (modified by the localDelta params) in the current volume
\r
881 for (int i=3;i--;) t[i] = r[i] = 0.;
\r
882 if (SensVolMatrix(volid,fSensVolMatrix)) return;
\r
883 AliAlignObjParams tempAlignObj;
\r
884 tempAlignObj.SetTranslation(loct[0],loct[1],loct[2]);
\r
885 tempAlignObj.SetRotation(locr[0],locr[1],locr[2]);
\r
887 tempAlignObj.GetMatrix(*fSensVolModifMatrix); // obtain local delta
\r
888 fSensVolModifMatrix->MultiplyLeft( fSensVolMatrix ); // obtain global delta
\r
889 fSensVolModifMatrix->MultiplyLeft( &fMatrix->Inverse() ); // obtain delta in current volume
\r
890 tempAlignObj.SetMatrix(*fSensVolModifMatrix);
\r
891 tempAlignObj.GetPars(t,r); // obtain params
\r
894 //-------------------------------------------------------------
\r
895 void AliITSAlignMille2Module::SetParVals(Double_t *vl,Int_t npar)
\r
898 for (int i=TMath::Min(npar,(Int_t)fNParTot);i--;) fParVals[i] = vl[i];
\r
901 //-------------------------------------------------------------
\r
902 void AliITSAlignMille2Module::GetGeomParamsGlo(Double_t *pars)
\r
904 // recompute parameters from local to global frame
\r
906 // is there anything to do?
\r
907 if (GeomParamsGlobal()) {for (int i=kMaxParGeom;i--;) pars[i] = fParVals[i]; return;}
\r
909 // IMPORTANT: It is assumed that the parents params are defined in a same way (local or global)
\r
910 // as for the current module. Since in the mp2 the modules are stored from parents to children,
\r
911 // it is safe to call this method in loop staring from the lowest level child, i.e. from the end
\r
912 // of the modules array.
\r
914 // DeltaGlobal = (ModifParents)*DeltaLocal*(ModifParents)^-1
\r
916 *fSensVolMatrix = *fMatrix; // current global matrix
\r
917 AliAlignObjParams tempAlignObj;
\r
918 AliITSAlignMille2Module* parent = GetParent();
\r
920 if (parent->GeomParamsGlobal()) {
\r
921 AliError("Cannot convert params to Global when the parents are already Global\n");
\r
922 for (int i=kMaxParGeom;i--;) pars[i] = 0;
\r
925 fSensVolMatrix->MultiplyLeft( &parent->GetMatrix()->Inverse() ); // Local Matrix
\r
926 Float_t *parpar = parent->GetParVals();
\r
927 tempAlignObj.SetTranslation(parpar[0],parpar[1],parpar[2]);
\r
928 tempAlignObj.SetRotation(parpar[3],parpar[4],parpar[5]);
\r
929 tempAlignObj.GetMatrix(*fSensVolModifMatrix);
\r
930 fSensVolMatrix->MultiplyLeft(fSensVolModifMatrix);
\r
931 fSensVolMatrix->MultiplyLeft(parent->GetMatrix()); // global matrix after parents modifications
\r
932 parent = parent->GetParent();
\r
935 tempAlignObj.SetTranslation(fParVals[0],fParVals[1],fParVals[2]);
\r
936 tempAlignObj.SetRotation(fParVals[3],fParVals[4],fParVals[5]);
\r
937 tempAlignObj.GetMatrix(*fSensVolModifMatrix); // local delta matrix
\r
938 fSensVolModifMatrix->Multiply( &fSensVolMatrix->Inverse() );
\r
939 fSensVolModifMatrix->MultiplyLeft( fSensVolMatrix );
\r
940 tempAlignObj.SetMatrix( *fSensVolModifMatrix ); // global delta matrix
\r
941 tempAlignObj.GetPars(pars,pars+3);
\r
945 //-------------------------------------------------------------
\r
946 void AliITSAlignMille2Module::GetGeomParamsLoc(Double_t *pars)
\r
948 // recompute parameters from global to local frame
\r
950 // is there anything to do?
\r
951 if (!GeomParamsGlobal()) {for (int i=kMaxParGeom;i--;) pars[i] = fParVals[i]; return;}
\r
953 // IMPORTANT: It is assumed that the parents params are defined in a same way (local or global)
\r
954 // as for the current module. Since in the mp2 the modules are stored from parents to children,
\r
955 // it is safe to call this method in loop staring from the lowest level child, i.e. from the end
\r
956 // of the modules array.
\r
958 // DeltaLocal = (DeltaParents*GlobalMat)^-1*DeltaGlobal*(DeltaParents*GlobalMat)
\r
960 AliITSAlignMille2Module* parent = GetParent();
\r
961 AliAlignObjParams tempAlignObj;
\r
962 tempAlignObj.SetTranslation(0.,0.,0.);
\r
963 tempAlignObj.SetRotation(0.,0.,0.);
\r
964 tempAlignObj.GetMatrix(*fSensVolMatrix); // get no-shift matrix
\r
966 while (parent) { // accumulate the product of parents global modifications
\r
967 if (!parent->GeomParamsGlobal()) {
\r
968 AliError("Cannot convert params to Local when the parents are already Local\n");
\r
969 for (int i=kMaxParGeom;i--;) pars[i] = 0;
\r
972 Float_t *parpar = parent->GetParVals();
\r
973 tempAlignObj.SetTranslation(parpar[0],parpar[1],parpar[2]);
\r
974 tempAlignObj.SetRotation(parpar[3],parpar[4],parpar[5]);
\r
975 tempAlignObj.GetMatrix(*fSensVolModifMatrix);
\r
976 fSensVolMatrix->Multiply(fSensVolModifMatrix);
\r
977 parent = parent->GetParent();
\r
979 // global matrix after parents modifications
\r
980 fSensVolMatrix->Multiply(fMatrix);
\r
982 tempAlignObj.SetTranslation(fParVals[0],fParVals[1],fParVals[2]);
\r
983 tempAlignObj.SetRotation(fParVals[3],fParVals[4],fParVals[5]);
\r
984 tempAlignObj.GetMatrix(*fSensVolModifMatrix); // global delta matrix
\r
985 fSensVolModifMatrix->MultiplyLeft( &fSensVolMatrix->Inverse() );
\r
986 fSensVolModifMatrix->Multiply( fSensVolMatrix );
\r
987 tempAlignObj.SetMatrix( *fSensVolModifMatrix ); // local delta matrix
\r
988 tempAlignObj.GetPars(pars,pars+3);
\r
993 //-------------------------------------------------------------
\r
994 void AliITSAlignMille2Module::CalcDerivDPosDPar(Int_t sensVol,const Double_t* pl, Double_t *deriv)
\r
996 // calculate jacobian of the global position vs Parameters (dPos/dParam)
\r
997 // for the point in the sensor sensVol
\r
998 const double kDel = 0.01;
\r
999 double pos0[3],pos1[3],pos2[3],pos3[3];
\r
1000 double delta[kMaxParGeom];
\r
1002 for (int ip=kMaxParGeom;ip--;) delta[ip] = 0;
\r
1004 for (int ip=kMaxParGeom;ip--;) {
\r
1006 delta[ip] -= kDel;
\r
1007 GetSensitiveVolumeModifiedMatrix(sensVol,delta,!GeomParamsGlobal())->LocalToMaster(pl,pos0);
\r
1008 delta[ip] += kDel/2;
\r
1009 GetSensitiveVolumeModifiedMatrix(sensVol,delta,!GeomParamsGlobal())->LocalToMaster(pl,pos1);
\r
1010 delta[ip] += kDel;
\r
1011 GetSensitiveVolumeModifiedMatrix(sensVol,delta,!GeomParamsGlobal())->LocalToMaster(pl,pos2);
\r
1012 delta[ip] += kDel/2;
\r
1013 GetSensitiveVolumeModifiedMatrix(sensVol,delta,!GeomParamsGlobal())->LocalToMaster(pl,pos3);
\r
1016 double *curd = deriv + ip*3;
\r
1017 for (int i=3;i--;) curd[i] = (8.*(pos2[i]-pos1[i]) - (pos3[i]-pos0[i]))/6./kDel;
\r
1022 //-------------------------------------------------------------
\r
1023 void AliITSAlignMille2Module::CalcDerivGloLoc(Int_t idx,Double_t *deriv)
\r
1025 // calculate derivative of global params vs local param idx: deriv[j] = dParGlo[j]/dParLoc[idx]
\r
1026 Double_t lpar[kMaxParGeom];
\r
1027 for (int i=kMaxParGeom;i--;) lpar[i] = 0.;
\r
1028 // using f(x+h),f(x-h),f(x+h/2),f(x-h2)...
\r
1029 Double_t par1[kMaxParGeom]; // f(x-h)
\r
1030 Double_t par2[kMaxParGeom]; // f(x-h/2)
\r
1031 Double_t par3[kMaxParGeom]; // f(x+h/2)
\r
1032 Double_t par4[kMaxParGeom]; // f(x+h)
\r
1034 const Double_t dpar = 1e-3;
\r
1037 lpar[idx] -= dpar;
\r
1038 GetGlobalParams(lpar,lpar+3, par1,par1+3);
\r
1041 lpar[idx] += dpar/2;
\r
1042 GetGlobalParams(lpar,lpar+3, par2,par2+3);
\r
1045 lpar[idx] += dpar;
\r
1046 GetGlobalParams(lpar,lpar+3, par3,par3+3);
\r
1049 lpar[idx] += dpar/2;
\r
1050 GetGlobalParams(lpar,lpar+3, par4,par4+3);
\r
1052 Double_t h2 = 1./(2.*dpar);
\r
1053 for (int i=kMaxParGeom;i--;) {
\r
1054 Double_t d0 = par4[i]-par1[i];
\r
1055 Double_t d2 = 2.*(par3[i]-par2[i]);
\r
1056 deriv[i] = h2*(4*d2 - d0)/3.;
\r
1057 if (TMath::Abs(deriv[i]) < 1.0e-9) deriv[i] = 0.0;
\r
1062 //-------------------------------------------------------------
\r
1063 void AliITSAlignMille2Module::CalcDerivLocGlo(Double_t *deriv)
\r
1065 // calculate derivative of local params vs global params: deriv[i][j] = dParLoc[i]/dParGlo[j]
\r
1066 Double_t gpar[kMaxParGeom];
\r
1067 for (int i=kMaxParGeom;i--;) gpar[i] = 0.;
\r
1068 // using f(x+h),f(x-h),f(x+h/2),f(x-h2)...
\r
1069 Double_t par1[kMaxParGeom]; // f(x-h)
\r
1070 Double_t par2[kMaxParGeom]; // f(x-h/2)
\r
1071 Double_t par3[kMaxParGeom]; // f(x+h/2)
\r
1072 Double_t par4[kMaxParGeom]; // f(x+h)
\r
1074 const Double_t dpar = 1e-3;
\r
1076 for (int ig=kMaxParGeom;ig--;) {
\r
1079 GetLocalParams(gpar,gpar+3, par1,par1+3);
\r
1082 gpar[ig] += dpar/2;
\r
1083 GetLocalParams(gpar,gpar+3, par2,par2+3);
\r
1087 GetLocalParams(gpar,gpar+3, par3,par3+3);
\r
1090 gpar[ig] += dpar/2;
\r
1091 GetLocalParams(gpar,gpar+3, par4,par4+3);
\r
1093 Double_t h2 = 1./(2.*dpar);
\r
1094 for (int i=kMaxParGeom;i--;) {
\r
1095 Double_t d0 = par4[i]-par1[i];
\r
1096 Double_t d2 = 2.*(par3[i]-par2[i]);
\r
1097 int idig = i*kMaxParGeom + ig;
\r
1098 deriv[idig] = h2*(4*d2 - d0)/3.;
\r
1099 if (TMath::Abs(deriv[idig]) < 1.0e-9) deriv[idig] = 0.0;
\r
1105 //________________________________________________________________________________________________________
\r
1106 void AliITSAlignMille2Module::CalcDerivGloLoc(Int_t sensVol,Int_t paridx,Double_t* derivative)
\r
1108 /// calculate numerically the derivatives of global params vs local param paridx for sensor sensVol: dPglob/dPloc_paridx
\r
1110 Double_t lpar[kMaxParGeom];
\r
1111 for (int i=kMaxParGeom;i--;) lpar[i] = 0.;
\r
1112 // using f(x+h),f(x-h),f(x+h/2),f(x-h2)...
\r
1113 Double_t par1[kMaxParGeom]; // f(x-h)
\r
1114 Double_t par2[kMaxParGeom]; // f(x-h/2)
\r
1115 Double_t par3[kMaxParGeom]; // f(x+h/2)
\r
1116 Double_t par4[kMaxParGeom]; // f(x+h)
\r
1118 const Double_t dpar = 1e-3;
\r
1121 lpar[paridx] -= dpar;
\r
1122 GetSensVolGlobalParams(sensVol,lpar,lpar+3, par1,par1+3);
\r
1125 lpar[paridx] += dpar/2;
\r
1126 GetSensVolGlobalParams(sensVol,lpar,lpar+3, par2,par2+3);
\r
1129 lpar[paridx] += dpar;
\r
1130 GetSensVolGlobalParams(sensVol,lpar,lpar+3, par3,par3+3);
\r
1133 lpar[paridx] += dpar/2;
\r
1134 GetSensVolGlobalParams(sensVol,lpar,lpar+3, par4,par4+3);
\r
1136 Double_t h2 = 1./(2.*dpar);
\r
1137 for (int i=kMaxParGeom;i--;) {
\r
1138 Double_t d0 = par4[i]-par1[i];
\r
1139 Double_t d2 = 2.*(par3[i]-par2[i]);
\r
1140 derivative[i] = h2*(4*d2 - d0)/3.;
\r
1141 if (TMath::Abs(derivative[i]) < 1.0e-9) derivative[i] = 0.0;
\r
1146 //________________________________________________________________________________________________________
\r
1147 void AliITSAlignMille2Module::CalcDerivCurLoc(Int_t sensVol,Int_t paridx,Double_t* derivative)
\r
1149 /// calculate numerically the derivatives of sensor params in the current volume vs sensor local param paridx
\r
1151 Double_t lpar[kMaxParGeom];
\r
1152 for (int i=kMaxParGeom;i--;) lpar[i] = 0.;
\r
1153 // using f(x+h),f(x-h),f(x+h/2),f(x-h2)...
\r
1154 Double_t par1[kMaxParGeom]; // f(x-h)
\r
1155 Double_t par2[kMaxParGeom]; // f(x-h/2)
\r
1156 Double_t par3[kMaxParGeom]; // f(x+h/2)
\r
1157 Double_t par4[kMaxParGeom]; // f(x+h)
\r
1159 const Double_t dpar = 1e-3;
\r
1162 lpar[paridx] -= dpar;
\r
1163 GetSensVolLocalParams(sensVol,lpar,lpar+3, par1,par1+3);
\r
1166 lpar[paridx] += dpar/2;
\r
1167 GetSensVolLocalParams(sensVol,lpar,lpar+3, par2,par2+3);
\r
1170 lpar[paridx] += dpar;
\r
1171 GetSensVolLocalParams(sensVol,lpar,lpar+3, par3,par3+3);
\r
1174 lpar[paridx] += dpar/2;
\r
1175 GetSensVolLocalParams(sensVol,lpar,lpar+3, par4,par4+3);
\r
1177 Double_t h2 = 1./(2.*dpar);
\r
1178 for (int i=kMaxParGeom;i--;) {
\r
1179 Double_t d0 = par4[i]-par1[i];
\r
1180 Double_t d2 = 2.*(par3[i]-par2[i]);
\r
1181 derivative[i] = h2*(4*d2 - d0)/3.;
\r
1182 if (TMath::Abs(derivative[i]) < 1.0e-9) derivative[i] = 0.0;
\r
1188 //-------------------------------------------------------------
\r
1189 void AliITSAlignMille2Module::GetGlobalParams(Double_t *t, Double_t *r) const
\r
1191 // global parameters of the module
\r
1192 AliAlignObjParams tempAlignObj;
\r
1193 tempAlignObj.SetMatrix( *fMatrix );
\r
1194 tempAlignObj.GetPars(t,r);
\r
1197 //-------------------------------------------------------------
\r
1198 void AliITSAlignMille2Module::GetGlobalParams(const Double_t* loct, const Double_t* locr, Double_t *t, Double_t *r)
\r
1200 // global parameters of the module after the modification by local loct,locr
\r
1201 AliAlignObjParams tempAlignObj;
\r
1202 tempAlignObj.SetTranslation(loct[0],loct[1],loct[2]);
\r
1203 tempAlignObj.SetRotation(locr[0],locr[1],locr[2]);
\r
1204 tempAlignObj.GetMatrix(*fSensVolModifMatrix);
\r
1205 *fSensVolMatrix = *fMatrix;
\r
1206 fSensVolMatrix->Multiply(fSensVolModifMatrix);
\r
1207 tempAlignObj.SetMatrix(*fSensVolMatrix);
\r
1208 tempAlignObj.GetPars(t,r);
\r
1211 //-------------------------------------------------------------
\r
1212 void AliITSAlignMille2Module::GetLocalParams(const Double_t* glot, const Double_t* glor, Double_t *t, Double_t *r)
\r
1214 // obtain local delta parameters from global delta params
\r
1215 AliAlignObjParams tempAlignObj;
\r
1216 tempAlignObj.SetTranslation(glot[0],glot[1],glot[2]);
\r
1217 tempAlignObj.SetRotation(glor[0],glor[1],glor[2]);
\r
1218 tempAlignObj.GetMatrix(*fSensVolMatrix);
\r
1219 fSensVolMatrix->Multiply( fMatrix );
\r
1220 fSensVolMatrix->MultiplyLeft( &fMatrix->Inverse() );
\r
1221 tempAlignObj.SetMatrix(*fSensVolMatrix);
\r
1222 tempAlignObj.GetPars(t,r);
\r