Separating run-dependent mapping data from data, which are not
[u/mrichter/AliRoot.git] / MUON / AliMUONGeometryTransformer.cxx
CommitLineData
afc8e661 1/**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3 * SigmaEffect_thetadegrees *
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 purpeateose. It is *
13 * provided "as is" without express or implied warranty. *
14 **************************************************************************/
15
16// $Id$
3d1463c8 17
18//-----------------------------------------------------------------------------
afc8e661 19// Class AliMUONGeometryTransformer
20// ----------------------------
21// Top container class for geometry transformations
afc8e661 22// Author: Ivana Hrivnacova, IPN Orsay
3d1463c8 23//-----------------------------------------------------------------------------
afc8e661 24
afc8e661 25#include "AliMUONGeometryTransformer.h"
26#include "AliMUONGeometryModuleTransformer.h"
27#include "AliMUONGeometryDetElement.h"
2864a3ac 28#include "AliMUONGeometryBuilder.h"
afc8e661 29
ea7ea157 30#include "AliMpDEManager.h"
327d1302 31#include "AliMpConstants.h"
ea7ea157 32#include "AliMpExMap.h"
88544f7e 33#include "AliMpCDB.h"
9bf6860b 34#include "AliMpArea.h"
35#include <float.h>
36#include "AliMpVPadIterator.h"
37#include "AliMpPad.h"
38#include "AliMpDEIterator.h"
39#include <TVector2.h>
40#include "AliMpVSegmentation.h"
41#include "AliMpSegmentation.h"
630711ed 42#include "AliMpExMapIterator.h"
a7d4e65b 43#include "AliLog.h"
44#include "AliAlignObjMatrix.h"
bf16b32c 45#include "AliAlignObj.h"
a7d4e65b 46
47#include <Riostream.h>
48#include <TSystem.h>
49#include <TClonesArray.h>
50#include <TGeoManager.h>
51#include <TGeoPhysicalNode.h>
a6269834 52#include <TFile.h>
327d1302 53#include <TString.h>
a7d4e65b 54
55#include <sstream>
afc8e661 56
a9aad96e 57/// \cond CLASSIMP
afc8e661 58ClassImp(AliMUONGeometryTransformer)
a9aad96e 59/// \endcond
327d1302 60
61const TString AliMUONGeometryTransformer::fgkDefaultDetectorName = "MUON";
afc8e661 62
63//______________________________________________________________________________
327d1302 64AliMUONGeometryTransformer::AliMUONGeometryTransformer()
d4d05625 65
afc8e661 66 : TObject(),
327d1302 67 fDetectorName(fgkDefaultDetectorName),
a7d4e65b 68 fModuleTransformers(0),
9bf6860b 69 fMisAlignArray(0),
70 fDEAreas(0x0)
afc8e661 71{
72/// Standard constructor
73
74 // Create array for geometry modules
ea7ea157 75 fModuleTransformers = new TObjArray(100);
327d1302 76 fModuleTransformers->SetOwner(true);
afc8e661 77}
78
79//______________________________________________________________________________
327d1302 80AliMUONGeometryTransformer::AliMUONGeometryTransformer(TRootIOCtor* /*ioCtor*/)
afc8e661 81 : TObject(),
d4d05625 82 fDetectorName(),
a7d4e65b 83 fModuleTransformers(0),
9bf6860b 84 fMisAlignArray(0),
85 fDEAreas(0x0)
afc8e661 86{
87/// Default constructor
88}
89
90//______________________________________________________________________________
afc8e661 91AliMUONGeometryTransformer::~AliMUONGeometryTransformer()
92{
93/// Destructor
94
95 delete fModuleTransformers;
a7d4e65b 96 delete fMisAlignArray;
9bf6860b 97 delete fDEAreas;
afc8e661 98}
99
afc8e661 100//
101// private methods
102//
103
9bf6860b 104
105//_____________________________________________________________________________
106AliMpArea*
107AliMUONGeometryTransformer::GetDEArea(Int_t detElemId) const
108{
109 /// Get area (in global coordinates) covered by a given detection element
110 if (!fDEAreas)
111 {
112 CreateDEAreas();
113 }
114 return static_cast<AliMpArea*>(fDEAreas->GetValue(detElemId));
115}
116
117//_____________________________________________________________________________
118void
119AliMUONGeometryTransformer::CreateDEAreas() const
120{
121 /// Create DE areas
122
630711ed 123 fDEAreas = new AliMpExMap;
9bf6860b 124
125 AliMpDEIterator it;
126
127 it.First();
128
129 /// Generate the DE areas in global coordinates
130
131 while ( !it.IsDone() )
132 {
133 Int_t detElemId = it.CurrentDEId();
134
135 if ( !HasDE(detElemId) ) continue;
136
137 const AliMpVSegmentation* seg = AliMpSegmentation::Instance()->GetMpSegmentation(detElemId,AliMp::kCath0);
138
139 Double_t xg,yg,zg;
140
141 AliMp::StationType stationType = AliMpDEManager::GetStationType(detElemId);
142
143 Double_t xl(0.0), yl(0.0), zl(0.0);
144 Double_t dx(seg->Dimensions().X());
145 Double_t dy(seg->Dimensions().Y());
146
147 if ( stationType == AliMp::kStation1 || stationType == AliMp::kStation2 )
148 {
149 Double_t xmin(FLT_MAX);
150 Double_t xmax(-FLT_MAX);
151 Double_t ymin(FLT_MAX);
152 Double_t ymax(-FLT_MAX);
153
154 for ( Int_t icathode = 0; icathode < 2; ++icathode )
155 {
156 const AliMpVSegmentation* cathode
157 = AliMpSegmentation::Instance()->GetMpSegmentation(detElemId,AliMp::GetCathodType(icathode));
158
14a02207 159 AliMpVPadIterator* itp = cathode->CreateIterator();
9bf6860b 160
14a02207 161 itp->First();
9bf6860b 162
14a02207 163 while ( !itp->IsDone() )
9bf6860b 164 {
14a02207 165 AliMpPad pad = itp->CurrentItem();
9bf6860b 166 AliMpArea a(pad.Position(),pad.Dimensions());
167 xmin = TMath::Min(xmin,a.LeftBorder());
168 xmax = TMath::Max(xmax,a.RightBorder());
169 ymin = TMath::Min(ymin,a.DownBorder());
170 ymax = TMath::Max(ymax,a.UpBorder());
14a02207 171 itp->Next();
9bf6860b 172 }
173
14a02207 174 delete itp;
9bf6860b 175 }
176
177 xl = (xmin+xmax)/2.0;
178 yl = (ymin+ymax)/2.0;
179 dx = (xmax-xmin)/2.0;
180 dy = (ymax-ymin)/2.0;
181
182 Local2Global(detElemId,xl,yl,zl,xg,yg,zg);
183 }
184 else
185 {
186 Local2Global(detElemId,xl,yl,zl,xg,yg,zg);
187 }
188
189 fDEAreas->Add(detElemId,new AliMpArea(TVector2(xg,yg),TVector2(dx,dy)));
190
191 it.Next();
192 }
193}
194
afc8e661 195//_____________________________________________________________________________
88544f7e 196Bool_t AliMUONGeometryTransformer::LoadMapping() const
197{
198/// Load mapping from CDB
199
200 if ( ! AliMpCDB::LoadMpSegmentation() )
201 {
202 AliFatal("Could not access mapping from OCDB !");
203 return false;
204 }
205
206 return true;
207}
208
209//_____________________________________________________________________________
afc8e661 210AliMUONGeometryModuleTransformer*
211AliMUONGeometryTransformer::GetModuleTransformerNonConst(
212 Int_t index, Bool_t warn) const
213{
214/// Return the geometry module specified by index
215
216 if (index < 0 || index >= fModuleTransformers->GetEntriesFast()) {
217 if (warn) {
218 AliWarningStream()
219 << "Index: " << index << " outside limits" << std::endl;
220 }
221 return 0;
222 }
223
224 return (AliMUONGeometryModuleTransformer*) fModuleTransformers->At(index);
225}
226
227//______________________________________________________________________________
afc8e661 228TGeoHMatrix AliMUONGeometryTransformer::GetTransform(
229 Double_t x, Double_t y, Double_t z,
230 Double_t a1, Double_t a2, Double_t a3,
231 Double_t a4, Double_t a5, Double_t a6) const
232{
a9aad96e 233/// Build the transformation from the given parameters
afc8e661 234
235 // Compose transform
236 return TGeoCombiTrans(TGeoTranslation(x, y, z),
237 TGeoRotation("rot", a1, a2, a3, a4, a5, a6));
238}
239
240
241//______________________________________________________________________________
a7d4e65b 242void AliMUONGeometryTransformer::FillModuleTransform(Int_t moduleId,
afc8e661 243 Double_t x, Double_t y, Double_t z,
244 Double_t a1, Double_t a2, Double_t a3,
245 Double_t a4, Double_t a5, Double_t a6)
246{
a9aad96e 247/// Fill the transformation of the module.
afc8e661 248
afc8e661 249 AliMUONGeometryModuleTransformer* moduleTransformer
317aa7dc 250 = GetModuleTransformerNonConst(moduleId, false);
afc8e661 251
252 if ( !moduleTransformer) {
a7d4e65b 253 AliErrorStream()
254 << "Module " << moduleId << " has not volume path defined." << endl;
afc8e661 255 }
256
257 // Build the transformation from the parameters
258 TGeoHMatrix transform
259 = GetTransform(x, y, z, a1, a2, a3, a4, a5, a6);
260
261 moduleTransformer->SetTransformation(transform);
afc8e661 262}
263
264//______________________________________________________________________________
a7d4e65b 265void AliMUONGeometryTransformer::FillDetElemTransform(
266 Int_t detElemId,
afc8e661 267 Double_t x, Double_t y, Double_t z,
268 Double_t a1, Double_t a2, Double_t a3,
269 Double_t a4, Double_t a5, Double_t a6)
270{
a9aad96e 271/// Fill the transformation of the detection element.
afc8e661 272
273 // Module Id
ea7ea157 274 Int_t moduleId = AliMpDEManager::GetGeomModuleId(detElemId);
afc8e661 275
a7d4e65b 276 // Get module transformer
2864a3ac 277 const AliMUONGeometryModuleTransformer* kModuleTransformer
278 = GetModuleTransformer(moduleId);
a7d4e65b 279
2864a3ac 280 if ( ! kModuleTransformer ) {
a7d4e65b 281 AliFatal(Form("Module transformer not defined, detElemId: %d", detElemId));
282 return;
2864a3ac 283 }
284
a7d4e65b 285 // Get detection element
286 AliMUONGeometryDetElement* detElement
287 = kModuleTransformer->GetDetElement(detElemId);
288
289 if ( ! detElement ) {
290 AliFatal(Form("Det element %d has not volume path defined", detElemId));
291 return;
292 }
293
294 // Build the transformation from the parameters
295 TGeoHMatrix localTransform
296 = GetTransform(x, y, z, a1, a2, a3, a4, a5, a6);
297 detElement->SetLocalTransformation(localTransform);
298
299 // Compute global transformation
2864a3ac 300 TGeoHMatrix globalTransform
301 = AliMUONGeometryBuilder::Multiply(
302 *kModuleTransformer->GetTransformation(),
303 localTransform );
304 detElement->SetGlobalTransformation(globalTransform);
afc8e661 305}
a7d4e65b 306
307//______________________________________________________________________________
a7d4e65b 308TString AliMUONGeometryTransformer::ReadModuleTransforms(ifstream& in)
afc8e661 309{
a9aad96e 310/// Read and fill modules transformations from the stream.
311/// Return true, if reading finished correctly.
afc8e661 312
ea7ea157 313 TString key(AliMUONGeometryModuleTransformer::GetModuleNamePrefix());
314 while ( key == AliMUONGeometryModuleTransformer::GetModuleNamePrefix() ) {
a7d4e65b 315 Int_t id;
afc8e661 316 Double_t x, y, z;
317 Double_t a1, a2, a3, a4, a5, a6;
318 TString dummy;
319
320 in >> id;
afc8e661 321 in >> dummy;
322 in >> x;
323 in >> y;
324 in >> z;
325 in >> dummy;
326 in >> a1;
327 in >> a2;
328 in >> a3;
329 in >> a4;
330 in >> a5;
331 in >> a6;
332
a7d4e65b 333 //cout << "moduleId=" << id << " "
afc8e661 334 // << "position= " << x << ", " << y << ", " << z << " "
335 // << "rotation= " << a1 << ", " << a2 << ", " << a3 << ", "
336 // << a4 << ", " << a5 << ", " << a6
337 // << endl;
338
339 // Fill data
a7d4e65b 340 FillModuleTransform(id, x, y, z, a1, a2, a3, a4, a5, a6);
afc8e661 341
342 // Go to next line
343 in >> key;
344 }
345
346 return key;
347}
348
349//______________________________________________________________________________
a7d4e65b 350TString AliMUONGeometryTransformer::ReadDetElemTransforms(ifstream& in)
afc8e661 351{
a9aad96e 352/// Read detection elements transformations from the stream.
353/// Return true, if reading finished correctly.
afc8e661 354
ea7ea157 355 TString key(AliMUONGeometryDetElement::GetDENamePrefix());
356 while ( key == AliMUONGeometryDetElement::GetDENamePrefix() ) {
afc8e661 357
358 // Input data
359 Int_t detElemId;
afc8e661 360 Double_t x, y, z;
361 Double_t a1, a2, a3, a4, a5, a6;
362 TString dummy;
363
364 in >> detElemId;
afc8e661 365 in >> dummy;
366 in >> x;
367 in >> y;
368 in >> z;
369 in >> dummy;
370 in >> a1;
371 in >> a2;
372 in >> a3;
373 in >> a4;
374 in >> a5;
375 in >> a6;
376
377 //cout << "detElemId=" << detElemId << " "
afc8e661 378 // << "position= " << x << ", " << y << ", " << z << " "
379 // << "rotation= " << a1 << ", " << a2 << ", " << a3 << ", "
a7d4e65b 380 // << a4 << ", " << a5 << ", " << a6
afc8e661 381 // << endl;
382
383 // Fill data
a7d4e65b 384 FillDetElemTransform(detElemId, x, y, z, a1, a2, a3, a4, a5, a6);
afc8e661 385
386 // Go to next line
387 in >> key;
388 }
389
390 return key;
391}
392
393//______________________________________________________________________________
a7d4e65b 394Bool_t
a7d4e65b 395AliMUONGeometryTransformer::ReadTransformations(const TString& fileName)
396{
a9aad96e 397/// Read transformations from a file.
398/// Return true, if reading finished correctly.
a7d4e65b 399
400 // File path
401 TString filePath = gSystem->Getenv("ALICE_ROOT");
402 filePath += "/MUON/data/";
403 filePath += fileName;
404
405 // Open input file
406 ifstream in(filePath, ios::in);
407 if (!in) {
408 cerr << filePath << endl;
409 AliFatal("File not found.");
410 return false;
411 }
412
413 TString key;
414 in >> key;
415 while ( !in.eof() ) {
ea7ea157 416 if ( key == AliMUONGeometryModuleTransformer::GetModuleNamePrefix() )
a7d4e65b 417 key = ReadModuleTransforms(in);
ea7ea157 418 else if ( key == AliMUONGeometryDetElement::GetDENamePrefix() )
a7d4e65b 419 key = ReadDetElemTransforms(in);
420 else {
421 AliFatal(Form("%s key not recognized", key.Data()));
422 return false;
423 }
424 }
425
426 return true;
427}
428
429//______________________________________________________________________________
430Bool_t
327d1302 431AliMUONGeometryTransformer::LoadTransformations()
a7d4e65b 432{
327d1302 433/// Load transformations for defined modules and detection elements
434/// using AliGeomManager
a7d4e65b 435
327d1302 436 if ( ! AliGeomManager::GetGeometry() ) {
437 AliFatal("Geometry has to be laoded in AliGeomManager first.");
438 return false;
439 }
a7d4e65b 440
327d1302 441 for (Int_t i=0; i<fModuleTransformers->GetEntriesFast(); i++) {
442 AliMUONGeometryModuleTransformer* moduleTransformer
443 = (AliMUONGeometryModuleTransformer*)fModuleTransformers->At(i);
444
445 // Module symbolic name
446 TString symname = GetModuleSymName(moduleTransformer->GetModuleId());
447
448 // Set matrix from physical node
449 TGeoHMatrix* matrix = AliGeomManager::GetMatrix(symname);
88544f7e 450 if ( ! matrix ) {
327d1302 451 AliErrorStream() << "Geometry module matrix not found." << endl;
452 return false;
453 }
454 moduleTransformer->SetTransformation(*matrix);
455
456 // Loop over detection elements
457 AliMpExMap* detElements = moduleTransformer->GetDetElementStore();
630711ed 458 TIter next(detElements->CreateIterator());
459 AliMUONGeometryDetElement* detElement;
460
461 while ( ( detElement = static_cast<AliMUONGeometryDetElement*>(next()) ) )
462 {
327d1302 463 // Det element symbolic name
14a02207 464 TString symnameDE = GetDESymName(detElement->GetId());
327d1302 465
466 // Set global matrix from physical node
14a02207 467 TGeoHMatrix* globalMatrix = AliGeomManager::GetMatrix(symnameDE);
88544f7e 468 if ( ! globalMatrix ) {
327d1302 469 AliErrorStream() << "Detection element matrix not found." << endl;
470 return false;
471 }
472 detElement->SetGlobalTransformation(*globalMatrix);
473
474 // Set local matrix
475 TGeoHMatrix localMatrix =
476 AliMUONGeometryBuilder::Multiply(
477 (*matrix).Inverse(), (*globalMatrix) );
478 detElement->SetLocalTransformation(localMatrix);
479 }
480 }
481 return true;
482}
a7d4e65b 483
484//______________________________________________________________________________
afc8e661 485void AliMUONGeometryTransformer::WriteTransform(ofstream& out,
a7d4e65b 486 const TGeoMatrix* transform) const
afc8e661 487{
a9aad96e 488/// Write given transformation
afc8e661 489
490 out << " pos: ";
491 const Double_t* xyz = transform->GetTranslation();
492 out << setw(10) << setprecision(4) << xyz[0] << " "
493 << setw(10) << setprecision(4) << xyz[1] << " "
494 << setw(10) << setprecision(4) << xyz[2];
495
496 out << " rot: ";
497 const Double_t* rm = transform->GetRotationMatrix();
498 TGeoRotation rotation;
499 rotation.SetMatrix(const_cast<Double_t*>(rm));
500 Double_t a1, a2, a3, a4, a5, a6;
501 rotation.GetAngles(a1, a2, a3, a4, a5, a6);
502
503 out << setw(8) << setprecision(4) << a1 << " "
504 << setw(8) << setprecision(4) << a2 << " "
505 << setw(8) << setprecision(4) << a3 << " "
506 << setw(8) << setprecision(4) << a4 << " "
507 << setw(8) << setprecision(4) << a5 << " "
508 << setw(8) << setprecision(4) << a6 << " " << endl;
509}
510
511//______________________________________________________________________________
a7d4e65b 512void AliMUONGeometryTransformer::WriteModuleTransforms(ofstream& out) const
513{
a9aad96e 514/// Write module transformations for all module transformers
afc8e661 515
516 for (Int_t i=0; i<fModuleTransformers->GetEntriesFast(); i++) {
517 AliMUONGeometryModuleTransformer* moduleTransformer
518 = (AliMUONGeometryModuleTransformer*)fModuleTransformers->At(i);
a7d4e65b 519 const TGeoMatrix* transform
afc8e661 520 = moduleTransformer->GetTransformation();
521
a7d4e65b 522 // Write data on out
ea7ea157 523 out << AliMUONGeometryModuleTransformer::GetModuleNamePrefix() << " "
524 << setw(4) << moduleTransformer->GetModuleId();
afc8e661 525
526 WriteTransform(out, transform);
527 }
528 out << endl;
529}
530
531//______________________________________________________________________________
a7d4e65b 532void AliMUONGeometryTransformer::WriteDetElemTransforms(ofstream& out) const
afc8e661 533{
a9aad96e 534/// Write detection element transformations for all detection elements in all
535/// module transformers
afc8e661 536
afc8e661 537 for (Int_t i=0; i<fModuleTransformers->GetEntriesFast(); i++) {
538 AliMUONGeometryModuleTransformer* moduleTransformer
539 = (AliMUONGeometryModuleTransformer*)fModuleTransformers->At(i);
ea7ea157 540 AliMpExMap* detElements = moduleTransformer->GetDetElementStore();
630711ed 541 TIter next(detElements->CreateIterator());
542 AliMUONGeometryDetElement* detElement;
543 while ( ( detElement = static_cast<AliMUONGeometryDetElement*>(next()) ) )
544 {
a7d4e65b 545 const TGeoMatrix* transform
afc8e661 546 = detElement->GetLocalTransformation();
547
afc8e661 548 // Write data on out
ea7ea157 549 out << AliMUONGeometryDetElement::GetDENamePrefix() << " "
550 << setw(4) << detElement->GetId();
afc8e661 551
552 WriteTransform(out, transform);
553 }
554 out << endl;
555 }
556}
557
d4d05625 558//______________________________________________________________________________
559TString AliMUONGeometryTransformer::GetModuleSymName(Int_t moduleId) const
560{
561/// Return the module symbolic name (use for alignment)
562
327d1302 563 return "/" + fDetectorName + "/"
564 + AliMUONGeometryModuleTransformer::GetModuleName(moduleId);
d4d05625 565}
566
567//______________________________________________________________________________
568TString AliMUONGeometryTransformer::GetDESymName(Int_t detElemId) const
569{
9c4d2d12 570/// Return the detection element symbolic name (used for alignment)
d4d05625 571
d4d05625 572 // Module Id
ea7ea157 573 Int_t moduleId = AliMpDEManager::GetGeomModuleId(detElemId);
d4d05625 574
327d1302 575 return GetModuleSymName(moduleId) + "/"
576 + AliMUONGeometryDetElement::GetDEName(detElemId);
d4d05625 577}
578
afc8e661 579//
580// public functions
581//
582
583//______________________________________________________________________________
584Bool_t
327d1302 585AliMUONGeometryTransformer::LoadGeometryData(const TString& fileName)
afc8e661 586{
327d1302 587/// Read geometry data either from ASCII file with transformations or
588/// from root geometry file (if fileName has ".root" extension)
a7d4e65b 589
327d1302 590 CreateModules();
a7d4e65b 591
592 // Get file extension
327d1302 593 std::string fileName2 = fileName.Data();
594 std::string rootExt = fileName2.substr(fileName2.size()-5, fileName2.size());
a7d4e65b 595
327d1302 596 if ( rootExt != ".root" )
597 return ReadTransformations(fileName);
598 else {
599 // Load root geometry
600 AliGeomManager::LoadGeometry(fileName.Data());
601 return LoadTransformations();
602 }
a7d4e65b 603}
604
605//______________________________________________________________________________
606Bool_t
327d1302 607AliMUONGeometryTransformer::LoadGeometryData()
a7d4e65b 608{
327d1302 609/// Load geometry data from already loaded Root geometry using AliGeomManager
a7d4e65b 610
327d1302 611 if ( ! AliGeomManager::GetGeometry() ) {
612 AliErrorStream() << "Geometry has not been loaded in AliGeomManager" << endl;
613 return false;
614 }
afc8e661 615
327d1302 616 CreateModules();
a7d4e65b 617
327d1302 618 return LoadTransformations();
a7d4e65b 619}
afc8e661 620
621//______________________________________________________________________________
622Bool_t
623AliMUONGeometryTransformer::WriteTransformations(const TString& fileName) const
624{
a9aad96e 625/// Write transformations into a file.
626/// Return true, if writing finished correctly.
afc8e661 627
628 // No writing
629 // if builder is not associated with any geometry module
630 if (fModuleTransformers->GetEntriesFast() == 0) return false;
631
632 // File path
633 TString filePath = gSystem->Getenv("ALICE_ROOT");
634 filePath += "/MUON/data/";
635 filePath += fileName;
636
a7d4e65b 637 // Open output file
afc8e661 638 ofstream out(filePath, ios::out);
639 if (!out) {
640 cerr << filePath << endl;
641 AliError("File not found.");
642 return false;
643 }
644#if !defined (__DECCXX)
645 out.setf(std::ios::fixed);
646#endif
a7d4e65b 647 WriteModuleTransforms(out);
648 WriteDetElemTransforms(out);
649
650 return true;
651}
652
653//______________________________________________________________________________
654Bool_t
655AliMUONGeometryTransformer::WriteMisAlignmentData(const TString& fileName) const
656{
a9aad96e 657/// Write misalignment data into a file
658/// Return true, if writing finished correctly.
a7d4e65b 659
660 // No writing
661 // if builder is not associated with any geometry module
662 if ( fModuleTransformers->GetEntriesFast() == 0 ) {
663 AliWarningStream() << "No geometry modules defined." << endl;
664 return false;
665 }
666
667 // No writing
668 // if builder has no mis-alignment data
669 if ( ! fMisAlignArray ) {
670 AliWarningStream() << "No mis-alignment data defined." << endl;
671 return false;
672 }
673
674 // File path
675 TString filePath = gSystem->Getenv("ALICE_ROOT");
676 filePath += "/MUON/data/";
677 filePath += fileName;
678
679 // Write mis-alignment data in the root file
680 TFile file(fileName.Data(), "RECREATE");
681 fMisAlignArray->Write();
682 file.Close();
afc8e661 683
684 return true;
685}
686
687//_____________________________________________________________________________
688void AliMUONGeometryTransformer::AddModuleTransformer(
689 AliMUONGeometryModuleTransformer* moduleTransformer)
690{
a9aad96e 691/// Add the module transformer to the array
afc8e661 692
ea7ea157 693 // Expand the size if not sufficient
694 Int_t moduleId = moduleTransformer->GetModuleId();
695 if ( moduleId >= fModuleTransformers->GetSize() )
696 fModuleTransformers->Expand(moduleId+1);
697
698 fModuleTransformers->AddAt(moduleTransformer, moduleId);
afc8e661 699}
700
701//_____________________________________________________________________________
a7d4e65b 702void AliMUONGeometryTransformer::AddMisAlignModule(Int_t moduleId,
703 const TGeoHMatrix& matrix)
704{
a9aad96e 705/// Build AliAlignObjMatrix with module ID, its volumePath
a7d4e65b 706/// and the given delta transformation matrix
707
708 if ( ! fMisAlignArray )
709 fMisAlignArray = new TClonesArray("AliAlignObjMatrix", 200);
710
711 const AliMUONGeometryModuleTransformer* kTransformer
712 = GetModuleTransformer(moduleId);
713 if ( ! kTransformer ) {
714 AliErrorStream() << "Module " << moduleId << " not found." << endl;
715 return;
716 }
717
bf16b32c 718 // Get unique align object ID
ae079791 719 Int_t volId = AliGeomManager::LayerToVolUID(AliGeomManager::kMUON, moduleId);
bf16b32c 720
a7d4e65b 721 // Create mis align matrix
722 TClonesArray& refArray =*fMisAlignArray;
723 Int_t pos = fMisAlignArray->GetEntriesFast();
d4d05625 724 new (refArray[pos]) AliAlignObjMatrix(GetModuleSymName(moduleId), volId,
b760c02e 725 const_cast<TGeoHMatrix&>(matrix),kTRUE);
a7d4e65b 726}
727
728//_____________________________________________________________________________
729void AliMUONGeometryTransformer::AddMisAlignDetElement(Int_t detElemId,
730 const TGeoHMatrix& matrix)
731{
a9aad96e 732/// Build AliAlignObjMatrix with detection element ID, its volumePath
a7d4e65b 733/// and the given delta transformation matrix
734
735 if ( ! fMisAlignArray )
736 fMisAlignArray = new TClonesArray("AliAlignObjMatrix", 200);
737
738 const AliMUONGeometryDetElement* kDetElement
739 = GetDetElement(detElemId);
740
741 if ( ! kDetElement ) {
742 AliErrorStream() << "Det element " << detElemId << " not found." << endl;
743 return;
744 }
745
bf16b32c 746 // Get unique align object ID
ae079791 747 Int_t volId = AliGeomManager::LayerToVolUID(AliGeomManager::kMUON, detElemId);
bf16b32c 748
a7d4e65b 749 // Create mis align matrix
750 TClonesArray& refArray =*fMisAlignArray;
751 Int_t pos = fMisAlignArray->GetEntriesFast();
d4d05625 752 new(refArray[pos]) AliAlignObjMatrix(GetDESymName(detElemId), volId,
b760c02e 753 const_cast<TGeoHMatrix&>(matrix),kTRUE);
a7d4e65b 754}
755
327d1302 756//______________________________________________________________________________
757void AliMUONGeometryTransformer::CreateModules()
758{
759/// Create modules and their detection elements using info from mapping;
760/// but do not fill matrices
761
88544f7e 762 // Load mapping as its info is used to define modules & DEs
763 LoadMapping();
327d1302 764
b96f7067 765 if ( fModuleTransformers->GetEntriesFast() == 0 ) {
766 // Create modules only if they do not yet exist
767
768 // Loop over geometry module
769 for (Int_t moduleId = 0; moduleId < AliMpConstants::NofGeomModules(); ++moduleId ) {
327d1302 770
b96f7067 771 // Create geometry module transformer
772 AliMUONGeometryModuleTransformer* moduleTransformer
773 = new AliMUONGeometryModuleTransformer(moduleId);
774 AddModuleTransformer(moduleTransformer);
775 }
776 }
327d1302 777
778 // Loop over detection elements
779 AliMpDEIterator it;
780 for ( it.First(); ! it.IsDone(); it.Next() ) {
781
782 Int_t detElemId = it.CurrentDEId();
783 Int_t moduleId = AliMpDEManager::GetGeomModuleId(detElemId);
784
785 // Get detection element store
786 AliMpExMap* detElements =
787 GetModuleTransformer(moduleId)->GetDetElementStore();
788
789 // Add detection element
790 AliMUONGeometryDetElement* detElement
791 = new AliMUONGeometryDetElement(detElemId);
792 detElements->Add(detElemId, detElement);
793 }
794}
795
a7d4e65b 796//_____________________________________________________________________________
d4d05625 797void AliMUONGeometryTransformer::AddAlignableVolumes() const
798{
df22c125 799/// Set symbolic names and matrices to alignable objects to TGeo
d4d05625 800
801 if ( ! gGeoManager ) {
802 AliWarning("TGeoManager not defined.");
803 return;
804 }
805
806 // Modules
807 for (Int_t i=0; i<fModuleTransformers->GetEntriesFast(); i++) {
808 AliMUONGeometryModuleTransformer* module
809 = (AliMUONGeometryModuleTransformer*)fModuleTransformers->At(i);
810
811 // Set module symbolic name
df22c125 812 TGeoPNEntry* pnEntry
327d1302 813 = gGeoManager->SetAlignableEntry(GetModuleSymName(module->GetModuleId()),
df22c125 814 module->GetVolumePath());
327d1302 815 if ( ! pnEntry ) {
816 AliErrorStream()
b96f7067 817 << "Volume path " << module->GetVolumePath().Data()
818 << " for geometry module " << module->GetModuleId() << " " << module
327d1302 819 << " not found in geometry." << endl;
820 }
821 else {
822 // Set module matrix
823 pnEntry->SetMatrix(new TGeoHMatrix(*module->GetTransformation()));
824 // the matrix will be deleted via TGeoManager
825 }
d4d05625 826
827 // Detection elements
ea7ea157 828 AliMpExMap* detElements = module->GetDetElementStore();
630711ed 829 TIter next(detElements->CreateIterator());
830 AliMUONGeometryDetElement* detElement;
831
832 while ( ( detElement = static_cast<AliMUONGeometryDetElement*>(next()) ) )
833 {
d4d05625 834 // Set detection element symbolic name
14a02207 835 TGeoPNEntry* pnEntryDE
df22c125 836 = gGeoManager->SetAlignableEntry(GetDESymName(detElement->GetId()),
837 detElement->GetVolumePath());
14a02207 838 if ( ! pnEntryDE ) {
327d1302 839 AliErrorStream()
b96f7067 840 << "Volume path "
841 << detElement->GetVolumePath().Data()
842 << " for detection element " << detElement->GetId()
327d1302 843 << " not found in geometry." << endl;
844 }
845 else {
846 // Set detection element matrix
14a02207 847 pnEntryDE->SetMatrix(new TGeoHMatrix(*detElement->GetGlobalTransformation()));
327d1302 848 // the matrix will be deleted via TGeoManager
849 }
d4d05625 850 }
851 }
852}
853
854//_____________________________________________________________________________
ae612121 855TClonesArray* AliMUONGeometryTransformer::CreateZeroAlignmentData() const
856{
857/// Create array with zero alignment data
858
859 // Create array for zero-alignment objects
860 TClonesArray* array = new TClonesArray("AliAlignObjMatrix", 200);
861 TClonesArray& refArray =*array;
862 array->SetOwner(true);
863
864 // Identity matrix
865 TGeoHMatrix matrix;
866
867 // Modules
868 for (Int_t i=0; i<fModuleTransformers->GetEntriesFast(); i++) {
869 AliMUONGeometryModuleTransformer* module
870 = (AliMUONGeometryModuleTransformer*)fModuleTransformers->At(i);
871
ae612121 872 Int_t moduleId = module->GetModuleId();
873
874 // Align object ID
ae079791 875 Int_t volId = AliGeomManager::LayerToVolUID(AliGeomManager::kMUON, moduleId);
ae612121 876
877 // Create mis align matrix
878 Int_t pos = array->GetEntriesFast();
d4d05625 879 new (refArray[pos]) AliAlignObjMatrix(GetModuleSymName(moduleId), volId, matrix, kTRUE);
ae612121 880 }
881
882 // Detection elements
883 for (Int_t i=0; i<fModuleTransformers->GetEntriesFast(); i++) {
884 AliMUONGeometryModuleTransformer* moduleTransformer
885 = (AliMUONGeometryModuleTransformer*)fModuleTransformers->At(i);
ae612121 886
630711ed 887 AliMpExMap* detElements = moduleTransformer->GetDetElementStore();
888 TIter next(detElements->CreateIterator());
889 AliMUONGeometryDetElement* detElement;
890
891 while ( ( detElement = static_cast<AliMUONGeometryDetElement*>(next()) ) )
892 {
ae612121 893 Int_t detElemId = detElement->GetId();
894
895 // Align object ID
ae079791 896 Int_t volId = AliGeomManager::LayerToVolUID(AliGeomManager::kMUON, detElemId);
ae612121 897
898 // Create mis align matrix
899 Int_t pos = array->GetEntriesFast();
d4d05625 900 new (refArray[pos]) AliAlignObjMatrix(GetDESymName(detElemId), volId, matrix, kTRUE);
ae612121 901 }
902 }
903
904 return array;
905}
906
907//_____________________________________________________________________________
f384585c 908void AliMUONGeometryTransformer::ClearMisAlignmentData()
909{
910/// Clear the array of misalignment data
911
912 if ( ! fMisAlignArray ) return;
913
914 fMisAlignArray->Delete();
915}
916
917//_____________________________________________________________________________
afc8e661 918void AliMUONGeometryTransformer::Global2Local(Int_t detElemId,
919 Float_t xg, Float_t yg, Float_t zg,
920 Float_t& xl, Float_t& yl, Float_t& zl) const
921{
922/// Transform point from the global reference frame (ALIC)
923/// to the local reference frame of the detection element specified
924/// by detElemId.
f7006443 925
afc8e661 926 const AliMUONGeometryModuleTransformer* kTransformer
927 = GetModuleTransformerByDEId(detElemId);
928
929 if (kTransformer)
930 kTransformer->Global2Local(detElemId, xg, yg, zg, xl, yl, zl);
931}
932
933//_____________________________________________________________________________
934void AliMUONGeometryTransformer::Global2Local(Int_t detElemId,
935 Double_t xg, Double_t yg, Double_t zg,
936 Double_t& xl, Double_t& yl, Double_t& zl) const
937{
938/// Transform point from the global reference frame (ALIC)
939/// to the local reference frame of the detection element specified
940/// by detElemId.
f7006443 941
afc8e661 942 const AliMUONGeometryModuleTransformer* kTransformer
943 = GetModuleTransformerByDEId(detElemId);
944
945 if (kTransformer)
946 kTransformer->Global2Local(detElemId, xg, yg, zg, xl, yl, zl);
947}
948
949//_____________________________________________________________________________
950void AliMUONGeometryTransformer::Local2Global(Int_t detElemId,
951 Float_t xl, Float_t yl, Float_t zl,
952 Float_t& xg, Float_t& yg, Float_t& zg) const
953{
954/// Transform point from the local reference frame of the detection element
955/// specified by detElemId to the global reference frame (ALIC).
956
957 const AliMUONGeometryModuleTransformer* kTransformer
958 = GetModuleTransformerByDEId(detElemId);
959
960 if (kTransformer)
961 kTransformer->Local2Global(detElemId, xl, yl, zl, xg, yg, zg);
962}
963
964//_____________________________________________________________________________
965void AliMUONGeometryTransformer::Local2Global(Int_t detElemId,
966 Double_t xl, Double_t yl, Double_t zl,
967 Double_t& xg, Double_t& yg, Double_t& zg) const
968{
969/// Transform point from the local reference frame of the detection element
970/// specified by detElemId to the global reference frame (ALIC).
971
972 const AliMUONGeometryModuleTransformer* kTransformer
973 = GetModuleTransformerByDEId(detElemId);
974
975 if (kTransformer)
976 kTransformer->Local2Global(detElemId, xl, yl, zl, xg, yg, zg);
977}
978
979//_____________________________________________________________________________
980const AliMUONGeometryModuleTransformer*
981AliMUONGeometryTransformer::GetModuleTransformer(Int_t index, Bool_t warn) const
982{
a9aad96e 983/// Return the geometry module transformer specified by index
afc8e661 984
985 return GetModuleTransformerNonConst(index, warn);
986}
987
988//_____________________________________________________________________________
989const AliMUONGeometryModuleTransformer*
990AliMUONGeometryTransformer::GetModuleTransformerByDEId(Int_t detElemId,
991 Bool_t warn) const
992{
a9aad96e 993/// Return the geometry module transformer specified by detection element ID
afc8e661 994
995 // Get module index
ea7ea157 996 Int_t index = AliMpDEManager::GetGeomModuleId(detElemId);
afc8e661 997
998 return GetModuleTransformer(index, warn);
999}
317aa7dc 1000
1001//_____________________________________________________________________________
a7d4e65b 1002const AliMUONGeometryDetElement*
1003AliMUONGeometryTransformer::GetDetElement(Int_t detElemId, Bool_t warn) const
1004{
a9aad96e 1005/// Return detection element with given detElemId
a7d4e65b 1006
1007 const AliMUONGeometryModuleTransformer* kTransformer
1008 = GetModuleTransformerByDEId(detElemId, warn);
1009
1010 if (!kTransformer) return 0;
1011
1012 return kTransformer->GetDetElement(detElemId, warn);
1013}
1014
1015//_____________________________________________________________________________
317aa7dc 1016Bool_t AliMUONGeometryTransformer::HasDE(Int_t detElemId) const
1017{
1018/// Return true if detection element with given detElemId is defined
1019
1020 const AliMUONGeometryModuleTransformer* kTransformer
1021 = GetModuleTransformerByDEId(detElemId, false);
1022
1023 if (!kTransformer) return false;
1024
1025 return ( kTransformer->GetDetElement(detElemId, false) != 0 );
1026}
1027
1028