ACTARSim
ACTAR TPC Simulation Reference Guide
ActarSimPrimaryGeneratorAction.cc
Go to the documentation of this file.
1 // - AUTHOR: Hector Alvarez-Pol 11/2004
2 /******************************************************************
3  * Copyright (C) 2005-2016, Hector Alvarez-Pol *
4  * All rights reserved. *
5  * *
6  * License according to GNU LESSER GPL (see lgpl-3.0.txt). *
7  * For the list of contributors see CREDITS. *
8  ******************************************************************/
9 //////////////////////////////////////////////////////////////////
10 /// \class ActarSimPrimaryGeneratorAction
11 /// Actions to perform to generate a primary vertex
12 /////////////////////////////////////////////////////////////////
13 
15 
19 
20 #include "ActarSimROOTAnalysis.hh"
24 
25 #include "ActarSimBeamInfo.hh"
26 
27 #include "G4RunManager.hh"
28 #include "G4Event.hh"
29 #include "G4ParticleGun.hh"
30 #include "G4ThreeVector.hh"
31 #include "G4Gamma.hh"
32 #include "G4Geantino.hh"
33 #include "globals.hh"
34 #include "Randomize.hh"
35 
36 #include "G4ParticleDefinition.hh"
37 #include "G4PhysicalConstants.hh"
38 #include "G4SystemOfUnits.hh"
39 
40 # include <cstdlib>
41 # include <iostream>
42 # include <fstream>
43 using namespace std;
44 
45 //////////////////////////////////////////////////////////////////
46 /// Constructor: init values are filled
48  :gasDetector(0), incidentIon(0),targetIon(0),scatteredIon(0),recoilIon(0),
49  beamInteractionFlag("off"),
50  realisticBeamFlag("off"), reactionFromEvGenFlag("off"), reactionFromCrossSectionFlag("off"),
51  reactionFromFileFlag("off"),reactionFromCineFlag("off"),
52  randomThetaFlag("off"),reactionFile("He8onC12_100MeV_Elastic.dat"),reactionFromKineFlag("off"),
53  vertexPosition(0) {
54 
55  G4ThreeVector zero;
56  particleTable = G4ParticleTable::GetParticleTable();
57  ionTable = G4IonTable::GetIonTable();
58 
59  //create a particleGun
60  particleGun = new G4ParticleGun(1);
61 
62  //create a messenger for this class
64 
65  G4ParticleDefinition* pd = particleTable->FindParticle("proton");
66  if(pd != 0)
67  particleGun->SetParticleDefinition(pd);
68 
69  particleGun->SetParticlePosition(zero);
70  particleGun->SetParticleTime(0.0);
71  particleGun->SetParticlePolarization(zero);
72  particleGun->SetParticleCharge(1.0);
73  particleGun->SetParticleMomentumDirection(G4ThreeVector(0.0,0.0,1.0));
74  particleGun->SetParticleEnergy(1*MeV);
75 
76  //NOTE: FOR THE MOMENT THIS IS NOT ACCESIBLE. REVIEW IN THE FUTURE
77  //create a pointer that gives access to the tabulated xs
78  //pReadEvGen = new ActarSimEventGenerator();
79 
80  reactionQ = 0.0001; //does 0 work? (QM)
81  labEnergy = 100 *MeV; // 15MeV*numero de nucleones (EI)
82  incidentEnergy = 10 *MeV;
83  // (EN) and (ENI) are taken from the target and projectile ion definitions
84  thetaLabAngle = 45 * deg; // 45 degrees (TH)
85  randomThetaMin = 0.*deg;
86  randomThetaMax = 180.*deg;
88 
89  beamDirectionFlag = 1; // 0 : direction given by angles, 1 : direction given by vector
90 
91  //additional initial values for some variables
92  SetBeamMomentumDirection(G4ThreeVector(0.0,0.0,1.0));
93 }
94 
95 //////////////////////////////////////////////////////////////////
96 /// Simple destructor
98  delete particleGun;
99  delete gunMessenger;
100 }
101 
102 //////////////////////////////////////////////////////////////////
103 /// Function called at the begining of event. Generate most of the
104 /// primary physics. These are the possible options:
105 ///
106 /// - CASE A1: Beam interaction in the gas. First the beam part...
107 /// [ corresponds to line if(beamInteractionFlag == "on"){ ].
108 /// While the beam is only emitted if beamInteractionFlag == "on"
109 /// the reaction products are always produced later in the code.
110 /// The beam is described by the (G4Ions*) incidentIon (or incident particles)
111 /// and it is tracked in the gas in the even events (begining at zero, 0,2,4, ...)
112 /// while in the odd events (1,3,5, ...) the reaction products are tracked,
113 /// (CINE, KINE, from file, one output particle, ...) using some parameters
114 /// (vertex position, remaining beam ion energy, ...) obtained in the beam tracking.
115 ///
116 /// - CASE A2: now the beam is not included and the fragments produced.
117 /// [ corresponds to line else if(realisticBeamFlag == "on") { ].
118 /// Despite the name of the flag, there is no beam interacting in the gas.
119 /// RealisticBeamFlag means a reaction products being generated according to a
120 /// realistic vertex posisioning as if a beam were interacting.
121 /// Not anymore a gaussian, but a flat distribution in a given radius around Z axis.
122 ///
123 /// - CASE B: Reaction from Event-Generator
124 /// WARNING: THIS IS NOT IMPLEMENTED
125 ///
126 /// - CASE C Reaction products taken from a file (format given by CINE output).
127 /// [ corresponds to line if(reactionFromFileFlag == "on"){ ].
128 /// FILE format: first row should contain 6 integers with the info:
129 /// [scattered ion Z; scattered ion A; scattered ion charge state;
130 /// recoiled ion Z; recoil ion A; recoil ion charge state].
131 /// The folowing lines contains:
132 /// scattered ion angle; scattered ion energy; recoil ion angle; recoil ion energy
133 /// (typical output from CINE, for example)
134 /// A random line (that is, a random angle) is taken from the event list
135 ///
136 /// - CASE D Reaction products kinematics calculated using Cine
137 /// [ corresponds to line else if(reactionFromCineFlag == "on"){ ].
138 /// The CINE program (W. Mittig) has been translated to C++ ...
139 ///
140 /// - CASE E Reaction products kinematics calculated using Kine
141 /// [ corresponds to line else if(reactionFromKineFlag == "on"){ ].
142 ///
143 /// - CASE F Particle selected manually (using the messenger commands)
145  const G4int verboseLevel = G4RunManager::GetRunManager()->GetVerboseLevel();
146  if(verboseLevel>0)
147  G4cout << G4endl << " _____ G4RunManager VerboseLevel = " <<verboseLevel<< G4endl;
148 
149  G4ThreeVector zero;
150  G4double theta1=0.;
151  G4double theta2=0.;
152  G4double energy1=0.;
153  G4double energy2=0.;
154 
156  (G4RunManager::GetRunManager()->GetUserDetectorConstruction());
157 
158  //reading this parameter from the geometry
159  if(!gasDetector) {
161  if(gasDetector->GetDetectorGeometry()=="tube")
163  else
165 
166  if(verboseLevel>0){
167  G4cout << "##################################################################" << G4endl
168  << "##### ActarSimPrimaryGeneratorAction::GeneratePrimaries() #######" << G4endl
169  << "##### Information: Length of gas volume = " << lengthParameter << " ######" << G4endl;
170  G4cout << "##################################################################" << G4endl;
171  }
172  }
173  //
174  // CASE A1: Beam interaction in the gas. First the beam part...
175  // While the beam is only emitted if beamInteractionFlag == "on"
176  // the reaction products are always produced later in the code.
177  //
178  if(beamInteractionFlag == "on"){
179  // The beam is described by the (G4Ions*) incidentIon (or incident particles)
180  // and it is tracked in the gas in the even events (begining at zero, 0,2,4, ...)
181  // while in the odd events (1,3,5, ...) the reaction products are tracked,
182  // (CINE, KINE, from file, one output particle, ...) using some parameters
183  // (vertex position, remaining beam ion energy, ...) obtained in the beam tracking.
184  ActarSimBeamInfo *pBeamInfo = (ActarSimBeamInfo*) 0;
185 
187  pBeamInfo = gActarSimROOTAnalysis->GetBeamInfo();
189  }
190 
191  if(pBeamInfo->GetStatus() > 1){
192  // Beam reached vertex: Tracking vertex products (later in this code)
193  // Resetting the BeamInfo status to 0, for the next beam tracking
194  if(verboseLevel>0){
195  G4cout << G4endl
196  << " *************************************************** " << G4endl
197  << " * ActarSimPrimaryGeneratorAction::GeneratePrimaries() " << G4endl
198  << " * beamInteractionFlag=on, beam.Status>1 ... " << G4endl
199  << " * Moving to status 0 and continuing with reaction!" << G4endl;
200  G4cout << " *************************************************** "<< G4endl;
201  }
202  vertexPosition.setX(pBeamInfo->GetXVertex());
203  vertexPosition.setY(pBeamInfo->GetYVertex());
204  vertexPosition.setZ(pBeamInfo->GetZVertex());
205  SetLabEnergy(pBeamInfo->GetEnergyVertex());
206  pBeamInfo->SetStatus(0);
207  } //end of if(pBeamInfo->GetStatus() > 1)
208  else if(pBeamInfo->GetStatus() == 1){
209  // the beam finished the tracking in the previous event without reaching
210  // the requested vertex position! This is a faulty case! Aborting present event and continue.
211  G4cout << G4endl
212  << " *************************************************** " << G4endl
213  << " * ActarSimPrimaryGeneratorAction::GeneratePrimaries() " << G4endl
214  << " * ERROR STATUS! beamInteractionFlag=on, beam.Status=1 ... " << G4endl
215  << " * Moving to status 0 and ABORTING! " << G4endl;
216  G4cout << " *************************************************** "<< G4endl;
217  pBeamInfo->SetStatus(0);
218  anEvent->SetEventAborted();
219  } //end of else if(pBeamInfo->GetStatus() == 1)
220  else{ //corresponding to beam status equal to 0,
221  // Setting the parameters to send a beam particle
222  // they come from CINE or KINE or incident ion definition.
223  if(verboseLevel>0){
224  G4cout << G4endl
225  << " *************************************************** " << G4endl
226  << " * ActarSimPrimaryGeneratorAction::GeneratePrimaries() " << G4endl
227  << " * beamInteractionFlag=on, beam.Status=0 ... " << G4endl
228  << " * Moving to status 1 and tracking the beam!" << G4endl;
229  G4cout << " *************************************************** "<< G4endl;
230  }
231  if(!incidentIon) {
232  incidentIon = (G4Ions*) ionTable->GetIon(2, 8, 0.); // 8He (S1)
233  incidentIonCharge = 2;
234  G4cout << G4endl
235  << " *************************************************** " << G4endl
236  << " * ActarSimPrimaryGeneratorAction::GeneratePrimaries() " << G4endl
237  << " * No incident ion selected: using 8He as incident beam" << G4endl;
238  G4cout << " *************************************************** "<< G4endl;
239  }
240  pBeamInfo->SetStatus(1);
241 
242  // TODO: Kinematics calculated assuming beam following perfect Z direction.
243  // It the beam has another 4-momentum, the reaction plane and kinematics
244  // should be transformed accordingly. Fine tuning, anyway (check if needed)
245  particleGun->SetParticleDefinition(incidentIon);
246  particleGun->SetParticleCharge(incidentIonCharge);
247  pBeamInfo->SetCharge(incidentIonCharge);
248  pBeamInfo->SetMass(incidentIon->GetPDGMass());
249 
250  // vertex_z0 decides the z position of the vertex. The beam is tracked till z0 is reached ...
251  G4double vertex_z0 = 0;
252 
253  if(randomVertexZPositionFlag=="off"){
254  vertex_z0 = vertexZPosition;
255  }
256  else if(randomVertexZPositionFlag=="on"){
258  }
259  // TODO: The probability of interaction is simply constant over the path on the gas.
260  // This is the right place for introducing some dependence with the ion energy using
261  // the reaction cross section, or even a simple exponential if a constant cross sections
262  // approximation is suitable (non-resonant beam)
263 
264  pBeamInfo->SetZVertex(vertex_z0);
265  pBeamInfo->SetEnergyEntrance(GetIncidentEnergy());
266 
267  if(realisticBeamFlag == "on") {
268  // Emittance is defined in mm mrad
269  // The polar angle at Entrance is defined by the relation between emitance and radiusAtEntrance.
270  // this relation is roughtly emittance = widthPos * widthAng ~ 2 * radiusMax * 2 * thetaMax
271  // A step function is used for the position and angular distributions
272  G4double radiusAtEntrance = beamRadiusAtEntrance * G4UniformRand(); //from 0 to beamRadiusAtEntrance
273  G4double thetaWidth = emittance/(4*beamRadiusAtEntrance/mm); //polar angle width between zero and maximum (as emittance is in mm*mrads, thetaWidth is given in mrads!!)
274  G4double thetaAtEntrance = thetaWidth * G4UniformRand() * mrad;
275  G4double phiAtEntrance = G4UniformRand() * twopi; //angle phi of momentum
276  G4double phi2AtEntrance = G4UniformRand() * twopi; //angle for defining the entrance point
277 
278  G4ThreeVector directionAtEntrance = G4ThreeVector(sin(thetaAtEntrance)*cos(phiAtEntrance),
279  sin(thetaAtEntrance)*sin(phiAtEntrance),
280  cos(thetaAtEntrance));
281 
282  //Entrance coordinates (x0,y0,0) with angles (thetaAtEntrance, phiAtEntrance)
283  G4double x0 = beamPosition.x() + radiusAtEntrance*cos(phi2AtEntrance);
284  G4double y0 = beamPosition.y() + radiusAtEntrance*sin(phi2AtEntrance);
285  G4double z0 = beamPosition.z();
286 
287  if(verboseLevel>0){
288  G4cout << G4endl
289  << " *************************************************** " << G4endl
290  << " * ActarSimPrimaryGeneratorAction::GeneratePrimaries() " << G4endl
291  << " * beamInteractionFlag=on, beam.Status=0, realisticBeamFlag=on " << G4endl
292  << " * Beam with entrance emittance:" << G4endl
293  << " * ThetaWidth: " << thetaWidth << G4endl
294  << " * RadiusAtEntrance: " << radiusAtEntrance << G4endl;
295  G4cout << " *************************************************** "<< G4endl;
296  }
297  particleGun->SetParticlePosition(G4ThreeVector(x0,y0,z0));
298  particleGun->SetParticleMomentumDirection(directionAtEntrance);
299  pBeamInfo->SetPositionEntrance(x0,y0,z0);
300  pBeamInfo->SetAnglesEntrance(thetaAtEntrance,phiAtEntrance);
301  } //end of if(realisticBeamFlag == "on")
302  else{ // simplest case: beam at (0,0,0) with direction along Z
303  particleGun->SetParticlePosition(beamPosition);
304  particleGun->SetParticleMomentumDirection(beamMomentumDirection);
306  pBeamInfo->SetAnglesEntrance(0.,0.);
307  }
308  particleGun->SetParticleTime(0.0);
309  particleGun->SetParticlePolarization(zero);
310  particleGun->SetParticleEnergy(GetIncidentEnergy());
311  particleGun->GeneratePrimaryVertex(anEvent);
312 
313  //Histogramming
316 
317  return; //end of the function after generating the beam...
318  //waiting for next event for the reaction products.
319  }
320  }//end of if(beamInteractionFlag == "on")
321 
322  // CASE A2: now the beam is not included...
323  else if(realisticBeamFlag == "on") {
324  // Despite the name of the flag, there is no beam interacting in the gas.
325  // RealisticBeamFlag means a reaction products being generated according to a
326  // realistic vertex posisioning as if a beam were interacting.
327  // Not anymore a gaussian, but a flat distribution in a given radius around Z axis.
328  G4double radiusAtEntrance = beamRadiusAtEntrance * G4UniformRand(); //from 0 to beamRadiusAtEntrance
329  G4double phi2AtEntrance = G4UniformRand() * twopi; //angle for defining the entrance point
330 
331  //Vertexcoordinates (vertex_x0,vertex_y0,vertex_z0) with angles (thetaAtEntrance, phiAtEntrance)
332  G4double vertex_x0 = radiusAtEntrance*cos(phi2AtEntrance)+beamPosition.x();
333  G4double vertex_y0 = radiusAtEntrance*sin(phi2AtEntrance)+beamPosition.y();
334  G4double vertex_z0 = 0.;
335 
336  if(randomVertexZPositionFlag=="on"){
338  }
339  else{
340  //vertex_z0 = G4UniformRand()*(2.* lengthParameter);
341  vertex_z0 = -lengthParameter + G4UniformRand()*lengthParameter;//If Z origin is at the center of GasBox
342  }
343 
344  if(verboseLevel>0){
345  G4cout << G4endl
346  << " *************************************************** " << G4endl
347  << " * ActarSimPrimaryGeneratorAction::GeneratePrimaries() " << G4endl
348  << " * beamInteractionFlag=off but realisticBeamFlag=on " << G4endl
349  << " * No beam interaction, but vertex generated with some emittance effects:" << G4endl
350  << " * RadiusAtVertex: " << radiusAtEntrance << G4endl;
351  G4cout << " *************************************************** "<< G4endl;
352  }
353 
354  //setting the vertexPos vector to the previous calculated values
355  vertexPosition.setX(vertex_x0);
356  vertexPosition.setY(vertex_y0);
357  vertexPosition.setZ(vertex_z0);
358  }
359 
360  // After the beam, now different options for the reaction products!
361  //
362  // CASE B Reaction from Event-Generator
363  //
364  if(reactionFromEvGenFlag == "on") {
365  if(verboseLevel>0){
366  G4cout << G4endl
367  << " *************************************************** " << G4endl
368  << " * WARNING: THIS IS NOT IMPLEMENTED!!!" << G4endl
369  << " * ActarSimPrimaryGeneratorAction::GeneratePrimaries() " << G4endl
370  << " * reactionFromEvGenFlag=on " << G4endl
371  << " * An external event generator is used..." << G4endl
372  << " * WARNING: THIS IS NOT IMPLEMENTED!!!" << G4endl;
373  G4cout << " *************************************************** "<< G4endl;
374  }
375  /* REMOVING THE COMPLETE CASE B CODE
376  //Initial values
377 
378  G4double particle_energy = 50*MeV;
379  G4double particle_energy_rec = 50*MeV;
380  G4double momentum_x = 1.;
381  G4double momentum_y = 0.;
382  G4double momentum_z = 1.5;
383  G4double momentum_x_rec = 1.;
384  G4double momentum_y_rec = 0.;
385  G4double momentum_z_rec = 1.5;
386  G4double phi= 0. ;
387  if( particle_energy && particle_energy_rec ){;}
388  if( momentum_x && momentum_x_rec){;}
389  if( momentum_y && momentum_y_rec){;}
390  if( momentum_z && momentum_z_rec){;}
391  //TRANSFER
392  // Polar angle:
393  G4double theta=0;
394  // Random number between 0 and 1
395  G4double randnum = G4UniformRand();
396  G4double energy_scatt=0;
397  G4double slop1=0.,slop2=0.,offset1=0.,offset2=0.;
398  G4double theta_recoil=0;
399  G4double energy_recoil=0;
400  G4double slop_rec=0.,offset_rec=0.;
401 
402  //The last angle could be different from 181,
403  //extract the nbins from ActarSimEventGenerator (todo)
404  for(G4int i=0;i<181;i++) {
405  if(randnum>=pReadEvGen->Icross_section[i] &&
406  randnum<pReadEvGen->Icross_section[i+1]) {
407  slop1=(pReadEvGen->LabAngle_scatt[i+1]-
408  pReadEvGen->LabAngle_scatt[i])/(pReadEvGen->Icross_section[i+1]-
409  pReadEvGen->Icross_section[i]);
410  offset1= pReadEvGen->LabAngle_scatt[i]-slop1*pReadEvGen->Icross_section[i];
411  theta=randnum*slop1+offset1;
412 
413  for(G4int j=0; j<181; j++) {
414  if(theta>=pReadEvGen->LabAngle_scatt[j] &&
415  theta<pReadEvGen->LabAngle_scatt[j+1]) {
416  slop2=(pReadEvGen->LabEnergy_scatt[int(pReadEvGen->LabAngle_scatt[j+1])]-
417  pReadEvGen->LabEnergy_scatt[int(pReadEvGen->LabAngle_scatt[j])])/
418  (pReadEvGen->LabAngle_scatt[j+1]-pReadEvGen->LabAngle_scatt[j]);
419 
420  offset2= pReadEvGen->LabEnergy_scatt[int(pReadEvGen->LabAngle_scatt[j])]-
421  slop2*pReadEvGen->LabAngle_scatt[j];
422  energy_scatt=theta*slop2+offset2;
423  //Angle of the Recoil
424  theta_recoil=pReadEvGen->LabAngle_recoil[j];
425  //The same for the recoil
426  slop_rec=(pReadEvGen->LabEnergy_recoil[int(pReadEvGen->LabAngle_recoil[j+1])]-
427  pReadEvGen->LabEnergy_recoil[int(pReadEvGen->LabAngle_recoil[j])])/
428  (pReadEvGen->LabAngle_recoil[j+1]-pReadEvGen->LabAngle_recoil[j]);
429  offset_rec=pReadEvGen->LabEnergy_recoil[int(pReadEvGen->LabAngle_scatt[j])]-
430  slop_rec*pReadEvGen->LabAngle_recoil[j];
431  energy_recoil=theta_recoil*slop_rec+offset_rec;
432  }
433  }
434  theta=theta*deg; // Polar angle in radian
435  theta_recoil=theta_recoil*deg; // Polar angle in radian
436  }
437  }
438  // Azimuthal angle:
439  phi = G4UniformRand()*twopi;
440 
441  momentum_x = sin(theta)*cos(phi);
442  momentum_y = sin(theta)*sin(phi);
443  momentum_z = cos(theta);
444 
445  momentum_x_rec = sin(theta_recoil)*cos(phi+pi);
446  momentum_y_rec = sin(theta_recoil)*sin(phi+pi);
447  momentum_z_rec = cos(theta_recoil);
448 
449  particle_energy = energy_scatt;
450  LabParticleAngle = theta;
451 
452  particle_energy_rec = energy_recoil;
453  LabParticleAngle_rec = theta_recoil;
454 
455  */
456  //Send 2 vertex
457  //Define ions from the macro (talk to Hector->use the ones from CINE)
458  }
459 
460  // CASE C Reaction products taken from a file (format given by CINE output)
461  if(reactionFromFileFlag == "on"){
462  // FILE format: first row should contain 6 integers with the info:
463  // scattered ion Z; scattered ion A; scattered ion charge state;
464  // recoiled ion Z; recoil ion A; recoil ion charge state;
465  // The folowing lines contains:
466  // scattered ion angle; scattered ion energy; recoil ion angle; recoil ion energy
467  // (typical output from CINE, for example)
468  // A random line (that is, a random angle) is taken from the event list
469  if(verboseLevel>0){
470  G4cout << G4endl
471  << " *************************************************** " << G4endl
472  << " * ActarSimPrimaryGeneratorAction::GeneratePrimaries() " << G4endl
473  << " * reactionFromFileFlag = on " << G4endl
474  << " * An external file with products information is used." << G4endl;
475  G4cout << " *************************************************** "<< G4endl;
476  }
477  ifstream inputFile(reactionFile);
478  if(reactionFile) {
479  //TODO Modify completely this funtion!!! Dynamic objetc to avoid hardcoded size in arrays and limits
480  G4double cine[91*4+1];
481  G4int ion1Z, ion1A, ion1Charge;
482  G4int ion2Z, ion2A, ion2Charge;
483 
484  inputFile >> ion1Z; inputFile >> ion1A; inputFile >> ion1Charge;
485  inputFile >> ion2Z; inputFile >> ion2A; inputFile >> ion2Charge;
486 
487  if(verboseLevel>1){
488  G4cout << G4endl
489  << " First ion Z, A and Charge: "
490  << ion1Z << " " << ion1A << " " << ion1Charge << G4endl
491  << " Second ion Z, A and Charge: "
492  << ion2Z << " " << ion2A << " " << ion2Charge << G4endl;
493  }
494  G4int i=0;
495  do{
496  inputFile >> cine[i];
497  i++;
498  }while(!inputFile.eof());
499 
500  G4int rowsInputFile = (G4int) i/4;
501  //Taken a random cinematic from the previous table
502  G4int randomRow = (G4int)(G4UniformRand()*rowsInputFile);
503  theta1 = pi*cine[randomRow*4]/180;
504  theta2 = pi*cine[randomRow*4+2]/180;
505  energy1 = cine[randomRow*4+1];
506  energy2 = cine[randomRow*4+3];
507  G4double phi = twopi *G4UniformRand(); //flat in phi
508  G4ThreeVector direction1 = G4ThreeVector(sin(theta1)*cos(phi),
509  sin(theta1)*sin(phi),
510  cos(theta1));
511  G4ThreeVector direction2 = G4ThreeVector(sin(theta2)*cos(phi+pi),
512  sin(theta2)*sin(phi+pi),
513  cos(theta2));
514  if(ion1Z==1 && ion1A==1 && ion1Charge==1){
515  G4ParticleDefinition* pd = particleTable->FindParticle("proton");
516  if(pd != 0) particleGun->SetParticleDefinition(pd);
517  }
518  else{
519  G4Ions* ion1;
520  ion1 = (G4Ions*) ionTable->GetIon(ion1Z, ion1A, 0.0);
521  particleGun->SetParticleDefinition(ion1);
522  particleGun->SetParticleCharge(ion1Charge);
523  }
524  particleGun->SetParticlePosition(vertexPosition);
525 
526  //time, including the beam tracking before the vertex formation
527  if(beamInteractionFlag == "on") {
528  ActarSimBeamInfo *pBeamInfo = (ActarSimBeamInfo*) 0;
530  pBeamInfo = gActarSimROOTAnalysis->GetBeamInfo();
531  particleGun->SetParticleTime(pBeamInfo->GetTimeVertex());
532  }
533  }
534  else
535  particleGun->SetParticleTime(0.0);
536 
537  particleGun->SetParticlePolarization(zero);
538  particleGun->SetParticleMomentumDirection(direction1);
539  particleGun->SetParticleEnergy(energy1*MeV);
540 
541  particleGun->GeneratePrimaryVertex(anEvent);
542 
543  if(ion2Z==1 && ion2A==1 && ion2Charge==1){
544  G4ParticleDefinition* pd = particleTable->FindParticle("proton");
545  if(pd != 0) particleGun->SetParticleDefinition(pd);
546  }
547  else{
548  G4Ions* ion2;
549  ion2 = (G4Ions*) ionTable->GetIon(ion2Z, ion2Z, 0.0);
550  particleGun->SetParticleDefinition(ion2);
551  particleGun->SetParticleCharge(ion2Charge);
552  }
553  particleGun->SetParticlePosition(vertexPosition);
554 
555  //time, including the beam tracking before the vertex formation
556  if(beamInteractionFlag == "on") {
557  ActarSimBeamInfo *pBeamInfo = (ActarSimBeamInfo*) 0;
559  pBeamInfo = gActarSimROOTAnalysis->GetBeamInfo();
560  particleGun->SetParticleTime(pBeamInfo->GetTimeVertex());
561  }
562  }
563  else
564  particleGun->SetParticleTime(0.0);
565 
566  particleGun->SetParticlePolarization(zero);
567  particleGun->SetParticleMomentumDirection(direction2);
568  particleGun->SetParticleEnergy(energy2*MeV);
569 
570  particleGun->GeneratePrimaryVertex(anEvent);
571  }
572  else { //no file found
573  G4cout << " *************************************************** " << G4endl
574  << "File " << reactionFile << " not found." << G4endl;
575  G4cout << " *************************************************** "<< G4endl;
576  }
577  } //end of if(reactionFromFileFlag == "on")
578 
579  //CASE D Reaction products kinematics calculated using Cine
580  else if(reactionFromCineFlag == "on"){
581  // The CINE program (W. Mittig) has been translated to C++ ...
582  if(verboseLevel>0){
583  G4cout << G4endl
584  << " *************************************************** " << G4endl
585  << " * ActarSimPrimaryGeneratorAction::GeneratePrimaries() " << G4endl
586  << " * reactionFromCineFlag = on " << G4endl
587  << " * Using CINE for the kinematics of reaction products." << G4endl;
588  G4cout << " *************************************************** "<< G4endl;
589  }
590  //Initial values for CINE. It is not allowed to create this initial values in the constructor...
591  if(!incidentIon) {
592  incidentIon = (G4Ions*) ionTable->GetIon(2, 8, 0.); // 8He (S1)
593  incidentIonCharge = 2;
594  }
595  if(!targetIon) {
596  targetIon = (G4Ions*) ionTable->GetIon(6, 12, 0.); // C12 (S2)
597  targetIonCharge = 6;
598  }
599  if(!scatteredIon){
600  scatteredIon = (G4Ions*) ionTable->GetIon(2, 8, 0.); // 8He (S3)
601  scatteredIonCharge = 2;
602  }
603  if(!recoilIon){
604  recoilIon = (G4Ions*) ionTable->GetIon(6, 12, 0.); // C12 (S4)
605  recoilIonCharge = 6;
606  }
607 
608  //CINE object...
610 
611  CINE->SetIncidentMass(GetIncidentIon()->GetAtomicMass());
612  CINE->SetTargetMass(GetTargetIon()->GetAtomicMass());
613  CINE->SetScatteredMass(GetScatteredIon()->GetAtomicMass());
614  CINE->SetRecoilMass(GetRecoilIon()->GetAtomicMass());
615  CINE->SetReactionQ(GetReactionQ());
616  CINE->SetLabEnergy(GetLabEnergy());
617  CINE->SetTargetExcitationEnergy(GetTargetIon()->GetExcitationEnergy()/MeV);
618  CINE->SetProjectileExcitationEnergy(GetIncidentIon()->GetExcitationEnergy()/MeV);
619  // Random generator for scattered angle triggered by a messenger Cmd
620  if(randomThetaFlag == "on") {
621  if(verboseLevel>0){
622  G4cout << G4endl
623  << " *************************************************** " << G4endl
624  << " * ActarSimPrimaryGeneratorAction::GeneratePrimaries() " << G4endl
625  << " * reactionFromCineFlag = on, randomThetaFlag = on " << G4endl
626  << " * Using CINE with random angle theta " << G4endl
627  << " * with limits in theta between ["
628  << randomThetaMin/rad << "," << randomThetaMax/rad << "] rads ( ["
629  << randomThetaMin/deg << "," << randomThetaMax/deg << "] degrees)" << G4endl;
630  }
631 
632  //flat prob in theta from randomThetaMin to randomThetaMin
634  ((randomThetaMax-randomThetaMin) * G4UniformRand())) * rad);
635  CINE->SetThetaLabAngle(GetThetaLabAngle()/deg);
636 
637  if(verboseLevel>0) {
638  G4cout << G4endl
639  << " * Selected angle: "<< GetThetaLabAngle()/rad << " rad ( "
640  << GetThetaLabAngle()/deg << " deg )"<< G4endl;
641  G4cout << " *************************************************** "<< G4endl;
642  }
643  } //end of if(randomThetaFlag == "on")
644 
645  if(verboseLevel>0){
646  G4cout << G4endl
647  << " *************************************************** " << G4endl
648  << " * ActarSimPrimaryGeneratorAction::GeneratePrimaries() " << G4endl
649  << " * CINE: Setting masses to the following values: " << G4endl
650  << " * incident ion (atomic) mass: " << GetIncidentIon()->GetAtomicMass() << G4endl
651  << " * target ion (atomic) mass: " << GetTargetIon()->GetAtomicMass() << G4endl
652  << " * scattered ion (atomic) mass: " << GetScatteredIon()->GetAtomicMass() << G4endl
653  << " * recoil ion (atomic) mass: " << GetRecoilIon()->GetAtomicMass() << G4endl;
654  G4cout << " * Setting reaction Q to:" << GetReactionQ() << G4endl;
655  G4cout << " * Setting labEnergy to:" << GetLabEnergy() << G4endl;
656  G4cout << " * Setting targetExcitationEnergy to:"
657  << GetTargetIon()->GetExcitationEnergy() << G4endl;
658  G4cout << " * Setting projectileExcitationEnergy to:"
659  << GetIncidentIon()->GetExcitationEnergy() << G4endl;
660  G4cout << " * Setting labAngle to:" << GetThetaLabAngle() << " deg" << G4endl;
661  G4cout << " *************************************************** "<< G4endl;
662  }
663 
664  if(verboseLevel>2){
665  //Parameters are introduced in CINE... Just a checker
666  G4cout << " CINE: Checking parameters..." << CINE->GetS1()
667  << " " << CINE->GetS2() << " " << CINE->GetS3()
668  << " " << CINE->GetS4() << " " << CINE->GetQM()
669  << " " << CINE->GetEI() << " " << CINE->GetEN()
670  << " " << CINE->GetENI() << " " << CINE->GetThetaLabAngle() << endl;
671  }
672  if(verboseLevel>2){
673  //Parameters are introduced in CINE... Just a checker
674  G4cout << " " << G4endl;
675  G4cout << " CINE: Checking... parameters are introduced in CINE..." << G4endl;
676  //G4cout << " verboseLevel>0..." << G4endl;
677  G4cout << " mass of the incident particle = " << CINE->GetS1()<< G4endl;
678  G4cout << " mass of the target = " << CINE->GetS2() << G4endl;
679  G4cout << " mass of the scattered particle = " << CINE->GetS3()<< G4endl;
680  G4cout << " mass of the recoil = " << CINE->GetS4() << G4endl;
681  G4cout << " Reaction Q = " << CINE->GetQM()<< G4endl;
682  G4cout << " LAB energy (total Lab energy in MeV) = " << CINE->GetEI() << G4endl;
683  G4cout << " Target excitation energy (positive) = " << CINE->GetEN()<< G4endl;
684  G4cout << " Projectile excitation energy (positive) = " << CINE->GetENI() << G4endl;
685  G4cout << " CINE->GetThetaLabAngle = " << CINE->GetThetaLabAngle() << G4endl;
686  G4cout << " " << G4endl;
687  }
688 
689  //Calling the relativistic kinematic calculation
690  CINE->RelativisticKinematics();
691 
692  if(verboseLevel>1){
693  G4cout << " *************************************************** "<< G4endl;
694  G4cout << " ***** CINE: Relativistic calculation invoked ****** "<< G4endl;
695  G4cout << " *************************************************** "<< G4endl;
696  }
697 
698  G4int stillNoSol=0;
699  if(CINE->GetANGAV(1)<0 && randomThetaFlag == "on") {
700  while( CINE->GetANGAV(1)<0 && stillNoSol<50) { //50 tries to get a result!
701  G4cout << " *************************************************** "<< G4endl;
702  G4cout << " * There is no CINE solution" << G4endl;
703  G4cout << " * Trying again with CINE and other scattered angle..." << G4endl;
704  stillNoSol++;
705  SetThetaLabAngle(pi * G4UniformRand() * rad);
706  CINE->SetThetaLabAngle(GetThetaLabAngle()/deg);
707  if(verboseLevel>1) G4cout << " *** random Theta = "
708  << GetThetaLabAngle()/rad << " rad = "
709  << GetThetaLabAngle()/deg << " deg "<< G4endl;
710  //Calling again the relativistic kinematic calculation
711  CINE->RelativisticKinematics();
712  }
713  if(stillNoSol>49)
714  G4cout << G4endl
715  << " ####################################################### "<< G4endl
716  << " ERROR in ActarSimPrimaryGeneratorAction::GeneratePrimaries()" << G4endl
717  << " There is no CINE solution for any angle" << G4endl
718  << " A dummy solution is used: DO NOT RELY ON THE RESULTS!" << G4endl
719  << " ####################################################### "<< G4endl;
720  }
721  if(CINE->GetANGAV(1)<0 && randomThetaFlag == "off") {
722  G4cout << G4endl
723  <<" ####################################################### "<< G4endl
724  << " ERROR in ActarSimPrimaryGeneratorAction::GeneratePrimaries()" << G4endl
725  << " There is no CINE solution for this angle" << G4endl
726  << " A dummy solution is used: DO NOT RELY ON THE RESULTS!" << G4endl
727  <<" ####################################################### "<< G4endl;
728  theta2 = (CINE->GetANGAV(4))*deg;
729  energy1 = CINE->GetANGAV(1);
730  energy2 = CINE->GetANGAV(5);
731  }
732  else if( CINE->GetANGAR(1)<0 && stillNoSol<50) {
733  if(verboseLevel>0){
734  G4cout << " One solution:" << G4endl;
735  CINE->printResults(0);
736  }
737  theta2 = (CINE->GetANGAV(4))*deg;
738  energy1 = CINE->GetANGAV(1);
739  energy2 = CINE->GetANGAV(5);
740  }
741  else {
742  //In this case one should select only one of the two possible cases!
743  if(verboseLevel>0){
744  G4cout << " Two solutions" << G4endl;
745  G4cout << " First solution:" << G4endl;
746  CINE->printResults(0);
747  G4cout << " Second solution:" << G4endl;
748  CINE->printResults(1);
749  }
750  if((G4int)(2*G4UniformRand()) == 0){
751  //theta2 = pi*CINE->GetANGAV(4)/180;
752  theta2 = (CINE->GetANGAV(4))*deg;
753  energy1 = CINE->GetANGAV(1);
754  energy2 = CINE->GetANGAV(5);
755  }
756  else{
757  //theta2 = pi*CINE->GetANGAV(4)/180;
758  theta2 = (CINE->GetANGAV(4))*deg;
759  energy1 = CINE->GetANGAR(1);
760  energy2 = CINE->GetANGAR(5);
761  }
762  }
763  if(verboseLevel>0){
764  G4cout << " *************************************************** "<< G4endl;
765  G4cout << " At least one solution found... generating primaries." << G4endl;
766  G4cout << " " << G4endl;
767  }
768  theta1 = CINE->GetThetaLabAngle()*deg; //Note the units coming from CINE !
769  G4double phi = twopi * G4UniformRand(); //flat probability in phi
770  G4ThreeVector direction1 = G4ThreeVector(sin(theta1)*cos(phi),
771  sin(theta1)*sin(phi),
772  cos(theta1));
773  G4ThreeVector direction2 = G4ThreeVector(sin(theta2)*cos(phi+pi),
774  sin(theta2)*sin(phi+pi),
775  cos(theta2));
776 
777  particleGun->SetParticleDefinition(scatteredIon);
778  particleGun->SetParticleCharge(scatteredIonCharge);
779  particleGun->SetParticlePosition(vertexPosition);
780  //time, including the beam tracking before the vertex formation
781  if(beamInteractionFlag == "on") {
782  ActarSimBeamInfo *pBeamInfo = (ActarSimBeamInfo*) 0;
784  pBeamInfo = gActarSimROOTAnalysis->GetBeamInfo();
785  particleGun->SetParticleTime(pBeamInfo->GetTimeVertex());
786  }
787  }
788  else
789  particleGun->SetParticleTime(0.0);
790 
791  particleGun->SetParticlePolarization(zero);
792  particleGun->SetParticleMomentumDirection(direction1);
793  particleGun->SetParticleEnergy(energy1);
794 
795  particleGun->GeneratePrimaryVertex(anEvent);
796 
797  particleGun->SetParticleDefinition(recoilIon);
798  particleGun->SetParticleCharge(recoilIonCharge);
799  particleGun->SetParticlePosition(vertexPosition);
800 
801  //time, including the beam tracking before the vertex formation
802  if(beamInteractionFlag == "on") {
803  ActarSimBeamInfo *pBeamInfo = (ActarSimBeamInfo*) 0;
805  pBeamInfo = gActarSimROOTAnalysis->GetBeamInfo();
806  particleGun->SetParticleTime(pBeamInfo->GetTimeVertex());
807  }
808  }
809  else
810  particleGun->SetParticleTime(0.0);
811 
812  particleGun->SetParticlePolarization(zero);
813  particleGun->SetParticleMomentumDirection(direction2);
814  particleGun->SetParticleEnergy(energy2);
815 
816  particleGun->GeneratePrimaryVertex(anEvent);
817  }
818 
819  //CASE E Reaction products kinematics calculated using Kine
820  else if(reactionFromKineFlag == "on"){
821  if(verboseLevel>0){
822  G4cout << G4endl
823  << " *************************************************** " << G4endl
824  << " * ActarSimPrimaryGeneratorAction::GeneratePrimaries() " << G4endl
825  << " * reactionFromKineFlag = on " << G4endl
826  << " * Using KINE for the kinematics of reaction products." << G4endl;
827  G4cout << " *************************************************** "<< G4endl;
828  }
829  //Initial values for KINE. It is not allowed to create this initial values
830  //in the constructor...
831  if(!incidentIon) {
832  incidentIon = (G4Ions*) ionTable->GetIon(2, 8, 0.); // 8He (S1)
833  incidentIonCharge = 2;
834  }
835  if(!targetIon) {
836  targetIon = (G4Ions*) ionTable->GetIon(6, 12, 0.); // C12 (S2)
837  targetIonCharge = 6;
838  }
839  if(!scatteredIon){
840  scatteredIon = (G4Ions*) ionTable->GetIon(2, 8, 0.); // 8He (S3)
841  scatteredIonCharge = 2;
842  }
843  if(!recoilIon){
844  recoilIon = (G4Ions*) ionTable->GetIon(6, 12, 0.); // C12 (S4)
845  recoilIonCharge = 6;
846  }
847 
848  //KINE object...
850 
855 
860 
861  KINE->SetLabEnergy(GetLabEnergy());
862 
863  // Random generator for scattered angle triggered by a messenger Cmd
864  if(randomThetaFlag == "on") {
865  SetThetaCMAngle((randomThetaMin + // randomThetaMin, randomThetaMax, use exist ones
866  ((randomThetaMax-randomThetaMin) * G4UniformRand())) * rad);
867  KINE->SetThetaCMAngle(GetThetaCMAngle()/deg); // units: degree, deg=pi/180.
868  if(verboseLevel>1)
869  G4cout << " *** random CM Theta = " << GetThetaCMAngle() << ", it is "
870  << GetThetaCMAngle()/rad << " rad = "
871  << GetThetaCMAngle()/deg << " deg "<< G4endl;
872  }
873  else {
874  KINE->SetThetaCMAngle(GetThetaCMAngle()/deg); // units: degree
875  }
876  if(verboseLevel>1){
877  G4cout << " KINE: Setting (atomic) masses to :" << GetIncidentIon()->GetAtomicMass()
878  << " " << GetTargetIon()->GetAtomicMass()
879  << " " << GetScatteredIon()->GetAtomicMass()
880  << " " << GetRecoilIon()->GetAtomicMass()<< " "<< endl;
881  G4cout << " KINE: Setting labEnergy to:" << KINE->GetLabEnergy() << G4endl;
882  G4cout << " KINE: Setting targetExcitationEnergy to:"
883  << GetTargetIon()->GetExcitationEnergy() << G4endl;
884  G4cout << " KINE: Setting projectileExcitationEnergy to:"
885  << GetIncidentIon()->GetExcitationEnergy() << G4endl;
886  G4cout << " Kine: Setting excitation energy of Scattered particle to:"
887  << GetScatteredIon()->GetExcitationEnergy() << G4endl;
888  G4cout << " KINE: Setting CM Angle to:" << KINE->GetThetaCMAngle() << " deg" << G4endl;
889  }
890  //Calling the relativistic kinematic calculation
891  KINE->KineKinematics();
892 
893  if(KINE->GetNoSolution()) G4cout << "Kine NO solution, check your input!" << G4endl;
894 
895  if(verboseLevel>1){
896  G4cout << " *************************************************** "<< G4endl;
897  G4cout << " ***** KINE: Relativistic calculation invoked ****** "<< G4endl;
898  G4cout << " *************************************************** "<< G4endl;
899  }
900 
901  G4double thetaBeam1, thetaBeam2;
902 
903  thetaBeam1 = KINE->GetANGAs(0); // unit: rad
904  thetaBeam2 = KINE->GetANGAr(0); // unit: rad
905  energy1 = KINE->GetANGAs(1); // unit: MeV
906  energy2 = KINE->GetANGAr(1); // unit: MeV
907 
908  if(verboseLevel>1){
909  G4cout << "Kine: Scattered energy:" << KINE->GetANGAs(1) << " MeV" << G4endl;
910  G4cout << "Kine: Recoiled energy:" << KINE->GetANGAr(1) << " MeV" << G4endl;
911  G4cout << "Kine: Scattered angle:" << KINE->GetANGAs(0)/deg << " deg" << G4endl;
912  G4cout << "Kine: recoiled angle:" << KINE->GetANGAr(0)/deg << " deg" << G4endl;
913  G4cout << "Kine: passed Scattered energy:" << energy1 << " MeV" << G4endl;
914  G4cout << "Kine: passed Recoil energy:" << energy2 << " MeV" << G4endl;
915  G4cout << "Kine: passed Scattered angle:" << theta1/deg << " deg" << G4endl;
916  G4cout << "Kine: passed Recoil angle:" << theta2/deg << " deg" << G4endl;
917  G4cout << "deg=" << deg << ", MeV=" << MeV << G4endl;
918  }
919  G4double phiBeam1=0., phiBeam2=0.;
920  phiBeam1 = twopi * G4UniformRand(); //flat probability in phi
921  phiBeam2 = phiBeam1 + pi;
922 
923  // Euler transformation here for (theta1, phi1) and (theta2, phi2)
924  G4double thetaLab1, phiLab1, thetaLab2, phiLab2;
925 
926  ActarSimBeamInfo *pBeamInfo = (ActarSimBeamInfo*) 0;
928 
930 
931  EulerTransformer->SetThetaInBeamSystem(thetaBeam1);
932  EulerTransformer->SetPhiInBeamSystem(phiBeam1);
933  EulerTransformer->SetBeamDirectionAtVertexTheta(pBeamInfo->GetThetaVertex());
934  EulerTransformer->SetBeamDirectionAtVertexPhi(pBeamInfo->GetPhiVertex());
935  EulerTransformer->DoTheEulerTransformationBeam2Lab(); // Euler transformation for particle 1
936 
937  thetaLab1 = EulerTransformer->GetThetaInLabSystem();
938  phiLab1 = EulerTransformer->GetPhiInLabSystem();
939  if(randomPhiAngleFlag=="off") phiLab1 = GetUserPhiAngle()+pi;
940 
941  G4ThreeVector direction1 = G4ThreeVector(sin(thetaLab1)*cos(phiLab1),
942  sin(thetaLab1)*sin(phiLab1),
943  cos(thetaLab1));
944 
945  EulerTransformer->SetThetaInBeamSystem(thetaBeam2);
946  EulerTransformer->SetPhiInBeamSystem(phiBeam2);
947  EulerTransformer->DoTheEulerTransformationBeam2Lab(); // Euler transformation for particle 2
948 
949  thetaLab2 = EulerTransformer->GetThetaInLabSystem();
950  phiLab2 = EulerTransformer->GetPhiInLabSystem();
951  if(randomPhiAngleFlag=="off") phiLab2 = GetUserPhiAngle();
952 
953  G4ThreeVector direction2 = G4ThreeVector(sin(thetaLab2)*cos(phiLab2),
954  sin(thetaLab2)*sin(phiLab2),
955  cos(thetaLab2));
956  delete EulerTransformer;
957 
958  particleGun->SetParticleDefinition(scatteredIon);
959  particleGun->SetParticleCharge(scatteredIonCharge);
960  particleGun->SetParticlePosition(vertexPosition);
961 
962  //time, including the beam tracking before the vertex formation
963  if(beamInteractionFlag == "on") {
964  //ActarSimBeamInfo *pBeamInfo = (ActarSimBeamInfo*) 0;
966  pBeamInfo = gActarSimROOTAnalysis->GetBeamInfo();
967  particleGun->SetParticleTime(pBeamInfo->GetTimeVertex());
968  }
969  }
970  else
971  particleGun->SetParticleTime(0.0);
972 
973  particleGun->SetParticlePolarization(zero);
974  particleGun->SetParticleMomentumDirection(direction1);
975  particleGun->SetParticleEnergy(energy1);
976 
977  particleGun->GeneratePrimaryVertex(anEvent);
978 
979  particleGun->SetParticleDefinition(recoilIon);
980  particleGun->SetParticleCharge(recoilIonCharge);
981  particleGun->SetParticlePosition(vertexPosition);
982 
983  //time, including the beam tracking before the vertex formation
984  if(beamInteractionFlag == "on") {
985  //ActarSimBeamInfo *pBeamInfo = (ActarSimBeamInfo*) 0;
987  pBeamInfo = gActarSimROOTAnalysis->GetBeamInfo();
988  particleGun->SetParticleTime(pBeamInfo->GetTimeVertex());
989  }
990  }
991  else
992  particleGun->SetParticleTime(0.0);
993 
994  particleGun->SetParticlePolarization(zero);
995  particleGun->SetParticleMomentumDirection(direction2);
996  particleGun->SetParticleEnergy(energy2);
997 
998  particleGun->GeneratePrimaryVertex(anEvent);
999 
1000  //TODO: Check if this part can be used and the status
1001  G4double ExEnergyScattered= GetExEnergyOfScattered();
1002  if(ExEnergyScattered>0){ //Photon is emmited isotropically from vertex
1003  G4double cosTheta_gamma;
1004  G4double phi_gamma = twopi*G4UniformRand();
1005  G4double sinTheta_gamma;
1006  cosTheta_gamma = -1.0 + 2.0*G4UniformRand();
1007  sinTheta_gamma = sqrt(1 - cosTheta_gamma*cosTheta_gamma);
1008  //G4ParticleTable* particleTable = G4ParticleTable::GetParticleTable();
1009  G4String particleName;
1010  particleGun->SetParticleDefinition(particleTable->FindParticle(particleName="gamma"));
1011  particleGun->SetParticleMomentumDirection(G4ThreeVector(sinTheta_gamma*cos(phi_gamma),
1012  sinTheta_gamma*sin(phi_gamma),
1013  cosTheta_gamma));
1014  if(ExEnergyScattered<1.500 && ExEnergyScattered>.86)
1015  particleGun->SetParticleEnergy(ExEnergyScattered-0.854);
1016  else
1017  particleGun->SetParticleEnergy(ExEnergyScattered);
1018  particleGun->SetParticlePosition(vertexPosition);
1019  particleGun->SetParticleTime(0.0);
1020  particleGun->GeneratePrimaryVertex(anEvent);
1021  if(ExEnergyScattered<1.5&&ExEnergyScattered>.86){
1022  particleGun->SetParticleEnergy(0.854);
1023  phi_gamma = twopi*G4UniformRand();
1024  cosTheta_gamma = -1.0 + 2.0*G4UniformRand();
1025  sinTheta_gamma = sqrt(1 - cosTheta_gamma*cosTheta_gamma);
1026  particleGun -> SetParticleMomentumDirection(G4ThreeVector(sinTheta_gamma*cos(phi_gamma),
1027  sinTheta_gamma*sin(phi_gamma),
1028  cosTheta_gamma));
1029  particleGun->SetParticlePosition(vertexPosition);
1030  particleGun->SetParticleTime(0.0);
1031  particleGun->GeneratePrimaryVertex(anEvent);
1032  }
1033  }//end if(ExEnergyScattered>0)
1034  }
1035 
1036  // CASE F Particle selected manually (using the messenger commands)
1037  else{
1038  if(verboseLevel>0){
1039  G4cout << G4endl
1040  << " *************************************************** " << G4endl
1041  << " * ActarSimPrimaryGeneratorAction::GeneratePrimaries() " << G4endl
1042  << " * No particular event generator or kinematics code... " << G4endl
1043  << " * A single particle is thrown using messenger commands." << G4endl;
1044  G4cout << " *************************************************** "<< G4endl;
1045  }
1046 
1047  if(!particleGun->GetParticleDefinition()) {
1048  G4ParticleDefinition* pd = particleTable->FindParticle("proton");
1049  if(pd != 0) particleGun->SetParticleDefinition(pd);
1050  }
1051 
1052  //Random distribution for polar and azimuthal angles
1053  G4double theta;
1054  if(randomThetaFlag == "on") {
1055  G4double CosRandomThetaMin=cos(randomThetaMin);
1056  G4double CosRandomThetaMax=cos(randomThetaMax);
1057 
1058  if(CosRandomThetaMin==1. && CosRandomThetaMax==0. ) {
1059  theta=2*pi*G4UniformRand();
1060  }
1061  else{
1062  theta=randomThetaMin + ((randomThetaMax-randomThetaMin) * G4UniformRand()) * rad;
1063  }
1064  }
1065  else{
1066  theta=GetUserThetaAngle();
1067  }
1068 
1069  if(theta){;}
1070 
1071  G4double phi;
1072  if(randomPhiFlag == "on"){
1073  G4double CosRandomPhiMin=cos(randomPhiMin);
1074  G4double CosRandomPhiMax=cos(randomPhiMax);
1075 
1076  if(CosRandomPhiMin==1. && CosRandomPhiMax==1.)
1077  phi=2*pi*G4UniformRand();
1078  else
1079  phi=randomPhiMin + ((randomPhiMax-randomPhiMin) * G4UniformRand()) * rad;
1080  }
1081  else phi=GetUserPhiAngle();
1082 
1083  if(phi){;}
1084 
1085  if(alphaSourceFlag == "on"){
1086  G4ParticleDefinition* pd = particleTable->FindParticle("alpha");
1087  if(pd != 0) particleGun->SetParticleDefinition(pd);
1088  G4int i=rand() % 3;
1089  G4double alpha_energy[3]={5.15,5.48,5.8};
1090  particleGun->SetParticleEnergy(alpha_energy[i]*MeV);
1091  }
1092  else{
1093  particleGun->SetParticleEnergy(GetIncidentEnergy());
1094  }
1095 
1096  //Piotr: for the p/alpha discrimination test
1097  //G4double ParticleEnergy = GetIncidentEnergy() * G4UniformRand();
1098  //particleGun->SetParticleEnergy(ParticleEnergy);
1099 
1100  G4double radiusAtEntrance = beamRadiusAtEntrance * G4UniformRand(); //from 0 to beamRadiusAtEntrance
1101  G4double phi2AtEntrance = G4UniformRand() * twopi; //angle for defining the entrance point
1102 
1103  //Entrance coordinates (x0,y0,0)
1104  G4double x0 = beamPosition.x() + radiusAtEntrance*cos(phi2AtEntrance);
1105  G4double y0 = beamPosition.y() + radiusAtEntrance*sin(phi2AtEntrance);
1106  G4double z0 = beamPosition.z();
1107 
1108  //particleGun->SetParticlePosition(beamPosition);
1109  particleGun->SetParticlePosition(G4ThreeVector(x0,y0,z0));
1110 
1111  //Particle momentum
1112  if(randomThetaFlag == "on" || randomPhiFlag == "on" || !beamDirectionFlag) particleGun->SetParticleMomentumDirection(G4ThreeVector(sin(theta)*cos(phi),sin(phi),cos(theta)*cos(phi) ) );
1113  else if(beamDirectionFlag) particleGun->SetParticleMomentumDirection(beamMomentumDirection);
1114 
1115  particleGun->GeneratePrimaryVertex(anEvent);
1116  }
1117 
1118  ActarSimBeamInfo *pBeamInfo = (ActarSimBeamInfo*) 0;
1120  pBeamInfo = gActarSimROOTAnalysis->GetBeamInfo();
1121  //Histogramming
1122  gActarSimROOTAnalysis->GeneratePrimaries(anEvent,pBeamInfo);
1123  }
1124 }
void SetBeamMomentumDirection(G4ParticleMomentum aMomentumDirection)
G4String randomThetaFlag
Flag for a random theta angle in CINE.
Double_t GetTimeVertex() const
Double_t GetXVertex() const
G4String reactionFromCineFlag
Flag for a reaction calculated using Cine.
void GeneratePrimaries(const G4Event *, G4double, G4double, G4double, G4double)
G4bool beamDirectionFlag
Flag for a beam direction defined by angles (0) or vector (1)
void SetMassOfScattered(G4double value)
G4String reactionFromFileFlag
Flag for a reaction taken from a file.
void SetMassOfRecoiled(G4double value)
G4double lengthParameter
Parameter coming from the geometry selection.
void SetExEnergyOfScattered(G4double value)
void SetCharge(Double_t c)
Double_t GetYVertex() const
void SetExEnergyOfRecoiled(G4double value)
G4IonTable * ionTable
Pointer to the G4IonTable.
void SetTargetExcitationEnergy(G4double value)
void SetEnergyEntrance(Double_t e)
Double_t GetZVertex() const
G4double thetaLabAngle
Polar angle in the laboratory system.
G4double incidentEnergy
Total incident ion energy.
STL namespace.
void SetBeamInteractionFlag(G4String val)
G4double randomThetaMax
Maximum random theta angle in CINE.
void SetExEnergyOfTarget(G4double value)
G4double randomPhiMin
Minimum random phi angle in CINE.
G4String reactionFromEvGenFlag
Flag for a reaction taken from the tabulated Ev Generator.
G4String randomPhiFlag
Flag for a random phi angle in CINE.
G4ParticleMomentum beamMomentumDirection
Beam (momentum) direction.
void printResults(G4int sel)
Print the results for each solution.
G4double targetIonCharge
Charge of target ion.
G4double randomThetaMin
Minimum random theta angle in CINE.
G4double randomVertexZPositionMax
Maximum value for the (random) Z position of the vertex.
G4ThreeVector vertexPosition
Position of the vertex.
G4ThreeVector beamPosition
Beam position at the entrance.
void SetStatus(Int_t s)
G4ParticleGun * particleGun
Pointer to G4particleGun object initialized in constructor.
void SetExEnergyOfProjectile(G4double value)
G4Ions * incidentIon
Pointer to incident ion.
G4double randomVertexZPositionMin
Minimum value for the (random) Z position of the vertex.
void SetMass(Double_t m)
G4String reactionFromKineFlag
Flag for using KINE.
Double_t GetPhiVertex() const
ActarSimGasDetectorConstruction * GetGasDetector()
void SetBeamDirectionAtVertexTheta(G4double value)
G4ParticleTable * particleTable
Pointer to the G4ParticleTable.
G4String reactionFile
File definition for a reaction.
ActarSimROOTAnalysis * gActarSimROOTAnalysis
Global pointer to this soliton.
G4Ions * recoilIon
Pointer to recoil ion.
void GenerateBeam(const G4Event *)
Defining any beam related histogram or information in the output file.
void SetAnglesEntrance(Double_t, Double_t)
Sets the angles at entrance.
Double_t GetEnergyVertex() const
G4double incidentIonCharge
Charge of incident ion.
void SetPositionEntrance(Double_t, Double_t, Double_t)
Sets the position at entrance of the chamber.
ActarSimPrimaryGeneratorAction()
Constructor: init values are filled.
void SetProjectileExcitationEnergy(G4double value)
G4double recoilIonCharge
Charge of recoil ion.
G4Ions * targetIon
Pointer to target ion.
ActarSimGasDetectorConstruction * gasDetector
Pointer to gas detector constructor, to get some geometrical info.
Int_t GetStatus() const
G4Ions * scatteredIon
Pointer to scattered ion.
ActarSimBeamInfo * GetBeamInfo()
G4String realisticBeamFlag
Flag for realistic beam interaction.
void SetBeamDirectionAtVertexPhi(G4double value)
void SetZVertex(Double_t z)
Double_t GetThetaVertex() const
G4String alphaSourceFlag
Flag for a alpha source emitter.
ActarSimPrimaryGeneratorMessenger * gunMessenger
Pointer to messenger.
G4double vertexZPosition
Value for the (random) Z position of the vertex.
G4String randomVertexZPositionFlag
Flag to control the (random) Z position of the vertex.
void SetMassOfProjectile(G4double value)
G4double scatteredIonCharge
Charge of scattered ion.
G4String randomPhiAngleFlag
Flag for a random phi angle.
G4double beamRadiusAtEntrance
Beam radius at the entrance point.
G4double randomPhiMax
Maximum random phi angle in CINE.
void SetParticleMomentumDirection(G4ParticleMomentum aMomentumDirection)
G4String beamInteractionFlag
Flag for beam interaction mode.