1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
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 **************************************************************************/
19 /// \class AliMUONContourMakerTest
21 /// Class used to test (and in particular time) the contour creation
24 /// \author Laurent Aphecetche, Subatech
27 #include "AliMUONContourMakerTest.h"
29 #include "AliCodeTimer.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"
40 #include "AliMpDDLStore.h"
41 #include "AliMpDEManager.h"
42 #include "AliMpExMap.h"
44 #include "Riostream.h"
48 #include "TGeoMatrix.h"
50 #include "TObjArray.h"
51 #include "TPolyLine.h"
55 ClassImp(AliMUONContourMakerTest)
60 //_____________________________________________________________________________
61 void Plot(TPolyLine& line, Bool_t orientation)
69 Double_t* x = line.GetX();
70 Double_t* y = line.GetY();
72 for ( Int_t i = 0; i < line.GetLastPoint(); ++i )
79 Bool_t horizontal = AliMUONSegment::AreEqual(y1,y2);
81 TLine* a = new TArrow(x1,y1,x2,y2,0.03,"->-");
92 //_____________________________________________________________________________
93 AliMUONContourMakerTest::AliMUONContourMakerTest()
98 //_____________________________________________________________________________
99 AliMUONContourMakerTest::~AliMUONContourMakerTest()
105 //______________________________________________________________________________
107 AliMUONContourMakerTest::CreateContourList(const TObjArray& manuContours)
109 /// Create an array of maps of contour names
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 :
114 /// mapArray[0].key = station0
115 /// mapArray[0].value = map of strings { station0/chamber0, station0/chamber1 }
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).
122 AliCodeTimerAuto("");
124 TIter next(&manuContours);
125 AliMUONContour* contour;
126 TObjArray* mapArray = new TObjArray;
128 while ( ( contour = static_cast<AliMUONContour*>(next()) ) )
130 // Key is something like station#/chamber#/de#/buspatch#/manu#
132 TString key(contour->GetName());
133 TObjArray* s = key.Tokenize("/");
134 for ( Int_t i = 0; i < s->GetLast(); ++i )
136 TMap* m = static_cast<TMap*>(mapArray->At(i));
140 if ( i > mapArray->GetSize() ) mapArray->Expand(i);
141 mapArray->AddAt(m,i);
144 for ( Int_t k = 0; k <= i; ++k )
146 TObjString* str = static_cast<TObjString*>(s->At(k));
147 parent += str->String();
148 if ( k < i ) parent += "/";
150 TString child(parent);
152 child += static_cast<TObjString*>(s->At(i+1))->String();
154 TObjArray* ma = static_cast<TObjArray*>(m->GetValue(parent.Data()));
158 m->Add(new TObjString(parent.Data()),ma);
160 TPair* p = static_cast<TPair*>(ma->FindObject(child.Data()));
163 ma->Add(new TObjString(child.Data()));
172 //_____________________________________________________________________________
174 AliMUONContourMakerTest::Exec(const Option_t* opt)
177 /// Generate the geometry transformations, then
178 /// contours for all manus, and then for all the elements
179 /// (bus patches, detection elements, etc...)
181 AliInfo("Resetting all timers before I start...");
183 AliCodeTimer::Instance()->Reset();
185 AliMpCDB::LoadDDLStore2();
187 AliCodeTimer::Instance()->Print();
189 AliInfo("Resetting all timers after loading the mapping...");
191 AliCodeTimer::Instance()->Reset();
193 AliCodeTimerAuto("");
195 AliMpExMap* real(0x0);
196 AliMpExMap* exploded(0x0);
198 GenerateTransformations(real,exploded);
200 TObjArray* manus(0x0);
205 if ( sopt.Contains("MANU") || sopt.Contains("ALL") )
207 AliMUONManuContourMaker manuMaker(exploded);
208 manus = manuMaker.GenerateManuContours(kTRUE);
211 if ( sopt.Contains("ALL") && manus )
213 manus->SetOwner(kFALSE);
214 all = GenerateAllContours(*manus);
215 if ( sopt.Contains("SAVE") && all )
217 TFile f("AliMUONContourMakerTest.all.root","RECREATE");
218 all->Write("ALL",TObject::kSingleKey);
224 AliCodeTimer::Instance()->Print();
230 //______________________________________________________________________________
232 AliMUONContourMakerTest::GenerateAllContours(const TObjArray& manuContours)
234 /// From a map of manu contours, generate the compound contours (bp, de, etc...)
236 /// Note that manuContours should NOT be the owner of its contours,
237 /// as they are adopted by the array returned by this method.
239 AliCodeTimerAuto("");
241 // Get the list of contours to create
242 TObjArray* mapArray = CreateContourList(manuContours);
244 // Now loop over the mapArray to actually create the contours
245 TIter next2(mapArray,kIterBackward);
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);
252 TIter nextContour(&manuContours);
253 AliMUONContour* contour(0x0);
255 while ( ( contour = static_cast<AliMUONContour*>(nextContour()) ) )
257 allContourMap.Add(new TObjString(contour->GetName()),contour);
258 allContourArray->Add(contour);
261 AliMUONContourMaker maker;
263 for ( Int_t i = mapArray->GetLast(); i >= 1; --i )
264 // end at 1 to avoid merging different cathodes together, which
267 TMap* a = static_cast<TMap*>(mapArray->At(i));
270 while ( ( str = static_cast<TObjString*>(next3()) ) )
272 TObjArray* m = static_cast<TObjArray*>(a->GetValue(str->String().Data()));
275 TObjArray subcontours;
276 subcontours.SetOwner(kFALSE);
277 while ( ( k = static_cast<TObjString*>(next4()) ) )
279 contour = static_cast<AliMUONContour*>(allContourMap.GetValue(k->String().Data()));
282 subcontours.Add(contour);
286 AliError(Form("Did not find contour %s",k->String().Data()))
287 return allContourArray;
291 contour = maker.MergeContour(subcontours,str->String().Data());
298 AliError(Form("ERROR : could not merge into %s",str->String().Data()));
302 if ( contour->Area().IsValid() == kFALSE )
305 AliError(Form("ERROR : area of contour %s is invalid",str->String().Data()));
311 // do it again, but get intermediate results to plot them
312 PrintAsPNG(str->String().Data(),subcontours);
315 StdoutToAliError(contour->Area().Print("B"););
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()) ) )
324 if (!cont->IsValid())
326 AliError(Form("subcontour %s is invalid",cont->GetName()));
329 TFile f("subcontour.root","recreate");
330 subcontours.Write("fault",TObject::kSingleKey);
333 return allContourArray;
336 allContourArray->Add(contour);
337 allContourMap.Add(new TObjString(str->String().Data()),contour);
341 return allContourArray;
344 //_____________________________________________________________________________
346 AliMUONContourMakerTest::GenerateTransformations(AliMpExMap*& real, AliMpExMap*& exploded)
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).
352 AliCodeTimerAuto("");
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
359 cout << "ERROR : cannot get geometry !" << endl;
362 real = new AliMpExMap;
363 exploded = new AliMpExMap;
364 AliMpDEIterator deIt;
366 while ( !deIt.IsDone() )
368 Int_t detElemId = deIt.CurrentDEId();
369 const AliMUONGeometryDetElement* de = transformer.GetDetElement(detElemId);
371 real->Add(detElemId,de->GetGlobalTransformation()->Clone());
373 TGeoHMatrix* matrix = static_cast<TGeoHMatrix*>(de->GetGlobalTransformation()->Clone());
374 Double_t* translation = matrix->GetTranslation();
376 if ( AliMpDEManager::GetStationType(detElemId) == AliMp::kStation345 )
378 translation[0] *= 1.0;
379 translation[1] *= 1.5;
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;
388 translation[0] += xshift[ishift];
389 translation[1] += yshift[ishift];
391 matrix->SetTranslation(translation);
392 exploded->Add(detElemId,matrix);
397 //_____________________________________________________________________________
399 AliMUONContourMakerTest::GetBoundingBox(const TObjArray& array,
400 Double_t& xmin, Double_t& ymin,
401 Double_t& xmax, Double_t& ymax,
402 Bool_t enlarge) const
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)
412 AliMUONContour* contour;
413 while ( ( contour = static_cast<AliMUONContour*>(next()) ) )
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());
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;
430 xmax = xmin + xsize + xshift*2;
431 ymax = ymin + ysize + yshift*2;
435 //_____________________________________________________________________________
437 AliMUONContourMakerTest::PlotSegments(const TObjArray& segments, Int_t lineColor, Int_t lineWidth, Bool_t orientation) const
439 /// Plot an array of segments
441 TIter next(&segments);
443 while ( ( s = static_cast<AliMUONSegment*>(next()) ) )
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);
454 //_____________________________________________________________________________
456 AliMUONContourMakerTest::Plot(const AliMUONPolygon& polygon,
457 Int_t lineColor, Int_t lineWidth,
458 Bool_t orientation) const
461 TPolyLine* line = new TPolyLine(polygon.NumberOfVertices());
462 for ( Int_t i = 0; i < polygon.NumberOfVertices(); ++i )
464 line->SetPoint(i,polygon.X(i),polygon.Y(i));
467 line->SetLineColor(lineColor);
468 line->SetLineWidth(lineWidth);
469 ::Plot(*line,kFALSE);
470 if ( orientation ) ::Plot(*line,kTRUE);
473 //_____________________________________________________________________________
475 AliMUONContourMakerTest::Plot(const AliMUONContour& contour, Int_t lineColor, Int_t lineWidth,
476 Bool_t orientation) const
478 /// Plot a contour (i.e. a set of polygons)
479 const TObjArray* polygons = contour.Polygons();
480 TIter next(polygons);
482 while ( ( pol = static_cast<AliMUONPolygon*>(next()) ) )
484 Plot(*pol,lineColor,lineWidth,orientation);
488 //_____________________________________________________________________________
490 AliMUONContourMakerTest::PlotContours(const TObjArray& array, Bool_t orientations) const
492 /// Plot an array of contours
494 AliMUONContour* contour;
495 while ( ( contour = static_cast<AliMUONContour*>(next()) ) )
497 Plot(*contour,5,4,orientations);
501 //______________________________________________________________________________
503 AliMUONContourMakerTest::PrintAsPNG(const char* basename, const TObjArray& contourArray,
504 const TObjArray* verticals, const TObjArray* horizontals) const
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);
514 TString name(Form("%s",basename));
515 name.ReplaceAll("/","_");
516 c->Print(Form("%s.png",name.Data()));
517 if ( verticals || horizontals )
520 if ( verticals ) PlotSegments(*verticals,1);
521 if ( horizontals) PlotSegments(*horizontals,2);
524 name = Form("%s",basename);
525 name.ReplaceAll("/","_");
526 c->Print(Form("%s-segments.png",name.Data()));