Line data Source code
1 : /**************************************************************************
2 : * Copyright(c) 2007-2009, ALICE Experiment at CERN, All rights reserved. *
3 : * *
4 : * Author: The ALICE Off-line Project. *
5 : * Contributors are mentioned in the code where appropriate. *
6 : * *
7 : * Permission to use, copy, modify and distribute this software and its *
8 : * documentation strictly for non-commercial purposes is hereby granted *
9 : * without fee, provided that the above copyright notice appears in all *
10 : * copies and that both the copyright notice and this permission notice *
11 : * appear in the supporting documentation. The authors make no claims *
12 : * about the suitability of this software for any purpose. It is *
13 : * provided "as is" without express or implied warranty. *
14 : **************************************************************************/
15 :
16 : /* $Id$ */
17 : //-----------------------------------------------------------------------------
18 : /// \class AliITSAlignMille2Module
19 : /// Alignment class for the ALICE ITS detector
20 : ///
21 : /// This class is used by AliITSAlignMille to build custom supermodules
22 : /// made of ITS sensitive modules. These supermodules are then aligned
23 : ///
24 : /// Custom supermodules must have VolumeID > 14335
25 : ///
26 : /// \author M. Lunardon
27 : //-----------------------------------------------------------------------------
28 :
29 : #include <TGeoManager.h>
30 : #include <TGeoMatrix.h>
31 :
32 : #include "AliITSAlignMille2Module.h"
33 : #include "AliITSgeomTGeo.h"
34 : #include "AliGeomManager.h"
35 : #include "AliAlignObjParams.h"
36 : #include "AliLog.h"
37 : #include "AliITSAlignMille2.h"
38 :
39 : /// \cond CLASSIMP
40 116 : ClassImp(AliITSAlignMille2Module)
41 : /// \endcond
42 :
43 : #define CORHW_
44 :
45 :
46 : const Float_t AliITSAlignMille2Module::fgkDummyConstraint = 1e-2;//1.E3;
47 :
48 : //-------------------------------------------------------------
49 : AliITSAlignMille2Module::AliITSAlignMille2Module() :
50 0 : TNamed(),
51 0 : fNSensVol(0),
52 0 : fIndex(-1),
53 0 : fDetType(-1),
54 0 : fVolumeID(0),
55 0 : fNParTot(0),
56 0 : fNParFree(0),
57 0 : fParOffs(0),
58 0 : fNProcPoints(0),
59 0 : fParVals(0),
60 0 : fParErrs(0),
61 0 : fParCstr(0),
62 0 : fSensVolIndex(0),
63 0 : fSensVolVolumeID(0),
64 0 : fMatrix(NULL),
65 0 : fSensVolMatrix(NULL),
66 0 : fSensVolModifMatrix(NULL),
67 0 : fParent(NULL),
68 0 : fChildren(0)
69 0 : {
70 : /// void constructor
71 0 : fMatrix = new TGeoHMatrix;
72 0 : fSensVolMatrix = new TGeoHMatrix;
73 0 : fSensVolModifMatrix = new TGeoHMatrix;
74 0 : fSensVolIndex.Set(1);
75 0 : fSensVolVolumeID.Set(1);
76 0 : fSigmaFactor[0]=fSigmaFactor[1]=fSigmaFactor[2]=1.0;
77 0 : }
78 :
79 : //-------------------------------------------------------------
80 : AliITSAlignMille2Module::AliITSAlignMille2Module(Int_t index, UShort_t volid, const char* symname,
81 : const TGeoHMatrix *m, Int_t nsv, const UShort_t *volidsv) :
82 0 : TNamed(),
83 0 : fNSensVol(0),
84 0 : fIndex(-1),
85 0 : fDetType(-1),
86 0 : fVolumeID(0),
87 0 : fNParTot(0),
88 0 : fNParFree(0),
89 0 : fParOffs(kMaxParGeom),
90 0 : fNProcPoints(0),
91 0 : fParVals(0),
92 0 : fParErrs(0),
93 0 : fParCstr(0),
94 0 : fSensVolIndex(0),
95 0 : fSensVolVolumeID(0),
96 0 : fMatrix(NULL),
97 0 : fSensVolMatrix(NULL),
98 0 : fSensVolModifMatrix(NULL),
99 0 : fParent(NULL),
100 0 : fChildren(0)
101 0 : {
102 : /// void constructor
103 0 : fMatrix = new TGeoHMatrix;
104 0 : fSensVolMatrix = new TGeoHMatrix;
105 0 : fSensVolModifMatrix = new TGeoHMatrix;
106 0 : fSigmaFactor[0]=fSigmaFactor[1]=fSigmaFactor[2]=1.0;
107 0 : for (int i=kMaxParGeom;i--;) fParOffs[i] = -1;
108 0 : if (Set(index,volid,symname,m,nsv,volidsv)) {
109 0 : AliInfo("Error in AliITSAlignMille2Module::Set() - initializing void supermodule...");
110 : }
111 0 : AssignDetType();
112 0 : }
113 :
114 : //-------------------------------------------------------------
115 : AliITSAlignMille2Module::AliITSAlignMille2Module(UShort_t volid) :
116 0 : TNamed(),
117 0 : fNSensVol(0),
118 0 : fIndex(-1),
119 0 : fDetType(-1),
120 0 : fVolumeID(0),
121 0 : fNParTot(0),
122 0 : fNParFree(0),
123 0 : fParOffs(kMaxParGeom),
124 0 : fNProcPoints(0),
125 0 : fParVals(0),
126 0 : fParErrs(0),
127 0 : fParCstr(0),
128 0 : fSensVolIndex(0),
129 0 : fSensVolVolumeID(0),
130 0 : fMatrix(NULL),
131 0 : fSensVolMatrix(NULL),
132 0 : fSensVolModifMatrix(NULL),
133 0 : fParent(NULL),
134 0 : fChildren(0)
135 0 : {
136 : /// simple constructor building a supermodule from a single sensitive volume
137 0 : fMatrix = new TGeoHMatrix;
138 0 : fSensVolMatrix = new TGeoHMatrix;
139 0 : fSensVolModifMatrix = new TGeoHMatrix;
140 : // temporary align object, just use the rotation...
141 0 : fSensVolIndex.Set(1);
142 0 : fSensVolVolumeID.Set(1);
143 0 : fSigmaFactor[0]=fSigmaFactor[1]=fSigmaFactor[2]=1.0;
144 0 : for (int i=kMaxParGeom;i--;) fParOffs[i] = -1;
145 : //
146 0 : fIndex = GetIndexFromVolumeID(volid);
147 0 : if (fIndex>=0 && gGeoManager) { // good sensitive module and geometry loaded
148 0 : SetName(AliGeomManager::SymName(volid));
149 0 : fVolumeID = volid;
150 0 : AddSensitiveVolume(volid);
151 0 : SetSensorsProvided(kTRUE);
152 0 : if (SensVolMatrix(volid, fMatrix))
153 0 : AliInfo("Matrix not defined");
154 : }
155 : else {
156 0 : AliInfo("Wrong VolumeID or Geometry not loaded - initializing void supermodule...");
157 : }
158 0 : AssignDetType();
159 0 : }
160 :
161 :
162 : //_____________________________________________________________________________
163 : AliITSAlignMille2Module::AliITSAlignMille2Module(const AliITSAlignMille2Module &m) :
164 0 : TNamed(m),
165 0 : fNSensVol(m.fNSensVol),
166 0 : fIndex(m.fIndex),
167 0 : fDetType(m.fDetType),
168 0 : fVolumeID(m.fVolumeID),
169 0 : fNParTot(m.fNParTot),
170 0 : fNParFree(m.fNParFree),
171 0 : fParOffs(m.fNParTot),
172 0 : fNProcPoints(0),
173 0 : fParVals(0),
174 0 : fParErrs(0),
175 0 : fParCstr(0),
176 0 : fSensVolIndex(m.fSensVolIndex),
177 0 : fSensVolVolumeID(m.fSensVolVolumeID),
178 0 : fMatrix(new TGeoHMatrix(*m.GetMatrix())),
179 0 : fSensVolMatrix(new TGeoHMatrix),
180 0 : fSensVolModifMatrix(new TGeoHMatrix),
181 0 : fParent(m.fParent),
182 0 : fChildren(0)
183 0 : {
184 : // Copy constructor
185 0 : fSensVolIndex = m.fSensVolIndex;
186 0 : fSensVolVolumeID = m.fSensVolVolumeID;
187 0 : for (int i=m.fNParTot;i--;) fParOffs[i] = m.fParOffs[i];
188 0 : for (int i=3;i--;) fSigmaFactor[i] = m.fSigmaFactor[i];
189 0 : if (fNParTot) {
190 0 : fParVals = new Float_t[fNParTot];
191 0 : fParErrs = new Float_t[fNParTot];
192 0 : fParCstr = new Float_t[fNParTot];
193 0 : for (int i=fNParTot;i--;) {
194 0 : fParVals[i] = m.fParVals[i];
195 0 : fParErrs[i] = m.fParErrs[i];
196 0 : fParCstr[i] = m.fParCstr[i];
197 : }
198 0 : }
199 0 : }
200 :
201 : //_____________________________________________________________________________
202 : AliITSAlignMille2Module& AliITSAlignMille2Module::operator=(const AliITSAlignMille2Module &m)
203 : {
204 : // operator =
205 : //
206 0 : if(this==&m) return *this;
207 0 : this->TNamed::operator=(m);
208 : //
209 0 : fNSensVol=m.fNSensVol;
210 0 : fIndex=m.fIndex;
211 0 : fDetType = m.fDetType;
212 0 : fVolumeID=m.fVolumeID;
213 0 : fNParTot = m.fNParTot;
214 0 : fNParFree = m.fNParFree;
215 0 : fNProcPoints = m.fNProcPoints;
216 0 : delete[] fParVals; fParVals = 0;
217 0 : delete[] fParErrs; fParErrs = 0;
218 0 : delete[] fParCstr; fParCstr = 0;
219 : //
220 0 : if (fNParTot) {
221 0 : fParVals = new Float_t[fNParTot];
222 0 : fParErrs = new Float_t[fNParTot];
223 0 : fParCstr = new Float_t[fNParTot];
224 0 : for (int i=m.GetNParTot();i--;) {
225 0 : fParVals[i] = m.fParVals[i];
226 0 : fParErrs[i] = m.fParErrs[i];
227 0 : fParCstr[i] = m.fParCstr[i];
228 : }
229 0 : }
230 : //
231 0 : fParOffs.Set(fNParTot);
232 0 : for (int i=0;i<fNParTot;i++) fParOffs[i] = m.fParOffs[i];
233 0 : for (int i=0;i<3;i++) fSigmaFactor[i] = m.fSigmaFactor[i];
234 0 : if (fMatrix) delete fMatrix;
235 0 : fMatrix=new TGeoHMatrix(*m.GetMatrix());
236 0 : if(fSensVolMatrix) delete fSensVolMatrix;
237 0 : fSensVolMatrix = new TGeoHMatrix(*m.fSensVolMatrix);
238 0 : if(fSensVolModifMatrix) delete fSensVolModifMatrix;
239 0 : fSensVolModifMatrix = new TGeoHMatrix(*m.fSensVolModifMatrix);
240 0 : fSensVolIndex = m.fSensVolIndex;
241 0 : fSensVolVolumeID = m.fSensVolVolumeID;
242 0 : fParent = m.fParent;
243 0 : fChildren.Clear();
244 0 : for (int i=0;i<m.GetNChildren();i++) fChildren.Add(m.GetChild(i));
245 0 : return *this;
246 0 : }
247 :
248 :
249 : //-------------------------------------------------------------
250 0 : AliITSAlignMille2Module::~AliITSAlignMille2Module() {
251 : /// Destructor
252 0 : delete fMatrix;
253 0 : delete fSensVolMatrix;
254 0 : delete fSensVolModifMatrix;
255 0 : delete[] fParVals;
256 0 : delete[] fParErrs;
257 0 : delete[] fParCstr;
258 0 : fChildren.Clear();
259 0 : }
260 :
261 : //-------------------------------------------------------------
262 : Int_t AliITSAlignMille2Module::Set(Int_t index, UShort_t volid, const char* symname,
263 : const TGeoHMatrix *m, Int_t nsv, const UShort_t *volidsv)
264 : {
265 : // initialize a custom supermodule
266 : // index, volid, symname and matrix must be given
267 : // if (volidsv) add nsv sensitive volumes to the supermodules
268 : // return 0 if success
269 :
270 0 : if (index<2198) {
271 0 : AliInfo("Index must be >= 2198");
272 0 : return -1;
273 : }
274 0 : if (volid<14336) {
275 0 : AliInfo("VolumeID must be >= 14336");
276 0 : return -2;
277 : }
278 :
279 0 : if (!symname) return -3;
280 0 : for (Int_t i=0; i<2198; i++) {
281 0 : if (!strcmp(symname,AliITSgeomTGeo::GetSymName(i))) {
282 0 : AliInfo("Symname already used by a Sensitive Volume");
283 0 : return -3;
284 : }
285 : }
286 :
287 0 : if (!m) return -4;
288 :
289 : // can initialize needed stuffs
290 0 : fIndex = index;
291 0 : fVolumeID = volid;
292 0 : SetName(symname);
293 : //
294 0 : (*fMatrix) = (*m);
295 : //
296 0 : fSensVolIndex.Set(nsv);
297 0 : fSensVolVolumeID.Set(nsv);
298 : // add sensitive volumes
299 0 : for (Int_t i=0; i<nsv; i++) AddSensitiveVolume(volidsv[i]);
300 :
301 0 : return 0;
302 0 : }
303 :
304 : //-------------------------------------------------------------
305 : void AliITSAlignMille2Module::SetFreeDOF(Int_t dof,Double_t cstr)
306 : {
307 0 : if (AliITSAlignMille2::IsZero(cstr)) fParCstr[dof] = 0; // fixed parameter
308 0 : else if (cstr>0) fParCstr[dof] = fgkDummyConstraint+1.; // the parameter is free and unconstrained
309 0 : else fParCstr[dof] = -cstr; // the parameter is free but constrained
310 0 : }
311 :
312 : //-------------------------------------------------------------
313 : Bool_t AliITSAlignMille2Module::IsSensor(UShort_t voluid)
314 : {
315 : // Does this volid correspond to sensor ?
316 0 : AliGeomManager::ELayerID layId = AliGeomManager::VolUIDToLayerSafe(voluid);
317 0 : if (layId>0 && layId<7) {
318 0 : Int_t mId = Int_t(voluid & 0x7ff);
319 0 : if( mId>=0 && mId<AliGeomManager::LayerSize(layId)) return kTRUE;
320 0 : }
321 0 : return kFALSE;
322 0 : }
323 :
324 : //-------------------------------------------------------------
325 : Int_t AliITSAlignMille2Module::GetIndexFromVolumeID(UShort_t voluid) {
326 : /// index from volume ID
327 0 : AliGeomManager::ELayerID lay = AliGeomManager::VolUIDToLayer(voluid);
328 0 : if (lay<1|| lay>6) return -1;
329 0 : Int_t idx=Int_t(voluid)-2048*lay;
330 0 : if (idx>=AliGeomManager::LayerSize(lay)) return -1;
331 0 : for (Int_t ilay=1; ilay<lay; ilay++)
332 0 : idx += AliGeomManager::LayerSize(ilay);
333 0 : return idx;
334 0 : }
335 :
336 : //-------------------------------------------------------------
337 : void AliITSAlignMille2Module::AddSensitiveVolume(UShort_t voluid)
338 : {
339 : /// add a sensitive volume to this supermodule
340 0 : if (GetIndexFromVolumeID(voluid)<0) return; // bad volid
341 : //
342 : // in principle, the correct size of fSensVol... arrays was set outside but check anyway
343 0 : if (fSensVolVolumeID.GetSize()<fNSensVol+1) {
344 0 : fSensVolVolumeID.Set(fNSensVol+1);
345 0 : fSensVolIndex.Set(fNSensVol+1);
346 0 : }
347 : //
348 0 : fSensVolVolumeID[fNSensVol] = Short_t(voluid);
349 0 : fSensVolIndex[fNSensVol] = GetIndexFromVolumeID(voluid);
350 0 : fNSensVol++;
351 0 : }
352 :
353 : //-------------------------------------------------------------
354 : void AliITSAlignMille2Module::DelSensitiveVolume(Int_t at)
355 : {
356 : // Suppress sensor at position "at"
357 : // in fact we are swapping with the last valid one
358 0 : int lastValid = --fNSensVol;
359 0 : int tmpv = fSensVolIndex[at];
360 0 : fSensVolIndex[at] = fSensVolIndex[lastValid];
361 0 : tmpv = fSensVolVolumeID[at];
362 0 : fSensVolVolumeID[at] = fSensVolVolumeID[lastValid];
363 0 : fSensVolVolumeID[lastValid] = tmpv;
364 : //
365 0 : }
366 :
367 : //-------------------------------------------------------------
368 : Bool_t AliITSAlignMille2Module::IsIn(UShort_t voluid) const
369 : {
370 : /// check if voluid is defined
371 0 : if (!voluid) return kFALSE; // only positive voluid are accepted
372 0 : for (Int_t i=0; i<fNSensVol; i++) if (UShort_t(fSensVolVolumeID[i])==voluid) return kTRUE;
373 0 : return kFALSE;
374 0 : }
375 :
376 : //-------------------------------------------------------------
377 : Bool_t AliITSAlignMille2Module::BelongsTo(AliITSAlignMille2Module* parent) const
378 : {
379 : /// check if parent contains the sensors of this volume
380 0 : if (fNSensVol<1 || fNSensVol>=parent->GetNSensitiveVolumes()) return kFALSE;
381 0 : return parent->IsIn( fSensVolVolumeID[0] );
382 0 : }
383 :
384 : //-------------------------------------------------------------
385 : TGeoHMatrix *AliITSAlignMille2Module::GetSensitiveVolumeModifiedMatrix(UShort_t voluid, const Double_t *delta,Bool_t local)
386 : {
387 : // modify the original TGeoHMatrix of the sensitive module 'voluid' according
388 : // with a delta transform. applied to the supermodule matrix
389 : // return NULL if error
390 :
391 0 : if (!IsIn(voluid)) return NULL;
392 0 : if (!gGeoManager) return NULL;
393 :
394 : // prepare the TGeoHMatrix
395 : Double_t tr[3],ang[3];
396 0 : tr[0]=delta[0]; // in centimeter
397 0 : tr[1]=delta[1];
398 0 : tr[2]=delta[2];
399 0 : ang[0]=delta[3]; // psi (X) in deg
400 0 : ang[1]=delta[4]; // theta (Y)
401 0 : ang[2]=delta[5]; // phi (Z)
402 : //
403 0 : static AliAlignObjParams tempAlignObj;
404 0 : tempAlignObj.SetRotation(ang[0],ang[1],ang[2]);
405 0 : tempAlignObj.SetTranslation(tr[0],tr[1],tr[2]);
406 0 : AliDebug(3,Form("Delta angles: psi=%f theta=%f phi=%f",ang[0],ang[1],ang[2]));
407 0 : TGeoHMatrix hm;
408 0 : tempAlignObj.GetMatrix(hm);
409 : //printf("\n0: delta matrix\n");hm.Print();
410 :
411 : // 1) start setting fSensVolModif = fSensVol
412 0 : if (SensVolMatrix(voluid, fSensVolModifMatrix)) return NULL;
413 : //
414 0 : if (local) {
415 : // 2) set fSensVolModif = SensVolRel
416 0 : fSensVolModifMatrix->MultiplyLeft( &fMatrix->Inverse() );
417 : // 3) multiply left by delta
418 0 : fSensVolModifMatrix->MultiplyLeft( &hm );
419 : // 4) multiply left by fMatrix
420 0 : fSensVolModifMatrix->MultiplyLeft( fMatrix );
421 : }
422 0 : else fSensVolModifMatrix->MultiplyLeft( &hm );
423 : //
424 0 : return fSensVolModifMatrix;
425 0 : }
426 :
427 : //-------------------------------------------------------------
428 : AliAlignObjParams *AliITSAlignMille2Module::GetSensitiveVolumeMisalignment(UShort_t voluid, const Double_t *deltalocal)
429 : {
430 : // calculate misalignment of sens.vol. 'voluid' according with a displacement 'deltalocal'
431 : // of the mother volume. The misalignment is returned as AliAlignObjParams object
432 :
433 0 : if (!IsIn(voluid)) return NULL;
434 0 : if (!gGeoManager) return NULL;
435 :
436 : // prepare the TGeoHMatrix
437 : Double_t tr[3],ang[3];
438 0 : tr[0]=deltalocal[0]; // in centimeter
439 0 : tr[1]=deltalocal[1];
440 0 : tr[2]=deltalocal[2];
441 0 : ang[0]=deltalocal[3]; // psi (X) in deg
442 0 : ang[1]=deltalocal[4]; // theta (Y)
443 0 : ang[2]=deltalocal[5]; // phi (Z)
444 : //
445 0 : static AliAlignObjParams tempAlignObj;
446 0 : tempAlignObj.SetRotation(ang[0],ang[1],ang[2]);
447 0 : tempAlignObj.SetTranslation(tr[0],tr[1],tr[2]);
448 0 : AliDebug(3,Form("Delta angles: psi=%f theta=%f phi=%f",ang[0],ang[1],ang[2]));
449 : //
450 0 : return GetSensitiveVolumeMisalignment(voluid,&tempAlignObj);
451 0 : }
452 :
453 : //-------------------------------------------------------------
454 : AliAlignObjParams *AliITSAlignMille2Module::GetSensitiveVolumeMisalignment(UShort_t voluid, const AliAlignObjParams *a)
455 : {
456 : // return the misalignment of the sens. vol. 'voluid' corresponding with
457 : // a misalignment 'a' in the mother volume
458 : // return NULL if error
459 :
460 : // Gsv = Gg * Gg-1 * Gsv -> Lsv,g = Gg-1 * Gsv
461 : // G'sv = Gg * Dg * Lsv,g === Gsv * Dsv
462 : // Gg * Dg * Gg-1 * Gsv = Gsv * Gsv-1 * Gg * Dg * Gg-1 * Gsv
463 : //
464 : // => Dsv = (Gsv-1 * Gg * Dg * Gg-1 * Gsv)
465 : //
466 :
467 0 : if (!IsIn(voluid)) return NULL;
468 0 : if (!gGeoManager) return NULL;
469 :
470 : //a->Print("");
471 :
472 : // prepare the Delta matrix Dg
473 0 : TGeoHMatrix dg;
474 0 : a->GetMatrix(dg);
475 : //dg.Print();
476 :
477 : // 1) start setting fSensVolModif = Gsv
478 0 : if (SensVolMatrix(voluid, fSensVolModifMatrix)) return NULL;
479 : //printf("\n1: modif=orig del sensvol\n");fSensVolModifMatrix->Print();
480 :
481 : // 2) set fSensVolModif = Gg-1 * Gsv
482 0 : fSensVolModifMatrix->MultiplyLeft( &fMatrix->Inverse() );
483 : //printf("\n2: modif=relative del sensvol\n");fSensVolModifMatrix->Print();
484 :
485 : // 3) set fSensVolModif = Dg * Gg-1 * Gsv
486 0 : fSensVolModifMatrix->MultiplyLeft( &dg );
487 : //printf("\n3: modif= delta*relative\n");fSensVolModifMatrix->Print();
488 :
489 : // 4) set fSensVolModif = Gg * Dg * Gg-1 * Gsv
490 0 : fSensVolModifMatrix->MultiplyLeft( fMatrix );
491 : //printf("\n4: modif=quasi,manca il Gsv-1...\n");fSensVolModifMatrix->Print();
492 :
493 : // 5) set fSensVolModif = Gsv-1 * Gg * Dg * Gg-1 * Gsv
494 0 : if (SensVolMatrix(voluid, &dg)) return NULL;
495 0 : fSensVolModifMatrix->MultiplyLeft( &dg.Inverse() );
496 : //printf("\n5: modif=finale\n");fSensVolModifMatrix->Print();
497 : //
498 : // >> RS
499 : // 6) mo' fSensVolModif dovrebbe essere la Dsv(loc) t.c. G'sv = Gsv*Dsv(loc)
500 : // per trasformarla in Dsv(loc rispetto al Gsv0, non modificato) dovrebbe essere:
501 : // Dsv(loc) -> Dpre * Dsv(loc) * Dpre-1
502 : //TGeoHMatrix dpre; // dpre = Gsv0-1*Gsv
503 : //if (SensVolOrigGlobalMatrix(voluid, &dg)) return NULL;
504 : //if (SensVolMatrix(voluid, &dpre)) return NULL;
505 : //dpre.MultiplyLeft( &dg.Inverse() );
506 : //fSensVolModifMatrix->Multiply( &dpre.Inverse() );
507 : //fSensVolModifMatrix->MultiplyLeft( &dpre );
508 : // direi che NON FUNZIONA!!!!
509 :
510 : // << RS
511 :
512 : // reset align object (may not be needed...)
513 0 : static AliAlignObjParams tempAlignObj;
514 0 : tempAlignObj.SetVolUID(0);
515 0 : tempAlignObj.SetSymName("");
516 0 : tempAlignObj.SetTranslation(0,0,0);
517 0 : tempAlignObj.SetRotation(0,0,0);
518 : //
519 : // >> RS
520 : #ifdef CORHW_
521 : // correction for SPD y-shift
522 0 : if (voluid>=2048 && voluid<4256) {
523 0 : TGeoHMatrix deltay;
524 0 : double dy[3]={0.,0.0081,0.};
525 0 : deltay.SetTranslation(dy);
526 0 : fSensVolModifMatrix->MultiplyLeft( &deltay );
527 0 : fSensVolModifMatrix->Multiply( &deltay.Inverse() );
528 0 : }
529 : #endif
530 : // << RS
531 0 : if (!tempAlignObj.SetMatrix(*fSensVolModifMatrix)) return NULL;
532 0 : tempAlignObj.SetVolUID(voluid);
533 0 : tempAlignObj.SetSymName(AliGeomManager::SymName(voluid));
534 : //
535 0 : return &tempAlignObj;
536 0 : }
537 :
538 : // >> RS
539 : //-------------------------------------------------------------
540 : AliAlignObjParams *AliITSAlignMille2Module::GetSensitiveVolumeTotalMisalignment(UShort_t voluid, const Double_t *deltalocal)
541 : {
542 : // calculate misalignment of sens.vol. 'voluid' according with a displacement 'deltalocal'
543 : // of the mother volume. The misalignment is returned as AliAlignObjParams object including
544 : // the (evenctual) prealignment => no merging needed
545 :
546 0 : if (!IsIn(voluid)) return NULL;
547 0 : if (!gGeoManager) return NULL;
548 :
549 : // prepare the TGeoHMatrix
550 : Double_t tr[3],ang[3];
551 0 : tr[0]=deltalocal[0]; // in centimeter
552 0 : tr[1]=deltalocal[1];
553 0 : tr[2]=deltalocal[2];
554 0 : ang[0]=deltalocal[3]; // psi (X) in deg
555 0 : ang[1]=deltalocal[4]; // theta (Y)
556 0 : ang[2]=deltalocal[5]; // phi (Z)
557 :
558 : // reset align object (may not be needed...)
559 0 : static AliAlignObjParams tempAlignObj;
560 0 : tempAlignObj.SetVolUID(0);
561 0 : tempAlignObj.SetSymName("");
562 0 : tempAlignObj.SetRotation(ang[0],ang[1],ang[2]);
563 0 : tempAlignObj.SetTranslation(tr[0],tr[1],tr[2]);
564 0 : AliDebug(3,Form("Delta angles: psi=%f theta=%f phi=%f",ang[0],ang[1],ang[2]));
565 :
566 : // Gsv = Gg * Gg-1 * Gsv -> Lsv,g = Gg-1 * Gsv
567 : // G'sv = Gg * Dg * Lsv,g === DGsv * Gsv
568 : //
569 : // => Dsv = (G0sv-1 * Gg * Dg * Gg-1 * GMsv) //
570 : //
571 :
572 : // prepare the Delta matrix Dg
573 0 : TGeoHMatrix dg;
574 0 : tempAlignObj.GetMatrix(dg);
575 : //dg.Print();
576 :
577 : // 1) start setting fSensVolModif = Gsv
578 0 : if (SensVolMatrix(voluid, fSensVolModifMatrix)) return NULL;
579 : //printf("\n1: modif=orig del sensvol\n");fSensVolModifMatrix->Print();
580 :
581 : // 2) set fSensVolModif = Gg-1 * Gsv
582 0 : fSensVolModifMatrix->MultiplyLeft( &fMatrix->Inverse() );
583 : //printf("\n2: modif=relative del sensvol\n");fSensVolModifMatrix->Print();
584 :
585 : // 3) set fSensVolModif = Dg * Gg-1 * Gsv
586 0 : fSensVolModifMatrix->MultiplyLeft( &dg );
587 : //printf("\n3: modif= delta*relative\n");fSensVolModifMatrix->Print();
588 :
589 : // 4) set fSensVolModif = Gg * Dg * Gg-1 * Gsv
590 0 : fSensVolModifMatrix->MultiplyLeft( fMatrix );
591 : //printf("\n4: modif=quasi,manca il Gsv-1...\n");fSensVolModifMatrix->Print();
592 :
593 : // 5) set fSensVolModif = G0sv-1 * Gg * Dg * Gg-1 * Gsv
594 : // qui usa l'orig anziche' la prealigned...
595 0 : if (SensVolOrigGlobalMatrix(voluid, &dg)) return NULL;
596 0 : fSensVolModifMatrix->MultiplyLeft( &dg.Inverse() );
597 : //printf("\n5: modif=finale\n");fSensVolModifMatrix->Print();
598 :
599 : // reset align object (may not be needed...)
600 0 : tempAlignObj.SetVolUID(0);
601 0 : tempAlignObj.SetSymName("");
602 0 : tempAlignObj.SetTranslation(0,0,0);
603 0 : tempAlignObj.SetRotation(0,0,0);
604 :
605 : #ifdef CORHW_
606 : // correction for SPD y-shift
607 0 : if (voluid>=2048 && voluid<4256) {
608 0 : TGeoHMatrix deltay;
609 0 : double dy[3]={0.,0.0081,0.};
610 0 : deltay.SetTranslation(dy);
611 0 : fSensVolModifMatrix->MultiplyLeft( &deltay );
612 0 : fSensVolModifMatrix->Multiply( &deltay.Inverse() );
613 0 : }
614 : #endif
615 0 : if (!tempAlignObj.SetMatrix(*fSensVolModifMatrix)) return NULL;
616 0 : tempAlignObj.SetVolUID(voluid);
617 0 : tempAlignObj.SetSymName(AliGeomManager::SymName(voluid));
618 :
619 :
620 : //tempAlignObj.Print("");
621 :
622 0 : return &tempAlignObj;
623 0 : }
624 : //-------------------------------------------------------------
625 :
626 : //-------------------------------------------------------------
627 : AliAlignObjParams *AliITSAlignMille2Module::GetSensitiveVolumeGlobalMisalignment(UShort_t voluid, const Double_t *deltalocal)
628 : {
629 : // calculate misalignment of sens.vol. 'voluid' according with a displacement 'deltalocal'
630 : // of the mother volume. The misalignment is returned as AliAlignObjParams object
631 :
632 0 : if (!IsIn(voluid)) return NULL;
633 0 : if (!gGeoManager) return NULL;
634 :
635 : // prepare the TGeoHMatrix
636 : Double_t tr[3],ang[3];
637 0 : tr[0]=deltalocal[0]; // in centimeter
638 0 : tr[1]=deltalocal[1];
639 0 : tr[2]=deltalocal[2];
640 0 : ang[0]=deltalocal[3]; // psi (X) in deg
641 0 : ang[1]=deltalocal[4]; // theta (Y)
642 0 : ang[2]=deltalocal[5]; // phi (Z)
643 :
644 : // reset align object (may not be needed...)
645 0 : static AliAlignObjParams tempAlignObj;
646 0 : tempAlignObj.SetTranslation(0,0,0);
647 0 : tempAlignObj.SetRotation(0,0,0);
648 :
649 0 : tempAlignObj.SetRotation(ang[0],ang[1],ang[2]);
650 0 : tempAlignObj.SetTranslation(tr[0],tr[1],tr[2]);
651 0 : AliDebug(3,Form("Delta angles: psi=%f theta=%f phi=%f",ang[0],ang[1],ang[2]));
652 :
653 : // Gsv = Gg * Gg-1 * Gsv -> Lsv,g = Gg-1 * Gsv
654 : // G'sv = Gg * Dg * Lsv,g === DGsv * Gsv
655 : //
656 : // => DGsv = (Gg * Dg * Gg-1)
657 : //
658 :
659 : // prepare the Delta matrix Dg
660 0 : TGeoHMatrix dg;
661 0 : tempAlignObj.GetMatrix(dg);
662 : //dg.Print();
663 :
664 0 : dg.MultiplyLeft( fMatrix );
665 0 : dg.Multiply( &fMatrix->Inverse() );
666 :
667 : // reset align object (may not be needed...)
668 0 : tempAlignObj.SetTranslation(0,0,0);
669 0 : tempAlignObj.SetRotation(0,0,0);
670 :
671 0 : tempAlignObj.SetVolUID(voluid);
672 0 : tempAlignObj.SetSymName(AliGeomManager::SymName(voluid));
673 :
674 0 : if (!tempAlignObj.SetMatrix(dg)) return NULL;
675 :
676 : //tempAlignObj.Print("");
677 :
678 0 : return &tempAlignObj;
679 0 : }
680 : // << RS
681 :
682 : //-------------------------------------------------------------
683 : TGeoHMatrix *AliITSAlignMille2Module::GetSensitiveVolumeMatrix(UShort_t voluid)
684 : {
685 : // return TGeoHMatrix of the sens.vol. 'voluid' in the current geometry
686 0 : if (SensVolMatrix(voluid,fSensVolMatrix)) return NULL;
687 0 : return fSensVolMatrix;
688 0 : }
689 :
690 : //-------------------------------------------------------------
691 : TGeoHMatrix *AliITSAlignMille2Module::GetSensitiveVolumeOrigGlobalMatrix(UShort_t voluid)
692 : {
693 : // return original ideal position (from AliGeomManager::GetOrigGlobalMatrix())
694 0 : if (SensVolOrigGlobalMatrix(voluid,fSensVolMatrix)) return NULL;
695 0 : return fSensVolMatrix;
696 0 : }
697 : //-------------------------------------------------------------
698 : Int_t AliITSAlignMille2Module::SensVolMatrix(UShort_t volid, TGeoHMatrix *m)
699 : {
700 : // set matrix for sensitive modules (SPD corrected)
701 : // return 0 if success
702 0 : Double_t rot[9];
703 0 : Int_t idx=GetIndexFromVolumeID(volid);
704 0 : if (idx<0) return -1;
705 0 : if (!AliITSgeomTGeo::GetRotation(idx,rot)) return -2;
706 0 : m->SetRotation(rot);
707 0 : Double_t oLoc[3]={0,0,0};
708 0 : Double_t oGlo[3]={0,0,0};
709 0 : if (!AliITSgeomTGeo::LocalToGlobal(idx,oLoc,oGlo)) return -3;
710 0 : m->SetTranslation(oGlo);
711 0 : return 0;
712 0 : }
713 :
714 : //-------------------------------------------------------------
715 : Int_t AliITSAlignMille2Module::SensVolOrigGlobalMatrix(UShort_t volid, TGeoHMatrix *m)
716 : {
717 : // set original global matrix for sensitive modules (SPD corrected)
718 : // return 0 if success
719 0 : Int_t idx=GetIndexFromVolumeID(volid);
720 0 : if (idx<0) return -1;
721 0 : TGeoHMatrix mo;
722 0 : if (!AliGeomManager::GetOrigGlobalMatrix(AliGeomManager::SymName(volid),mo)) return -1;
723 0 : (*m)=mo;
724 : //
725 : #ifdef CORHW_
726 : // SPD y-shift by 81 mu
727 0 : if (volid<5000) {
728 0 : Double_t oLoc[3]={0.0,0.0081,0.0};
729 0 : Double_t oGlo[3]={0,0,0};
730 0 : m->LocalToMaster(oLoc,oGlo);
731 0 : m->SetTranslation(oGlo);
732 0 : }
733 : #endif
734 0 : return 0;
735 0 : }
736 :
737 : //-------------------------------------------------------------
738 : UShort_t AliITSAlignMille2Module::GetVolumeIDFromSymname(const Char_t *symname) {
739 : /// volume ID from symname
740 0 : if (!symname) return 0;
741 :
742 0 : for (UShort_t voluid=2000; voluid<13300; voluid++) {
743 0 : Int_t modId;
744 0 : AliGeomManager::ELayerID layerId = AliGeomManager::VolUIDToLayer(voluid,modId);
745 0 : if (layerId>0 && layerId<7 && modId>=0 && modId<AliGeomManager::LayerSize(layerId)) {
746 0 : if (!strcmp(symname,AliGeomManager::SymName(layerId,modId))) return voluid;
747 : }
748 0 : }
749 :
750 0 : return 0;
751 0 : }
752 :
753 : //-------------------------------------------------------------
754 : UShort_t AliITSAlignMille2Module::GetVolumeIDFromIndex(Int_t index) {
755 : /// volume ID from index
756 0 : if (index<0 || index>2197) return 0;
757 0 : return GetVolumeIDFromSymname(AliITSgeomTGeo::GetSymName(index));
758 0 : }
759 :
760 : //-------------------------------------------------------------
761 : void AliITSAlignMille2Module::Print(Option_t*) const
762 : {
763 : // print data
764 : //
765 0 : const char* typeName[] = {"SPD","SDD","SSD"};
766 0 : printf("*** ITS SuperModule for AliITSAlignMille ***\n");
767 0 : printf("symname : %s (type: %s)\n",GetName(),fDetType<0 ? "N/A":typeName[fDetType]);
768 0 : printf("parent : %s | %d children\n",fParent ? fParent->GetName() : "N/A",GetNChildren());
769 0 : printf("volumeID : %4d | index : %4d | Geom.Params are %s\n",fVolumeID,fIndex,
770 0 : GeomParamsGlobal() ? "Global":"Local");
771 0 : printf("Factors : X=%.2f Y=%.2f Z=%.2f\n"
772 : "DOF: %cTx:%5d| %cTy:%5d| %cTz:%5d| %cPsi:%5d| %cTheta:%5d| %cPhi:%5d|",
773 0 : fSigmaFactor[0],fSigmaFactor[1],fSigmaFactor[2],
774 0 : IsFreeDOF(kDOFTX) ? '+':'-',GetParOffset(kDOFTX),IsFreeDOF(kDOFTY) ? '+':'-',GetParOffset(kDOFTY),
775 0 : IsFreeDOF(kDOFTZ) ? '+':'-',GetParOffset(kDOFTZ),IsFreeDOF(kDOFPS) ? '+':'-',GetParOffset(kDOFPS),
776 0 : IsFreeDOF(kDOFTH) ? '+':'-',GetParOffset(kDOFTH),IsFreeDOF(kDOFPH) ? '+':'-',GetParOffset(kDOFPH));
777 0 : if (IsSDD()) {
778 0 : printf("%cT0:%5d| %cDVl:%5d| %cDVr:%5d|",IsFreeDOF(kDOFT0)?'+':'-',GetParOffset(kDOFT0),
779 0 : IsFreeDOF(kDOFDVL)?'+':'-',GetParOffset(kDOFDVL),IsFreeDOF(kDOFDVR)?'+':'-',GetParOffset(kDOFDVR));
780 0 : if (IsVDriftLRSame()) printf("(dVL=dVR)");
781 : }
782 0 : printf("\n");
783 0 : fMatrix->Print();
784 0 : printf("%4d Sensitive volumes | %6d Processed Points\n",fNSensVol,fNProcPoints);
785 0 : for (Int_t i=0; i<fNSensVol; i++) printf(" voluid[%d] = %d\n",i,UShort_t(fSensVolVolumeID[i]));
786 0 : }
787 :
788 : //-------------------------------------------------------------
789 : Bool_t AliITSAlignMille2Module::IsAlignable() const
790 : {
791 : // it it alignable?
792 0 : TGeoManager* geoManager = AliGeomManager::GetGeometry();
793 0 : if (!geoManager) {
794 0 : AliInfo("Couldn't initialize geometry");
795 0 : return kFALSE;
796 : }
797 0 : return geoManager->GetAlignableEntry(GetName())!=0;
798 0 : }
799 :
800 : //-------------------------------------------------------------
801 : void AliITSAlignMille2Module::GetLocalMatrix(TGeoHMatrix &mat) const
802 : {
803 : // return the local matrix for transformation to its parent
804 0 : mat = *fMatrix;
805 0 : if (fParent) mat.MultiplyLeft( &fParent->GetMatrix()->Inverse() );
806 0 : }
807 :
808 : //-------------------------------------------------------------
809 : void AliITSAlignMille2Module::AssignDetType()
810 : {
811 : // assign the detector type
812 0 : TString tp = GetName();
813 0 : if (tp.Contains("SPD",TString::kIgnoreCase)) fDetType = kSPD;
814 0 : else if (tp.Contains("SDD",TString::kIgnoreCase)) fDetType = kSDD;
815 0 : else if (tp.Contains("SSD",TString::kIgnoreCase)) fDetType = kSSD;
816 0 : else fDetType = -1;
817 0 : fNParTot = IsSDD() ? kMaxParTot:kMaxParGeom;
818 0 : fNParFree = 0;
819 0 : fParVals = new Float_t[fNParTot];
820 0 : fParErrs = new Float_t[fNParTot];
821 0 : fParCstr = new Float_t[fNParTot];
822 0 : if (fParOffs.GetSize()<fNParTot) fParOffs.Set(fNParTot);
823 0 : for (int i=fNParTot;i--;) {
824 0 : fParVals[i] = fParErrs[i] = 0.;
825 0 : fParCstr[i] = 0.;
826 0 : fParOffs[i] = -1;
827 : }
828 0 : }
829 :
830 : //-------------------------------------------------------------
831 : void AliITSAlignMille2Module::EvaluateDOF()
832 : {
833 : // count d.o.f.
834 0 : fNParFree = 0;
835 0 : for (int i=fNParTot;i--;) if (IsFreeDOF(i)) fNParFree++;
836 0 : }
837 :
838 : //-------------------------------------------------------------
839 : void AliITSAlignMille2Module::GetSensVolGlobalParams(UShort_t volid,Double_t *t, Double_t *r)
840 : {
841 : // return global parameters of the sensor volid
842 0 : for (int i=3;i--;) t[i] = r[i] = 0.;
843 0 : if (SensVolMatrix(volid,fSensVolMatrix)) return;
844 0 : AliAlignObjParams tempAlignObj;
845 0 : tempAlignObj.SetMatrix(*fSensVolMatrix);
846 0 : tempAlignObj.GetPars(t,r);
847 0 : }
848 :
849 : //-------------------------------------------------------------
850 : void AliITSAlignMille2Module::GetSensVolLocalParams(UShort_t volid,Double_t *t, Double_t *r)
851 : {
852 : // return parameters of the sensor volid in the current module
853 0 : for (int i=3;i--;) t[i] = r[i] = 0.;
854 0 : if (SensVolMatrix(volid,fSensVolMatrix)) return;
855 0 : fSensVolMatrix->MultiplyLeft( &fMatrix->Inverse() );
856 0 : AliAlignObjParams tempAlignObj;
857 0 : tempAlignObj.SetMatrix(*fSensVolMatrix);
858 0 : tempAlignObj.GetPars(t,r);
859 0 : }
860 :
861 : //-------------------------------------------------------------
862 : void AliITSAlignMille2Module::GetSensVolGlobalParams(UShort_t volid,const Double_t* loct, const Double_t* locr,Double_t *t, Double_t *r)
863 : {
864 : // return global parameters of the sensor volid modified by the localDelta params
865 0 : for (int i=3;i--;) t[i] = r[i] = 0.;
866 0 : if (SensVolMatrix(volid,fSensVolMatrix)) return;
867 0 : AliAlignObjParams tempAlignObj;
868 0 : tempAlignObj.SetTranslation(loct[0],loct[1],loct[2]);
869 0 : tempAlignObj.SetRotation(locr[0],locr[1],locr[2]);
870 : //
871 0 : tempAlignObj.GetMatrix(*fSensVolModifMatrix); // obtain local delta
872 0 : fSensVolModifMatrix->MultiplyLeft( fSensVolMatrix ); // obtain global delta
873 0 : tempAlignObj.SetMatrix(*fSensVolModifMatrix);
874 0 : tempAlignObj.GetPars(t,r); // obtain global params
875 0 : }
876 :
877 : //-------------------------------------------------------------
878 : void AliITSAlignMille2Module::GetSensVolLocalParams(UShort_t volid,const Double_t* loct,const Double_t* locr,Double_t *t, Double_t *r)
879 : {
880 : // return parameters of the sensor volid (modified by the localDelta params) in the current volume
881 0 : for (int i=3;i--;) t[i] = r[i] = 0.;
882 0 : if (SensVolMatrix(volid,fSensVolMatrix)) return;
883 0 : AliAlignObjParams tempAlignObj;
884 0 : tempAlignObj.SetTranslation(loct[0],loct[1],loct[2]);
885 0 : tempAlignObj.SetRotation(locr[0],locr[1],locr[2]);
886 : //
887 0 : tempAlignObj.GetMatrix(*fSensVolModifMatrix); // obtain local delta
888 0 : fSensVolModifMatrix->MultiplyLeft( fSensVolMatrix ); // obtain global delta
889 0 : fSensVolModifMatrix->MultiplyLeft( &fMatrix->Inverse() ); // obtain delta in current volume
890 0 : tempAlignObj.SetMatrix(*fSensVolModifMatrix);
891 0 : tempAlignObj.GetPars(t,r); // obtain params
892 0 : }
893 :
894 : //-------------------------------------------------------------
895 : void AliITSAlignMille2Module::SetParVals(Double_t *vl,Int_t npar)
896 : {
897 : // set parameters
898 0 : for (int i=TMath::Min(npar,(Int_t)fNParTot);i--;) fParVals[i] = vl[i];
899 0 : }
900 :
901 : //-------------------------------------------------------------
902 : void AliITSAlignMille2Module::GetGeomParamsGlo(Double_t *pars)
903 : {
904 : // recompute parameters from local to global frame
905 : //
906 : // is there anything to do?
907 0 : if (GeomParamsGlobal()) {for (int i=kMaxParGeom;i--;) pars[i] = fParVals[i]; return;}
908 : //
909 : // IMPORTANT: It is assumed that the parents params are defined in a same way (local or global)
910 : // as for the current module. Since in the mp2 the modules are stored from parents to children,
911 : // it is safe to call this method in loop staring from the lowest level child, i.e. from the end
912 : // of the modules array.
913 : //
914 : // DeltaGlobal = (ModifParents)*DeltaLocal*(ModifParents)^-1
915 : //
916 0 : *fSensVolMatrix = *fMatrix; // current global matrix
917 0 : AliAlignObjParams tempAlignObj;
918 0 : AliITSAlignMille2Module* parent = GetParent();
919 0 : while (parent) {
920 0 : if (parent->GeomParamsGlobal()) {
921 0 : AliError("Cannot convert params to Global when the parents are already Global\n");
922 0 : for (int i=kMaxParGeom;i--;) pars[i] = 0;
923 0 : return;
924 : }
925 0 : fSensVolMatrix->MultiplyLeft( &parent->GetMatrix()->Inverse() ); // Local Matrix
926 0 : Float_t *parpar = parent->GetParVals();
927 0 : tempAlignObj.SetTranslation(parpar[0],parpar[1],parpar[2]);
928 0 : tempAlignObj.SetRotation(parpar[3],parpar[4],parpar[5]);
929 0 : tempAlignObj.GetMatrix(*fSensVolModifMatrix);
930 0 : fSensVolMatrix->MultiplyLeft(fSensVolModifMatrix);
931 0 : fSensVolMatrix->MultiplyLeft(parent->GetMatrix()); // global matrix after parents modifications
932 0 : parent = parent->GetParent();
933 : }
934 : //
935 0 : tempAlignObj.SetTranslation(fParVals[0],fParVals[1],fParVals[2]);
936 0 : tempAlignObj.SetRotation(fParVals[3],fParVals[4],fParVals[5]);
937 0 : tempAlignObj.GetMatrix(*fSensVolModifMatrix); // local delta matrix
938 0 : fSensVolModifMatrix->Multiply( &fSensVolMatrix->Inverse() );
939 0 : fSensVolModifMatrix->MultiplyLeft( fSensVolMatrix );
940 0 : tempAlignObj.SetMatrix( *fSensVolModifMatrix ); // global delta matrix
941 0 : tempAlignObj.GetPars(pars,pars+3);
942 : //
943 0 : }
944 :
945 : //-------------------------------------------------------------
946 : void AliITSAlignMille2Module::GetGeomParamsLoc(Double_t *pars)
947 : {
948 : // recompute parameters from global to local frame
949 : //
950 : // is there anything to do?
951 0 : if (!GeomParamsGlobal()) {for (int i=kMaxParGeom;i--;) pars[i] = fParVals[i]; return;}
952 : //
953 : // IMPORTANT: It is assumed that the parents params are defined in a same way (local or global)
954 : // as for the current module. Since in the mp2 the modules are stored from parents to children,
955 : // it is safe to call this method in loop staring from the lowest level child, i.e. from the end
956 : // of the modules array.
957 : //
958 : // DeltaLocal = (DeltaParents*GlobalMat)^-1*DeltaGlobal*(DeltaParents*GlobalMat)
959 : //
960 0 : AliITSAlignMille2Module* parent = GetParent();
961 0 : AliAlignObjParams tempAlignObj;
962 0 : tempAlignObj.SetTranslation(0.,0.,0.);
963 0 : tempAlignObj.SetRotation(0.,0.,0.);
964 0 : tempAlignObj.GetMatrix(*fSensVolMatrix); // get no-shift matrix
965 : //
966 0 : while (parent) { // accumulate the product of parents global modifications
967 0 : if (!parent->GeomParamsGlobal()) {
968 0 : AliError("Cannot convert params to Local when the parents are already Local\n");
969 0 : for (int i=kMaxParGeom;i--;) pars[i] = 0;
970 0 : return;
971 : }
972 0 : Float_t *parpar = parent->GetParVals();
973 0 : tempAlignObj.SetTranslation(parpar[0],parpar[1],parpar[2]);
974 0 : tempAlignObj.SetRotation(parpar[3],parpar[4],parpar[5]);
975 0 : tempAlignObj.GetMatrix(*fSensVolModifMatrix);
976 0 : fSensVolMatrix->Multiply(fSensVolModifMatrix);
977 0 : parent = parent->GetParent();
978 : }
979 : // global matrix after parents modifications
980 0 : fSensVolMatrix->Multiply(fMatrix);
981 : //
982 0 : tempAlignObj.SetTranslation(fParVals[0],fParVals[1],fParVals[2]);
983 0 : tempAlignObj.SetRotation(fParVals[3],fParVals[4],fParVals[5]);
984 0 : tempAlignObj.GetMatrix(*fSensVolModifMatrix); // global delta matrix
985 0 : fSensVolModifMatrix->MultiplyLeft( &fSensVolMatrix->Inverse() );
986 0 : fSensVolModifMatrix->Multiply( fSensVolMatrix );
987 0 : tempAlignObj.SetMatrix( *fSensVolModifMatrix ); // local delta matrix
988 0 : tempAlignObj.GetPars(pars,pars+3);
989 : //
990 0 : }
991 :
992 :
993 : //-------------------------------------------------------------
994 : void AliITSAlignMille2Module::CalcDerivDPosDPar(Int_t sensVol,const Double_t* pl, Double_t *deriv)
995 : {
996 : // calculate jacobian of the global position vs Parameters (dPos/dParam)
997 : // for the point in the sensor sensVol
998 : const double kDel = 0.01;
999 0 : double pos0[3],pos1[3],pos2[3],pos3[3];
1000 0 : double delta[kMaxParGeom];
1001 : //
1002 0 : for (int ip=kMaxParGeom;ip--;) delta[ip] = 0;
1003 : //
1004 0 : for (int ip=kMaxParGeom;ip--;) {
1005 : //
1006 0 : delta[ip] -= kDel;
1007 0 : GetSensitiveVolumeModifiedMatrix(sensVol,delta,!GeomParamsGlobal())->LocalToMaster(pl,pos0);
1008 0 : delta[ip] += kDel/2;
1009 0 : GetSensitiveVolumeModifiedMatrix(sensVol,delta,!GeomParamsGlobal())->LocalToMaster(pl,pos1);
1010 0 : delta[ip] += kDel;
1011 0 : GetSensitiveVolumeModifiedMatrix(sensVol,delta,!GeomParamsGlobal())->LocalToMaster(pl,pos2);
1012 0 : delta[ip] += kDel/2;
1013 0 : GetSensitiveVolumeModifiedMatrix(sensVol,delta,!GeomParamsGlobal())->LocalToMaster(pl,pos3);
1014 : //
1015 0 : delta[ip] = 0;
1016 0 : double *curd = deriv + ip*3;
1017 0 : for (int i=3;i--;) curd[i] = (8.*(pos2[i]-pos1[i]) - (pos3[i]-pos0[i]))/6./kDel;
1018 : }
1019 : //
1020 0 : }
1021 :
1022 : //-------------------------------------------------------------
1023 : void AliITSAlignMille2Module::CalcDerivGloLoc(Int_t idx,Double_t *deriv)
1024 : {
1025 : // calculate derivative of global params vs local param idx: deriv[j] = dParGlo[j]/dParLoc[idx]
1026 0 : Double_t lpar[kMaxParGeom];
1027 0 : for (int i=kMaxParGeom;i--;) lpar[i] = 0.;
1028 : // using f(x+h),f(x-h),f(x+h/2),f(x-h2)...
1029 0 : Double_t par1[kMaxParGeom]; // f(x-h)
1030 0 : Double_t par2[kMaxParGeom]; // f(x-h/2)
1031 0 : Double_t par3[kMaxParGeom]; // f(x+h/2)
1032 0 : Double_t par4[kMaxParGeom]; // f(x+h)
1033 : //
1034 : const Double_t dpar = 1e-3;
1035 : //
1036 : // first values
1037 0 : lpar[idx] -= dpar;
1038 0 : GetGlobalParams(lpar,lpar+3, par1,par1+3);
1039 : //
1040 : // second values
1041 0 : lpar[idx] += dpar/2;
1042 0 : GetGlobalParams(lpar,lpar+3, par2,par2+3);
1043 : //
1044 : // third values
1045 0 : lpar[idx] += dpar;
1046 0 : GetGlobalParams(lpar,lpar+3, par3,par3+3);
1047 : //
1048 : // fourth values
1049 0 : lpar[idx] += dpar/2;
1050 0 : GetGlobalParams(lpar,lpar+3, par4,par4+3);
1051 : //
1052 : Double_t h2 = 1./(2.*dpar);
1053 0 : for (int i=kMaxParGeom;i--;) {
1054 0 : Double_t d0 = par4[i]-par1[i];
1055 0 : Double_t d2 = 2.*(par3[i]-par2[i]);
1056 0 : deriv[i] = h2*(4*d2 - d0)/3.;
1057 0 : if (TMath::Abs(deriv[i]) < 1.0e-9) deriv[i] = 0.0;
1058 : }
1059 : //
1060 0 : }
1061 :
1062 : //-------------------------------------------------------------
1063 : void AliITSAlignMille2Module::CalcDerivLocGlo(Double_t *deriv)
1064 : {
1065 : // calculate derivative of local params vs global params: deriv[i][j] = dParLoc[i]/dParGlo[j]
1066 0 : Double_t gpar[kMaxParGeom];
1067 0 : for (int i=kMaxParGeom;i--;) gpar[i] = 0.;
1068 : // using f(x+h),f(x-h),f(x+h/2),f(x-h2)...
1069 0 : Double_t par1[kMaxParGeom]; // f(x-h)
1070 0 : Double_t par2[kMaxParGeom]; // f(x-h/2)
1071 0 : Double_t par3[kMaxParGeom]; // f(x+h/2)
1072 0 : Double_t par4[kMaxParGeom]; // f(x+h)
1073 : //
1074 : const Double_t dpar = 1e-3;
1075 : //
1076 0 : for (int ig=kMaxParGeom;ig--;) {
1077 : // first values
1078 0 : gpar[ig] -= dpar;
1079 0 : GetLocalParams(gpar,gpar+3, par1,par1+3);
1080 : //
1081 : // second values
1082 0 : gpar[ig] += dpar/2;
1083 0 : GetLocalParams(gpar,gpar+3, par2,par2+3);
1084 : //
1085 : // third values
1086 0 : gpar[ig] += dpar;
1087 0 : GetLocalParams(gpar,gpar+3, par3,par3+3);
1088 : //
1089 : // fourth values
1090 0 : gpar[ig] += dpar/2;
1091 0 : GetLocalParams(gpar,gpar+3, par4,par4+3);
1092 : //
1093 : Double_t h2 = 1./(2.*dpar);
1094 0 : for (int i=kMaxParGeom;i--;) {
1095 0 : Double_t d0 = par4[i]-par1[i];
1096 0 : Double_t d2 = 2.*(par3[i]-par2[i]);
1097 0 : int idig = i*kMaxParGeom + ig;
1098 0 : deriv[idig] = h2*(4*d2 - d0)/3.;
1099 0 : if (TMath::Abs(deriv[idig]) < 1.0e-9) deriv[idig] = 0.0;
1100 : }
1101 : }
1102 : //
1103 0 : }
1104 :
1105 : //________________________________________________________________________________________________________
1106 : void AliITSAlignMille2Module::CalcDerivGloLoc(Int_t sensVol,Int_t paridx,Double_t* derivative)
1107 : {
1108 : /// calculate numerically the derivatives of global params vs local param paridx for sensor sensVol: dPglob/dPloc_paridx
1109 : //
1110 0 : Double_t lpar[kMaxParGeom];
1111 0 : for (int i=kMaxParGeom;i--;) lpar[i] = 0.;
1112 : // using f(x+h),f(x-h),f(x+h/2),f(x-h2)...
1113 0 : Double_t par1[kMaxParGeom]; // f(x-h)
1114 0 : Double_t par2[kMaxParGeom]; // f(x-h/2)
1115 0 : Double_t par3[kMaxParGeom]; // f(x+h/2)
1116 0 : Double_t par4[kMaxParGeom]; // f(x+h)
1117 : //
1118 : const Double_t dpar = 1e-3;
1119 : //
1120 : // first values
1121 0 : lpar[paridx] -= dpar;
1122 0 : GetSensVolGlobalParams(sensVol,lpar,lpar+3, par1,par1+3);
1123 : //
1124 : // second values
1125 0 : lpar[paridx] += dpar/2;
1126 0 : GetSensVolGlobalParams(sensVol,lpar,lpar+3, par2,par2+3);
1127 : //
1128 : // third values
1129 0 : lpar[paridx] += dpar;
1130 0 : GetSensVolGlobalParams(sensVol,lpar,lpar+3, par3,par3+3);
1131 : //
1132 : // fourth values
1133 0 : lpar[paridx] += dpar/2;
1134 0 : GetSensVolGlobalParams(sensVol,lpar,lpar+3, par4,par4+3);
1135 : //
1136 : Double_t h2 = 1./(2.*dpar);
1137 0 : for (int i=kMaxParGeom;i--;) {
1138 0 : Double_t d0 = par4[i]-par1[i];
1139 0 : Double_t d2 = 2.*(par3[i]-par2[i]);
1140 0 : derivative[i] = h2*(4*d2 - d0)/3.;
1141 0 : if (TMath::Abs(derivative[i]) < 1.0e-9) derivative[i] = 0.0;
1142 : }
1143 : //
1144 0 : }
1145 :
1146 : //________________________________________________________________________________________________________
1147 : void AliITSAlignMille2Module::CalcDerivCurLoc(Int_t sensVol,Int_t paridx,Double_t* derivative)
1148 : {
1149 : /// calculate numerically the derivatives of sensor params in the current volume vs sensor local param paridx
1150 : //
1151 0 : Double_t lpar[kMaxParGeom];
1152 0 : for (int i=kMaxParGeom;i--;) lpar[i] = 0.;
1153 : // using f(x+h),f(x-h),f(x+h/2),f(x-h2)...
1154 0 : Double_t par1[kMaxParGeom]; // f(x-h)
1155 0 : Double_t par2[kMaxParGeom]; // f(x-h/2)
1156 0 : Double_t par3[kMaxParGeom]; // f(x+h/2)
1157 0 : Double_t par4[kMaxParGeom]; // f(x+h)
1158 : //
1159 : const Double_t dpar = 1e-3;
1160 : //
1161 : // first values
1162 0 : lpar[paridx] -= dpar;
1163 0 : GetSensVolLocalParams(sensVol,lpar,lpar+3, par1,par1+3);
1164 : //
1165 : // second values
1166 0 : lpar[paridx] += dpar/2;
1167 0 : GetSensVolLocalParams(sensVol,lpar,lpar+3, par2,par2+3);
1168 : //
1169 : // third values
1170 0 : lpar[paridx] += dpar;
1171 0 : GetSensVolLocalParams(sensVol,lpar,lpar+3, par3,par3+3);
1172 : //
1173 : // fourth values
1174 0 : lpar[paridx] += dpar/2;
1175 0 : GetSensVolLocalParams(sensVol,lpar,lpar+3, par4,par4+3);
1176 : //
1177 : Double_t h2 = 1./(2.*dpar);
1178 0 : for (int i=kMaxParGeom;i--;) {
1179 0 : Double_t d0 = par4[i]-par1[i];
1180 0 : Double_t d2 = 2.*(par3[i]-par2[i]);
1181 0 : derivative[i] = h2*(4*d2 - d0)/3.;
1182 0 : if (TMath::Abs(derivative[i]) < 1.0e-9) derivative[i] = 0.0;
1183 : }
1184 : //
1185 0 : }
1186 :
1187 :
1188 : //-------------------------------------------------------------
1189 : void AliITSAlignMille2Module::GetGlobalParams(Double_t *t, Double_t *r) const
1190 : {
1191 : // global parameters of the module
1192 0 : AliAlignObjParams tempAlignObj;
1193 0 : tempAlignObj.SetMatrix( *fMatrix );
1194 0 : tempAlignObj.GetPars(t,r);
1195 0 : }
1196 :
1197 : //-------------------------------------------------------------
1198 : void AliITSAlignMille2Module::GetGlobalParams(const Double_t* loct, const Double_t* locr, Double_t *t, Double_t *r)
1199 : {
1200 : // global parameters of the module after the modification by local loct,locr
1201 0 : AliAlignObjParams tempAlignObj;
1202 0 : tempAlignObj.SetTranslation(loct[0],loct[1],loct[2]);
1203 0 : tempAlignObj.SetRotation(locr[0],locr[1],locr[2]);
1204 0 : tempAlignObj.GetMatrix(*fSensVolModifMatrix);
1205 0 : *fSensVolMatrix = *fMatrix;
1206 0 : fSensVolMatrix->Multiply(fSensVolModifMatrix);
1207 0 : tempAlignObj.SetMatrix(*fSensVolMatrix);
1208 0 : tempAlignObj.GetPars(t,r);
1209 0 : }
1210 :
1211 : //-------------------------------------------------------------
1212 : void AliITSAlignMille2Module::GetLocalParams(const Double_t* glot, const Double_t* glor, Double_t *t, Double_t *r)
1213 : {
1214 : // obtain local delta parameters from global delta params
1215 0 : AliAlignObjParams tempAlignObj;
1216 0 : tempAlignObj.SetTranslation(glot[0],glot[1],glot[2]);
1217 0 : tempAlignObj.SetRotation(glor[0],glor[1],glor[2]);
1218 0 : tempAlignObj.GetMatrix(*fSensVolMatrix);
1219 0 : fSensVolMatrix->Multiply( fMatrix );
1220 0 : fSensVolMatrix->MultiplyLeft( &fMatrix->Inverse() );
1221 0 : tempAlignObj.SetMatrix(*fSensVolMatrix);
1222 0 : tempAlignObj.GetPars(t,r);
1223 0 : }
|