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 AliMUONContourHandler
21 /// Class used to create contours of the muon tracker parts :
22 /// manu, bus patches, detection elements, chambers.
24 /// \author Laurent Aphecetche, Subatech
27 #include "AliMUONContourHandler.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"
57 ClassImp(AliMUONContourHandler)
60 //_____________________________________________________________________________
61 AliMUONContourHandler::AliMUONContourHandler(Bool_t explodedView)
63 fTransformations(0x0),
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.
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)
77 fTransformations = GenerateTransformations(explodedView);
80 AliMUONManuContourMaker manuMaker(fTransformations);
82 TObjArray* manus = manuMaker.GenerateManuContours(kTRUE);
86 manus->SetOwner(kFALSE);
87 GenerateAllContours(*manus);
92 //_____________________________________________________________________________
93 AliMUONContourHandler::~AliMUONContourHandler()
96 delete fTransformations;
97 delete fAllContourMap;
98 delete fAllContourArray;
101 //______________________________________________________________________________
103 AliMUONContourHandler::Adopt(AliMUONContour* contour)
105 /// Adopt the given contour
106 if ( GetContour(contour->GetName()) )
108 // contour already exists
111 fAllContourMap->Add(new TObjString(contour->GetName()),contour);
115 //______________________________________________________________________________
117 AliMUONContourHandler::CreateContourList(const TObjArray& manuContours)
119 /// Create an array of maps of contour names
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 :
124 /// mapArray[0].key = station0
125 /// mapArray[0].value = map of strings { station0/chamber0, station0/chamber1 }
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).
132 AliCodeTimerAuto("",0);
136 if ( !fTransformations )
138 start = 2; // skip chamber and station contours, as we seem to be in 3D
141 TIter next(&manuContours);
142 AliMUONContour* contour;
143 TObjArray* mapArray = new TObjArray;
145 while ( ( contour = static_cast<AliMUONContour*>(next()) ) )
147 // Key is something like station#/chamber#/de#/buspatch#/manu#
149 TString key(contour->GetName());
150 TObjArray* s = key.Tokenize("/");
151 for ( Int_t i = start; i < s->GetLast(); ++i )
153 TMap* m = static_cast<TMap*>(mapArray->At(i));
157 if ( i > mapArray->GetSize() ) mapArray->Expand(i);
158 mapArray->AddAt(m,i);
161 for ( Int_t k = 0; k <= i; ++k )
163 TObjString* str = static_cast<TObjString*>(s->At(k));
164 parent += str->String();
165 if ( k < i ) parent += "/";
167 TString child(parent);
169 child += static_cast<TObjString*>(s->At(i+1))->String();
171 TObjArray* ma = static_cast<TObjArray*>(m->GetValue(parent.Data()));
175 m->Add(new TObjString(parent.Data()),ma);
177 TPair* p = static_cast<TPair*>(ma->FindObject(child.Data()));
180 ma->Add(new TObjString(child.Data()));
189 //______________________________________________________________________________
191 AliMUONContourHandler::GenerateAllContours(const TObjArray& manuContours)
193 /// From a map of manu contours, generate the compound contours (bp, de, etc...)
195 /// Note that manuContours should NOT be the owner of its contours,
196 /// as they are adopted by the array returned by this method.
198 AliCodeTimerAuto("",0);
200 // Get the list of contours to create
201 TObjArray* mapArray = CreateContourList(manuContours);
203 fAllContourMap = new TMap(20000,1);
204 fAllContourMap->SetOwnerKeyValue(kTRUE,kTRUE);
206 fAllContourArray = new TObjArray;
207 fAllContourArray->SetOwner(kFALSE); // the map is the real owner of the contours
209 TIter nextContour(&manuContours);
210 AliMUONContour* contour(0x0);
212 // start by adding the manu contours we begin with
213 while ( ( contour = static_cast<AliMUONContour*>(nextContour()) ) )
215 fAllContourMap->Add(new TObjString(contour->GetName()),contour);
218 AliMUONContourMaker maker;
220 for ( Int_t i = mapArray->GetLast(); i >= 1; --i )
221 // end at 1 to avoid merging different cathodes together, which
224 TMap* a = static_cast<TMap*>(mapArray->At(i));
227 while ( ( str = static_cast<TObjString*>(next3()) ) )
229 TObjArray* m = static_cast<TObjArray*>(a->GetValue(str->String().Data()));
232 TObjArray subcontours;
233 subcontours.SetOwner(kFALSE);
234 while ( ( k = static_cast<TObjString*>(next4()) ) )
236 contour = static_cast<AliMUONContour*>(fAllContourMap->GetValue(k->String().Data()));
239 subcontours.Add(contour);
243 AliError(Form("Did not find contour %s",k->String().Data()));
248 contour = maker.MergeContour(subcontours,str->String().Data());
255 AliError(Form("ERROR : could not merge into %s",str->String().Data()));
259 if ( contour->Area().IsValid() == kFALSE )
262 AliError(Form("ERROR : area of contour %s is invalid",str->String().Data()));
268 fAllContourMap->Add(new TObjString(str->String().Data()),contour);
269 fAllContourArray->Add(contour);
275 //_____________________________________________________________________________
277 AliMUONContourHandler::GenerateTransformations(Bool_t exploded)
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.
283 AliCodeTimerAuto("",0);
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
290 cout << "ERROR : cannot get geometry !" << endl;
293 AliMpExMap* transformations = new AliMpExMap;
294 AliMpDEIterator deIt;
296 while ( !deIt.IsDone() )
298 Int_t detElemId = deIt.CurrentDEId();
299 const AliMUONGeometryDetElement* de = transformer.GetDetElement(detElemId);
301 TGeoHMatrix* matrix = static_cast<TGeoHMatrix*>(de->GetGlobalTransformation()->Clone());
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
310 if ( AliMpDEManager::GetStationType(detElemId) == AliMp::kStation345 )
312 translation[0] *= xscale;
313 translation[1] *= yscale;
317 Double_t xshift[] = { shift, -shift, -shift, shift };
318 Double_t yshift[] = { shift, shift, -shift, -shift };
319 Int_t ishift = detElemId % 100;
321 translation[0] += xshift[ishift];
322 translation[1] += yshift[ishift];
324 matrix->SetTranslation(translation);
326 transformations->Add(detElemId,matrix);
329 return transformations;
332 //_____________________________________________________________________________
334 AliMUONContourHandler::GetContour(const char* contourname) const
336 /// Get a given contour
337 return static_cast<AliMUONContour*>(fAllContourMap->GetValue(contourname));
340 //_____________________________________________________________________________
342 AliMUONContourHandler::Print(Option_t* opt) const
346 if ( ! fAllContourMap ) return;
348 cout << Form("Contour map : collisions = %5.3f size = %d capacity = %d",
349 fAllContourMap->AverageCollisions(),
350 fAllContourMap->GetSize(),
351 fAllContourMap->Capacity()) << endl;
356 if ( sopt.Contains("ALL") || sopt.Contains("FULL") )
358 fAllContourMap->Print();