4c039060 |
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 | **************************************************************************/ |
88cb7938 |
15 | |
16 | /* $Id$ */ |
17 | |
e802be3e |
18 | //____________________________________________________________________ |
4347b38f |
19 | // |
37c4363a |
20 | // Forward Multiplicity Detector based on Silicon wafers. This class |
21 | // contains the base procedures for the Forward Multiplicity detector |
1a1fdef7 |
22 | // Detector consists of 3 sub-detectors FMD1, FMD2, and FMD3, each of |
23 | // which has 1 or 2 rings of silicon sensors. |
37c4363a |
24 | // |
25 | // This is the base class for all FMD manager classes. |
26 | // |
4347b38f |
27 | // The actual code is done by various separate classes. Below is |
28 | // diagram showing the relationship between the various FMD classes |
1a1fdef7 |
29 | // that handles the simulation |
4347b38f |
30 | // |
31 | // |
32 | // +----------+ +----------+ |
1a1fdef7 |
33 | // | AliFMDv1 | | AliFMDv0 | |
4347b38f |
34 | // +----------+ +----------+ |
1a1fdef7 |
35 | // | | +-----------------+ |
36 | // +----+--------------+ +--| AliFMDDigitizer | |
37 | // | | +-----------------+ |
38 | // | +---------------------+ | |
4ac75127 |
39 | // | +--| AliFMDBaseDigitizer |<--+ |
1a1fdef7 |
40 | // V 1 | +---------------------+ | |
41 | // +--------+<>--+ | +------------------+ |
42 | // | AliFMD | +--| AliFMDSDigitizer | |
43 | // +--------+<>--+ +------------------+ |
4ac75127 |
44 | // 1 | +-----------------+ |
45 | // +--| AliFMDSimulator | |
46 | // +-----------------+ |
47 | // ^ |
48 | // | |
49 | // +-------------+-------------+ |
50 | // | | |
51 | // +--------------------+ +-------------------+ |
52 | // | AliFMDGeoSimulator | | AliFMDG3Simulator | |
53 | // +--------------------+ +-------------------+ |
54 | // ^ ^ |
55 | // | | |
56 | // +-----------------------+ +----------------------+ |
57 | // | AliFMDGeoOldSimulator | | AliFMDG3OldSimulator | |
58 | // +-----------------------+ +----------------------+ |
4347b38f |
59 | // |
60 | // |
61 | // * AliFMD |
62 | // This defines the interface for the various parts of AliROOT that |
1a1fdef7 |
63 | // uses the FMD, like AliFMDSimulator, AliFMDDigitizer, |
64 | // AliFMDReconstructor, and so on. |
65 | // |
66 | // * AliFMDv0 |
67 | // This is a concrete implementation of the AliFMD interface. |
68 | // It is the responsibility of this class to create the FMD |
69 | // geometry. |
4347b38f |
70 | // |
71 | // * AliFMDv1 |
72 | // This is a concrete implementation of the AliFMD interface. |
73 | // It is the responsibility of this class to create the FMD |
74 | // geometry, process hits in the FMD, and serve hits and digits to |
75 | // the various clients. |
76 | // |
1a1fdef7 |
77 | // * AliFMDSimulator |
78 | // This is the base class for the FMD simulation tasks. The |
79 | // simulator tasks are responsible to implment the geoemtry, and |
80 | // process hits. |
4347b38f |
81 | // |
1a1fdef7 |
82 | // * AliFMDGeoSimulator |
83 | // This is a concrete implementation of the AliFMDSimulator that |
84 | // uses the TGeo classes directly only. |
37c4363a |
85 | // |
1a1fdef7 |
86 | // * AliFMDG3Simulator |
87 | // This is a concrete implementation of the AliFMDSimulator that |
88 | // uses the TVirtualMC interface with GEANT 3.21-like messages. |
37c4363a |
89 | // |
fe4da5cc |
90 | |
56b1929b |
91 | // These files are not in the same directory, so there's no reason to |
92 | // ask the preprocessor to search in the current directory for these |
93 | // files by including them with `#include "..."' |
1a1fdef7 |
94 | #include <math.h> // __CMATH__ |
56b1929b |
95 | #include <TClonesArray.h> // ROOT_TClonesArray |
96 | #include <TGeometry.h> // ROOT_TGeomtry |
97 | #include <TNode.h> // ROOT_TNode |
1a1fdef7 |
98 | #include <TXTRU.h> // ROOT_TXTRU |
99 | #include <TRotMatrix.h> // ROOT_TRotMatrix |
56b1929b |
100 | #include <TTUBE.h> // ROOT_TTUBE |
101 | #include <TTree.h> // ROOT_TTree |
56b1929b |
102 | #include <TBrowser.h> // ROOT_TBrowser |
103 | #include <TMath.h> // ROOT_TMath |
1a1fdef7 |
104 | #include <TVirtualMC.h> // ROOT_TVirtualMC |
56b1929b |
105 | |
106 | #include <AliRunDigitizer.h> // ALIRUNDIGITIZER_H |
107 | #include <AliLoader.h> // ALILOADER_H |
108 | #include <AliRun.h> // ALIRUN_H |
109 | #include <AliMC.h> // ALIMC_H |
110 | #include <AliLog.h> // ALILOG_H |
e802be3e |
111 | #include "AliFMD.h" // ALIFMD_H |
112 | #include "AliFMDDigit.h" // ALIFMDDIGIG_H |
113 | #include "AliFMDHit.h" // ALIFMDHIT_H |
1a1fdef7 |
114 | #include "AliFMDGeometry.h" // ALIFMDGEOMETRY_H |
115 | #include "AliFMDDetector.h" // ALIFMDDETECTOR_H |
116 | #include "AliFMDRing.h" // ALIFMDRING_H |
e802be3e |
117 | #include "AliFMDDigitizer.h" // ALIFMDDIGITIZER_H |
1a1fdef7 |
118 | #include "AliFMDSimulator.h" // ALIFMDSIMULATOR_H |
119 | #include "AliFMDG3Simulator.h" // ALIFMDG3SIMULATOR_H |
120 | #include "AliFMDGeoSimulator.h" // ALIFMDGEOSIMULATOR_H |
4ac75127 |
121 | #include "AliFMDG3OldSimulator.h" // ALIFMDG3OLDSIMULATOR_H |
122 | #include "AliFMDGeoOldSimulator.h" // ALIFMDGEOOLDSIMULATOR_H |
e802be3e |
123 | #include "AliFMDRawWriter.h" // ALIFMDRAWWRITER_H |
88cb7938 |
124 | |
4347b38f |
125 | //____________________________________________________________________ |
925e6570 |
126 | ClassImp(AliFMD) |
1a1fdef7 |
127 | #if 0 |
128 | ; // This is to keep Emacs from indenting the next line |
129 | #endif |
7e54281f |
130 | |
4347b38f |
131 | //____________________________________________________________________ |
132 | AliFMD::AliFMD() |
90da4514 |
133 | : AliDetector(), |
134 | fSDigits(0), |
afddaa11 |
135 | fNsdigits(0), |
1a1fdef7 |
136 | fDetailed(kTRUE), |
137 | fSimulator(0) |
fe4da5cc |
138 | { |
139 | // |
140 | // Default constructor for class AliFMD |
141 | // |
1a1fdef7 |
142 | AliDebug(10, "\tDefault CTOR"); |
4ac75127 |
143 | fHits = 0; |
144 | fDigits = 0; |
145 | fIshunt = 0; |
146 | fUseOld = kFALSE; |
147 | fUseDivided = kFALSE; |
148 | fUseAssembly = kFALSE; |
149 | fUseGeo = kTRUE; |
fe4da5cc |
150 | } |
dc8af42e |
151 | |
56b1929b |
152 | //____________________________________________________________________ |
153 | AliFMD::AliFMD(const AliFMD& other) |
154 | : AliDetector(other), |
56b1929b |
155 | fSDigits(other.fSDigits), |
156 | fNsdigits(other.fNsdigits), |
1a1fdef7 |
157 | fDetailed(other.fDetailed), |
158 | fSimulator(other.fSimulator) |
56b1929b |
159 | { |
160 | // Copy constructor |
4ac75127 |
161 | fUseOld = other.fUseOld; |
162 | fUseDivided = other.fUseDivided; |
163 | fUseAssembly = other.fUseAssembly; |
164 | fUseGeo = other.fUseGeo; |
56b1929b |
165 | } |
166 | |
4347b38f |
167 | //____________________________________________________________________ |
1a1fdef7 |
168 | AliFMD::AliFMD(const char *name, const char *title) |
4347b38f |
169 | : AliDetector (name, title), |
afddaa11 |
170 | fSDigits(0), |
171 | fNsdigits(0), |
1a1fdef7 |
172 | fDetailed(kTRUE), |
173 | fSimulator(0) |
fe4da5cc |
174 | { |
175 | // |
176 | // Standard constructor for Forward Multiplicity Detector |
177 | // |
1a1fdef7 |
178 | AliDebug(10, "\tStandard CTOR"); |
4ac75127 |
179 | fUseOld = kFALSE; |
180 | fUseDivided = kFALSE; |
181 | fUseAssembly = kFALSE; |
182 | fUseGeo = kTRUE; |
54240c8d |
183 | |
fe4da5cc |
184 | // Initialise Hit array |
4347b38f |
185 | HitsArray(); |
186 | gAlice->GetMCApp()->AddHitList(fHits); |
d1280e40 |
187 | |
4347b38f |
188 | // (S)Digits for the detectors disk |
189 | DigitsArray(); |
190 | SDigitsArray(); |
191 | |
192 | // CHC: What is this? |
dc8af42e |
193 | fIshunt = 0; |
4347b38f |
194 | SetMarkerColor(kRed); |
195 | SetLineColor(kYellow); |
fe4da5cc |
196 | } |
d28dcc0d |
197 | |
4347b38f |
198 | //____________________________________________________________________ |
dc8af42e |
199 | AliFMD::~AliFMD () |
d28dcc0d |
200 | { |
4347b38f |
201 | // Destructor for base class AliFMD |
202 | if (fHits) { |
203 | fHits->Delete(); |
204 | delete fHits; |
205 | fHits = 0; |
206 | } |
207 | if (fDigits) { |
208 | fDigits->Delete(); |
209 | delete fDigits; |
210 | fDigits = 0; |
211 | } |
212 | if (fSDigits) { |
213 | fSDigits->Delete(); |
214 | delete fSDigits; |
215 | fSDigits = 0; |
216 | } |
217 | } |
218 | |
56b1929b |
219 | //____________________________________________________________________ |
220 | AliFMD& |
221 | AliFMD::operator=(const AliFMD& other) |
222 | { |
223 | AliDetector::operator=(other); |
56b1929b |
224 | fSDigits = other.fSDigits; |
225 | fNsdigits = other.fNsdigits; |
1a1fdef7 |
226 | fDetailed = other.fDetailed; |
227 | fSimulator = other.fSimulator; |
228 | |
56b1929b |
229 | return *this; |
230 | } |
231 | |
4347b38f |
232 | //==================================================================== |
233 | // |
234 | // GEometry ANd Traking |
235 | // |
236 | //____________________________________________________________________ |
237 | void |
238 | AliFMD::CreateGeometry() |
239 | { |
4347b38f |
240 | // |
37c4363a |
241 | // Create the geometry of Forward Multiplicity Detector. The actual |
242 | // construction of the geometry is delegated to the class AliFMDRing |
243 | // and AliFMDSubDetector and the relevant derived classes. |
244 | // |
245 | // The flow of this member function is: |
246 | // |
247 | // FOR rings fInner and fOuter DO |
248 | // AliFMDRing::Init(); |
249 | // END FOR |
250 | // |
251 | // Set up hybrud card support (leg) volume shapes |
252 | // |
253 | // FOR rings fInner and fOuter DO |
254 | // AliFMDRing::SetupGeometry(); |
255 | // END FOR |
256 | // |
257 | // FOR subdetectors fFMD1, fFMD2, and fFMD3 DO |
258 | // AliFMDSubDetector::SetupGeomtry(); |
259 | // END FOR |
260 | // |
261 | // FOR subdetectors fFMD1, fFMD2, and fFMD3 DO |
262 | // AliFMDSubDetector::Geomtry(); |
263 | // END FOR |
1a1fdef7 |
264 | // |
265 | if (!fSimulator) { |
266 | AliFatal("Simulator object not made yet!"); |
267 | return; |
268 | } |
269 | fSimulator->DefineGeometry(); |
4347b38f |
270 | } |
271 | |
272 | //____________________________________________________________________ |
273 | void AliFMD::CreateMaterials() |
274 | { |
275 | // Register various materials and tracking mediums with the |
276 | // backend. |
277 | // |
824466d5 |
278 | AliDebug(10, "\tCreating materials"); |
56b1929b |
279 | |
1a1fdef7 |
280 | if (fSimulator) { |
281 | AliFatal("Simulator object already instantised!"); |
282 | return; |
4347b38f |
283 | } |
1a1fdef7 |
284 | AliFMDGeometry* geometry = AliFMDGeometry::Instance(); |
285 | geometry->Init(); |
4ac75127 |
286 | TVirtualMC* mc = TVirtualMC::GetMC(); |
287 | Bool_t geo = mc->IsRootGeometrySupported(); |
288 | if (geo && fUseGeo) { |
289 | if (fUseOld) |
290 | fSimulator = new AliFMDGeoOldSimulator(this, fDetailed); |
291 | else |
292 | fSimulator = new AliFMDGeoSimulator(this, fDetailed); |
293 | } |
294 | else { |
295 | if (fUseOld) |
296 | fSimulator = new AliFMDG3OldSimulator(this, fDetailed); |
297 | else |
298 | fSimulator = new AliFMDG3Simulator(this, fDetailed); |
299 | } |
300 | AliDebug(1, Form("using a %s as simulation backend", |
301 | fSimulator->IsA()->GetName())); |
302 | fSimulator->UseDivided(fUseDivided); |
303 | fSimulator->UseAssembly(fUseAssembly); |
1a1fdef7 |
304 | fSimulator->DefineMaterials(); |
d28dcc0d |
305 | } |
dc8af42e |
306 | |
4347b38f |
307 | //____________________________________________________________________ |
308 | void |
309 | AliFMD::Init() |
fe4da5cc |
310 | { |
311 | // |
4347b38f |
312 | // Initialis the FMD after it has been built |
313 | Int_t i; |
314 | // |
4951e003 |
315 | if (AliLog::GetGlobalDebugLevel()) { |
7c09877a |
316 | cout << "\n" << ClassName() << ": " << flush; |
317 | for (i = 0; i < 35; i++) cout << "*"; |
318 | cout << " FMD_INIT "; |
319 | for (i = 0; i < 35; i++) cout << "*"; |
320 | cout << "\n" << ClassName() << ": " << flush; |
4347b38f |
321 | // |
322 | // Here the FMD initialisation code (if any!) |
7c09877a |
323 | for (i = 0; i < 80; i++) cout << "*"; |
324 | cout << endl; |
4347b38f |
325 | } |
326 | // |
fe4da5cc |
327 | // |
fe4da5cc |
328 | } |
dc8af42e |
329 | |
54240c8d |
330 | //____________________________________________________________________ |
331 | void |
332 | AliFMD::FinishEvent() |
333 | { |
334 | if (fSimulator) fSimulator->EndEvent(); |
335 | } |
336 | |
337 | |
4347b38f |
338 | //==================================================================== |
339 | // |
340 | // Graphics and event display |
341 | // |
342 | //____________________________________________________________________ |
343 | void |
344 | AliFMD::BuildGeometry() |
b9a2d5e4 |
345 | { |
4347b38f |
346 | // |
347 | // Build simple ROOT TNode geometry for event display |
348 | // |
349 | // Build a simplified geometry of the FMD used for event display |
350 | // |
37c4363a |
351 | // The actual building of the TNodes is done by |
352 | // AliFMDSubDetector::SimpleGeometry. |
824466d5 |
353 | AliDebug(10, "\tCreating a simplified geometry"); |
b9a2d5e4 |
354 | |
1a1fdef7 |
355 | AliFMDGeometry* fmd = AliFMDGeometry::Instance(); |
356 | |
357 | static TXTRU* innerShape = 0; |
358 | static TXTRU* outerShape = 0; |
359 | static TObjArray* innerRot = 0; |
360 | static TObjArray* outerRot = 0; |
361 | |
362 | if (!innerShape || !outerShape) { |
363 | // Make the shapes for the modules |
364 | for (Int_t i = 0; i < 2; i++) { |
365 | AliFMDRing* r = 0; |
366 | switch (i) { |
367 | case 0: r = fmd->GetRing('I'); break; |
368 | case 1: r = fmd->GetRing('O'); break; |
369 | } |
370 | if (!r) { |
371 | AliError(Form("no ring found for i=%d", i)); |
372 | return; |
373 | } |
374 | Double_t siThick = r->GetSiThickness(); |
375 | const Int_t nv = r->GetNVerticies(); |
376 | Double_t theta = r->GetTheta(); |
377 | Int_t nmod = r->GetNModules(); |
378 | |
379 | TXTRU* shape = new TXTRU(r->GetName(), r->GetTitle(), "void", nv, 2); |
380 | for (Int_t j = 0; j < nv; j++) { |
381 | TVector2* vv = r->GetVertex(nv - 1 - j); |
382 | shape->DefineVertex(j, vv->X(), vv->Y()); |
383 | } |
384 | shape->DefineSection(0, -siThick / 2, 1, 0, 0); |
385 | shape->DefineSection(1, +siThick / 2, 1, 0, 0); |
386 | shape->SetLineColor(GetLineColor()); |
387 | |
388 | TObjArray* rots = new TObjArray(nmod); |
389 | for (Int_t j = 0; j < nmod; j++) { |
390 | Double_t th = (j + .5) * theta * 2; |
391 | TString name(Form("FMD_ring_%c_rot_%02d", r->GetId(), j)); |
392 | TString title(Form("FMD Ring %c Rotation # %d", r->GetId(), j)); |
393 | TRotMatrix* rot = new TRotMatrix(name.Data(), title.Data(), |
394 | 90, th, 90, fmod(90+th,360), 0, 0); |
395 | rots->AddAt(rot, j); |
396 | } |
397 | |
398 | switch (r->GetId()) { |
399 | case 'i': |
400 | case 'I': innerShape = shape; innerRot = rots; break; |
401 | case 'o': |
402 | case 'O': outerShape = shape; outerRot = rots; break; |
403 | } |
404 | } |
405 | } |
406 | |
4347b38f |
407 | TNode* top = gAlice->GetGeometry()->GetNode("alice"); |
408 | |
1a1fdef7 |
409 | for (Int_t i = 1; i <= 3; i++) { |
410 | AliFMDDetector* det = fmd->GetDetector(i); |
411 | if (!det) { |
412 | Warning("BuildGeometry", "FMD%d seems to be disabled", i); |
413 | continue; |
414 | } |
415 | Double_t w = 0; |
416 | Double_t rh = det->GetRing('I')->GetHighR(); |
417 | Char_t id = 'I'; |
418 | if (det->GetRing('O')) { |
419 | w = TMath::Abs(det->GetRingZ('O') - det->GetRingZ('I')); |
420 | id = (TMath::Abs(det->GetRingZ('O')) |
421 | > TMath::Abs(det->GetRingZ('I')) ? 'O' : 'I'); |
422 | rh = det->GetRing('O')->GetHighR(); |
423 | } |
424 | w += (det->GetRing(id)->GetModuleSpacing() + |
425 | det->GetRing(id)->GetSiThickness()); |
426 | TShape* shape = new TTUBE(det->GetName(), det->GetTitle(), "void", |
427 | det->GetRing('I')->GetLowR(), rh, w / 2); |
428 | Double_t z = (det->GetRingZ('I') - w / 2); |
429 | if (z > 0) z += det->GetRing(id)->GetModuleSpacing(); |
430 | top->cd(); |
431 | TNode* node = new TNode(det->GetName(), det->GetTitle(), shape, |
432 | 0, 0, z, 0); |
433 | fNodes->Add(node); |
434 | |
435 | for (Int_t j = 0; j < 2; j++) { |
436 | AliFMDRing* r = 0; |
437 | TShape* rshape = 0; |
438 | TObjArray* rots = 0; |
439 | switch (j) { |
440 | case 0: |
441 | r = det->GetRing('I'); rshape = innerShape; rots = innerRot; break; |
442 | case 1: |
443 | r = det->GetRing('O'); rshape = outerShape; rots = outerRot; break; |
444 | } |
445 | if (!r) continue; |
446 | |
447 | Double_t siThick = r->GetSiThickness(); |
448 | Int_t nmod = r->GetNModules(); |
449 | Double_t modspace = r->GetModuleSpacing(); |
450 | Double_t rz = - (z - det->GetRingZ(r->GetId())); |
451 | |
452 | for (Int_t k = 0; k < nmod; k++) { |
453 | node->cd(); |
454 | Double_t offz = (k % 2 == 1 ? modspace : 0); |
455 | TRotMatrix* rot = static_cast<TRotMatrix*>(rots->At(k)); |
456 | TString name(Form("%s%c_module_%02d", det->GetName(), r->GetId(),k)); |
457 | TString title(Form("%s%c Module %d", det->GetName(), r->GetId(),k)); |
458 | TNode* mnod = new TNode(name.Data(), title.Data(), rshape, |
459 | 0, 0, rz - siThick / 2 |
460 | + TMath::Sign(offz,z), rot); |
461 | mnod->SetLineColor(GetLineColor()); |
462 | fNodes->Add(mnod); |
463 | } // for (Int_t k = 0 ; ...) |
464 | } // for (Int_t j = 0 ; ...) |
465 | } // for (Int_t i = 1 ; ...) |
37c55dc0 |
466 | } |
88cb7938 |
467 | |
4347b38f |
468 | //____________________________________________________________________ |
469 | void |
470 | AliFMD::DrawDetector() |
fe4da5cc |
471 | { |
472 | // |
37c4363a |
473 | // Draw a shaded view of the Forward multiplicity detector |
fe4da5cc |
474 | // |
4347b38f |
475 | // DebugGuard guard("AliFMD::DrawDetector"); |
824466d5 |
476 | AliDebug(10, "\tDraw detector"); |
4347b38f |
477 | |
1a1fdef7 |
478 | #if 0 |
4347b38f |
479 | //Set ALIC mother transparent |
480 | gMC->Gsatt("ALIC","SEEN",0); |
4347b38f |
481 | // |
482 | gMC->Gdopt("hide", "on"); |
483 | gMC->Gdopt("shad", "on"); |
484 | gMC->Gsatt("*", "fill", 7); |
485 | gMC->SetClipBox("."); |
486 | gMC->SetClipBox("*", 0, 1000, -1000, 1000, -1000, 1000); |
487 | gMC->DefaultRange(); |
488 | gMC->Gdraw("alic", 40, 30, 0, 12, 12, .055, .055); |
489 | gMC->Gdhead(1111, "Forward Multiplicity Detector"); |
490 | gMC->Gdman(16, 10, "MAN"); |
491 | gMC->Gdopt("hide", "off"); |
1a1fdef7 |
492 | #endif |
fe4da5cc |
493 | } |
dc8af42e |
494 | |
4347b38f |
495 | //____________________________________________________________________ |
17323043 |
496 | Int_t |
4347b38f |
497 | AliFMD::DistanceToPrimitive(Int_t, Int_t) |
fe4da5cc |
498 | { |
499 | // |
500 | // Calculate the distance from the mouse to the FMD on the screen |
501 | // Dummy routine |
502 | // |
503 | return 9999; |
504 | } |
dc8af42e |
505 | |
4347b38f |
506 | //==================================================================== |
507 | // |
508 | // Hit and Digit managment |
509 | // |
510 | //____________________________________________________________________ |
511 | void |
512 | AliFMD::MakeBranch(Option_t * option) |
513 | { |
514 | // Create Tree branches for the FMD. |
37c4363a |
515 | // |
516 | // Options: |
517 | // |
518 | // H Make a branch of TClonesArray of AliFMDHit's |
519 | // D Make a branch of TClonesArray of AliFMDDigit's |
520 | // S Make a branch of TClonesArray of AliFMDSDigit's |
521 | // |
4347b38f |
522 | const Int_t kBufferSize = 16000; |
523 | TString branchname(GetName()); |
524 | TString opt(option); |
525 | |
526 | if (opt.Contains("H", TString::kIgnoreCase)) { |
527 | HitsArray(); |
528 | AliDetector::MakeBranch(option); |
529 | } |
530 | if (opt.Contains("D", TString::kIgnoreCase)) { |
531 | DigitsArray(); |
532 | MakeBranchInTree(fLoader->TreeD(), branchname.Data(), |
533 | &fDigits, kBufferSize, 0); |
534 | } |
535 | if (opt.Contains("S", TString::kIgnoreCase)) { |
536 | SDigitsArray(); |
537 | MakeBranchInTree(fLoader->TreeS(), branchname.Data(), |
538 | &fSDigits, kBufferSize, 0); |
539 | } |
540 | } |
541 | |
542 | //____________________________________________________________________ |
543 | void |
544 | AliFMD::SetTreeAddress() |
545 | { |
afddaa11 |
546 | // Set branch address for the Hits, Digits, and SDigits Tree. |
4347b38f |
547 | if (fLoader->TreeH()) HitsArray(); |
548 | AliDetector::SetTreeAddress(); |
549 | |
550 | TTree *treeD = fLoader->TreeD(); |
551 | if (treeD) { |
552 | DigitsArray(); |
553 | TBranch* branch = treeD->GetBranch ("FMD"); |
554 | if (branch) branch->SetAddress(&fDigits); |
555 | } |
556 | |
557 | TTree *treeS = fLoader->TreeS(); |
558 | if (treeS) { |
559 | SDigitsArray(); |
560 | TBranch* branch = treeS->GetBranch ("FMD"); |
561 | if (branch) branch->SetAddress(&fSDigits); |
562 | } |
563 | } |
564 | |
565 | |
566 | |
567 | //____________________________________________________________________ |
568 | void |
569 | AliFMD::SetHitsAddressBranch(TBranch *b) |
b9a2d5e4 |
570 | { |
37c4363a |
571 | // Set the TClonesArray to read hits into. |
4347b38f |
572 | b->SetAddress(&fHits); |
b9a2d5e4 |
573 | } |
574 | |
4347b38f |
575 | //____________________________________________________________________ |
576 | void |
577 | AliFMD::AddHit(Int_t track, Int_t *vol, Float_t *hits) |
578 | { |
579 | // Add a hit to the hits tree |
580 | // |
581 | // The information of the two arrays are decoded as |
582 | // |
583 | // Parameters |
584 | // track Track # |
585 | // ivol[0] [UShort_t ] Detector # |
586 | // ivol[1] [Char_t ] Ring ID |
587 | // ivol[2] [UShort_t ] Sector # |
588 | // ivol[3] [UShort_t ] Strip # |
589 | // hits[0] [Float_t ] Track's X-coordinate at hit |
590 | // hits[1] [Float_t ] Track's Y-coordinate at hit |
591 | // hits[3] [Float_t ] Track's Z-coordinate at hit |
592 | // hits[4] [Float_t ] X-component of track's momentum |
593 | // hits[5] [Float_t ] Y-component of track's momentum |
594 | // hits[6] [Float_t ] Z-component of track's momentum |
595 | // hits[7] [Float_t ] Energy deposited by track |
596 | // hits[8] [Int_t ] Track's particle Id # |
37c4363a |
597 | // hits[9] [Float_t ] Time when the track hit |
598 | // |
599 | // |
69b696b9 |
600 | AddHitByFields(track, |
601 | UShort_t(vol[0]), // Detector # |
602 | Char_t(vol[1]), // Ring ID |
603 | UShort_t(vol[2]), // Sector # |
604 | UShort_t(vol[3]), // Strip # |
605 | hits[0], // X |
606 | hits[1], // Y |
607 | hits[2], // Z |
608 | hits[3], // Px |
609 | hits[4], // Py |
610 | hits[5], // Pz |
611 | hits[6], // Energy loss |
612 | Int_t(hits[7]), // PDG |
613 | hits[8]); // Time |
4347b38f |
614 | } |
615 | |
616 | //____________________________________________________________________ |
54240c8d |
617 | AliFMDHit* |
69b696b9 |
618 | AliFMD::AddHitByFields(Int_t track, |
619 | UShort_t detector, |
620 | Char_t ring, |
621 | UShort_t sector, |
622 | UShort_t strip, |
623 | Float_t x, |
624 | Float_t y, |
625 | Float_t z, |
626 | Float_t px, |
627 | Float_t py, |
628 | Float_t pz, |
629 | Float_t edep, |
630 | Int_t pdg, |
631 | Float_t t) |
b9a2d5e4 |
632 | { |
dc8af42e |
633 | // |
4347b38f |
634 | // Add a hit to the list |
dc8af42e |
635 | // |
4347b38f |
636 | // Parameters: |
637 | // |
638 | // track Track # |
639 | // detector Detector # (1, 2, or 3) |
640 | // ring Ring ID ('I' or 'O') |
641 | // sector Sector # (For inner/outer rings: 0-19/0-39) |
642 | // strip Strip # (For inner/outer rings: 0-511/0-255) |
643 | // x Track's X-coordinate at hit |
644 | // y Track's Y-coordinate at hit |
645 | // z Track's Z-coordinate at hit |
646 | // px X-component of track's momentum |
647 | // py Y-component of track's momentum |
648 | // pz Z-component of track's momentum |
649 | // edep Energy deposited by track |
650 | // pdg Track's particle Id # |
651 | // t Time when the track hit |
652 | // |
653 | TClonesArray& a = *(HitsArray()); |
654 | // Search through the list of already registered hits, and see if we |
655 | // find a hit with the same parameters. If we do, then don't create |
656 | // a new hit, but rather update the energy deposited in the hit. |
657 | // This is done, so that a FLUKA based simulation will get the |
658 | // number of hits right, not just the enerrgy deposition. |
ac4c3fbb |
659 | AliFMDHit* hit = 0; |
4347b38f |
660 | for (Int_t i = 0; i < fNhits; i++) { |
661 | if (!a.At(i)) continue; |
ac4c3fbb |
662 | hit = static_cast<AliFMDHit*>(a.At(i)); |
4347b38f |
663 | if (hit->Detector() == detector |
664 | && hit->Ring() == ring |
665 | && hit->Sector() == sector |
666 | && hit->Strip() == strip |
667 | && hit->Track() == track) { |
37c4363a |
668 | Warning("AddHit", "already had a hit in FMD%d%c[%2d,%3d] for track # %d," |
669 | " adding energy (%f) to that hit (%f) -> %f", |
670 | detector, ring, sector, strip, track, edep, hit->Edep(), |
671 | hit->Edep() + edep); |
4347b38f |
672 | hit->SetEdep(hit->Edep() + edep); |
54240c8d |
673 | return hit; |
4347b38f |
674 | } |
675 | } |
676 | // If hit wasn't already registered, do so know. |
ac4c3fbb |
677 | hit = new (a[fNhits]) AliFMDHit(fIshunt, track, detector, ring, sector, |
678 | strip, x, y, z, px, py, pz, edep, pdg, t); |
4347b38f |
679 | fNhits++; |
54240c8d |
680 | return hit; |
b9a2d5e4 |
681 | } |
fe4da5cc |
682 | |
4347b38f |
683 | //____________________________________________________________________ |
684 | void |
69b696b9 |
685 | AliFMD::AddDigit(Int_t* digits, Int_t*) |
fe4da5cc |
686 | { |
4347b38f |
687 | // Add a digit to the Digit tree |
688 | // |
689 | // Paramters |
fe4da5cc |
690 | // |
4347b38f |
691 | // digits[0] [UShort_t] Detector # |
692 | // digits[1] [Char_t] Ring ID |
693 | // digits[2] [UShort_t] Sector # |
694 | // digits[3] [UShort_t] Strip # |
695 | // digits[4] [UShort_t] ADC Count |
696 | // digits[5] [Short_t] ADC Count, -1 if not used |
697 | // digits[6] [Short_t] ADC Count, -1 if not used |
698 | // |
69b696b9 |
699 | AddDigitByFields(UShort_t(digits[0]), // Detector # |
700 | Char_t(digits[1]), // Ring ID |
701 | UShort_t(digits[2]), // Sector # |
702 | UShort_t(digits[3]), // Strip # |
703 | UShort_t(digits[4]), // ADC Count1 |
704 | Short_t(digits[5]), // ADC Count2 |
705 | Short_t(digits[6])); // ADC Count3 |
4347b38f |
706 | } |
707 | |
708 | //____________________________________________________________________ |
709 | void |
69b696b9 |
710 | AliFMD::AddDigitByFields(UShort_t detector, |
711 | Char_t ring, |
712 | UShort_t sector, |
713 | UShort_t strip, |
714 | UShort_t count1, |
715 | Short_t count2, |
716 | Short_t count3) |
4347b38f |
717 | { |
718 | // add a real digit - as coming from data |
719 | // |
720 | // Parameters |
fe4da5cc |
721 | // |
4347b38f |
722 | // detector Detector # (1, 2, or 3) |
723 | // ring Ring ID ('I' or 'O') |
724 | // sector Sector # (For inner/outer rings: 0-19/0-39) |
725 | // strip Strip # (For inner/outer rings: 0-511/0-255) |
726 | // count1 ADC count (a 10-bit word) |
727 | // count2 ADC count (a 10-bit word), or -1 if not used |
728 | // count3 ADC count (a 10-bit word), or -1 if not used |
729 | TClonesArray& a = *(DigitsArray()); |
730 | |
731 | new (a[fNdigits++]) |
732 | AliFMDDigit(detector, ring, sector, strip, count1, count2, count3); |
733 | } |
734 | |
735 | //____________________________________________________________________ |
736 | void |
737 | AliFMD::AddSDigit(Int_t* digits) |
738 | { |
739 | // Add a digit to the SDigit tree |
740 | // |
741 | // Paramters |
b9a2d5e4 |
742 | // |
4347b38f |
743 | // digits[0] [UShort_t] Detector # |
744 | // digits[1] [Char_t] Ring ID |
745 | // digits[2] [UShort_t] Sector # |
746 | // digits[3] [UShort_t] Strip # |
747 | // digits[4] [Float_t] Total energy deposited |
748 | // digits[5] [UShort_t] ADC Count |
749 | // digits[6] [Short_t] ADC Count, -1 if not used |
750 | // digits[7] [Short_t] ADC Count, -1 if not used |
751 | // |
69b696b9 |
752 | AddSDigitByFields(UShort_t(digits[0]), // Detector # |
753 | Char_t(digits[1]), // Ring ID |
754 | UShort_t(digits[2]), // Sector # |
755 | UShort_t(digits[3]), // Strip # |
756 | Float_t(digits[4]), // Edep |
757 | UShort_t(digits[5]), // ADC Count1 |
758 | Short_t(digits[6]), // ADC Count2 |
759 | Short_t(digits[7])); // ADC Count3 |
4347b38f |
760 | } |
761 | |
762 | //____________________________________________________________________ |
763 | void |
69b696b9 |
764 | AliFMD::AddSDigitByFields(UShort_t detector, |
765 | Char_t ring, |
766 | UShort_t sector, |
767 | UShort_t strip, |
768 | Float_t edep, |
769 | UShort_t count1, |
770 | Short_t count2, |
771 | Short_t count3) |
4347b38f |
772 | { |
773 | // add a summable digit |
774 | // |
775 | // Parameters |
b9a2d5e4 |
776 | // |
4347b38f |
777 | // detector Detector # (1, 2, or 3) |
778 | // ring Ring ID ('I' or 'O') |
779 | // sector Sector # (For inner/outer rings: 0-19/0-39) |
780 | // strip Strip # (For inner/outer rings: 0-511/0-255) |
781 | // edep Total energy deposited |
782 | // count1 ADC count (a 10-bit word) |
783 | // count2 ADC count (a 10-bit word), or -1 if not used |
784 | // count3 ADC count (a 10-bit word), or -1 if not used |
37c4363a |
785 | // |
4347b38f |
786 | TClonesArray& a = *(SDigitsArray()); |
787 | |
788 | new (a[fNsdigits++]) |
789 | AliFMDSDigit(detector, ring, sector, strip, edep, count1, count2, count3); |
fe4da5cc |
790 | } |
4347b38f |
791 | |
792 | //____________________________________________________________________ |
793 | void |
794 | AliFMD::ResetSDigits() |
d28dcc0d |
795 | { |
4347b38f |
796 | // |
797 | // Reset number of digits and the digits array for this detector |
798 | // |
799 | fNsdigits = 0; |
800 | if (fSDigits) fSDigits->Clear(); |
801 | } |
802 | |
803 | |
804 | //____________________________________________________________________ |
805 | TClonesArray* |
806 | AliFMD::HitsArray() |
807 | { |
808 | // Initialize hit array if not already, and return pointer to it. |
809 | if (!fHits) { |
810 | fHits = new TClonesArray("AliFMDHit", 1000); |
811 | fNhits = 0; |
812 | } |
813 | return fHits; |
814 | } |
815 | |
816 | //____________________________________________________________________ |
817 | TClonesArray* |
818 | AliFMD::DigitsArray() |
819 | { |
820 | // Initialize digit array if not already, and return pointer to it. |
821 | if (!fDigits) { |
822 | fDigits = new TClonesArray("AliFMDDigit", 1000); |
823 | fNdigits = 0; |
824 | } |
825 | return fDigits; |
826 | } |
827 | |
828 | //____________________________________________________________________ |
829 | TClonesArray* |
830 | AliFMD::SDigitsArray() |
831 | { |
832 | // Initialize digit array if not already, and return pointer to it. |
833 | if (!fSDigits) { |
834 | fSDigits = new TClonesArray("AliFMDSDigit", 1000); |
835 | fNsdigits = 0; |
836 | } |
837 | return fSDigits; |
838 | } |
839 | |
840 | //==================================================================== |
841 | // |
842 | // Digitization |
843 | // |
844 | //____________________________________________________________________ |
845 | void |
846 | AliFMD::Hits2Digits() |
847 | { |
37c4363a |
848 | // Create AliFMDDigit's from AliFMDHit's. This is done by making a |
849 | // AliFMDDigitizer, and executing that code. |
850 | // |
a3537838 |
851 | Warning("Hits2Digits", "Try not to use this method.\n" |
852 | "Instead, use AliSimulator"); |
4347b38f |
853 | AliRunDigitizer* manager = new AliRunDigitizer(1, 1); |
854 | manager->SetInputStream(0, "galice.root"); |
855 | manager->SetOutputFile("H2Dfile"); |
dc8af42e |
856 | |
4347b38f |
857 | /* AliDigitizer* dig =*/ CreateDigitizer(manager); |
858 | manager->Exec(""); |
99d864b7 |
859 | delete manager; |
4347b38f |
860 | } |
861 | |
862 | //____________________________________________________________________ |
863 | void |
864 | AliFMD::Hits2SDigits() |
865 | { |
37c4363a |
866 | // Create AliFMDSDigit's from AliFMDHit's. This is done by creating |
867 | // an AliFMDSDigitizer object, and executing it. |
868 | // |
56b1929b |
869 | AliFMDSDigitizer* digitizer = new AliFMDSDigitizer("galice.root"); |
56b1929b |
870 | digitizer->Exec(""); |
99d864b7 |
871 | delete digitizer; |
4347b38f |
872 | } |
873 | |
dc8af42e |
874 | |
4347b38f |
875 | //____________________________________________________________________ |
876 | AliDigitizer* |
877 | AliFMD::CreateDigitizer(AliRunDigitizer* manager) const |
878 | { |
879 | // Create a digitizer object |
56b1929b |
880 | AliFMDDigitizer* digitizer = new AliFMDDigitizer(manager); |
56b1929b |
881 | return digitizer; |
4347b38f |
882 | } |
b9a2d5e4 |
883 | |
4347b38f |
884 | //==================================================================== |
885 | // |
886 | // Raw data simulation |
887 | // |
888 | //__________________________________________________________________ |
889 | void |
890 | AliFMD::Digits2Raw() |
891 | { |
37c4363a |
892 | // Turn digits into raw data. |
893 | // |
e802be3e |
894 | // This uses the class AliFMDRawWriter to do the job. Please refer |
895 | // to that class for more information. |
896 | AliFMDRawWriter writer(this); |
897 | writer.Exec(); |
b9a2d5e4 |
898 | } |
899 | |
4347b38f |
900 | |
901 | //==================================================================== |
902 | // |
903 | // Utility |
904 | // |
905 | //__________________________________________________________________ |
906 | void |
907 | AliFMD::Browse(TBrowser* b) |
908 | { |
37c4363a |
909 | // Browse this object. |
910 | // |
824466d5 |
911 | AliDebug(30, "\tBrowsing the FMD"); |
4347b38f |
912 | AliDetector::Browse(b); |
1a1fdef7 |
913 | if (fSimulator) b->Add(fSimulator); |
914 | b->Add(AliFMDGeometry::Instance()); |
4347b38f |
915 | } |
916 | |
4347b38f |
917 | //___________________________________________________________________ |
918 | // |
919 | // EOF |
920 | // |