]> git.uio.no Git - u/mrichter/AliRoot.git/blob - MUON/AliMUONVGeometryBuilder.cxx
Added functions for reading & writing transformations and sensitive volume maps files...
[u/mrichter/AliRoot.git] / MUON / AliMUONVGeometryBuilder.cxx
1 /**************************************************************************
2  * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3  *                                                                        *
4  * Author: The ALICE Off-line Project.                                    *
5  * Contributors are mentioned in the code where appropriate.              *
6  *                                                                        *
7  * Permission to use, copy, modify and distribute this software and its   *
8  * documentation strictly for non-commercial purposes is hereby granted   *
9  * without fee, provided that the above copyright notice appears in all   *
10  * copies and that both the copyright notice and this permission notice   *
11  * appear in the supporting documentation. The authors make no claims     *
12  * about the suitability of this software for any purpose. It is          *
13  * provided "as is" without express or implied warranty.                  *
14  **************************************************************************/
15
16 // $Id$
17 //
18 // Class AliMUONVGeometryBuilder
19 // -----------------------------
20 // Abstract base class for geometry construction per chamber(s).
21 // Author: Ivana Hrivnacova, IPN Orsay
22 // 23/01/2004
23
24 #include <Riostream.h>
25 #include <TObjArray.h>
26 #include <TSystem.h>
27 #include <TGeoMatrix.h>
28 #include <TVirtualMC.h>
29
30 #include "AliMUONVGeometryBuilder.h"
31 #include "AliMUONChamber.h"
32 #include "AliMUONChamberGeometry.h"
33 #include "AliMUONGeometryTransformStore.h"
34 #include "AliMUONGeometrySVMap.h"
35 #include "AliMUONGeometryEnvelopeStore.h"
36 #include "AliMUONGeometryEnvelope.h"
37 #include "AliMUONGeometryConstituent.h"
38 #include "AliMUONConstants.h"
39
40 ClassImp(AliMUONVGeometryBuilder)
41
42 const TString AliMUONVGeometryBuilder::fgkTransformFileNamePrefix = "transform_";
43 const TString AliMUONVGeometryBuilder::fgkSVMapFileNamePrefix = "svmap_";
44 const TString AliMUONVGeometryBuilder::fgkOutFileNameSuffix = ".out";
45
46 //______________________________________________________________________________
47 AliMUONVGeometryBuilder::AliMUONVGeometryBuilder(const TString& fileName,
48                                 AliMUONChamber* ch1, AliMUONChamber* ch2,
49                                 AliMUONChamber* ch3, AliMUONChamber* ch4,
50                                 AliMUONChamber* ch5, AliMUONChamber* ch6)
51  : TObject(),
52    fTransformFileName(fgkTransformFileNamePrefix+fileName),
53    fSVMapFileName(fgkSVMapFileNamePrefix+fileName),
54    fChambers(0)
55  {
56 // Standard constructor
57
58   // Create the chambers array
59   fChambers = new TObjArray();
60   
61   if (ch1) fChambers->Add(ch1);
62   if (ch2) fChambers->Add(ch2);
63   if (ch3) fChambers->Add(ch3);
64   if (ch4) fChambers->Add(ch4);
65   if (ch5) fChambers->Add(ch5);
66   if (ch6) fChambers->Add(ch6);
67 }
68
69
70 //______________________________________________________________________________
71 AliMUONVGeometryBuilder::AliMUONVGeometryBuilder()
72  : TObject(),
73    fTransformFileName(),
74    fSVMapFileName(),
75    fChambers(0)
76 {
77 // Default constructor
78 }
79
80
81 //______________________________________________________________________________
82 AliMUONVGeometryBuilder::AliMUONVGeometryBuilder(const AliMUONVGeometryBuilder& rhs)
83   : TObject(rhs)
84 {
85 // Protected copy constructor
86
87   Fatal("Copy constructor", 
88         "Copy constructor is not implemented.");
89 }
90
91 //______________________________________________________________________________
92 AliMUONVGeometryBuilder::~AliMUONVGeometryBuilder() {
93 //
94   if (fChambers) {
95     fChambers->Clear(); // Sets pointers to 0 sinche it is not the owner
96     delete fChambers;
97   }
98 }
99
100 //______________________________________________________________________________
101 AliMUONVGeometryBuilder& 
102 AliMUONVGeometryBuilder::operator = (const AliMUONVGeometryBuilder& rhs) 
103 {
104 // Protected assignement operator
105
106   // check assignement to self
107   if (this == &rhs) return *this;
108
109   Fatal("operator=", 
110         "Assignment operator is not implemented.");
111     
112   return *this;  
113 }
114
115 //
116 // private methods
117 //
118
119 //______________________________________________________________________________
120  TString  AliMUONVGeometryBuilder::ComposePath(const TString& volName, 
121                                                Int_t copyNo) const
122 {
123 // Compose path from given volName and copyNo
124 // ---
125
126   TString path(volName);
127   path += ".";
128   path += copyNo;
129   
130   return path;
131 }  
132
133 /*
134 //______________________________________________________________________________
135 void AliMUONVGeometryBuilder::MapSV(const TString& path0, 
136                                     const TString& volName, Int_t detElemId) const
137 {
138 // Update the path with all daughters volumes recursively
139 // and map it to the detection element Id if it is a sensitive volume
140 // ---
141
142   Int_t nofDaughters = gMC->NofVolDaughters(volName);
143   if (nofDaughters == 0) {
144
145     // Get the name of the last volume in the path
146     Ssiz_t npos1 = path0.Last('/')+1; 
147     Ssiz_t npos2 = path0.Last('.');
148     TString volName(path0(npos1, npos2-npos1));  
149     
150     // Check if it is sensitive volume
151     Int_t chamberId = AliMUONConstants::GetChamberId(detElemId);
152     AliMUONChamberGeometry* geometry = GetChamber(chamberId)->GetGeometry();
153     if (geometry->IsSensitiveVolume(volName)) {
154       //cout << ".. adding to the map  " 
155       //     <<  path0 << "  "  << detElemId << endl;
156       FillData(path0, detElemId); 
157     }  
158     return; 
159   }  
160
161   for (Int_t i=0; i<nofDaughters; i++) {
162     Int_t copyNo = gMC->VolDaughterCopyNo(volName, i);
163     TString newName =  gMC->VolDaughterName(volName, i);
164             
165     TString path = path0;
166     path += "/";
167     path += ComposePath(newName, copyNo);
168
169     MapSV(path, newName, detElemId);
170   }
171 }     
172 */
173
174 //______________________________________________________________________________
175 void AliMUONVGeometryBuilder::MapSV(const TString& /*path0*/, 
176                                     const TString& /*volName*/, 
177                                     Int_t /*detElemId*/) const
178 {
179 // Update the path with all daughters volumes recursively
180 // and map it to the detection element Id if it is a sensitive volume
181 // ---
182
183   Warning("MapSV", "Not yet available");
184 }     
185
186 //______________________________________________________________________________
187 void AliMUONVGeometryBuilder::FillData(Int_t chamberId,
188                   Double_t x, Double_t y, Double_t z,
189                   Double_t a1, Double_t a2, Double_t a3,
190                   Double_t a4, Double_t a5, Double_t a6) const 
191 {
192 // Fill the transformation of the chamber.
193 // ---
194
195   chamberId--;
196       // Chambers numbers in the file are starting from 1
197
198   GetChamber(chamberId)->GetGeometry()
199     ->SetTranslation(TGeoTranslation(x, y, z));
200   GetChamber(chamberId)->GetGeometry()
201     ->SetRotation(TGeoRotation("rot", a1, a2, a3, a4, a5, a6));
202 }                  
203   
204 //______________________________________________________________________________
205 void AliMUONVGeometryBuilder::FillData(
206                   Int_t detElemId, const TString& volName, Int_t copyNo,
207                   Double_t x, Double_t y, Double_t z,
208                   Double_t a1, Double_t a2, Double_t a3,
209                   Double_t a4, Double_t a5, Double_t a6) const 
210 {
211 // Fill the transformation of the detection element.
212 // ---
213
214   // Chamber Id
215   Int_t chamberId = AliMUONConstants::GetChamberId(detElemId);
216
217   // Get chamber transformations
218   AliMUONGeometryTransformStore* transforms 
219     = GetTransforms(chamberId);     
220
221   // Compose path
222   TString path = ComposePath(volName, copyNo);
223   
224   // Compose matrix
225   TGeoCombiTrans transform(path, x, y, z, 
226                            new TGeoRotation(path, a1, a2, a3, a4, a5, a6));
227     
228   // Add detection element transformation 
229   transforms->Add(detElemId, path, transform); 
230 }                  
231   
232 //______________________________________________________________________________
233 void AliMUONVGeometryBuilder::FillData(
234                    const TString& sensVolumePath, Int_t detElemId) const
235 {
236 // Fill the mapping of the sensitive volume path to the detection element.
237 // ---
238
239   // Chamber Id
240   Int_t chamberId = AliMUONConstants::GetChamberId(detElemId);
241
242   // Get chamber transformations
243   AliMUONGeometrySVMap* svMap = GetSVMap(chamberId);     
244
245   // Map the sensitive volume to detection element
246   svMap->Add(sensVolumePath, detElemId); 
247 }                  
248   
249 //______________________________________________________________________________
250 TString  AliMUONVGeometryBuilder::ReadData1(ifstream& in) const
251 {
252 // Reads and fills chambers transformations from a file
253 // Returns true, if reading finished correctly.
254 // ---
255
256   TString key("CH");
257   while ( key == TString("CH") ) {
258     Int_t id;
259     Double_t  x, y, z;
260     Double_t  a1, a2, a3, a4, a5, a6;
261     TString dummy;
262   
263     in >> id;
264     in >> dummy;
265     in >> x;
266     in >> y;
267     in >> z;
268     in >> dummy;
269     in >> a1; 
270     in >> a2; 
271     in >> a3; 
272     in >> a4; 
273     in >> a5; 
274     in >> a6; 
275
276     //cout << "id="     << id << "  "
277     //   << "position= " << x << ", " << y << ", " << z << "  "
278     //   << "rotation= " << a1 << ", " << a2 << ", " << a3  << ", "
279     //                   << a4 << ", " << a5 << ", " << a6 
280     //   << endl;   
281          
282     // Fill data
283     FillData(id, x, y, z, a1, a2, a3, a4, a5, a6);
284     
285     // Go to next line
286     in >> key;
287   }
288   
289   return key;            
290 }
291
292 //______________________________________________________________________________
293 TString  AliMUONVGeometryBuilder::ReadData2(ifstream& in) const
294 {
295 // Reads detection elements transformations from a file
296 // Returns true, if reading finished correctly.
297 // ---
298
299   TString key("DE");
300   while ( key == TString("DE") ) {
301
302     // Input data
303     Int_t detElemId;
304     TString   volumeName;
305     Int_t     copyNo;
306     Double_t  x, y, z;
307     Double_t  a1, a2, a3, a4, a5, a6;
308     TString dummy;
309   
310     in >> detElemId;
311     in >> volumeName;
312     in >> copyNo;
313     in >> dummy;
314     in >> x;
315     in >> y;
316     in >> z;
317     in >> dummy;
318     in >> a1; 
319     in >> a2; 
320     in >> a3; 
321     in >> a4; 
322     in >> a5; 
323     in >> a6; 
324
325     //cout << "detElemId=" << detElemId << "  "
326     //     << "volume=" << volumeName << "  "
327     //     << "copyNo=" << copyNo << "  "
328     //     << "position= " << x << ", " << y << ", " << z << "  "
329     //     << "rotation= " << a1 << ", " << a2 << ", " << a3  << ", "
330     //                   << a4 << ", " << a5 << ", " << a6 
331     //     << endl;   
332          
333     // Fill data
334     FillData(detElemId, volumeName, copyNo, x, y, z, a1, a2, a3, a4, a5, a6);    
335     
336     // Go to next line
337     in >> key;
338   } 
339   
340   return key;
341 }
342
343 //______________________________________________________________________________
344 TString  AliMUONVGeometryBuilder::ReadData3(ifstream& in) const
345 {
346 // Reads detection elements transformations from a file
347 // Returns true, if reading finished correctly.
348 // ---
349
350   TString key("SV");
351   while ( key == TString("SV") ) {
352
353     // Input data
354     TString   volumePath;
355     Int_t     detElemId;
356   
357     in >> volumePath;
358     in >> detElemId;
359
360     //cout << "volumePath=" << volumePath << "  "
361     //   << "detElemId=" << detElemId    
362     //     << endl;   
363          
364     // Fill data
365     FillData(volumePath, detElemId); 
366      
367     // Go to next line
368     in >> key;
369   } 
370   
371   return key;
372 }
373
374 //______________________________________________________________________________
375 void AliMUONVGeometryBuilder::WriteTransform(ofstream& out, 
376                                    const TGeoCombiTrans* transform) const
377 {
378 // Writes the transformations 
379 // ---
380
381   out << "   pos: ";
382   const Double_t* xyz = transform->GetTranslation();
383   out << setw(10) << setprecision(4) << xyz[0] << "  " 
384       << setw(10) << setprecision(4) << xyz[1] << "  " 
385       << setw(10) << setprecision(4) << xyz[2];
386
387   out << "   rot: ";
388   Double_t a1, a2, a3, a4, a5, a6;
389   TGeoRotation* rotation = transform->GetRotation();
390   rotation->GetAngles(a1, a2, a3, a4, a5, a6);
391   out << setw(8) << setprecision(4) << a1 << "  " 
392       << setw(8) << setprecision(4) << a2 << "  " 
393       << setw(8) << setprecision(4) << a3 << "  " 
394       << setw(8) << setprecision(4) << a4 << "  " 
395       << setw(8) << setprecision(4) << a5 << "  " 
396       << setw(8) << setprecision(4) << a6 << "  " << endl; 
397 }
398
399 //______________________________________________________________________________
400 void AliMUONVGeometryBuilder::WriteData1(ofstream& out) const
401 {
402 // Writes chamber transformations
403 // ---
404
405   for (Int_t i=0; i<fChambers->GetEntriesFast(); i++) {
406     AliMUONChamber* chamber 
407       = (AliMUONChamber*)fChambers->At(i);
408     AliMUONChamberGeometry* chamberGeometry
409        = chamber->GetGeometry();
410     const TGeoCombiTrans* transform 
411       = chamberGeometry->GetTransformation();    
412
413     out << "CH " 
414         << setw(4) << chamber->GetId() + 1 << "  ";
415     
416     WriteTransform(out, transform);
417   }
418   out << endl;
419 }
420
421 //______________________________________________________________________________
422 void AliMUONVGeometryBuilder::WriteData2(ofstream& out) const
423 {
424 // Writes detection elements (envelopes) transformations
425 // ---
426
427
428   for (Int_t i=0; i<fChambers->GetEntriesFast(); i++) {
429     AliMUONChamber* chamber 
430       = (AliMUONChamber*)fChambers->At(i);
431     AliMUONChamberGeometry* chamberGeometry
432        = chamber->GetGeometry();
433     const TObjArray* envelopes 
434       = chamberGeometry->GetEnvelopeStore()->GetEnvelopes();    
435
436     for (Int_t j=0; j<envelopes->GetEntriesFast(); j++) {
437       AliMUONGeometryEnvelope* envelope
438         = (AliMUONGeometryEnvelope*)envelopes->At(j);
439       const TGeoCombiTrans* transform 
440         = envelope->GetTransformation(); 
441       
442       // skip envelope not corresponding to detection element
443       if(envelope->GetUniqueID() == 0) continue;
444        
445       out << "DE " 
446           << setw(4) << envelope->GetUniqueID() << "    " 
447           << envelope->GetName() << " " 
448           << setw(4)<< envelope->GetCopyNo();
449      
450       WriteTransform(out, transform);
451     }
452     out << endl;                        
453   }     
454 }
455
456 //______________________________________________________________________________
457 void AliMUONVGeometryBuilder::WriteData3(ofstream& out) const
458 {
459 // Writes association of sensitive volumes and detection elements
460 // from the sensitive volume map
461 // ---
462
463   for (Int_t i=0; i<fChambers->GetEntriesFast(); i++) {
464     AliMUONChamber* chamber 
465       = (AliMUONChamber*)fChambers->At(i);
466     AliMUONChamberGeometry* chamberGeometry
467        = chamber->GetGeometry();
468     AliMUONGeometrySVMap* svMap
469       = chamberGeometry->GetSVMap();
470
471     svMap->WriteMap(out);
472     out << endl;  
473   }    
474 }
475
476 //
477 // protected methods
478 //
479
480 //______________________________________________________________________________
481 AliMUONChamber*  AliMUONVGeometryBuilder::GetChamber(Int_t chamberId) const
482 {
483 // Returns the chamber specified by chamberId
484 // ---
485
486   for (Int_t i=0; i<fChambers->GetEntriesFast(); i++) {
487     AliMUONChamber* chamber = (AliMUONChamber*)fChambers->At(i);
488     if ( chamber->GetId() == chamberId) return chamber;
489   }   
490   
491   return 0;
492 }  
493
494 //______________________________________________________________________________
495 AliMUONGeometryEnvelopeStore*  
496 AliMUONVGeometryBuilder::GetEnvelopes(Int_t chamberId) const
497 {
498 // Returns the envelope store of the chamber specified by chamberId
499 // ---
500
501   AliMUONChamber* chamber = GetChamber(chamberId);
502   
503   if (!chamber) {
504     Fatal("GetEnvelopes", "Chamber %d is not defined", chamberId); 
505     return 0;
506   }
507   
508   return chamber->GetGeometry()->GetEnvelopeStore();
509 }  
510
511 //______________________________________________________________________________
512 AliMUONGeometryTransformStore*  
513 AliMUONVGeometryBuilder::GetTransforms(Int_t chamberId) const
514 {
515 // Returns the transformation store of the chamber specified by chamberId
516 // ---
517
518   AliMUONChamber* chamber = GetChamber(chamberId);
519   
520   if (!chamber) {
521     Fatal("GetTransforms", "Chamber %d is not defined", chamberId); 
522     return 0;
523   }
524   
525   return chamber->GetGeometry()->GetTransformStore();
526 }  
527
528 //______________________________________________________________________________
529 AliMUONGeometrySVMap*  
530 AliMUONVGeometryBuilder::GetSVMap(Int_t chamberId) const
531 {
532 // Returns the transformation store of the chamber specified by chamberId
533 // ---
534
535   AliMUONChamber* chamber = GetChamber(chamberId);
536   
537   if (!chamber) {
538     Fatal("GetSVMap", "Chamber %d is not defined", chamberId); 
539     return 0;
540   }
541   
542   return chamber->GetGeometry()->GetSVMap();
543 }  
544
545 //
546 // public functions
547 //
548
549 //______________________________________________________________________________
550 void  AliMUONVGeometryBuilder:: FillTransformations() const
551 {
552 // Fills transformations store from defined geometry.
553 // ---
554
555   for (Int_t i=0; i<fChambers->GetEntriesFast(); i++) {
556     AliMUONChamber* chamber 
557       = (AliMUONChamber*)fChambers->At(i);
558     AliMUONChamberGeometry* chamberGeometry
559        = chamber->GetGeometry();
560     const TObjArray* envelopes 
561       = chamberGeometry->GetEnvelopeStore()->GetEnvelopes();    
562     AliMUONGeometryTransformStore* transforms 
563       = chamberGeometry->GetTransformStore();     
564
565     for (Int_t j=0; j<envelopes->GetEntriesFast(); j++) {
566       AliMUONGeometryEnvelope* envelope
567         = (AliMUONGeometryEnvelope*)envelopes->At(j);
568
569       // skip envelope not corresponding to detection element
570       if(envelope->GetUniqueID() == 0) continue;
571        
572       // Get envelope data 
573       Int_t detElemId = envelope->GetUniqueID();        
574       TString path = ComposePath(envelope->GetName(), 
575                                  envelope->GetCopyNo());
576       const TGeoCombiTrans* transform = envelope->GetTransformation(); 
577
578       // Add detection element transformation 
579       transforms->Add(detElemId, path, *transform); 
580     }  
581   }
582 }
583
584 //_____ _________________________________________________________________________
585 void  AliMUONVGeometryBuilder::RebuildSVMaps() const
586 {
587 // Clear the SV maps in memory and fill them from defined geometry.
588 // ---
589
590   for (Int_t i=0; i<fChambers->GetEntriesFast(); i++) {
591     AliMUONChamber* chamber 
592       = (AliMUONChamber*)fChambers->At(i);
593     AliMUONChamberGeometry* chamberGeometry
594        = chamber->GetGeometry();
595     
596     // Clear the map   
597     chamberGeometry->GetSVMap()->Clear();
598      
599     // Fill the map from geometry
600     const TObjArray* envelopes 
601       = chamberGeometry->GetEnvelopeStore()->GetEnvelopes();    
602
603     for (Int_t j=0; j<envelopes->GetEntriesFast(); j++) {
604       AliMUONGeometryEnvelope* envelope
605         = (AliMUONGeometryEnvelope*)envelopes->At(j);
606
607       // skip envelope not corresponding to detection element
608       if(envelope->GetUniqueID() == 0) continue;
609        
610       TString path0("/ALIC.1");
611       if (chamberGeometry->GetMotherVolume() != "ALIC") {
612         path0 += "/";
613         path0 += ComposePath(chamberGeometry->GetMotherVolume(), 1);
614       }  
615        
616       if (!envelope->IsVirtual()) {
617          TString path = path0;
618          path += "/";
619          path += ComposePath(envelope->GetName(), envelope->GetCopyNo());
620          MapSV(path, envelope->GetName(), envelope->GetUniqueID());
621       }
622       else {     
623         for  (Int_t k=0; k<envelope->GetConstituents()->GetEntriesFast(); k++) {
624           AliMUONGeometryConstituent* constituent
625             = (AliMUONGeometryConstituent*)envelope->GetConstituents()->At(k);
626          TString path = path0;
627          path += "/";
628          path += ComposePath(constituent->GetName(), constituent->GetCopyNo());
629          MapSV(path, constituent->GetName(), envelope->GetUniqueID());
630         }
631       }
632     }  
633   }                  
634 }
635
636 //______________________________________________________________________________
637 Bool_t  AliMUONVGeometryBuilder::ReadTransformations() const
638 {
639 // Reads transformations from a file
640 // Returns true, if reading finished correctly.
641 // ---
642
643   // File path
644   TString filePath = gSystem->Getenv("ALICE_ROOT");
645   filePath += "/MUON/data/";
646   filePath += fTransformFileName;
647   
648   // Open input file
649   ifstream in(filePath, ios::in);
650   if (!in) {
651     cerr << filePath << endl;   
652     Fatal("ReadTransformations", "File not found.");
653     return false;
654   }
655
656   TString key;
657   in >> key;
658   while ( !in.eof() ) {
659     if (key == TString("CH")) 
660       key = ReadData1(in);
661     else if (key == TString("DE"))
662       key = ReadData2(in);
663     else {
664       Fatal("ReadTransformations", "%s key not recognized",  key.Data());
665       return false;
666     }
667   }     
668
669   return true;
670 }
671
672 //______________________________________________________________________________
673 Bool_t  AliMUONVGeometryBuilder::ReadSVMap() const
674 {
675 // Reads the sensitive volume from a file
676 // Returns true, if reading finished correctly.
677 // ---
678
679   // File path
680   TString filePath = gSystem->Getenv("ALICE_ROOT");
681   filePath += "/MUON/data/";
682   filePath += fSVMapFileName;
683   
684   // Open input file
685   ifstream in(filePath, ios::in);
686   if (!in) {
687     cerr << filePath << endl;   
688     Fatal("ReadSVMap", "File not found.");
689     return false;
690   }
691
692   TString key;
693   in >> key;
694   while ( !in.eof() ) {
695     if (key == TString("SV")) 
696       key = ReadData3(in);
697     else {
698       Fatal("ReadSVMap", "%s key not recognized",  key.Data());
699       return false;
700     }
701   }     
702
703   return true;
704 }
705
706 //______________________________________________________________________________
707 Bool_t  AliMUONVGeometryBuilder::WriteTransformations() const
708 {
709 // Writes transformations into a file
710 // Returns true, if writing finished correctly.
711 // ---
712
713   // File path
714   TString filePath = gSystem->Getenv("ALICE_ROOT");
715   filePath += "/MUON/data/";
716   filePath += fTransformFileName;
717   filePath += fgkOutFileNameSuffix;
718   
719   // Open input file
720   ofstream out(filePath, ios::out);
721   if (!out) {
722     cerr << filePath << endl;   
723     Error("WriteTransformations", "File not found.");
724     return false;
725   }
726   out.setf(std::ios::fixed);
727
728   WriteData1(out);
729   WriteData2(out);
730   
731   return true;
732 }  
733
734 //______________________________________________________________________________
735 Bool_t  AliMUONVGeometryBuilder::WriteSVMap(Bool_t rebuild) const
736 {
737 // Writes sensitive volume map into a file
738 // Returns true, if writing finished correctly.
739 // ---
740
741   // File path
742   TString filePath = gSystem->Getenv("ALICE_ROOT");
743   filePath += "/MUON/data/";
744   filePath += fSVMapFileName;
745   filePath += fgkOutFileNameSuffix;
746   
747   // Open input file
748   ofstream out(filePath, ios::out);
749   if (!out) {
750     cerr << filePath << endl;   
751     Error("WriteTransformations", "File not found.");
752     return false;
753   }
754   out.setf(std::ios::fixed);
755   
756   if (rebuild)  RebuildSVMaps();
757
758   WriteData3(out);
759   
760   return true;
761 }  
762