]> git.uio.no Git - u/mrichter/AliRoot.git/blame - TFluka/source.cxx
Some bug fixes (A. Gheata)
[u/mrichter/AliRoot.git] / TFluka / source.cxx
CommitLineData
b9d0a01d 1#define METHODDEBUG
2
3// Fortran
4#include "TCallf77.h"
5
6// Fluka commons
7#include "Fdblprc.h" //(DBLPRC) fluka common
8#include "Fdimpar.h" //(DIMPAR) fluka parameters
9#include "Fepisor.h" //(EPISOR) fluka common
10#include "Fstack.h" //(STACK) fluka common
11#include "Fstars.h" //(STARS) fluka common
12#include "Fbeam.h" //(BEAM) fluka common
13#include "Fpaprop.h" //(PAPROP) fluka common
14#include "Fltclcm.h" //(LTCLCM) fluka common
15//#include "Fcaslim.h" //(CASLIM) fluka common
16
17//Virutal MC
a7bb59a2 18#ifndef WITH_ROOT
b9d0a01d 19#include "TFluka.h"
a7bb59a2 20#else
21#include "TFlukaGeo.h"
22#endif
23
b9d0a01d 24#include "TVirtualMCStack.h"
45dc600a 25#include "TVirtualMCApplication.h"
b9d0a01d 26#include "TParticle.h"
27#include "TVector3.h"
28
29//Other
eae0fe66 30#include <Riostream.h>
b9d0a01d 31
32#ifndef WIN32
33# define source source_
34# define geocrs geocrs_
35# define georeg georeg_
36# define geohsm geohsm_
37# define soevsv soevsv_
38#else
39# define source SOURCE
40# define geocrs GEOCRS
41# define georeg GEOREG
42# define geohsm GEOHSM
43# define soevsv SOEVSV
44#endif
45
b9d0a01d 46extern "C" {
47 //
48 // Prototypes for FLUKA functions
49 //
50 void type_of_call geocrs(Double_t &, Double_t &, Double_t &);
51 void type_of_call georeg(Double_t &, Double_t &, Double_t &,
52 Int_t &, Int_t &);
53 void type_of_call geohsm(Int_t &, Int_t &, Int_t &, Int_t &);
54 void type_of_call soevsv();
55 /*
56 *----------------------------------------------------------------------*
57 * *
58 * Created on 07 january 1990 by Alfredo Ferrari & Paola Sala *
59 * Infn - Milan *
60 * *
61 * Last change on 21-jun-98 by Alfredo Ferrari *
62 * *
63 * C++ version on 27-sep-02 by Isidro Gonzalez *
64 * *
65 * This is just an example of a possible user written source routine. *
66 * note that the beam card still has some meaning - in the scoring the *
67 * maximum momentum used in deciding the binning is taken from the *
68 * beam momentum. Other beam card parameters are obsolete. *
69 * *
70 *----------------------------------------------------------------------*/
71
72 void source(Int_t& nomore) {
73#ifdef METHODDEBUG
ce60a136 74 cout << "==> source(" << nomore << ")" << endl;
b9d0a01d 75#endif
76
ce60a136 77 cout << "\t* EPISOR.lsouit = " << (EPISOR.lsouit?'T':'F') << endl;
b9d0a01d 78
ce60a136 79 static Bool_t lfirst = true;
80 static Bool_t particleIsPrimary = true;
81 static Bool_t lastParticleWasPrimary = true;
82
83 /* +-------------------------------------------------------------------*
84 * First call initializations for FLUKA: */
b9d0a01d 85
b9d0a01d 86
ce60a136 87 nomore = 0;
b9d0a01d 88 // Get the pointer to the VMC
89 TVirtualMC* fluka = TFluka::GetMC();
ce60a136 90 // Get the stack
b9d0a01d 91 TVirtualMCStack* cppstack = fluka->GetStack();
ce60a136 92 TParticle* particle;
b9d0a01d 93 Int_t itrack = -1;
ce60a136 94 Int_t nprim = cppstack->GetNprimary();
95// Get the next particle from the stack
96 particle = cppstack->PopNextTrack(itrack);
97
98// Is this a secondary not handled by Fluka, i.e. a particle added by user action ?
99 lastParticleWasPrimary = particleIsPrimary;
100
101 if (itrack >= nprim) {
102 particleIsPrimary = kFALSE;
103 } else {
104 particleIsPrimary = kTRUE;
105 }
106
107// printf("--->Got Particle %d %d %d\n", itrack, particleIsPrimary, lastParticleWasPrimary);
108
109 if (lfirst) {
110 EPISOR.tkesum = zerzer;
111 lfirst = false;
112 EPISOR.lussrc = true;
113 } else {
114//
115// Post-track actions for primary track
116//
117 if (particleIsPrimary) {
118 TVirtualMCApplication::Instance()->PostTrack();
119 TVirtualMCApplication::Instance()->FinishPrimary();
120 }
121 }
b9d0a01d 122
123 //Exit if itrack is negative (-1). Set lsouit to false to mark last track for
124 //this event
ce60a136 125
b9d0a01d 126 if (itrack<0) {
127 nomore = 1;
128 EPISOR.lsouit = false;
129 cout << "\t* EPISOR.lsouit = " << (EPISOR.lsouit?'T':'F') << endl;
130 cout << "\t* No more particles. Exiting..." << endl;
131#ifdef METHODDEBUG
132 cout << "<== source(" << nomore << ")" << endl;
133#endif
134 return;
135 }
ce60a136 136
b9d0a01d 137 //Get some info about the particle and print it
ce60a136 138 //
139 //pdg code
140 Int_t pdg = particle->GetPdgCode();
141
b9d0a01d 142 TVector3 polarisation;
143 particle->GetPolarisation(polarisation);
144 cout << "\t* Particle " << itrack << " retrieved..." << endl;
145 cout << "\t\t+ Name = " << particle->GetName() << endl;
ce60a136 146 cout << "\t\t+ PDG/Fluka code = " << pdg
147 << " / " << fluka->IdFromPDG(pdg) << endl;
b9d0a01d 148 cout << "\t\t+ P = ("
149 << particle->Px() << " , "
150 << particle->Py() << " , "
151 << particle->Pz() << " ) --> "
152 << particle->P() << " GeV" << endl;
b9d0a01d 153 /* Lstack is the stack counter: of course any time source is called it
154 * must be =0
155 */
45dc600a 156
b9d0a01d 157 STACK.lstack++;
ce60a136 158
b9d0a01d 159 /* Wt is the weight of the particle*/
160 STACK.wt[STACK.lstack] = oneone;
161 STARS.weipri += STACK.wt[STACK.lstack];
ce60a136 162
b9d0a01d 163 /* Particle type (1=proton.....). Ijbeam is the type set by the BEAM
164 * card
165 */
ce60a136 166
b9d0a01d 167 //STACK.ilo[STACK.lstack] = BEAM.ijbeam;
ce60a136 168 if (pdg == 50000050 || pdg == 50000051) {
169 STACK.ilo[STACK.lstack] = fluka-> IdFromPDG(22);
170 } else {
171 STACK.ilo[STACK.lstack] = fluka-> IdFromPDG(pdg);
172 }
173
174
175
176
b9d0a01d 177 /* From this point .....
178 * Particle generation (1 for primaries)
ce60a136 179 */
b9d0a01d 180 STACK.lo[STACK.lstack] = 1;
ce60a136 181
b9d0a01d 182 /* User dependent flag:*/
183 STACK.louse[STACK.lstack] = 0;
ce60a136 184
b9d0a01d 185 /* User dependent spare variables:*/
148ba0b4 186 Int_t ispr = 0;
187 for (ispr = 0; ispr < mkbmx1; ispr++)
b9d0a01d 188 STACK.sparek[STACK.lstack][ispr] = zerzer;
ce60a136 189
b9d0a01d 190 /* User dependent spare flags:*/
148ba0b4 191 for (ispr = 0; ispr < mkbmx2; ispr++)
b9d0a01d 192 STACK.ispark[STACK.lstack][ispr] = 0;
ce60a136 193
b9d0a01d 194 /* Save the track number of the stack particle:*/
5d298556 195 STACK.ispark[STACK.lstack][mkbmx2-1] = itrack;
b9d0a01d 196 STACK.nparma++;
197 STACK.numpar[STACK.lstack] = STACK.nparma;
198 STACK.nevent[STACK.lstack] = 0;
199 STACK.dfnear[STACK.lstack] = +zerzer;
ce60a136 200
201 /* Particle age (s)*/
b9d0a01d 202 STACK.agestk[STACK.lstack] = +zerzer;
203 STACK.aknshr[STACK.lstack] = -twotwo;
ce60a136 204
b9d0a01d 205 /* Group number for "low" energy neutrons, set to 0 anyway*/
206 STACK.igroup[STACK.lstack] = 0;
ce60a136 207
208 /* Kinetic energy */
209 if (pdg == 50000050 || pdg == 50000051) {
210 //
211 // Special case for optical photons
212 STACK.tke[STACK.lstack] = particle->Energy();
213 } else {
214 STACK.tke[STACK.lstack] = particle->Energy() - particle->GetMass();
215 }
216
b9d0a01d 217
218 /* Particle momentum*/
b9d0a01d 219 STACK.pmom [STACK.lstack] = particle->P();
220
ce60a136 221 /* Cosines (tx,ty,tz)*/
b9d0a01d 222 Double_t cosx = particle->Px()/particle->P();
223 Double_t cosy = particle->Py()/particle->P();
57dd4539 224 Double_t cosz = TMath::Sqrt(oneone - cosx*cosx - cosy*cosy);
225 if (particle->Pz() < 0.) cosz = -cosz;
b9d0a01d 226 STACK.tx [STACK.lstack] = cosx;
227 STACK.ty [STACK.lstack] = cosy;
228 STACK.tz [STACK.lstack] = cosz;
229
ce60a136 230 /* Polarization cosines:*/
b9d0a01d 231 if (polarisation.Mag()) {
ce60a136 232 Double_t cospolx = polarisation.Px()/polarisation.Mag();
233 Double_t cospoly = polarisation.Py()/polarisation.Mag();
234 Double_t cospolz = sqrt(oneone - cospolx*cospolx - cospoly*cospoly);
235 STACK.tx [STACK.lstack] = cospolx;
236 STACK.ty [STACK.lstack] = cospoly;
237 STACK.tz [STACK.lstack] = cospolz;
b9d0a01d 238 }
239 else {
ce60a136 240 STACK.txpol [STACK.lstack] = -twotwo;
241 STACK.typol [STACK.lstack] = +zerzer;
242 STACK.tzpol [STACK.lstack] = +zerzer;
b9d0a01d 243 }
244
245 /* Particle coordinates*/
ce60a136 246 // Vertext coordinates;
b9d0a01d 247 STACK.xa [STACK.lstack] = particle->Vx();
248 STACK.ya [STACK.lstack] = particle->Vy();
249 STACK.za [STACK.lstack] = particle->Vz();
250
b9d0a01d 251 /* Calculate the total kinetic energy of the primaries: don't change*/
252 Int_t st_ilo = STACK.ilo[STACK.lstack];
253 if ( st_ilo != 0 )
ce60a136 254 EPISOR.tkesum +=
255 ((STACK.tke[STACK.lstack] + PAPROP.amdisc[st_ilo+6])
256 * STACK.wt[STACK.lstack]);
b9d0a01d 257 else
ce60a136 258 EPISOR.tkesum += (STACK.tke[STACK.lstack] * STACK.wt[STACK.lstack]);
b9d0a01d 259
260 /* Here we ask for the region number of the hitting point.
261 * NREG (LSTACK) = ...
262 * The following line makes the starting region search much more
263 * robust if particles are starting very close to a boundary:
264 */
265 geocrs( STACK.tx[STACK.lstack],
266 STACK.ty[STACK.lstack],
267 STACK.tz[STACK.lstack] );
ce60a136 268
b9d0a01d 269 Int_t idisc;
ce60a136 270
b9d0a01d 271 georeg ( STACK.xa[STACK.lstack],
272 STACK.ya[STACK.lstack],
273 STACK.za[STACK.lstack],
274 STACK.nreg[STACK.lstack],
275 idisc);//<-- dummy return variable not used
b9d0a01d 276 /* Do not change these cards:*/
277 Int_t igeohsm1 = 1;
278 Int_t igeohsm2 = -11;
279 geohsm ( STACK.nhspnt[STACK.lstack], igeohsm1, igeohsm2, LTCLCM.mlattc );
280 STACK.nlattc[STACK.lstack] = LTCLCM.mlattc;
281 soevsv();
ce60a136 282//
283// Pre-track actions at for primary tracks
284//
285 if (particleIsPrimary) {
286 TVirtualMCApplication::Instance()->BeginPrimary();
287 TVirtualMCApplication::Instance()->PreTrack();
288 }
289
290//
291
b9d0a01d 292#ifdef METHODDEBUG
293 cout << "<== source(" << nomore << ")" << endl;
294#endif
295 }
296}