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