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