]> git.uio.no Git - u/mrichter/AliRoot.git/blob - STEER/AliModule.cxx
Bug fix in buffer expansion size calculation, report 79334
[u/mrichter/AliRoot.git] / STEER / AliModule.cxx
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 // Base class for ALICE modules. Both sensitive modules (Modules) and      //
21 // non-sensitive ones are described by this base class. This class           //
22 // supports the hit and digit trees produced by the simulation and also      //
23 // the objects produced by the reconstruction.                               //
24 //                                                                           //
25 // This class is also responsible for building the geometry of the           //
26 // Modules.                                                                //
27 //                                                                           //
28 //Begin_Html
29 /*
30 <img src="picts/AliModuleClass.gif">
31 */
32 //End_Html
33 //                                                                           //
34 ///////////////////////////////////////////////////////////////////////////////
35
36 #include <TObjArray.h>
37 #include <TClonesArray.h>
38 #include <TTree.h>
39 #include <TSystem.h>
40 #include <TDirectory.h>
41 #include <TVirtualMC.h>
42 #include <TGeoManager.h>
43 #include <TString.h>
44
45 #include "AliLog.h"
46 #include "AliConfig.h"
47 #include "AliLoader.h"
48 #include "AliMagF.h"
49 #include "AliModule.h"
50 #include "AliRun.h"
51 #include "AliTrackReference.h"
52 #include "AliMC.h"
53 #include "AliSimulation.h"
54 #include "AliRawDataHeader.h"
55
56 #include "AliDAQ.h"
57
58 ClassImp(AliModule)
59  
60 Float_t AliModule::fgDensityFactor = 1.0;
61  
62 //_______________________________________________________________________
63 AliModule::AliModule():
64   fIdtmed(0),
65   fIdmate(0),
66   fLoMedium(0),
67   fHiMedium(0),
68   fActive(0),
69   fEnable(1),
70   fMaxIterTrackRef(0),
71   fCurrentIterTrackRef(0),
72   fRunLoader(0)
73 {
74   //
75   // Default constructor for the AliModule class
76   //
77 }
78  
79 //_______________________________________________________________________
80 AliModule::AliModule(const char* name,const char *title):
81   TNamed(name,title),
82   fIdtmed(new TArrayI(100)),
83   fIdmate(new TArrayI(100)),
84   fLoMedium(65536),
85   fHiMedium(0),
86   fActive(0),
87   fEnable(1),
88   fMaxIterTrackRef(0),
89   fCurrentIterTrackRef(0),
90   fRunLoader(0)
91 {
92   //
93   // Normal constructor invoked by all Modules.
94   // Create the list for Module specific histograms
95   // Add this Module to the global list of Modules in Run.
96   //
97   // Get the Module numeric ID
98
99   Int_t id = gAlice->GetModuleID(name);
100   if (id>=0) {
101     // Module already added !
102      AliWarning(Form("Module: %s already present at %d",name,id));
103      return;
104   }
105   //
106   // Add this Module to the list of Modules
107
108   gAlice->AddModule(this);
109
110   //PH  SetMarkerColor(3);
111   //
112   // Clear space for tracking media and material indexes
113
114   for(Int_t i=0;i<100;i++) (*fIdmate)[i]=(*fIdtmed)[i]=0;
115 }
116  
117 //_______________________________________________________________________
118 AliModule::~AliModule()
119 {
120   //
121   // Destructor
122   //
123
124   // Remove this Module from the list of Modules
125   if (gAlice) {
126     TObjArray * modules = gAlice->Modules();
127     if (modules) modules->Remove(this);
128   }
129
130   // Delete TArray objects
131   delete fIdtmed;
132   delete fIdmate;
133
134
135
136 //_______________________________________________________________________
137 void AliModule::AliMaterial(Int_t imat, const char* name, Float_t a, 
138                             Float_t z, Float_t dens, Float_t radl,
139                             Float_t absl, Float_t *buf, Int_t nwbuf) const
140 {
141   //
142   // Store the parameters for a material
143   //
144   // imat        the material index will be stored in (*fIdmate)[imat]
145   // name        material name
146   // a           atomic mass
147   // z           atomic number
148   // dens        density
149   // radl        radiation length
150   // absl        absorbtion length
151   // buf         adress of an array user words
152   // nwbuf       number of user words
153   //
154   Int_t kmat;
155   //Build the string uniquename as "DET_materialname"
156   TString uniquename = GetName();
157   uniquename.Append("_");
158   uniquename.Append(name);
159   //if geometry loaded from file only fill fIdmate, else create material too
160   if(AliSimulation::Instance()->IsGeometryFromFile()){
161     TGeoMaterial *mat = gGeoManager->GetMaterial(uniquename.Data());
162     kmat = mat->GetUniqueID();
163     (*fIdmate)[imat]=kmat;
164   }else{
165     if (fgDensityFactor != 1.0)
166       AliWarning(Form("Material density multiplied by %.2f!", fgDensityFactor));
167     gMC->Material(kmat, uniquename.Data(), a, z, dens * fgDensityFactor, radl, absl, buf, nwbuf);
168     (*fIdmate)[imat]=kmat;
169   }
170 }
171   
172 //_______________________________________________________________________
173 void AliModule::AliGetMaterial(Int_t imat, char* name, Float_t &a, 
174                                Float_t &z, Float_t &dens, Float_t &radl,
175                                Float_t &absl) const
176 {
177   //
178   // Store the parameters for a material
179   //
180   // imat        the material index will be stored in (*fIdmate)[imat]
181   // name        material name
182   // a           atomic mass
183   // z           atomic number
184   // dens        density
185   // radl        radiation length
186   // absl        absorbtion length
187   // buf         adress of an array user words
188   // nwbuf       number of user words
189   //
190
191   Float_t buf[10];
192   Int_t nwbuf, kmat;
193   kmat=(*fIdmate)[imat];
194   gMC->Gfmate(kmat, name, a, z, dens, radl, absl, buf, nwbuf);
195 }
196   
197
198 //_______________________________________________________________________
199 void AliModule::AliMixture(Int_t imat, const char *name, Float_t *a,
200                            Float_t *z, Float_t dens, Int_t nlmat,
201                            Float_t *wmat) const
202
203   //
204   // Defines mixture or compound imat as composed by 
205   // nlmat materials defined by arrays a, z and wmat
206   // 
207   // If nlmat > 0 wmat contains the proportion by
208   // weights of each basic material in the mixture  
209   // 
210   // If nlmat < 0 wmat contains the number of atoms 
211   // of eack kind in the molecule of the compound
212   // In this case, wmat is changed on output to the relative weigths.
213   //
214   // imat        the material index will be stored in (*fIdmate)[imat]
215   // name        material name
216   // a           array of atomic masses
217   // z           array of atomic numbers
218   // dens        density
219   // nlmat       number of components
220   // wmat        array of concentrations
221   //
222   Int_t kmat;
223   //Build the string uniquename as "DET_mixturename"
224   TString uniquename = GetName();
225   uniquename.Append("_");
226   uniquename.Append(name);
227   //if geometry loaded from file only fill fIdmate, else create mixture too
228   if(AliSimulation::Instance()->IsGeometryFromFile()){
229     TGeoMaterial *mat = gGeoManager->GetMaterial(uniquename.Data());
230     kmat = mat->GetUniqueID();
231     (*fIdmate)[imat]=kmat;
232   }else{
233     if (fgDensityFactor != 1.0)
234       AliWarning(Form("Material density multiplied by %.2f!", fgDensityFactor));
235     gMC->Mixture(kmat, uniquename.Data(), a, z, dens * fgDensityFactor, nlmat, wmat);
236     (*fIdmate)[imat]=kmat;
237   }
238
239  
240 //_______________________________________________________________________
241 void AliModule::AliMedium(Int_t numed, const char *name, Int_t nmat,
242                           Int_t isvol, Int_t ifield, Float_t fieldm,
243                           Float_t tmaxfd, Float_t stemax, Float_t deemax,
244                           Float_t epsil, Float_t stmin, Float_t *ubuf,
245                           Int_t nbuf) const
246
247   //
248   // Store the parameters of a tracking medium
249   //
250   // numed       the medium number is stored into (*fIdtmed)[numed]
251   // name        medium name
252   // nmat        the material number is stored into (*fIdmate)[nmat]
253   // isvol       sensitive volume if isvol!=0
254   // ifield      magnetic field flag (see below)
255   // fieldm      maximum magnetic field
256   // tmaxfd      maximum deflection angle due to magnetic field
257   // stemax      maximum step allowed
258   // deemax      maximum fractional energy loss in one step
259   // epsil       tracking precision in cm
260   // stmin       minimum step due to continuous processes
261   //
262   // ifield =  0       no magnetic field
263   //        = -1       user decision in guswim
264   //        =  1       tracking performed with Runge Kutta
265   //        =  2       tracking performed with helix
266   //        =  3       constant magnetic field along z
267   //  
268   Int_t kmed;
269   //Build the string uniquename as "DET_mediumname"
270   TString uniquename = GetName();
271   uniquename.Append("_");
272   uniquename.Append(name);
273   //if geometry loaded from file only fill fIdtmed, else create medium too
274   if(AliSimulation::Instance()->IsGeometryFromFile()){
275     TGeoMedium *med = gGeoManager->GetMedium(uniquename.Data());
276     kmed = med->GetId();
277     (*fIdtmed)[numed]=kmed;
278   }else{
279     gMC->Medium(kmed, uniquename.Data(), (*fIdmate)[nmat], isvol, ifield,
280                 fieldm, tmaxfd, stemax, deemax, epsil, stmin, ubuf, nbuf);
281     (*fIdtmed)[numed]=kmed;
282   }
283
284  
285 //_______________________________________________________________________
286 void AliModule::AliMatrix(Int_t &nmat, Float_t theta1, Float_t phi1,
287                           Float_t theta2, Float_t phi2, Float_t theta3,
288                           Float_t phi3) const
289 {
290   // 
291   // Define a rotation matrix. Angles are in degrees.
292   //
293   // nmat        on output contains the number assigned to the rotation matrix
294   // theta1      polar angle for axis I
295   // phi1        azimuthal angle for axis I
296   // theta2      polar angle for axis II
297   // phi2        azimuthal angle for axis II
298   // theta3      polar angle for axis III
299   // phi3        azimuthal angle for axis III
300   //
301   gMC->Matrix(nmat, theta1, phi1, theta2, phi2, theta3, phi3); 
302
303
304 //_______________________________________________________________________
305 Float_t AliModule::ZMin() const
306 {
307   return -500;
308 }
309
310 //_______________________________________________________________________
311 Float_t AliModule::ZMax() const
312 {
313   return 500;
314 }
315
316 //_______________________________________________________________________
317 void AliModule::AddAlignableVolumes() const
318 {
319   // 
320   if (IsActive())
321     AliWarning(Form(" %s still has to implement the AddAlignableVolumes method!",GetName()));
322 }
323
324 //_______________________________________________________________________
325
326 AliLoader*  AliModule::MakeLoader(const char* /*topfoldername*/)
327 {
328   return 0x0;
329 }
330  
331
332 //_____________________________________________________________________________
333 AliTrackReference*  AliModule::AddTrackReference(Int_t label, Int_t id){
334   //
335   // add a trackrefernce to the list
336     return (gAlice->GetMCApp()->AddTrackReference(label, id));
337 }
338
339 //_____________________________________________________________________________
340 TTree* AliModule::TreeTR()
341 {
342   //
343   // Return TR tree pointer
344   //
345   if ( fRunLoader == 0x0)
346    {
347      AliError("Can not get the run loader");
348      return 0x0;
349    }
350
351   TTree* tree = fRunLoader->TreeTR();
352   return tree;
353 }
354
355
356 //_____________________________________________________________________________
357 void AliModule::Digits2Raw()
358 {
359 // This is a dummy version that just copies the digits file contents
360 // to a raw data file.
361
362   AliWarning(Form("Dummy version called for %s", GetName()));
363
364   Int_t nDDLs = AliDAQ::NumberOfDdls(GetName());
365
366   if (!GetLoader()) return;
367   fstream digitsFile(GetLoader()->GetDigitsFileName(), ios::in);
368   if (!digitsFile) return;
369
370   digitsFile.seekg(0, ios::end);
371   UInt_t size = digitsFile.tellg();
372   UInt_t ddlSize = 4 * (size / (4*nDDLs));
373   Char_t* buffer = new Char_t[ddlSize+1];
374
375   for (Int_t iDDL = 0; iDDL < nDDLs; iDDL++) {
376     char fileName[256]="";
377     strncpy(fileName,AliDAQ::DdlFileName(GetName(),iDDL),255);
378     fstream rawFile(fileName, ios::out);
379     if (!rawFile) break;
380
381     AliRawDataHeader header;
382     header.fSize = ddlSize + sizeof(header);
383     rawFile.write((char*) &header, sizeof(header));
384
385     digitsFile.read(buffer, ddlSize);
386     rawFile.write(buffer, ddlSize);
387     rawFile.close();
388   }
389
390   digitsFile.close();
391   delete[] buffer;
392 }