next50 trigger mask in AliHLTGlobalEsdConverterComponent
[u/mrichter/AliRoot.git] / MUON / AliMUONContourHandler.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 ///
19 /// \class AliMUONContourHandler
20 /// 
21 /// Class used to create contours of the muon tracker parts :
22 /// manu, bus patches, detection elements, chambers.
23 ///
24 /// \author Laurent Aphecetche, Subatech
25 ///
26
27 #include "AliMUONContourHandler.h"
28
29 #include "AliCodeTimer.h"
30 #include "AliLog.h"
31 #include "AliMUONContour.h"
32 #include "AliMUONContourMaker.h"
33 #include "AliMUONGeometryDetElement.h"
34 #include "AliMUONGeometryTransformer.h"
35 #include "AliMUONManuContourMaker.h"
36 #include "AliMUONPolygon.h"
37 #include "AliMUONSegment.h"
38 #include "AliMpArea.h"
39 #include "AliMpCDB.h"
40 #include "AliMpDDLStore.h"
41 #include "AliMpDEManager.h"
42 #include "AliMpExMap.h"
43 #include <float.h>
44 #include "Riostream.h"
45 #include "TArrow.h"
46 #include "TCanvas.h"
47 #include "TFile.h"
48 #include "TGeoMatrix.h"
49 #include "TLine.h"
50 #include "TObjArray.h"
51 #include "TPolyLine.h"
52 #include "TSystem.h"
53
54 using std::cout;
55 using std::endl;
56 ///\cond CLASSIMP
57 ClassImp(AliMUONContourHandler)
58 ///\endcond
59
60 //_____________________________________________________________________________
61 AliMUONContourHandler::AliMUONContourHandler(Bool_t explodedView) 
62 : TObject(),
63 fTransformations(0x0),
64 fAllContourMap(0x0),
65 fAllContourArray(0x0)
66 {
67   /// ctor. If explodedView=kTRUE, we generate views that will look 
68   /// fine in 2D (i.e. won't show overlaps of DE as in reality)
69   /// Use kFALSE if you want realistic geometry, though.
70   ///
71   /// IMPORTANT : as we many MUON classes, this one cannot work
72   /// before you've loaded the mapping in memory (see e.g. AliMpCDB::LoadDDLStore)
73   ///
74   
75   if ( explodedView ) 
76   {
77     fTransformations = GenerateTransformations(explodedView);
78   }
79   
80   AliMUONManuContourMaker manuMaker(fTransformations);
81   
82   TObjArray* manus = manuMaker.GenerateManuContours(kTRUE);
83   
84   if (manus)
85   {
86     manus->SetOwner(kFALSE);
87     GenerateAllContours(*manus);
88   }
89   delete manus;
90 }
91
92 //_____________________________________________________________________________
93 AliMUONContourHandler::~AliMUONContourHandler()
94 {
95   /// Dtor
96   delete fTransformations;
97   delete fAllContourMap;
98   delete fAllContourArray;
99 }
100
101 //______________________________________________________________________________
102 Bool_t 
103 AliMUONContourHandler::Adopt(AliMUONContour* contour)
104 {
105   /// Adopt the given contour
106   if ( GetContour(contour->GetName()) ) 
107   {
108     // contour already exists
109     return kFALSE;
110   }
111   fAllContourMap->Add(new TObjString(contour->GetName()),contour);
112   return kTRUE;
113 }
114
115 //______________________________________________________________________________
116 TObjArray*
117 AliMUONContourHandler::CreateContourList(const TObjArray& manuContours)
118 {    
119   /// Create an array of maps of contour names
120   ///
121   /// Assyming that key is something like station#/chamber#/de#/buspatch#/manu#
122   /// the idea here is to put one TMap for each level in mapArray :
123   ///
124   /// mapArray[0].key = station0
125   /// mapArray[0].value = map of strings { station0/chamber0, station0/chamber1 }
126   ///
127   /// Then each entry in mapArray will be converted into a contour by
128   /// merging its children (e.g. station0 contour will be made from the merging
129   /// of station0/chamber0 and station0/chamber1 in the example above).
130   ///
131   
132   AliCodeTimerAuto("",0);
133   
134   Int_t start(0);
135   
136   if ( !fTransformations )
137   {
138     start = 2; // skip chamber and station contours, as we seem to be in 3D
139   }
140     
141   TIter next(&manuContours);
142   AliMUONContour* contour;
143   TObjArray* mapArray = new TObjArray;
144   
145   while ( ( contour = static_cast<AliMUONContour*>(next()) ) )
146   {
147     // Key is something like station#/chamber#/de#/buspatch#/manu#
148     
149     TString key(contour->GetName());
150     TObjArray* s = key.Tokenize("/");
151     for ( Int_t i = start; i < s->GetLast(); ++i ) 
152     {
153       TMap* m = static_cast<TMap*>(mapArray->At(i));
154       if (!m)
155       {
156         m = new TMap;
157         if ( i > mapArray->GetSize() ) mapArray->Expand(i);
158         mapArray->AddAt(m,i);
159       }
160       TString parent;
161       for ( Int_t k = 0; k <= i; ++k )
162       {
163         TObjString* str = static_cast<TObjString*>(s->At(k));
164         parent += str->String();
165         if ( k < i ) parent += "/";
166       }
167       TString child(parent);
168       child += "/";
169       child += static_cast<TObjString*>(s->At(i+1))->String();
170       
171       TObjArray* ma = static_cast<TObjArray*>(m->GetValue(parent.Data()));
172       if (!ma)
173       {
174         ma = new TObjArray;
175         m->Add(new TObjString(parent.Data()),ma);
176       }
177       TPair* p = static_cast<TPair*>(ma->FindObject(child.Data()));
178       if ( !p ) 
179       {
180         ma->Add(new TObjString(child.Data()));
181       }
182     }
183     delete s;
184   }
185   
186   return mapArray;
187 }
188
189 //______________________________________________________________________________
190 void
191 AliMUONContourHandler::GenerateAllContours(const TObjArray& manuContours)
192 {
193   /// From a map of manu contours, generate the compound contours (bp, de, etc...)
194   /// by merging them.
195   /// Note that manuContours should NOT be the owner of its contours,
196   /// as they are adopted by the array returned by this method.
197   
198   AliCodeTimerAuto("",0);
199   
200   // Get the list of contours to create
201   TObjArray* mapArray = CreateContourList(manuContours);
202   
203   fAllContourMap = new TMap(20000,1);
204   fAllContourMap->SetOwnerKeyValue(kTRUE,kTRUE);
205   
206   fAllContourArray = new TObjArray;
207   fAllContourArray->SetOwner(kFALSE); // the map is the real owner of the contours
208   
209   TIter nextContour(&manuContours);  
210   AliMUONContour* contour(0x0);
211   
212   // start by adding the manu contours we begin with
213   while ( ( contour = static_cast<AliMUONContour*>(nextContour()) ) )
214   {
215     fAllContourMap->Add(new TObjString(contour->GetName()),contour);
216   }
217   
218   AliMUONContourMaker maker;
219   
220   for ( Int_t i = mapArray->GetLast(); i >= 1; --i ) 
221     // end at 1 to avoid merging different cathodes together, which
222     // would not work...
223   {
224     TMap* a = static_cast<TMap*>(mapArray->At(i));
225     TIter next3(a);
226     TObjString* str;
227     while ( ( str = static_cast<TObjString*>(next3()) ) )
228     {
229       TObjArray* m = static_cast<TObjArray*>(a->GetValue(str->String().Data()));
230       TIter next4(m);
231       TObjString* k;
232       TObjArray subcontours;
233       subcontours.SetOwner(kFALSE);
234       while ( ( k = static_cast<TObjString*>(next4()) ) )
235       {
236         contour = static_cast<AliMUONContour*>(fAllContourMap->GetValue(k->String().Data()));
237         if ( contour ) 
238         {
239           subcontours.Add(contour);
240         }
241         else
242         {
243           AliError(Form("Did not find contour %s",k->String().Data()));
244           continue;
245         }
246       }
247       
248       contour = maker.MergeContour(subcontours,str->String().Data());
249       
250       bool error(kFALSE);
251       
252       if (!contour)
253       {
254         error=kTRUE;
255         AliError(Form("ERROR : could not merge into %s",str->String().Data()));
256       }
257       else
258       {
259         if ( contour->Area().IsValid() == kFALSE ) 
260         {
261           error=kTRUE;
262           AliError(Form("ERROR : area of contour %s is invalid",str->String().Data()));
263         }
264       }
265       
266       if (!error)
267       {
268         fAllContourMap->Add(new TObjString(str->String().Data()),contour);
269         fAllContourArray->Add(contour);
270       }
271     }
272   }
273 }
274
275 //_____________________________________________________________________________
276 AliMpExMap* 
277 AliMUONContourHandler::GenerateTransformations(Bool_t exploded)
278 {
279   /// Generate geometric transformations to be used to compute the contours
280   /// If exploded=kFALSE then we generate real transformations, otherwise
281   /// we generate tweaked ones that look fine on screen.
282   
283   AliCodeTimerAuto("",0);
284   
285   AliMUONGeometryTransformer transformer;
286   Bool_t ok = transformer.LoadGeometryData("transform.dat");
287   //  transformer.LoadGeometryData("geometry.root"); //FIXME: add a protection if geometry.root file does not exist
288   if (!ok)
289   {
290     cout << "ERROR : cannot get geometry !" << endl;
291     return 0x0;
292   }
293   AliMpExMap* transformations = new AliMpExMap;
294   AliMpDEIterator deIt;
295   deIt.First();
296   while ( !deIt.IsDone() )
297   {
298     Int_t detElemId = deIt.CurrentDEId();
299     const AliMUONGeometryDetElement* de = transformer.GetDetElement(detElemId);
300     
301     TGeoHMatrix* matrix = static_cast<TGeoHMatrix*>(de->GetGlobalTransformation()->Clone());
302
303     if (exploded)
304     {
305       Double_t* translation = matrix->GetTranslation();
306       Double_t xscale = 1.0;
307       Double_t yscale = 1.5;
308       Double_t shift = 5.0; // cm
309           
310       if ( AliMpDEManager::GetStationType(detElemId) == AliMp::kStation345 ) 
311       {
312         translation[0] *= xscale;
313         translation[1] *= yscale; 
314       }
315       else
316       {
317         Double_t xshift[] = { shift, -shift, -shift, shift };
318         Double_t yshift[] = { shift, shift, -shift, -shift };
319         Int_t ishift = detElemId % 100;
320         
321         translation[0] += xshift[ishift];
322         translation[1] += yshift[ishift];
323       }
324       matrix->SetTranslation(translation);
325     }
326     transformations->Add(detElemId,matrix);
327     deIt.Next();
328   }
329   return transformations;
330 }
331
332 //_____________________________________________________________________________
333 AliMUONContour* 
334 AliMUONContourHandler::GetContour(const char* contourname) const
335 {
336   /// Get a given contour
337   return static_cast<AliMUONContour*>(fAllContourMap->GetValue(contourname));
338 }
339
340 //_____________________________________________________________________________
341 void
342 AliMUONContourHandler::Print(Option_t* opt) const
343 {
344   /// printout
345   
346   if ( ! fAllContourMap )  return;
347   
348   cout << Form("Contour map : collisions = %5.3f size = %d capacity = %d", 
349                fAllContourMap->AverageCollisions(),
350                fAllContourMap->GetSize(),
351                fAllContourMap->Capacity()) << endl;
352
353   TString sopt(opt);
354   sopt.ToUpper();
355   
356   if ( sopt.Contains("ALL") || sopt.Contains("FULL") )
357   {
358     fAllContourMap->Print();
359   }
360 }