Changeset 1347 for trunk/source/event


Ignore:
Timestamp:
Dec 22, 2010, 3:52:27 PM (15 years ago)
Author:
garnier
Message:

geant4 tag 9.4

Location:
trunk/source/event
Files:
10 edited

Legend:

Unmodified
Added
Removed
  • trunk/source/event/GNUmakefile

    r816 r1347  
    1 # $Id: GNUmakefile,v 1.8 2005/10/17 21:21:53 tinslay Exp $
     1# $Id: GNUmakefile,v 1.10 2010/10/27 07:21:13 gcosmo Exp $
    22# ------------------------------------------------------------
    33# GNUmakefile for events library.  Makoto Asai, 5/9/95.
  • trunk/source/event/History

    r1337 r1347  
    1 $Id: History,v 1.131 2010/06/12 04:07:45 asaim Exp $
     1$Id: History,v 1.142 2010/12/15 22:15:07 asaim Exp $
    22-------------------------------------------------------------------
    33
     
    1717     * Reverse chronological order (last date on top), please *
    1818     ----------------------------------------------------------
     19
     20December 15th, 2010, M.Asai (event-V09-03-10)
     21- Fixing incorrect destination stack for the case more than three track stacks are used.
     22
     23November 24th, 2010, M.Asai (event-V09-03-09)
     24- Added protection against null pointer : G4TrackStack.cc, G4SmartTrackStack.cc
     25
     26Novemver 10th, 2010, F.Lei (event-V09-03-08)
     27- User can now specify arbitrary energy distribution by supplying the data points
     28  in a 2-column (energy<in MeV> and flux) ASCII file, via the UI command
     29   /gps/hist/file your_file_name
     30- Further update of the auto energy biasing implementation
     31- Bug fix (new implementation) in the Spline interpolation implementation
     32- Bug fix in the Logarithm interpolation implementation (alpha = -1 case).   
     33
     34November 8th, 2010, M.Asai (event-V09-03-07)
     35- Setting touchable history of the origin to G4Track.
     36
     37November 2nd, 2010, F.Lei
     38- Implemented concrete destructor for G4SPSEneDistribution (bug #1149)
     39- Added automatic energy biasing scheme. Users now can bias the energy distribution
     40  sampling to a given power-law distribution (index alpha) via the UI command 
     41    /gps/ene/biasAlpha alpha
     42  Files affected are
     43        G4SingleParticleSource.hh .cc
     44        G4SPSEneDistribution.hh .cc 
     45        G4SPSRandomGenerator.hh .cc 
     46        G4GeneralParticleSourceMessenger.hh .cc
     47
     48October 27th, 2010, G.Cosmo (event-V09-03-06)
     49- Restored DLL setup as originally. Withdrawn changes in last tag.
     50
     51October 19th, 2010, G.Cosmo (event-V09-03-05)
     52- Replaced G4EVENT_ALLOC_EXPORT flag with G4ALLOC_EXPORT for DLL exported
     53  symbols.
     54
     55August 9th, 2010, M.Asai (event-V09-03-04)
     56- Fixing electron mass correction for ions in G4PrimaryTransformer.
    1957
    2058June 11th, 2010, M.Asai (event-V09-03-03)
  • trunk/source/event/include/G4GeneralParticleSourceMessenger.hh

    r816 r1347  
    212212  G4UIcmdWithADouble         *gradientCmd1;
    213213  G4UIcmdWithADouble         *interceptCmd1;
     214  G4UIcmdWithADouble         *arbeintCmd1;
    214215  G4UIcmdWithoutParameter    *calculateCmd1;
    215216  G4UIcmdWithABool           *energyspecCmd1;
     
    237238  // old ones, will be removed soon
    238239  G4UIcmdWith3Vector         *histpointCmd1;
     240  G4UIcmdWithAString         *histfileCmd1;
    239241  G4UIcmdWithAString         *histnameCmd1;
    240242  G4UIcmdWithAString         *arbintCmd1;
  • trunk/source/event/include/G4SPSEneDistribution.hh

    r1315 r1347  
    144144#include "G4SPSRandomGenerator.hh"
    145145
    146 class G4SPSEneDistribution
    147 {
     146class G4SPSEneDistribution {
    148147public:
    149   G4SPSEneDistribution ();
    150   ~G4SPSEneDistribution ();
    151 
    152   void SetEnergyDisType(G4String);
    153   inline G4String GetEnergyDisType() {return EnergyDisType;};
    154   void SetEmin(G4double);
    155   inline G4double GetEmin() {return Emin;} ;
    156   inline G4double GetArbEmin() {return ArbEmin;} ;
    157   void SetEmax(G4double);
    158   inline G4double GetEmax() {return Emax;} ;
    159   inline G4double GetArbEmax() {return ArbEmax;};
    160   void SetMonoEnergy(G4double);
    161   void SetAlpha(G4double);
    162   void SetTemp(G4double);
    163   void SetBeamSigmaInE(G4double);
    164   void SetEzero(G4double);
    165   void SetGradient(G4double);
    166   void SetInterCept(G4double);
    167   void UserEnergyHisto(G4ThreeVector);
    168   void ArbEnergyHisto(G4ThreeVector);
    169   void EpnEnergyHisto(G4ThreeVector);
    170 
    171   void InputEnergySpectra(G4bool);
    172   void InputDifferentialSpectra(G4bool);
    173   void ArbInterpolate(G4String);
    174   inline G4String GetIntType() {return IntType;};
    175   void Calculate();
    176   //
    177   void SetBiasRndm(G4SPSRandomGenerator* a) {eneRndm = a; };
    178   // method to re-set the histograms
    179   void ReSetHist(G4String);
    180   // Set the verbosity level.
    181   void SetVerbosity(G4int a) {verbosityLevel = a; } ;
    182   //x
    183 
    184   G4double GetMonoEnergy () {return MonoEnergy; }; //Mono-energteic energy
    185   G4double GetSE() {return SE;}; // Standard deviation for Gaussion distrbution in energy
    186   G4double Getalpha () {return alpha;}; // alpha (pow)
    187   G4double GetEzero() {return Ezero;}; // E0 (exp)
    188   G4double GetTemp() {return Temp;}; // Temp (bbody,brem)
    189   G4double Getgrad() {return grad;}; // gradient and intercept for linear spectra
    190   G4double Getcept() {return cept;};
    191 
    192   inline G4PhysicsOrderedFreeVector  GetUserDefinedEnergyHisto(){return UDefEnergyH;};
    193   inline G4PhysicsOrderedFreeVector  GetArbEnergyHisto(){return ArbEnergyH;};
    194 
    195   G4double GenerateOne(G4ParticleDefinition*);
    196  
     148        G4SPSEneDistribution();
     149        ~G4SPSEneDistribution();
     150
     151        void SetEnergyDisType(G4String);
     152        inline G4String GetEnergyDisType() {
     153                return EnergyDisType;
     154        }
     155        ;
     156        void SetEmin(G4double);
     157        inline G4double GetEmin() {
     158                return Emin;
     159        }
     160        ;
     161        inline G4double GetArbEmin() {
     162                return ArbEmin;
     163        }
     164        ;
     165        void SetEmax(G4double);
     166        inline G4double GetEmax() {
     167                return Emax;
     168        }
     169        ;
     170        inline G4double GetArbEmax() {
     171                return ArbEmax;
     172        }
     173        ;
     174        void SetMonoEnergy(G4double);
     175        void SetAlpha(G4double);
     176        void SetBiasAlpha(G4double);
     177        void SetTemp(G4double);
     178        void SetBeamSigmaInE(G4double);
     179        void SetEzero(G4double);
     180        void SetGradient(G4double);
     181        void SetInterCept(G4double);
     182        void UserEnergyHisto(G4ThreeVector);
     183        void ArbEnergyHisto(G4ThreeVector);
     184        void ArbEnergyHistoFile(G4String);
     185        void EpnEnergyHisto(G4ThreeVector);
     186
     187        void InputEnergySpectra(G4bool);
     188        void InputDifferentialSpectra(G4bool);
     189        void ArbInterpolate(G4String);
     190        inline G4String GetIntType() {
     191                return IntType;
     192        }
     193        ;
     194        void Calculate();
     195        //
     196        void SetBiasRndm(G4SPSRandomGenerator* a) {
     197                eneRndm = a;
     198        }
     199        ;
     200        // method to re-set the histograms
     201        void ReSetHist(G4String);
     202        // Set the verbosity level.
     203        void SetVerbosity(G4int a) {
     204                verbosityLevel = a;
     205        }
     206        ;
     207        //x
     208        G4double GetWeight() {
     209                return weight;
     210        }
     211
     212        G4double GetMonoEnergy() {
     213                return MonoEnergy;
     214        }
     215        ; //Mono-energteic energy
     216        G4double GetSE() {
     217                return SE;
     218        }
     219        ; // Standard deviation for Gaussion distrbution in energy
     220        G4double Getalpha() {
     221                return alpha;
     222        }
     223        ; // alpha (pow)
     224        G4double GetEzero() {
     225                return Ezero;
     226        }
     227        ; // E0 (exp)
     228        G4double GetTemp() {
     229                return Temp;
     230        }
     231        ; // Temp (bbody,brem)
     232        G4double Getgrad() {
     233                return grad;
     234        }
     235        ; // gradient and intercept for linear spectra
     236        G4double Getcept() {
     237                return cept;
     238        }
     239        ;
     240
     241        inline G4PhysicsOrderedFreeVector GetUserDefinedEnergyHisto() {
     242                return UDefEnergyH;
     243        }
     244        ;
     245        inline G4PhysicsOrderedFreeVector GetArbEnergyHisto() {
     246                return ArbEnergyH;
     247        }
     248        ;
     249
     250        G4double GenerateOne(G4ParticleDefinition*);
     251        G4double GetProbability (G4double);
     252
     253
    197254private:
    198   void LinearInterpolation();
    199   void LogInterpolation();
    200   void ExpInterpolation();
    201   void SplineInterpolation();
    202   void CalculateCdgSpectrum();
    203   void CalculateBbodySpectrum();
    204 
    205   // The following methods generate energies according to the spectral
    206   // parameters defined above.
    207   void GenerateMonoEnergetic();
    208   void GenerateLinearEnergies(G4bool);
    209   void GeneratePowEnergies(G4bool);
    210   void GenerateExpEnergies(G4bool );
    211   void GenerateGaussEnergies();
    212   void GenerateBremEnergies();
    213   void GenerateBbodyEnergies();
    214   void GenerateCdgEnergies();
    215   void GenUserHistEnergies();
    216   void GenEpnHistEnergies();
    217   void GenArbPointEnergies();
    218   // converts energy per nucleon to energy.
    219   void ConvertEPNToEnergy();
     255        void LinearInterpolation();
     256        void LogInterpolation();
     257        void ExpInterpolation();
     258        void SplineInterpolation();
     259        void CalculateCdgSpectrum();
     260        void CalculateBbodySpectrum();
     261
     262        // The following methods generate energies according to the spectral
     263        // parameters defined above.
     264        void GenerateMonoEnergetic();
     265        void GenerateLinearEnergies(G4bool);
     266        void GeneratePowEnergies(G4bool);
     267        void GenerateBiasPowEnergies();
     268        void GenerateExpEnergies(G4bool);
     269        void GenerateGaussEnergies();
     270        void GenerateBremEnergies();
     271        void GenerateBbodyEnergies();
     272        void GenerateCdgEnergies();
     273        void GenUserHistEnergies();
     274        void GenEpnHistEnergies();
     275        void GenArbPointEnergies();
     276        // converts energy per nucleon to energy.
     277        void ConvertEPNToEnergy();
     278
    220279
    221280private:
    222281
    223   G4String EnergyDisType; // energy dis type Variable  - Mono,Lin,Exp,etc
    224   G4double MonoEnergy; //Mono-energteic energy
    225   G4double SE ; // Standard deviation for Gaussion distrbution in energy
    226   G4double Emin, Emax; // emin and emax
    227   G4double alpha, Ezero, Temp; // alpha (pow), E0 (exp) and Temp (bbody,brem)
    228   G4double grad, cept; // gradient and intercept for linear spectra
    229   G4bool EnergySpec; // true - energy spectra, false - momentum spectra
    230   G4bool DiffSpec;  // true - differential spec, false integral spec
    231   G4bool ApplyRig; // false no rigidity cutoff, true then apply one
    232   G4double ERig; // energy of rigidity cutoff
    233   G4PhysicsOrderedFreeVector UDefEnergyH; // energy hist data
    234   G4PhysicsOrderedFreeVector IPDFEnergyH; 
    235   G4bool IPDFEnergyExist, IPDFArbExist, Epnflag;
    236   G4PhysicsOrderedFreeVector ArbEnergyH; // Arb x,y histogram
    237   G4PhysicsOrderedFreeVector IPDFArbEnergyH; // IPDF for Arb
    238   G4PhysicsOrderedFreeVector EpnEnergyH;
    239   G4double CDGhist[3]; // cumulative histo for cdg
    240   G4double BBHist[10001], Bbody_x[10001];
    241   G4String IntType; // Interpolation type
    242   G4double Arb_grad[1024], Arb_cept[1024]; // grad and cept for 1024 segments
    243   G4double Arb_alpha[1024], Arb_Const[1024]; // alpha and constants
    244   G4double Arb_ezero[1024]; // ezero
    245   G4double ArbEmin, ArbEmax; // Emin and Emax for the whole arb distribution used primarily for debug.
    246 
    247   G4double               particle_energy;
    248   G4ParticleDefinition*  particle_definition;
    249 
    250   G4SPSRandomGenerator* eneRndm;
    251 
    252   // Verbosity
    253   G4int verbosityLevel;
    254 
    255   G4PhysicsOrderedFreeVector ZeroPhysVector ; // for re-set only
    256 
    257   G4DataInterpolation *SplineInt; // holds Spline stuff
     282        G4String EnergyDisType; // energy dis type Variable  - Mono,Lin,Exp,etc
     283        G4double weight; // particle weight
     284        G4double MonoEnergy; //Mono-energteic energy
     285        G4double SE; // Standard deviation for Gaussion distrbution in energy
     286        G4double Emin, Emax; // emin and emax
     287        G4double alpha, Ezero, Temp; // alpha (pow), E0 (exp) and Temp (bbody,brem)
     288        G4double biasalpha; // biased power index
     289        G4double grad, cept; // gradient and intercept for linear spectra
     290        G4double prob_norm; // normalisation factor use in calculate the probability
     291        G4bool Biased; // true - biased to power-law
     292        G4bool EnergySpec; // true - energy spectra, false - momentum spectra
     293        G4bool DiffSpec; // true - differential spec, false integral spec
     294        G4bool ApplyRig; // false no rigidity cutoff, true then apply one
     295        G4double ERig; // energy of rigidity cutoff
     296        G4PhysicsOrderedFreeVector UDefEnergyH; // energy hist data
     297        G4PhysicsOrderedFreeVector IPDFEnergyH;
     298        G4bool IPDFEnergyExist, IPDFArbExist, Epnflag;
     299        G4PhysicsOrderedFreeVector ArbEnergyH; // Arb x,y histogram
     300        G4PhysicsOrderedFreeVector IPDFArbEnergyH; // IPDF for Arb
     301        G4PhysicsOrderedFreeVector EpnEnergyH;
     302        G4double CDGhist[3]; // cumulative histo for cdg
     303        G4double BBHist[10001], Bbody_x[10001];
     304        G4String IntType; // Interpolation type
     305        G4double Arb_grad[1024], Arb_cept[1024]; // grad and cept for 1024 segments
     306        G4double Arb_alpha[1024], Arb_Const[1024]; // alpha and constants
     307        G4double Arb_ezero[1024]; // ezero
     308        G4double ArbEmin, ArbEmax; // Emin and Emax for the whole arb distribution used primarily for debug.
     309
     310        G4double particle_energy;
     311        G4ParticleDefinition* particle_definition;
     312
     313        G4SPSRandomGenerator* eneRndm;
     314
     315        // Verbosity
     316        G4int verbosityLevel;
     317
     318        G4PhysicsOrderedFreeVector ZeroPhysVector; // for re-set only
     319
     320        G4DataInterpolation *SplineInt[1024]; // holds Spline stuff required for sampling
     321        G4DataInterpolation *Splinetemp; // holds a temp Spline used for calculating area
    258322
    259323};
    260324
    261 
    262325#endif
    263326
    264 
    265 
    266 
  • trunk/source/event/include/G4SPSRandomGenerator.hh

    r816 r1347  
    136136#include "G4DataInterpolation.hh"
    137137
    138 class G4SPSRandomGenerator
    139 {
     138class G4SPSRandomGenerator {
    140139public:
    141   G4SPSRandomGenerator ();
    142   ~G4SPSRandomGenerator ();
    143 
    144   //  static G4SPSRandomGenerator* getInstance ();
    145 
    146   // Biasing Methods
    147   void SetXBias(G4ThreeVector);
    148   void SetYBias(G4ThreeVector);
    149   void SetZBias(G4ThreeVector);
    150   void SetThetaBias(G4ThreeVector);
    151   void SetPhiBias(G4ThreeVector);
    152   void SetEnergyBias(G4ThreeVector);
    153   void SetPosThetaBias(G4ThreeVector);
    154   void SetPosPhiBias(G4ThreeVector);
    155   G4double GenRandX();
    156   G4double GenRandY();
    157   G4double GenRandZ();
    158   G4double GenRandTheta();
    159   G4double GenRandPhi();
    160   G4double GenRandEnergy();
    161   G4double GenRandPosTheta();
    162   G4double GenRandPosPhi();
    163 
    164   inline void SetIntensityWeight(G4double weight) {bweights[8]=weight;};
    165 
    166   inline G4double GetBiasWeight()
    167   { return bweights[0]*bweights[1]*bweights[2]*bweights[3]*bweights[4]*bweights[5]*bweights[6]*bweights[7]*bweights[8];};
    168  
    169  // method to re-set the histograms
    170   void ReSetHist(G4String);
    171 
    172   // Set the verbosity level.
    173    void SetVerbosity(G4int a) {verbosityLevel = a; } ;
     140        G4SPSRandomGenerator();
     141        ~G4SPSRandomGenerator();
     142
     143        //  static G4SPSRandomGenerator* getInstance ();
     144
     145        // Biasing Methods
     146        void SetXBias(G4ThreeVector);
     147        void SetYBias(G4ThreeVector);
     148        void SetZBias(G4ThreeVector);
     149        void SetThetaBias(G4ThreeVector);
     150        void SetPhiBias(G4ThreeVector);
     151        void SetEnergyBias(G4ThreeVector);
     152        void SetPosThetaBias(G4ThreeVector);
     153        void SetPosPhiBias(G4ThreeVector);
     154        G4double GenRandX();
     155        G4double GenRandY();
     156        G4double GenRandZ();
     157        G4double GenRandTheta();
     158        G4double GenRandPhi();
     159        G4double GenRandEnergy();
     160        G4double GenRandPosTheta();
     161        G4double GenRandPosPhi();
     162
     163        inline void SetIntensityWeight(G4double weight) {
     164                bweights[8] = weight;
     165        }
     166        ;
     167
     168        inline G4double GetBiasWeight() {
     169                return bweights[0] * bweights[1] * bweights[2] * bweights[3]
     170                                * bweights[4] * bweights[5] * bweights[6] * bweights[7]
     171                                * bweights[8];
     172        }
     173        ;
     174
     175        // method to re-set the histograms
     176        void ReSetHist(G4String);
     177
     178        // Set the verbosity level.
     179        void SetVerbosity(G4int a) {
     180                verbosityLevel = a;
     181        }
     182        ;
    174183
    175184private:
    176185
    177   //  static G4SPSRandomGenerator  *instance;
    178 
    179   G4bool XBias, IPDFXBias;
    180   G4PhysicsOrderedFreeVector XBiasH;
    181   G4PhysicsOrderedFreeVector IPDFXBiasH;
    182   G4bool YBias, IPDFYBias;
    183   G4PhysicsOrderedFreeVector YBiasH;
    184   G4PhysicsOrderedFreeVector IPDFYBiasH;
    185   G4bool ZBias, IPDFZBias;
    186   G4PhysicsOrderedFreeVector ZBiasH;
    187   G4PhysicsOrderedFreeVector IPDFZBiasH;
    188   G4bool ThetaBias, IPDFThetaBias;
    189   G4PhysicsOrderedFreeVector ThetaBiasH;
    190   G4PhysicsOrderedFreeVector IPDFThetaBiasH;
    191   G4bool PhiBias, IPDFPhiBias;
    192   G4PhysicsOrderedFreeVector PhiBiasH;
    193   G4PhysicsOrderedFreeVector IPDFPhiBiasH;
    194   G4bool EnergyBias, IPDFEnergyBias;
    195   G4PhysicsOrderedFreeVector EnergyBiasH;
    196   G4PhysicsOrderedFreeVector IPDFEnergyBiasH;
    197   G4bool PosThetaBias, IPDFPosThetaBias;
    198   G4PhysicsOrderedFreeVector PosThetaBiasH;
    199   G4PhysicsOrderedFreeVector IPDFPosThetaBiasH;
    200   G4bool PosPhiBias, IPDFPosPhiBias;
    201   G4PhysicsOrderedFreeVector PosPhiBiasH;
    202   G4PhysicsOrderedFreeVector IPDFPosPhiBiasH;
    203 
    204   G4double bweights[9]; //record x,y,z,theta,phi,energy,posThet,posPhi,intensity weights
    205 
    206   // Verbosity
    207   G4int verbosityLevel;
    208 
    209   G4PhysicsOrderedFreeVector ZeroPhysVector ; // for re-set only
    210  
     186        //  static G4SPSRandomGenerator  *instance;
     187
     188        G4bool XBias, IPDFXBias;
     189        G4PhysicsOrderedFreeVector XBiasH;
     190        G4PhysicsOrderedFreeVector IPDFXBiasH;
     191        G4bool YBias, IPDFYBias;
     192        G4PhysicsOrderedFreeVector YBiasH;
     193        G4PhysicsOrderedFreeVector IPDFYBiasH;
     194        G4bool ZBias, IPDFZBias;
     195        G4PhysicsOrderedFreeVector ZBiasH;
     196        G4PhysicsOrderedFreeVector IPDFZBiasH;
     197        G4bool ThetaBias, IPDFThetaBias;
     198        G4PhysicsOrderedFreeVector ThetaBiasH;
     199        G4PhysicsOrderedFreeVector IPDFThetaBiasH;
     200        G4bool PhiBias, IPDFPhiBias;
     201        G4PhysicsOrderedFreeVector PhiBiasH;
     202        G4PhysicsOrderedFreeVector IPDFPhiBiasH;
     203        G4bool EnergyBias, IPDFEnergyBias;
     204        G4PhysicsOrderedFreeVector EnergyBiasH;
     205        G4PhysicsOrderedFreeVector IPDFEnergyBiasH;
     206        G4bool PosThetaBias, IPDFPosThetaBias;
     207        G4PhysicsOrderedFreeVector PosThetaBiasH;
     208        G4PhysicsOrderedFreeVector IPDFPosThetaBiasH;
     209        G4bool PosPhiBias, IPDFPosPhiBias;
     210        G4PhysicsOrderedFreeVector PosPhiBiasH;
     211        G4PhysicsOrderedFreeVector IPDFPosPhiBiasH;
     212
     213        G4double alpha;   // for biasing energy
     214
     215        G4double bweights[9]; //record x,y,z,theta,phi,energy,posThet,posPhi,intensity weights
     216
     217        // Verbosity
     218        G4int verbosityLevel;
     219
     220        G4PhysicsOrderedFreeVector ZeroPhysVector; // for re-set only
     221
    211222};
    212223
    213 
    214224#endif
    215225
    216 
    217 
    218 
  • trunk/source/event/include/G4SingleParticleSource.hh

    r816 r1347  
    121121#include "G4SPSRandomGenerator.hh"
    122122
    123 class G4SingleParticleSource : public G4VPrimaryGenerator
    124 {
     123class G4SingleParticleSource: public G4VPrimaryGenerator {
    125124public:
    126   G4SingleParticleSource ();
    127   ~G4SingleParticleSource ();
    128   void GeneratePrimaryVertex(G4Event *evt);
    129   //
    130   G4SPSPosDistribution* GetPosDist() {return posGenerator;};
    131   G4SPSAngDistribution* GetAngDist() {return angGenerator;};
    132   G4SPSEneDistribution* GetEneDist() {return eneGenerator;};
    133   G4SPSRandomGenerator* GetBiasRndm() {return biasRndm;};
    134 
    135   // Set the verbosity level.
    136   void SetVerbosity(G4int);
    137 
    138   // Set the particle species
    139   void SetParticleDefinition (G4ParticleDefinition * aParticleDefinition);
    140   inline G4ParticleDefinition * GetParticleDefinition () { return particle_definition;} ;
    141 
    142   inline void SetParticleCharge(G4double aCharge) { particle_charge = aCharge; } ;
    143 
    144   // Set polarization
    145   inline void SetParticlePolarization (G4ThreeVector aVal) {particle_polarization = aVal;};
    146   inline G4ThreeVector GetParticlePolarization ()  {return particle_polarization;};
    147 
    148   // Set Time.
    149   inline void SetParticleTime(G4double aTime)  { particle_time = aTime; };
    150   inline G4double GetParticleTime()  { return particle_time; };
    151 
    152   inline void SetNumberOfParticles(G4int i)  { NumberOfParticlesToBeGenerated = i; };
    153   //
    154   inline G4int GetNumberOfParticles() { return NumberOfParticlesToBeGenerated; };
    155   inline G4ThreeVector GetParticlePosition()  { return particle_position;};
    156   inline G4ThreeVector GetParticleMomentumDirection()  { return particle_momentum_direction;};
    157   inline G4double GetParticleEnergy()  {return particle_energy;};
     125        G4SingleParticleSource();
     126        ~G4SingleParticleSource();
     127        void GeneratePrimaryVertex(G4Event *evt);
     128        //
     129        G4SPSPosDistribution* GetPosDist() {
     130                return posGenerator;
     131        }
     132        ;
     133        G4SPSAngDistribution* GetAngDist() {
     134                return angGenerator;
     135        }
     136        ;
     137        G4SPSEneDistribution* GetEneDist() {
     138                return eneGenerator;
     139        }
     140        ;
     141        G4SPSRandomGenerator* GetBiasRndm() {
     142                return biasRndm;
     143        }
     144        ;
     145
     146        // Set the verbosity level.
     147        void SetVerbosity(G4int);
     148
     149        // Set the particle species
     150        void SetParticleDefinition(G4ParticleDefinition * aParticleDefinition);
     151        inline G4ParticleDefinition * GetParticleDefinition() {
     152                return particle_definition;
     153        }
     154        ;
     155
     156        inline void SetParticleCharge(G4double aCharge) {
     157                particle_charge = aCharge;
     158        }
     159        ;
     160
     161        // Set polarization
     162        inline void SetParticlePolarization(G4ThreeVector aVal) {
     163                particle_polarization = aVal;
     164        }
     165        ;
     166        inline G4ThreeVector GetParticlePolarization() {
     167                return particle_polarization;
     168        }
     169        ;
     170
     171        // Set Time.
     172        inline void SetParticleTime(G4double aTime) {
     173                particle_time = aTime;
     174        }
     175        ;
     176        inline G4double GetParticleTime() {
     177                return particle_time;
     178        }
     179        ;
     180
     181        inline void SetNumberOfParticles(G4int i) {
     182                NumberOfParticlesToBeGenerated = i;
     183        }
     184        ;
     185        //
     186        inline G4int GetNumberOfParticles() {
     187                return NumberOfParticlesToBeGenerated;
     188        }
     189        ;
     190        inline G4ThreeVector GetParticlePosition() {
     191                return particle_position;
     192        }
     193        ;
     194        inline G4ThreeVector GetParticleMomentumDirection() {
     195                return particle_momentum_direction;
     196        }
     197        ;
     198        inline G4double GetParticleEnergy() {
     199                return particle_energy;
     200        }
     201        ;
    158202
    159203private:
    160204
    161   G4SPSPosDistribution* posGenerator;
    162   G4SPSAngDistribution* angGenerator;
    163   G4SPSEneDistribution* eneGenerator;
    164   G4SPSRandomGenerator* biasRndm;
    165   //
    166   // Other particle properties
    167   G4int                  NumberOfParticlesToBeGenerated;
    168   G4ParticleDefinition * particle_definition;
    169   G4ParticleMomentum    particle_momentum_direction;
    170   G4double              particle_energy;
    171   G4double              particle_charge;
    172   G4ThreeVector          particle_position;
    173   G4double              particle_time;
    174   G4ThreeVector          particle_polarization;
    175   G4double              particle_weight;
    176 
    177   // Verbosity
    178   G4int verbosityLevel;
     205        G4SPSPosDistribution* posGenerator;
     206        G4SPSAngDistribution* angGenerator;
     207        G4SPSEneDistribution* eneGenerator;
     208        G4SPSRandomGenerator* biasRndm;
     209        //
     210        // Other particle properties
     211        G4int NumberOfParticlesToBeGenerated;
     212        G4ParticleDefinition * particle_definition;
     213        G4ParticleMomentum particle_momentum_direction;
     214        G4double particle_energy;
     215        G4double particle_charge;
     216        G4ThreeVector particle_position;
     217        G4double particle_time;
     218        G4ThreeVector particle_polarization;
     219        G4double particle_weight;
     220
     221        // Verbosity
     222        G4int verbosityLevel;
    179223
    180224};
    181225
    182 
    183226#endif
    184227
    185 
    186 
    187 
  • trunk/source/event/src/G4GeneralParticleSourceMessenger.cc

    r1196 r1347  
    151151  directionCmd->SetGuidance("Set momentum direction.");
    152152  directionCmd->SetGuidance("Direction needs not to be a unit vector.");
    153   directionCmd->SetParameterName("Px","Py","Pz",true,true);
     153  directionCmd->SetParameterName("Px","Py","Pz",false,false);
    154154  directionCmd->SetRange("Px != 0 || Py != 0 || Pz != 0");
    155155 
    156156  energyCmd = new G4UIcmdWithADoubleAndUnit("/gps/energy",this);
    157157  energyCmd->SetGuidance("Set kinetic energy.");
    158   energyCmd->SetParameterName("Energy",true,true);
     158  energyCmd->SetParameterName("Energy",false,false);
    159159  energyCmd->SetDefaultUnit("GeV");
    160160  //energyCmd->SetUnitCategory("Energy");
     
    163163  positionCmd = new G4UIcmdWith3VectorAndUnit("/gps/position",this);
    164164  positionCmd->SetGuidance("Set starting position of the particle.");
    165   positionCmd->SetParameterName("X","Y","Z",true,true);
     165  positionCmd->SetParameterName("X","Y","Z",false,false);
    166166  positionCmd->SetDefaultUnit("cm");
    167167  //positionCmd->SetUnitCategory("Length");
     
    193193  timeCmd = new G4UIcmdWithADoubleAndUnit("/gps/time",this);
    194194  timeCmd->SetGuidance("Set initial time of the particle.");
    195   timeCmd->SetParameterName("t0",true,true);
     195  timeCmd->SetParameterName("t0",false,false);
    196196  timeCmd->SetDefaultUnit("ns");
    197197  //timeCmd->SetUnitCategory("Time");
     
    200200  polCmd = new G4UIcmdWith3Vector("/gps/polarization",this);
    201201  polCmd->SetGuidance("Set polarization.");
    202   polCmd->SetParameterName("Px","Py","Pz",true,true);
     202  polCmd->SetParameterName("Px","Py","Pz",false,false);
    203203  polCmd->SetRange("Px>=-1.&&Px<=1.&&Py>=-1.&&Py<=1.&&Pz>=-1.&&Pz<=1.");
    204204
    205205  numberCmd = new G4UIcmdWithAnInteger("/gps/number",this);
    206206  numberCmd->SetGuidance("Set number of particles to be generated per vertex.");
    207   numberCmd->SetParameterName("N",true,true);
     207  numberCmd->SetParameterName("N",false,false);
    208208  numberCmd->SetRange("N>0");
    209209
     
    225225  typeCmd1->SetGuidance("Sets source distribution type.");
    226226  typeCmd1->SetGuidance("Either Point, Beam, Plane, Surface or Volume");
    227   typeCmd1->SetParameterName("DisType",true,true);
     227  typeCmd1->SetParameterName("DisType",false,false);
    228228  typeCmd1->SetDefaultValue("Point");
    229229  typeCmd1->SetCandidates("Point Beam Plane Surface Volume");
     
    231231  shapeCmd1 = new G4UIcmdWithAString("/gps/pos/shape",this);
    232232  shapeCmd1->SetGuidance("Sets source shape for Plan, Surface or Volume type source.");
    233   shapeCmd1->SetParameterName("Shape",true,true);
     233  shapeCmd1->SetParameterName("Shape",false,false);
    234234  shapeCmd1->SetDefaultValue("NULL");
    235235  shapeCmd1->SetCandidates("Circle Annulus Ellipse Square Rectangle Sphere Ellipsoid Cylinder Para");
     
    238238  centreCmd1->SetGuidance("Set centre coordinates of source.");
    239239  centreCmd1->SetGuidance("   same effect as the /gps/position command");
    240   centreCmd1->SetParameterName("X","Y","Z",true,true);
     240  centreCmd1->SetParameterName("X","Y","Z",false,false);
    241241  centreCmd1->SetDefaultUnit("cm");
    242242  //  centreCmd1->SetUnitCandidates("micron mm cm m km");
     
    245245  posrot1Cmd1->SetGuidance("Set the 1st vector defining the rotation matrix'.");
    246246  posrot1Cmd1->SetGuidance("It does not need to be a unit vector.");
    247   posrot1Cmd1->SetParameterName("R1x","R1y","R1z",true,true);
     247  posrot1Cmd1->SetParameterName("R1x","R1y","R1z",false,false);
    248248  posrot1Cmd1->SetRange("R1x != 0 || R1y != 0 || R1z != 0");
    249249
     
    251251  posrot2Cmd1->SetGuidance("Set the 2nd vector defining the rotation matrix'.");
    252252  posrot2Cmd1->SetGuidance("It does not need to be a unit vector.");
    253   posrot2Cmd1->SetParameterName("R2x","R2y","R2z",true,true);
     253  posrot2Cmd1->SetParameterName("R2x","R2y","R2z",false,false);
    254254  posrot2Cmd1->SetRange("R2x != 0 || R2y != 0 || R2z != 0");
    255255
    256256  halfxCmd1 = new G4UIcmdWithADoubleAndUnit("/gps/pos/halfx",this);
    257257  halfxCmd1->SetGuidance("Set x half length of source.");
    258   halfxCmd1->SetParameterName("Halfx",true,true);
     258  halfxCmd1->SetParameterName("Halfx",false,false);
    259259  halfxCmd1->SetDefaultUnit("cm");
    260260  //  halfxCmd1->SetUnitCandidates("micron mm cm m km");
     
    262262  halfyCmd1 = new G4UIcmdWithADoubleAndUnit("/gps/pos/halfy",this);
    263263  halfyCmd1->SetGuidance("Set y half length of source.");
    264   halfyCmd1->SetParameterName("Halfy",true,true);
     264  halfyCmd1->SetParameterName("Halfy",false,false);
    265265  halfyCmd1->SetDefaultUnit("cm");
    266266  //  halfyCmd1->SetUnitCandidates("micron mm cm m km");
     
    268268  halfzCmd1 = new G4UIcmdWithADoubleAndUnit("/gps/pos/halfz",this);
    269269  halfzCmd1->SetGuidance("Set z half length of source.");
    270   halfzCmd1->SetParameterName("Halfz",true,true);
     270  halfzCmd1->SetParameterName("Halfz",false,false);
    271271  halfzCmd1->SetDefaultUnit("cm");
    272272  //  halfzCmd1->SetUnitCandidates("micron mm cm m km");
     
    274274  radiusCmd1 = new G4UIcmdWithADoubleAndUnit("/gps/pos/radius",this);
    275275  radiusCmd1->SetGuidance("Set radius of source.");
    276   radiusCmd1->SetParameterName("Radius",true,true);
     276  radiusCmd1->SetParameterName("Radius",false,false);
    277277  radiusCmd1->SetDefaultUnit("cm");
    278278  //  radiusCmd1->SetUnitCandidates("micron mm cm m km");
     
    280280  radius0Cmd1 = new G4UIcmdWithADoubleAndUnit("/gps/pos/inner_radius",this);
    281281  radius0Cmd1->SetGuidance("Set inner radius of source when required.");
    282   radius0Cmd1->SetParameterName("Radius0",true,true);
     282  radius0Cmd1->SetParameterName("Radius0",false,false);
    283283  radius0Cmd1->SetDefaultUnit("cm");
    284284  //  radius0Cmd1->SetUnitCandidates("micron mm cm m km");
     
    287287  possigmarCmd1->SetGuidance("Set standard deviation in radial of the beam positional profile");
    288288  possigmarCmd1->SetGuidance(" applicable to Beam type source only");
    289   possigmarCmd1->SetParameterName("Sigmar",true,true);
     289  possigmarCmd1->SetParameterName("Sigmar",false,false);
    290290  possigmarCmd1->SetDefaultUnit("cm");
    291291  //  possigmarCmd1->SetUnitCandidates("micron mm cm m km");
     
    294294  possigmaxCmd1->SetGuidance("Set standard deviation of beam positional profile in x-dir");
    295295  possigmaxCmd1->SetGuidance(" applicable to Beam type source only");
    296   possigmaxCmd1->SetParameterName("Sigmax",true,true);
     296  possigmaxCmd1->SetParameterName("Sigmax",false,false);
    297297  possigmaxCmd1->SetDefaultUnit("cm");
    298298  //  possigmaxCmd1->SetUnitCandidates("micron mm cm m km");
     
    301301  possigmayCmd1->SetGuidance("Set standard deviation of beam positional profile in y-dir");
    302302  possigmayCmd1->SetGuidance(" applicable to Beam type source only");
    303   possigmayCmd1->SetParameterName("Sigmay",true,true);
     303  possigmayCmd1->SetParameterName("Sigmay",false,false);
    304304  possigmayCmd1->SetDefaultUnit("cm");
    305305  //  possigmayCmd1->SetUnitCandidates("micron mm cm m km");
     
    307307  paralpCmd1 = new G4UIcmdWithADoubleAndUnit("/gps/pos/paralp",this);
    308308  paralpCmd1->SetGuidance("Angle from y-axis of y' in Para");
    309   paralpCmd1->SetParameterName("paralp",true,true);
     309  paralpCmd1->SetParameterName("paralp",false,false);
    310310  paralpCmd1->SetDefaultUnit("rad");
    311311  //  paralpCmd1->SetUnitCandidates("rad deg");
     
    313313  partheCmd1 = new G4UIcmdWithADoubleAndUnit("/gps/pos/parthe",this);
    314314  partheCmd1->SetGuidance("Polar angle through centres of z faces");
    315   partheCmd1->SetParameterName("parthe",true,true);
     315  partheCmd1->SetParameterName("parthe",false,false);
    316316  partheCmd1->SetDefaultUnit("rad");
    317317  //  partheCmd1->SetUnitCandidates("rad deg");
     
    319319  parphiCmd1 = new G4UIcmdWithADoubleAndUnit("/gps/pos/parphi",this);
    320320  parphiCmd1->SetGuidance("Azimuth angle through centres of z faces");
    321   parphiCmd1->SetParameterName("parphi",true,true);
     321  parphiCmd1->SetParameterName("parphi",false,false);
    322322  parphiCmd1->SetDefaultUnit("rad");
    323323  //  parphiCmd1->SetUnitCandidates("rad deg");
     
    326326  confineCmd1->SetGuidance("Confine source to volume (NULL to unset).");
    327327  confineCmd1->SetGuidance("usage: confine VolName");
    328   confineCmd1->SetParameterName("VolName",true,true);
     328  confineCmd1->SetParameterName("VolName",false,false);
    329329  confineCmd1->SetDefaultValue("NULL");
    330330
     
    333333  typeCmd->SetGuidance("Sets source distribution type. (obsolete!)");
    334334  typeCmd->SetGuidance("Either Point, Beam, Plane, Surface or Volume");
    335   typeCmd->SetParameterName("DisType",true,true);
     335  typeCmd->SetParameterName("DisType",false,false);
    336336  typeCmd->SetDefaultValue("Point");
    337337  typeCmd->SetCandidates("Point Beam Plane Surface Volume");
     
    339339  shapeCmd = new G4UIcmdWithAString("/gps/shape",this);
    340340  shapeCmd->SetGuidance("Sets source shape type.(obsolete!)");
    341   shapeCmd->SetParameterName("Shape",true,true);
     341  shapeCmd->SetParameterName("Shape",false,false);
    342342  shapeCmd->SetDefaultValue("NULL");
    343343  shapeCmd->SetCandidates("Circle Annulus Ellipse Square Rectangle Sphere Ellipsoid Cylinder Para");
     
    345345  centreCmd = new G4UIcmdWith3VectorAndUnit("/gps/centre",this);
    346346  centreCmd->SetGuidance("Set centre coordinates of source.(obsolete!)");
    347   centreCmd->SetParameterName("X","Y","Z",true,true);
     347  centreCmd->SetParameterName("X","Y","Z",false,false);
    348348  centreCmd->SetDefaultUnit("cm");
    349349  //  centreCmd->SetUnitCandidates("micron mm cm m km");
     
    352352  posrot1Cmd->SetGuidance("Set rotation matrix of x'.(obsolete!)");
    353353  posrot1Cmd->SetGuidance("Posrot1 does not need to be a unit vector.");
    354   posrot1Cmd->SetParameterName("R1x","R1y","R1z",true,true);
     354  posrot1Cmd->SetParameterName("R1x","R1y","R1z",false,false);
    355355  posrot1Cmd->SetRange("R1x != 0 || R1y != 0 || R1z != 0");
    356356
     
    358358  posrot2Cmd->SetGuidance("Set rotation matrix of y'.(obsolete!)");
    359359  posrot2Cmd->SetGuidance("Posrot2 does not need to be a unit vector.");
    360   posrot2Cmd->SetParameterName("R2x","R2y","R2z",true,true);
     360  posrot2Cmd->SetParameterName("R2x","R2y","R2z",false,false);
    361361  posrot2Cmd->SetRange("R2x != 0 || R2y != 0 || R2z != 0");
    362362
    363363  halfxCmd = new G4UIcmdWithADoubleAndUnit("/gps/halfx",this);
    364364  halfxCmd->SetGuidance("Set x half length of source.(obsolete!)");
    365   halfxCmd->SetParameterName("Halfx",true,true);
     365  halfxCmd->SetParameterName("Halfx",false,false);
    366366  halfxCmd->SetDefaultUnit("cm");
    367367  //  halfxCmd->SetUnitCandidates("micron mm cm m km");
     
    369369  halfyCmd = new G4UIcmdWithADoubleAndUnit("/gps/halfy",this);
    370370  halfyCmd->SetGuidance("Set y half length of source.(obsolete!)");
    371   halfyCmd->SetParameterName("Halfy",true,true);
     371  halfyCmd->SetParameterName("Halfy",false,false);
    372372  halfyCmd->SetDefaultUnit("cm");
    373373  //  halfyCmd->SetUnitCandidates("micron mm cm m km");
     
    375375  halfzCmd = new G4UIcmdWithADoubleAndUnit("/gps/halfz",this);
    376376  halfzCmd->SetGuidance("Set z half length of source.(obsolete!)");
    377   halfzCmd->SetParameterName("Halfz",true,true);
     377  halfzCmd->SetParameterName("Halfz",false,false);
    378378  halfzCmd->SetDefaultUnit("cm");
    379379  //  halfzCmd->SetUnitCandidates("micron mm cm m km");
     
    381381  radiusCmd = new G4UIcmdWithADoubleAndUnit("/gps/radius",this);
    382382  radiusCmd->SetGuidance("Set radius of source.(obsolete!)");
    383   radiusCmd->SetParameterName("Radius",true,true);
     383  radiusCmd->SetParameterName("Radius",false,false);
    384384  radiusCmd->SetDefaultUnit("cm");
    385385  //  radiusCmd->SetUnitCandidates("micron mm cm m km");
     
    387387  radius0Cmd = new G4UIcmdWithADoubleAndUnit("/gps/radius0",this);
    388388  radius0Cmd->SetGuidance("Set inner radius of source.(obsolete!)");
    389   radius0Cmd->SetParameterName("Radius0",true,true);
     389  radius0Cmd->SetParameterName("Radius0",false,false);
    390390  radius0Cmd->SetDefaultUnit("cm");
    391391  //  radius0Cmd->SetUnitCandidates("micron mm cm m km");
     
    393393  possigmarCmd = new G4UIcmdWithADoubleAndUnit("/gps/sigmaposr",this);
    394394  possigmarCmd->SetGuidance("Set standard deviation of beam position in radial(obsolete!)");
    395   possigmarCmd->SetParameterName("Sigmar",true,true);
     395  possigmarCmd->SetParameterName("Sigmar",false,false);
    396396  possigmarCmd->SetDefaultUnit("cm");
    397397  // possigmarCmd->SetUnitCandidates("micron mm cm m km");
     
    399399  possigmaxCmd = new G4UIcmdWithADoubleAndUnit("/gps/sigmaposx",this);
    400400  possigmaxCmd->SetGuidance("Set standard deviation of beam position in x-dir(obsolete!)");
    401   possigmaxCmd->SetParameterName("Sigmax",true,true);
     401  possigmaxCmd->SetParameterName("Sigmax",false,false);
    402402  possigmaxCmd->SetDefaultUnit("cm");
    403403  //  possigmaxCmd->SetUnitCandidates("micron mm cm m km");
     
    405405  possigmayCmd = new G4UIcmdWithADoubleAndUnit("/gps/sigmaposy",this);
    406406  possigmayCmd->SetGuidance("Set standard deviation of beam position in y-dir(obsolete!)");
    407   possigmayCmd->SetParameterName("Sigmay",true,true);
     407  possigmayCmd->SetParameterName("Sigmay",false,false);
    408408  possigmayCmd->SetDefaultUnit("cm");
    409409  //  possigmayCmd->SetUnitCandidates("micron mm cm m km");
     
    411411  paralpCmd = new G4UIcmdWithADoubleAndUnit("/gps/paralp",this);
    412412  paralpCmd->SetGuidance("Angle from y-axis of y' in Para(obsolete!)");
    413   paralpCmd->SetParameterName("paralp",true,true);
     413  paralpCmd->SetParameterName("paralp",false,false);
    414414  paralpCmd->SetDefaultUnit("rad");
    415415  //  paralpCmd->SetUnitCandidates("rad deg");
     
    417417  partheCmd = new G4UIcmdWithADoubleAndUnit("/gps/parthe",this);
    418418  partheCmd->SetGuidance("Polar angle through centres of z faces(obsolete!)");
    419   partheCmd->SetParameterName("parthe",true,true);
     419  partheCmd->SetParameterName("parthe",false,false);
    420420  partheCmd->SetDefaultUnit("rad");
    421421  //  partheCmd->SetUnitCandidates("rad deg");
     
    423423  parphiCmd = new G4UIcmdWithADoubleAndUnit("/gps/parphi",this);
    424424  parphiCmd->SetGuidance("Azimuth angle through centres of z faces(obsolete!)");
    425   parphiCmd->SetParameterName("parphi",true,true);
     425  parphiCmd->SetParameterName("parphi",false,false);
    426426  parphiCmd->SetDefaultUnit("rad");
    427427  //  parphiCmd->SetUnitCandidates("rad deg");
     
    430430  confineCmd->SetGuidance("Confine source to volume (NULL to unset)(obsolete!) .");
    431431  confineCmd->SetGuidance("usage: confine VolName");
    432   confineCmd->SetParameterName("VolName",true,true);
     432  confineCmd->SetParameterName("VolName",false,false);
    433433  confineCmd->SetDefaultValue("NULL");
    434434
     
    440440  angtypeCmd1->SetGuidance("Sets angular source distribution type");
    441441  angtypeCmd1->SetGuidance("Possible variables are: iso, cos, planar, beam1d, beam2d, focused or user");
    442   angtypeCmd1->SetParameterName("AngDis",true,true);
     442  angtypeCmd1->SetParameterName("AngDis",false,false);
    443443  angtypeCmd1->SetDefaultValue("iso");
    444444  angtypeCmd1->SetCandidates("iso cos planar beam1d beam2d focused user");
     
    447447  angrot1Cmd1->SetGuidance("Sets the 1st vector for angular distribution rotation matrix");
    448448  angrot1Cmd1->SetGuidance("Need not be a unit vector");
    449   angrot1Cmd1->SetParameterName("AR1x","AR1y","AR1z",true,true);
     449  angrot1Cmd1->SetParameterName("AR1x","AR1y","AR1z",false,false);
    450450  angrot1Cmd1->SetRange("AR1x != 0 || AR1y != 0 || AR1z != 0");
    451451
     
    453453  angrot2Cmd1->SetGuidance("Sets the 2nd vector for angular distribution rotation matrix");
    454454  angrot2Cmd1->SetGuidance("Need not be a unit vector");
    455   angrot2Cmd1->SetParameterName("AR2x","AR2y","AR2z",true,true);
     455  angrot2Cmd1->SetParameterName("AR2x","AR2y","AR2z",false,false);
    456456  angrot2Cmd1->SetRange("AR2x != 0 || AR2y != 0 || AR2z != 0");
    457457
    458458  minthetaCmd1 = new G4UIcmdWithADoubleAndUnit("/gps/ang/mintheta",this);
    459459  minthetaCmd1->SetGuidance("Set minimum theta");
    460   minthetaCmd1->SetParameterName("MinTheta",true,true);
     460  minthetaCmd1->SetParameterName("MinTheta",false,false);
    461461  minthetaCmd1->SetDefaultValue(0.);
    462462  minthetaCmd1->SetDefaultUnit("rad");
     
    465465  maxthetaCmd1 = new G4UIcmdWithADoubleAndUnit("/gps/ang/maxtheta",this);
    466466  maxthetaCmd1->SetGuidance("Set maximum theta");
    467   maxthetaCmd1->SetParameterName("MaxTheta",true,true);
     467  maxthetaCmd1->SetParameterName("MaxTheta",false,false);
    468468  maxthetaCmd1->SetDefaultValue(pi);
    469469  maxthetaCmd1->SetDefaultUnit("rad");
     
    472472  minphiCmd1 = new G4UIcmdWithADoubleAndUnit("/gps/ang/minphi",this);
    473473  minphiCmd1->SetGuidance("Set minimum phi");
    474   minphiCmd1->SetParameterName("MinPhi",true,true);
     474  minphiCmd1->SetParameterName("MinPhi",false,false);
    475475  minphiCmd1->SetDefaultUnit("rad");
    476476  //  minphiCmd1->SetUnitCandidates("rad deg");
     
    478478  maxphiCmd1 = new G4UIcmdWithADoubleAndUnit("/gps/ang/maxphi",this);
    479479  maxphiCmd1->SetGuidance("Set maximum phi");
    480   maxphiCmd1->SetParameterName("MaxPhi",true,true);
     480  maxphiCmd1->SetParameterName("MaxPhi",false,false);
    481481  maxphiCmd1->SetDefaultValue(pi);
    482482  maxphiCmd1->SetDefaultUnit("rad");
     
    485485  angsigmarCmd1 = new G4UIcmdWithADoubleAndUnit("/gps/ang/sigma_r",this);
    486486  angsigmarCmd1->SetGuidance("Set standard deviation in direction for 1D beam.");
    487   angsigmarCmd1->SetParameterName("Sigmara",true,true);
     487  angsigmarCmd1->SetParameterName("Sigmara",false,false);
    488488  angsigmarCmd1->SetDefaultUnit("rad");
    489489  //  angsigmarCmd1->SetUnitCandidates("rad deg");
     
    491491  angsigmaxCmd1 = new G4UIcmdWithADoubleAndUnit("/gps/ang/sigma_x",this);
    492492  angsigmaxCmd1->SetGuidance("Set standard deviation in direction in x-direc. for 2D beam");
    493   angsigmaxCmd1->SetParameterName("Sigmaxa",true,true);
     493  angsigmaxCmd1->SetParameterName("Sigmaxa",false,false);
    494494  angsigmaxCmd1->SetDefaultUnit("rad");
    495495  //  angsigmaxCmd1->SetUnitCandidates("rad deg");
     
    497497  angsigmayCmd1 = new G4UIcmdWithADoubleAndUnit("/gps/ang/sigma_y",this);
    498498  angsigmayCmd1->SetGuidance("Set standard deviation in direction in y-direc. for 2D beam");
    499   angsigmayCmd1->SetParameterName("Sigmaya",true,true);
     499  angsigmayCmd1->SetParameterName("Sigmaya",false,false);
    500500  angsigmayCmd1->SetDefaultUnit("rad");
    501501  //  angsigmayCmd1->SetUnitCandidates("rad deg");
     
    503503  angfocusCmd = new G4UIcmdWith3VectorAndUnit("/gps/ang/focuspoint",this);
    504504  angfocusCmd->SetGuidance("Set the focusing point for the beam");
    505   angfocusCmd->SetParameterName("x","y","z",true,true);
     505  angfocusCmd->SetParameterName("x","y","z",false,false);
    506506  angfocusCmd->SetDefaultUnit("cm");
    507507  //  angfocusCmd->SetUnitCandidates("micron mm cm m km");
     
    523523  angtypeCmd->SetGuidance("Sets angular source distribution type (obsolete!)");
    524524  angtypeCmd->SetGuidance("Possible variables are: iso, cos planar beam1d beam2d or user");
    525   angtypeCmd->SetParameterName("AngDis",true,true);
     525  angtypeCmd->SetParameterName("AngDis",false,false);
    526526  angtypeCmd->SetDefaultValue("iso");
    527527  angtypeCmd->SetCandidates("iso cos planar beam1d beam2d user");
     
    530530  angrot1Cmd->SetGuidance("Sets the x' vector for angular distribution(obsolete!) ");
    531531  angrot1Cmd->SetGuidance("Need not be a unit vector");
    532   angrot1Cmd->SetParameterName("AR1x","AR1y","AR1z",true,true);
     532  angrot1Cmd->SetParameterName("AR1x","AR1y","AR1z",false,false);
    533533  angrot1Cmd->SetRange("AR1x != 0 || AR1y != 0 || AR1z != 0");
    534534
     
    536536  angrot2Cmd->SetGuidance("Sets the y' vector for angular distribution (obsolete!)");
    537537  angrot2Cmd->SetGuidance("Need not be a unit vector");
    538   angrot2Cmd->SetParameterName("AR2x","AR2y","AR2z",true,true);
     538  angrot2Cmd->SetParameterName("AR2x","AR2y","AR2z",false,false);
    539539  angrot2Cmd->SetRange("AR2x != 0 || AR2y != 0 || AR2z != 0");
    540540
    541541  minthetaCmd = new G4UIcmdWithADoubleAndUnit("/gps/mintheta",this);
    542542  minthetaCmd->SetGuidance("Set minimum theta (obsolete!)");
    543   minthetaCmd->SetParameterName("MinTheta",true,true);
     543  minthetaCmd->SetParameterName("MinTheta",false,false);
    544544  minthetaCmd->SetDefaultUnit("rad");
    545545  //  minthetaCmd->SetUnitCandidates("rad deg");
     
    547547  maxthetaCmd = new G4UIcmdWithADoubleAndUnit("/gps/maxtheta",this);
    548548  maxthetaCmd->SetGuidance("Set maximum theta (obsolete!)");
    549   maxthetaCmd->SetParameterName("MaxTheta",true,true);
     549  maxthetaCmd->SetParameterName("MaxTheta",false,false);
    550550  maxthetaCmd->SetDefaultValue(3.1416);
    551551  maxthetaCmd->SetDefaultUnit("rad");
     
    554554  minphiCmd = new G4UIcmdWithADoubleAndUnit("/gps/minphi",this);
    555555  minphiCmd->SetGuidance("Set minimum phi (obsolete!)");
    556   minphiCmd->SetParameterName("MinPhi",true,true);
     556  minphiCmd->SetParameterName("MinPhi",false,false);
    557557  minphiCmd->SetDefaultUnit("rad");
    558558  //  minphiCmd->SetUnitCandidates("rad deg");
     
    560560  maxphiCmd = new G4UIcmdWithADoubleAndUnit("/gps/maxphi",this);
    561561  maxphiCmd->SetGuidance("Set maximum phi(obsolete!)");
    562   maxphiCmd->SetParameterName("MaxPhi",true,true);
     562  maxphiCmd->SetParameterName("MaxPhi",false,false);
    563563  maxphiCmd->SetDefaultUnit("rad");
    564564  //  maxphiCmd->SetUnitCandidates("rad deg");
     
    566566  angsigmarCmd = new G4UIcmdWithADoubleAndUnit("/gps/sigmaangr",this);
    567567  angsigmarCmd->SetGuidance("Set standard deviation of beam direction in radial(obsolete!).");
    568   angsigmarCmd->SetParameterName("Sigmara",true,true);
     568  angsigmarCmd->SetParameterName("Sigmara",false,false);
    569569  angsigmarCmd->SetDefaultUnit("rad");
    570570  //  angsigmarCmd->SetUnitCandidates("rad deg");
     
    572572  angsigmaxCmd = new G4UIcmdWithADoubleAndUnit("/gps/sigmaangx",this);
    573573  angsigmaxCmd->SetGuidance("Set standard deviation of beam direction in x-direc(obsolete!).");
    574   angsigmaxCmd->SetParameterName("Sigmaxa",true,true);
     574  angsigmaxCmd->SetParameterName("Sigmaxa",false,false);
    575575  angsigmaxCmd->SetDefaultUnit("rad");
    576576  //  angsigmaxCmd->SetUnitCandidates("rad deg");
     
    578578  angsigmayCmd = new G4UIcmdWithADoubleAndUnit("/gps/sigmaangy",this);
    579579  angsigmayCmd->SetGuidance("Set standard deviation of beam direction in y-direc.(obsolete!)");
    580   angsigmayCmd->SetParameterName("Sigmaya",true,true);
     580  angsigmayCmd->SetParameterName("Sigmaya",false,false);
    581581  angsigmayCmd->SetDefaultUnit("rad");
    582582  //  angsigmayCmd->SetUnitCandidates("rad deg");
     
    601601  energytypeCmd1 = new G4UIcmdWithAString("/gps/ene/type",this);
    602602  energytypeCmd1->SetGuidance("Sets energy distribution type");
    603   energytypeCmd1->SetParameterName("EnergyDis",true,true);
     603  energytypeCmd1->SetParameterName("EnergyDis",false,false);
    604604  energytypeCmd1->SetDefaultValue("Mono");
    605605  energytypeCmd1->SetCandidates("Mono Lin Pow Exp Gauss Brem Bbody Cdg User Arb Epn");
     
    607607  eminCmd1 = new G4UIcmdWithADoubleAndUnit("/gps/ene/min",this);
    608608  eminCmd1->SetGuidance("Sets minimum energy");
    609   eminCmd1->SetParameterName("emin",true,true);
     609  eminCmd1->SetParameterName("emin",false,false);
    610610  eminCmd1->SetDefaultUnit("keV");
    611611  //  eminCmd1->SetUnitCandidates("eV keV MeV GeV TeV PeV");
     
    613613  emaxCmd1 = new G4UIcmdWithADoubleAndUnit("/gps/ene/max",this);
    614614  emaxCmd1->SetGuidance("Sets maximum energy");
    615   emaxCmd1->SetParameterName("emax",true,true);
     615  emaxCmd1->SetParameterName("emax",false,false);
    616616  emaxCmd1->SetDefaultUnit("keV");
    617617  //  emaxCmd1->SetUnitCandidates("eV keV MeV GeV TeV PeV");
     
    619619  monoenergyCmd1 = new G4UIcmdWithADoubleAndUnit("/gps/ene/mono",this);
    620620  monoenergyCmd1->SetGuidance("Sets a monocromatic energy (same as  gps/energy)");
    621   monoenergyCmd1->SetParameterName("monoenergy",true,true);
     621  monoenergyCmd1->SetParameterName("monoenergy",false,false);
    622622  monoenergyCmd1->SetDefaultUnit("keV");
    623623  //  monoenergyCmd1->SetUnitCandidates("eV keV MeV GeV TeV PeV");
     
    625625  engsigmaCmd1 = new G4UIcmdWithADoubleAndUnit("/gps/ene/sigma",this);
    626626  engsigmaCmd1->SetGuidance("Sets the standard deviation for Gaussian energy dist.");
    627   engsigmaCmd1->SetParameterName("Sigmae",true,true);
     627  engsigmaCmd1->SetParameterName("Sigmae",false,false);
    628628  engsigmaCmd1->SetDefaultUnit("keV");
    629629  //  engsigmaCmd1->SetUnitCandidates("eV keV MeV GeV TeV PeV");
     
    631631  alphaCmd1 = new G4UIcmdWithADouble("/gps/ene/alpha",this);
    632632  alphaCmd1->SetGuidance("Sets Alpha (index) for power-law energy dist.");
    633   alphaCmd1->SetParameterName("alpha",true,true);
     633  alphaCmd1->SetParameterName("alpha",false,false);
    634634 
    635635  tempCmd1 = new G4UIcmdWithADouble("/gps/ene/temp",this);
    636636  tempCmd1->SetGuidance("Sets the temperature for Brem and BBody distributions (in Kelvin)");
    637   tempCmd1->SetParameterName("temp",true,true);
     637  tempCmd1->SetParameterName("temp",false,false);
    638638
    639639  ezeroCmd1 = new G4UIcmdWithADouble("/gps/ene/ezero",this);
    640640  ezeroCmd1->SetGuidance("Sets E_0 for exponential distribution (in MeV)");
    641   ezeroCmd1->SetParameterName("ezero",true,true);
     641  ezeroCmd1->SetParameterName("ezero",false,false);
    642642
    643643  gradientCmd1 = new G4UIcmdWithADouble("/gps/ene/gradient",this);
    644644  gradientCmd1->SetGuidance("Sets the gradient for Lin distribution (in 1/MeV)");
    645   gradientCmd1->SetParameterName("gradient",true,true);
     645  gradientCmd1->SetParameterName("gradient",false,false);
    646646
    647647  interceptCmd1 = new G4UIcmdWithADouble("/gps/ene/intercept",this);
    648648  interceptCmd1->SetGuidance("Sets the intercept for Lin distributions (in MeV)");
    649   interceptCmd1->SetParameterName("intercept",true,true);
     649  interceptCmd1->SetParameterName("intercept",false,false);
     650
     651  arbeintCmd1 = new G4UIcmdWithADouble("/gps/ene/biasAlpha",this);
     652  arbeintCmd1->SetGuidance("Set the power-law index for the energy sampling distri. )");
     653  arbeintCmd1->SetParameterName("arbeint",false,false);
    650654
    651655  calculateCmd1 = new G4UIcmdWithoutParameter("/gps/ene/calculate",this);
     
    665669  energytypeCmd = new G4UIcmdWithAString("/gps/energytype",this);
    666670  energytypeCmd->SetGuidance("Sets energy distribution type (obsolete!)");
    667   energytypeCmd->SetParameterName("EnergyDis",true,true);
     671  energytypeCmd->SetParameterName("EnergyDis",false,false);
    668672  energytypeCmd->SetDefaultValue("Mono");
    669673  energytypeCmd->SetCandidates("Mono Lin Pow Exp Gauss Brem Bbody Cdg User Arb Epn");
     
    671675  eminCmd = new G4UIcmdWithADoubleAndUnit("/gps/emin",this);
    672676  eminCmd->SetGuidance("Sets Emin (obsolete!)");
    673   eminCmd->SetParameterName("emin",true,true);
     677  eminCmd->SetParameterName("emin",false,false);
    674678  eminCmd->SetDefaultUnit("keV");
    675679  //  eminCmd->SetUnitCandidates("eV keV MeV GeV TeV PeV");
     
    677681  emaxCmd = new G4UIcmdWithADoubleAndUnit("/gps/emax",this);
    678682  emaxCmd->SetGuidance("Sets Emax (obsolete!)");
    679   emaxCmd->SetParameterName("emax",true,true);
     683  emaxCmd->SetParameterName("emax",false,false);
    680684  emaxCmd->SetDefaultUnit("keV");
    681685  //  emaxCmd->SetUnitCandidates("eV keV MeV GeV TeV PeV");
     
    683687  monoenergyCmd = new G4UIcmdWithADoubleAndUnit("/gps/monoenergy",this);
    684688  monoenergyCmd->SetGuidance("Sets Monoenergy (obsolete, use gps/energy instead!)");
    685   monoenergyCmd->SetParameterName("monoenergy",true,true);
     689  monoenergyCmd->SetParameterName("monoenergy",false,false);
    686690  monoenergyCmd->SetDefaultUnit("keV");
    687691  //  monoenergyCmd->SetUnitCandidates("eV keV MeV GeV TeV PeV");
     
    689693  engsigmaCmd = new G4UIcmdWithADoubleAndUnit("/gps/sigmae",this);
    690694  engsigmaCmd->SetGuidance("Sets the standard deviation for Gaussian energy dist.(obsolete!)");
    691   engsigmaCmd->SetParameterName("Sigmae",true,true);
     695  engsigmaCmd->SetParameterName("Sigmae",false,false);
    692696  engsigmaCmd->SetDefaultUnit("keV");
    693697  //  engsigmaCmd->SetUnitCandidates("eV keV MeV GeV TeV PeV");
     
    695699  alphaCmd = new G4UIcmdWithADouble("/gps/alpha",this);
    696700  alphaCmd->SetGuidance("Sets Alpha (index) for power-law energy dist(obsolete!).");
    697   alphaCmd->SetParameterName("alpha",true,true);
     701  alphaCmd->SetParameterName("alpha",false,false);
    698702 
    699703  tempCmd = new G4UIcmdWithADouble("/gps/temp",this);
    700704  tempCmd->SetGuidance("Sets the temperature for Brem and BBody (in Kelvin)(obsolete!)");
    701   tempCmd->SetParameterName("temp",true,true);
     705  tempCmd->SetParameterName("temp",false,false);
    702706
    703707  ezeroCmd = new G4UIcmdWithADouble("/gps/ezero",this);
    704708  ezeroCmd->SetGuidance("Sets ezero exponential distributions (in MeV)(obsolete!)");
    705   ezeroCmd->SetParameterName("ezero",true,true);
     709  ezeroCmd->SetParameterName("ezero",false,false);
    706710
    707711  gradientCmd = new G4UIcmdWithADouble("/gps/gradient",this);
    708712  gradientCmd->SetGuidance("Sets the gradient for Lin distributions (in 1/MeV)(obsolete!)");
    709   gradientCmd->SetParameterName("gradient",true,true);
     713  gradientCmd->SetParameterName("gradient",false,false);
    710714
    711715  interceptCmd = new G4UIcmdWithADouble("/gps/intercept",this);
    712716  interceptCmd->SetGuidance("Sets the intercept for Lin distributions (in MeV)(obsolete!)");
    713   interceptCmd->SetParameterName("intercept",true,true);
     717  interceptCmd->SetParameterName("intercept",false,false);
    714718
    715719  calculateCmd = new G4UIcmdWithoutParameter("/gps/calculate",this);
     
    732736  histnameCmd1 = new G4UIcmdWithAString("/gps/hist/type",this);
    733737  histnameCmd1->SetGuidance("Sets histogram type");
    734   histnameCmd1->SetParameterName("HistType",true,true);
     738  histnameCmd1->SetParameterName("HistType",false,false);
    735739  histnameCmd1->SetDefaultValue("biasx");
    736740  histnameCmd1->SetCandidates("biasx biasy biasz biast biasp biase biaspt biaspp theta phi energy arb epn");
     
    738742  resethistCmd1 = new G4UIcmdWithAString("/gps/hist/reset",this);
    739743  resethistCmd1->SetGuidance("Reset (clean) the histogram ");
    740   resethistCmd1->SetParameterName("HistType",true,true);
     744  resethistCmd1->SetParameterName("HistType",false,false);
    741745  resethistCmd1->SetDefaultValue("energy");
    742746  resethistCmd1->SetCandidates("biasx biasy biasz biast biasp biase biaspt biaspp theta phi energy arb epn");
     
    748752  histpointCmd1->SetRange("Ehi >= 0. && Weight >= 0.");
    749753
     754  histfileCmd1 = new G4UIcmdWithAString("/gps/hist/file",this);
     755  histfileCmd1->SetGuidance("import the arb energy hist in an ASCII file");
     756  histfileCmd1->SetParameterName("HistFile",false,false);
     757
    750758  arbintCmd1 = new G4UIcmdWithAString("/gps/hist/inter",this);
    751759  arbintCmd1->SetGuidance("Sets the interpolation method for arbitrary distribution.");
    752   arbintCmd1->SetParameterName("int",true,true);
     760  arbintCmd1->SetParameterName("int",false,false);
    753761  arbintCmd1->SetDefaultValue("Lin");
    754762  arbintCmd1->SetCandidates("Lin Log Exp Spline");
     
    757765  histnameCmd = new G4UIcmdWithAString("/gps/histname",this);
    758766  histnameCmd->SetGuidance("Sets histogram type (obsolete!)");
    759   histnameCmd->SetParameterName("HistType",true,true);
     767  histnameCmd->SetParameterName("HistType",false,false);
    760768  histnameCmd->SetDefaultValue("biasx");
    761769  histnameCmd->SetCandidates("biasx biasy biasz biast biasp biase biaspt biaspp theta phi energy arb epn");
     
    764772  resethistCmd = new G4UIcmdWithAString("/gps/resethist",this);
    765773  resethistCmd->SetGuidance("Re-Set the histogram (obsolete!)");
    766   resethistCmd->SetParameterName("HistType",true,true);
     774  resethistCmd->SetParameterName("HistType",false,false);
    767775  resethistCmd->SetDefaultValue("energy");
    768776  resethistCmd->SetCandidates("biasx biasy biasz biast biasp biase biaspt biaspp theta phi energy arb epn");
     
    771779  histpointCmd->SetGuidance("Allows user to define a histogram (obsolete!)");
    772780  histpointCmd->SetGuidance("Enter: Ehi Weight");
    773   histpointCmd->SetParameterName("Ehi","Weight","Junk",true,true);
     781  histpointCmd->SetParameterName("Ehi","Weight","Junk",false,false);
    774782  histpointCmd->SetRange("Ehi >= 0. && Weight >= 0.");
    775783
    776784  arbintCmd = new G4UIcmdWithAString("/gps/arbint",this);
    777785  arbintCmd->SetGuidance("Sets Arbitrary Interpolation type.(obsolete!) ");
    778   arbintCmd->SetParameterName("int",true,true);
     786  arbintCmd->SetParameterName("int",false,false);
    779787  arbintCmd->SetDefaultValue("NULL");
    780788  arbintCmd->SetCandidates("Lin Log Exp Spline");
     
    870878  delete gradientCmd1;
    871879  delete interceptCmd1;
     880  delete arbeintCmd1;
    872881  delete calculateCmd1;
    873882  delete energyspecCmd1;
     
    882891  delete resethistCmd1;
    883892  delete histpointCmd1;
     893  delete histfileCmd1;
    884894  delete arbintCmd1;
    885895
     
    15051515      fParticleGun->GetEneDist()->SetInterCept(interceptCmd1->GetNewDoubleValue(newValues));
    15061516    }
     1517  else if(command == arbeintCmd1)
     1518    {
     1519      fParticleGun->GetEneDist()->SetBiasAlpha(arbeintCmd1->GetNewDoubleValue(newValues));
     1520    }
    15071521  else if(command == calculateCmd1)
    15081522    {
     
    15201534    {
    15211535      histtype = newValues;
     1536    }
     1537  else if(command == histfileCmd1)
     1538    {
     1539      histtype = "arb";
     1540      fParticleGun->GetEneDist()->ArbEnergyHistoFile(newValues);
    15221541    }
    15231542  else if(command == histpointCmd1)
  • trunk/source/event/src/G4SPSEneDistribution.cc

    r1196 r1347  
    5050#include "G4SPSEneDistribution.hh"
    5151
    52 G4SPSEneDistribution::G4SPSEneDistribution()
    53 {
    54   //
    55   // Initialise all variables
    56   particle_energy = 1.0*MeV;
    57 
    58   EnergyDisType = "Mono";
    59   MonoEnergy = 1*MeV;
    60   Emin = 0.;
    61   Emax = 1.e30;
    62   alpha = 0.;
    63   Ezero = 0.;
    64   SE = 0.;
    65   Temp = 0.;
    66   grad = 0.;
    67   cept = 0.;
    68   EnergySpec = true; // true - energy spectra, false - momentum spectra
    69   DiffSpec = true;  // true - differential spec, false integral spec
    70   IntType = "NULL"; // Interpolation type
    71   IPDFEnergyExist = false;
    72   IPDFArbExist = false;
    73 
    74   ArbEmin = 0.;
    75   ArbEmax = 1.e30;
    76 
    77   verbosityLevel = 0 ;
    78 
    79 }
    80 
    81 G4SPSEneDistribution::~G4SPSEneDistribution()
    82 {}
    83 
    84 void G4SPSEneDistribution::SetEnergyDisType(G4String DisType)
    85 {
    86   EnergyDisType = DisType;
    87   if (EnergyDisType == "User"){
    88     UDefEnergyH = IPDFEnergyH = ZeroPhysVector ;
    89     IPDFEnergyExist = false ;
    90   } else if ( EnergyDisType == "Arb"){
    91     ArbEnergyH =IPDFArbEnergyH = ZeroPhysVector ;
    92     IPDFArbExist = false;
    93   } else if (EnergyDisType == "Epn"){
    94     UDefEnergyH = IPDFEnergyH = ZeroPhysVector ;
    95     IPDFEnergyExist = false ;
    96     EpnEnergyH = ZeroPhysVector ;
    97   }
    98 }
    99 
    100 void G4SPSEneDistribution::SetEmin(G4double emi)
    101 {
    102   Emin = emi;
    103 }
    104 
    105 void G4SPSEneDistribution::SetEmax(G4double ema)
    106 {
    107   Emax = ema;
    108 }
    109 
    110 void G4SPSEneDistribution::SetMonoEnergy(G4double menergy)
    111 {
    112   MonoEnergy = menergy;
    113 }
    114 
    115 void G4SPSEneDistribution::SetBeamSigmaInE(G4double e)
    116 {
    117   SE = e;
    118 }
    119 void G4SPSEneDistribution::SetAlpha(G4double alp)
    120 {
    121   alpha = alp;
    122 }
    123 
    124 void G4SPSEneDistribution::SetTemp(G4double tem)
    125 {
    126   Temp = tem;
    127 }
    128 
    129 void G4SPSEneDistribution::SetEzero(G4double eze)
    130 {
    131   Ezero = eze;
    132 }
    133 
    134 void G4SPSEneDistribution::SetGradient(G4double gr)
    135 {
    136   grad = gr;
    137 }
    138 
    139 void G4SPSEneDistribution::SetInterCept(G4double c)
    140 {
    141   cept = c;
    142 }
    143 
    144 void G4SPSEneDistribution::UserEnergyHisto(G4ThreeVector input)
    145 {
    146   G4double ehi, val;
    147   ehi = input.x();
    148   val = input.y();
    149   if(verbosityLevel > 1) {
    150     G4cout << "In UserEnergyHisto" << G4endl;
    151     G4cout << " " << ehi << " " << val << G4endl;
    152   }
    153   UDefEnergyH.InsertValues(ehi, val);
    154   Emax = ehi;
    155 }
    156 
    157 void G4SPSEneDistribution::ArbEnergyHisto(G4ThreeVector input)
    158 {
    159   G4double ehi, val;
    160   ehi = input.x();
    161   val = input.y();
    162   if(verbosityLevel >1 ) {
    163     G4cout << "In ArbEnergyHisto" << G4endl;
    164     G4cout << " " << ehi << " " << val << G4endl;
    165   }
    166   ArbEnergyH.InsertValues(ehi, val);
    167 }
    168 
    169 void G4SPSEneDistribution::EpnEnergyHisto(G4ThreeVector input)
    170 {
    171   G4double ehi, val;
    172   ehi = input.x();
    173   val = input.y();
    174   if(verbosityLevel > 1) {
    175     G4cout << "In EpnEnergyHisto" << G4endl;
    176     G4cout << " " << ehi << " " << val << G4endl;
    177   }
    178   EpnEnergyH.InsertValues(ehi, val);
    179   Emax = ehi;
    180   Epnflag = true;
    181 }
    182 
    183 void G4SPSEneDistribution::Calculate()
    184 {
    185   if(EnergyDisType == "Cdg")
    186     CalculateCdgSpectrum();
    187   else if(EnergyDisType == "Bbody")
    188     CalculateBbodySpectrum();
    189 }
    190 
    191 void G4SPSEneDistribution::CalculateCdgSpectrum()
    192 {
    193   // This uses the spectrum from The INTEGRAL Mass Model (TIMM)
    194   // to generate a Cosmic Diffuse X/gamma ray spectrum.
    195   G4double pfact[2] = {8.5, 112};
    196   G4double spind[2] = {1.4, 2.3};
    197   G4double ene_line[3] = {1.*keV, 18.*keV, 1E6*keV};
    198   G4int n_par;
    199 
    200   ene_line[0] = Emin;
    201   if(Emin < 18*keV)
    202     {
    203       n_par = 2;
    204       ene_line[2] = Emax;
    205       if(Emax < 18*keV)
    206         {
    207           n_par = 1;
    208           ene_line[1] = Emax;
    209         }
    210     }
    211   else
    212     {
    213       n_par = 1;
    214       pfact[0] = 112.;
    215       spind[0] = 2.3;
    216       ene_line[1] = Emax;
    217     }
     52G4SPSEneDistribution::G4SPSEneDistribution() {
     53        //
     54        // Initialise all variables
     55        particle_energy = 1.0 * MeV;
     56
     57        EnergyDisType = "Mono";
     58        weight = 1.;
     59        MonoEnergy = 1 * MeV;
     60        Emin = 0.;
     61        Emax = 1.e30;
     62        alpha = 0.;
     63        biasalpha = 0.;
     64        prob_norm = 1.0;
     65        Ezero = 0.;
     66        SE = 0.;
     67        Temp = 0.;
     68        grad = 0.;
     69        cept = 0.;
     70        Biased = false; // not biased
     71        EnergySpec = true; // true - energy spectra, false - momentum spectra
     72        DiffSpec = true; // true - differential spec, false integral spec
     73        IntType = "NULL"; // Interpolation type
     74        IPDFEnergyExist = false;
     75        IPDFArbExist = false;
     76
     77        ArbEmin = 0.;
     78        ArbEmax = 1.e30;
     79
     80        verbosityLevel = 0;
     81
     82}
     83
     84G4SPSEneDistribution::~G4SPSEneDistribution() {
     85}
     86
     87void G4SPSEneDistribution::SetEnergyDisType(G4String DisType) {
     88        EnergyDisType = DisType;
     89        if (EnergyDisType == "User") {
     90                UDefEnergyH = IPDFEnergyH = ZeroPhysVector;
     91                IPDFEnergyExist = false;
     92        } else if (EnergyDisType == "Arb") {
     93                ArbEnergyH = IPDFArbEnergyH = ZeroPhysVector;
     94                IPDFArbExist = false;
     95        } else if (EnergyDisType == "Epn") {
     96                UDefEnergyH = IPDFEnergyH = ZeroPhysVector;
     97                IPDFEnergyExist = false;
     98                EpnEnergyH = ZeroPhysVector;
     99        }
     100}
     101
     102void G4SPSEneDistribution::SetEmin(G4double emi) {
     103        Emin = emi;
     104}
     105
     106void G4SPSEneDistribution::SetEmax(G4double ema) {
     107        Emax = ema;
     108}
     109
     110void G4SPSEneDistribution::SetMonoEnergy(G4double menergy) {
     111        MonoEnergy = menergy;
     112}
     113
     114void G4SPSEneDistribution::SetBeamSigmaInE(G4double e) {
     115        SE = e;
     116}
     117void G4SPSEneDistribution::SetAlpha(G4double alp) {
     118        alpha = alp;
     119}
     120
     121void G4SPSEneDistribution::SetBiasAlpha(G4double alp) {
     122        biasalpha = alp;
     123        Biased = true;
     124}
     125
     126void G4SPSEneDistribution::SetTemp(G4double tem) {
     127        Temp = tem;
     128}
     129
     130void G4SPSEneDistribution::SetEzero(G4double eze) {
     131        Ezero = eze;
     132}
     133
     134void G4SPSEneDistribution::SetGradient(G4double gr) {
     135        grad = gr;
     136}
     137
     138void G4SPSEneDistribution::SetInterCept(G4double c) {
     139        cept = c;
     140}
     141
     142void G4SPSEneDistribution::UserEnergyHisto(G4ThreeVector input) {
     143        G4double ehi, val;
     144        ehi = input.x();
     145        val = input.y();
     146        if (verbosityLevel > 1) {
     147                G4cout << "In UserEnergyHisto" << G4endl;
     148                G4cout << " " << ehi << " " << val << G4endl;
     149        }
     150        UDefEnergyH.InsertValues(ehi, val);
     151        Emax = ehi;
     152}
     153
     154void G4SPSEneDistribution::ArbEnergyHisto(G4ThreeVector input) {
     155        G4double ehi, val;
     156        ehi = input.x();
     157        val = input.y();
     158        if (verbosityLevel > 1) {
     159                G4cout << "In ArbEnergyHisto" << G4endl;
     160                G4cout << " " << ehi << " " << val << G4endl;
     161        }
     162        ArbEnergyH.InsertValues(ehi, val);
     163}
     164
     165void G4SPSEneDistribution::ArbEnergyHistoFile(G4String filename) {
     166        std::ifstream infile(filename, std::ios::in);
     167        if (!infile)
     168                G4Exception("Unable to open the histo ASCII file");
     169        G4double ehi, val;
     170        while (infile >> ehi >> val) {
     171                ArbEnergyH.InsertValues(ehi, val);
     172        }
     173}
     174
     175void G4SPSEneDistribution::EpnEnergyHisto(G4ThreeVector input) {
     176        G4double ehi, val;
     177        ehi = input.x();
     178        val = input.y();
     179        if (verbosityLevel > 1) {
     180                G4cout << "In EpnEnergyHisto" << G4endl;
     181                G4cout << " " << ehi << " " << val << G4endl;
     182        }
     183        EpnEnergyH.InsertValues(ehi, val);
     184        Emax = ehi;
     185        Epnflag = true;
     186}
     187
     188void G4SPSEneDistribution::Calculate() {
     189        if (EnergyDisType == "Cdg")
     190                CalculateCdgSpectrum();
     191        else if (EnergyDisType == "Bbody")
     192                CalculateBbodySpectrum();
     193}
     194
     195void G4SPSEneDistribution::CalculateCdgSpectrum() {
     196        // This uses the spectrum from The INTEGRAL Mass Model (TIMM)
     197        // to generate a Cosmic Diffuse X/gamma ray spectrum.
     198        G4double pfact[2] = { 8.5, 112 };
     199        G4double spind[2] = { 1.4, 2.3 };
     200        G4double ene_line[3] = { 1. * keV, 18. * keV, 1E6 * keV };
     201        G4int n_par;
     202
     203        ene_line[0] = Emin;
     204        if (Emin < 18 * keV) {
     205                n_par = 2;
     206                ene_line[2] = Emax;
     207                if (Emax < 18 * keV) {
     208                        n_par = 1;
     209                        ene_line[1] = Emax;
     210                }
     211        } else {
     212                n_par = 1;
     213                pfact[0] = 112.;
     214                spind[0] = 2.3;
     215                ene_line[1] = Emax;
     216        }
     217
     218        // Create a cumulative histogram.
     219        CDGhist[0] = 0.;
     220        G4double omalpha;
     221        G4int i = 0;
     222
     223        while (i < n_par) {
     224                omalpha = 1. - spind[i];
     225                CDGhist[i + 1] = CDGhist[i] + (pfact[i] / omalpha) * (std::pow(
     226                                ene_line[i + 1] / keV, omalpha) - std::pow(ene_line[i] / keV,
     227                                omalpha));
     228                i++;
     229        }
     230
     231        // Normalise histo and divide by 1000 to make MeV.
     232        i = 0;
     233        while (i < n_par) {
     234                CDGhist[i + 1] = CDGhist[i + 1] / CDGhist[n_par];
     235                //      G4cout << CDGhist[i] << CDGhist[n_par] << G4endl;
     236                i++;
     237        }
     238}
     239
     240void G4SPSEneDistribution::CalculateBbodySpectrum() {
     241        // create bbody spectrum
     242        // Proved very hard to integrate indefinitely, so different
     243        // method. User inputs emin, emax and T. These are used to
     244        // create a 10,000 bin histogram.
     245        // Use photon density spectrum = 2 nu**2/c**2 * (std::exp(h nu/kT)-1)
     246        // = 2 E**2/h**2c**2 times the exponential
     247        G4double erange = Emax - Emin;
     248        G4double steps = erange / 10000.;
     249        G4double Bbody_y[10000];
     250        G4double k = 8.6181e-11; //Boltzmann const in MeV/K
     251        G4double h = 4.1362e-21; // Plancks const in MeV s
     252        G4double c = 3e8; // Speed of light
     253        G4double h2 = h * h;
     254        G4double c2 = c * c;
     255        G4int count = 0;
     256        G4double sum = 0.;
     257        BBHist[0] = 0.;
     258        while (count < 10000) {
     259                Bbody_x[count] = Emin + G4double(count * steps);
     260                Bbody_y[count] = (2. * std::pow(Bbody_x[count], 2.)) / (h2 * c2
     261                                * (std::exp(Bbody_x[count] / (k * Temp)) - 1.));
     262                sum = sum + Bbody_y[count];
     263                BBHist[count + 1] = BBHist[count] + Bbody_y[count];
     264                count++;
     265        }
     266
     267        Bbody_x[10000] = Emax;
     268        // Normalise cumulative histo.
     269        count = 0;
     270        while (count < 10001) {
     271                BBHist[count] = BBHist[count] / sum;
     272                count++;
     273        }
     274}
     275
     276void G4SPSEneDistribution::InputEnergySpectra(G4bool value) {
     277        // Allows user to specifiy spectrum is momentum
     278        EnergySpec = value; // false if momentum
     279        if (verbosityLevel > 1)
     280                G4cout << "EnergySpec has value " << EnergySpec << G4endl;
     281}
     282
     283void G4SPSEneDistribution::InputDifferentialSpectra(G4bool value) {
     284        // Allows user to specify integral or differential spectra
     285        DiffSpec = value; // true = differential, false = integral
     286        if (verbosityLevel > 1)
     287                G4cout << "Diffspec has value " << DiffSpec << G4endl;
     288}
     289
     290void G4SPSEneDistribution::ArbInterpolate(G4String IType) {
     291        if (EnergyDisType != "Arb")
     292                G4cout << "Error: this is for arbitrary distributions" << G4endl;
     293        IntType = IType;
     294        ArbEmax = ArbEnergyH.GetMaxLowEdgeEnergy();
     295        ArbEmin = ArbEnergyH.GetMinLowEdgeEnergy();
     296
     297        // Now interpolate points
     298        if (IntType == "Lin")
     299                LinearInterpolation();
     300        if (IntType == "Log")
     301                LogInterpolation();
     302        if (IntType == "Exp")
     303                ExpInterpolation();
     304        if (IntType == "Spline")
     305                SplineInterpolation();
     306}
     307
     308void G4SPSEneDistribution::LinearInterpolation() {
     309        // Method to do linear interpolation on the Arb points
     310        // Calculate equation of each line segment, max 1024.
     311        // Calculate Area under each segment
     312        // Create a cumulative array which is then normalised Arb_Cum_Area
     313
     314        G4double Area_seg[1024]; // Stores area under each segment
     315        G4double sum = 0., Arb_x[1024], Arb_y[1024], Arb_Cum_Area[1024];
     316        G4int i, count;
     317        G4int maxi = ArbEnergyH.GetVectorLength();
     318        for (i = 0; i < maxi; i++) {
     319                Arb_x[i] = ArbEnergyH.GetLowEdgeEnergy(size_t(i));
     320                Arb_y[i] = ArbEnergyH(size_t(i));
     321        }
     322        // Points are now in x,y arrays. If the spectrum is integral it has to be
     323        // made differential and if momentum it has to be made energy.
     324        if (DiffSpec == false) {
     325                // Converts integral point-wise spectra to Differential
     326                for (count = 0; count < maxi - 1; count++) {
     327                        Arb_y[count] = (Arb_y[count] - Arb_y[count + 1])
     328                                        / (Arb_x[count + 1] - Arb_x[count]);
     329                }
     330                maxi--;
     331        }
     332        //
     333        if (EnergySpec == false) {
     334                // change currently stored values (emin etc) which are actually momenta
     335                // to energies.
     336                if (particle_definition == NULL)
     337                        G4cout << "Error: particle not defined" << G4endl;
     338                else {
     339                        // Apply Energy**2 = p**2c**2 + m0**2c**4
     340                        // p should be entered as E/c i.e. without the division by c
     341                        // being done - energy equivalent.
     342                        G4double mass = particle_definition->GetPDGMass();
     343                        // convert point to energy unit and its value to per energy unit
     344                        G4double total_energy;
     345                        for (count = 0; count < maxi; count++) {
     346                                total_energy = std::sqrt((Arb_x[count] * Arb_x[count]) + (mass
     347                                                * mass)); // total energy
     348
     349                                Arb_y[count] = Arb_y[count] * Arb_x[count] / total_energy;
     350                                Arb_x[count] = total_energy - mass; // kinetic energy
     351                        }
     352                }
     353        }
     354        //
     355        i = 1;
     356        Arb_grad[0] = 0.;
     357        Arb_cept[0] = 0.;
     358        Area_seg[0] = 0.;
     359        Arb_Cum_Area[0] = 0.;
     360        while (i < maxi) {
     361                // calc gradient and intercept for each segment
     362                Arb_grad[i] = (Arb_y[i] - Arb_y[i - 1]) / (Arb_x[i] - Arb_x[i - 1]);
     363                if (verbosityLevel == 2)
     364                        G4cout << Arb_grad[i] << G4endl;
     365                if (Arb_grad[i] > 0.) {
     366                        if (verbosityLevel == 2)
     367                                G4cout << "Arb_grad is positive" << G4endl;
     368                        Arb_cept[i] = Arb_y[i] - (Arb_grad[i] * Arb_x[i]);
     369                } else if (Arb_grad[i] < 0.) {
     370                        if (verbosityLevel == 2)
     371                                G4cout << "Arb_grad is negative" << G4endl;
     372                        Arb_cept[i] = Arb_y[i] + (-Arb_grad[i] * Arb_x[i]);
     373                } else {
     374                        if (verbosityLevel == 2)
     375                                G4cout << "Arb_grad is 0." << G4endl;
     376                        Arb_cept[i] = Arb_y[i];
     377                }
     378
     379                Area_seg[i] = ((Arb_grad[i] / 2) * (Arb_x[i] * Arb_x[i] - Arb_x[i - 1]
     380                                * Arb_x[i - 1]) + Arb_cept[i] * (Arb_x[i] - Arb_x[i - 1]));
     381                Arb_Cum_Area[i] = Arb_Cum_Area[i - 1] + Area_seg[i];
     382                sum = sum + Area_seg[i];
     383                if (verbosityLevel == 2)
     384                        G4cout << Arb_x[i] << Arb_y[i] << Area_seg[i] << sum << Arb_grad[i]
     385                                        << G4endl;
     386                i++;
     387        }
     388
     389        i = 0;
     390        while (i < maxi) {
     391                Arb_Cum_Area[i] = Arb_Cum_Area[i] / sum; // normalisation
     392                IPDFArbEnergyH.InsertValues(Arb_x[i], Arb_Cum_Area[i]);
     393                i++;
     394        }
     395
     396        // now scale the ArbEnergyH, needed by Probability()
     397        ArbEnergyH.ScaleVector(1., 1./sum);
     398
     399        if (verbosityLevel >= 1) {
     400                G4cout << "Leaving LinearInterpolation" << G4endl;
     401                ArbEnergyH.DumpValues();
     402                IPDFArbEnergyH.DumpValues();
     403        }
     404}
     405
     406void G4SPSEneDistribution::LogInterpolation() {
     407        // Interpolation based on Logarithmic equations
     408        // Generate equations of line segments
     409        // y = Ax**alpha => log y = alpha*logx + logA
     410        // Find area under line segments
     411        // create normalised, cumulative array Arb_Cum_Area
     412        G4double Area_seg[1024]; // Stores area under each segment
     413        G4double sum = 0., Arb_x[1024], Arb_y[1024], Arb_Cum_Area[1024];
     414        G4int i, count;
     415        G4int maxi = ArbEnergyH.GetVectorLength();
     416        for (i = 0; i < maxi; i++) {
     417                Arb_x[i] = ArbEnergyH.GetLowEdgeEnergy(size_t(i));
     418                Arb_y[i] = ArbEnergyH(size_t(i));
     419        }
     420        // Points are now in x,y arrays. If the spectrum is integral it has to be
     421        // made differential and if momentum it has to be made energy.
     422        if (DiffSpec == false) {
     423                // Converts integral point-wise spectra to Differential
     424                for (count = 0; count < maxi - 1; count++) {
     425                        Arb_y[count] = (Arb_y[count] - Arb_y[count + 1])
     426                                        / (Arb_x[count + 1] - Arb_x[count]);
     427                }
     428                maxi--;
     429        }
     430        //
     431        if (EnergySpec == false) {
     432                // change currently stored values (emin etc) which are actually momenta
     433                // to energies.
     434                if (particle_definition == NULL)
     435                        G4cout << "Error: particle not defined" << G4endl;
     436                else {
     437                        // Apply Energy**2 = p**2c**2 + m0**2c**4
     438                        // p should be entered as E/c i.e. without the division by c
     439                        // being done - energy equivalent.
     440                        G4double mass = particle_definition->GetPDGMass();
     441                        // convert point to energy unit and its value to per energy unit
     442                        G4double total_energy;
     443                        for (count = 0; count < maxi; count++) {
     444                                total_energy = std::sqrt((Arb_x[count] * Arb_x[count]) + (mass
     445                                                * mass)); // total energy
     446
     447                                Arb_y[count] = Arb_y[count] * Arb_x[count] / total_energy;
     448                                Arb_x[count] = total_energy - mass; // kinetic energy
     449                        }
     450                }
     451        }
     452        //
     453        i = 1;
     454        Arb_alpha[0] = 0.;
     455        Arb_Const[0] = 0.;
     456        Area_seg[0] = 0.;
     457        Arb_Cum_Area[0] = 0.;
     458        if (Arb_x[0] <= 0. || Arb_y[0] <= 0.) {
     459                G4cout << "You should not use log interpolation with points <= 0."
     460                                << G4endl;
     461                G4cout << "These will be changed to 1e-20, which may cause problems"
     462                                << G4endl;
     463                if (Arb_x[0] <= 0.)
     464                        Arb_x[0] = 1e-20;
     465                if (Arb_y[0] <= 0.)
     466                        Arb_y[0] = 1e-20;
     467        }
     468
     469        G4double alp;
     470        while (i < maxi) {
     471                // Incase points are negative or zero
     472                if (Arb_x[i] <= 0. || Arb_y[i] <= 0.) {
     473                        G4cout << "You should not use log interpolation with points <= 0."
     474                                        << G4endl;
     475                        G4cout
     476                                        << "These will be changed to 1e-20, which may cause problems"
     477                                        << G4endl;
     478                        if (Arb_x[i] <= 0.)
     479                                Arb_x[i] = 1e-20;
     480                        if (Arb_y[i] <= 0.)
     481                                Arb_y[i] = 1e-20;
     482                }
     483
     484                Arb_alpha[i] = (std::log10(Arb_y[i]) - std::log10(Arb_y[i - 1]))
     485                                / (std::log10(Arb_x[i]) - std::log10(Arb_x[i - 1]));
     486                Arb_Const[i] = Arb_y[i] / (std::pow(Arb_x[i], Arb_alpha[i]));
     487                alp = Arb_alpha[i] + 1;
     488                if (alp == 0.) {
     489                  Area_seg[i] = Arb_Const[i] * (std::log(Arb_x[i]) - std::log(Arb_x[i - 1]));
     490                } else {
     491                  Area_seg[i] = (Arb_Const[i] / alp) * (std::pow(Arb_x[i], alp)
     492                                - std::pow(Arb_x[i - 1], alp));
     493                }
     494                sum = sum + Area_seg[i];
     495                Arb_Cum_Area[i] = Arb_Cum_Area[i - 1] + Area_seg[i];
     496                if (verbosityLevel == 2)
     497                        G4cout << Arb_alpha[i] << Arb_Const[i] << Area_seg[i] << G4endl;
     498                i++;
     499        }
     500
     501        i = 0;
     502        while (i < maxi) {
     503                Arb_Cum_Area[i] = Arb_Cum_Area[i] / sum;
     504                IPDFArbEnergyH.InsertValues(Arb_x[i], Arb_Cum_Area[i]);
     505                i++;
     506        }
     507
     508        // now scale the ArbEnergyH, needed by Probability()
     509        ArbEnergyH.ScaleVector(1., 1./sum);
     510
     511        if (verbosityLevel >= 1)
     512                G4cout << "Leaving LogInterpolation " << G4endl;
     513}
     514
     515void G4SPSEneDistribution::ExpInterpolation() {
     516        // Interpolation based on Exponential equations
     517        // Generate equations of line segments
     518        // y = Ae**-(x/e0) => ln y = -x/e0 + lnA
     519        // Find area under line segments
     520        // create normalised, cumulative array Arb_Cum_Area
     521        G4double Area_seg[1024]; // Stores area under each segment
     522        G4double sum = 0., Arb_x[1024], Arb_y[1024], Arb_Cum_Area[1024];
     523        G4int i, count;
     524        G4int maxi = ArbEnergyH.GetVectorLength();
     525        for (i = 0; i < maxi; i++) {
     526                Arb_x[i] = ArbEnergyH.GetLowEdgeEnergy(size_t(i));
     527                Arb_y[i] = ArbEnergyH(size_t(i));
     528        }
     529        // Points are now in x,y arrays. If the spectrum is integral it has to be
     530        // made differential and if momentum it has to be made energy.
     531        if (DiffSpec == false) {
     532                // Converts integral point-wise spectra to Differential
     533                for (count = 0; count < maxi - 1; count++) {
     534                        Arb_y[count] = (Arb_y[count] - Arb_y[count + 1])
     535                                        / (Arb_x[count + 1] - Arb_x[count]);
     536                }
     537                maxi--;
     538        }
     539        //
     540        if (EnergySpec == false) {
     541                // change currently stored values (emin etc) which are actually momenta
     542                // to energies.
     543                if (particle_definition == NULL)
     544                        G4cout << "Error: particle not defined" << G4endl;
     545                else {
     546                        // Apply Energy**2 = p**2c**2 + m0**2c**4
     547                        // p should be entered as E/c i.e. without the division by c
     548                        // being done - energy equivalent.
     549                        G4double mass = particle_definition->GetPDGMass();
     550                        // convert point to energy unit and its value to per energy unit
     551                        G4double total_energy;
     552                        for (count = 0; count < maxi; count++) {
     553                                total_energy = std::sqrt((Arb_x[count] * Arb_x[count]) + (mass
     554                                                * mass)); // total energy
     555
     556                                Arb_y[count] = Arb_y[count] * Arb_x[count] / total_energy;
     557                                Arb_x[count] = total_energy - mass; // kinetic energy
     558                        }
     559                }
     560        }
     561        //
     562        i = 1;
     563        Arb_ezero[0] = 0.;
     564        Arb_Const[0] = 0.;
     565        Area_seg[0] = 0.;
     566        Arb_Cum_Area[0] = 0.;
     567        while (i < maxi) {
     568                G4double test = std::log(Arb_y[i]) - std::log(Arb_y[i - 1]);
     569                if (test > 0. || test < 0.) {
     570                        Arb_ezero[i] = -(Arb_x[i] - Arb_x[i - 1]) / (std::log(Arb_y[i])
     571                                        - std::log(Arb_y[i - 1]));
     572                        Arb_Const[i] = Arb_y[i] / (std::exp(-Arb_x[i] / Arb_ezero[i]));
     573                        Area_seg[i] = -(Arb_Const[i] * Arb_ezero[i]) * (std::exp(-Arb_x[i]
     574                                        / Arb_ezero[i]) - std::exp(-Arb_x[i - 1] / Arb_ezero[i]));
     575                } else {
     576                        G4cout << "Flat line segment: problem" << G4endl;
     577                        Arb_ezero[i] = 0.;
     578                        Arb_Const[i] = 0.;
     579                        Area_seg[i] = 0.;
     580                }
     581                sum = sum + Area_seg[i];
     582                Arb_Cum_Area[i] = Arb_Cum_Area[i - 1] + Area_seg[i];
     583                if (verbosityLevel == 2)
     584                        G4cout << Arb_ezero[i] << Arb_Const[i] << Area_seg[i] << G4endl;
     585                i++;
     586        }
     587
     588        i = 0;
     589        while (i < maxi) {
     590                Arb_Cum_Area[i] = Arb_Cum_Area[i] / sum;
     591                IPDFArbEnergyH.InsertValues(Arb_x[i], Arb_Cum_Area[i]);
     592                i++;
     593        }
     594
     595        // now scale the ArbEnergyH, needed by Probability()
     596        ArbEnergyH.ScaleVector(1., 1./sum);
     597
     598        if (verbosityLevel >= 1)
     599                G4cout << "Leaving ExpInterpolation " << G4endl;
     600}
     601
     602void G4SPSEneDistribution::SplineInterpolation() {
     603        // Interpolation using Splines.
     604        // Create Normalised arrays, make x 0->1 and y hold
     605        // the function (Energy)
     606        //
     607        // Current method based on the above will not work in all cases.
     608        // new method is implemented below.
    218609 
    219   // Create a cumulative histogram.
    220   CDGhist[0] = 0.;
    221   G4double omalpha;
    222   G4int i = 0;
    223 
    224   while(i < n_par)
    225     {
    226       omalpha = 1. - spind[i];
    227       CDGhist[i+1] = CDGhist[i] + (pfact[i]/omalpha)*
    228         (std::pow(ene_line[i+1]/keV,omalpha)-std::pow(ene_line[i]/keV,omalpha));
    229       i++;
    230     }
    231  
    232   // Normalise histo and divide by 1000 to make MeV.
    233   i = 0;
    234   while(i < n_par)
    235     {
    236       CDGhist[i+1] = CDGhist[i+1]/CDGhist[n_par];
    237       //      G4cout << CDGhist[i] << CDGhist[n_par] << G4endl;
    238       i++;
    239     }
    240 }
    241 
    242 void G4SPSEneDistribution::CalculateBbodySpectrum()
    243 {
    244   // create bbody spectrum
    245   // Proved very hard to integrate indefinitely, so different
    246   // method. User inputs emin, emax and T. These are used to
    247   // create a 10,000 bin histogram.
    248   // Use photon density spectrum = 2 nu**2/c**2 * (std::exp(h nu/kT)-1)
    249   // = 2 E**2/h**2c**2 times the exponential
    250   G4double erange = Emax - Emin;
    251   G4double steps = erange/10000.;
    252   G4double Bbody_y[10000];
    253   G4double k = 8.6181e-11; //Boltzmann const in MeV/K
    254   G4double h = 4.1362e-21; // Plancks const in MeV s
    255   G4double c = 3e8; // Speed of light
    256   G4double h2 = h*h;
    257   G4double c2 = c*c;
    258   G4int count = 0;
    259   G4double sum = 0.;
    260   BBHist[0] = 0.;
    261   while(count < 10000)
    262     {
    263       Bbody_x[count] = Emin + G4double(count*steps);
    264       Bbody_y[count] = (2.*std::pow(Bbody_x[count],2.))/
    265         (h2*c2*(std::exp(Bbody_x[count]/(k*Temp)) - 1.));
    266       sum = sum + Bbody_y[count];
    267       BBHist[count+1] = BBHist[count] + Bbody_y[count];
    268       count++;
    269     }
    270 
    271   Bbody_x[10000] = Emax;
    272   // Normalise cumulative histo.
    273   count = 0;
    274   while(count<10001)
    275     {
    276       BBHist[count] = BBHist[count]/sum;
    277       count++;
    278     }
    279 }
    280 
    281 void G4SPSEneDistribution::InputEnergySpectra(G4bool value)
    282 {
    283   // Allows user to specifiy spectrum is momentum
    284   EnergySpec = value; // false if momentum
    285   if(verbosityLevel > 1)
    286     G4cout << "EnergySpec has value " << EnergySpec << G4endl;
    287 }
    288 
    289 void G4SPSEneDistribution::InputDifferentialSpectra(G4bool value)
    290 {
    291   // Allows user to specify integral or differential spectra
    292   DiffSpec = value; // true = differential, false = integral
    293   if(verbosityLevel > 1)
    294     G4cout << "Diffspec has value " << DiffSpec << G4endl;
    295 }
    296 
    297 void G4SPSEneDistribution::ArbInterpolate(G4String IType)
    298 {
    299   if(EnergyDisType != "Arb")
    300     G4cout << "Error: this is for arbitrary distributions" << G4endl;
    301   IntType = IType;
    302   ArbEmax = Emax;
    303   ArbEmin = Emin;
    304 
    305   // Now interpolate points
    306   if(IntType == "Lin")
    307     LinearInterpolation();
    308   if(IntType == "Log")
    309     LogInterpolation();
    310   if(IntType == "Exp")
    311     ExpInterpolation();
    312   if(IntType == "Spline")
    313     SplineInterpolation(); 
    314 }
    315 
    316 void G4SPSEneDistribution::LinearInterpolation()
    317 {
    318   // Method to do linear interpolation on the Arb points
    319   // Calculate equation of each line segment, max 1024.
    320   // Calculate Area under each segment
    321   // Create a cumulative array which is then normalised Arb_Cum_Area
    322 
    323   G4double Area_seg[1024]; // Stores area under each segment
    324   G4double sum = 0., Arb_x[1024], Arb_y[1024], Arb_Cum_Area[1024];
    325   G4int i, count;
    326   G4int maxi = ArbEnergyH.GetVectorLength();
    327   for(i=0;i<maxi;i++) {
    328     Arb_x[i] = ArbEnergyH.GetLowEdgeEnergy(size_t(i));
    329     Arb_y[i] = ArbEnergyH(size_t(i));
    330   }
    331   // Points are now in x,y arrays. If the spectrum is integral it has to be
    332   // made differential and if momentum it has to be made energy.
    333   if(DiffSpec == false) {
    334     // Converts integral point-wise spectra to Differential
    335     for( count=0;count < maxi-1;count++) {
    336       Arb_y[count] = (Arb_y[count] - Arb_y[count+1])/(Arb_x[count+1]-Arb_x[count]);
    337     }
    338     maxi--;
    339   }
    340   //
    341   if(EnergySpec == false) {
    342     // change currently stored values (emin etc) which are actually momenta
    343     // to energies.
    344     if(particle_definition == NULL)
    345       G4cout << "Error: particle not defined" << G4endl;
    346     else {
    347       // Apply Energy**2 = p**2c**2 + m0**2c**4
    348       // p should be entered as E/c i.e. without the division by c
    349       // being done - energy equivalent.
    350       G4double mass = particle_definition->GetPDGMass();
    351       // convert point to energy unit and its value to per energy unit
    352       G4double total_energy;
    353       for(count=0;count<maxi;count++) {
    354         total_energy = std::sqrt((Arb_x[count]*Arb_x[count])
    355                             + (mass*mass)); // total energy
    356        
    357         Arb_y[count] = Arb_y[count] * Arb_x[count]/total_energy;
    358         Arb_x[count] = total_energy - mass ;  // kinetic energy
    359       }
    360     }
    361   }
    362   //
    363   i=1;
    364   Arb_grad[0] = 0.;
    365   Arb_cept[0] = 0.;
    366   Area_seg[0] = 0.;
    367   Arb_Cum_Area[0] = 0.;
    368   while(i < maxi)
    369     {
    370       // calc gradient and intercept for each segment
    371       Arb_grad[i] = (Arb_y[i] - Arb_y[i-1]) / (Arb_x[i] - Arb_x[i-1]);
    372       if(verbosityLevel == 2)
    373         G4cout << Arb_grad[i] << G4endl;
    374       if(Arb_grad[i] > 0.)
    375         {
    376           if(verbosityLevel == 2)
    377             G4cout << "Arb_grad is positive" << G4endl;
    378           Arb_cept[i] = Arb_y[i] - (Arb_grad[i] * Arb_x[i]);
    379         }
    380       else if(Arb_grad[i] < 0.)
    381         {
    382           if(verbosityLevel == 2)
    383             G4cout << "Arb_grad is negative" << G4endl;
    384           Arb_cept[i] = Arb_y[i] + (-Arb_grad[i] * Arb_x[i]);
    385         }
    386       else
    387         {
    388           if(verbosityLevel == 2)
    389             G4cout << "Arb_grad is 0." << G4endl;
    390           Arb_cept[i] = Arb_y[i];
    391         }
    392 
    393       Area_seg[i] = ((Arb_grad[i]/2)*(Arb_x[i]*Arb_x[i] - Arb_x[i-1]*Arb_x[i-1]) + Arb_cept[i]*(Arb_x[i] - Arb_x[i-1]));
    394       Arb_Cum_Area[i] = Arb_Cum_Area[i-1] + Area_seg[i];
    395       sum = sum + Area_seg[i];
    396       if(verbosityLevel == 2)
    397         G4cout << Arb_x[i] << Arb_y[i] << Area_seg[i] << sum << Arb_grad[i] << G4endl;
    398       i++;
    399     }
    400 
    401   i=0;
    402   while(i < maxi)
    403     {
    404       Arb_Cum_Area[i] = Arb_Cum_Area[i]/sum; // normalisation
    405       IPDFArbEnergyH.InsertValues(Arb_x[i], Arb_Cum_Area[i]);
    406       i++;
    407     }
    408 
    409   if(verbosityLevel >= 1)
    410     {
    411       G4cout << "Leaving LinearInterpolation" << G4endl;
    412       ArbEnergyH.DumpValues();
    413       IPDFArbEnergyH.DumpValues();
    414     }
    415 }
    416 
    417 void G4SPSEneDistribution::LogInterpolation()
    418 {
    419   // Interpolation based on Logarithmic equations
    420   // Generate equations of line segments
    421   // y = Ax**alpha => log y = alpha*logx + logA
    422   // Find area under line segments
    423   // create normalised, cumulative array Arb_Cum_Area
    424   G4double Area_seg[1024]; // Stores area under each segment
    425   G4double sum = 0., Arb_x[1024], Arb_y[1024], Arb_Cum_Area[1024];
    426   G4int i, count;
    427   G4int maxi = ArbEnergyH.GetVectorLength();
    428   for(i=0;i<maxi;i++) {
    429     Arb_x[i] = ArbEnergyH.GetLowEdgeEnergy(size_t(i));
    430     Arb_y[i] = ArbEnergyH(size_t(i));
    431   }
    432   // Points are now in x,y arrays. If the spectrum is integral it has to be
    433   // made differential and if momentum it has to be made energy.
    434   if(DiffSpec == false) {
    435     // Converts integral point-wise spectra to Differential
    436     for( count=0;count<maxi-1;count++) {
    437       Arb_y[count] = (Arb_y[count] - Arb_y[count+1])/(Arb_x[count+1]-Arb_x[count]);
    438     }
    439     maxi--;
    440   }
    441   //
    442   if(EnergySpec == false) {
    443     // change currently stored values (emin etc) which are actually momenta
    444     // to energies.
    445     if(particle_definition == NULL)
    446       G4cout << "Error: particle not defined" << G4endl;
    447     else {
    448       // Apply Energy**2 = p**2c**2 + m0**2c**4
    449       // p should be entered as E/c i.e. without the division by c
    450       // being done - energy equivalent.
    451       G4double mass = particle_definition->GetPDGMass();
    452       // convert point to energy unit and its value to per energy unit
    453       G4double total_energy;
    454       for(count=0;count<maxi;count++) {
    455         total_energy = std::sqrt((Arb_x[count]*Arb_x[count])
    456                             + (mass*mass)); // total energy
    457        
    458         Arb_y[count] = Arb_y[count] * Arb_x[count]/total_energy;
    459         Arb_x[count] = total_energy - mass ;  // kinetic energy
    460       }
    461     }
    462   }
    463   //
    464   i=1;
    465   Arb_alpha[0] = 0.;
    466   Arb_Const[0] = 0.;
    467   Area_seg[0] = 0.;
    468   Arb_Cum_Area[0]=0. ; 
    469   if(Arb_x[0] <= 0. || Arb_y[0] <= 0.)
    470     {
    471       G4cout << "You should not use log interpolation with points <= 0." << G4endl;
    472       G4cout << "These will be changed to 1e-20, which may cause problems" << G4endl;
    473       if(Arb_x[0] <= 0.)
    474         Arb_x[0] = 1e-20;
    475       if(Arb_y[0] <= 0.)
    476         Arb_y[0] = 1e-20;
    477     }
    478 
    479   G4double alp; 
    480   while(i <maxi)
    481     {
    482       // Incase points are negative or zero
    483       if(Arb_x[i] <= 0. || Arb_y[i] <= 0.)
    484         {
    485           G4cout << "You should not use log interpolation with points <= 0." << G4endl;
    486           G4cout << "These will be changed to 1e-20, which may cause problems" << G4endl;
    487           if(Arb_x[i] <= 0.)
    488             Arb_x[i] = 1e-20;
    489           if(Arb_y[i] <= 0.)
    490             Arb_y[i] = 1e-20;
    491         }
    492 
    493       Arb_alpha[i] = (std::log10(Arb_y[i])-std::log10(Arb_y[i-1]))/(std::log10(Arb_x[i])-std::log10(Arb_x[i-1]));
    494       Arb_Const[i] = Arb_y[i]/(std::pow(Arb_x[i],Arb_alpha[i]));
    495       alp = Arb_alpha[i] + 1;
    496       Area_seg[i] = (Arb_Const[i]/alp) * (std::pow(Arb_x[i],alp) - std::pow(Arb_x[i-1],alp));
    497       sum = sum + Area_seg[i];
    498       Arb_Cum_Area[i] = Arb_Cum_Area[i-1] + Area_seg[i];
    499       if(verbosityLevel == 2)
    500         G4cout << Arb_alpha[i] << Arb_Const[i] << Area_seg[i] << G4endl;
    501       i++;
    502     }
    503  
    504   i=0;
    505   while(i<maxi)
    506     {
    507       Arb_Cum_Area[i] = Arb_Cum_Area[i]/sum;
    508       IPDFArbEnergyH.InsertValues(Arb_x[i], Arb_Cum_Area[i]);
    509       i++;
    510     }
    511   if(verbosityLevel >= 1)
    512     G4cout << "Leaving LogInterpolation " << G4endl;
    513 }
    514 
    515 void G4SPSEneDistribution::ExpInterpolation()
    516 {
    517   // Interpolation based on Exponential equations
    518   // Generate equations of line segments
    519   // y = Ae**-(x/e0) => ln y = -x/e0 + lnA
    520   // Find area under line segments
    521   // create normalised, cumulative array Arb_Cum_Area
    522   G4double Area_seg[1024]; // Stores area under each segment
    523   G4double sum = 0., Arb_x[1024], Arb_y[1024], Arb_Cum_Area[1024];
    524   G4int i, count;
    525   G4int maxi = ArbEnergyH.GetVectorLength();
    526   for(i=0;i<maxi;i++) {
    527     Arb_x[i] = ArbEnergyH.GetLowEdgeEnergy(size_t(i));
    528     Arb_y[i] = ArbEnergyH(size_t(i));
    529   }
    530   // Points are now in x,y arrays. If the spectrum is integral it has to be
    531   // made differential and if momentum it has to be made energy.
    532   if(DiffSpec == false) {
    533     // Converts integral point-wise spectra to Differential
    534     for( count=0;count< maxi-1;count++) {
    535       Arb_y[count] = (Arb_y[count] - Arb_y[count+1])/(Arb_x[count+1]-Arb_x[count]);
    536     }
    537     maxi--;
    538   }
    539   //
    540   if(EnergySpec == false) {
    541     // change currently stored values (emin etc) which are actually momenta
    542     // to energies.
    543     if(particle_definition == NULL)
    544       G4cout << "Error: particle not defined" << G4endl;
    545     else {
    546       // Apply Energy**2 = p**2c**2 + m0**2c**4
    547       // p should be entered as E/c i.e. without the division by c
    548       // being done - energy equivalent.
    549       G4double mass = particle_definition->GetPDGMass();
    550       // convert point to energy unit and its value to per energy unit
    551       G4double total_energy;
    552       for(count=0;count<maxi;count++) {
    553         total_energy = std::sqrt((Arb_x[count]*Arb_x[count])
    554                             + (mass*mass)); // total energy
    555        
    556         Arb_y[count] = Arb_y[count] * Arb_x[count]/total_energy;
    557         Arb_x[count] = total_energy - mass ;  // kinetic energy
    558       }
    559     }
    560   }
    561   //
    562   i=1;
    563   Arb_ezero[0] = 0.;
    564   Arb_Const[0] = 0.;
    565   Area_seg[0] = 0.;
    566   Arb_Cum_Area[0] = 0.;
    567   while(i < maxi)
    568     {
    569       G4double test = std::log(Arb_y[i]) - std::log(Arb_y[i-1]);
    570       if(test > 0. || test < 0.)
    571         {
    572           Arb_ezero[i] = -(Arb_x[i] - Arb_x[i-1])/(std::log(Arb_y[i]) - std::log(Arb_y[i-1]));
    573           Arb_Const[i] = Arb_y[i]/(std::exp(-Arb_x[i]/Arb_ezero[i]));
    574           Area_seg[i]=-(Arb_Const[i]*Arb_ezero[i])*(std::exp(-Arb_x[i]/Arb_ezero[i])
    575                                                     -std::exp(-Arb_x[i-1]/Arb_ezero[i]));
    576         }
    577       else
    578         {
    579           G4cout << "Flat line segment: problem" << G4endl;
    580           Arb_ezero[i] = 0.;
    581           Arb_Const[i] = 0.;
    582           Area_seg[i] = 0.;
    583         }
    584       sum = sum + Area_seg[i];
    585       Arb_Cum_Area[i] = Arb_Cum_Area[i-1] + Area_seg[i];
    586       if(verbosityLevel == 2)
    587         G4cout << Arb_ezero[i] << Arb_Const[i] << Area_seg[i] << G4endl;
    588       i++;
    589     }
    590  
    591   i=0;
    592   while(i<maxi)
    593     {
    594       Arb_Cum_Area[i] = Arb_Cum_Area[i]/sum;
    595       IPDFArbEnergyH.InsertValues(Arb_x[i], Arb_Cum_Area[i]);
    596       i++;
    597     }
    598   if(verbosityLevel >= 1)
    599     G4cout << "Leaving ExpInterpolation " << G4endl;
    600 }
    601 
    602 void G4SPSEneDistribution::SplineInterpolation()
    603 {
    604   // Interpolation using Splines.
    605   // Create Normalised arrays, make x 0->1 and y hold
    606   // the function (Energy)
    607   G4double  Arb_x[1024], Arb_y[1024];
    608   G4int i, count;
    609   G4int maxi = ArbEnergyH.GetVectorLength();
    610   for(i=0;i<maxi;i++) {
    611     Arb_x[i] = ArbEnergyH.GetLowEdgeEnergy(size_t(i));
    612     Arb_y[i] = ArbEnergyH(size_t(i));
    613   }
    614   // Points are now in x,y arrays. If the spectrum is integral it has to be
    615   // made differential and if momentum it has to be made energy.
    616   if(DiffSpec == false) {
    617     // Converts integral point-wise spectra to Differential
    618     for( count=0;count< maxi-1;count++) {
    619       Arb_y[count] = (Arb_y[count] - Arb_y[count+1])/(Arb_x[count+1]-Arb_x[count]);
    620     }
    621     maxi--;
    622   }
    623   //
    624   if(EnergySpec == false) {
    625     // change currently stored values (emin etc) which are actually momenta
    626     // to energies.
    627     if(particle_definition == NULL)
    628       G4cout << "Error: particle not defined" << G4endl;
    629     else {
    630       // Apply Energy**2 = p**2c**2 + m0**2c**4
    631       // p should be entered as E/c i.e. without the division by c
    632       // being done - energy equivalent.
    633       G4double mass = particle_definition->GetPDGMass();
    634       // convert point to energy unit and its value to per energy unit
    635       G4double total_energy;
    636       for(count=0;count<maxi;count++) {
    637         total_energy = std::sqrt((Arb_x[count]*Arb_x[count])
    638                             + (mass*mass)); // total energy
    639        
    640         Arb_y[count] = Arb_y[count] * Arb_x[count]/total_energy;
    641         Arb_x[count] = total_energy - mass ;  // kinetic energy
    642       }
    643     }
    644   }
    645   //
    646   for(i=1;i<maxi;i++)
    647     Arb_y[i] += Arb_y[i-1];
    648 
    649   for(i=0;i<maxi;i++)
    650     Arb_y[i] /= Arb_y[maxi-1];
    651   // now Arb_y is accumulated normalised probabilities
    652   /*  for(i=0; i<maxi;i++) {
    653       if(verbosityLevel >1)
    654        G4cout << i <<" "<< Arb_x[i] << " " << Arb_y[i] << G4endl;
    655        IPDFArbEnergyH.InsertValues(Arb_x[i], Arb_y[i]);   
    656    }
    657    Emax = IPDFArbEnergyH.GetLowEdgeEnergy(IPDFArbEnergyH.GetVectorLength()-1);
    658    Emin = IPDFArbEnergyH.GetLowEdgeEnergy(0);
    659   */
    660   // Should now have normalised cumulative probabilities in Arb_y
    661   // and energy values in Arb_x.
    662   // maxi = maxi + 1;
    663   // Put y into x and x into y. The spline interpolation will then
    664   // go through x-axis to find where to interpolate (cum probability)
    665   // then generate a y (which will now be energy).
    666   SplineInt = new G4DataInterpolation(Arb_y,Arb_x,maxi,1e30,1e30);
    667   if(verbosityLevel >1 )
    668     {
    669       G4cout << SplineInt << G4endl;
    670       G4cout << SplineInt->LocateArgument(1.0) << G4endl;
    671     }
    672   if(verbosityLevel > 0 )
    673     G4cout << "Leaving SplineInterpolation " << G4endl;
    674 }
    675 
    676 void G4SPSEneDistribution::GenerateMonoEnergetic()
    677 {
    678   // Method to generate MonoEnergetic particles.
    679   particle_energy = MonoEnergy;
    680 }
    681 
    682 void G4SPSEneDistribution::GenerateGaussEnergies()
    683 {
    684   // Method to generate Gaussian particles.
    685   particle_energy = G4RandGauss::shoot(MonoEnergy,SE);
    686   if (particle_energy < 0) particle_energy = 0.;
    687 }
    688 
    689 void G4SPSEneDistribution::GenerateLinearEnergies(G4bool bArb = false)
    690 {
    691   G4double rndm;
    692   G4double emaxsq = std::pow(Emax,2.); //Emax squared
    693   G4double eminsq = std::pow(Emin,2.); //Emin squared
    694   G4double intersq = std::pow(cept,2.); //cept squared
    695 
    696   if (bArb) rndm = G4UniformRand();
    697   else rndm = eneRndm->GenRandEnergy();
    698  
    699   G4double bracket = ((grad/2.)*(emaxsq - eminsq) + cept*(Emax-Emin));
    700   bracket = bracket * rndm;
    701   bracket = bracket + (grad/2.)*eminsq + cept*Emin;
    702   // Now have a quad of form m/2 E**2 + cE - bracket = 0
    703   bracket = -bracket;
    704   //  G4cout << "BRACKET" << bracket << G4endl;
    705   if(grad != 0.)
    706     {
    707       G4double sqbrack = (intersq - 4*(grad/2.)*(bracket));
    708       //      G4cout << "SQBRACK" << sqbrack << G4endl;
    709       sqbrack = std::sqrt(sqbrack);
    710       G4double root1 = -cept + sqbrack;
    711       root1 = root1/(2.*(grad/2.));
    712      
    713       G4double root2 = -cept - sqbrack;
    714       root2 = root2/(2.*(grad/2.));
    715 
    716       //      G4cout << root1 << " roots " << root2 << G4endl;
    717 
    718       if(root1 > Emin && root1 < Emax)
    719         particle_energy = root1;
    720       if(root2 > Emin && root2 < Emax)
    721         particle_energy = root2;
    722     }
    723   else if(grad == 0.)
    724     // have equation of form cE - bracket =0
    725     particle_energy = bracket/cept;
    726 
    727   if(particle_energy < 0.)
    728     particle_energy = -particle_energy;
    729  
    730   if(verbosityLevel >= 1)
    731     G4cout << "Energy is " << particle_energy << G4endl;
    732 }
    733 
    734 void G4SPSEneDistribution::GeneratePowEnergies(G4bool bArb = false)
    735 {
    736   // Method to generate particle energies distributed as
    737   // a powerlaw
    738 
    739   G4double rndm;
    740   G4double emina, emaxa;
    741 
    742   emina = std::pow(Emin,alpha+1);
    743   emaxa = std::pow(Emax,alpha+1);
    744 
    745   if (bArb) rndm = G4UniformRand();
    746   else rndm = eneRndm->GenRandEnergy();
    747  
    748   if(alpha != -1.)
    749     {
    750       particle_energy = ((rndm*(emaxa - emina)) + emina);
    751       particle_energy = std::pow(particle_energy,(1./(alpha+1.)));
    752     }
    753   else if(alpha == -1.)
    754     {
    755       particle_energy = (std::log(Emin) + rndm*(std::log(Emax) - std::log(Emin)));
    756       particle_energy = std::exp(particle_energy);
    757     }
    758   if(verbosityLevel >= 1)
    759     G4cout << "Energy is " << particle_energy << G4endl;
    760 }
    761 
    762 void G4SPSEneDistribution::GenerateExpEnergies(G4bool bArb = false)
    763 {
    764   // Method to generate particle energies distributed according
    765   // to an exponential curve.
    766   G4double rndm;
    767  
    768   if (bArb) rndm = G4UniformRand();
    769   else rndm = eneRndm->GenRandEnergy();
    770 
    771   particle_energy = -Ezero*(std::log(rndm*(std::exp(-Emax/Ezero) - std::exp(-Emin/Ezero)) +
    772                                 std::exp(-Emin/Ezero)));
    773   if(verbosityLevel >= 1)
    774     G4cout << "Energy is " << particle_energy << G4endl;
    775 }
    776 
    777 void G4SPSEneDistribution::GenerateBremEnergies()
    778 {
    779   // Method to generate particle energies distributed according
    780   // to a Bremstrahlung equation of
    781   // form I = const*((kT)**1/2)*E*(e**(-E/kT))
    782  
    783   G4double rndm;
    784   rndm = eneRndm->GenRandEnergy();
    785   G4double expmax, expmin, k;
    786 
    787   k = 8.6181e-11; // Boltzmann's const in MeV/K
    788   G4double ksq = std::pow(k,2.); // k squared
    789   G4double Tsq = std::pow(Temp,2.); // Temp squared
    790 
    791   expmax = std::exp(-Emax/(k*Temp));
    792   expmin = std::exp(-Emin/(k*Temp));
    793 
    794   // If either expmax or expmin are zero then this will cause problems
    795   // Most probably this will be because T is too low or E is too high
    796 
    797   if(expmax == 0.)
    798     G4cout << "*****EXPMAX=0. Choose different E's or Temp" << G4endl;
    799   if(expmin == 0.)
    800     G4cout << "*****EXPMIN=0. Choose different E's or Temp" << G4endl;
    801 
    802   G4double tempvar = rndm *((-k)*Temp*(Emax*expmax - Emin*expmin) -
    803     (ksq*Tsq*(expmax-expmin)));
    804 
    805   G4double bigc = (tempvar - k*Temp*Emin*expmin - ksq*Tsq*expmin)/(-k*Temp);
    806 
    807   // This gives an equation of form: Ee(-E/kT) + kTe(-E/kT) - C =0
    808   // Solve this iteratively, step from Emin to Emax in 1000 steps
    809   // and take the best solution.
    810 
    811   G4double erange = Emax - Emin;
    812   G4double steps = erange/1000.;
    813   G4int i;
    814   G4double etest, diff, err;
    815  
    816   err = 100000.;
    817 
    818   for(i=1; i<1000; i++)
    819     {
    820       etest = Emin + (i-1)*steps;
    821      
    822       diff = etest*(std::exp(-etest/(k*Temp))) + k*Temp*(std::exp(-etest/(k*Temp))) - bigc;
    823 
    824       if(diff < 0.)
    825         diff = -diff;
    826 
    827       if(diff < err)
    828         {
    829           err = diff;
    830           particle_energy = etest;
    831         }
    832     } 
    833   if(verbosityLevel >= 1)
    834     G4cout << "Energy is " << particle_energy << G4endl;
    835 }
    836 
    837 void G4SPSEneDistribution::GenerateBbodyEnergies()
    838 {
    839   // BBody_x holds Energies, and BBHist holds the cumulative histo.
    840   // binary search to find correct bin then lin interpolation.
    841   // Use the earlier defined histogram + RandGeneral method to generate
    842   // random numbers following the histos distribution.
    843   G4double rndm;
    844   G4int nabove, nbelow = 0, middle;
    845   nabove = 10001;
    846   rndm = eneRndm->GenRandEnergy();
    847 
    848   // Binary search to find bin that rndm is in
    849   while(nabove-nbelow > 1)
    850     {
    851       middle = (nabove + nbelow)/2;
    852       if(rndm == BBHist[middle]) break;
    853       if(rndm < BBHist[middle]) nabove = middle;
    854       else nbelow = middle;
    855     }
    856  
    857   // Now interpolate in that bin to find the correct output value.
    858   G4double x1, x2, y1, y2, m, q;
    859   x1 = Bbody_x[nbelow];
    860   x2 = Bbody_x[nbelow+1];
    861   y1 = BBHist[nbelow];
    862   y2 = BBHist[nbelow+1];
    863   m = (y2-y1)/(x2-x1);
    864   q = y1 - m*x1;
    865  
    866   particle_energy = (rndm - q)/m;
    867 
    868   if(verbosityLevel >= 1)
    869     {
    870       G4cout << "Energy is " << particle_energy << G4endl;
    871     }
    872 }
    873 
    874 void G4SPSEneDistribution::GenerateCdgEnergies()
    875 {
    876   // Gen random numbers, compare with values in cumhist
    877   // to find appropriate part of spectrum and then
    878   // generate energy in the usual inversion way.
    879   //  G4double pfact[2] = {8.5, 112};
    880   // G4double spind[2] = {1.4, 2.3};
    881   // G4double ene_line[3] = {1., 18., 1E6};
    882   G4double rndm, rndm2;
    883   G4double ene_line[3];
    884   G4double omalpha[2];
    885   if(Emin < 18*keV && Emax < 18*keV)
    886     {
    887       omalpha[0] = 1. - 1.4;
    888       ene_line[0] = Emin;
    889       ene_line[1] = Emax;
    890     }
    891   if(Emin < 18*keV && Emax > 18*keV)
    892     {
    893       omalpha[0] = 1. - 1.4;
    894       omalpha[1] = 1. - 2.3;
    895       ene_line[0] = Emin;
    896       ene_line[1] = 18.*keV;
    897       ene_line[2] = Emax;
    898     }
    899   if(Emin > 18*keV)
    900     {
    901       omalpha[0] = 1. - 2.3;
    902       ene_line[0] = Emin;
    903       ene_line[1] = Emax;
    904     }
    905   rndm = eneRndm->GenRandEnergy();
    906   rndm2 = eneRndm->GenRandEnergy();
    907 
    908   G4int i = 0;
    909   while( rndm >= CDGhist[i])
    910     {
    911       i++;
    912     }
    913   // Generate final energy.
    914   particle_energy = (std::pow(ene_line[i-1],omalpha[i-1]) + (std::pow(ene_line[i],omalpha[i-1])
    915                                         - std::pow(ene_line[i-1],omalpha[i-1]))*rndm2);
    916   particle_energy = std::pow(particle_energy,(1./omalpha[i-1]));
    917 
    918   if(verbosityLevel >= 1)
    919     G4cout << "Energy is " << particle_energy << G4endl;
    920 }
    921 
    922 void G4SPSEneDistribution::GenUserHistEnergies()
    923 {
    924   // Histograms are DIFFERENTIAL.
    925   //  G4cout << "In GenUserHistEnergies " << G4endl;
    926   if(IPDFEnergyExist == false)
    927     {
    928       G4int ii;
    929       G4int maxbin = G4int(UDefEnergyH.GetVectorLength());
    930       G4double bins[1024], vals[1024], sum;
    931       sum=0.;
    932 
    933       if((EnergySpec == false) && (particle_definition == NULL))
    934         G4cout << "Error: particle definition is NULL" << G4endl;
    935      
    936       if(maxbin > 1024)
    937         {
    938           G4cout << "Maxbin > 1024" << G4endl;
    939           G4cout << "Setting maxbin to 1024, other bins are lost" << G4endl;
    940         }
    941 
    942       if(DiffSpec == false)
    943         G4cout << "Histograms are Differential!!! " << G4endl;
    944       else
    945         {
    946           bins[0] = UDefEnergyH.GetLowEdgeEnergy(size_t(0));
    947           vals[0] = UDefEnergyH(size_t(0));
    948           sum = vals[0];
    949           for(ii=1;ii<maxbin;ii++)
    950             {
    951               bins[ii] = UDefEnergyH.GetLowEdgeEnergy(size_t(ii));
    952               vals[ii] = UDefEnergyH(size_t(ii)) + vals[ii-1];
    953               sum = sum + UDefEnergyH(size_t(ii));
     610        G4double sum, Arb_x[1024], Arb_y[1024], Arb_Cum_Area[1024];
     611        G4int i, count;
     612
     613        G4int maxi = ArbEnergyH.GetVectorLength();
     614        for (i = 0; i < maxi; i++) {
     615                Arb_x[i] = ArbEnergyH.GetLowEdgeEnergy(size_t(i));
     616                Arb_y[i] = ArbEnergyH(size_t(i));
     617        }
     618        // Points are now in x,y arrays. If the spectrum is integral it has to be
     619        // made differential and if momentum it has to be made energy.
     620        if (DiffSpec == false) {
     621                // Converts integral point-wise spectra to Differential
     622                for (count = 0; count < maxi - 1; count++) {
     623                        Arb_y[count] = (Arb_y[count] - Arb_y[count + 1])
     624                                        / (Arb_x[count + 1] - Arb_x[count]);
     625                }
     626                maxi--;
     627        }
     628        //
     629        if (EnergySpec == false) {
     630                // change currently stored values (emin etc) which are actually momenta
     631                // to energies.
     632                if (particle_definition == NULL)
     633                        G4cout << "Error: particle not defined" << G4endl;
     634                else {
     635                        // Apply Energy**2 = p**2c**2 + m0**2c**4
     636                        // p should be entered as E/c i.e. without the division by c
     637                        // being done - energy equivalent.
     638                        G4double mass = particle_definition->GetPDGMass();
     639                        // convert point to energy unit and its value to per energy unit
     640                        G4double total_energy;
     641                        for (count = 0; count < maxi; count++) {
     642                                total_energy = std::sqrt((Arb_x[count] * Arb_x[count]) + (mass
     643                                                * mass)); // total energy
     644
     645                                Arb_y[count] = Arb_y[count] * Arb_x[count] / total_energy;
     646                                Arb_x[count] = total_energy - mass; // kinetic energy
     647                        }
     648                }
     649        }
     650
     651        //
     652        i = 1;
     653        Arb_Cum_Area[0] = 0.;
     654        sum = 0.;
     655        Splinetemp = new G4DataInterpolation(Arb_x, Arb_y, maxi, 0., 0.);
     656        G4double ei[101],prob[101];
     657        while (i < maxi) {
     658          // 100 step per segment for the integration of area
     659          G4double de = (Arb_x[i] - Arb_x[i - 1])/100.;
     660          G4double area = 0.;
     661
     662          for (count = 0; count < 101; count++) {
     663            ei[count] = Arb_x[i - 1] + de*count ;
     664            prob[count] =  Splinetemp->CubicSplineInterpolation(ei[count]);
     665            if (prob[count] < 0.) {
     666              G4cout <<   "Warning: G4DataInterpolation returns value < 0  " << prob[count] <<" "<<ei[count]<< G4endl;
     667              G4Exception("         Please use an alternative method, e.g. Lin, for interpolation");
    954668            }
    955         }
    956 
    957       if(EnergySpec == false)
    958         {
    959           G4double mass = particle_definition->GetPDGMass();
    960           // multiply the function (vals) up by the bin width
    961           // to make the function counts/s (i.e. get rid of momentum
    962           // dependence).
    963           for(ii=1;ii<maxbin;ii++)
    964             {
    965               vals[ii] = vals[ii] * (bins[ii] - bins[ii-1]);
    966             }
    967           // Put energy bins into new histo, plus divide by energy bin width
    968           // to make evals counts/s/energy
    969           for(ii=0;ii<maxbin;ii++)
    970             {
    971               bins[ii] = std::sqrt((bins[ii]*bins[ii]) + (mass*mass)) - mass; //kinetic energy
    972             }
    973           for(ii=1;ii<maxbin;ii++)
    974             {
    975               vals[ii] = vals[ii]/(bins[ii] - bins[ii-1]);
    976             }
    977           sum = vals[maxbin-1];
    978           vals[0] = 0.;
    979         }
    980       for(ii=0;ii<maxbin;ii++)
    981         {
    982           vals[ii] = vals[ii]/sum;
    983           IPDFEnergyH.InsertValues(bins[ii], vals[ii]);
    984         }
    985      
    986       // Make IPDFEnergyExist = true
    987       IPDFEnergyExist = true;
    988       if(verbosityLevel > 1)
    989         IPDFEnergyH.DumpValues();   
    990     }
    991  
    992   // IPDF has been create so carry on
    993   G4double rndm = eneRndm->GenRandEnergy();
    994   particle_energy = IPDFEnergyH.GetEnergy(rndm);
    995  
    996   if(verbosityLevel >= 1)
    997     G4cout << "Energy is " << particle_energy << G4endl;
    998 }
    999 
    1000 void G4SPSEneDistribution::GenArbPointEnergies()
    1001 {
    1002   if(verbosityLevel > 0)
    1003     G4cout << "In GenArbPointEnergies" << G4endl;
    1004   G4double rndm;
    1005   rndm = eneRndm->GenRandEnergy();
    1006   if(IntType != "Spline")
    1007     {
    1008       //      IPDFArbEnergyH.DumpValues();
    1009       // Find the Bin
    1010       // have x, y, no of points, and cumulative area distribution
    1011       G4int nabove, nbelow = 0, middle;
    1012       nabove = IPDFArbEnergyH.GetVectorLength();
    1013       //      G4cout << nabove << G4endl;
    1014       // Binary search to find bin that rndm is in
    1015       while(nabove-nbelow > 1)
    1016         {
    1017           middle = (nabove + nbelow)/2;
    1018           if(rndm == IPDFArbEnergyH(size_t(middle))) break;
    1019           if(rndm < IPDFArbEnergyH(size_t(middle))) nabove = middle;
    1020           else nbelow = middle;
    1021         }
    1022       if(IntType == "Lin")
    1023         {
    1024           Emax = IPDFArbEnergyH.GetLowEdgeEnergy(size_t(nbelow+1));
     669            area += prob[count]*de;
     670          }
     671          Arb_Cum_Area[i] = Arb_Cum_Area[i - 1] + area;
     672          sum += area;
     673
     674          prob[0] = prob[0]/(area/de);
     675          for (count = 1; count < 100; count++)
     676            prob[count] = prob[count-1] + prob[count]/(area/de);
     677
     678          SplineInt[i] = new G4DataInterpolation(prob, ei, 101, 0., 0.);
     679          // note i start from 1!
     680          i++;
     681        }
     682        i = 0;
     683        while (i < maxi) {
     684                Arb_Cum_Area[i] = Arb_Cum_Area[i] / sum; // normalisation
     685                IPDFArbEnergyH.InsertValues(Arb_x[i], Arb_Cum_Area[i]);
     686                i++;
     687        }
     688        // now scale the ArbEnergyH, needed by Probability()
     689        ArbEnergyH.ScaleVector(1., 1./sum);
     690
     691        if (verbosityLevel > 0)
     692          G4cout << "Leaving SplineInterpolation " << G4endl;
     693}
     694
     695void G4SPSEneDistribution::GenerateMonoEnergetic() {
     696        // Method to generate MonoEnergetic particles.
     697        particle_energy = MonoEnergy;
     698}
     699
     700void G4SPSEneDistribution::GenerateGaussEnergies() {
     701        // Method to generate Gaussian particles.
     702        particle_energy = G4RandGauss::shoot(MonoEnergy,SE);
     703        if (particle_energy < 0) particle_energy = 0.;
     704}
     705
     706void G4SPSEneDistribution::GenerateLinearEnergies(G4bool bArb = false) {
     707        G4double rndm;
     708        G4double emaxsq = std::pow(Emax, 2.); //Emax squared
     709        G4double eminsq = std::pow(Emin, 2.); //Emin squared
     710        G4double intersq = std::pow(cept, 2.); //cept squared
     711
     712        if (bArb)
     713                rndm = G4UniformRand();
     714        else
     715                rndm = eneRndm->GenRandEnergy();
     716
     717        G4double bracket = ((grad / 2.) * (emaxsq - eminsq) + cept * (Emax - Emin));
     718        bracket = bracket * rndm;
     719        bracket = bracket + (grad / 2.) * eminsq + cept * Emin;
     720        // Now have a quad of form m/2 E**2 + cE - bracket = 0
     721        bracket = -bracket;
     722        //  G4cout << "BRACKET" << bracket << G4endl;
     723        if (grad != 0.) {
     724                G4double sqbrack = (intersq - 4 * (grad / 2.) * (bracket));
     725                //      G4cout << "SQBRACK" << sqbrack << G4endl;
     726                sqbrack = std::sqrt(sqbrack);
     727                G4double root1 = -cept + sqbrack;
     728                root1 = root1 / (2. * (grad / 2.));
     729
     730                G4double root2 = -cept - sqbrack;
     731                root2 = root2 / (2. * (grad / 2.));
     732
     733                //      G4cout << root1 << " roots " << root2 << G4endl;
     734
     735                if (root1 > Emin && root1 < Emax)
     736                        particle_energy = root1;
     737                if (root2 > Emin && root2 < Emax)
     738                        particle_energy = root2;
     739        } else if (grad == 0.)
     740                // have equation of form cE - bracket =0
     741                particle_energy = bracket / cept;
     742
     743        if (particle_energy < 0.)
     744                particle_energy = -particle_energy;
     745
     746        if (verbosityLevel >= 1)
     747                G4cout << "Energy is " << particle_energy << G4endl;
     748}
     749
     750void G4SPSEneDistribution::GeneratePowEnergies(G4bool bArb = false) {
     751        // Method to generate particle energies distributed as
     752        // a power-law
     753
     754        G4double rndm;
     755        G4double emina, emaxa;
     756
     757        emina = std::pow(Emin, alpha + 1);
     758        emaxa = std::pow(Emax, alpha + 1);
     759
     760        if (bArb)
     761                rndm = G4UniformRand();
     762        else
     763                rndm = eneRndm->GenRandEnergy();
     764
     765        if (alpha != -1.) {
     766                particle_energy = ((rndm * (emaxa - emina)) + emina);
     767                particle_energy = std::pow(particle_energy, (1. / (alpha + 1.)));
     768        } else {
     769                particle_energy = (std::log(Emin) + rndm * (std::log(Emax) - std::log(
     770                                Emin)));
     771                particle_energy = std::exp(particle_energy);
     772        }
     773        if (verbosityLevel >= 1)
     774                G4cout << "Energy is " << particle_energy << G4endl;
     775}
     776
     777void G4SPSEneDistribution::GenerateBiasPowEnergies() {
     778        // Method to generate particle energies distributed as
     779        // in biased power-law and calculate its weight
     780
     781        G4double rndm;
     782        G4double emina, emaxa, emin, emax;
     783
     784        G4double normal = 1. ;
     785
     786        emin = Emin;
     787        emax = Emax;
     788        //      if (EnergyDisType == "Arb") {
     789        //  emin = ArbEmin;
     790        //  emax = ArbEmax;
     791        //}
     792
     793        rndm = eneRndm->GenRandEnergy();
     794
     795        if (biasalpha != -1.) {
     796                emina = std::pow(emin, biasalpha + 1);
     797                emaxa = std::pow(emax, biasalpha + 1);
     798                particle_energy = ((rndm * (emaxa - emina)) + emina);
     799                particle_energy = std::pow(particle_energy, (1. / (biasalpha + 1.)));
     800                normal = 1./(1+biasalpha) * (emaxa - emina);
     801        } else {
     802                particle_energy = (std::log(emin) + rndm * (std::log(emax) - std::log(
     803                                emin)));
     804                particle_energy = std::exp(particle_energy);
     805                normal = std::log(emax) - std::log(emin) ;
     806        }
     807        weight = GetProbability(particle_energy) / (std::pow(particle_energy,biasalpha)/normal);
     808
     809        if (verbosityLevel >= 1)
     810                G4cout << "Energy is " << particle_energy << G4endl;
     811}
     812
     813void G4SPSEneDistribution::GenerateExpEnergies(G4bool bArb = false) {
     814        // Method to generate particle energies distributed according
     815        // to an exponential curve.
     816        G4double rndm;
     817
     818        if (bArb)
     819                rndm = G4UniformRand();
     820        else
     821                rndm = eneRndm->GenRandEnergy();
     822
     823        particle_energy = -Ezero * (std::log(rndm * (std::exp(-Emax / Ezero)
     824                        - std::exp(-Emin / Ezero)) + std::exp(-Emin / Ezero)));
     825        if (verbosityLevel >= 1)
     826                G4cout << "Energy is " << particle_energy << G4endl;
     827}
     828
     829void G4SPSEneDistribution::GenerateBremEnergies() {
     830        // Method to generate particle energies distributed according
     831        // to a Bremstrahlung equation of
     832        // form I = const*((kT)**1/2)*E*(e**(-E/kT))
     833
     834        G4double rndm;
     835        rndm = eneRndm->GenRandEnergy();
     836        G4double expmax, expmin, k;
     837
     838        k = 8.6181e-11; // Boltzmann's const in MeV/K
     839        G4double ksq = std::pow(k, 2.); // k squared
     840        G4double Tsq = std::pow(Temp, 2.); // Temp squared
     841
     842        expmax = std::exp(-Emax / (k * Temp));
     843        expmin = std::exp(-Emin / (k * Temp));
     844
     845        // If either expmax or expmin are zero then this will cause problems
     846        // Most probably this will be because T is too low or E is too high
     847
     848        if (expmax == 0.)
     849                G4cout << "*****EXPMAX=0. Choose different E's or Temp" << G4endl;
     850        if (expmin == 0.)
     851                G4cout << "*****EXPMIN=0. Choose different E's or Temp" << G4endl;
     852
     853        G4double tempvar = rndm * ((-k) * Temp * (Emax * expmax - Emin * expmin)
     854                        - (ksq * Tsq * (expmax - expmin)));
     855
     856        G4double bigc = (tempvar - k * Temp * Emin * expmin - ksq * Tsq * expmin)
     857                        / (-k * Temp);
     858
     859        // This gives an equation of form: Ee(-E/kT) + kTe(-E/kT) - C =0
     860        // Solve this iteratively, step from Emin to Emax in 1000 steps
     861        // and take the best solution.
     862
     863        G4double erange = Emax - Emin;
     864        G4double steps = erange / 1000.;
     865        G4int i;
     866        G4double etest, diff, err;
     867
     868        err = 100000.;
     869
     870        for (i = 1; i < 1000; i++) {
     871                etest = Emin + (i - 1) * steps;
     872
     873                diff = etest * (std::exp(-etest / (k * Temp))) + k * Temp * (std::exp(
     874                                -etest / (k * Temp))) - bigc;
     875
     876                if (diff < 0.)
     877                        diff = -diff;
     878
     879                if (diff < err) {
     880                        err = diff;
     881                        particle_energy = etest;
     882                }
     883        }
     884        if (verbosityLevel >= 1)
     885                G4cout << "Energy is " << particle_energy << G4endl;
     886}
     887
     888void G4SPSEneDistribution::GenerateBbodyEnergies() {
     889        // BBody_x holds Energies, and BBHist holds the cumulative histo.
     890        // binary search to find correct bin then lin interpolation.
     891        // Use the earlier defined histogram + RandGeneral method to generate
     892        // random numbers following the histos distribution.
     893        G4double rndm;
     894        G4int nabove, nbelow = 0, middle;
     895        nabove = 10001;
     896        rndm = eneRndm->GenRandEnergy();
     897
     898        // Binary search to find bin that rndm is in
     899        while (nabove - nbelow > 1) {
     900                middle = (nabove + nbelow) / 2;
     901                if (rndm == BBHist[middle])
     902                        break;
     903                if (rndm < BBHist[middle])
     904                        nabove = middle;
     905                else
     906                        nbelow = middle;
     907        }
     908
     909        // Now interpolate in that bin to find the correct output value.
     910        G4double x1, x2, y1, y2, m, q;
     911        x1 = Bbody_x[nbelow];
     912        x2 = Bbody_x[nbelow + 1];
     913        y1 = BBHist[nbelow];
     914        y2 = BBHist[nbelow + 1];
     915        m = (y2 - y1) / (x2 - x1);
     916        q = y1 - m * x1;
     917
     918        particle_energy = (rndm - q) / m;
     919
     920        if (verbosityLevel >= 1) {
     921                G4cout << "Energy is " << particle_energy << G4endl;
     922        }
     923}
     924
     925void G4SPSEneDistribution::GenerateCdgEnergies() {
     926        // Gen random numbers, compare with values in cumhist
     927        // to find appropriate part of spectrum and then
     928        // generate energy in the usual inversion way.
     929        //  G4double pfact[2] = {8.5, 112};
     930        // G4double spind[2] = {1.4, 2.3};
     931        // G4double ene_line[3] = {1., 18., 1E6};
     932        G4double rndm, rndm2;
     933        G4double ene_line[3];
     934        G4double omalpha[2];
     935        if (Emin < 18 * keV && Emax < 18 * keV) {
     936                omalpha[0] = 1. - 1.4;
     937                ene_line[0] = Emin;
     938                ene_line[1] = Emax;
     939        }
     940        if (Emin < 18 * keV && Emax > 18 * keV) {
     941                omalpha[0] = 1. - 1.4;
     942                omalpha[1] = 1. - 2.3;
     943                ene_line[0] = Emin;
     944                ene_line[1] = 18. * keV;
     945                ene_line[2] = Emax;
     946        }
     947        if (Emin > 18 * keV) {
     948                omalpha[0] = 1. - 2.3;
     949                ene_line[0] = Emin;
     950                ene_line[1] = Emax;
     951        }
     952        rndm = eneRndm->GenRandEnergy();
     953        rndm2 = eneRndm->GenRandEnergy();
     954
     955        G4int i = 0;
     956        while (rndm >= CDGhist[i]) {
     957                i++;
     958        }
     959        // Generate final energy.
     960        particle_energy = (std::pow(ene_line[i - 1], omalpha[i - 1]) + (std::pow(
     961                        ene_line[i], omalpha[i - 1]) - std::pow(ene_line[i - 1], omalpha[i
     962                        - 1])) * rndm2);
     963        particle_energy = std::pow(particle_energy, (1. / omalpha[i - 1]));
     964
     965        if (verbosityLevel >= 1)
     966                G4cout << "Energy is " << particle_energy << G4endl;
     967}
     968
     969void G4SPSEneDistribution::GenUserHistEnergies() {
     970        // Histograms are DIFFERENTIAL.
     971        //  G4cout << "In GenUserHistEnergies " << G4endl;
     972        if (IPDFEnergyExist == false) {
     973                G4int ii;
     974                G4int maxbin = G4int(UDefEnergyH.GetVectorLength());
     975                G4double bins[1024], vals[1024], sum;
     976                sum = 0.;
     977
     978                if ((EnergySpec == false) && (particle_definition == NULL))
     979                        G4cout << "Error: particle definition is NULL" << G4endl;
     980
     981                if (maxbin > 1024) {
     982                        G4cout << "Maxbin > 1024" << G4endl;
     983                        G4cout << "Setting maxbin to 1024, other bins are lost" << G4endl;
     984                }
     985
     986                if (DiffSpec == false)
     987                        G4cout << "Histograms are Differential!!! " << G4endl;
     988                else {
     989                        bins[0] = UDefEnergyH.GetLowEdgeEnergy(size_t(0));
     990                        vals[0] = UDefEnergyH(size_t(0));
     991                        sum = vals[0];
     992                        for (ii = 1; ii < maxbin; ii++) {
     993                                bins[ii] = UDefEnergyH.GetLowEdgeEnergy(size_t(ii));
     994                                vals[ii] = UDefEnergyH(size_t(ii)) + vals[ii - 1];
     995                                sum = sum + UDefEnergyH(size_t(ii));
     996                        }
     997                }
     998
     999                if (EnergySpec == false) {
     1000                        G4double mass = particle_definition->GetPDGMass();
     1001                        // multiply the function (vals) up by the bin width
     1002                        // to make the function counts/s (i.e. get rid of momentum
     1003                        // dependence).
     1004                        for (ii = 1; ii < maxbin; ii++) {
     1005                                vals[ii] = vals[ii] * (bins[ii] - bins[ii - 1]);
     1006                        }
     1007                        // Put energy bins into new histo, plus divide by energy bin width
     1008                        // to make evals counts/s/energy
     1009                        for (ii = 0; ii < maxbin; ii++) {
     1010                                bins[ii] = std::sqrt((bins[ii] * bins[ii]) + (mass * mass))
     1011                                                - mass; //kinetic energy
     1012                        }
     1013                        for (ii = 1; ii < maxbin; ii++) {
     1014                                vals[ii] = vals[ii] / (bins[ii] - bins[ii - 1]);
     1015                        }
     1016                        sum = vals[maxbin - 1];
     1017                        vals[0] = 0.;
     1018                }
     1019                for (ii = 0; ii < maxbin; ii++) {
     1020                        vals[ii] = vals[ii] / sum;
     1021                        IPDFEnergyH.InsertValues(bins[ii], vals[ii]);
     1022                }
     1023
     1024                // Make IPDFEnergyExist = true
     1025                IPDFEnergyExist = true;
     1026                if (verbosityLevel > 1)
     1027                        IPDFEnergyH.DumpValues();
     1028        }
     1029
     1030        // IPDF has been create so carry on
     1031        G4double rndm = eneRndm->GenRandEnergy();
     1032        particle_energy = IPDFEnergyH.GetEnergy(rndm);
     1033
     1034        if (verbosityLevel >= 1)
     1035                G4cout << "Energy is " << particle_energy << G4endl;
     1036}
     1037
     1038void G4SPSEneDistribution::GenArbPointEnergies() {
     1039        if (verbosityLevel > 0)
     1040                G4cout << "In GenArbPointEnergies" << G4endl;
     1041        G4double rndm;
     1042        rndm = eneRndm->GenRandEnergy();
     1043        //      IPDFArbEnergyH.DumpValues();
     1044        // Find the Bin
     1045        // have x, y, no of points, and cumulative area distribution
     1046        G4int nabove, nbelow = 0, middle;
     1047        nabove = IPDFArbEnergyH.GetVectorLength();
     1048        //      G4cout << nabove << G4endl;
     1049        // Binary search to find bin that rndm is in
     1050        while (nabove - nbelow > 1) {
     1051          middle = (nabove + nbelow) / 2;
     1052          if (rndm == IPDFArbEnergyH(size_t(middle)))
     1053            break;
     1054          if (rndm < IPDFArbEnergyH(size_t(middle)))
     1055            nabove = middle;
     1056          else
     1057            nbelow = middle;
     1058        }
     1059        if (IntType == "Lin") {
     1060          Emax = IPDFArbEnergyH.GetLowEdgeEnergy(size_t(nbelow + 1));
    10251061          Emin = IPDFArbEnergyH.GetLowEdgeEnergy(size_t(nbelow));
    1026           grad = Arb_grad[nbelow+1];
    1027           cept = Arb_cept[nbelow+1];
     1062          grad = Arb_grad[nbelow + 1];
     1063          cept = Arb_cept[nbelow + 1];
    10281064          //      G4cout << rndm << " " << Emax << " " << Emin << " " << grad << " " << cept << G4endl;
    10291065          GenerateLinearEnergies(true);
    1030         }
    1031       else if(IntType == "Log")
    1032         {
    1033           Emax = IPDFArbEnergyH.GetLowEdgeEnergy(size_t(nbelow+1));
     1066        } else if (IntType == "Log") {
     1067          Emax = IPDFArbEnergyH.GetLowEdgeEnergy(size_t(nbelow + 1));
    10341068          Emin = IPDFArbEnergyH.GetLowEdgeEnergy(size_t(nbelow));
    1035           alpha = Arb_alpha[nbelow+1];
     1069          alpha = Arb_alpha[nbelow + 1];
    10361070          //      G4cout << rndm << " " << Emax << " " << Emin << " " << alpha << G4endl;
    10371071          GeneratePowEnergies(true);
    1038         }
    1039       else if(IntType == "Exp")
    1040         {
    1041           Emax = IPDFArbEnergyH.GetLowEdgeEnergy(size_t(nbelow+1));
     1072        } else if (IntType == "Exp") {
     1073          Emax = IPDFArbEnergyH.GetLowEdgeEnergy(size_t(nbelow + 1));
    10421074          Emin = IPDFArbEnergyH.GetLowEdgeEnergy(size_t(nbelow));
    1043           Ezero = Arb_ezero[nbelow+1];
     1075          Ezero = Arb_ezero[nbelow + 1];
    10441076          //      G4cout << rndm << " " << Emax << " " << Emin << " " << Ezero << G4endl;
    10451077          GenerateExpEnergies(true);
    1046         }
    1047     }
    1048   else if(IntType == "Spline")
    1049     {
    1050       if(verbosityLevel > 1)
    1051         G4cout << "IntType = Spline " << rndm << G4endl;
    1052       // in SplineInterpolation created SplineInt
    1053       // Now generate a random number put it into CubicSplineInterpolation
    1054       // and you should get out an energy!?!
    1055       particle_energy = -1e100;
    1056       while (particle_energy < Emin || particle_energy > Emax ) {
    1057         particle_energy = SplineInt->CubicSplineInterpolation(rndm);
    1058         rndm = eneRndm->GenRandEnergy();
    1059       }
    1060       if(verbosityLevel >= 1)
    1061         G4cout << "Energy is " << particle_energy << G4endl;
    1062     }
    1063   else
    1064     G4cout << "Error: IntType unknown type" << G4endl;
    1065 }
    1066 
    1067 void G4SPSEneDistribution::GenEpnHistEnergies()
    1068 {
    1069   //  G4cout << "In GenEpnHistEnergies " << Epnflag << G4endl;
    1070  
    1071   // Firstly convert to energy if not already done.
    1072   if(Epnflag == true)
    1073     // epnflag = true means spectrum is epn, false means e.
    1074     {
    1075       // convert to energy by multiplying by A number
    1076       ConvertEPNToEnergy();
    1077       // EpnEnergyH will be replace by UDefEnergyH.
    1078       //      UDefEnergyH.DumpValues();
    1079     }
    1080 
    1081   //  G4cout << "Creating IPDFEnergy if not already done so" << G4endl;
    1082   if(IPDFEnergyExist == false)
    1083     {
    1084       // IPDF has not been created, so create it
    1085       G4double bins[1024],vals[1024], sum;
    1086       G4int ii;
    1087       G4int maxbin = G4int(UDefEnergyH.GetVectorLength());
    1088       bins[0] = UDefEnergyH.GetLowEdgeEnergy(size_t(0));
    1089       vals[0] = UDefEnergyH(size_t(0));
    1090       sum = vals[0];
    1091       for(ii=1;ii<maxbin;ii++)
     1078        } else if (IntType == "Spline") {
     1079          Emax = IPDFArbEnergyH.GetLowEdgeEnergy(size_t(nbelow + 1));
     1080          Emin = IPDFArbEnergyH.GetLowEdgeEnergy(size_t(nbelow));
     1081          particle_energy = -1e100;
     1082          rndm = eneRndm->GenRandEnergy();
     1083          while (particle_energy < Emin || particle_energy > Emax) {
     1084            particle_energy = SplineInt[nbelow+1]->CubicSplineInterpolation(rndm);
     1085            rndm = eneRndm->GenRandEnergy();
     1086          }
     1087          if (verbosityLevel >= 1)
     1088            G4cout << "Energy is " << particle_energy << G4endl;
     1089        } else
     1090                G4cout << "Error: IntType unknown type" << G4endl;
     1091}
     1092
     1093void G4SPSEneDistribution::GenEpnHistEnergies() {
     1094        //  G4cout << "In GenEpnHistEnergies " << Epnflag << G4endl;
     1095
     1096        // Firstly convert to energy if not already done.
     1097        if (Epnflag == true)
     1098        // epnflag = true means spectrum is epn, false means e.
    10921099        {
    1093           bins[ii] = UDefEnergyH.GetLowEdgeEnergy(size_t(ii));
    1094           vals[ii] = UDefEnergyH(size_t(ii)) + vals[ii-1];
    1095           sum = sum + UDefEnergyH(size_t(ii));
    1096         }
    1097      
    1098       for(ii=0;ii<maxbin;ii++)
    1099         {
    1100           vals[ii] = vals[ii]/sum;
    1101           IPDFEnergyH.InsertValues(bins[ii], vals[ii]);
    1102         }
    1103       // Make IPDFEpnExist = true
    1104       IPDFEnergyExist = true;
    1105     }
    1106   //  IPDFEnergyH.DumpValues();
    1107   // IPDF has been create so carry on
    1108   G4double rndm = eneRndm->GenRandEnergy();
    1109   particle_energy = IPDFEnergyH.GetEnergy(rndm);
    1110 
    1111   if(verbosityLevel >= 1)
    1112     G4cout << "Energy is " << particle_energy << G4endl;
    1113 }
    1114 
    1115 void G4SPSEneDistribution::ConvertEPNToEnergy()
    1116 {
    1117   // Use this before particle generation to convert  the
    1118   // currently stored histogram from energy/nucleon
    1119   // to energy.
    1120   //  G4cout << "In ConvertEpntoEnergy " << G4endl;
    1121   if(particle_definition==NULL)
    1122     G4cout << "Error: particle not defined" << G4endl;
    1123   else
    1124     {
    1125       // Need to multiply histogram by the number of nucleons.
    1126       // Baryon Number looks to hold the no. of nucleons.
    1127       G4int Bary = particle_definition->GetBaryonNumber();
    1128       //      G4cout << "Baryon No. " << Bary << G4endl;
    1129       // Change values in histogram, Read it out, delete it, re-create it
    1130       G4int count, maxcount;
    1131       maxcount = G4int(EpnEnergyH.GetVectorLength());
    1132       //      G4cout << maxcount << G4endl;
    1133       G4double ebins[1024],evals[1024];
    1134       if(maxcount > 1024)
    1135         {
    1136           G4cout << "Histogram contains more than 1024 bins!" << G4endl;
    1137           G4cout << "Those above 1024 will be ignored" << G4endl;
    1138           maxcount = 1024;
    1139         }
    1140       if(maxcount < 1)
    1141         {
    1142           G4cout << "Histogram contains less than 1 bin!" << G4endl;
    1143           G4cout << "Redefine the histogram" << G4endl;
    1144           return;
    1145         }
    1146       for(count=0;count<maxcount;count++)
    1147         {
    1148           // Read out
    1149           ebins[count] = EpnEnergyH.GetLowEdgeEnergy(size_t(count));
    1150           evals[count] = EpnEnergyH(size_t(count));
    1151         }
    1152 
    1153       // Multiply the channels by the nucleon number to give energies
    1154       for(count=0;count<maxcount;count++)
    1155         {
    1156           ebins[count] = ebins[count] * Bary;
    1157         }
    1158 
    1159       // Set Emin and Emax
    1160       Emin = ebins[0];
    1161       if (maxcount > 1)
    1162         Emax = ebins[maxcount-1];
    1163       else
    1164         Emax = ebins[0];
    1165       // Put energy bins into new histogram - UDefEnergyH.
    1166       for(count=0;count<maxcount;count++)
    1167         {
    1168           UDefEnergyH.InsertValues(ebins[count], evals[count]);
    1169         }
    1170       Epnflag = false; //so that you dont repeat this method.
    1171     } 
     1100                // convert to energy by multiplying by A number
     1101                ConvertEPNToEnergy();
     1102                // EpnEnergyH will be replace by UDefEnergyH.
     1103                //      UDefEnergyH.DumpValues();
     1104        }
     1105
     1106        //  G4cout << "Creating IPDFEnergy if not already done so" << G4endl;
     1107        if (IPDFEnergyExist == false) {
     1108                // IPDF has not been created, so create it
     1109                G4double bins[1024], vals[1024], sum;
     1110                G4int ii;
     1111                G4int maxbin = G4int(UDefEnergyH.GetVectorLength());
     1112                bins[0] = UDefEnergyH.GetLowEdgeEnergy(size_t(0));
     1113                vals[0] = UDefEnergyH(size_t(0));
     1114                sum = vals[0];
     1115                for (ii = 1; ii < maxbin; ii++) {
     1116                        bins[ii] = UDefEnergyH.GetLowEdgeEnergy(size_t(ii));
     1117                        vals[ii] = UDefEnergyH(size_t(ii)) + vals[ii - 1];
     1118                        sum = sum + UDefEnergyH(size_t(ii));
     1119                }
     1120
     1121                for (ii = 0; ii < maxbin; ii++) {
     1122                        vals[ii] = vals[ii] / sum;
     1123                        IPDFEnergyH.InsertValues(bins[ii], vals[ii]);
     1124                }
     1125                // Make IPDFEpnExist = true
     1126                IPDFEnergyExist = true;
     1127        }
     1128        //  IPDFEnergyH.DumpValues();
     1129        // IPDF has been create so carry on
     1130        G4double rndm = eneRndm->GenRandEnergy();
     1131        particle_energy = IPDFEnergyH.GetEnergy(rndm);
     1132
     1133        if (verbosityLevel >= 1)
     1134                G4cout << "Energy is " << particle_energy << G4endl;
     1135}
     1136
     1137void G4SPSEneDistribution::ConvertEPNToEnergy() {
     1138        // Use this before particle generation to convert  the
     1139        // currently stored histogram from energy/nucleon
     1140        // to energy.
     1141        //  G4cout << "In ConvertEpntoEnergy " << G4endl;
     1142        if (particle_definition == NULL)
     1143                G4cout << "Error: particle not defined" << G4endl;
     1144        else {
     1145                // Need to multiply histogram by the number of nucleons.
     1146                // Baryon Number looks to hold the no. of nucleons.
     1147                G4int Bary = particle_definition->GetBaryonNumber();
     1148                //      G4cout << "Baryon No. " << Bary << G4endl;
     1149                // Change values in histogram, Read it out, delete it, re-create it
     1150                G4int count, maxcount;
     1151                maxcount = G4int(EpnEnergyH.GetVectorLength());
     1152                //      G4cout << maxcount << G4endl;
     1153                G4double ebins[1024], evals[1024];
     1154                if (maxcount > 1024) {
     1155                        G4cout << "Histogram contains more than 1024 bins!" << G4endl;
     1156                        G4cout << "Those above 1024 will be ignored" << G4endl;
     1157                        maxcount = 1024;
     1158                }
     1159                if (maxcount < 1) {
     1160                        G4cout << "Histogram contains less than 1 bin!" << G4endl;
     1161                        G4cout << "Redefine the histogram" << G4endl;
     1162                        return;
     1163                }
     1164                for (count = 0; count < maxcount; count++) {
     1165                        // Read out
     1166                        ebins[count] = EpnEnergyH.GetLowEdgeEnergy(size_t(count));
     1167                        evals[count] = EpnEnergyH(size_t(count));
     1168                }
     1169
     1170                // Multiply the channels by the nucleon number to give energies
     1171                for (count = 0; count < maxcount; count++) {
     1172                        ebins[count] = ebins[count] * Bary;
     1173                }
     1174
     1175                // Set Emin and Emax
     1176                Emin = ebins[0];
     1177                if (maxcount > 1)
     1178                        Emax = ebins[maxcount - 1];
     1179                else
     1180                        Emax = ebins[0];
     1181                // Put energy bins into new histogram - UDefEnergyH.
     1182                for (count = 0; count < maxcount; count++) {
     1183                        UDefEnergyH.InsertValues(ebins[count], evals[count]);
     1184                }
     1185                Epnflag = false; //so that you dont repeat this method.
     1186        }
    11721187}
    11731188
    11741189//
    1175 void G4SPSEneDistribution::ReSetHist(G4String atype)
    1176 {
    1177   if (atype == "energy"){
    1178     UDefEnergyH = IPDFEnergyH = ZeroPhysVector ;
    1179     IPDFEnergyExist = false ;
    1180     Emin = 0.;
    1181     Emax = 1e30;} 
    1182   else if ( atype == "arb"){
    1183     ArbEnergyH =IPDFArbEnergyH = ZeroPhysVector ;
    1184     IPDFArbExist = false;}
    1185   else if ( atype == "epn"){
    1186     UDefEnergyH = IPDFEnergyH = ZeroPhysVector ;
    1187     IPDFEnergyExist = false ;
    1188     EpnEnergyH = ZeroPhysVector ;}
    1189   else {
    1190     G4cout << "Error, histtype not accepted " << G4endl;
    1191   }
    1192 }
    1193 
    1194 G4double G4SPSEneDistribution::GenerateOne(G4ParticleDefinition* a)
    1195 {
    1196   particle_definition = a;
    1197   particle_energy = -1.;
    1198   while ( (EnergyDisType == "Arb")? (particle_energy < ArbEmin || particle_energy > ArbEmax)
    1199           : (particle_energy < Emin || particle_energy > Emax) ) {
    1200     if(EnergyDisType == "Mono")
    1201       GenerateMonoEnergetic();
    1202     else if(EnergyDisType == "Lin")
    1203       GenerateLinearEnergies();
    1204     else if(EnergyDisType == "Pow")
    1205       GeneratePowEnergies();
    1206     else if(EnergyDisType == "Exp")
    1207       GenerateExpEnergies();
    1208     else if(EnergyDisType == "Gauss")
    1209       GenerateGaussEnergies();
    1210     else if(EnergyDisType == "Brem")
    1211       GenerateBremEnergies();
    1212     else if(EnergyDisType == "Bbody")
    1213       GenerateBbodyEnergies();
    1214     else if(EnergyDisType == "Cdg")
    1215       GenerateCdgEnergies();
    1216     else if(EnergyDisType == "User")
    1217       GenUserHistEnergies();
    1218     else if(EnergyDisType == "Arb")
    1219       GenArbPointEnergies();
    1220     else if(EnergyDisType == "Epn")
    1221       GenEpnHistEnergies();
    1222     else
    1223       G4cout << "Error: EnergyDisType has unusual value" << G4endl;
    1224   }
    1225   return particle_energy;
    1226 }
    1227 
    1228 
    1229 
    1230 
    1231 
    1232 
    1233 
    1234 
    1235 
     1190void G4SPSEneDistribution::ReSetHist(G4String atype) {
     1191        if (atype == "energy") {
     1192                UDefEnergyH = IPDFEnergyH = ZeroPhysVector;
     1193                IPDFEnergyExist = false;
     1194                Emin = 0.;
     1195                Emax = 1e30;
     1196        } else if (atype == "arb") {
     1197                ArbEnergyH = IPDFArbEnergyH = ZeroPhysVector;
     1198                IPDFArbExist = false;
     1199        } else if (atype == "epn") {
     1200                UDefEnergyH = IPDFEnergyH = ZeroPhysVector;
     1201                IPDFEnergyExist = false;
     1202                EpnEnergyH = ZeroPhysVector;
     1203        } else {
     1204                G4cout << "Error, histtype not accepted " << G4endl;
     1205        }
     1206}
     1207
     1208G4double G4SPSEneDistribution::GenerateOne(G4ParticleDefinition* a) {
     1209        particle_definition = a;
     1210        particle_energy = -1.;
     1211
     1212        while ((EnergyDisType == "Arb") ? (particle_energy < ArbEmin
     1213                        || particle_energy > ArbEmax) : (particle_energy < Emin
     1214                        || particle_energy > Emax)) {
     1215                if (Biased) {
     1216                        GenerateBiasPowEnergies();
     1217                } else {
     1218                        if (EnergyDisType == "Mono")
     1219                                GenerateMonoEnergetic();
     1220                        else if (EnergyDisType == "Lin")
     1221                                GenerateLinearEnergies();
     1222                        else if (EnergyDisType == "Pow")
     1223                                GeneratePowEnergies();
     1224                        else if (EnergyDisType == "Exp")
     1225                                GenerateExpEnergies();
     1226                        else if (EnergyDisType == "Gauss")
     1227                                GenerateGaussEnergies();
     1228                        else if (EnergyDisType == "Brem")
     1229                                GenerateBremEnergies();
     1230                        else if (EnergyDisType == "Bbody")
     1231                                GenerateBbodyEnergies();
     1232                        else if (EnergyDisType == "Cdg")
     1233                                GenerateCdgEnergies();
     1234                        else if (EnergyDisType == "User")
     1235                                GenUserHistEnergies();
     1236                        else if (EnergyDisType == "Arb")
     1237                                GenArbPointEnergies();
     1238                        else if (EnergyDisType == "Epn")
     1239                                GenEpnHistEnergies();
     1240                        else
     1241                                G4cout << "Error: EnergyDisType has unusual value" << G4endl;
     1242                }
     1243        }
     1244        return particle_energy;
     1245}
     1246
     1247G4double G4SPSEneDistribution::GetProbability(G4double ene) {
     1248        G4double prob = 1.;
     1249
     1250        if (EnergyDisType == "Lin") {
     1251          if (prob_norm == 1.) {
     1252            prob_norm = 0.5*grad*Emax*Emax + cept*Emax - 0.5*grad*Emin*Emin - cept*Emin;
     1253          }
     1254          prob = cept + grad * ene;
     1255          prob /= prob_norm;
     1256        }
     1257        else if (EnergyDisType == "Pow") {
     1258          if (prob_norm == 1.) {
     1259            if (alpha != -1.) {
     1260              G4double emina = std::pow(Emin, alpha + 1);
     1261              G4double emaxa = std::pow(Emax, alpha + 1);
     1262              prob_norm = 1./(1.+alpha) * (emaxa - emina);
     1263            } else {
     1264              prob_norm = std::log(Emax) - std::log(Emin) ;
     1265            }
     1266          }
     1267          prob = std::pow(ene, alpha)/prob_norm;
     1268        }
     1269        else if (EnergyDisType == "Exp"){
     1270          if (prob_norm == 1.) {
     1271            prob_norm = -Ezero*(std::exp(-Emax/Ezero) - std::exp(Emin/Ezero));
     1272          } 
     1273          prob = std::exp(-ene / Ezero);
     1274          prob /= prob_norm;
     1275        }
     1276        else if (EnergyDisType == "Arb") {
     1277          prob = ArbEnergyH.Value(ene);
     1278          //  prob = ArbEInt->CubicSplineInterpolation(ene);
     1279          //G4double deltaY;
     1280          //prob = ArbEInt->PolynomInterpolation(ene, deltaY);
     1281          if (prob <= 0.) {
     1282            //G4cout << " Warning:G4SPSEneDistribution::GetProbability: prob<= 0. "<<prob <<" "<<ene << " " <<deltaY<< G4endl;
     1283            G4cout << " Warning:G4SPSEneDistribution::GetProbability: prob<= 0. "<<prob <<" "<<ene << G4endl;
     1284            prob = 1e-30;
     1285          }
     1286          // already normalised
     1287        }
     1288        else
     1289                G4cout << "Error: EnergyDisType not supported" << G4endl;
     1290       
     1291        return prob;
     1292}
  • trunk/source/event/src/G4SPSRandomGenerator.cc

    r816 r1347  
    6363//G4SPSRandomGenerator* G4SPSRandomGenerator::instance = 0;
    6464
    65 G4SPSRandomGenerator::G4SPSRandomGenerator()
    66 {
    67   // Initialise all variables
    68 
    69   // Bias variables
    70   XBias = false;
    71   IPDFXBias = false;
    72   YBias = false;
    73   IPDFYBias = false;
    74   ZBias = false;
    75   IPDFZBias = false;
    76   ThetaBias = false;
    77   IPDFThetaBias = false;
    78   PhiBias = false;
    79   IPDFPhiBias = false;
    80   EnergyBias = false;
    81   IPDFEnergyBias = false;
    82   PosThetaBias = false;
    83   IPDFPosThetaBias = false;
    84   PosPhiBias = false;
    85   IPDFPosPhiBias = false;
    86   bweights[0] = bweights[1] = bweights[2] = bweights[3] = bweights[4] = bweights[5] = bweights[6] = bweights[7]= bweights[8]= 1. ;
    87   verbosityLevel = 0 ;
    88 }
    89 
    90 G4SPSRandomGenerator::~G4SPSRandomGenerator()
    91 {}
     65G4SPSRandomGenerator::G4SPSRandomGenerator() {
     66        // Initialise all variables
     67
     68        // Bias variables
     69        XBias = false;
     70        IPDFXBias = false;
     71        YBias = false;
     72        IPDFYBias = false;
     73        ZBias = false;
     74        IPDFZBias = false;
     75        ThetaBias = false;
     76        IPDFThetaBias = false;
     77        PhiBias = false;
     78        IPDFPhiBias = false;
     79        EnergyBias = false;
     80        IPDFEnergyBias = false;
     81        PosThetaBias = false;
     82        IPDFPosThetaBias = false;
     83        PosPhiBias = false;
     84        IPDFPosPhiBias = false;
     85        bweights[0] = bweights[1] = bweights[2] = bweights[3] = bweights[4]
     86                        = bweights[5] = bweights[6] = bweights[7] = bweights[8] = 1.;
     87        verbosityLevel = 0;
     88}
     89
     90G4SPSRandomGenerator::~G4SPSRandomGenerator() {
     91}
    9292
    9393//G4SPSRandomGenerator* G4SPSRandomGenerator::getInstance ()
     
    9999// Biasing methods
    100100
    101 void G4SPSRandomGenerator::SetXBias(G4ThreeVector input)
    102 
    103   G4double ehi, val;
    104   ehi = input.x();
    105   val = input.y();
    106   XBiasH.InsertValues(ehi, val);
    107   XBias = true;
    108 }
    109 
    110 void G4SPSRandomGenerator::SetYBias(G4ThreeVector input)
    111 {
    112   G4double ehi, val;
    113   ehi = input.x();
    114   val = input.y();
    115   YBiasH.InsertValues(ehi, val);
    116   YBias = true;
    117 }
    118 
    119 void G4SPSRandomGenerator::SetZBias(G4ThreeVector input)
    120 {
    121   G4double ehi, val;
    122   ehi = input.x();
    123   val = input.y();
    124   ZBiasH.InsertValues(ehi, val);
    125   ZBias = true;
    126 }
    127 
    128 void G4SPSRandomGenerator::SetThetaBias(G4ThreeVector input)
    129 {
    130   G4double ehi, val;
    131   ehi = input.x();
    132   val = input.y();
    133   ThetaBiasH.InsertValues(ehi, val);
    134   ThetaBias = true;
    135 }
    136 
    137 void G4SPSRandomGenerator::SetPhiBias(G4ThreeVector input)
    138 {
    139   G4double ehi, val;
    140   ehi = input.x();
    141   val = input.y();
    142   PhiBiasH.InsertValues(ehi, val);
    143   PhiBias = true;
    144 }
    145 
    146 void G4SPSRandomGenerator::SetEnergyBias(G4ThreeVector input)
    147 {
    148   G4double ehi, val;
    149   ehi = input.x();
    150   val = input.y();
    151   EnergyBiasH.InsertValues(ehi, val);
    152   EnergyBias = true;
    153 }
    154 
    155 void G4SPSRandomGenerator::SetPosThetaBias(G4ThreeVector input)
    156 {
    157   G4double ehi, val;
    158   ehi = input.x();
    159   val = input.y();
    160   PosThetaBiasH.InsertValues(ehi, val);
    161   PosThetaBias = true;
    162 }
    163 
    164 void G4SPSRandomGenerator::SetPosPhiBias(G4ThreeVector input)
    165 {
    166   G4double ehi, val;
    167   ehi = input.x();
    168   val = input.y();
    169   PosPhiBiasH.InsertValues(ehi, val);
    170   PosPhiBias = true;
    171 }
    172 
    173 void G4SPSRandomGenerator::ReSetHist(G4String atype)
    174 {
    175   if ( atype == "biasx") {
    176     XBias = false ;
    177     IPDFXBias = false;
    178     XBiasH = IPDFXBiasH = ZeroPhysVector ;}
    179   else if ( atype == "biasy") {
    180     YBias = false ;
    181     IPDFYBias = false;
    182     YBiasH = IPDFYBiasH = ZeroPhysVector ;}
    183   else if ( atype == "biasz") {
    184     ZBias = false ;
    185     IPDFZBias = false;
    186     ZBiasH = IPDFZBiasH = ZeroPhysVector ;}
    187   else if ( atype == "biast") {
    188     ThetaBias = false ;
    189     IPDFThetaBias = false;
    190     ThetaBiasH = IPDFThetaBiasH = ZeroPhysVector ;}
    191   else if ( atype == "biasp") {
    192     PhiBias = false ;
    193     IPDFPhiBias = false;
    194     PhiBiasH = IPDFPhiBiasH = ZeroPhysVector ;}
    195   else if ( atype == "biase") {
    196     EnergyBias = false ;
    197     IPDFEnergyBias = false;
    198     EnergyBiasH = IPDFEnergyBiasH = ZeroPhysVector ;}
    199   else if ( atype == "biaspt") {
    200     PosThetaBias = false ;
    201     IPDFPosThetaBias = false;
    202     PosThetaBiasH = IPDFPosThetaBiasH = ZeroPhysVector ;}
    203   else if ( atype == "biaspp") {
    204     PosPhiBias = false ;
    205     IPDFPosPhiBias = false;
    206     PosPhiBiasH = IPDFPosPhiBiasH = ZeroPhysVector ;}
    207   else {
    208     G4cout << "Error, histtype not accepted " << G4endl;
    209   }
    210 }
    211 
    212 G4double G4SPSRandomGenerator::GenRandX()
    213 {
    214   if(verbosityLevel >= 1)
    215     G4cout << "In GenRandX" << G4endl;
    216   if(XBias == false)
    217     {
    218       // X is not biased
    219       G4double rndm = G4UniformRand();
    220       return(rndm);
    221     }
    222   else
    223     {
    224       // X is biased
    225       if(IPDFXBias == false)
    226         {
    227           // IPDF has not been created, so create it
    228           G4double bins[1024],vals[1024], sum;
    229           G4int ii;
    230           G4int maxbin = G4int(XBiasH.GetVectorLength());
    231           bins[0] = XBiasH.GetLowEdgeEnergy(size_t(0));
    232           vals[0] = XBiasH(size_t(0));
    233           sum = vals[0];
    234           for(ii=1;ii<maxbin;ii++)
    235             {
    236               bins[ii] = XBiasH.GetLowEdgeEnergy(size_t(ii));
    237               vals[ii] = XBiasH(size_t(ii)) + vals[ii-1];
    238               sum = sum + XBiasH(size_t(ii));
    239             }
    240 
    241           for(ii=0;ii<maxbin;ii++)
    242             {
    243               vals[ii] = vals[ii]/sum;
    244               IPDFXBiasH.InsertValues(bins[ii], vals[ii]);
    245             }
    246           // Make IPDFXBias = true
    247           IPDFXBias = true;
    248         }
    249       // IPDF has been create so carry on
    250       G4double rndm = G4UniformRand();
    251 
    252       // Calculate the weighting: Find the bin that the determined
    253       // rndm is in and the weigthing will be the difference in the
    254       // natural probability (from the x-axis) divided by the
    255       // difference in the biased probability (the area).
    256       size_t numberOfBin = IPDFXBiasH.GetVectorLength();
    257       G4int biasn1 = 0;
    258       G4int biasn2 = numberOfBin/2;
    259       G4int biasn3 = numberOfBin - 1;
    260       while (biasn1 != biasn3 - 1) {
    261       if (rndm > IPDFXBiasH(biasn2))
    262          biasn1 = biasn2;
    263       else
    264          biasn3 = biasn2;
    265       biasn2 = biasn1 + (biasn3 - biasn1 + 1)/2;
    266       }
    267       // retrieve the areas and then the x-axis values
    268       bweights[0] = IPDFXBiasH(biasn2) - IPDFXBiasH(biasn2 - 1);
    269       G4double xaxisl = IPDFXBiasH.GetLowEdgeEnergy(size_t(biasn2-1));
    270       G4double xaxisu = IPDFXBiasH.GetLowEdgeEnergy(size_t(biasn2));
    271       G4double NatProb = xaxisu - xaxisl;
    272       //G4cout << "X Bin weight " << bweights[0] << " " << rndm << G4endl;
    273       //G4cout << "lower and upper xaxis vals "<<xaxisl<<" "<<xaxisu<<G4endl;
    274       bweights[0] = NatProb/bweights[0];
    275       if(verbosityLevel >= 1)
    276         G4cout << "X bin weight " << bweights[0] << " " << rndm << G4endl;
    277       return(IPDFXBiasH.GetEnergy(rndm));
    278     }
    279 }
    280 
    281 G4double G4SPSRandomGenerator::GenRandY()
    282 {
    283   if(verbosityLevel >= 1)
    284     G4cout << "In GenRandY" << G4endl;
    285   if(YBias == false)
    286     {
    287       // Y is not biased
    288       G4double rndm = G4UniformRand();
    289       return(rndm);
    290     }
    291   else
    292     {
    293       // Y is biased
    294       if(IPDFYBias == false)
    295         {
    296           // IPDF has not been created, so create it
    297           G4double bins[1024],vals[1024], sum;
    298           G4int ii;
    299           G4int maxbin = G4int(YBiasH.GetVectorLength());
    300           bins[0] = YBiasH.GetLowEdgeEnergy(size_t(0));
    301           vals[0] = YBiasH(size_t(0));
    302           sum = vals[0];
    303           for(ii=1;ii<maxbin;ii++)
    304             {
    305               bins[ii] = YBiasH.GetLowEdgeEnergy(size_t(ii));
    306               vals[ii] = YBiasH(size_t(ii)) + vals[ii-1];
    307               sum = sum + YBiasH(size_t(ii));
    308             }
    309 
    310           for(ii=0;ii<maxbin;ii++)
    311             {
    312               vals[ii] = vals[ii]/sum;
    313               IPDFYBiasH.InsertValues(bins[ii], vals[ii]);
    314             }
    315           // Make IPDFYBias = true
    316           IPDFYBias = true;
    317         }
    318       // IPDF has been create so carry on
    319       G4double rndm = G4UniformRand();
    320       size_t numberOfBin = IPDFYBiasH.GetVectorLength();
    321       G4int biasn1 = 0;
    322       G4int biasn2 = numberOfBin/2;
    323       G4int biasn3 = numberOfBin - 1;
    324       while (biasn1 != biasn3 - 1) {
    325       if (rndm > IPDFYBiasH(biasn2))
    326          biasn1 = biasn2;
    327       else
    328          biasn3 = biasn2;
    329       biasn2 = biasn1 + (biasn3 - biasn1 + 1)/2;
    330       }
    331       bweights[1] =  IPDFYBiasH(biasn2) - IPDFYBiasH(biasn2 - 1);
    332       G4double xaxisl = IPDFYBiasH.GetLowEdgeEnergy(size_t(biasn2-1));
    333       G4double xaxisu = IPDFYBiasH.GetLowEdgeEnergy(size_t(biasn2));
    334       G4double NatProb = xaxisu - xaxisl;
    335       bweights[1] = NatProb/bweights[1];
    336       if(verbosityLevel >= 1)
    337         G4cout << "Y bin weight " << bweights[1] << " " << rndm << G4endl;
    338       return(IPDFYBiasH.GetEnergy(rndm));
    339     }
    340 }
    341 
    342 G4double G4SPSRandomGenerator::GenRandZ()
    343 {
    344   if(verbosityLevel >= 1)
    345     G4cout << "In GenRandZ" << G4endl;
    346   if(ZBias == false)
    347     {
    348       // Z is not biased
    349       G4double rndm = G4UniformRand();
    350       return(rndm);
    351     }
    352   else
    353     {
    354       // Z is biased
    355       if(IPDFZBias == false)
    356         {
    357           // IPDF has not been created, so create it
    358           G4double bins[1024],vals[1024], sum;
    359           G4int ii;
    360           G4int maxbin = G4int(ZBiasH.GetVectorLength());
    361           bins[0] = ZBiasH.GetLowEdgeEnergy(size_t(0));
    362           vals[0] = ZBiasH(size_t(0));
    363           sum = vals[0];
    364           for(ii=1;ii<maxbin;ii++)
    365             {
    366               bins[ii] = ZBiasH.GetLowEdgeEnergy(size_t(ii));
    367               vals[ii] = ZBiasH(size_t(ii)) + vals[ii-1];
    368               sum = sum + ZBiasH(size_t(ii));
    369             }
    370 
    371           for(ii=0;ii<maxbin;ii++)
    372             {
    373               vals[ii] = vals[ii]/sum;
    374               IPDFZBiasH.InsertValues(bins[ii], vals[ii]);
    375             }
    376           // Make IPDFZBias = true
    377           IPDFZBias = true;
    378         }
    379       // IPDF has been create so carry on
    380       G4double rndm = G4UniformRand();
    381       //      size_t weight_bin_no = IPDFZBiasH.FindValueBinLocation(rndm);
    382       size_t numberOfBin = IPDFZBiasH.GetVectorLength();
    383       G4int biasn1 = 0;
    384       G4int biasn2 = numberOfBin/2;
    385       G4int biasn3 = numberOfBin - 1;
    386       while (biasn1 != biasn3 - 1) {
    387       if (rndm > IPDFZBiasH(biasn2))
    388          biasn1 = biasn2;
    389       else
    390          biasn3 = biasn2;
    391       biasn2 = biasn1 + (biasn3 - biasn1 + 1)/2;
    392       }
    393       bweights[2] =  IPDFZBiasH(biasn2) - IPDFZBiasH(biasn2 - 1);
    394       G4double xaxisl = IPDFZBiasH.GetLowEdgeEnergy(size_t(biasn2-1));
    395       G4double xaxisu = IPDFZBiasH.GetLowEdgeEnergy(size_t(biasn2));
    396       G4double NatProb = xaxisu - xaxisl;
    397       bweights[2] = NatProb/bweights[2];
    398       if(verbosityLevel >= 1)
    399         G4cout << "Z bin weight " << bweights[2] << " " << rndm << G4endl;
    400       return(IPDFZBiasH.GetEnergy(rndm));
    401     }
    402 }
    403 
    404 G4double G4SPSRandomGenerator::GenRandTheta()
    405 {
    406   if(verbosityLevel >= 1)
    407     {
    408       G4cout << "In GenRandTheta" << G4endl;
    409       G4cout << "Verbosity " << verbosityLevel << G4endl;
    410     }
    411   if(ThetaBias == false)
    412     {
    413       // Theta is not biased
    414       G4double rndm = G4UniformRand();
    415       return(rndm);
    416     }
    417   else
    418     {
    419       // Theta is biased
    420       if(IPDFThetaBias == false)
    421         {
    422           // IPDF has not been created, so create it
    423           G4double bins[1024],vals[1024], sum;
    424           G4int ii;
    425           G4int maxbin = G4int(ThetaBiasH.GetVectorLength());
    426           bins[0] = ThetaBiasH.GetLowEdgeEnergy(size_t(0));
    427           vals[0] = ThetaBiasH(size_t(0));
    428           sum = vals[0];
    429           for(ii=1;ii<maxbin;ii++)
    430             {
    431               bins[ii] = ThetaBiasH.GetLowEdgeEnergy(size_t(ii));
    432               vals[ii] = ThetaBiasH(size_t(ii)) + vals[ii-1];
    433               sum = sum + ThetaBiasH(size_t(ii));
    434             }
    435 
    436           for(ii=0;ii<maxbin;ii++)
    437             {
    438               vals[ii] = vals[ii]/sum;
    439               IPDFThetaBiasH.InsertValues(bins[ii], vals[ii]);
    440             }
    441           // Make IPDFThetaBias = true
    442           IPDFThetaBias = true;
    443         }
    444       // IPDF has been create so carry on
    445       G4double rndm = G4UniformRand();
    446       //      size_t weight_bin_no = IPDFThetaBiasH.FindValueBinLocation(rndm);
    447       size_t numberOfBin = IPDFThetaBiasH.GetVectorLength();
    448       G4int biasn1 = 0;
    449       G4int biasn2 = numberOfBin/2;
    450       G4int biasn3 = numberOfBin - 1;
    451       while (biasn1 != biasn3 - 1) {
    452       if (rndm > IPDFThetaBiasH(biasn2))
    453          biasn1 = biasn2;
    454       else
    455          biasn3 = biasn2;
    456       biasn2 = biasn1 + (biasn3 - biasn1 + 1)/2;
    457       }
    458       bweights[3] =  IPDFThetaBiasH(biasn2) - IPDFThetaBiasH(biasn2 - 1);
    459       G4double xaxisl = IPDFThetaBiasH.GetLowEdgeEnergy(size_t(biasn2-1));
    460       G4double xaxisu = IPDFThetaBiasH.GetLowEdgeEnergy(size_t(biasn2));
    461       G4double NatProb = xaxisu - xaxisl;
    462       bweights[3] = NatProb/bweights[3];
    463       if(verbosityLevel >= 1)
    464         G4cout << "Theta bin weight " << bweights[3] << " " << rndm << G4endl;
    465       return(IPDFThetaBiasH.GetEnergy(rndm));
    466     }
    467 }
    468 
    469 G4double G4SPSRandomGenerator::GenRandPhi()
    470 {
    471   if(verbosityLevel >= 1)
    472     G4cout << "In GenRandPhi" << G4endl;
    473   if(PhiBias == false)
    474     {
    475       // Phi is not biased
    476       G4double rndm = G4UniformRand();
    477       return(rndm);
    478     }
    479   else
    480     {
    481       // Phi is biased
    482       if(IPDFPhiBias == false)
    483         {
    484           // IPDF has not been created, so create it
    485           G4double bins[1024],vals[1024], sum;
    486           G4int ii;
    487           G4int maxbin = G4int(PhiBiasH.GetVectorLength());
    488           bins[0] = PhiBiasH.GetLowEdgeEnergy(size_t(0));
    489           vals[0] = PhiBiasH(size_t(0));
    490           sum = vals[0];
    491           for(ii=1;ii<maxbin;ii++)
    492             {
    493               bins[ii] = PhiBiasH.GetLowEdgeEnergy(size_t(ii));
    494               vals[ii] = PhiBiasH(size_t(ii)) + vals[ii-1];
    495               sum = sum + PhiBiasH(size_t(ii));
    496             }
    497 
    498           for(ii=0;ii<maxbin;ii++)
    499             {
    500               vals[ii] = vals[ii]/sum;
    501               IPDFPhiBiasH.InsertValues(bins[ii], vals[ii]);
    502             }
    503           // Make IPDFPhiBias = true
    504           IPDFPhiBias = true;
    505         }
    506       // IPDF has been create so carry on
    507       G4double rndm = G4UniformRand();
    508       //      size_t weight_bin_no = IPDFPhiBiasH.FindValueBinLocation(rndm);
    509       size_t numberOfBin = IPDFPhiBiasH.GetVectorLength();
    510       G4int biasn1 = 0;
    511       G4int biasn2 = numberOfBin/2;
    512       G4int biasn3 = numberOfBin - 1;
    513       while (biasn1 != biasn3 - 1) {
    514       if (rndm > IPDFPhiBiasH(biasn2))
    515          biasn1 = biasn2;
    516       else
    517          biasn3 = biasn2;
    518       biasn2 = biasn1 + (biasn3 - biasn1 + 1)/2;
    519       }
    520       bweights[4] =  IPDFPhiBiasH(biasn2) - IPDFPhiBiasH(biasn2 - 1);
    521       G4double xaxisl = IPDFPhiBiasH.GetLowEdgeEnergy(size_t(biasn2-1));
    522       G4double xaxisu = IPDFPhiBiasH.GetLowEdgeEnergy(size_t(biasn2));
    523       G4double NatProb = xaxisu - xaxisl;
    524       bweights[4] = NatProb/bweights[4];
    525       if(verbosityLevel >= 1)
    526         G4cout << "Phi bin weight " << bweights[4] << " " << rndm << G4endl;
    527       return(IPDFPhiBiasH.GetEnergy(rndm));
    528     }
    529 }
    530 
    531 G4double G4SPSRandomGenerator::GenRandEnergy()
    532 {
    533   if(verbosityLevel >= 1)
    534     G4cout << "In GenRandEnergy" << G4endl;
    535   if(EnergyBias == false)
    536     {
    537       // Energy is not biased
    538       G4double rndm = G4UniformRand();
    539       return(rndm);
    540     }
    541   else {
    542     // ENERGY is biased
    543     if(IPDFEnergyBias == false) {
    544       // IPDF has not been created, so create it
    545       G4double bins[1024],vals[1024], sum;
    546       G4int ii;
    547       G4int maxbin = G4int(EnergyBiasH.GetVectorLength());
    548       bins[0] = EnergyBiasH.GetLowEdgeEnergy(size_t(0));
    549       vals[0] = EnergyBiasH(size_t(0));
    550       sum = vals[0];
    551       for(ii=1;ii<maxbin;ii++) {
    552         bins[ii] = EnergyBiasH.GetLowEdgeEnergy(size_t(ii));
    553         vals[ii] = EnergyBiasH(size_t(ii)) + vals[ii-1];
    554         sum = sum + EnergyBiasH(size_t(ii));
    555       }
    556      
    557       for(ii=0;ii<maxbin;ii++) {
    558         vals[ii] = vals[ii]/sum;
    559         IPDFEnergyBiasH.InsertValues(bins[ii], vals[ii]);
    560       }
    561       // Make IPDFEnergyBias = true
    562       IPDFEnergyBias = true;
    563     }
    564     // IPDF has been create so carry on
    565     G4double rndm = G4UniformRand();
    566     //  size_t weight_bin_no = IPDFEnergyBiasH.FindValueBinLocation(rndm);
    567     size_t numberOfBin = IPDFEnergyBiasH.GetVectorLength();
    568     G4int biasn1 = 0;
    569     G4int biasn2 = numberOfBin/2;
    570     G4int biasn3 = numberOfBin - 1;
    571     while (biasn1 != biasn3 - 1) {
    572       if (rndm > IPDFEnergyBiasH(biasn2))
    573         biasn1 = biasn2;
    574       else
    575         biasn3 = biasn2;
    576       biasn2 = biasn1 + (biasn3 - biasn1 + 1)/2;
    577     }
    578     bweights[5] =  IPDFEnergyBiasH(biasn2) - IPDFEnergyBiasH(biasn2 - 1);
    579     G4double xaxisl = IPDFEnergyBiasH.GetLowEdgeEnergy(size_t(biasn2-1));
    580     G4double xaxisu = IPDFEnergyBiasH.GetLowEdgeEnergy(size_t(biasn2));
    581     G4double NatProb = xaxisu - xaxisl;
    582     bweights[5] = NatProb/bweights[5];
    583     if(verbosityLevel >= 1)
    584       G4cout << "Energy bin weight " << bweights[5] << " " << rndm << G4endl;
    585     return(IPDFEnergyBiasH.GetEnergy(rndm));
    586   }
    587 }
    588 
    589 
    590 G4double G4SPSRandomGenerator::GenRandPosTheta()
    591 {
    592   if(verbosityLevel >= 1)
    593     {
    594       G4cout << "In GenRandPosTheta" << G4endl;
    595       G4cout << "Verbosity " << verbosityLevel << G4endl;
    596     }
    597   if(PosThetaBias == false)
    598     {
    599       // Theta is not biased
    600       G4double rndm = G4UniformRand();
    601       return(rndm);
    602     }
    603   else
    604     {
    605       // Theta is biased
    606       if(IPDFPosThetaBias == false)
    607         {
    608           // IPDF has not been created, so create it
    609           G4double bins[1024],vals[1024], sum;
    610           G4int ii;
    611           G4int maxbin = G4int(PosThetaBiasH.GetVectorLength());
    612           bins[0] = PosThetaBiasH.GetLowEdgeEnergy(size_t(0));
    613           vals[0] = PosThetaBiasH(size_t(0));
    614           sum = vals[0];
    615           for(ii=1;ii<maxbin;ii++)
    616             {
    617               bins[ii] = PosThetaBiasH.GetLowEdgeEnergy(size_t(ii));
    618               vals[ii] = PosThetaBiasH(size_t(ii)) + vals[ii-1];
    619               sum = sum + PosThetaBiasH(size_t(ii));
    620             }
    621 
    622           for(ii=0;ii<maxbin;ii++)
    623             {
    624               vals[ii] = vals[ii]/sum;
    625               IPDFPosThetaBiasH.InsertValues(bins[ii], vals[ii]);
    626             }
    627           // Make IPDFThetaBias = true
    628           IPDFPosThetaBias = true;
    629         }
    630       // IPDF has been create so carry on
    631       G4double rndm = G4UniformRand();
    632       //      size_t weight_bin_no = IPDFThetaBiasH.FindValueBinLocation(rndm);
    633       size_t numberOfBin = IPDFPosThetaBiasH.GetVectorLength();
    634       G4int biasn1 = 0;
    635       G4int biasn2 = numberOfBin/2;
    636       G4int biasn3 = numberOfBin - 1;
    637       while (biasn1 != biasn3 - 1) {
    638       if (rndm > IPDFPosThetaBiasH(biasn2))
    639          biasn1 = biasn2;
    640       else
    641          biasn3 = biasn2;
    642       biasn2 = biasn1 + (biasn3 - biasn1 + 1)/2;
    643       }
    644       bweights[6] =  IPDFPosThetaBiasH(biasn2) - IPDFPosThetaBiasH(biasn2 - 1);
    645       G4double xaxisl = IPDFPosThetaBiasH.GetLowEdgeEnergy(size_t(biasn2-1));
    646       G4double xaxisu = IPDFPosThetaBiasH.GetLowEdgeEnergy(size_t(biasn2));
    647       G4double NatProb = xaxisu - xaxisl;
    648       bweights[6] = NatProb/bweights[6];
    649       if(verbosityLevel >= 1)
    650         G4cout << "PosTheta bin weight " << bweights[6] << " " << rndm << G4endl;
    651       return(IPDFPosThetaBiasH.GetEnergy(rndm));
    652     }
    653 }
    654 
    655 G4double G4SPSRandomGenerator::GenRandPosPhi()
    656 {
    657   if(verbosityLevel >= 1)
    658     G4cout << "In GenRandPosPhi" << G4endl;
    659   if(PosPhiBias == false)
    660     {
    661       // PosPhi is not biased
    662       G4double rndm = G4UniformRand();
    663       return(rndm);
    664     }
    665   else
    666     {
    667       // PosPhi is biased
    668       if(IPDFPosPhiBias == false)
    669         {
    670           // IPDF has not been created, so create it
    671           G4double bins[1024],vals[1024], sum;
    672           G4int ii;
    673           G4int maxbin = G4int(PosPhiBiasH.GetVectorLength());
    674           bins[0] = PosPhiBiasH.GetLowEdgeEnergy(size_t(0));
    675           vals[0] = PosPhiBiasH(size_t(0));
    676           sum = vals[0];
    677           for(ii=1;ii<maxbin;ii++)
    678             {
    679               bins[ii] = PosPhiBiasH.GetLowEdgeEnergy(size_t(ii));
    680               vals[ii] = PosPhiBiasH(size_t(ii)) + vals[ii-1];
    681               sum = sum + PosPhiBiasH(size_t(ii));
    682             }
    683 
    684           for(ii=0;ii<maxbin;ii++)
    685             {
    686               vals[ii] = vals[ii]/sum;
    687               IPDFPosPhiBiasH.InsertValues(bins[ii], vals[ii]);
    688             }
    689           // Make IPDFPosPhiBias = true
    690           IPDFPosPhiBias = true;
    691         }
    692       // IPDF has been create so carry on
    693       G4double rndm = G4UniformRand();
    694       //      size_t weight_bin_no = IPDFPosPhiBiasH.FindValueBinLocation(rndm);
    695       size_t numberOfBin = IPDFPosPhiBiasH.GetVectorLength();
    696       G4int biasn1 = 0;
    697       G4int biasn2 = numberOfBin/2;
    698       G4int biasn3 = numberOfBin - 1;
    699       while (biasn1 != biasn3 - 1) {
    700       if (rndm > IPDFPosPhiBiasH(biasn2))
    701          biasn1 = biasn2;
    702       else
    703          biasn3 = biasn2;
    704       biasn2 = biasn1 + (biasn3 - biasn1 + 1)/2;
    705       }
    706       bweights[7] =  IPDFPosPhiBiasH(biasn2) - IPDFPosPhiBiasH(biasn2 - 1);
    707       G4double xaxisl = IPDFPosPhiBiasH.GetLowEdgeEnergy(size_t(biasn2-1));
    708       G4double xaxisu = IPDFPosPhiBiasH.GetLowEdgeEnergy(size_t(biasn2));
    709       G4double NatProb = xaxisu - xaxisl;
    710       bweights[7] = NatProb/bweights[7];
    711       if(verbosityLevel >= 1)
    712         G4cout << "PosPhi bin weight " << bweights[7] << " " << rndm << G4endl;
    713       return(IPDFPosPhiBiasH.GetEnergy(rndm));
    714     }
    715 }
    716 
    717 
    718 
    719 
    720 
     101void G4SPSRandomGenerator::SetXBias(G4ThreeVector input) {
     102        G4double ehi, val;
     103        ehi = input.x();
     104        val = input.y();
     105        XBiasH.InsertValues(ehi, val);
     106        XBias = true;
     107}
     108
     109void G4SPSRandomGenerator::SetYBias(G4ThreeVector input) {
     110        G4double ehi, val;
     111        ehi = input.x();
     112        val = input.y();
     113        YBiasH.InsertValues(ehi, val);
     114        YBias = true;
     115}
     116
     117void G4SPSRandomGenerator::SetZBias(G4ThreeVector input) {
     118        G4double ehi, val;
     119        ehi = input.x();
     120        val = input.y();
     121        ZBiasH.InsertValues(ehi, val);
     122        ZBias = true;
     123}
     124
     125void G4SPSRandomGenerator::SetThetaBias(G4ThreeVector input) {
     126        G4double ehi, val;
     127        ehi = input.x();
     128        val = input.y();
     129        ThetaBiasH.InsertValues(ehi, val);
     130        ThetaBias = true;
     131}
     132
     133void G4SPSRandomGenerator::SetPhiBias(G4ThreeVector input) {
     134        G4double ehi, val;
     135        ehi = input.x();
     136        val = input.y();
     137        PhiBiasH.InsertValues(ehi, val);
     138        PhiBias = true;
     139}
     140
     141void G4SPSRandomGenerator::SetEnergyBias(G4ThreeVector input) {
     142        G4double ehi, val;
     143        ehi = input.x();
     144        val = input.y();
     145        EnergyBiasH.InsertValues(ehi, val);
     146        EnergyBias = true;
     147}
     148
     149void G4SPSRandomGenerator::SetPosThetaBias(G4ThreeVector input) {
     150        G4double ehi, val;
     151        ehi = input.x();
     152        val = input.y();
     153        PosThetaBiasH.InsertValues(ehi, val);
     154        PosThetaBias = true;
     155}
     156
     157void G4SPSRandomGenerator::SetPosPhiBias(G4ThreeVector input) {
     158        G4double ehi, val;
     159        ehi = input.x();
     160        val = input.y();
     161        PosPhiBiasH.InsertValues(ehi, val);
     162        PosPhiBias = true;
     163}
     164
     165void G4SPSRandomGenerator::ReSetHist(G4String atype) {
     166        if (atype == "biasx") {
     167                XBias = false;
     168                IPDFXBias = false;
     169                XBiasH = IPDFXBiasH = ZeroPhysVector;
     170        } else if (atype == "biasy") {
     171                YBias = false;
     172                IPDFYBias = false;
     173                YBiasH = IPDFYBiasH = ZeroPhysVector;
     174        } else if (atype == "biasz") {
     175                ZBias = false;
     176                IPDFZBias = false;
     177                ZBiasH = IPDFZBiasH = ZeroPhysVector;
     178        } else if (atype == "biast") {
     179                ThetaBias = false;
     180                IPDFThetaBias = false;
     181                ThetaBiasH = IPDFThetaBiasH = ZeroPhysVector;
     182        } else if (atype == "biasp") {
     183                PhiBias = false;
     184                IPDFPhiBias = false;
     185                PhiBiasH = IPDFPhiBiasH = ZeroPhysVector;
     186        } else if (atype == "biase") {
     187                EnergyBias = false;
     188                IPDFEnergyBias = false;
     189                EnergyBiasH = IPDFEnergyBiasH = ZeroPhysVector;
     190        } else if (atype == "biaspt") {
     191                PosThetaBias = false;
     192                IPDFPosThetaBias = false;
     193                PosThetaBiasH = IPDFPosThetaBiasH = ZeroPhysVector;
     194        } else if (atype == "biaspp") {
     195                PosPhiBias = false;
     196                IPDFPosPhiBias = false;
     197                PosPhiBiasH = IPDFPosPhiBiasH = ZeroPhysVector;
     198        } else {
     199                G4cout << "Error, histtype not accepted " << G4endl;
     200        }
     201}
     202
     203G4double G4SPSRandomGenerator::GenRandX() {
     204        if (verbosityLevel >= 1)
     205                G4cout << "In GenRandX" << G4endl;
     206        if (XBias == false) {
     207                // X is not biased
     208                G4double rndm = G4UniformRand();
     209                return (rndm);
     210        } else {
     211                // X is biased
     212                if (IPDFXBias == false) {
     213                        // IPDF has not been created, so create it
     214                        G4double bins[1024], vals[1024], sum;
     215                        G4int ii;
     216                        G4int maxbin = G4int(XBiasH.GetVectorLength());
     217                        bins[0] = XBiasH.GetLowEdgeEnergy(size_t(0));
     218                        vals[0] = XBiasH(size_t(0));
     219                        sum = vals[0];
     220                        for (ii = 1; ii < maxbin; ii++) {
     221                                bins[ii] = XBiasH.GetLowEdgeEnergy(size_t(ii));
     222                                vals[ii] = XBiasH(size_t(ii)) + vals[ii - 1];
     223                                sum = sum + XBiasH(size_t(ii));
     224                        }
     225
     226                        for (ii = 0; ii < maxbin; ii++) {
     227                                vals[ii] = vals[ii] / sum;
     228                                IPDFXBiasH.InsertValues(bins[ii], vals[ii]);
     229                        }
     230                        // Make IPDFXBias = true
     231                        IPDFXBias = true;
     232                }
     233                // IPDF has been create so carry on
     234                G4double rndm = G4UniformRand();
     235
     236                // Calculate the weighting: Find the bin that the determined
     237                // rndm is in and the weigthing will be the difference in the
     238                // natural probability (from the x-axis) divided by the
     239                // difference in the biased probability (the area).
     240                size_t numberOfBin = IPDFXBiasH.GetVectorLength();
     241                G4int biasn1 = 0;
     242                G4int biasn2 = numberOfBin / 2;
     243                G4int biasn3 = numberOfBin - 1;
     244                while (biasn1 != biasn3 - 1) {
     245                        if (rndm > IPDFXBiasH(biasn2))
     246                                biasn1 = biasn2;
     247                        else
     248                                biasn3 = biasn2;
     249                        biasn2 = biasn1 + (biasn3 - biasn1 + 1) / 2;
     250                }
     251                // retrieve the areas and then the x-axis values
     252                bweights[0] = IPDFXBiasH(biasn2) - IPDFXBiasH(biasn2 - 1);
     253                G4double xaxisl = IPDFXBiasH.GetLowEdgeEnergy(size_t(biasn2 - 1));
     254                G4double xaxisu = IPDFXBiasH.GetLowEdgeEnergy(size_t(biasn2));
     255                G4double NatProb = xaxisu - xaxisl;
     256                //G4cout << "X Bin weight " << bweights[0] << " " << rndm << G4endl;
     257                //G4cout << "lower and upper xaxis vals "<<xaxisl<<" "<<xaxisu<<G4endl;
     258                bweights[0] = NatProb / bweights[0];
     259                if (verbosityLevel >= 1)
     260                        G4cout << "X bin weight " << bweights[0] << " " << rndm << G4endl;
     261                return (IPDFXBiasH.GetEnergy(rndm));
     262        }
     263}
     264
     265G4double G4SPSRandomGenerator::GenRandY() {
     266        if (verbosityLevel >= 1)
     267                G4cout << "In GenRandY" << G4endl;
     268        if (YBias == false) {
     269                // Y is not biased
     270                G4double rndm = G4UniformRand();
     271                return (rndm);
     272        } else {
     273                // Y is biased
     274                if (IPDFYBias == false) {
     275                        // IPDF has not been created, so create it
     276                        G4double bins[1024], vals[1024], sum;
     277                        G4int ii;
     278                        G4int maxbin = G4int(YBiasH.GetVectorLength());
     279                        bins[0] = YBiasH.GetLowEdgeEnergy(size_t(0));
     280                        vals[0] = YBiasH(size_t(0));
     281                        sum = vals[0];
     282                        for (ii = 1; ii < maxbin; ii++) {
     283                                bins[ii] = YBiasH.GetLowEdgeEnergy(size_t(ii));
     284                                vals[ii] = YBiasH(size_t(ii)) + vals[ii - 1];
     285                                sum = sum + YBiasH(size_t(ii));
     286                        }
     287
     288                        for (ii = 0; ii < maxbin; ii++) {
     289                                vals[ii] = vals[ii] / sum;
     290                                IPDFYBiasH.InsertValues(bins[ii], vals[ii]);
     291                        }
     292                        // Make IPDFYBias = true
     293                        IPDFYBias = true;
     294                }
     295                // IPDF has been create so carry on
     296                G4double rndm = G4UniformRand();
     297                size_t numberOfBin = IPDFYBiasH.GetVectorLength();
     298                G4int biasn1 = 0;
     299                G4int biasn2 = numberOfBin / 2;
     300                G4int biasn3 = numberOfBin - 1;
     301                while (biasn1 != biasn3 - 1) {
     302                        if (rndm > IPDFYBiasH(biasn2))
     303                                biasn1 = biasn2;
     304                        else
     305                                biasn3 = biasn2;
     306                        biasn2 = biasn1 + (biasn3 - biasn1 + 1) / 2;
     307                }
     308                bweights[1] = IPDFYBiasH(biasn2) - IPDFYBiasH(biasn2 - 1);
     309                G4double xaxisl = IPDFYBiasH.GetLowEdgeEnergy(size_t(biasn2 - 1));
     310                G4double xaxisu = IPDFYBiasH.GetLowEdgeEnergy(size_t(biasn2));
     311                G4double NatProb = xaxisu - xaxisl;
     312                bweights[1] = NatProb / bweights[1];
     313                if (verbosityLevel >= 1)
     314                        G4cout << "Y bin weight " << bweights[1] << " " << rndm << G4endl;
     315                return (IPDFYBiasH.GetEnergy(rndm));
     316        }
     317}
     318
     319G4double G4SPSRandomGenerator::GenRandZ() {
     320        if (verbosityLevel >= 1)
     321                G4cout << "In GenRandZ" << G4endl;
     322        if (ZBias == false) {
     323                // Z is not biased
     324                G4double rndm = G4UniformRand();
     325                return (rndm);
     326        } else {
     327                // Z is biased
     328                if (IPDFZBias == false) {
     329                        // IPDF has not been created, so create it
     330                        G4double bins[1024], vals[1024], sum;
     331                        G4int ii;
     332                        G4int maxbin = G4int(ZBiasH.GetVectorLength());
     333                        bins[0] = ZBiasH.GetLowEdgeEnergy(size_t(0));
     334                        vals[0] = ZBiasH(size_t(0));
     335                        sum = vals[0];
     336                        for (ii = 1; ii < maxbin; ii++) {
     337                                bins[ii] = ZBiasH.GetLowEdgeEnergy(size_t(ii));
     338                                vals[ii] = ZBiasH(size_t(ii)) + vals[ii - 1];
     339                                sum = sum + ZBiasH(size_t(ii));
     340                        }
     341
     342                        for (ii = 0; ii < maxbin; ii++) {
     343                                vals[ii] = vals[ii] / sum;
     344                                IPDFZBiasH.InsertValues(bins[ii], vals[ii]);
     345                        }
     346                        // Make IPDFZBias = true
     347                        IPDFZBias = true;
     348                }
     349                // IPDF has been create so carry on
     350                G4double rndm = G4UniformRand();
     351                //      size_t weight_bin_no = IPDFZBiasH.FindValueBinLocation(rndm);
     352                size_t numberOfBin = IPDFZBiasH.GetVectorLength();
     353                G4int biasn1 = 0;
     354                G4int biasn2 = numberOfBin / 2;
     355                G4int biasn3 = numberOfBin - 1;
     356                while (biasn1 != biasn3 - 1) {
     357                        if (rndm > IPDFZBiasH(biasn2))
     358                                biasn1 = biasn2;
     359                        else
     360                                biasn3 = biasn2;
     361                        biasn2 = biasn1 + (biasn3 - biasn1 + 1) / 2;
     362                }
     363                bweights[2] = IPDFZBiasH(biasn2) - IPDFZBiasH(biasn2 - 1);
     364                G4double xaxisl = IPDFZBiasH.GetLowEdgeEnergy(size_t(biasn2 - 1));
     365                G4double xaxisu = IPDFZBiasH.GetLowEdgeEnergy(size_t(biasn2));
     366                G4double NatProb = xaxisu - xaxisl;
     367                bweights[2] = NatProb / bweights[2];
     368                if (verbosityLevel >= 1)
     369                        G4cout << "Z bin weight " << bweights[2] << " " << rndm << G4endl;
     370                return (IPDFZBiasH.GetEnergy(rndm));
     371        }
     372}
     373
     374G4double G4SPSRandomGenerator::GenRandTheta() {
     375        if (verbosityLevel >= 1) {
     376                G4cout << "In GenRandTheta" << G4endl;
     377                G4cout << "Verbosity " << verbosityLevel << G4endl;
     378        }
     379        if (ThetaBias == false) {
     380                // Theta is not biased
     381                G4double rndm = G4UniformRand();
     382                return (rndm);
     383        } else {
     384                // Theta is biased
     385                if (IPDFThetaBias == false) {
     386                        // IPDF has not been created, so create it
     387                        G4double bins[1024], vals[1024], sum;
     388                        G4int ii;
     389                        G4int maxbin = G4int(ThetaBiasH.GetVectorLength());
     390                        bins[0] = ThetaBiasH.GetLowEdgeEnergy(size_t(0));
     391                        vals[0] = ThetaBiasH(size_t(0));
     392                        sum = vals[0];
     393                        for (ii = 1; ii < maxbin; ii++) {
     394                                bins[ii] = ThetaBiasH.GetLowEdgeEnergy(size_t(ii));
     395                                vals[ii] = ThetaBiasH(size_t(ii)) + vals[ii - 1];
     396                                sum = sum + ThetaBiasH(size_t(ii));
     397                        }
     398
     399                        for (ii = 0; ii < maxbin; ii++) {
     400                                vals[ii] = vals[ii] / sum;
     401                                IPDFThetaBiasH.InsertValues(bins[ii], vals[ii]);
     402                        }
     403                        // Make IPDFThetaBias = true
     404                        IPDFThetaBias = true;
     405                }
     406                // IPDF has been create so carry on
     407                G4double rndm = G4UniformRand();
     408                //      size_t weight_bin_no = IPDFThetaBiasH.FindValueBinLocation(rndm);
     409                size_t numberOfBin = IPDFThetaBiasH.GetVectorLength();
     410                G4int biasn1 = 0;
     411                G4int biasn2 = numberOfBin / 2;
     412                G4int biasn3 = numberOfBin - 1;
     413                while (biasn1 != biasn3 - 1) {
     414                        if (rndm > IPDFThetaBiasH(biasn2))
     415                                biasn1 = biasn2;
     416                        else
     417                                biasn3 = biasn2;
     418                        biasn2 = biasn1 + (biasn3 - biasn1 + 1) / 2;
     419                }
     420                bweights[3] = IPDFThetaBiasH(biasn2) - IPDFThetaBiasH(biasn2 - 1);
     421                G4double xaxisl = IPDFThetaBiasH.GetLowEdgeEnergy(size_t(biasn2 - 1));
     422                G4double xaxisu = IPDFThetaBiasH.GetLowEdgeEnergy(size_t(biasn2));
     423                G4double NatProb = xaxisu - xaxisl;
     424                bweights[3] = NatProb / bweights[3];
     425                if (verbosityLevel >= 1)
     426                        G4cout << "Theta bin weight " << bweights[3] << " " << rndm
     427                                        << G4endl;
     428                return (IPDFThetaBiasH.GetEnergy(rndm));
     429        }
     430}
     431
     432G4double G4SPSRandomGenerator::GenRandPhi() {
     433        if (verbosityLevel >= 1)
     434                G4cout << "In GenRandPhi" << G4endl;
     435        if (PhiBias == false) {
     436                // Phi is not biased
     437                G4double rndm = G4UniformRand();
     438                return (rndm);
     439        } else {
     440                // Phi is biased
     441                if (IPDFPhiBias == false) {
     442                        // IPDF has not been created, so create it
     443                        G4double bins[1024], vals[1024], sum;
     444                        G4int ii;
     445                        G4int maxbin = G4int(PhiBiasH.GetVectorLength());
     446                        bins[0] = PhiBiasH.GetLowEdgeEnergy(size_t(0));
     447                        vals[0] = PhiBiasH(size_t(0));
     448                        sum = vals[0];
     449                        for (ii = 1; ii < maxbin; ii++) {
     450                                bins[ii] = PhiBiasH.GetLowEdgeEnergy(size_t(ii));
     451                                vals[ii] = PhiBiasH(size_t(ii)) + vals[ii - 1];
     452                                sum = sum + PhiBiasH(size_t(ii));
     453                        }
     454
     455                        for (ii = 0; ii < maxbin; ii++) {
     456                                vals[ii] = vals[ii] / sum;
     457                                IPDFPhiBiasH.InsertValues(bins[ii], vals[ii]);
     458                        }
     459                        // Make IPDFPhiBias = true
     460                        IPDFPhiBias = true;
     461                }
     462                // IPDF has been create so carry on
     463                G4double rndm = G4UniformRand();
     464                //      size_t weight_bin_no = IPDFPhiBiasH.FindValueBinLocation(rndm);
     465                size_t numberOfBin = IPDFPhiBiasH.GetVectorLength();
     466                G4int biasn1 = 0;
     467                G4int biasn2 = numberOfBin / 2;
     468                G4int biasn3 = numberOfBin - 1;
     469                while (biasn1 != biasn3 - 1) {
     470                        if (rndm > IPDFPhiBiasH(biasn2))
     471                                biasn1 = biasn2;
     472                        else
     473                                biasn3 = biasn2;
     474                        biasn2 = biasn1 + (biasn3 - biasn1 + 1) / 2;
     475                }
     476                bweights[4] = IPDFPhiBiasH(biasn2) - IPDFPhiBiasH(biasn2 - 1);
     477                G4double xaxisl = IPDFPhiBiasH.GetLowEdgeEnergy(size_t(biasn2 - 1));
     478                G4double xaxisu = IPDFPhiBiasH.GetLowEdgeEnergy(size_t(biasn2));
     479                G4double NatProb = xaxisu - xaxisl;
     480                bweights[4] = NatProb / bweights[4];
     481                if (verbosityLevel >= 1)
     482                        G4cout << "Phi bin weight " << bweights[4] << " " << rndm << G4endl;
     483                return (IPDFPhiBiasH.GetEnergy(rndm));
     484        }
     485}
     486
     487G4double G4SPSRandomGenerator::GenRandEnergy() {
     488        if (verbosityLevel >= 1)
     489                G4cout << "In GenRandEnergy" << G4endl;
     490        if (EnergyBias == false) {
     491                // Energy is not biased
     492                G4double rndm = G4UniformRand();
     493                return (rndm);
     494        } else {
     495                // ENERGY is biased
     496                if (IPDFEnergyBias == false) {
     497                        // IPDF has not been created, so create it
     498                        G4double bins[1024], vals[1024], sum;
     499                        G4int ii;
     500                        G4int maxbin = G4int(EnergyBiasH.GetVectorLength());
     501                        bins[0] = EnergyBiasH.GetLowEdgeEnergy(size_t(0));
     502                        vals[0] = EnergyBiasH(size_t(0));
     503                        sum = vals[0];
     504                        for (ii = 1; ii < maxbin; ii++) {
     505                                bins[ii] = EnergyBiasH.GetLowEdgeEnergy(size_t(ii));
     506                                vals[ii] = EnergyBiasH(size_t(ii)) + vals[ii - 1];
     507                                sum = sum + EnergyBiasH(size_t(ii));
     508                        }
     509                        IPDFEnergyBiasH = ZeroPhysVector;
     510                        for (ii = 0; ii < maxbin; ii++) {
     511                                vals[ii] = vals[ii] / sum;
     512                                IPDFEnergyBiasH.InsertValues(bins[ii], vals[ii]);
     513                        }
     514                        // Make IPDFEnergyBias = true
     515                        IPDFEnergyBias = true;
     516                }
     517                // IPDF has been create so carry on
     518                G4double rndm = G4UniformRand();
     519                //  size_t weight_bin_no = IPDFEnergyBiasH.FindValueBinLocation(rndm);
     520                size_t numberOfBin = IPDFEnergyBiasH.GetVectorLength();
     521                G4int biasn1 = 0;
     522                G4int biasn2 = numberOfBin / 2;
     523                G4int biasn3 = numberOfBin - 1;
     524                while (biasn1 != biasn3 - 1) {
     525                        if (rndm > IPDFEnergyBiasH(biasn2))
     526                                biasn1 = biasn2;
     527                        else
     528                                biasn3 = biasn2;
     529                        biasn2 = biasn1 + (biasn3 - biasn1 + 1) / 2;
     530                }
     531                bweights[5] = IPDFEnergyBiasH(biasn2) - IPDFEnergyBiasH(biasn2 - 1);
     532                G4double xaxisl = IPDFEnergyBiasH.GetLowEdgeEnergy(size_t(biasn2 - 1));
     533                G4double xaxisu = IPDFEnergyBiasH.GetLowEdgeEnergy(size_t(biasn2));
     534                G4double NatProb = xaxisu - xaxisl;
     535                bweights[5] = NatProb / bweights[5];
     536                if (verbosityLevel >= 1)
     537                        G4cout << "Energy bin weight " << bweights[5] << " " << rndm
     538                                        << G4endl;
     539                return (IPDFEnergyBiasH.GetEnergy(rndm));
     540        }
     541}
     542
     543G4double G4SPSRandomGenerator::GenRandPosTheta() {
     544        if (verbosityLevel >= 1) {
     545                G4cout << "In GenRandPosTheta" << G4endl;
     546                G4cout << "Verbosity " << verbosityLevel << G4endl;
     547        }
     548        if (PosThetaBias == false) {
     549                // Theta is not biased
     550                G4double rndm = G4UniformRand();
     551                return (rndm);
     552        } else {
     553                // Theta is biased
     554                if (IPDFPosThetaBias == false) {
     555                        // IPDF has not been created, so create it
     556                        G4double bins[1024], vals[1024], sum;
     557                        G4int ii;
     558                        G4int maxbin = G4int(PosThetaBiasH.GetVectorLength());
     559                        bins[0] = PosThetaBiasH.GetLowEdgeEnergy(size_t(0));
     560                        vals[0] = PosThetaBiasH(size_t(0));
     561                        sum = vals[0];
     562                        for (ii = 1; ii < maxbin; ii++) {
     563                                bins[ii] = PosThetaBiasH.GetLowEdgeEnergy(size_t(ii));
     564                                vals[ii] = PosThetaBiasH(size_t(ii)) + vals[ii - 1];
     565                                sum = sum + PosThetaBiasH(size_t(ii));
     566                        }
     567
     568                        for (ii = 0; ii < maxbin; ii++) {
     569                                vals[ii] = vals[ii] / sum;
     570                                IPDFPosThetaBiasH.InsertValues(bins[ii], vals[ii]);
     571                        }
     572                        // Make IPDFThetaBias = true
     573                        IPDFPosThetaBias = true;
     574                }
     575                // IPDF has been create so carry on
     576                G4double rndm = G4UniformRand();
     577                //      size_t weight_bin_no = IPDFThetaBiasH.FindValueBinLocation(rndm);
     578                size_t numberOfBin = IPDFPosThetaBiasH.GetVectorLength();
     579                G4int biasn1 = 0;
     580                G4int biasn2 = numberOfBin / 2;
     581                G4int biasn3 = numberOfBin - 1;
     582                while (biasn1 != biasn3 - 1) {
     583                        if (rndm > IPDFPosThetaBiasH(biasn2))
     584                                biasn1 = biasn2;
     585                        else
     586                                biasn3 = biasn2;
     587                        biasn2 = biasn1 + (biasn3 - biasn1 + 1) / 2;
     588                }
     589                bweights[6] = IPDFPosThetaBiasH(biasn2) - IPDFPosThetaBiasH(biasn2 - 1);
     590                G4double xaxisl =
     591                                IPDFPosThetaBiasH.GetLowEdgeEnergy(size_t(biasn2 - 1));
     592                G4double xaxisu = IPDFPosThetaBiasH.GetLowEdgeEnergy(size_t(biasn2));
     593                G4double NatProb = xaxisu - xaxisl;
     594                bweights[6] = NatProb / bweights[6];
     595                if (verbosityLevel >= 1)
     596                        G4cout << "PosTheta bin weight " << bweights[6] << " " << rndm
     597                                        << G4endl;
     598                return (IPDFPosThetaBiasH.GetEnergy(rndm));
     599        }
     600}
     601
     602G4double G4SPSRandomGenerator::GenRandPosPhi() {
     603        if (verbosityLevel >= 1)
     604                G4cout << "In GenRandPosPhi" << G4endl;
     605        if (PosPhiBias == false) {
     606                // PosPhi is not biased
     607                G4double rndm = G4UniformRand();
     608                return (rndm);
     609        } else {
     610                // PosPhi is biased
     611                if (IPDFPosPhiBias == false) {
     612                        // IPDF has not been created, so create it
     613                        G4double bins[1024], vals[1024], sum;
     614                        G4int ii;
     615                        G4int maxbin = G4int(PosPhiBiasH.GetVectorLength());
     616                        bins[0] = PosPhiBiasH.GetLowEdgeEnergy(size_t(0));
     617                        vals[0] = PosPhiBiasH(size_t(0));
     618                        sum = vals[0];
     619                        for (ii = 1; ii < maxbin; ii++) {
     620                                bins[ii] = PosPhiBiasH.GetLowEdgeEnergy(size_t(ii));
     621                                vals[ii] = PosPhiBiasH(size_t(ii)) + vals[ii - 1];
     622                                sum = sum + PosPhiBiasH(size_t(ii));
     623                        }
     624
     625                        for (ii = 0; ii < maxbin; ii++) {
     626                                vals[ii] = vals[ii] / sum;
     627                                IPDFPosPhiBiasH.InsertValues(bins[ii], vals[ii]);
     628                        }
     629                        // Make IPDFPosPhiBias = true
     630                        IPDFPosPhiBias = true;
     631                }
     632                // IPDF has been create so carry on
     633                G4double rndm = G4UniformRand();
     634                //      size_t weight_bin_no = IPDFPosPhiBiasH.FindValueBinLocation(rndm);
     635                size_t numberOfBin = IPDFPosPhiBiasH.GetVectorLength();
     636                G4int biasn1 = 0;
     637                G4int biasn2 = numberOfBin / 2;
     638                G4int biasn3 = numberOfBin - 1;
     639                while (biasn1 != biasn3 - 1) {
     640                        if (rndm > IPDFPosPhiBiasH(biasn2))
     641                                biasn1 = biasn2;
     642                        else
     643                                biasn3 = biasn2;
     644                        biasn2 = biasn1 + (biasn3 - biasn1 + 1) / 2;
     645                }
     646                bweights[7] = IPDFPosPhiBiasH(biasn2) - IPDFPosPhiBiasH(biasn2 - 1);
     647                G4double xaxisl = IPDFPosPhiBiasH.GetLowEdgeEnergy(size_t(biasn2 - 1));
     648                G4double xaxisu = IPDFPosPhiBiasH.GetLowEdgeEnergy(size_t(biasn2));
     649                G4double NatProb = xaxisu - xaxisl;
     650                bweights[7] = NatProb / bweights[7];
     651                if (verbosityLevel >= 1)
     652                        G4cout << "PosPhi bin weight " << bweights[7] << " " << rndm
     653                                        << G4endl;
     654                return (IPDFPosPhiBiasH.GetEnergy(rndm));
     655        }
     656}
     657
  • trunk/source/event/src/G4SingleParticleSource.cc

    r816 r1347  
    5858#include "G4SingleParticleSource.hh"
    5959
    60 G4SingleParticleSource::G4SingleParticleSource()
    61 {
    62   // Initialise all variables
    63   // Position distribution Variables
     60G4SingleParticleSource::G4SingleParticleSource() {
     61        // Initialise all variables
     62        // Position distribution Variables
    6463
    65   NumberOfParticlesToBeGenerated = 1;
    66   particle_definition = G4Geantino::GeantinoDefinition();
    67   G4ThreeVector zero;
    68   particle_momentum_direction = G4ParticleMomentum(1,0,0);
    69   particle_energy = 1.0*MeV;
    70   particle_position = zero;
    71   particle_time = 0.0;
    72   particle_polarization = zero;
    73   particle_charge = 0.0;
    74   particle_weight = 1.0;
     64        NumberOfParticlesToBeGenerated = 1;
     65        particle_definition = G4Geantino::GeantinoDefinition();
     66        G4ThreeVector zero;
     67        particle_momentum_direction = G4ParticleMomentum(1, 0, 0);
     68        particle_energy = 1.0 * MeV;
     69        particle_position = zero;
     70        particle_time = 0.0;
     71        particle_polarization = zero;
     72        particle_charge = 0.0;
     73        particle_weight = 1.0;
    7574
    76   biasRndm = new G4SPSRandomGenerator();
    77   posGenerator = new G4SPSPosDistribution();
    78   posGenerator->SetBiasRndm(biasRndm);
    79   angGenerator = new G4SPSAngDistribution();
    80   angGenerator->SetPosDistribution(posGenerator);
    81   angGenerator->SetBiasRndm(biasRndm);
    82   eneGenerator = new G4SPSEneDistribution();
    83   eneGenerator->SetBiasRndm(biasRndm);
     75        biasRndm = new G4SPSRandomGenerator();
     76        posGenerator = new G4SPSPosDistribution();
     77        posGenerator->SetBiasRndm(biasRndm);
     78        angGenerator = new G4SPSAngDistribution();
     79        angGenerator->SetPosDistribution(posGenerator);
     80        angGenerator->SetBiasRndm(biasRndm);
     81        eneGenerator = new G4SPSEneDistribution();
     82        eneGenerator->SetBiasRndm(biasRndm);
    8483
    85   // verbosity
    86   verbosityLevel = 0;
     84        // verbosity
     85        verbosityLevel = 0;
    8786
    8887}
    8988
    90 G4SingleParticleSource::~G4SingleParticleSource()
    91 {}
    92 
    93 void G4SingleParticleSource::SetVerbosity(int vL)
    94 {
    95   verbosityLevel = vL;
    96   posGenerator->SetVerbosity(vL);
    97   angGenerator->SetVerbosity(vL);
    98   eneGenerator->SetVerbosity(vL);
    99   G4cout << "Verbosity Set to: " << verbosityLevel << G4endl;
     89G4SingleParticleSource::~G4SingleParticleSource() {
     90        delete biasRndm;
     91        delete posGenerator;
     92        delete angGenerator;
     93        delete eneGenerator;
    10094}
    10195
    102 void G4SingleParticleSource::SetParticleDefinition
    103   (G4ParticleDefinition* aParticleDefinition)
    104 {
    105   particle_definition = aParticleDefinition;
    106   particle_charge = particle_definition->GetPDGCharge();
     96void G4SingleParticleSource::SetVerbosity(int vL) {
     97        verbosityLevel = vL;
     98        posGenerator->SetVerbosity(vL);
     99        angGenerator->SetVerbosity(vL);
     100        eneGenerator->SetVerbosity(vL);
     101        G4cout << "Verbosity Set to: " << verbosityLevel << G4endl;
    107102}
    108103
    109 void G4SingleParticleSource::GeneratePrimaryVertex(G4Event *evt)
    110 {
    111   if(particle_definition==NULL) return;
    112 
    113   if(verbosityLevel > 1)
    114     G4cout << " NumberOfParticlesToBeGenerated: "<<NumberOfParticlesToBeGenerated << G4endl;
    115 
    116   // Position stuff
    117   particle_position = posGenerator->GenerateOne();
    118 
    119   // create a new vertex
    120   G4PrimaryVertex* vertex = new G4PrimaryVertex(particle_position,particle_time);
    121 
    122   for( G4int i=0; i<NumberOfParticlesToBeGenerated; i++ ) {
    123     // Angular stuff
    124     particle_momentum_direction = angGenerator->GenerateOne();
    125     // Energy stuff
    126     particle_energy = eneGenerator->GenerateOne(particle_definition);
    127    
    128     if(verbosityLevel >= 2)
    129       G4cout << "Creating primaries and assigning to vertex" << G4endl;
    130     // create new primaries and set them to the vertex
    131     G4double mass =  particle_definition->GetPDGMass();
    132     G4double energy = particle_energy + mass;
    133     G4double pmom = std::sqrt(energy*energy-mass*mass);
    134     G4double px = pmom*particle_momentum_direction.x();
    135     G4double py = pmom*particle_momentum_direction.y();
    136     G4double pz = pmom*particle_momentum_direction.z();
    137 
    138     if(verbosityLevel > 1){
    139       G4cout << "Particle name: "<<particle_definition->GetParticleName() << G4endl;
    140       G4cout << "       Energy: "<<particle_energy << G4endl;
    141       G4cout << "     Position: "<<particle_position<< G4endl;
    142       G4cout << "    Direction: "<<particle_momentum_direction << G4endl;
    143     }
    144     G4PrimaryParticle* particle =
    145       new G4PrimaryParticle(particle_definition,px,py,pz);
    146     particle->SetMass( mass );
    147     particle->SetCharge( particle_charge );
    148     particle->SetPolarization(particle_polarization.x(),
    149                               particle_polarization.y(),
    150                               particle_polarization.z());
    151     // Set bweight equal to the multiple of all non-zero weights
    152     particle_weight = biasRndm->GetBiasWeight();
    153     // pass it to primary particle
    154     particle->SetWeight(particle_weight);
    155 
    156     vertex->SetPrimary( particle );
    157      
    158   }
    159   // now pass the weight to the primary vertex. CANNOT be used here!
    160   //  vertex->SetWeight(particle_weight);
    161   evt->AddPrimaryVertex( vertex );
    162   if(verbosityLevel > 1)
    163     G4cout << " Primary Vetex generated !"<< G4endl;   
     104void G4SingleParticleSource::SetParticleDefinition(
     105                G4ParticleDefinition* aParticleDefinition) {
     106        particle_definition = aParticleDefinition;
     107        particle_charge = particle_definition->GetPDGCharge();
    164108}
    165109
     110void G4SingleParticleSource::GeneratePrimaryVertex(G4Event *evt) {
     111        if (particle_definition == NULL)
     112                return;
    166113
     114        if (verbosityLevel > 1)
     115                G4cout << " NumberOfParticlesToBeGenerated: "
     116                                << NumberOfParticlesToBeGenerated << G4endl;
    167117
     118        // Position stuff
     119        particle_position = posGenerator->GenerateOne();
    168120
     121        // create a new vertex
     122        G4PrimaryVertex* vertex = new G4PrimaryVertex(particle_position,
     123                        particle_time);
    169124
     125        for (G4int i = 0; i < NumberOfParticlesToBeGenerated; i++) {
     126                // Angular stuff
     127                particle_momentum_direction = angGenerator->GenerateOne();
     128                // Energy stuff
     129                particle_energy = eneGenerator->GenerateOne(particle_definition);
    170130
     131                if (verbosityLevel >= 2)
     132                        G4cout << "Creating primaries and assigning to vertex" << G4endl;
     133                // create new primaries and set them to the vertex
     134                G4double mass = particle_definition->GetPDGMass();
     135                G4double energy = particle_energy + mass;
     136                G4double pmom = std::sqrt(energy * energy - mass * mass);
     137                G4double px = pmom * particle_momentum_direction.x();
     138                G4double py = pmom * particle_momentum_direction.y();
     139                G4double pz = pmom * particle_momentum_direction.z();
    171140
     141                if (verbosityLevel > 1) {
     142                        G4cout << "Particle name: "
     143                                        << particle_definition->GetParticleName() << G4endl;
     144                        G4cout << "       Energy: " << particle_energy << G4endl;
     145                        G4cout << "     Position: " << particle_position << G4endl;
     146                        G4cout << "    Direction: " << particle_momentum_direction
     147                                        << G4endl;
     148                }
     149                G4PrimaryParticle* particle = new G4PrimaryParticle(
     150                                particle_definition, px, py, pz);
     151                particle->SetMass(mass);
     152                particle->SetCharge(particle_charge);
     153                particle->SetPolarization(particle_polarization.x(),
     154                                particle_polarization.y(), particle_polarization.z());
     155                // Set bweight equal to the multiple of all non-zero weights
     156                particle_weight = eneGenerator->GetWeight()*biasRndm->GetBiasWeight();
     157                // pass it to primary particle
     158                particle->SetWeight(particle_weight);
    172159
     160                vertex->SetPrimary(particle);
    173161
     162        }
     163        // now pass the weight to the primary vertex. CANNOT be used here!
     164        //  vertex->SetWeight(particle_weight);
     165        evt->AddPrimaryVertex(vertex);
     166        if (verbosityLevel > 1)
     167                G4cout << " Primary Vetex generated !" << G4endl;
     168}
     169
Note: See TracChangeset for help on using the changeset viewer.