Line data Source code
1 : //
2 : // Class to take survey data and
3 : // transform that to alignment objects.
4 : //
5 : // FMD
6 : //
7 : #include "AliFMDSurveyToAlignObjs.h"
8 : #include "AliLog.h"
9 : #include "AliSurveyPoint.h"
10 : #include <TGraph2DErrors.h>
11 : #include <TF2.h>
12 : #include <TVector3.h>
13 : #include <iostream>
14 : #include <iomanip>
15 : #include <TMath.h>
16 : #include <TRotation.h>
17 : #include <TGeoMatrix.h>
18 : #include <TGeoManager.h>
19 : #include <TGeoPhysicalNode.h>
20 : #include "AliFMDGeometry.h"
21 :
22 : //____________________________________________________________________
23 : Double_t
24 : AliFMDSurveyToAlignObjs::GetUnitFactor() const
25 : {
26 : // Returns the conversion factor from the measured values to
27 : // centimeters.
28 0 : if (!fSurveyObj) return 0;
29 0 : TString units(fSurveyObj->GetUnits());
30 0 : if (units.CompareTo("mm", TString::kIgnoreCase) == 0) return .1;
31 0 : else if (units.CompareTo("cm", TString::kIgnoreCase) == 0) return 1.;
32 0 : else if (units.CompareTo("m", TString::kIgnoreCase) == 0) return 100.;
33 0 : return 1;
34 0 : }
35 :
36 : //____________________________________________________________________
37 : Bool_t
38 : AliFMDSurveyToAlignObjs::GetPoint(const char* name,
39 : TVector3& point,
40 : TVector3& error) const
41 : {
42 : // Get named point. On return, point will contain the point
43 : // coordinates in centimeters, and error will contain the
44 : // meassurement errors in centimeters too. If no point is found,
45 : // returns false, otherwise true.
46 0 : if (!fSurveyPoints) return kFALSE;
47 :
48 0 : Double_t unit = GetUnitFactor();
49 0 : if (unit == 0) return kFALSE;
50 :
51 0 : TObject* obj = fSurveyPoints->FindObject(name);
52 0 : if (!obj) return kFALSE;
53 :
54 0 : AliSurveyPoint* p = static_cast<AliSurveyPoint*>(obj);
55 0 : point.SetXYZ(unit * p->GetX(),
56 0 : unit * p->GetY(),
57 0 : unit * p->GetZ());
58 0 : error.SetXYZ(unit * p->GetPrecisionX(),
59 0 : unit * p->GetPrecisionY(),
60 0 : unit * p->GetPrecisionZ());
61 : return kTRUE;
62 0 : }
63 :
64 : //____________________________________________________________________
65 : Bool_t
66 : AliFMDSurveyToAlignObjs::CalculatePlane(const TVector3& a,
67 : const TVector3& b,
68 : const TVector3& c,
69 : Double_t depth,
70 : Double_t* trans,
71 : Double_t* rot) const
72 : {
73 : //
74 : // Calculate the plane translation and rotation from 3 survey points
75 : //
76 : // Parameters:
77 : // a 1st Survey point
78 : // b 2nd Survey point
79 : // c 3rd Survey point
80 : // trans Translation vector
81 : // rot Rotation matrix (direction cosines)
82 : //
83 : // Return:
84 : //
85 : //
86 :
87 : // Vector a->b, b->c, and normal to plane defined by these two
88 : // vectors.
89 0 : TVector3 ab(b-a), bc(c-a);
90 :
91 : // Normal vector to the plane of the fiducial marks obtained
92 : // as cross product of the two vectors on the plane d0^d1
93 0 : TVector3 nn(ab.Cross(bc));
94 0 : if (nn.Mag() < 1e-8) {
95 0 : Info("CalculatePlane", "Normal vector is null vector");
96 0 : return kFALSE;
97 : }
98 :
99 : // We express the plane in Hessian normal form.
100 : //
101 : // n x = -p,
102 : //
103 : // where n is the normalised normal vector given by
104 : //
105 : // n_x = a / l, n_y = b / l, n_z = c / l, p = d / l
106 : //
107 : // with l = sqrt(a^2+b^2+c^2) and a, b, c, and d are from the
108 : // normal plane equation
109 : //
110 : // ax + by + cz + d = 0
111 : //
112 : // Normalize
113 0 : TVector3 n(nn.Unit());
114 : // Double_t p = - (n * a);
115 :
116 : // The center of the square with the fiducial marks as the
117 : // corners. The mid-point of one diagonal - md. Used to get the
118 : // center of the surveyd box.
119 : // TVector3 md(a + c);
120 : // md *= 1/2.;
121 : //Info("CalculatePlane", "corner=(%8f,%8f,%8f)", c.X(),c.Y(),c.Z());
122 : //Info("CalculatePlane", "corner=(%8f,%8f,%8f)", b.X(),b.Y(),b.Z());
123 0 : TVector3 md(c + b);
124 0 : md *= 1./2;
125 : //Info("CalculatePlane", "mid=(%8f,%8f,%8f)", md.X(),md.Y(),md.Z());
126 : //Info("CalculatePlane", "normal=(%8f,%8f,%8f)", n.X(),n.Y(),n.Z());
127 :
128 : // The center of the box.
129 0 : TVector3 orig(md - depth * n);
130 : // Info("CalculatePlane", "orig=(%8f,%8f,%8f)", orig.X(),orig.Y(),orig.Z());
131 0 : trans[0] = orig[0];
132 0 : trans[1] = orig[1];
133 0 : trans[2] = orig[2];
134 : //Info("CalculatePlane", "trans=(%8f,%8f,%8f)", trans[0],trans[1],trans[2]);
135 :
136 : // Normalize the spanning vectors
137 0 : TVector3 uab(ab.Unit());
138 0 : TVector3 ubc(bc.Unit());
139 :
140 0 : for (size_t i = 0; i < 3; i++) {
141 0 : rot[i * 3 + 0] = ubc[i];
142 0 : rot[i * 3 + 1] = uab[i];
143 : // rot[i * 3 + 0] = uab[i];
144 : // rot[i * 3 + 1] = ubc[i];
145 0 : rot[i * 3 + 2] = n[i];
146 : }
147 : return kTRUE;
148 0 : }
149 :
150 : //____________________________________________________________________
151 : Bool_t
152 : AliFMDSurveyToAlignObjs::FitPlane(const TObjArray& points,
153 : const TObjArray& errors,
154 : Double_t /* depth */,
155 : Double_t* trans,
156 : Double_t* rot) const
157 : {
158 : //
159 : // Calculate the plane rotation and translation by doing a fit of
160 : // the plane equation to the surveyed points. At least 4 points
161 : // must be passed in the @a points array with corresponding errors
162 : // in the array @a errors. The arrays are assumed to contain
163 : // TVector3 objects.
164 : //
165 : // Parameters:
166 : // points Array surveyed positions
167 : // errors Array of errors corresponding to @a points
168 : // depth Survey targets depth (perpendicular to the plane)
169 : // trans On return, translation of the plane
170 : // rot On return, rotation (direction cosines) of the plane
171 : //
172 : // Return:
173 : // @c true on success, @c false otherwise
174 : //
175 :
176 0 : Int_t nPoints = points.GetEntries();
177 0 : if (nPoints < 4) {
178 0 : AliError(Form("Cannot fit a plane equation to less than 4 survey points, "
179 : "got only %d", nPoints));
180 0 : return kFALSE;
181 : }
182 :
183 0 : TGraph2DErrors g;
184 : // Loop and fill graph
185 0 : for (int i = 0; i < nPoints; i++) {
186 0 : TVector3* p = static_cast<TVector3*>(points.At(i));
187 0 : TVector3* e = static_cast<TVector3*>(errors.At(i));
188 :
189 0 : if (!p || !e) continue;
190 :
191 0 : g.SetPoint(i, p->X(), p->Y(), p->Z());
192 0 : g.SetPointError(i, e->X(), e->Y(), e->Z());
193 :
194 0 : }
195 :
196 : // Check that we have enough points
197 0 : if (g.GetN() < 4) {
198 0 : AliError(Form("Only got %d survey points - no good for plane fit",
199 : g.GetN()));
200 0 : return kFALSE;
201 : }
202 :
203 : // Next, declare fitting function and fit to graph.
204 : // Fit to the plane equation:
205 : //
206 : // ax + by + cz + d = 0
207 : //
208 : // or
209 : //
210 : // z = - ax/c - by/c - d/c
211 : //
212 0 : TF2 f("plane", "-[0]*x-[1]*y-[2]",
213 0 : g.GetXmin(), g.GetXmax(), g.GetYmin(), g.GetYmax());
214 0 : g.Fit(&f, "Q");
215 :
216 : // Now, extract the normal and offset
217 0 : TVector3 nv(f.GetParameter(0), f.GetParameter(1), 1);
218 0 : TVector3 n(nv.Unit());
219 0 : Double_t p = -f.GetParameter(2);
220 :
221 : // Create two vectors spanning the plane
222 0 : TVector3 a(1, 0, f.Eval(1, 0)-p);
223 0 : TVector3 b(0, -1, f.Eval(0, -1)-p);
224 0 : TVector3 ua(a.Unit());
225 0 : TVector3 ub(b.Unit());
226 : // Double_t angAb = ua.Angle(ub);
227 : // PrintVector("ua: ", ua);
228 : // PrintVector("ub: ", ub);
229 : // std::cout << "Angle: " << angAb * 180 / TMath::Pi() << std::endl;
230 :
231 0 : for (size_t i = 0; i < 3; i++) {
232 0 : rot[i * 3 + 0] = ua[i];
233 0 : rot[i * 3 + 1] = ub[i];
234 0 : rot[i * 3 + 2] = n[i];
235 : }
236 :
237 : // The intersection of the plane is given by (0, 0, -d/c)
238 0 : trans[0] = 0;
239 0 : trans[1] = 0;
240 0 : trans[2] = p;
241 :
242 : return kTRUE;
243 0 : }
244 :
245 :
246 : //____________________________________________________________________
247 : Bool_t
248 : AliFMDSurveyToAlignObjs::MakeDelta(const char* path,
249 : const Double_t* rot,
250 : const Double_t* trans,
251 : TGeoHMatrix& delta) const
252 : {
253 : //
254 : // Create a delta transform from a global rotation matrix and
255 : // translation.
256 : //
257 : // Parameters:
258 : // path Path of element to transform.
259 : // rot Rotation matrix (direction cosines)
260 : // trans Translation
261 : // delta On return, the delta transform
262 : //
263 : // Return:
264 : // Newly
265 : //
266 0 : if (!gGeoManager) return kFALSE;
267 0 : if (!gGeoManager->cd(path)) return kFALSE;
268 :
269 :
270 0 : TGeoMatrix* global = gGeoManager->GetCurrentMatrix();
271 : #if 0
272 : PrintRotation(Form("%s rot:", global->GetName()),global->GetRotationMatrix());
273 : PrintVector(Form("%s trans:", global->GetName()),global->GetTranslation());
274 : #endif
275 :
276 0 : return MakeDelta(global, rot, trans, delta);
277 0 : }
278 :
279 : //____________________________________________________________________
280 : Bool_t
281 : AliFMDSurveyToAlignObjs::MakeDelta(const TGeoMatrix* global,
282 : const Double_t* rot,
283 : const Double_t* trans,
284 : TGeoHMatrix& delta) const
285 : {
286 : //
287 : // Create a delta transform from a global rotation matrix and
288 : // translation.
289 : //
290 : // Parameters:
291 : // global Global matrix of element to transform.
292 : // rot Rotation matrix (direction cosines)
293 : // trans Translation
294 : // delta On return, the delta transform
295 : //
296 : // Return:
297 : // Newly
298 : //
299 0 : TGeoHMatrix* geoM = new TGeoHMatrix;
300 0 : geoM->SetTranslation(trans);
301 0 : geoM->SetRotation(rot);
302 : // Info("MakeDelta", "The HMatrix from survey");
303 : // geoM->Print();
304 : // Info("MakeDelta", "The global matrix");
305 : // global->Print();
306 :
307 0 : delta = global->Inverse();
308 : // Info("MakeDelta", "The inverse global matrix");
309 : // delta.Print();
310 0 : delta.MultiplyLeft(geoM);
311 : // Info("MakeDelta", "The delta matrix");
312 : // delta.Print();
313 0 : return true;
314 0 : }
315 :
316 : namespace {
317 : Double_t getFMD1Offset()
318 : {
319 : static Double_t off = 0;
320 0 : return off;
321 :
322 : #if 0
323 : if (off != 0) return off;
324 :
325 : const char* lidN = "FMD1_lid_mat0";
326 : TGeoMatrix* lidM = static_cast<TGeoMatrix*>(gGeoManager->GetListOfMatrices()
327 : ->FindObject(lidN));
328 : if (!lidM) {
329 : Error("getFMD1Offset", "Couldn't find FMD1 lid transformation %s", lidN);
330 : return 0;
331 : }
332 :
333 : const Double_t* lidT = lidM->GetTranslation();
334 : Double_t lidZ = lidT[2];
335 : off = lidZ-3.3;
336 :
337 : return off;
338 : #endif
339 : }
340 : }
341 :
342 : //____________________________________________________________________
343 : Bool_t
344 : AliFMDSurveyToAlignObjs::GetFMD1Plane(Double_t* rot, Double_t* trans) const
345 : {
346 : //
347 : // Get the FMD1 plane from the survey points
348 : //
349 : // Parameters:
350 : // rot Rotation matrix (direction cosines)
351 : // trans Translation
352 : //
353 : // Return:
354 : // @c true on success, @c false otherwise.
355 : //
356 :
357 : // The possile survey points
358 0 : TVector3 icb, ict, ocb, oct, eicb, eict, eocb, eoct;
359 : Int_t missing = 0;
360 0 : if (!GetPoint("V0L_ICB", icb, eicb)) missing++;
361 0 : if (!GetPoint("V0L_ICT", ict, eict)) missing++;
362 0 : if (!GetPoint("V0L_OCB", ocb, eocb)) missing++;
363 0 : if (!GetPoint("V0L_OCT", oct, eoct)) missing++;
364 :
365 : // Check that we have enough points
366 0 : if (missing > 1) {
367 0 : AliWarning(Form("Only got %d survey points - no good for FMD1 plane",
368 : 4-missing));
369 0 : return kFALSE;
370 : }
371 : #if 0
372 : TObjArray points;
373 : TObjArray errors;
374 : points.Add(&icb); errors.Add(&eicb);
375 : points.Add(&ict); errors.Add(&eict);
376 : points.Add(&oct); errors.Add(&eoct);
377 : points.Add(&ocb); errors.Add(&eocb);
378 :
379 : Bool_t ret = FitPlane(points, errors, 0, trans, rot);
380 : if (!ret) {
381 : Warning("GetFMD1Plane", "fit to plane failed");
382 : }
383 : for (Int_t i = 0; i < 4; i++) {
384 : TVector3* v = static_cast<TVector3*>(points.At(i));
385 : TVector3* e = static_cast<TVector3*>(errors.At(i));
386 : Info("GetFMD1Plane", "p%d=(%8f,%8f,%8f)+/-(%8f,%8f,%8f)",
387 : i, v->X(), v->Y(), v->Z(), e->X(), e->Y(), e->Z());
388 : }
389 : #else
390 0 : Double_t off = getFMD1Offset();
391 0 : Info("GetFMD1Plane", "Lid offset is %f", off);
392 :
393 : // if (!CalculatePlane(ocb, icb, ict, off, trans, rot)) return kFALSE;
394 : // Bool_t ret = CalculatePlane(ocb, icb, oct, off, trans, rot);
395 0 : Bool_t ret = CalculatePlane(oct, ocb, ict, off, trans, rot);
396 : #endif
397 0 : PrintRotation("FMD1 rotation:", rot);
398 0 : PrintVector("FMD1 translation:", trans);
399 :
400 0 : return ret;
401 0 : }
402 :
403 : //____________________________________________________________________
404 : Bool_t
405 : AliFMDSurveyToAlignObjs::DoFMD1()
406 : {
407 : //
408 : // Do the FMD1 analysis. We have 4 survey targets on V0-A on the
409 : // C-side. These are
410 : //
411 : // - V0A_ICT In-side, C-side, top.
412 : // - V0A_ICB In-side, C-side, bottom.
413 : // - V0A_OCT Out-side, C-side, top.
414 : // - V0A_OCB Out-side, C-side, bottom.
415 : //
416 : // These 4 survey targets sit 3.3mm over the V0-A C-side surface, or
417 : // 3.3mm over the back surface of FMD1.
418 : //
419 : // Since these are really sitting on a plane, we can use the method
420 : // proposed by the CORE offline.
421 : //
422 : // Return:
423 : // @c true on success, @c false otherwise.
424 : //
425 :
426 : // Do the FMD1 stuff
427 0 : Double_t rot[9], trans[3];
428 0 : if (!GetFMD1Plane(rot, trans)) return kFALSE;
429 : // const char* path = "/ALIC_1/F1MT_1/FMD1_lid_0";
430 :
431 : #if 0
432 : // TGeoHMatrix delta;
433 : Double_t gRot[9], gTrans[3];
434 : TVector3 ocb(-127, -220, 324.67);
435 : TVector3 oct(-127, +220, 324.67);
436 : TVector3 icb(+127, -220, 324.67);
437 : TVector3 ict(+127, +220, 324.67);
438 : if (!CalculatePlane(ocb, icb, oct, 0, gTrans, gRot)) {
439 : Warning("DoFMD1", "Failed to make reference plane");
440 : return kFALSE;
441 : }
442 : PrintRotation("FMD1 ref rotation:", gRot);
443 : PrintVector("FMD1 ref translation:", gTrans);
444 : TGeoRotation ggRot; ggRot.SetMatrix(gRot);
445 : TGeoCombiTrans global(gTrans[0], gTrans[1], gTrans[2], &ggRot);
446 : #endif
447 0 : Double_t off = getFMD1Offset();
448 0 : Info("DoFMD1", "Lid offset is %f", off);
449 :
450 0 : TGeoTranslation global(0,0,324.670-off);
451 0 : if (!MakeDelta(&global, rot, trans, fFMD1Delta))
452 0 : return kFALSE;
453 :
454 : // PrintRotation("FMD1 delta rotation:", fFMD1Delta.GetRotationMatrix());
455 : // PrintVector("FMD1 delta translation:", fFMD1Delta.GetTranslation());
456 :
457 0 : return kTRUE;
458 0 : }
459 :
460 : //____________________________________________________________________
461 : Bool_t
462 : AliFMDSurveyToAlignObjs::GetFMD2Plane(Double_t* rot, Double_t* trans) const
463 : {
464 : //
465 : // Get the surveyed plane corresponding to the backside of FMD2.
466 : // The plane is done as a best fit of the plane equation to at least
467 : // 4 of the available survey points.
468 : //
469 : // Parameters:
470 : // rot Rotation matrix (direction cosines)
471 : // trans Translation vector.
472 : //
473 : // Return:
474 : // @c true on success, @c false otherwise
475 : //
476 :
477 : // The possible survey points
478 0 : const char* names[] = { "FMD2_ITOP", "FMD2_OTOP",
479 : "FMD2_IBOTM", "FMD2_OBOTM",
480 : "FMD2_IBOT", "FMD2_OBOT",
481 : 0 };
482 0 : const char** name = names;
483 :
484 0 : TObjArray points;
485 0 : TObjArray errors;
486 :
487 : // Loop and fill graph
488 : int i = 0;
489 0 : while (*name) {
490 0 : TVector3 p, e;
491 0 : if (!GetPoint(*name, p, e)) {
492 0 : name++;
493 0 : i++;
494 0 : continue;
495 : }
496 :
497 0 : if (i == 5) {
498 0 : Warning("GetFMD2plane", "Setting error on %d, %s to 0.4", i, *name);
499 0 : e.SetXYZ(0.4, 0.4, 0.4); // OBOT
500 0 : }
501 0 : points.Add(new TVector3(p));
502 0 : errors.Add(new TVector3(e));
503 0 : name++;
504 0 : i++;
505 0 : }
506 0 : if (points.GetEntries() < 4) {
507 0 : AliWarning(Form("Only got %d survey points - no good for FMD2 plane",
508 : points.GetEntries()));
509 0 : return kFALSE;
510 : }
511 :
512 0 : return FitPlane(points, errors, 0, trans, rot);
513 0 : }
514 :
515 : #define M(I,J) rot[(J-1) * 3 + (I-1)]
516 : //____________________________________________________________________
517 : Bool_t
518 : AliFMDSurveyToAlignObjs::DoFMD2()
519 : {
520 : //
521 : // Do the FMD2 calculations. We have 6 survey points of which only
522 : // 5 are normally surveyed. These are all sittings
523 : //
524 : // - FMD2_ITOP - In-side, top
525 : // - FMD2_IBOTM - In-side, middle bottom
526 : // - FMD2_IBOT - In-side, bottom
527 : // - FMD2_OTOP - Out-side, top
528 : // - FMD2_OBOTM - Out-side, middle bottom
529 : // - FMD2_OBOT - Out-side, bottom
530 : //
531 : // The nominal coordinates of these retro-fitted survey stickers
532 : // isn't known. Also, these stickers are put on a thin (0.3mm
533 : // thick) carbon cover which flexes quite easily. This means, that
534 : // to rotations and xy-translation obtained from the survey data
535 : // cannot be used, and left is only the z-translation.
536 : //
537 : // Further more, since FMD2 to is attached to the ITS SPD thermal
538 : // screen, it is questionable if the FMD2 survey will ever be used.
539 : //
540 : // Return:
541 : // @c true on success, @c false otherwise.
542 : //
543 :
544 : // Do the FMD2 stuff
545 0 : Double_t rot[9], trans[3];
546 0 : if (!GetFMD2Plane(rot, trans)) return kFALSE;
547 0 : PrintRotation("FMD2 rotation:", rot);
548 0 : PrintVector("FMD2 translation:", trans);
549 :
550 : #if 0
551 : for (int i = 0; i < 3; i++) {
552 : for (int j = 0; j < 3; j++) {
553 : rot[i*3+j] = (i == j ? 1 : 0);
554 : }
555 : }
556 : #endif
557 0 : trans[0] = trans[1] = 0;
558 0 : trans[2] += 0.015;
559 : // PrintRotation("FMD2 rotation:", rot);
560 : // PrintVector("FMD2 translation:", trans);
561 :
562 : // TGeoHMatrix delta;
563 0 : if (!MakeDelta("/ALIC_1/F2MT_2/FMD2_support_0/FMD2_back_cover_2",
564 0 : rot, trans, fFMD2Delta)) return kFALSE;
565 :
566 : // PrintRotation("FMD2 delta rotation:", fFMD2Delta.GetRotationMatrix());
567 : // PrintVector("FMD2 delta translation:", fFMD2Delta.GetTranslation());
568 :
569 0 : return kTRUE;
570 0 : }
571 :
572 : //____________________________________________________________________
573 : void
574 : AliFMDSurveyToAlignObjs::Run()
575 : {
576 : //
577 : // Run the task.
578 : //
579 : //
580 :
581 0 : AliFMDGeometry* geom = AliFMDGeometry::Instance();
582 0 : geom->Init();
583 0 : geom->InitTransformations();
584 :
585 0 : DoFMD1();
586 0 : DoFMD2();
587 0 : }
588 :
589 : //____________________________________________________________________
590 : void
591 : AliFMDSurveyToAlignObjs::Run(const char** files)
592 : {
593 : //
594 : // Run the task.
595 : //
596 : //
597 :
598 0 : AliFMDGeometry* geom = AliFMDGeometry::Instance();
599 0 : geom->Init();
600 0 : geom->InitTransformations();
601 :
602 : const char** file = files;
603 0 : while (*file) {
604 0 : if ((*file)[0] == '\0') {
605 0 : Warning("Run", "no file specified");
606 0 : file++;
607 0 : continue;
608 : }
609 0 : if (!LoadSurveyFromLocalFile(*file)) {
610 0 : Warning("Run", "Failed to load %s", *file);
611 0 : file++;
612 0 : continue;
613 : }
614 0 : TString sDet(fSurveyObj->GetDetector());
615 0 : Int_t d = Int_t(sDet[sDet.Length()-1] - '0');
616 0 : Info("Run", "Making alignment for %s (%d)", sDet.Data(), d);
617 : Bool_t ret = true;
618 0 : switch (d) {
619 0 : case 1: ret = DoFMD1(); break;
620 0 : case 2: ret = DoFMD2(); break;
621 : default:
622 0 : Warning("Run", "Do not know how to deal with %s", sDet.Data());
623 : break;
624 : }
625 0 : if (!ret) {
626 0 : Warning("Run", "Calculation for %s failed", sDet.Data());
627 : }
628 0 : file++;
629 0 : }
630 0 : CreateAlignObjs();
631 0 : GetAlignObjArray()->Print();
632 0 : FillDefaultAlignObjs();
633 0 : }
634 :
635 : //____________________________________________________________________
636 : AliAlignObjParams*
637 : AliFMDSurveyToAlignObjs::CreateDefaultAlignObj(const TString& path,
638 : Int_t id)
639 : {
640 0 : Int_t nAlign = fAlignObjArray->GetEntries();
641 : AliAlignObjParams* obj =
642 0 : new ((*fAlignObjArray)[nAlign]) AliAlignObjParams(path.Data(),
643 0 : id,0,0,0,0,0,0,kTRUE);
644 0 : if (!obj) {
645 0 : AliError(Form("Failed to create alignment object for %s", path.Data()));
646 0 : return 0;
647 : }
648 0 : if (!obj->SetLocalPars(0, 0, 0, 0, 0, 0)) {
649 0 : AliError(Form("Failed to set local transforms on %s", path.Data()));
650 0 : return obj;
651 : }
652 0 : return obj;
653 0 : }
654 :
655 : //____________________________________________________________________
656 : AliAlignObjParams*
657 : AliFMDSurveyToAlignObjs::FindAlignObj(const TString& path) const
658 : {
659 : AliAlignObjParams* p = 0;
660 0 : for (int i = 0; i < fAlignObjArray->GetEntries(); i++) {
661 0 : p = static_cast<AliAlignObjParams*>(fAlignObjArray->At(i));
662 0 : if (path.EqualTo(p->GetSymName())) return p;
663 : }
664 0 : return 0;
665 0 : }
666 :
667 : //____________________________________________________________________
668 : Bool_t
669 : AliFMDSurveyToAlignObjs::FillDefaultAlignObjs()
670 : {
671 0 : for (int d = 1; d <= 3; d++) {
672 : const char sides[] = { 'T', 'B', 0 };
673 : const char* side = sides;
674 0 : while (*side) {
675 0 : TString path = TString::Format("FMD/FMD%d_%c", d, *side);
676 0 : if (!FindAlignObj(path)) CreateDefaultAlignObj(path, 0);
677 :
678 0 : const char halves[] = { 'I', d == 1 ? '\0' : 'O', 0 };
679 0 : const char* half = halves;
680 0 : while (*half) {
681 0 : int nsec = *half == 'I' ? 10 : 20;
682 0 : int start = *side == 'T' ? 0 : nsec/2;
683 0 : int end = *side == 'T' ? nsec/2 : nsec;
684 0 : for (int s=start; s < end; s++) {
685 0 : path = TString::Format("FMD/FMD%d_%c/FMD%c_%02d",
686 0 : d, *side, *half, s);
687 0 : CreateDefaultAlignObj(path, 0);
688 : }
689 0 : half++;
690 : }
691 0 : side++;
692 0 : }
693 :
694 : }
695 0 : return true;
696 0 : }
697 :
698 : //____________________________________________________________________
699 : Bool_t
700 : AliFMDSurveyToAlignObjs::CreateAlignObjs()
701 : {
702 : //
703 : //
704 : // Method to create the alignment objects
705 : //
706 : // Return:
707 : // @c true on success, @c false otherwise
708 : //
709 0 : TClonesArray& array = *fAlignObjArray;
710 0 : Int_t n = array.GetEntriesFast();
711 :
712 0 : if (!fFMD1Delta.IsIdentity()) {
713 0 : new (array[n++]) AliAlignObjParams("FMD/FMD1_T", 0, fFMD1Delta, kTRUE);
714 0 : new (array[n++]) AliAlignObjParams("FMD/FMD1_B", 0, fFMD1Delta, kTRUE);
715 : }
716 0 : if (!fFMD2Delta.IsIdentity()) {
717 0 : new (array[n++]) AliAlignObjParams("FMD/FMD2_T", 0, fFMD2Delta, kTRUE);
718 0 : new (array[n++]) AliAlignObjParams("FMD/FMD2_B", 0, fFMD2Delta, kTRUE);
719 : }
720 : // array.Print();
721 :
722 0 : return kTRUE;
723 0 : }
724 :
725 : //____________________________________________________________________
726 : void
727 : AliFMDSurveyToAlignObjs::PrintVector(const char* text, const TVector3& v)
728 : {
729 : //
730 : // Service member function to print a vector
731 : //
732 : // Parameters:
733 : // text Prefix text
734 : // v Vector
735 : //
736 0 : Double_t va[] = { v.X(), v.Y(), v.Z() };
737 0 : PrintVector(text, va);
738 0 : }
739 : //____________________________________________________________________
740 : void
741 : AliFMDSurveyToAlignObjs::PrintVector(const char* text, const Double_t* v)
742 : {
743 : //
744 : // Service member function to print a vector
745 : //
746 : // Parameters:
747 : // text Prefix text
748 : // v Vector (array of 3 doubles)
749 : //
750 0 : std::cout << text
751 0 : << std::setw(15) << v[0]
752 0 : << std::setw(15) << v[1]
753 0 : << std::setw(15) << v[2]
754 0 : << std::endl;
755 0 : }
756 :
757 :
758 : //____________________________________________________________________
759 : void
760 : AliFMDSurveyToAlignObjs::PrintRotation(const char* text, const Double_t* rot)
761 : {
762 : //
763 : // Service member function to print a rotation matrix
764 : //
765 : // Parameters:
766 : // text Prefix text
767 : // v Matrix (array of 9 doubles)
768 : //
769 :
770 0 : std::cout << text << std::endl;
771 0 : for (size_t i = 0; i < 3; i++) {
772 0 : for (size_t j = 0; j < 3; j++)
773 0 : std::cout << std::setw(15) << rot[i * 3 + j];
774 0 : std::cout << std::endl;
775 : }
776 0 : }
777 :
778 : //____________________________________________________________________
779 : //
780 : // EOF
781 : //
|