1 #include "AliFMDSurveyToAlignObjs.h"
2 #include "AliSurveyPoint.h"
3 #include <TGraph2DErrors.h>
10 #include <TGeoMatrix.h>
11 #include <TGeoManager.h>
12 #include <TGeoPhysicalNode.h>
13 #include "AliFMDGeometry.h"
15 //____________________________________________________________________
17 AliFMDSurveyToAlignObjs::GetUnitFactor() const
19 // Returns the conversion factor from the measured values to
21 TString units(fSurveyObj->GetUnits());
22 if (units.CompareTo("mm", TString::kIgnoreCase) == 0) return .1;
23 else if (units.CompareTo("cm", TString::kIgnoreCase) == 0) return 1.;
24 else if (units.CompareTo("m", TString::kIgnoreCase) == 0) return 100.;
28 //____________________________________________________________________
30 AliFMDSurveyToAlignObjs::GetPoint(const char* name,
32 TVector3& error) const
34 // Get named point. On return, point will contain the point
35 // coordinates in centimeters, and error will contain the
36 // meassurement errors in centimeters too. If no point is found,
37 // returns false, otherwise true.
38 Double_t unit = GetUnitFactor();
39 TObject* obj = fSurveyPoints->FindObject(name);
40 if (!obj) return kFALSE;
42 AliSurveyPoint* p = static_cast<AliSurveyPoint*>(obj);
43 point.SetXYZ(unit * p->GetX(),
46 error.SetXYZ(unit * p->GetPrecisionX(),
47 unit * p->GetPrecisionY(),
48 unit * p->GetPrecisionZ());
52 //____________________________________________________________________
54 AliFMDSurveyToAlignObjs::CalculatePlane(const TVector3& a,
60 // Vector a->b, b->c, and normal to plane defined by these two
62 TVector3 ab(b-a), bc(c-b);
64 // Normal vector to the plane of the fiducial marks obtained
65 // as cross product of the two vectors on the plane d0^d1
66 TVector3 nn(ab.Cross(bc));
67 if (nn.Mag() < 1e-8) {
68 Info("DoIt", "Normal vector is null vector");
72 // We express the plane in Hessian normal form.
76 // where n is the normalised normal vector given by
78 // n_x = a / l, n_y = b / l, n_z = c / l, p = d / l
80 // with l = sqrt(a^2+b^2+c^2) and a, b, c, and d are from the
81 // normal plane equation
83 // ax + by + cz + d = 0
86 TVector3 n(nn.Unit());
87 Double_t p = - (n * a);
89 // The center of the square with the fiducial marks as the
90 // corners. The mid-point of one diagonal - md. Used to get the
91 // center of the surveyd box.
95 // The center of the box.
101 // Normalize the spanning vectors
102 TVector3 uab(ab.Unit());
103 TVector3 ubc(bc.Unit());
105 for (size_t i = 0; i < 3; i++) {
106 rot[i * 3 + 0] = uab[i];
107 rot[i * 3 + 1] = ubc[i];
108 rot[i * 3 + 2] = n[i];
114 //____________________________________________________________________
116 AliFMDSurveyToAlignObjs::GetFMD1Plane(Double_t* rot, Double_t* trans) const
119 // The possile survey points
120 TVector3 icb, ict, ocb, oct, dummy;
122 if (!GetPoint("V0L_ICB", icb, dummy)) missing++;
123 if (!GetPoint("V0L_ICT", icb, dummy)) missing++;
124 if (!GetPoint("V0L_OCB", icb, dummy)) missing++;
125 if (!GetPoint("V0L_OCT", icb, dummy)) missing++;
127 // Check that we have enough points
129 Error("GetFMD1Plane", "Only got %d survey points - no good for FMD1 plane",
134 if (!CalculatePlane(icb, ict, oct, rot, trans)) return kFALSE;
139 //____________________________________________________________________
141 AliFMDSurveyToAlignObjs::DoFMD1()
146 //____________________________________________________________________
148 AliFMDSurveyToAlignObjs::GetFMD2Plane(Double_t* rot, Double_t* trans) const
151 // The possile survey points
152 const char* names[] = { "FMD2_ITOP", "FMD2_OTOP",
153 "FMD2_IBOTM", "FMD2_OBOTM",
154 "FMD2_IBOT", "FMD2_OBOT",
156 const char** name = names;
159 // Loop and fill graph
162 if (!GetPoint(*name++, p, e)) continue;
164 g.SetPoint(i, p.X(), p.Y(), p.Z());
165 g.SetPointError(i, e.X(), e.Y(), e.Z());
169 // Check that we have enough points
171 Error("GetFMD2Plane", "Only got %d survey points - no good for FMD2 plane",
176 // Next, declare fitting function and fit to graph.
177 // Fit to the plane equation:
179 // ax + by + cz + d = 0
183 // z = - ax/c - by/c - d/c
185 TF2 f("fmd2Plane", "-[0]*x-[1]*y-[2]",
186 g.GetXmin(), g.GetXmax(), g.GetYmin(), g.GetYmax());
189 // Now, extract the normal and offset
190 TVector3 nv(f.GetParameter(0), f.GetParameter(1), 1);
191 TVector3 n(nv.Unit());
192 Double_t p = -f.GetParameter(2);
194 // Create two vectors spanning the plane
195 TVector3 a(1, 0, f.Eval(1, 0)-p);
196 TVector3 b(0, -1, f.Eval(0, -1)-p);
197 TVector3 ua(a.Unit());
198 TVector3 ub(b.Unit());
199 Double_t angAb = ua.Angle(ub);
200 // PrintVector("ua: ", ua);
201 // PrintVector("ub: ", ub);
202 // std::cout << "Angle: " << angAb * 180 / TMath::Pi() << std::endl;
204 for (size_t i = 0; i < 3; i++) {
205 rot[i * 3 + 0] = ua[i];
206 rot[i * 3 + 1] = ub[i];
207 rot[i * 3 + 2] = n[i];
210 // The intersection of the plane is given by (0, 0, -d/c)
218 #define M(I,J) rot[(J-1) * 3 + (I-1)]
219 //____________________________________________________________________
221 AliFMDSurveyToAlignObjs::DoFMD2()
223 Double_t rot[9], trans[3];
224 if (!GetFMD2Plane(rot, trans)) return kFALSE;
226 PrintRotation("Rotation: ", rot);
227 PrintVector("Translation: ", trans);
230 Double_t theta = TMath::ATan2(M(3,1), M(3,2));
231 Double_t phi = TMath::ACos(M(3,3));
232 Double_t psi = -TMath::ATan2(M(1,3), M(2,3));
234 std::cout << " Theta=" << theta * 180 / TMath::Pi()
235 << " Phi=" << phi * 180 / TMath::Pi()
236 << " Psi=" << psi * 180 / TMath::Pi()
240 r.SetXEulerAngles(theta, phi, psi);
243 TGeoRotation* geoR = new TGeoRotation("FMD2_survey_rotation",
247 TGeoCombiTrans* geoM = new TGeoCombiTrans(trans[0], trans[1], trans[2], geoR);
249 TGeoHMatrix* geoM = new TGeoHMatrix;
250 geoM->SetRotation(rot);
251 geoM->SetTranslation(trans);
255 const char* path = "/ALIC_1/F2MT_2/FMD2_support_0/FMD2_back_cover_2";
256 gGeoManager->cd(path);
257 TGeoMatrix* globalBack = gGeoManager->GetCurrentMatrix();
259 PrintRotation("Back rotation:", globalBack->GetRotationMatrix());
260 PrintVector("Back translation:", globalBack->GetTranslation());
262 // TObjArray* pns = gGeoManager->GetListOfPhysicalNodes();
263 // TObject* oT = pns->FindObject("/ALIC_1/F2MT_2");
264 // TObject* oB = pns->FindObject("/ALIC_1/F2MB_2");
266 // Warning("DoFMD2", Form("Physical node /ALIC_1/F2MT_2 not found"));
270 // Warning("DoFMD2", Form("Physical node /ALIC_1/F2MB_2 not found"));
273 // TGeoPhysicalNode* top = static_cast<TGeoPhysicalNode*>(oT);
274 // TGeoPhysicalNode* bot = static_cast<TGeoPhysicalNode*>(oB);
275 TGeoHMatrix tDelta(globalBack->Inverse());
276 TGeoHMatrix bDelta(globalBack->Inverse());
277 PrintRotation("Back^-1 rotation:", tDelta.GetRotationMatrix());
278 PrintVector("Back^-1 translation:", tDelta.GetTranslation());
280 std::cout << "tDelta = 1? " << tDelta.IsIdentity() << std::endl;
282 tDelta.MultiplyLeft(geoM);
283 bDelta.MultiplyLeft(geoM);
285 PrintRotation("tDelta rotation:", tDelta.GetRotationMatrix());
286 PrintVector("tDelta translation:", tDelta.GetTranslation());
287 PrintRotation("bDelta rotation:", bDelta.GetRotationMatrix());
288 PrintVector("bDelta translation:", bDelta.GetTranslation());
293 //____________________________________________________________________
295 AliFMDSurveyToAlignObjs::Run()
297 AliFMDGeometry* geom = AliFMDGeometry::Instance();
299 geom->InitTransformations();
304 //____________________________________________________________________
306 AliFMDSurveyToAlignObjs::PrintVector(const char* text, const TVector3& v)
308 Double_t va[] = { v.X(), v.Y(), v.Z() };
309 PrintVector(text, va);
311 //____________________________________________________________________
313 AliFMDSurveyToAlignObjs::PrintVector(const char* text, const Double_t* v)
316 << std::setw(15) << v[0]
317 << std::setw(15) << v[1]
318 << std::setw(15) << v[2]
323 //____________________________________________________________________
325 AliFMDSurveyToAlignObjs::PrintRotation(const char* text, const Double_t* rot)
327 std::cout << text << std::endl;
328 for (size_t i = 0; i < 3; i++) {
329 for (size_t j = 0; j < 3; j++)
330 std::cout << std::setw(15) << rot[i * 3 + j];
331 std::cout << std::endl;
335 //____________________________________________________________________