]> git.uio.no Git - u/mrichter/AliRoot.git/blame - MUON/AliMUONContourMakerTest.cxx
Protection against division by zero.
[u/mrichter/AliRoot.git] / MUON / AliMUONContourMakerTest.cxx
CommitLineData
0b936dc0 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 AliMUONContourMakerTest
20///
21/// Class used to test (and in particular time) the contour creation
22/// algorithms.
23///
24/// \author Laurent Aphecetche, Subatech
25///
26
27#include "AliMUONContourMakerTest.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///\cond CLASSIMP
55ClassImp(AliMUONContourMakerTest)
56///\endcond
57
58namespace
59{
60 //_____________________________________________________________________________
61 void Plot(TPolyLine& line, Bool_t orientation)
62 {
63 if ( !orientation )
64 {
65 line.Draw();
66 }
67 else
68 {
69 Double_t* x = line.GetX();
70 Double_t* y = line.GetY();
71
72 for ( Int_t i = 0; i < line.GetLastPoint(); ++i )
73 {
74 Double_t x1 = x[i];
75 Double_t y1 = y[i];
76 Double_t x2 = x[i+1];
77 Double_t y2 = y[i+1];
78
79 Bool_t horizontal = AliMUONSegment::AreEqual(y1,y2);
80
81 TLine* a = new TArrow(x1,y1,x2,y2,0.03,"->-");
82 if (horizontal)
83 {
84 a->SetLineStyle(3);
85 }
86 a->Draw();
87 }
88 }
89 }
90}
91
92//_____________________________________________________________________________
93AliMUONContourMakerTest::AliMUONContourMakerTest()
94{
95 /// ctor
96}
97
98//_____________________________________________________________________________
99AliMUONContourMakerTest::~AliMUONContourMakerTest()
100{
101 /// dtor
102}
103
104
105//______________________________________________________________________________
106TObjArray*
107AliMUONContourMakerTest::CreateContourList(const TObjArray& manuContours)
108{
109 /// Create an array of maps of contour names
110 ///
111 /// Assyming that key is something like station#/chamber#/de#/buspatch#/manu#
112 /// the idea here is to put one TMap for each level in mapArray :
113 ///
114 /// mapArray[0].key = station0
115 /// mapArray[0].value = map of strings { station0/chamber0, station0/chamber1 }
116 ///
117 /// Then each entry in mapArray will be converted into a contour by
118 /// merging its children (e.g. station0 contour will be made from the merging
119 /// of station0/chamber0 and station0/chamber1 in the example above).
120 ///
121
122 AliCodeTimerAuto("");
123
124 TIter next(&manuContours);
125 AliMUONContour* contour;
126 TObjArray* mapArray = new TObjArray;
127
128 while ( ( contour = static_cast<AliMUONContour*>(next()) ) )
129 {
130 // Key is something like station#/chamber#/de#/buspatch#/manu#
131
132 TString key(contour->GetName());
133 TObjArray* s = key.Tokenize("/");
134 for ( Int_t i = 0; i < s->GetLast(); ++i )
135 {
136 TMap* m = static_cast<TMap*>(mapArray->At(i));
137 if (!m)
138 {
139 m = new TMap;
140 if ( i > mapArray->GetSize() ) mapArray->Expand(i);
141 mapArray->AddAt(m,i);
142 }
143 TString parent;
144 for ( Int_t k = 0; k <= i; ++k )
145 {
146 TObjString* str = static_cast<TObjString*>(s->At(k));
147 parent += str->String();
148 if ( k < i ) parent += "/";
149 }
150 TString child(parent);
151 child += "/";
152 child += static_cast<TObjString*>(s->At(i+1))->String();
153
154 TObjArray* ma = static_cast<TObjArray*>(m->GetValue(parent.Data()));
155 if (!ma)
156 {
157 ma = new TObjArray;
158 m->Add(new TObjString(parent.Data()),ma);
159 }
160 TPair* p = static_cast<TPair*>(ma->FindObject(child.Data()));
161 if ( !p )
162 {
163 ma->Add(new TObjString(child.Data()));
164 }
165 }
166 delete s;
167 }
168
169 return mapArray;
170}
171
172//_____________________________________________________________________________
173void
174AliMUONContourMakerTest::Exec(const Option_t* opt)
175{
176 /// Main method
177 /// Generate the geometry transformations, then
178 /// contours for all manus, and then for all the elements
179 /// (bus patches, detection elements, etc...)
180
181 AliInfo("Resetting all timers before I start...");
182
183 AliCodeTimer::Instance()->Reset();
184
185 AliMpCDB::LoadDDLStore2();
186
187 AliCodeTimer::Instance()->Print();
188
189 AliInfo("Resetting all timers after loading the mapping...");
190
191 AliCodeTimer::Instance()->Reset();
192
193 AliCodeTimerAuto("");
194
195 AliMpExMap* real(0x0);
196 AliMpExMap* exploded(0x0);
197
198 GenerateTransformations(real,exploded);
199
200 TObjArray* manus(0x0);
201 TObjArray* all(0x0);
202
203 TString sopt(opt);
204
205 if ( sopt.Contains("MANU") || sopt.Contains("ALL") )
206 {
207 AliMUONManuContourMaker manuMaker(exploded);
208 manus = manuMaker.GenerateManuContours(kTRUE);
209 }
210
211 if ( sopt.Contains("ALL") && manus )
212 {
213 manus->SetOwner(kFALSE);
214 all = GenerateAllContours(*manus);
215 if ( sopt.Contains("SAVE") && all )
216 {
217 TFile f("AliMUONContourMakerTest.all.root","RECREATE");
218 all->Write("ALL",TObject::kSingleKey);
219 f.Close();
220 }
221
222 }
223
224 AliCodeTimer::Instance()->Print();
225
226 delete manus;
227 delete all;
228}
229
230//______________________________________________________________________________
231TObjArray*
232AliMUONContourMakerTest::GenerateAllContours(const TObjArray& manuContours)
233{
234 /// From a map of manu contours, generate the compound contours (bp, de, etc...)
235 /// by merging them.
236 /// Note that manuContours should NOT be the owner of its contours,
237 /// as they are adopted by the array returned by this method.
238
239 AliCodeTimerAuto("");
240
241 // Get the list of contours to create
242 TObjArray* mapArray = CreateContourList(manuContours);
243
244 // Now loop over the mapArray to actually create the contours
245 TIter next2(mapArray,kIterBackward);
246
247 TMap allContourMap;
248 allContourMap.SetOwnerKeyValue(kTRUE,kFALSE); // not owner of contours, as the returned array will be the owner
249 TObjArray* allContourArray = new TObjArray;
250 allContourArray->SetOwner(kTRUE);
251
252 TIter nextContour(&manuContours);
253 AliMUONContour* contour(0x0);
254
255 while ( ( contour = static_cast<AliMUONContour*>(nextContour()) ) )
256 {
257 allContourMap.Add(new TObjString(contour->GetName()),contour);
258 allContourArray->Add(contour);
259 }
260
261 AliMUONContourMaker maker;
262
263 for ( Int_t i = mapArray->GetLast(); i >= 1; --i )
264 // end at 1 to avoid merging different cathodes together, which
265 // would not work...
266 {
267 TMap* a = static_cast<TMap*>(mapArray->At(i));
268 TIter next3(a);
269 TObjString* str;
270 while ( ( str = static_cast<TObjString*>(next3()) ) )
271 {
272 TObjArray* m = static_cast<TObjArray*>(a->GetValue(str->String().Data()));
273 TIter next4(m);
274 TObjString* k;
275 TObjArray subcontours;
276 subcontours.SetOwner(kFALSE);
277 while ( ( k = static_cast<TObjString*>(next4()) ) )
278 {
279 contour = static_cast<AliMUONContour*>(allContourMap.GetValue(k->String().Data()));
280 if ( contour )
281 {
282 subcontours.Add(contour);
283 }
284 else
285 {
286 AliError(Form("Did not find contour %s",k->String().Data()))
287 return allContourArray;
288 }
289 }
290
291 contour = maker.MergeContour(subcontours,str->String().Data());
292
293 bool error(kFALSE);
294
295 if (!contour)
296 {
297 error=kTRUE;
298 AliError(Form("ERROR : could not merge into %s",str->String().Data()));
299 }
300 else
301 {
302 if ( contour->Area().IsValid() == kFALSE )
303 {
304 error=kTRUE;
305 AliError(Form("ERROR : area of contour %s is invalid",str->String().Data()));
306 }
307 }
308
309 if ( error )
310 {
311 // do it again, but get intermediate results to plot them
312 PrintAsPNG(str->String().Data(),subcontours);
313 if (contour )
314 {
315 StdoutToAliError(contour->Area().Print("B"););
316 }
317 AliError(Form("%d subcontours",subcontours.GetLast()+1));
318 StdoutToAliError(subcontours.Print(););
319 // check whether one of the subcontour itself is already invalid ?
320 TIter next(&subcontours);
321 AliMUONContour* cont;
322 while ( ( cont = static_cast<AliMUONContour*>(next()) ) )
323 {
324 if (!cont->IsValid())
325 {
326 AliError(Form("subcontour %s is invalid",cont->GetName()));
327 }
328 }
329 TFile f("subcontour.root","recreate");
330 subcontours.Write("fault",TObject::kSingleKey);
331 f.Close();
332
333 return allContourArray;
334 }
335
336 allContourArray->Add(contour);
337 allContourMap.Add(new TObjString(str->String().Data()),contour);
338 }
339 }
340
341 return allContourArray;
342}
343
344//_____________________________________________________________________________
345void
346AliMUONContourMakerTest::GenerateTransformations(AliMpExMap*& real, AliMpExMap*& exploded)
347{
348 /// Generate geometric transformations to be used to compute the contours
349 /// (real are, as the name implies, real ones, while the other ones are
350 /// a bit tweaked to look fine on screen).
351
352 AliCodeTimerAuto("");
353
354 AliMUONGeometryTransformer transformer;
355 Bool_t ok = transformer.LoadGeometryData("transform.dat");
356 // transformer.LoadGeometryData("geometry.root"); //FIXME: add a protection if geometry.root file does not exist
357 if (!ok)
358 {
359 cout << "ERROR : cannot get geometry !" << endl;
360 return;
361 }
362 real = new AliMpExMap;
363 exploded = new AliMpExMap;
364 AliMpDEIterator deIt;
365 deIt.First();
366 while ( !deIt.IsDone() )
367 {
368 Int_t detElemId = deIt.CurrentDEId();
369 const AliMUONGeometryDetElement* de = transformer.GetDetElement(detElemId);
370
371 real->Add(detElemId,de->GetGlobalTransformation()->Clone());
372
373 TGeoHMatrix* matrix = static_cast<TGeoHMatrix*>(de->GetGlobalTransformation()->Clone());
374 Double_t* translation = matrix->GetTranslation();
375
376 if ( AliMpDEManager::GetStationType(detElemId) == AliMp::kStation345 )
377 {
378 translation[0] *= 1.0;
379 translation[1] *= 1.5;
380 }
381 else
382 {
383 Double_t shift = 5; // cm
384 Double_t xshift[] = { shift, -shift, -shift, shift };
385 Double_t yshift[] = { shift, shift, -shift, -shift };
386 Int_t ishift = detElemId % 100;
387
388 translation[0] += xshift[ishift];
389 translation[1] += yshift[ishift];
390 }
391 matrix->SetTranslation(translation);
392 exploded->Add(detElemId,matrix);
393 deIt.Next();
394 }
395}
396
397//_____________________________________________________________________________
398void
399AliMUONContourMakerTest::GetBoundingBox(const TObjArray& array,
400 Double_t& xmin, Double_t& ymin,
401 Double_t& xmax, Double_t& ymax,
402 Bool_t enlarge) const
403{
404 /// Get the bounding box of all the contours in array.
405 /// If enlarge = kTRUE, the bounding box is "enlarged" a bit
406 /// (e.g. to leave some blank around a plot in a canvas)
407 ///
408
409 xmin=ymin=FLT_MAX;
410 xmax=ymax=-FLT_MAX;
411 TIter next(&array);
412 AliMUONContour* contour;
413 while ( ( contour = static_cast<AliMUONContour*>(next()) ) )
414 {
415 AliMpArea area(contour->Area());
416 xmin = TMath::Min(xmin,area.LeftBorder());
417 xmax = TMath::Max(xmax,area.RightBorder());
418 ymin = TMath::Min(ymin,area.DownBorder());
419 ymax = TMath::Max(ymax,area.UpBorder());
420 }
421
422 if (enlarge)
423 {
424 Double_t xsize = (xmax-xmin);
425 Double_t ysize = (ymax-ymin);
426 Double_t xshift = xsize*0.1;
427 Double_t yshift = ysize*0.1;
428 xmin -= xshift;
429 ymin -= yshift;
430 xmax = xmin + xsize + xshift*2;
431 ymax = ymin + ysize + yshift*2;
432 }
433}
434
435//_____________________________________________________________________________
436void
437AliMUONContourMakerTest::PlotSegments(const TObjArray& segments, Int_t lineColor, Int_t lineWidth, Bool_t orientation) const
438{
439 /// Plot an array of segments
440
441 TIter next(&segments);
442 AliMUONSegment* s;
443 while ( ( s = static_cast<AliMUONSegment*>(next()) ) )
444 {
445 TPolyLine* line = new TPolyLine(2);
446 line->SetPoint(0,s->StartX(),s->StartY());
447 line->SetPoint(1,s->EndX(),s->EndY());
448 line->SetLineColor(lineColor);
449 line->SetLineWidth(lineWidth);
450 ::Plot(*line,orientation);
451 }
452}
453
454//_____________________________________________________________________________
455void
456AliMUONContourMakerTest::Plot(const AliMUONPolygon& polygon,
457 Int_t lineColor, Int_t lineWidth,
458 Bool_t orientation) const
459{
460 /// Plot a polygon
461 TPolyLine* line = new TPolyLine(polygon.NumberOfVertices());
462 for ( Int_t i = 0; i < polygon.NumberOfVertices(); ++i )
463 {
464 line->SetPoint(i,polygon.X(i),polygon.Y(i));
465 }
466
467 line->SetLineColor(lineColor);
468 line->SetLineWidth(lineWidth);
469 ::Plot(*line,kFALSE);
470 if ( orientation ) ::Plot(*line,kTRUE);
471}
472
473//_____________________________________________________________________________
474void
475AliMUONContourMakerTest::Plot(const AliMUONContour& contour, Int_t lineColor, Int_t lineWidth,
476 Bool_t orientation) const
477{
478 /// Plot a contour (i.e. a set of polygons)
479 const TObjArray* polygons = contour.Polygons();
480 TIter next(polygons);
481 AliMUONPolygon* pol;
482 while ( ( pol = static_cast<AliMUONPolygon*>(next()) ) )
483 {
484 Plot(*pol,lineColor,lineWidth,orientation);
485 }
486}
487
488//_____________________________________________________________________________
489void
490AliMUONContourMakerTest::PlotContours(const TObjArray& array, Bool_t orientations) const
491{
492 /// Plot an array of contours
493 TIter next(&array);
494 AliMUONContour* contour;
495 while ( ( contour = static_cast<AliMUONContour*>(next()) ) )
496 {
497 Plot(*contour,5,4,orientations);
498 }
499}
500
501//______________________________________________________________________________
502void
503AliMUONContourMakerTest::PrintAsPNG(const char* basename, const TObjArray& contourArray,
504 const TObjArray* verticals, const TObjArray* horizontals) const
505{
506 /// Output contours and segments into a PNG file.
507 TCanvas* c = new TCanvas(basename,basename,0,0,600,600);
508 double xmin,ymin,xmax,ymax;
509 GetBoundingBox(contourArray,xmin,ymin,xmax,ymax,kTRUE);
510 c->Range(xmin,ymin,xmax,ymax);
511 PlotContours(contourArray,kTRUE);
512 c->Modified();
513 c->Update();
514 TString name(Form("%s",basename));
515 name.ReplaceAll("/","_");
516 c->Print(Form("%s.png",name.Data()));
517 if ( verticals || horizontals )
518 {
519 c->Clear();
520 if ( verticals ) PlotSegments(*verticals,1);
521 if ( horizontals) PlotSegments(*horizontals,2);
522 c->Modified();
523 c->Update();
524 name = Form("%s",basename);
525 name.ReplaceAll("/","_");
526 c->Print(Form("%s-segments.png",name.Data()));
527 }
528 delete c;
529}
530