Line data Source code
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 12 : ClassImp(AliMUONContourHandler)
58 : ///\endcond
59 :
60 : //_____________________________________________________________________________
61 : AliMUONContourHandler::AliMUONContourHandler(Bool_t explodedView)
62 0 : : TObject(),
63 0 : fTransformations(0x0),
64 0 : fAllContourMap(0x0),
65 0 : fAllContourArray(0x0)
66 0 : {
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 0 : if ( explodedView )
76 : {
77 0 : fTransformations = GenerateTransformations(explodedView);
78 0 : }
79 :
80 0 : AliMUONManuContourMaker manuMaker(fTransformations);
81 :
82 0 : TObjArray* manus = manuMaker.GenerateManuContours(kTRUE);
83 :
84 0 : if (manus)
85 : {
86 0 : manus->SetOwner(kFALSE);
87 0 : GenerateAllContours(*manus);
88 : }
89 0 : delete manus;
90 0 : }
91 :
92 : //_____________________________________________________________________________
93 : AliMUONContourHandler::~AliMUONContourHandler()
94 0 : {
95 : /// Dtor
96 0 : delete fTransformations;
97 0 : delete fAllContourMap;
98 0 : delete fAllContourArray;
99 0 : }
100 :
101 : //______________________________________________________________________________
102 : Bool_t
103 : AliMUONContourHandler::Adopt(AliMUONContour* contour)
104 : {
105 : /// Adopt the given contour
106 0 : if ( GetContour(contour->GetName()) )
107 : {
108 : // contour already exists
109 0 : return kFALSE;
110 : }
111 0 : fAllContourMap->Add(new TObjString(contour->GetName()),contour);
112 0 : return kTRUE;
113 0 : }
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 0 : AliCodeTimerAuto("",0);
133 :
134 : Int_t start(0);
135 :
136 0 : if ( !fTransformations )
137 : {
138 : start = 2; // skip chamber and station contours, as we seem to be in 3D
139 : }
140 :
141 0 : TIter next(&manuContours);
142 : AliMUONContour* contour;
143 0 : TObjArray* mapArray = new TObjArray;
144 :
145 0 : while ( ( contour = static_cast<AliMUONContour*>(next()) ) )
146 : {
147 : // Key is something like station#/chamber#/de#/buspatch#/manu#
148 :
149 0 : TString key(contour->GetName());
150 0 : TObjArray* s = key.Tokenize("/");
151 0 : for ( Int_t i = start; i < s->GetLast(); ++i )
152 : {
153 0 : TMap* m = static_cast<TMap*>(mapArray->At(i));
154 0 : if (!m)
155 : {
156 0 : m = new TMap;
157 0 : if ( i > mapArray->GetSize() ) mapArray->Expand(i);
158 0 : mapArray->AddAt(m,i);
159 : }
160 0 : TString parent;
161 0 : for ( Int_t k = 0; k <= i; ++k )
162 : {
163 0 : TObjString* str = static_cast<TObjString*>(s->At(k));
164 0 : parent += str->String();
165 0 : if ( k < i ) parent += "/";
166 : }
167 0 : TString child(parent);
168 0 : child += "/";
169 0 : child += static_cast<TObjString*>(s->At(i+1))->String();
170 :
171 0 : TObjArray* ma = static_cast<TObjArray*>(m->GetValue(parent.Data()));
172 0 : if (!ma)
173 : {
174 0 : ma = new TObjArray;
175 0 : m->Add(new TObjString(parent.Data()),ma);
176 : }
177 0 : TPair* p = static_cast<TPair*>(ma->FindObject(child.Data()));
178 0 : if ( !p )
179 : {
180 0 : ma->Add(new TObjString(child.Data()));
181 : }
182 0 : }
183 0 : delete s;
184 0 : }
185 :
186 : return mapArray;
187 0 : }
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 0 : AliCodeTimerAuto("",0);
199 :
200 : // Get the list of contours to create
201 0 : TObjArray* mapArray = CreateContourList(manuContours);
202 :
203 0 : fAllContourMap = new TMap(20000,1);
204 0 : fAllContourMap->SetOwnerKeyValue(kTRUE,kTRUE);
205 :
206 0 : fAllContourArray = new TObjArray;
207 0 : fAllContourArray->SetOwner(kFALSE); // the map is the real owner of the contours
208 :
209 0 : TIter nextContour(&manuContours);
210 : AliMUONContour* contour(0x0);
211 :
212 : // start by adding the manu contours we begin with
213 0 : while ( ( contour = static_cast<AliMUONContour*>(nextContour()) ) )
214 : {
215 0 : fAllContourMap->Add(new TObjString(contour->GetName()),contour);
216 : }
217 :
218 0 : AliMUONContourMaker maker;
219 :
220 0 : 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 0 : TMap* a = static_cast<TMap*>(mapArray->At(i));
225 0 : TIter next3(a);
226 : TObjString* str;
227 0 : while ( ( str = static_cast<TObjString*>(next3()) ) )
228 : {
229 0 : TObjArray* m = static_cast<TObjArray*>(a->GetValue(str->String().Data()));
230 0 : TIter next4(m);
231 : TObjString* k;
232 0 : TObjArray subcontours;
233 0 : subcontours.SetOwner(kFALSE);
234 0 : while ( ( k = static_cast<TObjString*>(next4()) ) )
235 : {
236 0 : contour = static_cast<AliMUONContour*>(fAllContourMap->GetValue(k->String().Data()));
237 0 : if ( contour )
238 : {
239 0 : subcontours.Add(contour);
240 : }
241 : else
242 : {
243 0 : AliError(Form("Did not find contour %s",k->String().Data()));
244 : continue;
245 : }
246 : }
247 :
248 0 : contour = maker.MergeContour(subcontours,str->String().Data());
249 :
250 : bool error(kFALSE);
251 :
252 0 : if (!contour)
253 : {
254 : error=kTRUE;
255 0 : AliError(Form("ERROR : could not merge into %s",str->String().Data()));
256 : }
257 : else
258 : {
259 0 : if ( contour->Area().IsValid() == kFALSE )
260 : {
261 : error=kTRUE;
262 0 : AliError(Form("ERROR : area of contour %s is invalid",str->String().Data()));
263 : }
264 : }
265 :
266 0 : if (!error)
267 : {
268 0 : fAllContourMap->Add(new TObjString(str->String().Data()),contour);
269 0 : fAllContourArray->Add(contour);
270 : }
271 0 : }
272 0 : }
273 0 : }
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 0 : AliCodeTimerAuto("",0);
284 :
285 0 : AliMUONGeometryTransformer transformer;
286 0 : Bool_t ok = transformer.LoadGeometryData("transform.dat");
287 : // transformer.LoadGeometryData("geometry.root"); //FIXME: add a protection if geometry.root file does not exist
288 0 : if (!ok)
289 : {
290 0 : cout << "ERROR : cannot get geometry !" << endl;
291 0 : return 0x0;
292 : }
293 0 : AliMpExMap* transformations = new AliMpExMap;
294 0 : AliMpDEIterator deIt;
295 0 : deIt.First();
296 0 : while ( !deIt.IsDone() )
297 : {
298 0 : Int_t detElemId = deIt.CurrentDEId();
299 0 : const AliMUONGeometryDetElement* de = transformer.GetDetElement(detElemId);
300 :
301 0 : TGeoHMatrix* matrix = static_cast<TGeoHMatrix*>(de->GetGlobalTransformation()->Clone());
302 :
303 0 : if (exploded)
304 : {
305 0 : 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 0 : if ( AliMpDEManager::GetStationType(detElemId) == AliMp::kStation345 )
311 : {
312 0 : translation[0] *= xscale;
313 0 : translation[1] *= yscale;
314 0 : }
315 : else
316 : {
317 0 : Double_t xshift[] = { shift, -shift, -shift, shift };
318 0 : Double_t yshift[] = { shift, shift, -shift, -shift };
319 0 : Int_t ishift = detElemId % 100;
320 :
321 0 : translation[0] += xshift[ishift];
322 0 : translation[1] += yshift[ishift];
323 0 : }
324 0 : matrix->SetTranslation(translation);
325 0 : }
326 0 : transformations->Add(detElemId,matrix);
327 0 : deIt.Next();
328 : }
329 : return transformations;
330 0 : }
331 :
332 : //_____________________________________________________________________________
333 : AliMUONContour*
334 : AliMUONContourHandler::GetContour(const char* contourname) const
335 : {
336 : /// Get a given contour
337 0 : return static_cast<AliMUONContour*>(fAllContourMap->GetValue(contourname));
338 : }
339 :
340 : //_____________________________________________________________________________
341 : void
342 : AliMUONContourHandler::Print(Option_t* opt) const
343 : {
344 : /// printout
345 :
346 0 : if ( ! fAllContourMap ) return;
347 :
348 0 : cout << Form("Contour map : collisions = %5.3f size = %d capacity = %d",
349 0 : fAllContourMap->AverageCollisions(),
350 0 : fAllContourMap->GetSize(),
351 0 : fAllContourMap->Capacity()) << endl;
352 :
353 0 : TString sopt(opt);
354 0 : sopt.ToUpper();
355 :
356 0 : if ( sopt.Contains("ALL") || sopt.Contains("FULL") )
357 : {
358 0 : fAllContourMap->Print();
359 : }
360 0 : }
|