]>
Commit | Line | Data |
---|---|---|
fef32488 | 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 | ||
b80faac0 | 54 | using std::cout; |
55 | using std::endl; | |
fef32488 | 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 | ||
e937ba7c | 75 | if ( explodedView ) |
76 | { | |
77 | fTransformations = GenerateTransformations(explodedView); | |
78 | } | |
79 | ||
fef32488 | 80 | AliMUONManuContourMaker manuMaker(fTransformations); |
e937ba7c | 81 | |
fef32488 | 82 | TObjArray* manus = manuMaker.GenerateManuContours(kTRUE); |
e937ba7c | 83 | |
fef32488 | 84 | if (manus) |
85 | { | |
86 | manus->SetOwner(kFALSE); | |
87 | GenerateAllContours(*manus); | |
88 | } | |
89 | delete manus; | |
90 | } | |
91 | ||
92 | //_____________________________________________________________________________ | |
93 | AliMUONContourHandler::~AliMUONContourHandler() | |
94 | { | |
95 | /// Dtor | |
e937ba7c | 96 | delete fTransformations; |
fef32488 | 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 | ||
99c136e1 | 132 | AliCodeTimerAuto("",0); |
fef32488 | 133 | |
e937ba7c | 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 | ||
fef32488 | 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("/"); | |
e937ba7c | 151 | for ( Int_t i = start; i < s->GetLast(); ++i ) |
fef32488 | 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 | ||
99c136e1 | 198 | AliCodeTimerAuto("",0); |
fef32488 | 199 | |
200 | // Get the list of contours to create | |
201 | TObjArray* mapArray = CreateContourList(manuContours); | |
202 | ||
fef32488 | 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 | { | |
13242232 | 243 | AliError(Form("Did not find contour %s",k->String().Data())); |
fef32488 | 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 | ||
99c136e1 | 283 | AliCodeTimerAuto("",0); |
fef32488 | 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 | |
e937ba7c | 342 | AliMUONContourHandler::Print(Option_t* opt) const |
fef32488 | 343 | { |
344 | /// printout | |
345 | ||
fc2293be | 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 | ||
e937ba7c | 353 | TString sopt(opt); |
354 | sopt.ToUpper(); | |
355 | ||
356 | if ( sopt.Contains("ALL") || sopt.Contains("FULL") ) | |
357 | { | |
358 | fAllContourMap->Print(); | |
359 | } | |
fef32488 | 360 | } |