00001
00002
00003
00004
00005
00006
00007
00008 #include "xsec.h"
00009 #include "grid.h"
00010 #include "nucleilist.h"
00011
00012 using namespace std;
00013
00014 TSpallationNetwork::TSpallationNetwork(TGrid* co, TXSecBase* xsecmodel, vector<int>& nuclei) {
00015
00016 energy = co->GetEk();
00017 const int dimEn = energy.size();
00018 const double factor = Clight*1.e-27;
00019
00020 for (int iloop = 0; iloop < nuclei.size()-1; ++iloop) {
00021
00022
00023 if (nuclei[iloop] <= 1001) continue;
00024
00025 int iz = -1000;
00026 int ia = -1000;
00027 Utility::id_nuc(nuclei[iloop], ia, iz);
00028
00029 for (int idaught = iloop+1; idaught < nuclei.size(); ++idaught) {
00030
00031 int jz = -1000;
00032 int ja = -1000;
00033 Utility::id_nuc(nuclei[idaught], ja, jz);
00034
00035
00036 if (nuclei[idaught] < 1001 || ia < ja) continue;
00037
00038 pair<int,int> couple(1000*iz+ia,1000*jz+ja);
00039
00040 if (spallationxsec == GalpropXSec) spall[couple] = xsecmodel->GetXSec(iz,ia,jz,ja);
00041 else if (spallationxsec == Webber03) {
00042 vector<double> beta = co->GetBeta();
00043
00044 for(unsigned int ip = 0; ip < dimEn; ip++) {
00045 spall[couple].push_back(xsecmodel->GetXSec(couple, energy[ip])*factor*beta[ip]*(1.0*He_abundance*xsecmodel->GetHefactor()));
00046 }
00047 }
00048 else {
00049 cerr << "Wrong SpallationXSec option" << endl;
00050 }
00051 }
00052 }
00053
00054
00055
00056 if (prop_ap || prop_el) {
00057
00058 const double factorprot = factor*co->GetDeltaE();
00059 const double factorelpos = 1.e3*factorprot;
00060
00061 double PP_inel = 0.0;
00062 double PA_inel = 0.0;
00063 double aPP_non = 0.0;
00064 double aPA_non = 0.0;
00065 double aPP_ann = 0.0;
00066 double aPA_ann = 0.0;
00067
00068 pair<int,int> couple(1001,1001);
00069 spall[couple] = vector<double>(dimEn, 0);
00070 for(unsigned int ip = 0; ip < dimEn; ++ip) {
00071 xsecmodel->nucleon_cs(2, energy[ip], 1, 2, 4, &PP_inel, &PA_inel, &aPP_non, &aPA_non, &aPP_ann, &aPA_ann);
00072 spall[couple][ip] = factorprot*(PP_inel + He_abundance*PA_inel);
00073 }
00074
00075 if (prop_ap) {
00076 pair<int,int> coupletert(-999,-999);
00077 spall[coupletert] = vector<double>(dimEn, 0.0);
00078 for(unsigned int ip = 0; ip < dimEn; ++ip) {
00079 xsecmodel->nucleon_cs(2, energy[ip], -1, 2, 4, &PP_inel, &PA_inel, &aPP_non, &aPA_non, &aPP_ann, &aPA_ann);
00080
00081 spall[coupletert][ip] = factorprot*( aPP_non + He_abundance*aPA_non );
00082
00083 }
00084
00085 spall_apel[pair<int,int>(2003,-999)] = vector< vector<double> >(dimEn, vector<double>(dimEn, 0.0));
00086 pair<int,int> coupleappr(1001,-999);
00087 pair<int,int> coupleapHe(2004,-999);
00088
00089 vector<double> pp = co->GetMomentum();
00090
00091 spall_apel[coupleappr] = vector< vector<double> >(dimEn, vector<double>(dimEn, 0.0));
00092 spall_apel[coupleapHe] = vector< vector<double> >(dimEn, vector<double>(dimEn, 0.0));
00093
00094 size_t limit = 1000;
00095 gsl_integration_workspace* w = gsl_integration_workspace_alloc(limit);
00096
00097 for (unsigned int i = 0; i < dimEn; i++) {
00098
00099 for (unsigned int ii=i+1; ii < dimEn; ii++) {
00100 spall_apel[coupleappr][i][ii] = factorelpos*energy[ii]*(xsecmodel->antiproton_cc1(w,limit,antiproton_cs, pp[i], pp[ii], 1, 1, 1, 1) * ( (!scaling) + (scaling)*(0.12 * pow(energy[i], -1.67) + 1.78)) + (!scaling)*He_abundance*xsecmodel->antiproton_cc1(w,limit,antiproton_cs, pp[i], pp[ii], 1, 1, 2, 4));
00101 spall_apel[coupleapHe][i][ii] = factorelpos*energy[ii]*4.0*(xsecmodel->antiproton_cc1(w,limit,antiproton_cs, pp[i], 4.0*pp[ii], 2, 4, 1, 1) * ( (!scaling) + (scaling)*(0.12 * pow(energy[i], -1.67) + 1.78)) + (!scaling)*He_abundance*xsecmodel->antiproton_cc1(w,limit,antiproton_cs, pp[i], 4.0*pp[ii], 2, 4, 2, 4));
00102 }
00103 }
00104 gsl_integration_workspace_free(w);
00105 }
00106
00107 if (prop_el) {
00108 pair<int,int> coupleel(1001, -1000);
00109 pair<int,int> couplepos(1001, 1000);
00110 spall_apel[coupleel] = vector< vector<double> >(dimEn, vector<double>(dimEn, 0.0));
00111 spall_apel[couplepos] = vector< vector<double> >(dimEn, vector<double>(dimEn, 0.0));
00112
00113 pair<int,int> coupleelHe(2004, -1000);
00114 pair<int,int> coupleposHe(2004, 1000);
00115 spall_apel[coupleelHe] = vector< vector<double> >(dimEn, vector<double>(dimEn, 0.0));
00116 spall_apel[coupleposHe] = vector< vector<double> >(dimEn, vector<double>(dimEn, 0.0));
00117
00118 spall_apel[pair<int,int>(2003,-1000)] = vector< vector<double> >(dimEn, vector<double>(dimEn, 0.0));
00119 spall_apel[pair<int,int>(2003,1000)] = vector< vector<double> >(dimEn, vector<double>(dimEn, 0.0));
00120
00121
00122 const int dimlept = 400;
00123 const double DBlog = (log10(1e5)-log10(1e-3))/(double)dimlept;
00124 double Elept[dimlept+1];
00125 for (int i = 0; i <= dimlept; i++) Elept[i] = pow(10, log10(1e-3)+double(i)*DBlog);
00126
00127 const int dimpr = 800;
00128 const double DBprlog = (log10(1e5)-log10(1e-3))/double(dimpr);
00129 double ET[dimpr+1];
00130 for (int j = 0; j <= dimpr; j++) ET[j] = pow(10, log10(1e-3) + double(j)*DBprlog);
00131
00132 Matrix_El_pp = vector<double>(401*801, 0.0);
00133 Matrix_El_pHe = vector<double>(401*801, 0.0);
00134 Matrix_El_Hep = vector<double>(401*801, 0.0);
00135 Matrix_El_HeHe = vector<double>(401*801, 0.0);
00136
00137 Matrix_Pos_pp = vector<double>(401*801, 0.0);
00138 Matrix_Pos_pHe = vector<double>(401*801, 0.0);
00139 Matrix_Pos_Hep = vector<double>(401*801, 0.0);
00140 Matrix_Pos_HeHe = vector<double>(401*801, 0.0);
00141
00142 TSpallationNetwork::InitDataTables();
00143
00144
00145 double ael[9];
00146 double bel[8];
00147 double cel[5];
00148 double del[5];
00149
00150 double apos[9];
00151 double bpos[8];
00152 double cpos[5];
00153 double dpos[5];
00154
00155 for (unsigned int i = 0; i < dimEn; i++) {
00156 double Eel = energy[i];
00157
00158 int i_lept = int(floor(log10(Eel/Elept[0])/DBlog));
00159 if (i_lept > dimlept-1) i_lept = dimlept-1;
00160 double t = (Eel-Elept[i_lept])/(Elept[i_lept+1]-Elept[i_lept]);
00161
00162
00163 for (unsigned int j = 0; j < dimEn; j++) {
00164 double Epr = energy[j];
00165
00166 if (ly == Kamae) {
00167 KamaeYields::elec_param_nd(Epr, ael);
00168 KamaeYields::elec_param_diff(Epr, bel);
00169 KamaeYields::elec_param_delta(Epr, cel);
00170 KamaeYields::elec_param_res(Epr, del);
00171
00172 KamaeYields::posi_param_nd(Epr, apos);
00173 KamaeYields::posi_param_diff(Epr, bpos);
00174 KamaeYields::posi_param_delta(Epr, cpos);
00175 KamaeYields::posi_param_res(Epr, dpos);
00176 }
00177
00178 int j_pr = int(floor(log10(Epr/ET[0])/DBprlog));
00179 if (j_pr > dimpr-1) j_pr = dimpr-1;
00180 double u = (Epr-ET[j_pr])/(ET[j_pr+1]-ET[j_pr]);
00181
00182 int indfixfix = index_matrix(i_lept,j_pr);
00183 int indupfix = index_matrix(i_lept+1,j_pr);
00184 int indfixup = index_matrix(i_lept,j_pr+1);
00185 int indupup = index_matrix(i_lept+1,j_pr+1);
00186
00187 double tu = (t)*(u);
00188 double t1u = (1.-t)*(u);
00189 double tu1 = (t)*(1.-u);
00190 double t1u1 = (1.-t)*(1.-u);
00191
00192 double cs_pp = (ly == GalpropTable) ? Matrix_El_pp[indfixfix]*t1u1 + Matrix_El_pp[indupfix]*tu1 + Matrix_El_pp[indfixup]*t1u +Matrix_El_pp[indupup]*tu : 1.e-3*(KamaeYields::sigma_nd(ID_POSITRON, Eel, Epr, apos) + KamaeYields::sigma_diff(ID_POSITRON, Eel, Epr, bpos) + KamaeYields::sigma_delta(ID_POSITRON, Eel, Epr, cpos) + KamaeYields::sigma_res(ID_POSITRON, Eel, Epr, dpos))/Eel;
00193 double cs_pHe = Matrix_El_pHe[indfixfix]*t1u1 + Matrix_El_pHe[indupfix]*tu1 + Matrix_El_pHe[indfixup]*t1u +Matrix_El_pHe[indupup]*tu;
00194 double cs_Hep = Matrix_El_Hep[indfixfix]*t1u1 + Matrix_El_Hep[indupfix]*tu1 + Matrix_El_Hep[indfixup]*t1u +Matrix_El_Hep[indupup]*tu;
00195 double cs_HeHe = Matrix_El_HeHe[indfixfix]*t1u1 + Matrix_El_HeHe[indupfix]*tu1 + Matrix_El_HeHe[indfixup]*t1u +Matrix_El_HeHe[indupup]*tu;
00196
00197
00198 spall_apel[couplepos][i][j] = Epr*(cs_pp + He_abundance*cs_pHe)*factorelpos;
00199 spall_apel[coupleposHe][i][j] = 4.0*Epr*(cs_Hep + He_abundance*cs_HeHe)*factorelpos;
00200
00201 cs_pp = (ly == GalpropTable) ? Matrix_Pos_pp[indfixfix]*t1u1 + Matrix_Pos_pp[indupfix]*tu1 + Matrix_Pos_pp[indfixup]*t1u +Matrix_Pos_pp[indupup]*tu : 1.e-3*(KamaeYields::sigma_nd(ID_ELECTRON, Eel, Epr, ael) + KamaeYields::sigma_diff(ID_ELECTRON, Eel, Epr, bel) + KamaeYields::sigma_delta(ID_ELECTRON, Eel, Epr, cel) + KamaeYields::sigma_res(ID_ELECTRON, Eel, Epr, del))/Eel;
00202 cs_pHe = Matrix_Pos_pHe[indfixfix]*t1u1 + Matrix_Pos_pHe[indupfix]*tu1 + Matrix_Pos_pHe[indfixup]*t1u +Matrix_Pos_pHe[indupup]*tu;
00203 cs_Hep = Matrix_Pos_Hep[indfixfix]*t1u1 + Matrix_Pos_Hep[indupfix]*tu1 + Matrix_Pos_Hep[indfixup]*t1u +Matrix_Pos_Hep[indupup]*tu;
00204 cs_HeHe = Matrix_Pos_HeHe[indfixfix]*t1u1 + Matrix_Pos_HeHe[indupfix]*tu1 + Matrix_Pos_HeHe[indfixup]*t1u +Matrix_Pos_HeHe[indupup]*tu;
00205
00206 spall_apel[coupleel][i][j] = Epr*(cs_pp + He_abundance*cs_pHe)*factorelpos;
00207 spall_apel[coupleelHe][i][j] = 4.0*Epr*(cs_Hep + He_abundance*cs_HeHe)*factorelpos;
00208 }
00209 }
00210 }
00211
00212 }
00213
00214 return ;
00215 }
00216
00217 double TSpallationNetwork::GetXSec(int i, int j, double en) {
00218 if (en > energy.back()) {
00219 cerr << "Out of range!" << endl;
00220 return 0;
00221 }
00222
00223 int l = 0;
00224 for (l = 0; l < energy.size(); ++l) {
00225 if (en >= energy[l]) break;
00226 }
00227 return spall[pair<int,int>(i,j)][l];
00228 }
00229
00230 double TSpallationNetwork::GetXSec(int i, int j, int k) {
00231 if (k >= energy.size()) {
00232 cerr << "Out of range!" << endl;
00233 return 0;
00234 }
00235 return spall[pair<int,int>(i,j)][k];
00236 }
00237
00238 void TSpallationNetwork::InitDataTables() {
00239
00240 ifstream infile(ElTablefile.c_str(), ios::in);
00241 double a,b,c,d;
00242
00243 for (int i = 0; i < 401; i++) {
00244 for (int j = 0; j < 801; j++) {
00245
00246 infile >> a >> b >> c >> d;
00247
00248 int ind = index_matrix(i,j);
00249
00250 Matrix_El_pp[ind] = a;
00251 Matrix_El_pHe[ind] = b;
00252 Matrix_El_Hep[ind] = c;
00253 Matrix_El_HeHe[ind] = d;
00254 }
00255 }
00256
00257 infile.close();
00258
00259 infile.open(PosTablefile.c_str(), ios::in);
00260
00261 for (int i = 0; i < 401; i++) {
00262 for (int j = 0; j < 801; j++) {
00263
00264 infile >> a >> b >> c >> d;
00265
00266 int ind = index_matrix(i,j);
00267
00268 Matrix_Pos_pp[ind] = a;
00269 Matrix_Pos_pHe[ind] = b;
00270 Matrix_Pos_Hep[ind] = c;
00271 Matrix_Pos_HeHe[ind] = d;
00272 }
00273 }
00274
00275 infile.close();
00276
00277 return;
00278 }
00279
00280 TInelasticCrossSection::TInelasticCrossSection(TGrid* Coord, int uid, TXSecBase* xsecmodel) {
00281 if (spallationxsec == GalpropXSec) xsec = xsecmodel->GetXSec(uid);
00282 else {
00283 if (xsecmodel->IsPresent(uid)) {
00284 vector<double> beta = Coord->GetBeta();
00285 vector<double> energy1 = Coord->GetEk();
00286
00287 const double factor = 1e-27*Clight;
00288 for(unsigned int ip = 0; ip < energy1.size(); ip++) xsec.push_back(xsecmodel->GetTotalXSec(uid, energy1[ip])*factor*beta[ip]*(1.0*He_abundance*xsecmodel->GetHefactor()));
00289 }
00290 else xsec = xsecmodel->GetXSec(uid);
00291 }
00292 }
00293
00294 TWebber03::TWebber03() : TXSecBase() {
00295
00296 ifstream file_to_read(Webber03Data.c_str(), ios::in);
00297 const int max_num_of_char_in_a_line = 512;
00298
00299 int channel_temp;
00300 double energy_temp, xsec_double;
00301
00302 while (file_to_read.good()) {
00303 file_to_read >> channel_temp;
00304
00305 if (channel_temp == 0) {
00306 for (int i = 0; i < 15; i++) {
00307 file_to_read >> energy_temp;
00308 energy.push_back(energy_temp/1000.0);
00309 }
00310 }
00311 else {
00312
00313 int uid1 = -1;
00314 int uid2 = -1;
00315 TWebber03::convert(channel_temp, uid1, uid2);
00316
00317 pair<int,int> couple = pair<int,int>(uid1,uid2);
00318 map< pair<int,int>, vector<double> >::iterator it = xsec.find(couple);
00319
00320 if (it == xsec.end()) {
00321 xsec[couple] = vector<double>(energy.size(), 0.0);
00322 for (int i = 0; i < 15; i++) {
00323 file_to_read >> xsec_double;
00324 xsec[couple][i] = xsec_double;
00325 }
00326 }
00327 }
00328
00329 file_to_read.ignore(max_num_of_char_in_a_line, '\n');
00330
00331 }
00332
00333 file_to_read.close();
00334
00335
00336
00337 file_to_read.open(Webber03DataTotal.c_str(), ios::in);
00338
00339 while (file_to_read.good()) {
00340 file_to_read >> channel_temp;
00341
00342 if (channel_temp == 0) file_to_read.ignore(max_num_of_char_in_a_line, '\n');
00343 else {
00344
00345 int uid1 = -1;
00346 TWebber03::convert_single(channel_temp, uid1);
00347 map< int, vector<double> >::iterator it = totalxsec.find(uid1);
00348
00349 if (it == totalxsec.end()) {
00350 totalxsec[uid1] = vector<double>(energy.size(), 0.0);
00351 for (int i = 0; i < 15; i++) {
00352 file_to_read >> xsec_double;
00353 totalxsec[uid1][i] = xsec_double;
00354 }
00355 }
00356 }
00357
00358 file_to_read.ignore(max_num_of_char_in_a_line, '\n');
00359
00360 }
00361 file_to_read.close();
00362
00363 }
00364
00365 void TWebber03::Print(TGrid* co) {
00366 vector<double> energia = co->GetEk();
00367 ofstream outfile("webber_test_6012_5011.dat", ios::out);
00368 for (int i = 0; i < energia.size(); ++i) outfile << energia[i] << " " << GetXSec(pair<int,int>(6012,5011), energia[i])*(1.0*He_abundance*GetHefactor()) << endl;
00369 }
00370
00371 double TWebber03::GetXSec(pair<int,int> input, double en) {
00372
00373 double result = 0.0;
00374
00375 map< pair<int,int>, vector<double> >::iterator it = xsec.find(input);
00376
00377 if (it == xsec.end()) {
00378 cerr << "Channel not found" << endl;
00379 return -1;
00380 }
00381
00382 int N = energy.size();
00383 if (en > energy.back()) return (*it).second.back();
00384
00385 gsl_vector_view x = gsl_vector_view_array (&energy[0], N);
00386 gsl_vector_view y = gsl_vector_view_array (&((*it).second)[0], N);
00387
00388 gsl_interp_accel *acc = gsl_interp_accel_alloc ();
00389
00390 gsl_spline *spline = gsl_spline_alloc (gsl_interp_cspline, N);
00391
00392 gsl_spline_init (spline, (&x.vector)->data, (&y.vector)->data, N);
00393
00394 result = gsl_spline_eval (spline, en, acc);
00395
00396 gsl_spline_free (spline);
00397 gsl_interp_accel_free (acc);
00398
00399 int l = 0;
00400 while (energy[l] < en) l++;
00401 double e1 = (energy[l]-en)/(energy[l]-energy[l-1]);
00402 double e2 = (en-energy[l-1])/(energy[l]-energy[l-1]);
00403
00404 double result1 = (*it).second[l-1]*e1 + (*it).second[l]*e2;
00405
00406 cout << "Comparison interpolation in Webber: " << result << " " << result1 << endl;
00407 return max(result,0.0);
00408 }
00409
00410 double TWebber03::GetTotalXSec(int input, double en) {
00411
00412 double result = 0.0;
00413
00414 int N = energy.size();
00415 if (en > energy.back()) return totalxsec[input].back();
00416
00417 gsl_vector_view x = gsl_vector_view_array (&energy[0], N);
00418 gsl_vector_view y = gsl_vector_view_array (&(totalxsec[input][0]), N);
00419
00420 gsl_interp_accel *acc = gsl_interp_accel_alloc ();
00421
00422 gsl_spline *spline = gsl_spline_alloc (gsl_interp_cspline, N);
00423
00424 gsl_spline_init (spline, (&x.vector)->data, (&y.vector)->data, N);
00425
00426 result = gsl_spline_eval (spline, en, acc);
00427
00428 gsl_spline_free (spline);
00429 gsl_interp_accel_free (acc);
00430 int l = 0;
00431 while (energy[l] < en) l++;
00432 double e1 = (energy[l]-en)/(energy[l]-energy[l-1]);
00433 double e2 = (en-energy[l-1])/(energy[l]-energy[l-1]);
00434
00435 double result1 = totalxsec[input][l-1]*e1 + totalxsec[input][l]*e2;
00436
00437 cout << "Comparison interpolation in Webber total: " << result << " " << result1 << endl;
00438 return max(result,0.0);
00439 }
00440
00441 TGalpropXSec::TGalpropXSec(TGrid* co) : TXSecBase() {
00442
00443 energy = co->GetEk();
00444 beta = co->GetBeta();
00445
00446 data_filename.push_back("data/isotope_cs.dat");
00447 data_filename.push_back("data/nucdata.dat");
00448 data_filename.push_back("data/p_cs_fits.dat");
00449 data_filename.push_back("data/eval_iso_cs.dat");
00450
00451 file_no[0] = 0;
00452 file_no[1] = 1;
00453 file_no[2] = 2;
00454 file_no[3] = 3;
00455
00456 int i,j,k,size;
00457 const int BufferSize=200;
00458 char readBuffer[BufferSize];
00459 ifstream data;
00460
00461 for(j=0; j<N_DATA_FILES; j++)
00462 {
00463 data.open(data_filename[j].c_str());
00464 if(data.fail())
00465 {
00466 cerr<<"read_nucdata: Error opening file "<<data_filename[j]<<endl;
00467 exit(1);
00468 }
00469
00470 while(!isspace(data.get()) && !data.eof())
00471 data.getline(readBuffer,BufferSize,'\n');
00472
00473 for(i=0; i<3; data >> n_data[i++][j]);
00474 data.getline(readBuffer,BufferSize,'\n');
00475
00476 for(size=1, i=0; i<3; size*=n_data[i++][j]);
00477
00478 data_file[j] = new float[size];
00479
00480 for(k = 0; k < size && !data.eof();)
00481 {
00482 while(!isspace(data.get()) && !data.eof())
00483 data.getline(readBuffer,BufferSize,'\n');
00484 for(i=0; i < n_data[0][j]; i++) data >> *(data_file[j]+k++);
00485 data.getline(readBuffer,BufferSize,'\n');
00486 }
00487 data.close();
00488 }
00489
00490 set_sigma_cc();
00491
00492 int ISS = -1;
00493 sigtap_cc(ISS);
00494
00495 return;
00496 }
00497
00498 void TGalpropXSec::set_sigma_cc() {
00499 int cdr=99;
00500 set_sigma_(&cdr);
00501 }
00502
00503 double TGalpropXSec::wsigma_cc(int IZ, int IA, int IZF, int IAF, double E) {
00504 return( wsigma_(&IZ,&IA,&IZF,&IAF,&E) );
00505 }
00506
00507 double TGalpropXSec::yieldx_cc(int IZ, int IA, int IZF, int IAF, float E) {
00508 float CSmb;
00509 yieldx_(&IZ,&IA,&IZF,&IAF,&E,&CSmb);
00510 return( 1.*CSmb );
00511 }
00512
00513 double TGalpropXSec::sighad_cc(int IS, double PA, double PZ, double TA, double TZ, double E) {
00514 return( sighad_(&IS, &PA, &PZ, &TA, &TZ, &E) );
00515 }
00516
00517 void TGalpropXSec::sigtap_cc(int ISS) {
00518 sigtap2_(&ISS);
00519 }
00520
00521 vector<double> TGalpropXSec::GetXSec(int iz, int ia, int jz, int ja) {
00522 int IZ1,IA1,IZ3,IA3,kopt,info, K_electron =0;
00523 int galdef_network_par=0;
00524 double branching_ratio,t_half;
00525
00526 const int diz=3;
00527 const double factor = Clight*1.e-27;
00528
00529 kopt = cross_section_option;
00530
00531 vector<double> spall = vector<double>(energy.size(), 0.0);
00532
00533
00534 for (IZ1=(jz-diz>1) ? jz-diz: 1; IZ1<=iz && IZ1<=jz+diz; IZ1++) {
00535 for (IA1=(2*IZ1-4>ja) ? 2*IZ1-4: ja; IA1<ia && IA1<=2.5*IZ1+4.2; IA1++) {
00536
00537
00538 if (IA1 < IZ1 || ia-IA1 < iz-IZ1) continue;
00539
00540
00541 branching_ratio = TGalpropXSec::nucdata(galdef_network_par,IZ1,IA1,K_electron,jz,ja, &IZ3,&IA3,&t_half);
00542
00543 if (branching_ratio == 0) continue;
00544
00545 t_half = t_half / year;
00546
00547
00548 if(t_half>=t_half_limit
00549 && 100*IZ1+IA1!=100*jz+ja && 100*IZ3+IA3!=100*jz+ja) continue;
00550
00551 for(unsigned int ip = 0; ip < energy.size(); ip++) spall[ip] += (TGalpropXSec::isotope_cs(energy[ip]*1000.0,iz,ia,IZ1,IA1,kopt,&info)*branching_ratio*(1.0+ He_abundance*TGalpropXSec::He_to_H_CS_ratio(energy[ip],iz,ia,IZ1,IA1))*beta[ip]*factor);
00552
00553 }
00554 }
00555
00556 return spall;
00557 }
00558
00559 vector<double> TGalpropXSec::GetXSec(int uid) {
00560 int Z = -1000;
00561 int A = -1000;
00562 Utility::id_nuc(uid, A, Z);
00563
00564 vector<double> result = vector<double>(energy.size(), 0.0);
00565
00566 if (A == 0) return result;
00567
00568 int target = 1;
00569 const bool protons = (A == 1 && Z == 1);
00570 const bool antiprotons = (A == 1 && Z == -1);
00571 if (protons) {
00572 A = 4;
00573 Z = 2;
00574 }
00575 if (antiprotons) {
00576 A = 4;
00577 Z = 2;
00578 target = -1;
00579 }
00580
00581 double PP_inel = 0.0;
00582 double PA_inel = 0.0;
00583 double aPP_non = 0.0;
00584 double aPA_non = 0.0;
00585 double aPP_ann = 0.0;
00586 double aPA_ann = 0.0;
00587
00588 const double factor = 1.e-27*Clight;
00589
00590 const double Hecontribution = He_abundance*TGalpropXSec::He_to_H_CS_totratio(A);
00591 for (unsigned int k = 0; k < energy.size(); ++k) {
00592 TGalpropXSec::nucleon_cs(2, energy[k], target, Z, A, &PP_inel, &PA_inel, &aPP_non, &aPA_non, &aPP_ann, &aPA_ann);
00593
00594 if (protons) result[k] = (PP_inel + He_abundance*PA_inel)*factor*beta[k];
00595 else if (antiprotons) result[k] = factor*(aPP_non + aPP_ann + He_abundance*(aPA_non + aPA_ann))*beta[k];
00596 else result[k] = PA_inel*factor*beta[k]*(1.0 + Hecontribution);
00597 }
00598
00599 return result;
00600
00601 }
00602
00603 double TGalpropXSec::He_to_H_CS_ratio(double E1,int IZI,int IAI,int IZF,int IAF) {
00604 double X,Y,a,b;
00605 double AMU,DELTA,FZI;
00606 double E[]= {-999, 0.43,0.73,1.51};
00607 double d[]= {-999, 2.45,3.45,4.40};
00608 double am[]= {-999, 0.082,0.047,0.031};
00609 double Z[]= {-999, 6.,8.,26.};
00610 double F[]= {-999, -0.76,-0.41,+1.00};
00611
00612 double CSratio = 0.;
00613 if(IAI <= IAF) return 0;
00614
00615 if(E1 < E[2])
00616 {
00617 AMU = FI(E1,E[1],E[2],am[1],am[2]);
00618 DELTA= FI( log(E1), log(E[1]), log(E[2]),d[1],d[2]);
00619 } else
00620 {
00621 AMU = FI(E1,E[2],E[3],am[2],am[3]);
00622 DELTA= FI( log(E1), log(E[2]), log(E[3]),d[2],d[3]);
00623 }
00624 if(E1 < E[1])
00625 {
00626 AMU = am[1];
00627 DELTA= d[1];
00628 }
00629 if(E1 > E[3])
00630 {
00631 AMU = am[3];
00632 DELTA= d[3];
00633 }
00634
00635 if(IZI < Z[2]) FZI = FI( log(IZI*1.), log(Z[1]), log(Z[2]),F[1],F[2]);
00636 else FZI = FI( log(IZI*1.), log(Z[2]), log(Z[3]),F[2],F[3]);
00637
00638 if(IZI-IZF <= IZI/2) CSratio = exp(AMU*pow(fabs(IZI-IZF-FZI*DELTA),1.43));
00639 else
00640 {
00641 X = exp(AMU*pow(fabs(IZI/2- FZI*DELTA), 1.43));
00642 Y = X-exp(AMU*pow(fabs(IZI/2-1-FZI*DELTA), 1.43));
00643 b = IZI/2*Y/X;
00644 a = X/pow(IZI/2,b);
00645 CSratio = a*pow(IZI-IZF,b);
00646 }
00647 return CSratio;
00648 }
00649
00650 double TGalpropXSec::nucdata(int ksp,int iz,int ia,int K_electron,int izf,int iaf,int* izl,int* ial,double* To) {
00651 int i,j,k,l,m,n,iy,iz0,ia0,iz4,ia4,iz5,ia5,iw[121],
00652 nksp=ksp*n_data[0][file_no[1]]*n_data[1][file_no[1]];
00653 float w[2][121], *decay = data_file[file_no[1]]+nksp;
00654 double b, xxx;
00655
00656
00657
00658 int stable[64][3] = {
00659 1, 0, 1, 1, 0, 1, 1, 0, 2, 2, 0, 2,
00660 0, 0, 0, 3, 0, 3, 3, 0, 4, 0, 0, 0,
00661 4, 0, 4, 4, 0, 5, 5, 0, 5, 6, 0, 6,
00662 6, 0, 6, 6, 0, 7, 7, 0, 7, 8, 0, 8,
00663 8, 0, 8, 8, 0, 8, 9, 0, 9, 10, 0, 10,
00664 10, 0, 10, 10, 0, 11, 11, 0, 11, 12, 0, 12,
00665 12, 0, 12, 12, 0, 13, 13, 0, 13, 14, 0, 14,
00666 14, 0, 14, 14, 0, 14, 15, 0, 15, 14, 0, 16,
00667 16, 0, 16, 16, 0, 16, 17, 0, 17, 16, 17, 18,
00668 17, 0, 18, 18, 0, 18, 18, 0, 19, 18, 19, 20,
00669 19, 0, 20, 18, 0, 20, 20, 0, 20, 20, 0, 22,
00670 21, 0, 21, 20, 0, 22, 22, 0, 22, 20, 0, 22,
00671 22, 0, 23, 22, 23, 24, 23, 0, 24, 24, 0, 24,
00672 24, 0, 25, 24, 25, 26, 25, 0, 26, 26, 0, 28,
00673 26, 0, 27, 26, 0, 28, 27, 0, 28, 26, 27, 28,
00674 28, 0, 28, 28, 0, 28, 28, 0, 29, 28, 0, 28
00675 };
00676
00677
00678 int nll = 25;
00679 float longliv[25][2][3] = {
00680 1.03, 12.33, 2.03,
00681 1.03, 12.33, 2.03,
00682
00683 4.07, 0., 4.07,
00684 4.07, 0.1459, 3.07,
00685
00686 4.10, 1.60e6, 5.10,
00687 4.10, 1.60e6, 5.10,
00688
00689 6.14, 5.73e3, 7.14,
00690 6.14, 5.73e3, 7.14,
00691
00692 11.22, 4.80e3, 10.22,
00693 11.22, 2.60e0, 10.22,
00694
00695 13.26, 9.10e5, 12.26,
00696 13.26, 4.075e6, 12.26,
00697
00698 14.32, 172., 16.32,
00699 14.32, 172., 16.32,
00700
00701 17.36, 3.07e5, 18.36,
00702 17.36, 1.58e7, 16.36,
00703
00704 18.37, 0., 18.37,
00705 18.37, 0.1, 17.37,
00706
00707 18.39, 2.69e2, 19.39,
00708 18.39, 2.69e2, 19.39,
00709
00710 19.40, 1.43e9, 20.40,
00711 19.40, 1.43e9, 20.40,
00712
00713 20.41, 0., 20.41,
00714 20.41, 1.03e5, 19.41,
00715
00716 18.42, 32.9, 20.42,
00717 18.42, 32.9, 20.42,
00718
00719 22.44, 0., 22.44,
00720 22.44, 49., 20.44,
00721
00722 23.49, 0., 23.49,
00723 23.49, 0.903, 22.49,
00724
00725 24.51, 0., 24.51,
00726 24.51, 0.076, 23.51,
00727
00728 25.53, 0., 25.53,
00729 25.53, 3.74e6, 24.53,
00730
00731 25.54, 6.30e5, 26.54,
00732 25.54, 0.855, 24.54,
00733
00734 26.55, 0., 26.55,
00735 26.55, 2.73e0, 25.55,
00736
00737 28.56, 4.00e4, 26.56,
00738 28.56, 0.1, 26.56,
00739
00740 27.57, 0., 27.57,
00741 27.57, 0.744, 26.57,
00742
00743 28.59, 0., 28.59,
00744 28.59, 7.60e4, 27.59,
00745
00746 27.60, 5.27e0, 28.60,
00747 27.60, 5.27e0, 28.60,
00748
00749 26.60, 1.50e6, 27.60,
00750 26.60, 1.50e6, 27.60,
00751
00752 28.63, 1.00e2, 29.63,
00753 28.63, 1.00e2, 29.63
00754 };
00755
00756 for(i=0;i<nll;i++) if(longliv[i][0][1]!=longliv[i][1][1]) longliv[i][1][1] *=2.;
00757
00758
00759
00760
00761
00762 int nb = 29;
00763 float boundary[29][2] = {
00764 1.01, 1.04, 3.04, 2.08,
00765 3.05, 3.11, 6.09, 4.14,
00766 6.10, 5.15, 8.13, 6.16,
00767 8.14, 7.21, 10.17, 8.22,
00768 12.20, 9.24, 12.21, 10.26,
00769 14.24, 11.30, 14.25, 12.30,
00770 15.27, 13.34, 16.29, 14.35,
00771 16.30, 15.38, 18.33, 16.40,
00772 20.36, 17.43, 20.37, 18.46,
00773 20.38, 19.48, 22.41, 20.51,
00774 22.42, 21.52, 24.45, 22.53,
00775 24.46, 23.55, 24.47, 24.59,
00776 25.49, 25.63, 26.51, 26.65,
00777 27.53, 27.69, 27.54, 28.69,
00778 28.56, 00.99
00779 };
00780
00781 b = *To = *izl = *ial = 0;
00782 if(iz <= 0 || ia <= 0) return(0.);
00783 if(iz*ia > 1 && iz >= ia) return(0.);
00784 if(2864 < fnuc(iz,ia)) return(0.);
00785 if(64 < ia) return(0.);
00786
00787
00788 iz0 = iz;
00789 ia0 = ia;
00790 if(ia>inuc(boundary[iz-1][1]-iz)) ia0=inuc(boundary[iz-1][1]-iz);
00791 if(29>ia-iz) if(ia>inuc(modf(boundary[ia-iz][0], &xxx)))
00792 {
00793 iz0=(int)boundary[ia-iz][0];
00794 ia0=inuc(boundary[ia-iz][0]-iz0);
00795 }
00796
00797 for(i=0; i<121; iw[i++]=-1) for(j=0; j<2; w[j++][i]=0.);
00798
00799
00800 for(i=0; i<n_data[1][file_no[1]]; i++)
00801 if(fnuc(iz0,ia0) == inuc(*(decay +i*n_data[0][file_no[1]] +0)))
00802 {
00803 iw[0] = i;
00804 w[1][0]= 1.00;
00805 break;
00806 }
00807
00808
00809 if(iw[0] < 0)
00810 {
00811 iz5 = iz0;
00812 ia5 = ia0;
00813
00814 if(iz0 > stable[ia0-1][2]) iz5 = stable[ia0-1][2];
00815 if(iz0 < stable[ia0-1][0]) iz5 = stable[ia0-1][0];
00816
00817 for(i=0; i<nll; i++)
00818 if(fnuc(iz5,ia5) == inuc(longliv[i][K_electron][0]))
00819 {
00820 *izl = iz5;
00821 *ial = ia5;
00822 *To = longliv[i][K_electron][1]*year;
00823 if(!*To) *izl=*ial=0;
00824 iz5 = (int) longliv[i][K_electron][2];
00825 ia5 = inuc(longliv[i][K_electron][2]-iz5);
00826 break;
00827 }
00828 if(fnuc(izf,iaf)==fnuc(iz5,ia5) || fnuc(izf,iaf)==fnuc(*izl,*ial)) b = 1.;
00829 if(fnuc(iz0,ia0) == fnuc(*izl,*ial)) *izl = *ial = 0;
00830 return(b);
00831 }
00832
00833
00834 for(l=-1, m=0, ia4=1, i=0; i<4; ia4 =(int) pow(3.,++i))
00835 {
00836 for(l+=ia4, iy=0, n=0; n<ia4; n++, m++)
00837 {
00838 if(iw[m] < 0) continue;
00839 for(w[0][m]=0., k=2; k<8; k+=2)
00840 {
00841 w[0][l+3*n+k/2]
00842 =*(decay +iw[m]*n_data[0][file_no[1]] +k-1);
00843 w[1][l+3*n+k/2]
00844 =*(decay +iw[m]*n_data[0][file_no[1]] +k)*w[1][m];
00845 for(j=0; j<iw[m]; j++)
00846 if(*(decay +iw[m]*n_data[0][file_no[1]] +k-1)
00847 == *(decay +j*n_data[0][file_no[1]] +0))
00848 {
00849 iw[l+3*n+k/2] = j;
00850 iy = l+3*n+k/2;
00851 }
00852 }
00853 }
00854 if(iy == 0) break;
00855 }
00856
00857
00858 for(k=0; k<=l+3*n; k++)
00859 {
00860 *To = *izl = *ial = 0;
00861 if(w[0][k] == 0.) continue;
00862 iz4 = (int) w[0][k];
00863 ia4 = inuc(w[0][k]-iz4);
00864 iz5 = iz4;
00865 ia5 = ia4;
00866
00867 if(iz4 > stable[ia4-1][2]) iz5 = stable[ia4-1][2];
00868 if(iz4 < stable[ia4-1][0]) iz5 = stable[ia4-1][0];
00869
00870 for(i=0; i<nll; i++)
00871 {
00872 if(fnuc(iz5,ia5) != inuc(longliv[i][K_electron][0])) continue;
00873 *izl = iz5;
00874 *ial = ia5;
00875 *To = longliv[i][K_electron][1]*year;
00876 if(!*To) *izl=*ial=0;
00877 iz5 = (int) longliv[i][K_electron][2];
00878 ia5 = inuc(longliv[i][K_electron][2]-iz5);
00879 break;
00880 }
00881 if(fnuc(izf,iaf) == fnuc(*izl,*ial) || fnuc(izf,iaf) == fnuc(iz5,ia5))
00882 return(w[1][k]);
00883 }
00884 return(b);
00885 }
00886
00887 double TGalpropXSec::isotope_cs(double emev,int iz,int ia,int izf,int iaf,int kopt,int* info) {
00888 int a1,a2,i,j,size, itable=0, info1;
00889 double e1,y,err2,xi1,xi2, f1=0., f2=0., T[11], a[3]={1.,1.,0.}, b[6];
00890 float *cs_data = data_file[file_no[0]], *p_cs = data_file[file_no[2]];
00891 double *tp=T;
00892 double ej;
00893 double CSmb = 0.0;
00894
00895 e1 = emev;
00896 *info = kopt;
00897
00898
00899 if(kopt == 1) CSmb = wsigma_cc(iz,ia,izf,iaf,emev);
00900 if(kopt == 2) CSmb = yieldx_cc(iz,ia,izf,iaf,e1);
00901 CSmb = max(0.,CSmb);
00902 if(kopt == 1 || kopt == 2) return(CSmb);
00903
00904 a1 = fnuc(iz, ia);
00905 a2 = fnuc(izf,iaf);
00906
00907
00908
00909 if(kopt == 12 || kopt == 22)
00910 {
00911 CSmb = eval_cs(emev,a1,a2,&info1);
00912 if (info1 > 0) return(max(0.,CSmb));
00913 kopt--;
00914 }
00915
00916
00917
00918 if(kopt == 11 || kopt == 21)
00919 {
00920
00921 if(izf != 0)
00922 {
00923
00924 if(10 == iaf)
00925 {
00926 b[0] = isotope_cs(emev,iz,ia,0,iaf,21,&j);
00927 if(j == -21)
00928 {
00929 if(510 == a2)
00930 {
00931 b[0]-=isotope_cs(emev,iz,ia,4,iaf,21,&j);
00932 return(max(0.,b[0]));
00933 }
00934 if(5 < izf) return(0.);
00935 }
00936 }
00937
00938 if(11 == iaf)
00939 {
00940 b[0] = isotope_cs(emev,iz,ia,0,iaf,21,&j);
00941 if(j == -21)
00942 {
00943 if(511 == a2) return(max(0.,b[0]));
00944 return(0.);
00945 }
00946 }
00947 }
00948
00949
00950 for(i=0; i<n_data[1][file_no[2]]-1; i++, p_cs+=n_data[0][file_no[2]])
00951 if(a1 == inuc(*p_cs) && a2 == inuc(*(p_cs+1)))
00952 {
00953 for(p_cs+=2, j=0; j<6; b[j++]=*p_cs++);
00954 if(b[0] >= 0.)
00955 {
00956 *info=-kopt;
00957 if(emev < b[5]) return(0);
00958 b[0]*=(1.+sin(b[1]*pow(log10(emev),1.*b[2]))*exp(-b[3]*(emev-b[4])));
00959 return(max(0.,b[0]));
00960 }
00961 kopt = (int)(-b[0]+0.1);
00962 }
00963 if(izf == 0) return(0.);
00964 }
00965
00966
00967 if(kopt == 1) CSmb = wsigma_cc(iz,ia,izf,iaf,emev);
00968 if(kopt == 2) CSmb = yieldx_cc(iz,ia,izf,iaf,e1);
00969 CSmb = max(0.,CSmb);
00970 if(kopt == 1 || kopt == 2) return(CSmb);
00971
00972
00973
00974 for(i=0; i<11; T[i++] = 0.);
00975
00976
00977
00978 for(size=1, i=0; i<3; size*=n_data[i++][file_no[0]]);
00979 for(tp = T, i=0; i<size; i+=n_data[0][file_no[0]], tp = T, f1=0., f2=0.)
00980 {
00981 if(a1 != inuc(*(cs_data+i))) continue;
00982 if(a2 != inuc(*(cs_data+i+1))) continue;
00983
00984
00985
00986 itable++;
00987 if(*(cs_data+i+4) < 0.) *(cs_data+i+4) *= -*(cs_data+i+3);
00988 err2 = pow(*(cs_data+i+4),2);
00989
00990 y = *(cs_data+i+3);
00991 ej = *(cs_data+i+2);
00992
00993 if(kopt/10 != 2) f1=wsigma_cc(iz,ia,izf,iaf,ej);
00994 if(kopt/10 != 1) f2=yieldx_cc(iz,ia,izf,iaf,*(cs_data+i+2));
00995
00996
00997 *tp++ += f1*y /err2;
00998 *tp++ += f1*f1/err2;
00999 *tp++ += f2*y /err2;
01000 *tp++ += f2*f2/err2;
01001 *tp++ += y /err2;
01002 *tp++ += 1. /err2;
01003
01004
01005 *tp++ += y*y /err2;
01006 *tp++ += 2.*f1*y/err2;
01007 *tp++ += f1*f1/err2;
01008 *tp++ += 2.*f2*y/err2;
01009 *tp += f2*f2/err2;
01010
01011
01012 for(j=0; j<3; j++) {
01013 a[j]= (T[2*j+1] != 0.) ? T[2*j]/T[2*j+1]: a[j];
01014 }
01015 }
01016
01017 if(kopt == 3 && a[2] != 0.) return(a[2]);
01018 if(kopt/10 == 1) CSmb = wsigma_cc(iz,ia,izf,iaf,emev);
01019 if(kopt/10 == 2) CSmb = yieldx_cc(iz,ia,izf,iaf,e1);
01020 if(kopt/10 == 1 || kopt/10 == 2) return(max(0.,CSmb*a[kopt/10-1]));
01021
01022
01023 if(itable < 2)
01024 {
01025 *info = itable;
01026 CSmb = a[0]*wsigma_cc(iz,ia,izf,iaf,emev);
01027 if(CSmb <= 0.)
01028 {
01029 CSmb = a[1]*yieldx_cc(iz,ia,izf,iaf,e1);
01030 if(CSmb != 0. && itable == 1) *info = 2;
01031 }
01032 } else
01033 {
01034 xi1= T[6] -a[0]*T[7] +a[0]*a[0]*T[8];
01035 xi2= T[6] -a[1]*T[9] +a[1]*a[1]*T[10];
01036 if(xi1 < xi2)
01037 {
01038 *info = 1;
01039 CSmb = a[0]*wsigma_cc(iz,ia,izf,iaf,emev);
01040 } else
01041 {
01042 *info = 2;
01043 CSmb = a[1]*yieldx_cc(iz,ia,izf,iaf,e1);
01044 }
01045 }
01046
01047 return(max(0.,CSmb));
01048 }
01049
01050 double TGalpropXSec::eval_cs(double emev,int za1,int za2,int* info) {
01051 int i,size;
01052 float *eval = data_file[file_no[3]];
01053 double x[2]={-1.e10,1.e10},y[2]={0.,0.};
01054
01055
01056
01057 for(size=1, i=0; i<3; size*=n_data[i++][file_no[3]]);
01058 for(*info=0, i=0; i<size; i+=n_data[0][file_no[3]])
01059 {
01060
01061 if(za1 != inuc(*(eval+i))) continue;
01062 if(za2 != inuc(*(eval+i+1))) continue;
01063
01064 if(x[0] < *(eval+i+2) && *(eval+i+2) <= emev)
01065 {
01066 x[0] = *(eval+i+2);
01067 y[0] = *(eval+i+3);
01068 }
01069 if(emev <= *(eval+i+2) && *(eval+i+2) < x[1])
01070 {
01071 x[1] = *(eval+i+2);
01072 y[1] = *(eval+i+3);
01073 }
01074 }
01075
01076 if(x[0]*x[1] < -1.e19) { *info = -1; return(0.); }
01077
01078 if(x[0] < 0.) { *info = 1; return(0.); }
01079 if(x[1] > 9.e9) { *info = 2; return(y[0]); }
01080
01081 if(x[1]-x[0] == 0.) { *info = 3; return(y[1]); }
01082
01083 for(*info = 4, i=0; i<2; i++) x[i] = log10(x[i]);
01084 return(y[0]+(log10(emev)-x[0])*(y[1]-y[0])/(x[1]-x[0]));
01085 }
01086
01087 void TGalpropXSec::nucleon_cs(int option, double Ek, int Zp, int Zt, int At, double *PP_inel,double *PA_inel,double *aPP_non,double *aPA_non,double *aPP_ann,double *aPA_ann) {
01088
01089 *PP_inel= *PA_inel= *aPP_non= *aPA_non= *aPP_ann= *aPA_ann=0.;
01090 if(Ek <= 0.) return;
01091
01092 double U,Cp,C1,s2,Z,A, aPP_inel=0.,aPA_inel=0., Emev=Ek, b0,Fcorr,rN,s0,p1,p2,p3,p4,p5,x,f1,f2;
01093 double PZ=fabs(1.*Zp),Em=1000.*Ek, TZ=Zt, TA=At;
01094 int ISS=2;
01095
01096
01097 if(Ek > 0.3)
01098 {
01099 U = log((Ek+mp)/200.);
01100 *PP_inel = 32.2*(1.+0.0273*U);
01101 if(U >= 0.) *PP_inel += 32.2*0.01*U*U;
01102 if(Ek < 3.) *PP_inel /= 1.+0.00262/pow(Ek,17.9+13.8*log(Ek)+4.41*pow(log(Ek),2));
01103 }
01104 if(Zp*At == 1) return;
01105
01106
01107 switch(option) {
01108 case 0:
01109 C1 = (At == 4) ? 0.8 : 1.;
01110 if(At == 9) C1 = 1.+0.75*exp(-Ek/0.075);
01111 *PA_inel = C1 *45. *pow(TA,0.7) *(1.+0.016*sin(5.3-2.63*log(TA)));
01112 if(Ek < 5.) *PA_inel *= 1.-0.62 *exp(-Ek/0.2) *sin(10.9/pow(Ek*1.e3,0.28));
01113 if(At == 4) *PA_inel = (Ek > 0.01) ?
01114 111.*(1.-(1.-sin(9.72*pow(log10(Ek*1000.),0.319)-4.14))*exp(-3.84*(Ek-0.1))) : 0.;
01115 break;
01116
01117 case 1:
01118 if(Zt>5) {
01119 b0 = 2.247-0.915*(1.-pow(TA,-1./3.));
01120 Fcorr = (1.-0.15*exp(-Emev))/(1.-0.0007*At);
01121 rN = (At-Zt>1.5) ? log(TA-Zt) : 1.;
01122 s0 = Pi*10.*pow(1.36,2.)*Fcorr*rN*(1.+pow(TA,1./3.)-b0*(1.-pow(TA,-1./3.)));
01123 p1 = 8.-8./At-0.008*At;
01124 p2 = 2.*(1.17-2.7/At-0.0014*At);
01125 p3 = 0.8+18./At-0.002*At;
01126 p4 = 5.6-0.016*At;
01127 p5 = 1.37*(1.+1./At);
01128 x = log10(Emev);
01129 f1 = 1./(1.+exp(-p1*(x+p2)));
01130 f2 = 1. +p3 *( 1. -1./(1.+exp(-p4*(x+p5))) );
01131 *PA_inel = f1*f2*s0;
01132 }
01133 break;
01134
01135 case 2:
01136 default:
01137 if (Em<14.) Em=14.;
01138 if (Em>1.e6) Em=1.e6;
01139 *PA_inel = sighad_cc(ISS,PZ,PZ,TA,TZ,Em);
01140 }
01141 if(Zp*At >= 1) return;
01142
01143
01144 if(Ek < 10.) *aPP_ann = 661.*(1.+0.0115/pow(Ek,0.774)-0.948*pow(Ek,0.0151));
01145 else
01146 {
01147
01148 s2 = 2.*mp*(Ek+2*mp);
01149 *aPP_ann = 2*35.43/pow(s2,0.560);
01150 }
01151
01152
01153 aPP_inel = *PP_inel + *aPP_ann;
01154 if(Ek <= 14.)
01155 {
01156 aPP_inel = 24.7*(1.+0.584/pow(Ek,0.115)+0.856/pow(Ek,0.566));
01157 if(*aPP_ann > aPP_inel) *aPP_ann = aPP_inel;
01158 }
01159
01160
01161 *aPP_non = aPP_inel - *aPP_ann;
01162 if(*aPP_non < 0.) *aPP_non = 0.;
01163
01164
01165 if(At > 1)
01166 {
01167
01168 *aPA_non = *PA_inel;
01169
01170
01171 A = At;
01172 Z = Zt;
01173 if(At == 4) { Z = 2.; A = 3.30; }
01174 *aPA_ann = pow(A,2./3.)
01175
01176 *(48.2 +19./pow(Ek,0.55)
01177 +(0.1-0.18/pow(Ek,1.2))*Z +0.0012/pow(Ek,1.5)*Z*Z) - *aPA_non;
01178 if(*aPA_ann < 0.) *aPA_ann = 0.;
01179 if(*aPA_ann < *aPP_ann) *aPA_ann = *aPP_ann;
01180 if(At == 4 && Ek > 5.) *aPA_ann = *aPP_ann;
01181
01182
01183
01184
01185
01186
01187
01188 }
01189 return;
01190 }
01191
01192
01193
01194
01195
01196
01197
01198
01199
01200
01201
01202
01203
01204
01205
01206
01207
01208 double TGalpropXSec::antiproton_cc1(gsl_integration_workspace* w, size_t limit, int key, double Pap, double Pp1, int NZ1, int NA1, int NZ2, int NA2) {
01209
01210 double Pp = Pp1/double(NA1);
01211
01212 double s2 = 2.*mp*( sqrt( pow(Pp,2.) + pow(mp,2.) ) + mp );
01213 double s1 = sqrt(s2);
01214
01215 if (s1 <= 4.*mp)
01216 return 0.;
01217
01218 double MX = 3.*mp;
01219
01220 double gamma_CM = s1/(2.*mp);
01221 double betagamma_CM = sqrt( pow(gamma_CM, 2.) - 1. );
01222 double Eap = sqrt ( pow(Pap,2.) + mp*mp );
01223
01224 if (NA2 > 1.) {
01225 Eap = Eap + 0.06;
01226 Pap = sqrt( Eap*Eap - mp*mp);
01227 }
01228
01229 double Eap_MAX = (s2 - MX*MX + mp*mp)/(2.*s1);
01230 double Ek = sqrt(Pp*Pp + mp*mp)-mp;
01231
01232 double result = 0.;
01233 double cosX_MAX = -1.;
01234
01235 if (betagamma_CM*Pap > 0)
01236 cosX_MAX = (gamma_CM*Eap - Eap_MAX)/(betagamma_CM*Pap);
01237
01238 if (cosX_MAX < -1.)
01239 cosX_MAX = -1.;
01240
01241 double param[2] = {Pap, Pp};
01242
01243 if (cosX_MAX <= 1.0) {
01244
01245
01246
01247 double AI = 0;
01248 double error = 0;
01249 gsl_function F;
01250 F.function = &(tan_ng);
01251 F.params = param;
01252 gsl_integration_qag(&F, 1.0, cosX_MAX, 0, 1e-4, limit, 6, w, &AI, &error);
01253
01254 result = -AI * 2.0 * Pap * (2. * Pi) * 1.e-3 * Pap / Eap ;
01255
01256
01257 }
01258 if (NA1 * NA2 == 1 || Ek <= 0.3) return result;
01259
01260
01261
01262 double PP_inel = 0.;
01263 double PA_inel = 0.;
01264 double aPP_non = 0.;
01265 double aPA_non = 0.;
01266 double aPP_ann = 0.;
01267 double apA_ann = 0.;
01268 nucleon_cs(key, Ek, 1, NZ2, NA2, &PP_inel, &PA_inel, &aPP_non, &aPA_non, &aPP_ann, &apA_ann);
01269 double CS2 = PP_inel;
01270 if (NA2 > 1) CS2 = PA_inel;
01271 double CS1 = PP_inel;
01272 if (NA1 > 1) {
01273 nucleon_cs(key, Ek, 1, NZ1, NA1, &PP_inel, &PA_inel, &aPP_non, &aPA_non, &aPP_ann, &apA_ann);
01274 CS1 = PA_inel;
01275 }
01276
01277
01278 double correction = 1.2 * (double(NA1)*CS2 + double(NA2)*CS1) / (2.*PP_inel);
01279 return result*correction;
01280 }
01281
01282
01283
01284
01285
01286
01287
01288
01289
01290 double tan_ng(double cosX, void* param) {
01291
01292
01293
01294
01295
01296
01297 double* param1 = (double*)param;
01298 double Pap = param1[0];
01299 double Pp = param1[1];
01300
01301
01302 double s2 = 2.*mp*( sqrt(Pp*Pp+mp*mp) + mp );
01303 double s1 = sqrt(s2);
01304
01305 if (s1 < 4.*mp)
01306 return 0;
01307
01308 double gamma_CM = s1/(2.*mp);
01309 double betagamma_CM = sqrt( pow(gamma_CM, 2.) - 1. );
01310 double Eap = sqrt(Pap*Pap + mp*mp);
01311 double sinX = 0.;
01312 if (1.-pow(cosX,2) > 0)
01313 sinX = sqrt(1.-pow(cosX,2));
01314 double pt = Pap*sinX;
01315 double MX = 3.*mp;
01316
01317 double Xr = 2.*s1*( gamma_CM*Eap - betagamma_CM*Pap*cosX )/( s2 - MX*MX + mp*mp ) ;
01318
01319 if (Xr > 1)
01320 return 0;
01321
01322
01323
01324 double A = 0.465 * exp(-0.037*Xr) + 2.31 * exp(0.014*Xr);
01325 double B = 0.0302 * exp(-3.19*(Xr + 0.399))*pow(Xr+0.399, 8.39);
01326
01327 double f = (3.15-1.05e-4)*pow((1.-Xr), 7.9);
01328 if (Xr <= 0.5)
01329 f += 1.05e-4*exp(-10.1*Xr);
01330 double result = f*exp(-A*pt + B*pt*pt);
01331
01332 if (s1 < 10.) {
01333
01334 double Xt = ((gamma_CM*Eap-betagamma_CM*Pap*cosX)-mp)/( (s2 - MX*MX +
01335 mp*mp) / (2.*s1)-mp);
01336 double a = 0.306*exp(-0.12*Xt);
01337 double b = 0.0552*exp(2.72*Xt);
01338 double c = 0.758 - 0.68*Xt + 1.54*pow(Xt,2.);
01339 double d = 0.594*exp(2.87*Xt);
01340 double Q1 = s1 - 4.*mp;
01341 double correction = (1. - exp(-exp(c*Q1-d)*(1.-exp(-a*pow(Q1,b))) ));
01342 result /= correction;
01343
01344 }
01345
01346 return result;
01347
01348 }