AliITSsimulation::fDetType correctly set in case of multiple events
[u/mrichter/AliRoot.git] / FMD / AliFMDGeometry.cxx
CommitLineData
1a1fdef7 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//
20// Forward Multiplicity Detector based on Silicon wafers.
21//
22// This class is a singleton that handles the geometry parameters of
23// the FMD detectors.
24//
25// The actual code is done by various separate classes. Below is
26// diagram showing the relationship between the various FMD classes
27// that handles the geometry
28//
29// +------------+
30// +- | AliFMDRing |
31// 2 | +------------+
32// +----------------+<>--+ |
33// | AliFMDGeometry | ^
34// +----------------+<>--+ V 1..2
35// 3 | +----------------+
36// +-| AliFMDDetector |
37// +----------------+
38// ^
39// |
40// +-------------+-------------+
41// | | |
42// +---------+ +---------+ +---------+
43// | AliFMD1 | | AliFMD2 | | AliFMD3 |
44// +---------+ +---------+ +---------+
45//
46//
47// * AliFMDRing
48// This class contains all stuff needed to do with a ring. It's
49// used by the AliFMDDetector objects to instantise inner and
50// outer rings. The AliFMDRing objects are shared by the
51// AliFMDDetector objects, and owned by the AliFMDv1 object.
52//
53// * AliFMD1, AliFMD2, and AliFMD3
54// These are specialisation of AliFMDDetector, that contains the
55// particularities of each of the sub-detector system. It is
56// envisioned that the classes should also define the support
57// volumes and material for each of the detectors.
58//
59//
60#include "AliFMDGeometry.h" // ALIFMDGEOMETRY_H
61#include "AliFMDRing.h" // ALIFMDRING_H
62#include "AliFMD1.h" // ALIFMD1_H
63#include "AliFMD2.h" // ALIFMD2_H
64#include "AliFMD3.h" // ALIFMD2_H
65#include "AliRecPoint.h" // ALIRECPOINT_H
66#include "AliLog.h" // ALIRECPOINT_H
67#include <TVector3.h> // ROOT_TVector3
68#include <TMatrix.h> // ROOT_TMatrix
69#include <TParticle.h> // ROOT_TParticle
70#include <Riostream.h>
54e415a8 71#ifndef USE_PRE_MOVE
72#include "AliFMDGeometryBuilder.h"
73#include <TArrayI.h>
74#include <TGeoManager.h>
75#include <TGeoVolume.h>
76#include <TGeoNode.h>
77static Int_t FindNodeDepth(const char* name, const char* volname);
78#endif
79
1a1fdef7 80
81//====================================================================
82ClassImp(AliFMDGeometry)
83#if 0
84 ; // This is here to keep Emacs for indenting the next line
85#endif
86
87//____________________________________________________________________
88AliFMDGeometry* AliFMDGeometry::fgInstance = 0;
89
90//____________________________________________________________________
91AliFMDGeometry*
92AliFMDGeometry::Instance()
93{
69b696b9 94 // Return (newly created) singleton instance
1a1fdef7 95 if (!fgInstance) fgInstance = new AliFMDGeometry;
96 return fgInstance;
97}
98
99//____________________________________________________________________
100AliFMDGeometry::AliFMDGeometry()
101 : AliGeometry("FMD", "Forward multiplicity")
102{
69b696b9 103 // PROTECTED
104 // Default constructor
54e415a8 105 fUseFMD1 = kTRUE;
106 fUseFMD2 = kTRUE;
107 fUseFMD3 = kTRUE;
108#ifndef USE_PRE_MOVE
109 fDetailed = kTRUE;
110 fUseAssembly = kTRUE;
111#endif
1a1fdef7 112 fInner = new AliFMDRing('I');
113 fOuter = new AliFMDRing('O');
114 fFMD1 = new AliFMD1(fInner);
115 fFMD2 = new AliFMD2(fInner, fOuter);
116 fFMD3 = new AliFMD3(fInner, fOuter);
117 fIsInitialized = kFALSE;
54e415a8 118 // fActive.Set(4);
119#ifndef USE_PRE_MOVE
120 fActive.Reset(-1);
121#endif
1a1fdef7 122}
123
124//____________________________________________________________________
69b696b9 125AliFMDGeometry::AliFMDGeometry(const AliFMDGeometry& other)
126 : AliGeometry(other),
127 fIsInitialized(other.fIsInitialized),
128 fInner(other.fInner),
129 fOuter(other.fOuter),
130 fFMD1(other.fFMD1),
131 fFMD2(other.fFMD2),
132 fFMD3(other.fFMD3),
133 fUseFMD1(other.fUseFMD1),
134 fUseFMD2(other.fUseFMD2),
135 fUseFMD3(other.fUseFMD3)
54e415a8 136#ifndef USE_PRE_MOVE
137 , fActive(other.fActive),
138 fDetailed(other.fDetailed),
139 fUseAssembly(other.fUseAssembly)
140#endif
69b696b9 141{
142 // PROTECTED
143 // Copy constructor
144}
145
146
147
148//____________________________________________________________________
149AliFMDGeometry&
150AliFMDGeometry::operator=(const AliFMDGeometry& other)
151{
152 // PROTECTED
153 // Assignment operator
154 fUseFMD1 = other.fUseFMD1;
155 fUseFMD2 = other.fUseFMD2;
156 fUseFMD3 = other.fUseFMD3;
157 fFMD1 = other.fFMD1;
158 fFMD2 = other.fFMD2;
159 fFMD3 = other.fFMD3;
160 fInner = other.fInner;
161 fOuter = other.fOuter;
162 fIsInitialized = other.fIsInitialized;
163 return *this;
164}
165
166//____________________________________________________________________
1a1fdef7 167void
168AliFMDGeometry::Init()
169{
69b696b9 170 // Initialize the the singleton if not done so already
1a1fdef7 171 if (fIsInitialized) return;
172 fInner->Init();
173 fOuter->Init();
174 fFMD1->Init();
175 fFMD2->Init();
176 fFMD3->Init();
177}
178
54e415a8 179#ifndef USE_PRE_MOVE
180//____________________________________________________________________
181void
182AliFMDGeometry::Build()
183{
184 if (!fBuilder) fBuilder = new AliFMDGeometryBuilder(fDetailed);
185 fBuilder->SetDetailed(fDetailed);
186 fBuilder->UseAssembly(fUseAssembly);
187 fBuilder->Exec();
188}
189
190//____________________________________________________________________
191void
192AliFMDGeometry::SetActive(Int_t* active, Int_t n)
193{
194 fActive.Set(n);
195 for (Int_t i = 0; i < n; i++) fActive[i] = active[i];
196}
197
198//____________________________________________________________________
199void
200AliFMDGeometry::AddActive(Int_t active)
201{
202 Int_t n = fActive.fN;
203 fActive.Set(n+1);
204 fActive[n] = active;
205}
206
207//____________________________________________________________________
208Bool_t
209AliFMDGeometry::IsActive(Int_t vol) const
210{
211 for (Int_t i = 0; i < fActive.fN; i++)
212 if (fActive[i] == vol) return kTRUE;
213 return kFALSE;
214}
215
216#endif
217
1a1fdef7 218//____________________________________________________________________
219AliFMDDetector*
220AliFMDGeometry::GetDetector(Int_t i) const
221{
69b696b9 222 // Get the ith detector. i should be one of 1, 2, or 3. If an
223 // invalid value is passed, 0 (NULL) is returned.
1a1fdef7 224 switch (i) {
225 case 1: return fUseFMD1 ? static_cast<AliFMDDetector*>(fFMD1) : 0;
226 case 2: return fUseFMD2 ? static_cast<AliFMDDetector*>(fFMD2) : 0;
227 case 3: return fUseFMD3 ? static_cast<AliFMDDetector*>(fFMD3) : 0;
228 }
229 return 0;
230}
231
232//____________________________________________________________________
233AliFMDRing*
234AliFMDGeometry::GetRing(Char_t i) const
235{
69b696b9 236 // Get the ith ring. i should be one of 'I' or 'O' (case
237 // insensitive). If an invalid parameter is passed, 0 (NULL) is
238 // returned.
1a1fdef7 239 switch (i) {
240 case 'I':
241 case 'i': return fInner;
242 case 'O':
243 case 'o': return fOuter;
244 }
245 return 0;
246}
247
248//____________________________________________________________________
249void
250AliFMDGeometry::Enable(Int_t i)
251{
69b696b9 252 // Enable the ith detector. i should be one of 1, 2, or 3
1a1fdef7 253 switch (i) {
254 case 1: fUseFMD1 = kTRUE; break;
255 case 2: fUseFMD2 = kTRUE; break;
256 case 3: fUseFMD3 = kTRUE; break;
257 }
258}
259
260//____________________________________________________________________
261void
262AliFMDGeometry::Disable(Int_t i)
263{
69b696b9 264 // Disable the ith detector. i should be one of 1, 2, or 3
1a1fdef7 265 switch (i) {
266 case 1: fUseFMD1 = kFALSE; break;
267 case 2: fUseFMD2 = kFALSE; break;
268 case 3: fUseFMD3 = kFALSE; break;
269 }
270}
271
272//____________________________________________________________________
273void
274AliFMDGeometry::Detector2XYZ(UShort_t detector,
69b696b9 275 Char_t ring,
276 UShort_t sector,
277 UShort_t strip,
278 Double_t& x,
279 Double_t& y,
280 Double_t& z) const
1a1fdef7 281{
69b696b9 282 // Translate detector coordinates (detector, ring, sector, strip) to
283 // spatial coordinates (x, y, z) in the master reference frame of
284 // ALICE.
1a1fdef7 285 AliFMDDetector* det = GetDetector(detector);
286 if (!det) return;
287 det->Detector2XYZ(ring, sector, strip, x, y, z);
288}
289
54e415a8 290//____________________________________________________________________
291Bool_t
292AliFMDGeometry::XYZ2Detector(Double_t x,
293 Double_t y,
294 Double_t z,
295 UShort_t& detector,
296 Char_t& ring,
297 UShort_t& sector,
298 UShort_t& strip) const
299{
300 // Translate spatial coordinates (x,y,z) in the master reference frame of
301 // ALICE to the detector coordinates (detector, ring, sector,
302 // strip). Note, that if this method is to be used in
303 // reconstruction or the like, then the input z-coordinate should be
304 // corrected for the events interactions points z-coordinate, like
305 // geom->XYZ2Detector(x,y,z-ipz,d,r,s,t);
306 AliFMDDetector* det = 0;
307 detector = 0;
308 for (int i = 1; i <= 3; i++) {
309 det = GetDetector(i);
310 if (!det) continue;
311 if (det->XYZ2Detector(x, y, z, ring, sector, strip)) {
312 detector = det->GetId();
313 return kTRUE;
314 }
315 }
316 return kFALSE;
317}
318
1a1fdef7 319
320//____________________________________________________________________
321void
322AliFMDGeometry::GetGlobal(const AliRecPoint* p,
323 TVector3& pos,
324 TMatrix& /* mat */) const
325{
69b696b9 326 // Get the global coordinates cooresponding to the reconstructed
327 // point p. The coordiates is returned in the 3-vector pos passed
328 // to this member function. The matrix mat is used for rotations.
1a1fdef7 329 GetGlobal(p, pos);
330}
331
332//____________________________________________________________________
333void
334AliFMDGeometry::GetGlobal(const AliRecPoint* p, TVector3& pos) const
335{
69b696b9 336 // Get the global coordinates cooresponding to the reconstructed
337 // point p. The coordiates is returned in the 3-vector pos passed
338 // to this member function. Note, as AliRecPoint only has places for
339 // 3 indicies, it is assumed that the ring hit is an inner ring -
340 // which obviously needn't be the case. This makes the member
341 // function pretty darn useless.
342 // FIXME: Implement this function to work with outer rings too.
1a1fdef7 343 Double_t x, y, z;
344 TVector3 local;
345 p->GetLocalPosition(local);
346 UShort_t detector = UShort_t(local.X());
347 UShort_t sector = UShort_t(local.Y());
348 UShort_t strip = UShort_t(local.Z());
349 Detector2XYZ(detector, 'I', sector, strip, x, y, z);
350 pos.SetXYZ(x, y, z);
351}
352
353//____________________________________________________________________
354Bool_t
355AliFMDGeometry::Impact(const TParticle* /* particle */) const
356{
69b696b9 357 // Return true, if the particle will hit the active detector
358 // elements, and false if not. Should be used for fast
359 // simulations. Note, that the function currently return false
360 // always.
361 // FIXME: Implement this function.
1a1fdef7 362 return kFALSE;
363}
364
54e415a8 365#ifndef USE_PRE_MOVE
366//____________________________________________________________________
367void
368AliFMDGeometry::ExtractGeomInfo()
369{
370 // Check the volume depth of some nodes, get the active volume
371 // numbers, and so forth.
372 //
373 // TODO: Here, we should actually also get the parameters of the
374 // shapes, like the verticies of the polygon shape that makes up the
375 // silicon sensor, the strip pitch, the ring radii, the z-positions,
376 // and so on - that is, all the geometric information we need for
377 // futher processing, such as simulation, digitization,
378 // reconstruction, etc.
379 Int_t detectorDepth = FindNodeDepth("FMD1_1", "ALIC");
380 Int_t ringDepth = FindNodeDepth(Form("FMDI_%d", Int_t('I')), "ALIC");
381 Int_t moduleDepth = FindNodeDepth("FIFV_0", "ALIC");
382 Int_t sectorDepth = FindNodeDepth("FISE_1", "ALIC");
383 fActive.Reset(-1);
384 AliDebug(1, Form("Geometry depths:\n"
385 " Sector: %d\n"
386 " Module: %d\n"
387 " Ring: %d\n"
388 " Detector: %d",
389 sectorDepth, moduleDepth, ringDepth, detectorDepth));
390 if (sectorDepth < 0 && moduleDepth < 0) {
391 fDetailed = kFALSE;
392 fSectorOff = -1;
393 fModuleOff = -1;
394 fRingOff = 0;
395 fDetectorOff = (ringDepth - detectorDepth);
396 TGeoVolume* actiVol = gGeoManager->GetVolume("FIAC");
397 TGeoVolume* actoVol = gGeoManager->GetVolume("FOAC");
398 if (actiVol) AddActive(actiVol->GetNumber());
399 if (actiVol) AddActive(actoVol->GetNumber());
400 }
401 else if (sectorDepth < 0) {
402 fDetailed = kFALSE;
403 fSectorOff = -1;
404 fModuleOff = 1;
405 fRingOff = (moduleDepth - ringDepth) + 1;
406 fDetectorOff = (moduleDepth - detectorDepth) + 1;
407 TGeoVolume* modiVol = gGeoManager->GetVolume("FIMO");
408 TGeoVolume* modoVol = gGeoManager->GetVolume("FOMO");
409 if (modiVol) AddActive(modiVol->GetNumber());
410 if (modoVol) AddActive(modoVol->GetNumber());
411 }
412 else {
413 Int_t stripDepth = FindNodeDepth("FIST_1", "ALIC");
414 fDetailed = kTRUE;
415 fSectorOff = (stripDepth - sectorDepth);
416 fModuleOff = (moduleDepth >= 0 ? (stripDepth - moduleDepth) : -1);
417 fRingOff = (stripDepth - ringDepth);
418 fDetectorOff = (stripDepth - detectorDepth );
419 TGeoVolume* striVol = gGeoManager->GetVolume("FIST");
420 TGeoVolume* stroVol = gGeoManager->GetVolume("FOST");
421 if (striVol) AddActive(striVol->GetNumber());
422 if (stroVol) AddActive(stroVol->GetNumber());
423 }
424 AliDebug(1, Form("Geometry offsets:\n"
425 " Sector: %d\n"
426 " Module: %d\n"
427 " Ring: %d\n"
428 " Detector: %d",
429 fSectorOff, fModuleOff, fRingOff, fDetectorOff));
430}
431
432
433//____________________________________________________________________
434static Int_t
435CheckNodes(TGeoNode* node, const char* name, Int_t& lvl)
436{
437 // If there's no node here.
438 if (!node) return -1;
439 // Check if it this one
440 TString sname(name);
441 if (sname == node->GetName()) return lvl;
442
443 // Check if the node is an immediate daugther
444 TObjArray* nodes = node->GetNodes();
445 if (!nodes) return -1;
446 // Increase the level, and search immediate sub nodes.
447 lvl++;
448 TGeoNode* found = static_cast<TGeoNode*>(nodes->FindObject(name));
449 if (found) return lvl;
450
451 // Check the sub node, if any of their sub-nodes match.
452 for (Int_t i = 0; i < nodes->GetEntries(); i++) {
453 TGeoNode* sub = static_cast<TGeoNode*>(nodes->At(i));
454 if (!sub) continue;
455 // Recurive check
456 if (CheckNodes(sub, name, lvl) >= 0) return lvl;
457 }
458 // If not found, decrease the level
459 lvl--;
460 return -1;
461}
462//____________________________________________________________________
463Int_t
464FindNodeDepth(const char* name, const char* volname)
465{
466 TGeoVolume* vol = gGeoManager->GetVolume(volname);
467 if (!vol) {
468 std::cerr << "No top volume defined" << std::endl;
469 return -1;
470 }
471 TObjArray* nodes = vol->GetNodes();
472 if (!nodes) {
473 std::cerr << "No nodes in top volume" << std::endl;
474 return -1;
475 }
476 TIter next(nodes);
477 TGeoNode* node = 0;
478 Int_t lvl = 0;
479 while ((node = static_cast<TGeoNode*>(next())))
480 if (CheckNodes(node, name, lvl) >= 0) return lvl;
481 return -1;
482}
483#endif
484
1a1fdef7 485//____________________________________________________________________
486//
487// EOF
488//