]> git.uio.no Git - u/mrichter/AliRoot.git/blame - FMD/AliFMDDetector.cxx
Correct raw data reconstruction in case of trigger
[u/mrichter/AliRoot.git] / FMD / AliFMDDetector.cxx
CommitLineData
1a1fdef7 1/**************************************************************************
2 * Copyright(c) 2004, 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 **************************************************************************/
1a1fdef7 15/* $Id$ */
c2fc1258 16/** @file AliFMDDetector.cxx
17 @author Christian Holm Christensen <cholm@nbi.dk>
18 @date Mon Mar 27 12:36:27 2006
19 @brief Sub-detector base class implementation
20*/
1a1fdef7 21
22//____________________________________________________________________
23//
24// Utility class to help implement the FMD geometry. This provides
25// the interface for the concrete geometry implementations of the FMD
26// sub-detectors.
27//
28// The AliFMDGeometry object owns the AliFMDDetector objects
29//
30// Latest changes by Christian Holm Christensen
31//
32#include "AliFMDDetector.h" // ALIFMDSUBDETECTOR_H
33#include "AliFMDRing.h" // ALIFMDRING_H
bf000c32 34#include "AliLog.h" // ALILOG_H
35#include <TGeoManager.h> // ROOT_TGeoManager
36#include <TGeoMatrix.h> // ROOT_TGeoMatrix
37#include <TMath.h> // ROOT_TMath
1a1fdef7 38
39//====================================================================
40ClassImp(AliFMDDetector)
41#if 0
42 ; // This is here to keep Emacs for indenting the next line
43#endif
44
45//____________________________________________________________________
46AliFMDDetector::AliFMDDetector(Int_t id, AliFMDRing* inner, AliFMDRing* outer)
47 : TNamed(Form("FMD%d", id), "Forward multiplicity ring"),
48 fId(id),
49 fInner(inner),
bf000c32 50 fOuter(outer),
51 fInnerTransforms(0),
52 fOuterTransforms(0)
1a1fdef7 53{
088f8e79 54 // Constructor
55 //
56 // ID Id of detector (1,2, or 3)
57 // INNER Inner ring geometry
58 // OUTER Outer ring geometry (if any)
59 //
1a1fdef7 60 SetHoneycombThickness();
61 SetAlThickness();
62 SetInnerHoneyLowR(0);
63 SetInnerHoneyHighR(0);
64 SetInnerZ(0);
65 SetOuterZ(0);
66 SetOuterHoneyLowR(0);
67 SetOuterHoneyHighR(0);
68}
69
088f8e79 70//____________________________________________________________________
71AliFMDDetector::AliFMDDetector(const AliFMDDetector& other)
72 : TNamed(other),
73 fId(other.fId),
74 fInner(other.fInner),
bf000c32 75 fOuter(other.fOuter),
76 fInnerTransforms(other.fInnerTransforms),
77 fOuterTransforms(other.fOuterTransforms)
088f8e79 78{
79 // Copy constructor
80 SetHoneycombThickness(other.GetHoneycombThickness());
81 SetAlThickness(other.GetAlThickness());
82 SetInnerHoneyLowR(other.GetInnerHoneyLowR());
83 SetInnerHoneyHighR(other.GetInnerHoneyHighR());
84 SetInnerZ(other.GetInnerZ());
85 SetOuterZ(other.GetOuterZ());
86 SetOuterHoneyLowR(other.GetOuterHoneyLowR());
87 SetOuterHoneyHighR(other.GetOuterHoneyHighR());
88}
89
90//____________________________________________________________________
91AliFMDDetector&
92AliFMDDetector::operator=(const AliFMDDetector& other)
93{
94 // Assignment operator
95 SetName(other.GetName());
96 SetTitle(other.GetTitle());
bf000c32 97 fId = other.fId;
98 fInner = other.fInner;
99 fOuter = other.fOuter;
100 fInnerTransforms = other.fInnerTransforms;
101 fOuterTransforms = other.fOuterTransforms;
088f8e79 102 SetHoneycombThickness(other.GetHoneycombThickness());
103 SetAlThickness(other.GetAlThickness());
104 SetInnerHoneyLowR(other.GetInnerHoneyLowR());
105 SetInnerHoneyHighR(other.GetInnerHoneyHighR());
106 SetInnerZ(other.GetInnerZ());
107 SetOuterZ(other.GetOuterZ());
108 SetOuterHoneyLowR(other.GetOuterHoneyLowR());
109 SetOuterHoneyHighR(other.GetOuterHoneyHighR());
110 return *this;
111}
112
1a1fdef7 113//____________________________________________________________________
114void
115AliFMDDetector::Init()
116{
088f8e79 117 // Initialize.
1a1fdef7 118 if (fInner) {
119 SetInnerHoneyLowR(fInner->GetLowR() + 1.);
120 SetInnerHoneyHighR(fInner->GetHighR() + 1.);
121 }
122 if (fOuter) {
123 SetOuterHoneyLowR(fOuter->GetLowR() + 1.);
124 SetOuterHoneyHighR(fOuter->GetHighR() + 1.);
bf000c32 125 }
126}
127
128//____________________________________________________________________
129Bool_t
130AliFMDDetector::HasAllTransforms(Char_t ring) const
131{
132 AliFMDRing* r = GetRing(ring);
133 if (!r) return kTRUE;
134 TObjArray* matricies = (r == fInner ? fInnerTransforms : fOuterTransforms);
135 if (!matricies) return kTRUE;
136 if (matricies->GetEntries() == r->GetNModules()) return kTRUE;
137 return kFALSE;
138}
139
140#define IS_NODE_THIS(name) \
141 (name[0] == 'F' && name[2] == 'M' && name[1] == Char_t(48+fId) && \
142 (name[3] == 'T' || name[3] == 'B'))
143#define IS_NODE_SENSOR(name) \
144 (name[0] == 'F' && name[2] == 'S' && name[3] == 'E')
145
146//____________________________________________________________________
147void
148AliFMDDetector::InitTransformations()
149{
150 if ((!fInner || (fInner && fInnerTransforms)) &&
151 (!fOuter || (fOuter && fOuterTransforms))) {
152 AliDebug(5, Form("Transforms for FMD%d already registered", fId));
153 return;
154 }
155 AliDebug(5, Form("Initializing transforms for FMD%d", fId));
156 if (!gGeoManager) {
157 AliFatal("No TGeoManager defined");
158 return;
159 }
160 TGeoVolume* topVolume = gGeoManager->GetTopVolume();
161 if (!topVolume) {
162 AliFatal("No top-level volume defined");
163 return;
164 }
165 // Make container of transforms
166 if (fInner && !fInnerTransforms)
167 fInnerTransforms = new TObjArray(fInner->GetNModules());
168 if (fOuter && !fOuterTransforms)
169 fOuterTransforms = new TObjArray(fOuter->GetNModules());
170
171 // Make an iterator
172 TGeoIterator next(topVolume);
173 TGeoNode* node = 0;
174
175 // Find the node corresponding to this detector, and then find the
176 // sensor volumes
177 Bool_t thisNodeFound = kFALSE;
178 Bool_t allInners = HasAllTransforms('I');
179 Bool_t allOuters = HasAllTransforms('O');
180
181 while ((node = static_cast<TGeoNode*>(next()))
182 && !(allInners && allOuters)) {
183 // Get nodes names
184 const Char_t* name = node->GetName();
185 if (!name) continue;
186 AliDebug(50, Form("Got volume %s", name));
187 // Check if this node is this detector
188 // The base offset for numbers in the ASCII table is 48
189 if (IS_NODE_THIS(name)) {
190 AliDebug(20, Form("Found detector node '%s' for FMD%d", name, fId));
191 thisNodeFound = kTRUE;
192 }
193 // if the detector was found, then we're on that branch, and we
194 // check if this node represents a module in that branch.
195 if (thisNodeFound && IS_NODE_SENSOR(name)) {
196 AliDebug(20, Form("Found sensor node '%s' for FMD%d", name, fId));
197 // Get the ring Id.
198 Char_t ringid = name[1];
199
200 // Get the approprate ring
201 AliFMDRing* ring = GetRing(ringid);
202 if (!ring) continue;
203
204 // Check whether we have all the modules we need for this ring,
205 // and if so, go on to the next node.
206 Bool_t& done = (ring == fInner ? allInners : allOuters);
207 if ((done = HasAllTransforms(ringid))) {
208 AliDebug(20, Form("Already has all module transforms for ring %c",
209 ringid));
210 continue;
211 }
212
213 // Get the approprate container
214 TObjArray* matricies = (ringid == 'i' || ringid == 'I'
215 ? fInnerTransforms : fOuterTransforms);
216
217 // Get the copy (module) number, and check that it hasn't
218 // already been added to the container.
219 Int_t copy = node->GetNumber();
220 if (matricies->At(copy)) {
221 AliWarning(Form("Have a transformation for module %d in ring %c",
222 copy, ringid));
223 continue;
224 }
225
226 // Get the global transformation matrix, and store it.
227 TGeoMatrix* trans = new TGeoHMatrix(*(next.GetCurrentMatrix()));
228 matricies->AddAt(trans, copy);
229
230 }
1a1fdef7 231 }
1a1fdef7 232}
233
234//____________________________________________________________________
235AliFMDRing*
236AliFMDDetector::GetRing(Char_t id) const
237{
088f8e79 238 // Get the specified ring
239 //
240 // ID Id of ring ('I' or 'O')
241 //
1a1fdef7 242 switch (id) {
243 case 'i':
244 case 'I': return GetInner();
245 case 'o':
246 case 'O': return GetOuter();
247 }
248 return 0;
249}
250
251//____________________________________________________________________
252Double_t
253AliFMDDetector::GetRingZ(Char_t id) const
254{
088f8e79 255 // Get the z-coordinate specified ring
256 //
257 // ID Id of ring ('I' or 'O')
258 //
1a1fdef7 259 switch (id) {
260 case 'i':
261 case 'I': return GetInnerZ();
262 case 'o':
263 case 'O': return GetOuterZ();
264 }
265 return 0;
266}
bf000c32 267
268//____________________________________________________________________
269TGeoMatrix*
270AliFMDDetector::FindTransform(Char_t ring, UShort_t sector) const
271{
272 // Find the transformation that corresponds to sector sector in ring
273 // ring.
274 TObjArray* matricies = 0;
275 switch (ring) {
276 case 'i': case 'I': matricies = fInnerTransforms; break;
277 case 'o': case 'O': matricies = fOuterTransforms; break;
278 }
279 if (!matricies) {
280 AliWarning(Form("Unknown ring %c of FMD%d", ring, fId));
281 return 0;
282 }
283 UInt_t module = sector / 2;
284 TGeoMatrix* m = static_cast<TGeoMatrix*>(matricies->At(module));
285 if (!m) {
286 AliWarning(Form("No matrix found for sector %d in FMD%d%c",
287 sector, fId, ring));
288 return 0;
289 }
290 return m;
291}
292
293
1a1fdef7 294//____________________________________________________________________
295void
bf000c32 296AliFMDDetector::Detector2XYZ(Char_t ring,
1a1fdef7 297 UShort_t sector,
298 UShort_t strip,
299 Double_t& x,
300 Double_t& y,
301 Double_t& z) const
302{
088f8e79 303 // Translate detector coordinates (this,ring,sector,strip) into
304 // (x,y,z) coordinates (in global reference frame)
1a1fdef7 305 AliFMDRing* r = GetRing(ring);
306 if (!r) return;
bf000c32 307#if 1
308 TGeoMatrix* m = FindTransform(ring, sector);
309 if (!m) return;
310 Double_t rho = r->GetStripRadius(strip);
311 Double_t phi = ((sector % 2) - .5) * r->GetTheta();
312 Double_t siThick = r->GetSiThickness();
313 Double_t modThick = (siThick
314 + r->GetPrintboardThickness()
315 + r->GetCopperThickness()
316 + r->GetChipThickness()
317 + r->GetSpacing());
318 AliDebug(10,Form("Rho %7.3f, angle %7.3f", rho, phi));
319# define DEGRAD TMath::Pi() / 180.
320 Double_t local[] = { rho * TMath::Cos(phi * DEGRAD),
321 rho * TMath::Sin(phi * DEGRAD),
322 -modThick + siThick / 2 };
323 Double_t master[3];
324 AliDebug(10, Form("Local (%7.3f,%7.3f,%7.3f)",local[0], local[1], local[2]));
325 m->LocalToMaster(local, master);
326 AliDebug(10, Form("Master (%7.3f,%7.3f,%7.3f)",
327 master[0],master[1],master[2]));
328 x = master[0];
329 y = master[1];
330 z = master[2];
331#else
1a1fdef7 332 z = GetRingZ(ring);
333 r->Detector2XYZ(sector, strip, x, y, z);
bf000c32 334#endif
1a1fdef7 335}
336
54e415a8 337//____________________________________________________________________
338Bool_t
339AliFMDDetector::XYZ2Detector(Double_t x,
340 Double_t y,
341 Double_t z,
342 Char_t& ring,
343 UShort_t& sector,
344 UShort_t& strip) const
345{
088f8e79 346 // Translate (x,y,z) coordinates (in global reference frame) into
347 // detector coordinates (this,ring,sector,strip).
54e415a8 348 AliFMDRing* rng = 0;
349 ring = -1;
350 for (int j = 0; j < 2; j++) {
351 rng = GetRing(j == 0 ? 'I' : 'O');
352 if (!rng) continue;
353 Double_t ringZ = GetRingZ(j == 0 ? 'I' : 'O');
354 Double_t modSpace = TMath::Sign(rng->GetModuleSpacing(), ringZ);
355 if (TMath::Abs(z - ringZ) < 0.01 ||
356 TMath::Abs(z - ringZ + modSpace) < 0.01) break;
357 rng = 0;
358 }
359 if (rng && rng->XYZ2Detector(x, y, z - GetRingZ(rng->GetId()),
360 sector, strip)) {
361 ring = rng->GetId();
362 return kTRUE;
363 }
364 return kFALSE;
365}
366
367
368
1a1fdef7 369//____________________________________________________________________
370//
371// EOF
372//