4ac75127 |
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. This class |
21 | // contains the base procedures for the Forward Multiplicity detector |
22 | // Detector consists of 3 sub-detectors FMD1, FMD2, and FMD3, each of |
23 | // which has 1 or 2 rings of silicon sensors. |
24 | // |
25 | // This is the base class for all FMD manager classes. |
26 | // |
27 | // The actual code is done by various separate classes. Below is |
28 | // diagram showing the relationship between the various FMD classes |
29 | // that handles the simulation |
30 | // |
31 | // +--------+ 1 +-----------------+ |
32 | // | AliFMD |<>-----| AliFMDSimulator | |
33 | // +--------+ +-----------------+ |
34 | // ^ |
35 | // | |
36 | // +-------------+-------------+ |
37 | // | | |
38 | // +--------------------+ +-------------------+ |
39 | // | AliFMDGeoSimulator | | AliFMDG3Simulator | |
40 | // +--------------------+ +-------------------+ |
41 | // ^ |
42 | // | |
43 | // +----------------------+ |
44 | // | AliFMDG3OldSimulator | |
45 | // +----------------------+ |
46 | // |
47 | // |
48 | // * AliFMD |
49 | // This defines the interface for the various parts of AliROOT that |
50 | // uses the FMD, like AliFMDSimulator, AliFMDDigitizer, |
51 | // AliFMDReconstructor, and so on. |
52 | // |
53 | // * AliFMDSimulator |
54 | // This is the base class for the FMD simulation tasks. The |
55 | // simulator tasks are responsible to implment the geoemtry, and |
56 | // process hits. |
57 | // |
58 | // * AliFMDGeoSimulator |
59 | // This is a concrete implementation of the AliFMDSimulator that |
60 | // uses the TGeo classes directly only. This defines the active |
61 | // volume as an ONLY XTRU shape with a divided MANY TUBS shape |
62 | // inside to implement the particular shape of the silicon |
63 | // sensors. |
64 | // |
65 | // * AliFMDG3OldSimulator |
66 | // This is a concrete implementation of the AliFMDSimulator that |
67 | // uses the TVirtualMC interface with GEANT 3.21-like messages. |
68 | // This implements the active volume as a divided TUBS shape. Hits |
69 | // in the corners should be cut away at run time (but currently |
70 | // isn't). |
71 | // |
72 | #include <math.h> |
73 | #include "AliFMDG3OldSimulator.h" // ALIFMDG3OLDSIMULATOR_H |
74 | #include "AliFMDGeometry.h" // ALIFMDGEOMETRY_H |
75 | #include "AliFMDDetector.h" // ALIFMDDETECTOR_H |
76 | #include "AliFMDRing.h" // ALIFMDRING_H |
77 | #include "AliFMD1.h" // ALIFMD1_H |
78 | #include "AliFMD2.h" // ALIFMD2_H |
79 | #include "AliFMD3.h" // ALIFMD3_H |
80 | #include "AliFMD.h" // ALIFMD_H |
81 | #include <AliLog.h> // ALILOG_H |
82 | #include <TVector2.h> // ROOT_TVector2 |
83 | #include <TVirtualMC.h> // ROOT_TVirtualMC |
84 | #include <TArrayI.h> // ROOT_TArrayI |
85 | |
86 | //==================================================================== |
87 | ClassImp(AliFMDG3OldSimulator) |
88 | #if 0 |
89 | ; // This is here to keep Emacs for indenting the next line |
90 | #endif |
91 | |
92 | //____________________________________________________________________ |
93 | AliFMDG3OldSimulator::AliFMDG3OldSimulator() |
94 | { |
95 | // Default constructor |
96 | fSectorOff = 1; |
97 | fModuleOff = -1; |
98 | fRingOff = 3; |
99 | fDetectorOff = 4; |
100 | fUseDivided = kTRUE; |
101 | } |
102 | |
103 | //____________________________________________________________________ |
104 | AliFMDG3OldSimulator::AliFMDG3OldSimulator(AliFMD* fmd, Bool_t detailed) |
105 | : AliFMDG3Simulator(fmd, detailed) |
106 | { |
107 | // Normal constructor |
108 | // |
109 | // Parameters: |
110 | // |
111 | // fmd Pointer to AliFMD object |
112 | // detailed Whether to make a detailed simulation or not |
113 | // |
114 | fSectorOff = 1; |
115 | fModuleOff = -1; |
116 | fRingOff = 3; |
117 | fDetectorOff = 4; |
118 | fUseDivided = detailed; |
119 | } |
120 | |
121 | //____________________________________________________________________ |
122 | Bool_t |
123 | AliFMDG3OldSimulator::RingGeometry(AliFMDRing* r) |
124 | { |
125 | // Setup the geometry of a ring. The defined TGeoVolume is |
126 | // returned, and should be used when setting up the rest of the |
127 | // volumes. |
128 | // |
129 | // Parameters: |
130 | // |
131 | // r Pointer to ring geometry object |
132 | // |
133 | // Returns: |
134 | // true on success |
135 | // |
136 | if (!r) { |
137 | AliError("Didn't get a ring object"); |
138 | return kFALSE; |
139 | } |
140 | Char_t id = r->GetId(); |
141 | Double_t siThick = r->GetSiThickness(); |
142 | // const Int_t nv = r->GetNVerticies(); |
54240c8d |
143 | //TVector2* a = r->GetVertex(5); |
4ac75127 |
144 | TVector2* b = r->GetVertex(3); |
54240c8d |
145 | //TVector2* c = r->GetVertex(4); |
4ac75127 |
146 | Double_t theta = r->GetTheta(); |
54240c8d |
147 | //Double_t off = (TMath::Tan(TMath::Pi() * theta / 180) |
148 | // * r->GetBondingWidth()); |
4ac75127 |
149 | Double_t rmax = b->Mod(); |
150 | Double_t rmin = r->GetLowR(); |
151 | Double_t pcbThick = r->GetPrintboardThickness(); |
152 | Double_t copperThick = r->GetCopperThickness(); // .01; |
153 | Double_t chipThick = r->GetChipThickness(); // .01; |
54240c8d |
154 | //Double_t modSpace = r->GetModuleSpacing(); |
155 | //Double_t legr = r->GetLegRadius(); |
156 | //Double_t legl = r->GetLegLength(); |
157 | //Double_t legoff = r->GetLegOffset(); |
4ac75127 |
158 | Int_t ns = r->GetNStrips(); |
54240c8d |
159 | Double_t space = r->GetSpacing(); |
4ac75127 |
160 | Int_t nsec = Int_t(360 / theta); |
54240c8d |
161 | //Double_t stripoff = a->Mod(); |
162 | //Double_t dstrip = (rmax - stripoff) / ns; |
4ac75127 |
163 | Double_t par[10]; |
164 | TString name; |
165 | TString name2; |
166 | TVirtualMC* mc = TVirtualMC::GetMC(); |
167 | |
168 | Int_t siId = fFMD->GetIdtmed()->At(kSiId); |
169 | Int_t airId = fFMD->GetIdtmed()->At(kAirId); |
170 | Int_t pcbId = fFMD->GetIdtmed()->At(kPcbId); |
54240c8d |
171 | //Int_t plaId = fFMD->GetIdtmed()->At(kPlasticId); |
4ac75127 |
172 | Int_t copId = fFMD->GetIdtmed()->At(kCopperId); |
173 | Int_t chiId = fFMD->GetIdtmed()->At(kSiChipId); |
174 | |
175 | Double_t ringWidth = (siThick + 2 * (pcbThick + copperThick + chipThick)); |
176 | // Virtual volume shape to divide - This volume is only defined if |
177 | // the geometry is set to be detailed. |
178 | // Ring mother volume |
179 | par[0] = rmin; |
180 | par[1] = rmax; |
181 | par[2] = ringWidth / 2; |
182 | name = Form(fgkRingName, id); |
183 | mc->Gsvolu(name.Data(), "TUBE", airId, par, 3); |
184 | |
185 | par[2] = siThick / 2; |
186 | name2 = name; |
187 | name = Form(fgkActiveName, id); |
188 | Double_t z = - ringWidth / 2 + siThick / 2; |
54240c8d |
189 | mc->Gsvolu(name.Data(), "TUBE", siId, par, 3); |
4ac75127 |
190 | mc->Gspos(name.Data(), 1, name2.Data(), 0, 0, z, 0); |
191 | |
192 | Int_t sid = mc->VolId(name.Data()); |
193 | if (fUseDivided) { |
194 | name2 = name; |
195 | name = Form(fgkSectorName, id); |
196 | mc->Gsdvn(name.Data(), name2.Data(), nsec, 2); |
197 | |
198 | name2 = name; |
199 | name = Form(fgkStripName, id); |
200 | mc->Gsdvn(name.Data(), name2.Data(), ns, 1); |
201 | sid = mc->VolId(name.Data()); |
202 | AliDebug(10, Form("Got volume id %d for volume %s", sid, name.Data())); |
203 | } |
204 | |
205 | switch (id) { |
206 | case 'i': |
207 | case 'I': fActiveId[0] = sid; break; |
208 | case 'o': |
209 | case 'O': fActiveId[2] = sid; break; |
210 | } |
211 | |
212 | // Shape of Printed circuit Board |
213 | Double_t boardThick = (pcbThick + copperThick + chipThick); |
54240c8d |
214 | par[0] = rmin + .1; |
4ac75127 |
215 | par[1] = rmax - .1; |
216 | par[2] = boardThick / 2; |
217 | name2 = Form(fgkRingName, id); |
218 | name = Form(fgkPCBName, id, 'B'); |
54240c8d |
219 | z += siThick / 2 + space + boardThick / 2; |
4ac75127 |
220 | mc->Gsvolu(name.Data(), "TUBE", pcbId, par, 3); |
221 | mc->Gspos(name.Data(), 1, name2.Data(), 0, 0, z, 0); |
222 | mc->Gspos(name.Data(), 2, name2.Data(), 0, 0, z + boardThick, 0); |
223 | mc->Gsatt(name.Data(), "seen", -2); |
224 | // PCB |
225 | par[2] = pcbThick / 2; |
226 | name2 = name; |
227 | name = Form("F%cPC", id); |
228 | z = -boardThick / 2 + pcbThick / 2; |
229 | mc->Gsvolu(name.Data(), "TUBE", pcbId, par, 3); |
230 | mc->Gspos(name.Data(), 1, name2.Data(), 0, 0, z, 0); |
231 | // Copper |
232 | par[2] = copperThick / 2; |
4ac75127 |
233 | name = Form("F%cCO", id); |
234 | z += pcbThick / 2 + copperThick / 2; |
235 | mc->Gsvolu(name.Data(), "TUBE", copId, par, 3); |
236 | mc->Gspos(name.Data(), 1, name2.Data(), 0, 0, z, 0); |
237 | // Chip |
238 | par[2] = chipThick / 2; |
4ac75127 |
239 | name = Form("F%cCH", id); |
54240c8d |
240 | z += copperThick / 2 + chipThick / 2; |
4ac75127 |
241 | mc->Gsvolu(name.Data(), "TUBE", chiId, par, 3); |
242 | mc->Gspos(name.Data(), 1, name2.Data(), 0, 0, z, 0); |
243 | |
244 | return kTRUE; |
245 | } |
246 | |
247 | //____________________________________________________________________ |
248 | // |
249 | // EOF |
250 | // |