00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include "generators/MJGeneratorPNNLCascade.hh"
00013 #include "Randomize.hh"
00014 #include <math.h>
00015 #include <iostream.h>
00016 #include <fstream.h>
00017
00018 const G4int MJGeneratorPNNLCascade::kNUM_BETA_TABLE_ELEMENTS = 100;
00019 const G4int MJGeneratorPNNLCascade::kPARTICLE_INDEX_ALPHA = 0;
00020 const G4int MJGeneratorPNNLCascade::kPARTICLE_INDEX_BETA = 1;
00021 const G4int MJGeneratorPNNLCascade::kPARTICLE_INDEX_POSITRON = 2;
00022
00023 MJGeneratorPNNLCascade::
00024 MJGeneratorPNNLCascade(G4int particle_type,
00025 G4double A, G4double Z,
00026 G4double E_endpoint, G4int delta_L,
00027 G4int num_gammas, G4double* gamma_list) :
00028 fType(particle_type),
00029 fA(A), fZ(Z),
00030 fE_endpoint(E_endpoint), fDelta_L(delta_L),
00031 fNum_gammas(num_gammas)
00032
00033 {
00034 fGamma_list = NULL;
00035 f_pBetaEnergyGen = NULL;
00036 fE_alpha = 0.0;
00037
00038 if (fNum_gammas > 0) {
00039 fGamma_list = new G4double[fNum_gammas];
00040 for (G4int i=0; i<fNum_gammas; i++)
00041 fGamma_list[i] = gamma_list[i];
00042 }
00043
00044 if ((fType == kPARTICLE_INDEX_BETA) || (fType == kPARTICLE_INDEX_POSITRON)) {
00045
00046
00047
00048
00049
00050
00051 G4double* Beta_E_arr = new G4double[kNUM_BETA_TABLE_ELEMENTS];
00052 G4double* Beta_dist_arr = new G4double[kNUM_BETA_TABLE_ELEMENTS];
00053 G4double Z_setup = fabs(fZ);
00054
00055
00056 if (fType == kPARTICLE_INDEX_POSITRON)
00057 Z_setup *= -1.0;
00058
00059 Setup_beta_shape(fE_endpoint, Z_setup, fA, fDelta_L,
00060 kNUM_BETA_TABLE_ELEMENTS, Beta_E_arr, Beta_dist_arr);
00061
00062 f_pBetaEnergyGen = new MJGeneratorPNNLLookup(kNUM_BETA_TABLE_ELEMENTS,
00063 Beta_E_arr, Beta_dist_arr);
00064 delete [] Beta_E_arr;
00065 delete [] Beta_dist_arr;
00066 }
00067 else if (fType == kPARTICLE_INDEX_ALPHA) {
00068 fE_alpha = fE_endpoint;
00069 }
00070 else {
00071 cout << "ERROR in MJGeneratorPNNLCascade constructor: " << endl
00072 << "Unrecognized charged particle type: " << fType << endl
00073 << "Valid options are" << endl
00074 << "(0) alpha" << endl
00075 << "(1) beta-" << endl
00076 << "(2) beta+" << endl
00077 << "Aborting." << endl;
00078 exit(1);
00079 }
00080 }
00081
00083 MJGeneratorPNNLCascade::
00084 MJGeneratorPNNLCascade(const MJGeneratorPNNLCascade& Cascade)
00085 {
00086 fType = Cascade.fType;
00087 fA = Cascade.fA;
00088 fZ = Cascade.fZ;
00089 fDelta_L = Cascade.fDelta_L;
00090 fNum_gammas = Cascade.fNum_gammas;
00091
00092 fE_endpoint = 0.0;
00093 fE_alpha = 0.0;
00094
00095 fGamma_list = NULL;
00096 f_pBetaEnergyGen = NULL;
00097
00098 if (fNum_gammas > 0) {
00099 fGamma_list = new G4double[fNum_gammas];
00100 for (G4int i=0; i<fNum_gammas; i++)
00101 fGamma_list[i] = Cascade.fGamma_list[i];
00102 }
00103
00104 if ((fType == kPARTICLE_INDEX_BETA) || (fType == kPARTICLE_INDEX_POSITRON)) {
00105 fE_endpoint = Cascade.fE_endpoint;
00106 f_pBetaEnergyGen = new MJGeneratorPNNLLookup(*(Cascade.f_pBetaEnergyGen));
00107 }
00108 else {
00109 fE_alpha = fE_alpha;
00110 }
00111 }
00112
00114 void MJGeneratorPNNLCascade::
00115 operator=(const MJGeneratorPNNLCascade& Cascade)
00116 {
00117 fType = Cascade.fType;
00118 fA = Cascade.fA;
00119 fZ = Cascade.fZ;
00120 fDelta_L = Cascade.fDelta_L;
00121 fNum_gammas = Cascade.fNum_gammas;
00122
00123 fE_endpoint = 0.0;
00124 fE_alpha = 0.0;
00125
00126 fGamma_list = NULL;
00127 f_pBetaEnergyGen = NULL;
00128
00129 if (fNum_gammas > 0) {
00130 fGamma_list = new G4double[fNum_gammas];
00131 for (G4int i=0; i<fNum_gammas; i++)
00132 fGamma_list[i] = Cascade.fGamma_list[i];
00133 }
00134
00135 if ((fType == kPARTICLE_INDEX_BETA) || (fType == kPARTICLE_INDEX_POSITRON)) {
00136 fE_endpoint = Cascade.fE_endpoint;
00137 f_pBetaEnergyGen = new MJGeneratorPNNLLookup(*(Cascade.f_pBetaEnergyGen));
00138 }
00139 else {
00140 fE_alpha = fE_alpha;
00141 }
00142 }
00143
00145 MJGeneratorPNNLCascade::
00146 ~MJGeneratorPNNLCascade()
00147 {
00148 if (fGamma_list)
00149 delete [] fGamma_list;
00150 }
00151
00153 void MJGeneratorPNNLCascade::
00154 SetGammaList(G4int num_gammas, G4double* gamma_list)
00155 {
00156
00157 fNum_gammas = num_gammas;
00158
00159 if (fGamma_list)
00160 delete [] fGamma_list;
00161
00162 fGamma_list = new G4double[num_gammas];
00163 for (G4int i=0; i<num_gammas; i++)
00164 fGamma_list[i] = gamma_list[i];
00165 }
00166
00168 void MJGeneratorPNNLCascade::
00169 DoPrintCascade() const
00170 {
00171
00172 cout << "Particle Type: " << fType << endl
00173 << "Parent (A,Z): " << fA << " " << fZ << endl;
00174
00175 if (fType == kPARTICLE_INDEX_BETA)
00176 cout << "Beta- endpoint (MeV): " << fE_endpoint << endl
00177 << "Delta(L): " << fDelta_L << endl;
00178 else if (fType == kPARTICLE_INDEX_POSITRON)
00179 cout << "Beta+ endpoint (MeV): " << fE_endpoint << endl
00180 << "Delta(L): " << fDelta_L << endl;
00181 else
00182 cout << "Alpha energy (MeV): " << fE_endpoint << endl;
00183
00184 cout << "Number of gammas: " << fNum_gammas << endl;
00185 if (fNum_gammas > 0) {
00186 cout << "Gamma energy list: ";
00187
00188 for (G4int i=0; i<fNum_gammas; i++) {
00189 if (i == 0)
00190 cout << fGamma_list[i] << endl;
00191 else
00192 cout << " " << fGamma_list[i] << endl;
00193 }
00194 }
00195 }
00196
00198 G4double MJGeneratorPNNLCascade::
00199 DoSampleChargedParticleEnergy() const
00200 {
00201
00202 if (fType == kPARTICLE_INDEX_ALPHA)
00203 return fE_alpha;
00204 else
00205 return DoSampleBetaDist();
00206 }
00207
00209 G4double MJGeneratorPNNLCascade::
00210 DoSampleBetaDist() const
00211 {
00212
00213 G4double x = G4UniformRand();
00214 G4double E = f_pBetaEnergyGen->DoLookupInterp(x) * MeV;
00215
00216 return E;
00217 }
00218
00220 void MJGeneratorPNNLCascade::
00221 Setup_beta_shape(G4double Qval, G4double Z,
00222 G4double A, G4int IDL, G4int num_entries,
00223 G4double* E_arr, G4double* Beta_arr)
00224 {
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238 const G4double PI = 3.1415927;
00239 const G4double M_e = 0.511;
00240
00241 G4double ZD;
00242 G4double T0;
00243 G4double Estep;
00244 G4double T, UF;
00245 G4double Y, FERFAC;
00246 G4double tmp1, tmp2;
00247
00248 ZD = (Z+1.0)/137.0;
00249 T0 = Qval/M_e;
00250 Estep = Qval/(num_entries-1);
00251
00252 for (G4int i=0; i<num_entries; i++) {
00253 T = i * Estep/M_e;
00254 E_arr[i] = T * M_e;
00255
00256 if (IDL >= 0) {
00257 switch (IDL) {
00258 case 0:
00259 UF = 1.0;
00260 break;
00261 case 1:
00262 UF=T*(T+2.0) + pow(T0-T,2.0);
00263 break;
00264 case 2:
00265 UF= pow((T*(T+2)),2.0) + pow((T0-T),4.0) +
00266 (10.0/3.0)*T*(T+2)*pow((T0-T),2.0);
00267 break;
00268 case 3:
00269 UF = pow((T*(T+2.0)),3.0) + pow((T0-T),6.0);
00270 UF += 7.0*T*(T+2)*pow((T0-T),2.0)*(T*(T+2.0)+pow((T0-T),2.0));
00271 break;
00272 default:
00273 cout << "Beta_shape: Unsupported value of IDL = " << IDL << endl;
00274 cout << "Only supported values at present are IDL=0,1,2,3." << endl;
00275 cout << "Aborting." << endl;
00276 exit(1);
00277 }
00278
00279 if (T > 0.0) {
00280 Beta_arr[i] = (T+1.0)*sqrt(T*(T+2.0))*pow((T0-T),2.0);
00281 Y = ZD*(T+1.0)/sqrt(T*(T+2.0));
00282 FERFAC = 2.0*PI*Y/(1.0-exp(-2.0*PI*Y));
00283 }
00284 else {
00285 if (Z > 0.0) {
00286 Beta_arr[i] = (T+1.0)*pow((T0-T),2.0);
00287 Y = ZD*(T+1.0);
00288 FERFAC = 2.0*PI*Y;
00289 }
00290 else {
00291 Beta_arr[i] = 0.0;
00292 FERFAC = 0.0;
00293 }
00294 }
00295
00296 Beta_arr[i] *= FERFAC*UF;
00297 }
00298
00299 else {
00300 tmp1 = double(i)/double(num_entries-1);
00301 tmp2 = 1.0/Qval;
00302 Beta_arr[i] = pow(Qval,2.0) * pow((tmp1 + tmp2),2.0) *
00303 pow((1.0 - tmp1 + tmp2),2.0);
00304 }
00305
00306 }
00307 }
00308