KaliVeda  1.12/06
Heavy-Ion Analysis Toolkit
KVRangeYanezMaterial.cpp
Go to the documentation of this file.
1 //Created by KVClassFactory on Thu Sep 27 14:50:08 2012
2 //Author: John Frankland,,,
3 
4 #include "KVRangeYanezMaterial.h"
5 #include "TF1.h"
6 #include "TEnv.h"
7 #include "KVUnits.h"
8 #include "KVNameValueList.h"
9 #include "Riostream.h"
10 #include "KVConfig.h"
11 
12 #include <KVNucleus.h>
13 using namespace std;
14 
15 
17 
18 namespace range {
19 # define NELMAX 10
20  int nelem;
21  int is_gas = 0;
22  struct elem {
23  int z;
24  int a;
25  double w;
27 
28 
29  double passage(int icorr, int zp, int ap, int iabso, int zt, int at,
30  double ein, double t, double* err);
31 
32  double egassap(int icorr, int zp, int ap, int iabso, int zt, int at,
33  double t, double eut, double* err);
34 
35  double thickn(int icorr, int zp, int ap, int iabso, int zt, int at,
36  double ein, double delen);
37 
38  double rangen(int icorr, int zp, int ap, int iabso, int zt, int at,
39  double ein);
40 }
41 //Int_t KVRangeYanezMaterial::fTableType = 1;//Hubert-Bimbot-Gauvin, valid for 2.5<E/A<100 MeV
42 
44 
45 using namespace range;
46 
47 
50 
52 {
53  // Default constructor
54 }
55 
56 
57 
60 
62  const KVIonRangeTable* t, const Char_t* name, const Char_t* symbol, const Char_t* state, Double_t density,
63  Int_t Z, Int_t A)
64  : KVIonRangeTableMaterial(t, name, symbol, state, density, Z, A)
65 {
66  // Create material (single-element absorber)
67  fTableType = 1; // Hubert for E/A>2.5MeV, switches to Northcliffe for <2.5AMeV.
68  fNelem = 1;
69  iabso = 0;
70  fAbsorb[0].z = Z;
71  fAbsorb[0].a = A;
72  fAbsorb[0].w = A;
73 
75 }
76 
77 
78 
79 
86 
89 {
90  // Copy constructor
91  // This ctor is used to make a copy of an existing object (for example
92  // when a method returns an object), and it is always a good idea to
93  // implement it.
94  // If your class allocates memory in its constructor(s) then it is ESSENTIAL :-)
95 
96  obj.Copy(*this);
97 }
98 
99 
100 
103 
105 {
106  // Destructor
107 }
108 
109 
110 
111 
119 
121 {
122  // This method copies the current state of 'this' object into 'obj'
123  // You should add here any member variables, for example:
124  // (supposing a member variable KVRangeYanezMaterial::fToto)
125  // CastedObj.fToto = fToto;
126  // or
127  // CastedObj.SetToto( GetToto() );
128 
130  //KVRangeYanezMaterial& CastedObj = (KVRangeYanezMaterial&)obj;
131 }
132 
133 
134 
136 
138 {
139  fDeltaE = new TF1(Form("KVRangeYanezMaterial:%s:EnergyLoss", GetType()), this,
141  0., 1.e+03, 0, "KVRangeYanezMaterial", "DeltaEFunc");
142  fDeltaE->SetNpx(100);
143  fRange = new TF1(Form("KVRangeYanezMaterial:%s:Range", GetType()), this,
145  0., 1.e+03, 0, "KVRangeYanezMaterial", "RangeFunc");
146  fRange->SetNpx(100);
147  fEres = new TF1(Form("KVRangeYanezMaterial:%s:ResidualEnergy", GetType()), this,
149  0., 1.e+03, 0, "KVRangeYanezMaterial", "EResFunc");
150  fEres->SetNpx(100);
151 }
152 
153 
154 
162 
164 {
165  // Function parameterising the energy loss of charged particles in this material.
166  // This is simply an interface to the passage() function of the Range C library.
167  // The incident energy E[0] is given in MeV.
168  // The energy loss is calculated in MeV.
169  // To avoid divergences as E->0, for any incident energy E<=1.e-3MeV (i.e. 1keV)
170  // we return dE=E i.e. all particles with E<=1keV are stopped.
171 
172  return (E[0] - EResFunc(E, p));
173 }
174 
175 
176 
184 
186 {
187  // Function parameterising the residual energy of charged particles after traversing this material.
188  // This is simply an interface to the passage() function of the Range C library.
189  // The incident energy E[0] is given in MeV.
190  // The residual energy is calculated in MeV.
191  // To avoid divergences as E->0, for any incident energy E<=1.e-3MeV (i.e. 1keV)
192  // we return Eres=0 i.e. all particles with E<=1keV are stopped.
193 
194  if (E[0] < 1.e-3) return 0.0;
195  return passage(fTableType, Zp, Ap, iabso, fAbsorb[0].z, fAbsorb[0].a, E[0], thickness / KVUnits::mg, &error);
196 }
197 
198 
199 
207 
209 {
210  // Function parameterising the range of charged particles in this material.
211  // This is simply an interface to the rangen() function of the Range C library.
212  // The incident energy E[0] is given in MeV.
213  // The range is calculated in g/cm**2.
214  // To avoid divergences as E->0, for any incident energy E<=1.e-3MeV (i.e. 1keV)
215  // we return range=0 i.e. all particles with E<=1keV are stopped.
216 
217  if (E[0] < 1.e-3) return 0.;
218  Double_t R = rangen(fTableType, Zp, Ap, iabso, fAbsorb[0].z, fAbsorb[0].a, E[0]);
219  return (R * KVUnits::mg);
220 }
221 
222 
223 
225 
227 {
228  nelem = fNelem;
229  is_gas = (int)IsGas(); // special treatment for effective charge in gases (M.F. Rivet, R. Bimbot et al)
230  if (iabso < 0) {
231  //cout << "nelem="<<nelem<<endl;
232  for (int k = 0; k < fNelem; k++) {
233  absorb[k].z = fAbsorb[k].z;
234  absorb[k].a = fAbsorb[k].a;
235  absorb[k].w = fAbsorb[k].w;
236  //cout << k << " " << absorb[k].z << " " << absorb[k].a << " " << absorb[k].w << endl;
237  }
238  }
239  Zp = Z;
240  Ap = A;
241 }
242 
243 
244 
249 
251 {
252  // Return function giving energy loss (in MeV) as a function of incident energy (in MeV) for
253  // charged particles (Z,A) traversing (or not) the thickness e (in g/cm**2) of this material.
254  // isotopic mass isoAmat argument is not used.
255 
257  thickness = e;
258  fDeltaE->SetRange(0, 400 * Ap);
259  return fDeltaE;
260 }
261 
262 
263 
268 
270 {
271  // Return function giving residual energy (in MeV) as a function of incident energy (in MeV) for
272  // charged particles (Z,A) traversing (or not) the thickness e (in g/cm**2) of this material.
273  // isotopic mass isoAmat argument is not used.
274 
276  thickness = e;
277  fEres->SetRange(0, 400 * Ap);
278  return fEres;
279 }
280 
281 
282 
287 
289 {
290  // Return function giving range (in g/cm**2) as a function of incident energy (in MeV) for
291  // charged particles (Z,A) traversing this material.
292  // isotopic mass isoAmat argument is not used.
293 
295  // Yanez' range functions tend to have a (negative) minimum at very low energy,
296  // below which the range diverges towards +infty at E=0.
297  // Therefore we limit the range of the function to E>=Emin where Emin
298  // is the energy for which the minimum occurs
299  Double_t minX = fRange->GetMinimumX(1.e-6, 400 * Ap);
300  fRange->SetRange(TMath::Max(1.e-6, minX), 400 * Ap);
301  return fRange;
302 }
303 
304 
305 
307 
309 {
311  if (IsCompound()) {
312  fNelem = 0;
313  iabso = -1;
314  TIter next(fComposition);
315  KVNameValueList* nvl;
316  while ((nvl = (KVNameValueList*)next())) {
317  fAbsorb[fNelem].z = nvl->GetIntValue("Z");
318  fAbsorb[fNelem].a = nvl->GetIntValue("A");
319  fAbsorb[fNelem].w = nvl->GetDoubleValue("Ar*Weight");
320  fNelem++;
321  }
322  }
323  else if (IsMixture()) {
324  fNelem = 0;
325  iabso = -1;
326  TIter next(fComposition);
327  KVNameValueList* nvl;
328  while ((nvl = (KVNameValueList*)next())) {
329  fAbsorb[fNelem].z = nvl->GetIntValue("Z");
330  fAbsorb[fNelem].a = nvl->GetIntValue("A");
331  fAbsorb[fNelem].w = nvl->GetDoubleValue("Ar*Weight");
332  fNelem++;
333  }
334  }
335 }
336 
337 
338 
343 
345 {
346  // Overrides KVIonRangeTableMaterial method to use the egassap() function of the Range C library.
347  // Calculates incident energy (in MeV) of an ion (Z,A) with residual energy Eres (MeV) after thickness e (in g/cm**2).
348  // isotopic mass isoAmat argument is not used.
350  return egassap(fTableType, Zp, Ap, iabso, fAbsorb[0].z, fAbsorb[0].a, e / KVUnits::mg, Eres, &error);
351 }
352 
353 
354 
361 
362 void KVRangeYanezMaterial::SaveMaterial(ofstream& matfile)
363 {
364  // Write definition of material in a file in the directory
365  //
366  // $(WORKING_DIR)/range_yanez/[name].dat
367  //
368  // All files in this directory are read when the table is initialised
369 
370  matfile << "// " << GetName() << " (" << GetSymbol() << ") generated ";
371  TDatime now;
372  matfile << now.AsString() << endl << endl;
373  if (IsCompound()) matfile << "COMPOUND" << endl;
374  else if (IsMixture()) matfile << "MIXTURE" << endl;
375  else matfile << "ELEMENT" << endl;
376  matfile << "name=" << GetName() << endl;
377  matfile << "symbol=" << GetSymbol() << endl;
378  matfile << "state=";
379  if (IsGas()) matfile << "gas" << endl;
380  else {
381  matfile << "solid" << endl;
382  matfile << "density=" << GetDensity() << endl;
383  }
384  if (IsCompound() || IsMixture()) {
385  matfile << "nelem=" << GetNElem() << endl;
386  TString listname = (IsCompound() ? "Compound element %d" : "Mixture element %d");
387 
388  for (int nel = 1; nel <= GetNElem(); ++nel) {
389  KVNameValueList* compo = (KVNameValueList*)fComposition->FindObject(Form(listname.Data(), nel));
390  KVNucleus nuc(compo->GetIntValue("Z"), compo->GetIntValue("A"));
391  matfile << nuc.GetSymbol() << " " << compo->GetIntValue("Natoms");
392  if (IsMixture()) matfile << " " << compo->GetDoubleValue("Proportion");
393  matfile << endl;
394  }
395  }
396  matfile << endl;
397 }
398 
399 
400 namespace range {
401  /*
402  Author: Ricardo Yanez
403  Copyright (c) 2005-2011 Ricardo Yanez <ricardo.yanez@calel.org>
404 
405  Calculates energy loss of an ion in an absorber by constructing
406  range tables based on either the,
407 
408  Northcliffe-Schilling correlations (E/A < 12 MeV/A)
409  (L.C. Northcliffe, R.F. Schilling, Nucl. Data Tables A7, 233, 1970).
410 
411  or,
412 
413  Hubert-Bimbot-Gauvin correlations (2.5 < E/A < 100 MeV/A)
414  (Atomic Data and Nuclear Data Tables, 1990, 46, pp. 1-213).
415 
416  License:
417 
418  This program is free software; you can redistribute it and/or modify
419  it under the terms of the GNU General Public License as published by
420  the Free Software Foundation; either version 2 of the License, or
421  (at your option) any later version.
422 
423  This program is distributed in the hope that it will be useful,
424  but WITHOUT ANY WARRANTY; without even the implied warranty of
425  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
426  GNU General Public License for more details.
427 
428  You should have received a copy of the GNU General Public License
429  along with this program; if not, write to the Free Software
430  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
431 
432  */
433 #define NMAX 4000
434 #define NSAV 2000
435 #define FMT 0.005
436 
437  struct elem cmpnd[NELMAX];
438  int numel;
439 
440  int isw1 = 0;
441  int isw2 = 0;
442  int isw3 = 0;
443  int isw4 = 0;
444  int isw5 = 0;
445 
446  /*
447 
449 
450  Calculate energy of ion after passage through an absorber foil.
451  */
452  double passage(int icorr, int zp, int ap, int iabso, int zt, int at,
453  double ein, double t, double* err)
454  {
455 
456  void rangetab(int icorr, int zp, int ap, int iabso, int zt, int at,
457  double * em, double * r, int* n);
458  unsigned int locate(double y[], int n, double x);
459  double polint(double * xa, double * ya, int n, double x, double * dy);
460 
461  double em[NMAX], r[NMAX];
462 
463  double elin, elut, rin, rut, lerr;
464  int n;
465 
466  int jj, jjj;
467 
468  /* check correlation */
469  if (icorr == 0 && ein / ap > 12.0)
470  icorr = 1; /* switch to H-B-G */
471  if (icorr == 1 && ein / ap <= 2.5)
472  icorr = 0; /* switch to N-S */
473 
474  rangetab(icorr, zp, ap, iabso, zt, at, &em[0], &r[0], &n);
475  jjj = n - 3;
476 
477  elin = log10(ein / (double)ap);
478  jj = locate(em, n, elin);
479  if (jj > jjj) jj = jjj;
480  rin = polint(&em[jj], &r[jj], 3, elin, &lerr);
481  rut = rin - t;
482  if (rut <= 0.0) {
483  *err = 0.0;
484  return 0.0;
485  }
486  else {
487  jj = locate(r, n, rut);
488  if (jj > jjj) jj = jjj;
489  elut = polint(&r[jj], &em[jj], 3, rut, &lerr);
490  *err = fabs(pow(10.0, elut - lerr * 3) - pow(10.0, elut + lerr * 3)) / pow(10.0, elut);
491  return pow(10.0, elut) * ap;
492  }
493  }
494 
495 
496 
497  /*
498 
500 
501  Calculate incoming energy of ion before passage
502  through an absorber of thickness t.
503  */
504  double egassap(int icorr, int zp, int ap, int iabso, int zt, int at,
505  double t, double eut, double* err)
506  {
507 
508  void rangetab(int icorr, int zp, int ap, int iabso, int zt, int at,
509  double * em, double * r, int* n);
510  unsigned int locate(double y[], int n, double x);
511  double polint(double * xa, double * ya, int n, double x, double * dy);
512 
513  double em[NMAX], r[NMAX];
514 
515  double elut, elin, eaut, rut, rin, lerr;
516  int n;
517 
518  int jj, jjj;
519 
520  if (eut / (double)ap != 0.0) {
521  if (icorr == 0 && eut / ap > 12.0)
522  icorr = 1; /* switch to H-B-G */
523  }
524 
525  rangetab(icorr, zp, ap, iabso, zt, at, &em[0], &r[0], &n);
526  jjj = n - 3;
527 
528  if (eut / (double)ap != 0.0) {
529  elut = log10(eut / (double)ap);
530  jj = locate(em, n, elut);
531  if (jj > jjj) jj = jjj;
532  rut = polint(&em[jj], &r[jj], 3, elut, &lerr);
533  }
534  else
535  rut = 0.0;
536 
537  rin = rut + t;
538  jj = locate(r, n, rin);
539  if (jj > jjj) jj = jjj;
540  elin = polint(&r[jj], &em[jj], 3, rin, &lerr);
541  *err = fabs(pow(10.0, elin - lerr * 3) - pow(10.0, elin + lerr * 3)) / pow(10.0, elin);
542  eaut = pow(10.0, elin);
543 
544  if (icorr == 0 && eaut > 12.0)
545  printf("warning: Hubert-Bimbot-Gauvin correlations should be used in this case.\n");
546  if (icorr == 1 && eaut <= 2.5)
547  printf("Warning: Northcliffe-Schilling correlations should be used in this case.\n");
548 
549  return eaut * ap;
550  }
551 
552 
553 
554  /*
555 
557 
558  Calculate absorber thickness for a given energy decrement
559  */
560  double thickn(int icorr, int zp, int ap, int iabso, int zt, int at,
561  double ein, double delen)
562  {
563 
564  void rangetab(int icorr, int zp, int ap, int iabso, int zt, int at,
565  double * em, double * r, int* n);
566  unsigned int locate(double y[], int n, double x);
567  double polint(double * xa, double * ya, int n, double x, double * dy);
568 
569  double em[NMAX], r[NMAX];
570 
571  double elin, elut, rin, rut, rerr;
572  int n;
573 
574  int jj, jjj;
575 
576  if (icorr == 0 && ein / (double)ap > 12.0)
577  icorr = 1; /* switch to H-B-G */
578  if (icorr == 1 && ein / (double)ap <= 2.5)
579  icorr = 0; /* switch to N-S */
580 
581  rangetab(icorr, zp, ap, iabso, zt, at, &em[0], &r[0], &n);
582  jjj = n - 3;
583 
584  elin = log10(ein / (double)ap);
585  jj = locate(em, n, elin);
586  if (jj > jjj) jj = jjj;
587  rin = polint(&em[jj], &r[jj], 3, elin, &rerr);
588  if (ein - delen <= 0.0)
589  rut = 0.0;
590  else {
591  elut = log10((ein - delen) / (double)ap);
592  jj = locate(em, n, elut);
593  if (jj > jjj) jj = jjj;
594  rut = polint(&em[jj], &r[jj], 3, elut, &rerr);
595  }
596  return rin - rut;
597  }
598 
599 
600 
601  /*
602 
604 
605  Calculate the range of a projectile
606  */
607  double rangen(int icorr, int zp, int ap, int iabso, int zt, int at,
608  double ein)
609  {
610 
611  void rangetab(int icorr, int zp, int ap, int iabso, int zt, int at,
612  double * em, double * r, int* n);
613  unsigned int locate(double y[], int n, double x);
614  double polint(double * xa, double * ya, int n, double x, double * dy);
615 
616  double em[NMAX], r[NMAX];
617 
618  double elin, rerr;
619  int n;
620 
621  int jj, jjj;
622 
623  if (icorr == 0 && ein / (double)ap > 12.0)
624  icorr = 1; /* switch to H-B-G */
625  if (icorr == 1 && ein / (double)ap <= 2.5)
626  icorr = 0; /* switch to N-S */
627 
628  rangetab(icorr, zp, ap, iabso, zt, at, &em[0], &r[0], &n);
629  jjj = n - 3;
630 
631  elin = log10(ein / (double)ap);
632  jj = locate(em, n, elin);
633  if (jj > jjj) jj = jjj;
634  return polint(&em[jj], &r[jj], 3, elin, &rerr);
635 
636  }
637 
638 
639 
640  /*
641 
643 
644  Calculates a range table given projectile and absorber. Tables are
645  saved in memory to speed up calculations. Up to NSAV such tables are
646  saved.
647  */
648  void rangetab(int icorr, int zp, int ap, int iabso, int zt, int at,
649  double* em, double* r, int* n)
650  {
651 
652  double dedx(int icorr, double e, int zp, int ap, int zt, int at);
653  void def_absorber(int zt, int at, int iabso);
654 
655  double elog[62] = {
656  -2.0000000000, -1.9030899870, -1.7958800173, -1.6989700043, -1.6020599913,
657  -1.4948500217, -1.3979400087, -1.3010299957, -1.2218487496, -1.1549019600,
658  -1.0969100130, -1.0457574906, -1.0000000000, -0.9030899870, -0.7958800173,
659  -0.6989700043, -0.6020599913, -0.4948500217, -0.3979400087, -0.3010299957,
660  -0.2218487496, -0.1549019600, -0.0969100130, -0.0457574906, 0.0000000000,
661  0.0969100130, 0.2041199827, 0.3010299957, 0.3979400087, 0.5051499783,
662  0.6020599913, 0.6989700043, 0.7781512504, 0.8450980400, 0.9030899870,
663  0.9542425094, 1.0000000000, 1.0413926852, 1.0791812460, 1.1760912591,
664  1.3010299957, 1.3979400087, 1.4771212547, 1.5440680444, 1.6020599913,
665  1.6532125138, 1.6989700043, 1.7781512504, 1.8450980400, 1.9030899870,
666  1.9542425094, 2.0000000000, 2.0413926852, 2.0791812460, 2.1760912591,
667  2.3010299957, 2.3979400087, 2.4771212547, 2.5440680444, 2.6020599913,
668  2.6532125138, 2.6989700043
669  };
670 
671  int ntalel;
672  double dedxt[NELMAX][NMAX];
673  double wtot;
674 
675  int i, j, k;
676  double est, elg, e;
677  double rng, rval, rnow, rold;
678  double etot, eold;
679  double dedxnow;
680 
681  int jsav;
682  static int isav = 0;
683  static int icc[NSAV], ijj[NSAV], iab[NSAV];
684  static int izp[NSAV], iap[NSAV], izt[NSAV], iat[NSAV];
685  static double esav[NSAV][NMAX], rsav[NSAV][NMAX];
686 
687 
688  /* check if table saved */
689  if (isav > 0) {
690  for (i = 0 ; i < isav ; i++) {
691  jsav = 0;
692  if (icorr == icc[i]) jsav++;
693  if (iabso == iab[i]) jsav++;
694  if (zp == izp[i]) jsav++;
695  if (ap == iap[i]) jsav++;
696  if (zt == izt[i]) jsav++;
697  if (at == iat[i]) jsav++;
698  if (jsav == 6) {
699  k = ijj[i];
700  for (j = 0 ; j < k ; j++) {
701  *(em + j) = esav[i][j];
702  *(r + j) = rsav[i][j];
703  }
704  *n = k;
705  return;
706  }
707  }
708  }
709 
710  if (isav > NSAV) {
711  printf("WARNING in rangetab: NSAV too small\n");
712  exit(0);
713  }
714  /* Save this call */
715  icc[isav] = icorr;
716  iab[isav] = iabso;
717  izp[isav] = zp;
718  iap[isav] = ap;
719  izt[isav] = zt;
720  iat[isav] = at;
721 
722  switch (icorr) {
723  case 0:
724  ntalel = 38;
725  break;
726  case 1:
727  ntalel = 61;
728  break;
729  case 2:
730  ntalel = 61;
731  break;
732  default:
733  printf("No valid range correlation.\n");
734  exit(0);
735  }
736 
737  /* define absorber */
738  def_absorber(zt, at, iabso);
739 
740  /* Compute a range table */
741  est = 3 * elog[0];
742  wtot = 0.0;
743  for (i = 0 ; i < numel ; i++) {
744  isw1 = isw2 = 0;
745  zt = cmpnd[i].z;
746  at = cmpnd[i].a;
747  wtot += cmpnd[i].w;
748  *n = 0;
749  for (j = 1 ; j <= 7000 ; j++) {
750  elg = FMT * (j - 1200);
751  e = pow(exp(elg), log(10.0));
752  if (elg >= est) {
753  if (elg <= elog[ntalel]) {
754  dedxt[i][*n] = dedx(icorr, e, zp, ap, zt, at);
755  *(em + (*n)) = elg;
756  (*n)++;
757  }
758  else
759  break;
760  if (*n > 3999) break;
761  }
762  }
763  }
764 
765  ijj[isav] = *n;
766 
767  rng = 0.0;
768  rold = 0.0;
769  eold = 0.0;
770  for (j = 0 ; j < *n ; j++) {
771  elg = *(em + j);
772  e = pow(exp(elg), log(10.0));
773  etot = e * ap;
774  dedxnow = 0.0;
775  for (i = 0 ; i < numel ; i++)
776  dedxnow += dedxt[i][j] * cmpnd[i].w;
777  dedxnow /= wtot;
778  rnow = 1.0 / dedxnow;
779  rval = 0.5 * (rold + rnow) * (etot - eold);
780  rng += rval;
781  *(r + j) = rng;
782  eold = etot;
783  rold = rnow;
784  esav[isav][j] = *(em + j);
785  rsav[isav][j] = *(r + j);
786  }
787  isav++;
788  }
789 
790 
791 
793 
794  void dedxtab(int icorr, int zp, int ap, int iabso, int zt, int at,
795  double e, double* tdedxe, double* tdedxn)
796  {
797 
798  double ededx(double e, int zp, int zt);
799  double ndedx(double e, int zp, int ap, int zt, int at);
800  double ededxh(double e, int zp, int zt);
801  void def_absorber(int zt, int at, int iabso);
802 
803  double dedxn[NELMAX], dedxe[NELMAX];
804  double tw;
805  double e_int;
806  int i;
807 
808  def_absorber(zt, at, iabso);
809 
810  for (i = 0 ; i < numel ; i++) {
811  isw1 = isw2 = 0;
812  zt = cmpnd[i].z;
813  at = cmpnd[i].a;
814  if (e < 2.5) {
815  dedxn[i] = ndedx(e, zp, ap, zt, at) * pow(zp, 2);
816  dedxe[i] = ededx(e, zp, zt) * pow(zp, 2);
817  }
818  else {
819  if (icorr == 1) {
820  dedxn[i] = 0.0;
821  dedxe[i] = ededxh(e, zp, zt);
822  }
823  else if (icorr == 0) {
824  dedxn[i] = ndedx(e, zp, ap, zt, at) * pow(zp, 2);
825  dedxe[i] = ededx(e, zp, zt) * pow(zp, 2);
826  }
827  else if (icorr == 2) {
828  if (e < 12) {
829  /* interpolate */
830  e_int = (e - 2.5) / 9.5;
831  dedxn[i] = (1. - e_int) * ndedx(e, zp, ap, zt, at) * pow(zp, 2);
832  dedxe[i] = e_int * ededxh(e, zp, zt) + (1. - e_int) * ededx(e, zp, zt) * pow(zp, 2);
833  }
834  else {
835  dedxn[i] = 0.0;
836  dedxe[i] = ededxh(e, zp, zt);
837  }
838  }
839  }
840  }
841  *tdedxn = *tdedxe = 0.0;
842  tw = 0.0;
843  for (i = 0 ; i < numel ; i++) {
844  *tdedxn += dedxn[i] * cmpnd[i].w;
845  *tdedxe += dedxe[i] * cmpnd[i].w;
846  tw += cmpnd[i].w;
847  }
848  *tdedxn /= tw;
849  *tdedxe /= tw;
850  }
851 
852 
853 
854 
856 
857  void def_absorber(int zt, int at, int iabso)
858  {
859 
860  int i;
861 
862  switch (iabso) {
863 
864  /* User defined */
865  case -1:
866  for (i = 0 ; i < nelem ; i++) {
867  cmpnd[i].z = absorb[i].z;
868  cmpnd[i].a = absorb[i].a;
869  cmpnd[i].w = absorb[i].w;
870  }
871  numel = nelem;
872  break;
873 
874  /* Single element */
875 
876  case 0:
877  numel = 1;
878  cmpnd[0].z = zt;
879  cmpnd[0].a = at;
880  cmpnd[0].w = at * 1;
881  break;
882 
883  /* Solids */
884 
885  case 1: /* Mylar (C-10, H-8, O-4) */
886  numel = 3;
887  cmpnd[0].z = 6;
888  cmpnd[0].a = 12;
889  cmpnd[0].w = cmpnd[0].a * 10.;
890  cmpnd[1].z = 1;
891  cmpnd[1].a = 1;
892  cmpnd[1].w = cmpnd[1].a * 8.;
893  cmpnd[2].z = 8;
894  cmpnd[2].a = 16;
895  cmpnd[2].w = cmpnd[2].a * 4.;
896  break;
897  case 2: /* Polyethylene (C-2, H-4) */
898  numel = 2;
899  cmpnd[0].z = 6;
900  cmpnd[0].a = 12;
901  cmpnd[0].w = cmpnd[0].a * 2.;
902  cmpnd[1].z = 1;
903  cmpnd[1].a = 1;
904  cmpnd[1].w = cmpnd[1].a * 4.;
905  break;
906  case 3: /* Polypropylene (C-3, H-6) */
907  numel = 2;
908  cmpnd[0].z = 6;
909  cmpnd[0].a = 12;
910  cmpnd[0].w = cmpnd[0].a * 3.;
911  cmpnd[1].z = 1;
912  cmpnd[1].a = 1;
913  cmpnd[1].w = cmpnd[1].a * 6.;
914  break;
915  case 4: /* Kapton (H-10, C-22, N-2, O-5) */
916  numel = 4;
917  cmpnd[0].z = 1;
918  cmpnd[0].a = 1;
919  cmpnd[0].w = cmpnd[0].a * 10.;
920  cmpnd[1].z = 6;
921  cmpnd[1].a = 12;
922  cmpnd[1].w = cmpnd[1].a * 22.;
923  cmpnd[2].z = 7;
924  cmpnd[2].a = 14;
925  cmpnd[2].w = cmpnd[2].a * 2.;
926  cmpnd[3].z = 8;
927  cmpnd[3].a = 16;
928  cmpnd[3].w = cmpnd[3].a * 5.;
929  break;
930  case 5: /* Cesium Iodine (CsI) */
931  numel = 2;
932  cmpnd[0].z = 55;
933  cmpnd[0].a = 133;
934  cmpnd[0].w = cmpnd[0].a * 1.;
935  cmpnd[1].z = 53;
936  cmpnd[1].a = 127;
937  cmpnd[1].w = cmpnd[1].a * 1.;
938  break;
939  case 6: /* Sodium Iodine (NaI) */
940  numel = 2;
941  cmpnd[0].z = 11;
942  cmpnd[0].a = 23;
943  cmpnd[0].w = cmpnd[0].a * 1.;
944  cmpnd[1].z = 53;
945  cmpnd[1].a = 127;
946  cmpnd[1].w = cmpnd[1].a * 1.;
947  break;
948  case 7: /* Aluminum Oxide (Al2O3) */
949  numel = 2;
950  cmpnd[0].z = 13;
951  cmpnd[0].a = 27;
952  cmpnd[0].w = cmpnd[0].a * 2.;
953  cmpnd[1].z = 8;
954  cmpnd[1].a = 16;
955  cmpnd[1].w = cmpnd[1].a * 3.;
956  break;
957  case 8: /* Tin-Lead (Sn60/Pb40) */
958  numel = 4;
959  cmpnd[0].z = 50;
960  cmpnd[0].a = 116;
961  cmpnd[0].w = 0.206 * 60.;
962  cmpnd[1].z = 50;
963  cmpnd[1].a = 118;
964  cmpnd[1].w = 0.340 * 60.;
965  cmpnd[2].z = 50;
966  cmpnd[2].a = 120;
967  cmpnd[2].w = 0.454 * 60.;
968  cmpnd[3].z = 82;
969  cmpnd[3].a = 208;
970  cmpnd[3].w = 40.;
971  break;
972  case 9: /* Natural Ni (Ni-nat) */
973  numel = 5;
974  cmpnd[0].z = 28;
975  cmpnd[0].a = 58;
976  cmpnd[0].w = cmpnd[0].a * 0.680769;
977  cmpnd[1].z = 28;
978  cmpnd[1].a = 60;
979  cmpnd[1].w = cmpnd[1].a * 0.262231;
980  cmpnd[2].z = 28;
981  cmpnd[2].a = 61;
982  cmpnd[2].w = cmpnd[2].a * 0.011399;
983  cmpnd[3].z = 28;
984  cmpnd[3].a = 62;
985  cmpnd[3].w = cmpnd[3].a * 0.036345;
986  cmpnd[4].z = 28;
987  cmpnd[4].a = 64;
988  cmpnd[4].w = cmpnd[4].a * 0.009256;
989  break;
990 
991  /* Gases */
992 
993  case 100: /* Carbon Tetrafluoride (CF4) */
994  numel = 2;
995  cmpnd[0].z = 6;
996  cmpnd[0].a = 12;
997  cmpnd[0].w = cmpnd[0].a * 1.;
998  cmpnd[1].z = 9;
999  cmpnd[1].a = 19;
1000  cmpnd[1].w = cmpnd[1].a * 4.;
1001  is_gas = 1;
1002  break;
1003  case 101: /* Propane (H-8, C-3) */
1004  numel = 2;
1005  cmpnd[0].z = 1;
1006  cmpnd[0].a = 1;
1007  cmpnd[0].w = cmpnd[0].a * 8.;
1008  cmpnd[1].z = 6;
1009  cmpnd[1].a = 12;
1010  cmpnd[1].w = cmpnd[1].a * 3.;
1011  is_gas = 1;
1012  break;
1013  case 102: /* Butane (H-10, C-4) */
1014  numel = 2;
1015  cmpnd[0].z = 1;
1016  cmpnd[0].a = 1;
1017  cmpnd[0].w = cmpnd[0].a * 10.;
1018  cmpnd[1].z = 6;
1019  cmpnd[1].a = 12;
1020  cmpnd[1].w = cmpnd[1].a * 4.;
1021  is_gas = 1;
1022  break;
1023  case 103: /* Octane (H-18, C-8) */
1024  numel = 2;
1025  cmpnd[0].z = 1;
1026  cmpnd[0].a = 1;
1027  cmpnd[0].w = cmpnd[0].a * 18.;
1028  cmpnd[1].z = 6;
1029  cmpnd[1].a = 12;
1030  cmpnd[1].w = cmpnd[1].a * 8.;
1031  is_gas = 1;
1032  break;
1033  default:
1034  printf("No valid absorber data.\n");
1035  exit(0);
1036  }
1037  }
1038 
1039 
1040 
1041  /*
1042  Compute 1/(dE/dx) for a given energy E/A and projectile and target.
1043  */
1044 
1045  /* SMOOTHERSTEP = interpolating function with zero first- and
1046  second- derivatives at the end points */
1047 #define SMOOTHERSTEP(x) ((x) * (x) * (x) * (3*(x)*(2*(x) - 5) + 10))
1048 
1049 
1051 
1052  double dedx(int icorr, double e, int zp, int ap, int zt, int at)
1053  {
1054 
1055  double ededx(double e, int zp, int zt);
1056  double ndedx(double e, int zp, int ap, int zt, int at);
1057  double ededxh(double e, int zp, int zt);
1058 
1059  double dedxn, dedxe, e_int, smoothe;
1060  static double emin = 0.1, emax = 2.5;
1061 
1062  if (icorr == 1 && e < 2.5) icorr = 0;
1063  if (icorr == 2) {
1064  if (e < emin) icorr = 0;
1065  else if (e > emax) icorr = 1;
1066  }
1067  switch (icorr) {
1068  case 0:
1069  dedxn = ndedx(e, zp, ap, zt, at);
1070  dedxe = ededx(e, zp, zt);
1071  return (dedxn + dedxe) * pow(zp, 2);
1072  break;
1073  case 1:
1074  return ededxh(e, zp, zt);
1075  break;
1076  case 2: /* interpolate in range emin<e<emax */
1077  e_int = (e - emin) / (emax - emin);
1078  smoothe = SMOOTHERSTEP(e_int);
1079  return (smoothe * ededxh(e, zp, zt) +
1080  (1. - smoothe) * (ndedx(e, zp, ap, zt, at) + ededx(e, zp, zt)) * pow(zp, 2));
1081  break;
1082  default:
1083  exit(0);
1084  }
1085  }
1086 
1087 
1088 
1089  /*
1090 
1092 
1093  Compute the "electrical" energy loss rate in any material (-dE/dx)/Z2
1094  */
1095  double ededx(double e, int zp, int zt)
1096  {
1097 
1098  void alion(int zp, double * dedxz2);
1099  void gfact(double * le, int zt, double * f);
1100  void mpyers(double * le, int zt, double * f);
1101 
1102  unsigned int locate(double y[], int n, double x);
1103  double polint(double * xa, double * ya, int n, double x, double * dy);
1104 
1105  double elog[42] = {-1.903090, -1.795880, -1.698970, -1.602060, -1.494850,
1106  -1.397940, -1.301030, -1.221849, -1.154902, -1.096910,
1107  -1.045757, -1.000000, -0.903090, -0.795880, -0.698970,
1108  -0.602060, -0.494850, -0.397940, -0.301030, -0.221849,
1109  -0.154902, -0.096910, -0.045757, 0.000000, +0.096910,
1110  +0.204120, +0.301030, +0.397940, +0.505150, +0.602060,
1111  +0.698970, +0.778151, +0.845098, +0.903090, +0.954243,
1112  +1.000000, +1.041393, +1.079181, +1.301030, +1.602060,
1113  +1.845098, +2.000000
1114  };
1115 
1116  int zgases[11] = {1, 2, 7, 8, 9, 10, 17, 18, 36, 54, 86};
1117 
1118  int i, j;
1119  unsigned int jj;
1120  static double dedxz2[42];
1121  static double ak, a, ftargl;
1122  double b, ftarg, el, err;
1123  int gas;
1124 
1125  if (!isw1) {
1126  alion(zp, &dedxz2[0]);
1127  ak = (dedxz2[2] - dedxz2[0]) / (elog[2] - elog[0]);
1128  a = dedxz2[0] - ak * elog[0];
1129  //ftarg = 1.0;
1130 
1131  /* Is it a gas? */
1132  gas = 0;
1133  for (i = 0 ; i < 11 ; i++)
1134  if (zt == zgases[i]) gas = 1;
1135 
1136  /* Special case for gases */
1137  if (gas) {
1138  gfact(&elog[0], zt, &ftargl);
1139  dedxz2[0] += ftargl;
1140  for (j = 1 ; j < 42 ; j++) {
1141  gfact(&elog[j], zt, &ftarg);
1142  dedxz2[j] += ftarg;
1143  }
1144  }
1145  /* It is a solid */
1146  else {
1147  if (zt != 13) {
1148  mpyers(&elog[0], zt, &ftargl);
1149  dedxz2[0] += ftargl;
1150  for (j = 1 ; j < 42 ; j++) {
1151  mpyers(&elog[j], zt, &ftarg);
1152  dedxz2[j] += ftarg;
1153  }
1154  }
1155  }
1156  isw1 = 1;
1157  }
1158  el = log10(e);
1159  if (el < elog[0])
1160  b = a + ak * el + ftargl;
1161  else {
1162  jj = locate(elog, 42, el);
1163  if (jj > 39) jj = 39;
1164  b = polint(&elog[jj], &dedxz2[jj], 3, el, &err);
1165  }
1166  return pow(10.0, b);
1167  }
1168 
1169 
1170 
1171  /*
1172 
1174 
1175  Computes current value of nuclear stopping power for a
1176  Projectile of energy E (MeV/A), mass ap and charge zp in an
1177  absorber with mass at and charge zt using a function fit to
1178  the LSS universal nuclear stopping power curve.
1179  */
1180  double ndedx(double e, int zp, int ap, int zt, int at)
1181  {
1182 
1183  double zexpo, dedr;
1184  double x, y, xl, yl;
1185 
1186  /* Compute current x-coordinate from projectile and target data */
1187  zexpo = sqrt(pow(zp, 2.0 / 3.0) + pow(zt, 2.0 / 3.0));
1188  x = sqrt((e * ap * at / (double)(ap + at)) / (zp * zt * zexpo));
1189 
1190  /* Get log for polynomial fit */
1191  xl = log10(x);
1192  yl = -6.80959 + xl *
1193  (-6.60315 + xl * (-1.73474 + xl * xl * (0.04937 + xl * 0.00486)));
1194  y = pow(10.0, yl);
1195 
1196  /* Convert y to -dEPS/dRHO */
1197  dedr = y * zt * ap / (zp * at * (ap + at) * zexpo);
1198  return dedr;
1199  }
1200 
1201 
1202  /*
1203 
1205 
1206  Compute the "electrical" energy loss rate in any material
1207  (-dE/dx) above 2.5 MeV/A according to Hubert et al.
1208  */
1209  double ededxh(double e, int zp, int zt)
1210  {
1211 
1212  double s2az(double e, int zt);
1213 
1214  static double b, c, d;
1215  static double x1, x2, x3, x4;
1216  double xg1;
1217 
1218  /* Special case for He */
1219  if (zp == 2) {
1220  isw2 = 1;
1221  return s2az(e, zt) * 4.0;
1222  }
1223 
1224  if (!isw2) {
1225  if (is_gas) {
1226  /* If the element or compound is a gas
1227  we use the (unpublished) effective charge
1228  parametrisation for gaseous absorbers
1229  (M.F. Rivet, IPN Orsay, private communication).
1230  */
1231  b = 2.6878;
1232  c = 0.07452;
1233  d = 0.51216 + 0.5693 * exp(-0.002158 * zt);
1234  x2 = 11.109 + 0.1057 * log(zt);
1235  x3 = 0.5622 - 0.07901 * log(zt);
1236  x4 = 0.8276 - 0.03059 * log(zt);
1237  }
1238  else {
1239  if (zt == 4) {
1240  b = 2.0;
1241  c = 0.04369;
1242  d = 2.045;
1243  x2 = 7.0;
1244  x3 = 0.2643;
1245  x4 = 0.4171;
1246  }
1247  else {
1248  if (zt == 6) {
1249  b = 1.91;
1250  c = 0.03958;
1251  d = 2.584;
1252  x2 = 6.933;
1253  x3 = 0.2433;
1254  x4 = 0.3969;
1255  }
1256  else {
1257  b = 1.658;
1258  c = 0.0517;
1259  d = 1.164 + 0.2319 * exp(-0.004302 * zt);
1260  x2 = 8.144 + 0.09876 * log(zt);
1261  x3 = 0.314 + 0.01072 * log(zt);
1262  x4 = 0.5218 + 0.02521 * log(zt);
1263  }
1264  }
1265  }
1266  x1 = d + b * exp(-c * zp);
1267  isw2 = 1;
1268  }
1269  xg1 = 1.0 - x1 * exp(-x2 * pow(e, x3) / pow(zp, x4));
1270  return s2az(e, zt) * pow((xg1 * zp), 2);
1271  }
1272 
1273 
1274 
1275  /*
1276 
1278 
1279  Given E/A (MeV/A) and the material atomic number Z, A
1280  logarithm F is calculated that should be used to convert
1281  stopping power in Aluminium to stopping power of the material
1282  with atomic number Z by adding it to the log of -(1/Z2)(dE/dx)
1283  This routine is for solids only.
1284  */
1285  void mpyers(double* le, int zt, double* f)
1286  {
1287 
1288  void splie2(double x1a[], double x2a[], double * ya[],
1289  int m, int n, double * y2a[]);
1290  void splin2(double x1a[], double x2a[], double * ya[], double * y2a[],
1291  int m, int n, double x1, double x2, double * y);
1292 
1293  double za[12] = {4., 6., 13., 22., 28., 32., 40., 47., 63., 73., 79., 92.};
1294 
1295  double ea[38] = {0.0125, .016, .02, .025, .032, .04, .05, .06, .07, .08, .09, .1,
1296  .125, .16, .2, .25, .32, .4, .5, .6, .7, .8, .9, 1., 1.25, 1.6, 2.,
1297  2.5, 3.2, 4., 5., 6., 7., 8., 9.0, 10., 11., 12.0
1298  };
1299 
1300  double fb[38][12] = {
1301  {1.6499, 1.3651, 1., .665, .5395, .4901, .454, .42, .2669, .2284, .21, .1799},
1302  {1.6501, 1.3652, 1., .6651, .54, .4901, .4541, .4201, .2671, .2285, .2099, .1801},
1303  {1.65, 1.365, 1., .6649, .54, .49, .454, .4199, .267, .2285, .2101, .1801},
1304  {1.65, 1.365, 1., .6649, .5401, .49, .4541, .42, .2669, .2286, .2105, .1801},
1305  {1.6482, 1.3662, 1., .6651, .541, .492, .454, .42, .267, .229, .2111, .1811},
1306  {1.6441, 1.3691, 1., .667, .544, .496, .457, .4231, .269, .2316, .2129, .1831},
1307  {1.638, 1.3729, 1., .67, .549, .4999, .461, .427, .271, .2354, .217, .1865},
1308  {1.632, 1.381, 1., .674, .554, .503, .465, .431, .276, .24, .2215, .1905},
1309  {1.625, 1.3901, 1., .678, .56, .508, .47, .436, .28, .245, .227, .195},
1310  {1.6181, 1.4021, 1., .683, .565, .5121, .473, .44, .285, .25, .231, .199},
1311  {1.611, 1.414, 1., .688, .57, .518, .477, .444, .291, .2545, .236, .2035},
1312  {1.6049, 1.427, 1., .693, .576, .522, .48, .449, .296, .259, .24, .207},
1313  {1.59, 1.467, 1., .704, .588, .533, .49, .459, .3075, .269, .2515, .2175},
1314  {1.569, 1.5251, 1., .716, .602, .546, .501, .47, .32, .281, .2635, .23},
1315  {1.548, 1.571, 1., .727, .615, .557, .511, .479, .332, .293, .275, .24},
1316  {1.523, 1.6021, 1., .739, .628, .57, .522, .489, .345, .305, .286, .25},
1317  {1.492, 1.621, 1., .753, .643, .587, .535, .5, .358, .318, .2985, .2625},
1318  {1.462, 1.623, 1., .762, .656, .6, .547, .511, .372, .331, .311, .273},
1319  {1.43, 1.607, 1., .773, .67, .615, .56, .522, .386, .344, .3235, .285},
1320  {1.402, 1.579, 1., .783, .682, .628, .57, .531, .397, .355, .3345, .297},
1321  {1.379, 1.548, 1., .79, .691, .637, .577, .538, .406, .363, .343, .304},
1322  {1.358, 1.514, 1., .797, .699, .647, .585, .545, .414, .372, .351, .312},
1323  {1.342, 1.483, 1., .802, .707, .656, .592, .551, .423, .38, .359, .32},
1324  {1.327, 1.453, 1., .809, .714, .663, .599, .557, .43, .387, .366, .327},
1325  {1.297, 1.389, 1., .82, .73, .68, .613, .569, .447, .403, .381, .341},
1326  {1.266, 1.327, 1., .835, .746, .697, .628, .58, .465, .421, .398, .357},
1327  {1.239, 1.293, 1., .847, .761, .714, .64, .593, .48, .438, .414, .373},
1328  {1.213, 1.271, 1., .859, .777, .73, .653, .606, .498, .453, .43, .39},
1329  {1.189, 1.256, 1., .87, .792, .745, .668, .618, .516, .472, .448, .407},
1330  {1.17, 1.246, 1., .879, .805, .758, .683, .63, .533, .488, .465, .423},
1331  {1.154, 1.237, 1., .886, .816, .77, .694, .642, .55, .502, .481, .439},
1332  {1.144, 1.23, 1., .892, .823, .78, .704, .651, .558, .515, .493, .453},
1333  {1.134, 1.225, 1., .896, .828, .787, .712, .659, .57, .524, .503, .463},
1334  {1.127, 1.22, 1., .9, .833, .792, .72, .665, .578, .533, .512, .472},
1335  {1.123, 1.215, 1., .903, .837, .797, .725, .671, .585, .54, .519, .48},
1336  {1.118, 1.21, 1., .907, .84, .801, .729, .677, .59, .547, .527, .487},
1337  {1.114, 1.207, 1., .91, .844, .805, .733, .683, .596, .554, .535, .493},
1338  {1.111, 1.203, 1., .912, .847, .809, .737, .688, .601, .56, .54, .498}
1339  };
1340 
1341  int i, j;
1342  static double lfb[38][12], y2b[38][12];
1343  static double* pfb[38], *py2b[38];
1344  static double lza[12], lea[38];
1345  double zl;
1346 
1347  if (!isw4) {
1348  for (i = 0 ; i < 38 ; i++) {
1349  lea[i] = log10(ea[i]);
1350  for (j = 0 ; j < 12 ; j++)
1351  lfb[i][j] = log10(fb[i][j]);
1352  }
1353  for (j = 0 ; j < 12 ; j++)
1354  lza[j] = log10(za[j]);
1355  for (i = 0 ; i < 38 ; i++) {
1356  pfb[i] = &(lfb[i])[0];
1357  py2b[i] = &(y2b[i])[0];
1358  }
1359  splie2(lza, lea, &pfb[0], 12, 38, &py2b[0]);
1360  isw4 = 1;
1361  }
1362 
1363  zl = log10(zt);
1364  if (*le < lea[0])
1365  *le = lea[0];
1366  splin2(lza, lea, &pfb[0], &py2b[0], 12, 38, zl, *le, f);
1367  }
1368 
1369 
1370  /*
1371 
1373 
1374  Given E/A (MeV/A) and the gas material atomic number Z, A
1375  logarithm F is calculated that should be used to convert
1376  stopping power in Aluminium to stopping power of the gas
1377  with atomic number Z by adding it to the log of -(1/Z2)(dE/dx)
1378  This routine is for gases only.
1379  */
1380  void gfact(double* le, int zt, double* f)
1381  {
1382 
1383  void splie2(double x1a[], double x2a[], double * ya[],
1384  int m, int n, double * y2a[]);
1385  void splin2(double x1a[], double x2a[], double * ya[], double * y2a[],
1386  int m, int n, double x1, double x2, double * y);
1387  unsigned int locate(double y[], int n, double x);
1388  double polint(double * xa, double * ya, int n, double x, double * dy);
1389 
1390  double za[9] = {1., 2., 7., 8., 10., 18., 36., 54., 86.};
1391 
1392  double ea[38] = {0.0125, .016, .02, .025, .032, .04, .05, .06, .07, .08, .09, .1,
1393  .125, .16, .2, .25, .32, .4, .5, .6, .7, .8, .9, 1., 1.25, 1.6, 2.,
1394  2.5, 3.2, 4., 5., 6., 7., 8., 9.0, 10., 11., 12.0
1395  };
1396 
1397  double far[38] = {0.584, .5891, .595, .607, .6251, .6461, .671, .6970, .722, .747,
1398  .771, .795, .851, .923, .985, 1.034, 1.0550, 1.051, 1.031, 1.001,
1399  .964, .928, .894, .871, .843, .8350, .842, .862, .885, .9, .909,
1400  .914, .918, .919, .9200, .92, .92, .9200
1401  };
1402 
1403  double fa[38][9] = {
1404  {6.4213, 2.7396, 1.8149, 1.7055, 1.5153, 1., .6132, .4349, .2868},
1405  {6.2480, 2.6351, 1.7709, 1.6654, 1.4804, 1., .6195, .4415, .2931},
1406  {6.0166, 2.4705, 1.7091, 1.6102, 1.4403, 1., .6235, .4536, .3036},
1407  {5.7334, 2.2751, 1.6345, 1.5404, 1.3939, 1., .6393, .4661, .3378},
1408  {5.4557, 2.0702, 1.5344, 1.4608, 1.3343, 1., .6495, .4895, .3408},
1409  {5.1854, 1.8853, 1.4441, 1.3900, 1.2800, 1., .6625, .5078, .3607},
1410  {4.9329, 1.7348, 1.3695, 1.3323, 1.2400, 1., .6736, .5246, .3800},
1411  {4.7917, 1.6397, 1.3299, 1.2854, 1.2152, 1., .6800, .5351, .3931},
1412  {4.6953, 1.5900, 1.3020, 1.2645, 1.1994, 1., .6815, .5415, .4003},
1413  {4.6454, 1.5596, 1.2866, 1.2504, 1.1901, 1., .6855, .5462, .4056},
1414  {4.6042, 1.5446, 1.2775, 1.2451, 1.1854, 1., .6873, .5499, .4072},
1415  {4.6038, 1.5447, 1.2805, 1.2403, 1.1799, 1., .6906, .5497, .4076},
1416  {4.6652, 1.5571, 1.2868, 1.2397, 1.1845, 1., .6886, .5488, .4078},
1417  {4.7995, 1.6002, 1.3131, 1.2654, 1.2004, 1., .6858, .5460, .4052},
1418  {4.9848, 1.6548, 1.3553, 1.3015, 1.2305, 1., .6802, .5401, .3990},
1419  {5.2418, 1.7351, 1.4072, 1.3549, 1.2650, 1., .6760, .5300, .3897},
1420  {5.6304, 1.8379, 1.4948, 1.4265, 1.3052, 1., .6673, .5204, .3801},
1421  {5.9373, 1.9601, 1.5566, 1.4796, 1.3397, 1., .6613, .5148, .3749},
1422  {6.1881, 2.0563, 1.5975, 1.5199, 1.3598, 1., .6595, .5150, .3754},
1423  {6.3436, 2.1279, 1.6104, 1.5305, 1.3676, 1., .6633, .5175, .3786},
1424  {6.3693, 2.1888, 1.6100, 1.5301, 1.3693, 1., .6691, .5207, .3848},
1425  {6.3254, 2.2198, 1.6045, 1.5301, 1.3674, 1., .6767, .5280, .3922},
1426  {6.2639, 2.2326, 1.5995, 1.5246, 1.3557, 1., .6823, .5391, .4005},
1427  {6.1883, 2.2377, 1.5970, 1.5155, 1.3502, 1., .6889, .5488, .4076},
1428  {5.8955, 2.2076, 1.5718, 1.5006, 1.3333, 1., .7022, .5670, .4282},
1429  {5.4133, 2.1198, 1.5306, 1.4635, 1.3102, 1., .7174, .5832, .4515},
1430  {4.9170, 2.0155, 1.4941, 1.4228, 1.2874, 1., .7304, .5998, .4715},
1431  {4.3851, 1.8851, 1.4397, 1.3701, 1.2645, 1., .7424, .6183, .4919},
1432  {3.9549, 1.7571, 1.3933, 1.3299, 1.2350, 1., .7605, .6328, .5073},
1433  {3.6667, 1.6578, 1.3555, 1.3000, 1.2222, 1., .7667, .6456, .5222},
1434  {3.4983, 1.5896, 1.3300, 1.2805, 1.2068, 1., .7778, .6567, .5390},
1435  {3.4027, 1.5471, 1.3151, 1.2648, 1.1980, 1., .7812, .6641, .5471},
1436  {3.3442, 1.5185, 1.3050, 1.2582, 1.1895, 1., .7865, .6710, .5545},
1437  {3.3080, 1.4962, 1.3003, 1.2546, 1.1850, 1., .7867, .6746, .5604},
1438  {3.2717, 1.4870, 1.2946, 1.2500, 1.1826, 1., .7881, .6772, .5652},
1439  {3.2500, 1.4837, 1.2946, 1.2500, 1.1826, 1., .7902, .6793, .5685},
1440  {3.2282, 1.4804, 1.2945, 1.2500, 1.1826, 1., .7924, .6815, .5707},
1441  {3.2066, 1.4772, 1.2946, 1.2500, 1.1826, 1., .7946, .6837, .5728}
1442  };
1443 
1444  int i, j;
1445  unsigned int jj;
1446  static double lfa[38][9], y2a[38][9];
1447  static double* pfa[38], *py2a[38];
1448  static double lza[9], lea[38], lfar[38];
1449  double zl, fgl, fgal, err;
1450 
1451  if (!isw3) {
1452  for (i = 0 ; i < 38 ; i++) {
1453  lea[i] = log10(ea[i]);
1454  lfar[i] = log10(far[i]);
1455  for (j = 0 ; j < 9 ; j++)
1456  lfa[i][j] = log10(fa[i][j]);
1457  }
1458  for (j = 0 ; j < 9 ; j++)
1459  lza[j] = log10(za[j]);
1460  for (i = 0 ; i < 38 ; i++) {
1461  pfa[i] = &(lfa[i])[0];
1462  py2a[i] = &(y2a[i])[0];
1463  }
1464  splie2(lza, lea, &pfa[0], 9, 38, &py2a[0]);
1465  isw3 = 1;
1466  }
1467  zl = log10(zt);
1468  if (*le < lea[0])
1469  *le = lea[0];
1470  splin2(lza, lea, &pfa[0], &py2a[0], 9, 38, zl, *le, &fgl);
1471  jj = locate(lea, 38, *le);
1472  if (jj > 35) jj = 35;
1473  fgal = polint(&lea[jj], &lfar[jj], 3, *le, &err);
1474  *f = fgl + fgal;
1475  }
1476 
1477 
1478  /*
1479 
1481 
1482  Get corresponding vectors of log(E/A) and log((dE/dx)/Z2) for a
1483  specific ion with charge Z in Aluminium
1484  */
1485  void alion(int zp, double* dedxz2)
1486  {
1487 
1488  void alref(double e, double * lz, double * dedx);
1489  unsigned int locate(double y[], int n, double x);
1490  double polint(double * xa, double * ya, int n, double x, double * dy);
1491 
1492  double elog[42] = {-1.903090, -1.795880, -1.698970, -1.602060, -1.494850,
1493  -1.397940, -1.301030, -1.221849, -1.154902, -1.096910,
1494  -1.045757, -1.000000, -0.903090, -0.795880, -0.698970,
1495  -0.602060, -0.494850, -0.397940, -0.301030, -0.221849,
1496  -0.154902, -0.096910, -0.045757, 0.000000, +0.096910,
1497  +0.204120, +0.301030, +0.397940, +0.505150, +0.602060,
1498  +0.698970, +0.778151, +0.845098, +0.903090, +0.954243,
1499  +1.000000, +1.041393, +1.079181, +1.301030, +1.602060,
1500  +1.845098, +2.000000
1501  };
1502 
1503  int j;
1504  unsigned int jj;
1505  double dedx[22], lz[22];
1506  double zlog, err;
1507 
1508  zlog = log10(zp);
1509 
1510  for (j = 0; j < 42 ; j++) {
1511  alref(elog[j], &lz[0], &dedx[0]);
1512  jj = locate(lz, 22, zlog);
1513  if (jj > 19) jj = 19;
1514  *(dedxz2 + j) = polint(&lz[jj], &dedx[jj], 3, zlog, &err);
1515  }
1516  }
1517 
1518 
1519  /*
1520 
1522 
1523  Data pool for aluminium -dE/dx/Z2.
1524  Call with energy E/A and get a series of log(Z) and log((-dE/dx)/Z2)
1525  */
1526  void alref(double le, double* lz, double* dedx)
1527  {
1528 
1529  unsigned int locate(double y[], int n, double x);
1530  double polint(double * xa, double * ya, int n, double x, double * dy);
1531 
1532  double zval[22] = {1., 2., 3., 4., 5., 6., 7., 8., 9., 10., 11., 12., 13., 16.,
1533  20., 25., 32., 40., 50., 61., 79., 100.
1534  };
1535 
1536  double elog[42] = {-1.903090, -1.795880, -1.698970, -1.602060, -1.494850,
1537  -1.397940, -1.301030, -1.221849, -1.154902, -1.096910,
1538  -1.045757, -1.000000, -0.903090, -0.795880, -0.698970,
1539  -0.602060, -0.494850, -0.397940, -0.301030, -0.221849,
1540  -0.154902, -0.096910, -0.045757, 0.000000, +0.096910,
1541  +0.204120, +0.301030, +0.397940, +0.505150, +0.602060,
1542  +0.698970, +0.778151, +0.845098, +0.903090, +0.954243,
1543  +1.000000, +1.041393, +1.079181, +1.301030, +1.602060,
1544  +1.845098, +2.000000
1545  };
1546 
1547  /* H; Z=1 */
1548  double h[42] = {-0.67572, -0.62160, -0.57349, -0.52143, -0.46980, -0.43063,
1549  -0.39794, -0.37779, -0.36653, -0.35952, -0.35655, -0.35655,
1550  -0.36351, -0.38195, -0.40782, -0.44129, -0.48545, -0.53018,
1551  -0.58004, -0.62709, -0.66555, -0.70115, -0.73049, -0.75945,
1552  -0.82102, -0.88941, -0.95468, -1.02228, -1.10237, -1.17393,
1553  -1.24413, -1.30103, -1.35655, -1.39794, -1.43180, -1.46852,
1554  -1.49485, -1.52288, -1.72584, -1.95861, -2.14874, -2.25181
1555  };
1556 
1557  /* He; Z=2 */
1558  double he[42] = {-0.87615, -0.82246, -0.77404, -0.72584, -0.67162, -0.62663,
1559  -0.58503, -0.55479, -0.53276, -0.51606, -0.50376, -0.49485,
1560  -0.48247, -0.48050, -0.48845, -0.50585, -0.53387, -0.56623,
1561  -0.60380, -0.64589, -0.68194, -0.71388, -0.74232, -0.76828,
1562  -0.82536, -0.89279, -0.95664, -1.02342, -1.09963, -1.17070,
1563  -1.24222, -1.30103, -1.35164, -1.39523, -1.43474, -1.46852,
1564  -1.49826, -1.53018, -1.70997, -1.94310, -2.13077, -2.23657
1565  };
1566 
1567  /* Li; Z=3 */
1568  double li[42] = {-1.03990, -0.98623, -0.93763, -0.88904, -0.83532, -0.78870,
1569  -0.74473, -0.71145, -0.68566, -0.66577, -0.65018, -0.63827,
1570  -0.61939, -0.60985, -0.61103, -0.61979, -0.63618, -0.65561,
1571  -0.67778, -0.70358, -0.72816, -0.75175, -0.77440, -0.79588,
1572  -0.84568, -0.90658, -0.96658, -1.02996, -1.10360, -1.17249,
1573  -1.24328, -1.30200, -1.35218, -1.39674, -1.43573, -1.47137,
1574  -1.50246, -1.53264, -1.70333, -1.93554, -2.11919, -2.22915
1575  };
1576 
1577  /* Be; Z=4 */
1578  double be[42] = {-1.16630, -1.11280, -1.06424, -1.01604, -0.96232, -0.91498,
1579  -0.86967, -0.83472, -0.80740, -0.78615, -0.76955, -0.75696,
1580  -0.73785, -0.72830, -0.72801, -0.73283, -0.74172, -0.75187,
1581  -0.76321, -0.77875, -0.79385, -0.80879, -0.82373, -0.83863,
1582  -0.87533, -0.92445, -0.97675, -1.03533, -1.10582, -1.17352,
1583  -1.24365, -1.30266, -1.35347, -1.39794, -1.43771, -1.47334,
1584  -1.50515, -1.53480, -1.70115, -1.92812, -2.11919, -2.22915
1585  };
1586 
1587  /* B; Z=5 */
1588  double b[42] = {-1.26857, -1.21496, -1.16673, -1.11827, -1.06449, -1.01827,
1589  -0.97469, -0.94157, -0.91578, -0.89551, -0.87943, -0.86646,
1590  -0.84430, -0.82786, -0.81976, -0.81667, -0.81793, -0.82206,
1591  -0.82822, -0.83791, -0.84783, -0.85811, -0.86864, -0.87943,
1592  -0.90714, -0.94692, -0.99140, -1.04383, -1.10969, -1.17496,
1593  -1.24413, -1.30277, -1.35379, -1.39881, -1.43890, -1.47470,
1594  -1.50808, -1.53820, -1.69897, -1.92812, -2.11351, -2.22915
1595  };
1596 
1597  /* C; Z=6 */
1598  double c[42] = {-1.36597, -1.31227, -1.26382, -1.21546, -1.16168, -1.11335,
1599  -1.06803, -1.03230, -1.00327, -0.97939, -0.95960, -0.94310,
1600  -0.91315, -0.88941, -0.87642, -0.86967, -0.86708, -0.86753,
1601  -0.86967, -0.87751, -0.88587, -0.89477, -0.90406, -0.91364,
1602  -0.93825, -0.97356, -1.01323, -1.06048, -1.12094, -1.18192,
1603  -1.24795, -1.30491, -1.35491, -1.39915, -1.43903, -1.47496,
1604  -1.50786, -1.53843, -1.69897, -1.92812, -2.10791, -2.23657
1605  };
1606 
1607  /* N; Z=7 */
1608  double n[42] = {-1.43468, -1.38099, -1.33264, -1.28417, -1.23065, -1.18207,
1609  -1.13789, -1.10316, -1.07498, -1.05171, -1.03209, -1.01543,
1610  -0.98331, -0.95348, -0.93242, -0.91721, -0.90694, -0.90295,
1611  -0.90309, -0.90873, -0.91546, -0.92289, -0.93091, -0.93930,
1612  -0.96160, -0.99419, -1.03152, -1.07625, -1.13389, -1.19230,
1613  -1.25579, -1.31053, -1.35877, -1.40150, -1.44002, -1.47509,
1614  -1.50693, -1.53638, -1.69897, -1.92812, -2.11351, -2.23657
1615  };
1616 
1617  /* O; Z=8 */
1618  double o[42] = {-1.51481, -1.46120, -1.41260, -1.36417, -1.31064, -1.26211,
1619  -1.21679, -1.18066, -1.15095, -1.12594, -1.10461, -1.08619,
1620  -1.04977, -1.01456, -0.98855, -0.96859, -0.95321, -0.94441,
1621  -0.93930, -0.94119, -0.94554, -0.95157, -0.95873, -0.96658,
1622  -0.98809, -1.01971, -1.05552, -1.09793, -1.15220, -1.20728,
1623  -1.26761, -1.32032, -1.36701, -1.40876, -1.44672, -1.48149,
1624  -1.51348, -1.54302, -1.70115, -1.92996, -2.11919, -2.23657
1625  };
1626 
1627  /* F; Z=9 */
1628  double f[42] = {-1.59335, -1.53983, -1.49135, -1.44295, -1.38931, -1.34087,
1629  -1.29243, -1.25489, -1.22382, -1.19744, -1.17473, -1.15490,
1630  -1.11504, -1.07534, -1.04469, -1.02002, -0.99984, -0.98727,
1631  -0.97881, -0.97881, -0.98183, -0.98680, -0.99298, -1.00000,
1632  -1.01946, -1.04827, -1.08092, -1.11968, -1.16939, -1.22033,
1633  -1.27653, -1.32619, -1.37067, -1.41086, -1.44759, -1.48149,
1634  -1.51281, -1.54206, -1.70333, -1.93554, -2.11919, -2.23657
1635  };
1636 
1637  /* Ne; Z=10 */
1638  double ne[42] = {-1.667562, -1.614036, -1.565431, -1.516984, -1.463442,
1639  -1.414991, -1.366532, -1.327440, -1.294821, -1.267044,
1640  -1.242984, -1.221849, -1.178814, -1.134837, -1.099851,
1641  -1.070581, -1.045661, -1.029374, -1.017729, -1.016554,
1642  -1.018544, -1.022505, -1.027751, -1.033858, -1.051294,
1643  -1.077638, -1.107905, -1.144118, -1.190912, -1.239050,
1644  -1.292430, -1.339704, -1.382161, -1.420559, -1.455684,
1645  -1.488117, -1.518128, -1.546223, -1.709965, -1.939302,
1646  -2.124939, -2.244125
1647  };
1648 
1649  /* Na; Z=11 */
1650  double na[42] = {-1.721058, -1.667311, -1.618892, -1.570501, -1.516820,
1651  -1.468416, -1.419933, -1.380786, -1.348226, -1.320407,
1652  -1.296389, -1.275318, -1.232446, -1.188746, -1.153929,
1653  -1.124556, -1.098528, -1.080058, -1.065126, -1.059368,
1654  -1.057930, -1.059286, -1.062507, -1.067048, -1.081744,
1655  -1.106069, -1.135107, -1.170563, -1.216675, -1.264098,
1656  -1.316521, -1.362626, -1.403721, -1.440816, -1.474580,
1657  -1.505523, -1.534028, -1.560602, -1.712198, -1.939302,
1658  -2.130768, -2.244125
1659  };
1660 
1661  /* Mg; Z=13 */
1662  double mg[42] = {-1.772578, -1.719030, -1.670517, -1.622183, -1.568525,
1663  -1.520073, -1.471637, -1.432043, -1.398770, -1.370336,
1664  -1.345650, -1.324005, -1.280013, -1.235689, -1.201234,
1665  -1.172622, -1.146496, -1.126147, -1.107635, -1.098269,
1666  -1.093830, -1.092708, -1.093905, -1.096722, -1.108137,
1667  -1.129466, -1.156326, -1.189926, -1.234445, -1.280588,
1668  -1.331705, -1.376751, -1.416896, -1.453012, -1.485895,
1669  -1.515997, -1.543782, -1.569643, -1.716699, -1.943095,
1670  -2.130768, -2.244125
1671  };
1672 
1673  /* Al; Z=13 */
1674  double al[42] = {-1.819477, -1.765788, -1.717342, -1.668938, -1.615315,
1675  -1.566832, -1.518362, -1.478769, -1.445056, -1.416178,
1676  -1.391120, -1.368989, -1.324092, -1.279083, -1.244712,
1677  -1.216274, -1.189346, -1.167302, -1.146395, -1.134325,
1678  -1.127585, -1.124494, -1.123946, -1.125247, -1.133765,
1679  -1.152303, -1.177082, -1.208978, -1.251858, -1.296734,
1680  -1.346616, -1.390614, -1.429789, -1.465058, -1.497104,
1681  -1.526405, -1.553485, -1.578552, -1.721246, -1.946922,
1682  -2.130768, -2.251812
1683  };
1684 
1685  /* S; Z=16 */
1686  double s[42] = {-1.940188, -1.886579, -1.838047, -1.789669, -1.736050,
1687  -1.687585, -1.639158, -1.599556, -1.566068, -1.536375,
1688  -1.510448, -1.487543, -1.440552, -1.393635, -1.358479,
1689  -1.328625, -1.298392, -1.272186, -1.246453, -1.229580,
1690  -1.218301, -1.211042, -1.206734, -1.204636, -1.206133,
1691  -1.217544, -1.236718, -1.263853, -1.302185, -1.343333,
1692  -1.389623, -1.430608, -1.467176, -1.500023, -1.529833,
1693  -1.557043, -1.582165, -1.605329, -1.739929, -1.954677,
1694  -2.142668, -2.251812
1695  };
1696 
1697  /* Ca; Z=20 */
1698  double ca[42] = {-2.075979, -2.021819, -1.972854, -1.923997, -1.869827,
1699  -1.820951, -1.771985, -1.732066, -1.698265, -1.668978,
1700  -1.643162, -1.619608, -1.570934, -1.521578, -1.483795,
1701  -1.450506, -1.415782, -1.385129, -1.354774, -1.334630,
1702  -1.320095, -1.309649, -1.302291, -1.297333, -1.292494,
1703  -1.296881, -1.310092, -1.331777, -1.364667, -1.401237,
1704  -1.443065, -1.480402, -1.513818, -1.543900, -1.571217,
1705  -1.596151, -1.619111, -1.640402, -1.761954, -1.968592,
1706  -2.148742, -2.259637
1707  };
1708 
1709  /* Mn; Z=25 */
1710  double mn[42] = {-2.225571, -2.170053, -2.119827, -2.069642, -2.014125,
1711  -1.963946, -1.913754, -1.872740, -1.838033, -1.807990,
1712  -1.781528, -1.757816, -1.707638, -1.655498, -1.613580,
1713  -1.575563, -1.535642, -1.500335, -1.465385, -1.442445,
1714  -1.425311, -1.412424, -1.402779, -1.395653, -1.385879,
1715  -1.384429, -1.392159, -1.408383, -1.435381, -1.466787,
1716  -1.503646, -1.537003, -1.567095, -1.594346, -1.619152,
1717  -1.641882, -1.662852, -1.682271, -1.787812, -1.982967,
1718  -2.161151, -2.267606
1719  };
1720 
1721  /* Ge; Z=32 */
1722  double ge[42] = {-2.400492, -2.343408, -2.291715, -2.240111, -2.182995,
1723  -2.131319, -2.079657, -2.037496, -2.001785, -1.970886,
1724  -1.943639, -1.919231, -1.867598, -1.810463, -1.763088,
1725  -1.718798, -1.672302, -1.631539, -1.591419, -1.564711,
1726  -1.544545, -1.529158, -1.517344, -1.508296, -1.494333,
1727  -1.487817, -1.490406, -1.500990, -1.521326, -1.546631,
1728  -1.577491, -1.606185, -1.632484, -1.656595, -1.678751,
1729  -1.699203, -1.718177, -1.735865, -1.823909, -2.002177,
1730  -2.187087, -2.283997
1731  };
1732 
1733  /* Zr; Z=40 */
1734  double zr[42] = {-2.561853, -2.503243, -2.450231, -2.397194, -2.338601,
1735  -2.285565, -2.232566, -2.189264, -2.152620, -2.120904,
1736  -2.092925, -2.067907, -2.014882, -1.956245, -1.903242,
1737  -1.852826, -1.799560, -1.753563, -1.709214, -1.677858,
1738  -1.654381, -1.636459, -1.622625, -1.611899, -1.594536,
1739  -1.584078, -1.582591, -1.588464, -1.602995, -1.622728,
1740  -1.648011, -1.672309, -1.695106, -1.716345, -1.736142,
1741  -1.754611, -1.771888, -1.788112, -1.861697, -2.026872,
1742  -2.200659, -2.301030
1743  };
1744 
1745  /* Sn; Z=50 */
1746  double sn[42] = {-2.721064, -2.660906, -2.606460, -2.552036, -2.491821,
1747  -2.437422, -2.383000, -2.338528, -2.300926, -2.268347,
1748  -2.239608, -2.213930, -2.159492, -2.099283, -2.044871,
1749  -1.990430, -1.930228, -1.878243, -1.830878, -1.794081,
1750  -1.766699, -1.745819, -1.729629, -1.716934, -1.695613,
1751  -1.680761, -1.675002, -1.676195, -1.685072, -1.699405,
1752  -1.719194, -1.739042, -1.758185, -1.776379, -1.793595,
1753  -1.809859, -1.825243, -1.839808, -1.913640, -2.060481,
1754  -2.229148, -2.318759
1755  };
1756 
1757  /* Pm; Z=61 */
1758  double pm[42] = {-2.859781, -2.798118, -2.742451, -2.686714, -2.625043,
1759  -2.569315, -2.513602, -2.468054, -2.429555, -2.396193,
1760  -2.366784, -2.340466, -2.284742, -2.223095, -2.167368,
1761  -2.111644, -2.049993, -1.993513, -1.942557, -1.901296,
1762  -1.870337, -1.846490, -1.827754, -1.812816, -1.786842,
1763  -1.766889, -1.756499, -1.752995, -1.756612, -1.766145,
1764  -1.781107, -1.797027, -1.812861, -1.828225, -1.842956,
1765  -1.857026, -1.870441, -1.883229, -1.958607, -2.096910,
1766  -2.259637, -2.337242
1767  };
1768 
1769  /* Au; Z=79 */
1770  double au[42] = {-3.042131, -2.978549, -2.921062, -2.863644, -2.800058,
1771  -2.742599, -2.685136, -2.638190, -2.598525, -2.564142,
1772  -2.533801, -2.506670, -2.449214, -2.385659, -2.328194,
1773  -2.270741, -2.207173, -2.149714, -2.092264, -2.047594,
1774  -2.012868, -1.985183, -1.962713, -1.944210, -1.910215,
1775  -1.881059, -1.862441, -1.851053, -1.846528, -1.849244,
1776  -1.857867, -1.868886, -1.880736, -1.892718, -1.904509,
1777  -1.915963, -1.927015, -1.937638, -2.017729, -2.154902,
1778  -2.288193, -2.361511
1779  };
1780 
1781  /* Fm; Z=100 */
1782  double fm[42] = {-3.208520, -3.143211, -3.084231, -3.025212, -2.959912,
1783  -2.900872, -2.841879, -2.793633, -2.752862, -2.717559,
1784  -2.686407, -2.658546, -2.599514, -2.534231, -2.475215,
1785  -2.416189, -2.350899, -2.291885, -2.232866, -2.188767,
1786  -2.152835, -2.122876, -2.097497, -2.075726, -2.033033,
1787  -1.992295, -1.962577, -1.940611, -1.925985, -1.921442,
1788  -1.924464, -1.931844, -1.941035, -1.950879, -1.960828,
1789  -1.970612, -1.980107, -1.989259, -2.070581, -2.193820,
1790  -2.309804, -2.371611
1791  };
1792 
1793  double err;
1794  int j;
1795  unsigned int jj;
1796 
1797  for (j = 0; j < 22 ; j++)
1798  *(lz + j) = log10(zval[j]);
1799 
1800  jj = locate(elog, 42, le);
1801  if (jj > 39) jj = 39;
1802 
1803  /* Interpolate data for Al to given energy for all standard ions */
1804 
1805  /* First hydrogen ions */
1806  *(dedx++) = polint(&elog[jj], &h[jj], 3, le, &err);
1807 
1808  /* Then Helium ions */
1809  *(dedx++) = polint(&elog[jj], &he[jj], 3, le, &err);
1810 
1811  /* Then Lithium ions */
1812  *(dedx++) = polint(&elog[jj], &li[jj], 3, le, &err);
1813 
1814  /* Then Beryllium ions */
1815  *(dedx++) = polint(&elog[jj], &be[jj], 3, le, &err);
1816 
1817  /* Then Bor ions */
1818  *(dedx++) = polint(&elog[jj], &b[jj], 3, le, &err);
1819 
1820  /* Then Carbon ions */
1821  *(dedx++) = polint(&elog[jj], &c[jj], 3, le, &err);
1822 
1823  /* Then Nitrogen ions */
1824  *(dedx++) = polint(&elog[jj], &n[jj], 3, le, &err);
1825 
1826  /* Then Oxygen ions */
1827  *(dedx++) = polint(&elog[jj], &o[jj], 3, le, &err);
1828 
1829  /* Then Fluorine ions */
1830  *(dedx++) = polint(&elog[jj], &f[jj], 3, le, &err);
1831 
1832  /* Then Neon ions */
1833  *(dedx++) = polint(&elog[jj], &ne[jj], 3, le, &err);
1834 
1835  /* Then Sodium ions */
1836  *(dedx++) = polint(&elog[jj], &na[jj], 3, le, &err);
1837 
1838  /* Then Magnesium ions */
1839  *(dedx++) = polint(&elog[jj], &mg[jj], 3, le, &err);
1840 
1841  /* Then Aluminium ions */
1842  *(dedx++) = polint(&elog[jj], &al[jj], 3, le, &err);
1843 
1844  /* Then Sulfur ions */
1845  *(dedx++) = polint(&elog[jj], &s[jj], 3, le, &err);
1846 
1847  /* Then Calcium ions */
1848  *(dedx++) = polint(&elog[jj], &ca[jj], 3, le, &err);
1849 
1850  /* Then Manganese ions */
1851  *(dedx++) = polint(&elog[jj], &mn[jj], 3, le, &err);
1852 
1853  /* Then Germanium ions */
1854  *(dedx++) = polint(&elog[jj], &ge[jj], 3, le, &err);
1855 
1856  /* Then Zirconium ions */
1857  *(dedx++) = polint(&elog[jj], &zr[jj], 3, le, &err);
1858 
1859  /* Then Tin ions */
1860  *(dedx++) = polint(&elog[jj], &sn[jj], 3, le, &err);
1861 
1862  /* Then Prometium ions */
1863  *(dedx++) = polint(&elog[jj], &pm[jj], 3, le, &err);
1864 
1865  /* Then Gold ions */
1866  *(dedx++) = polint(&elog[jj], &au[jj], 3, le, &err);
1867 
1868  /* Then Fermium ions */
1869  *(dedx++) = polint(&elog[jj], &fm[jj], 3, le, &err);
1870  }
1871 
1872 
1873 
1874  /*
1875 
1877 
1878  Interpolate for current value of s(2,a) function as given by
1879  F.Hubert, R.Rimbot and H.Gauvin, Atomic Data and Nuclear Data
1880  Tables, 1990, 46, pp. 1-213.
1881  */
1882  double s2az(double e, int zt)
1883  {
1884 
1885  void splie2(double x1a[], double x2a[], double * ya[],
1886  int m, int n, double * y2a[]);
1887  void splin2(double x1a[], double x2a[], double * ya[], double * y2a[],
1888  int m, int n, double x1, double x2, double * y);
1889 
1890  double za[18] = {4.0, 6.0, 13.0, 14.0, 22.0, 26.0, 28.0, 29.0, 32.0, 34.0, 40.0,
1891  47.0, 50.0, 64.0, 73.0, 79.0, 82.0, 92.0
1892  };
1893 
1894  double el[38] = {0.916291, 1.098612, 1.252763, 1.386294, 1.504077, 1.609438,
1895  1.704748, 1.791759, 1.871802, 1.945910, 2.079442, 2.197225,
1896  2.302585, 2.397895, 2.484907, 2.708050, 2.995732, 3.218876,
1897  3.401197, 3.555348, 3.688879, 3.806662, 3.912023, 4.007333,
1898  4.094345, 4.174387, 4.248495, 4.382027, 4.499810, 4.605170,
1899  5.010635, 5.298317, 5.521461, 5.703782, 5.857933, 5.991465,
1900  6.109248, 6.214608
1901  };
1902 
1903  static double sa2[18][38] = {
1904  {
1905  2.19060, 2.32662, 2.44357, 2.54625, 2.63806, 2.72038, 2.79565, 2.86470, 2.92901,
1906  2.98826, 3.09555, 3.19114, 3.27677, 3.35455, 3.42575, 3.60822, 3.84436, 4.02575,
1907  4.17501, 4.29953, 4.40693, 4.50104, 4.58488, 4.66015, 4.72819, 4.79060, 4.84820,
1908  4.95048, 5.04019, 5.11892, 5.41429, 5.61371, 5.75009, 5.85432, 5.93698, 6.00455,
1909  6.06082, 6.10800
1910  },
1911  {
1912  2.12549, 2.25929, 2.37462, 2.47575, 2.56623, 2.64754, 2.72190, 2.79035, 2.85337,
1913  2.91231, 3.01849, 3.11283, 3.19785, 3.27479, 3.34529, 3.52676, 3.76038, 3.94119,
1914  4.08936, 4.21313, 4.31999, 4.41372, 4.49699, 4.57174, 4.63976, 4.70168, 4.75890,
1915  4.86103, 4.94978, 5.02829, 5.32210, 5.51089, 5.64575, 5.75009, 5.83275, 5.89980,
1916  5.95610, 6.00253
1917  },
1918  {
1919  2.35942, 2.48561, 2.59461, 2.69082, 2.77700, 2.85467, 2.92574, 2.99124, 3.05177,
1920  3.10834, 3.21078, 3.30158, 3.38360, 3.45777, 3.52591, 3.70095, 3.92841, 4.10440,
1921  4.24925, 4.37010, 4.47392, 4.56547, 4.64677, 4.72002, 4.78639, 4.84724, 4.90290,
1922  5.00267, 5.09008, 5.16685, 5.45439, 5.64292, 5.77635, 5.87814, 5.95900, 6.02606,
1923  6.08139, 6.12728
1924  },
1925  {
1926  2.33666, 2.46187, 2.57047, 2.66607, 2.75161, 2.82895, 2.89951, 2.96472, 3.02516,
1927  3.08129, 3.18327, 3.27346, 3.35527, 3.42883, 3.49661, 3.67202, 3.89837, 4.07454,
1928  4.21821, 4.33897, 4.44241, 4.53378, 4.61522, 4.68828, 4.75454, 4.81527, 4.87109,
1929  4.97081, 5.05812, 5.13492, 5.42275, 5.61783, 5.75324, 5.85519, 5.93603, 6.00152,
1930  6.05654, 6.10240
1931  },
1932  {
1933  2.52604, 2.64649, 2.75161, 2.84387, 2.92667, 3.00175, 3.07046, 3.13385, 3.19236,
1934  3.24740, 3.34671, 3.43501, 3.51409, 3.58723, 3.65351, 3.82470, 4.04698, 4.21991,
1935  4.36027, 4.47854, 4.58194, 4.67184, 4.75222, 4.82426, 4.88952, 4.94942, 5.00490,
1936  5.10316, 5.18946, 5.26537, 5.54999, 5.73837, 5.87013, 5.97166, 6.05122, 6.11703,
1937  6.17179, 6.21711
1938  },
1939  {
1940  2.58296, 2.70008, 2.80222, 2.89273, 2.97348, 3.04703, 3.11452, 3.17666, 3.23399,
1941  3.28809, 3.38582, 3.47216, 3.55086, 3.62216, 3.68788, 3.85730, 4.07601, 4.24750,
1942  4.38805, 4.50533, 4.60667, 4.69592, 4.77537, 4.84692, 4.91204, 4.97154, 5.02600,
1943  5.12394, 5.20939, 5.28491, 5.56816, 5.75324, 5.88351, 5.98449, 6.06404, 6.12958,
1944  6.18384, 6.22972
1945  },
1946  {
1947  2.59931, 2.71394, 2.81383, 2.90270, 2.98232, 3.05442, 3.12073, 3.18206, 3.23844,
1948  3.29145, 3.38803, 3.47377, 3.55173, 3.62216, 3.68688, 3.85493, 4.07307, 4.24227,
1949  4.38203, 4.49856, 4.60018, 4.68910, 4.76828, 4.83931, 4.90425, 4.96328, 5.01804,
1950  5.11558, 5.20028, 5.27557, 5.55709, 5.74071, 5.87102, 5.97166, 6.05122, 6.11590,
1951  6.17059, 6.21586
1952  },
1953  {
1954  2.65962, 2.77379, 2.87307, 2.96133, 3.04073, 3.11227, 3.17845, 3.23972, 3.29616,
1955  3.34884, 3.44515, 3.53102, 3.60822, 3.67794, 3.74334, 3.91077, 4.12738, 4.29769,
1956  4.43543, 4.55400, 4.65384, 4.74271, 4.82177, 4.89285, 4.95721, 5.01653, 5.07078,
1957  5.16817, 5.25334, 5.32826, 5.60961, 5.79425, 5.92474, 6.02399, 6.10351, 6.16820,
1958  6.22214, 6.26722
1959  },
1960  {
1961  2.71018, 2.82304, 2.92155, 3.00932, 3.08785, 3.15943, 3.22515, 3.28542, 3.34175,
1962  3.39397, 3.49003, 3.57466, 3.65158, 3.72140, 3.78649, 3.95285, 4.16853, 4.33897,
1963  4.47634, 4.59275, 4.69373, 4.78221, 4.86103, 4.93194, 4.99636, 5.05537, 5.10977,
1964  5.20665, 5.29134, 5.36660, 5.64717, 5.80914, 5.93982, 6.03961, 6.12044, 6.18505,
1965  6.23993, 6.28584
1966  },
1967  {
1968  2.75436,
1969  2.86558, 2.96278, 3.04913, 3.12641, 3.19724, 3.26231, 3.32216, 3.37773, 3.42960,
1970  3.52421, 3.60914, 3.68489, 3.75502, 3.81899, 3.98459, 4.19971, 4.36812, 4.50533,
1971  4.62283, 4.72283, 4.81097, 4.88986, 4.96042, 5.02486, 5.08401, 5.13790, 5.23534,
1972  5.32005, 5.39483, 5.67520, 5.84305, 5.97264, 6.07268, 6.15281, 6.21837, 6.27118,
1973  6.31720
1974  },
1975  {
1976  2.77780, 2.88822, 2.98479, 3.07046, 3.14714, 3.21763, 3.28208, 3.34104, 3.39621,
1977  3.44750, 3.54132, 3.62497, 3.70095, 3.77009, 3.83275, 3.99676, 4.20976, 4.37605,
1978  4.51442, 4.62793, 4.72819, 4.81558, 4.89352, 4.96363, 5.02753, 5.08603, 5.14003,
1979  5.23628, 5.32056, 5.39483, 5.67374, 5.85956, 5.98847, 6.08798, 6.16582, 6.23099,
1980  6.28449, 6.32974
1981  },
1982  {
1983  2.86734, 2.97446, 3.06884, 3.15239, 3.22766, 3.29616, 3.35886, 3.41733, 3.47135,
1984  3.52167, 3.61377, 3.69590, 3.77009, 3.83854, 3.90084, 4.06139, 4.27228, 4.43543,
1985  4.57077, 4.68313, 4.78161, 4.86783, 4.94485, 5.01389, 5.07678, 5.13450, 5.18767,
1986  5.28244, 5.36553, 5.43873, 5.71383, 5.89797, 6.02502, 6.12385, 6.20219, 6.26590,
1987  6.31858, 6.36398
1988  },
1989  {
1990  2.92667, 3.03240, 3.12527, 3.20769, 3.28208, 3.34955, 3.41201, 3.46974, 3.52337,
1991  3.57288, 3.66419, 3.74651, 3.82013, 3.88733, 3.94895, 4.10895, 4.31811, 4.48141,
1992  4.61522, 4.72847, 4.82644, 4.91238, 4.98900, 5.05812, 5.12101, 5.17876, 5.23159,
1993  5.32620, 5.40925, 5.48284, 5.75718, 5.94077, 6.06835, 6.16701, 6.24507, 6.30892,
1994  6.36253, 6.40698
1995  },
1996  {
1997  3.03812, 3.14018, 3.22956, 3.30907, 3.38140, 3.44672, 3.50739, 3.56313, 3.61563,
1998  3.66419, 3.75289, 3.83275, 3.90455, 3.97124, 4.03137, 4.18827, 4.39369, 4.55448,
1999  4.68638, 4.79815, 4.89485, 4.97986, 5.05537, 5.12394, 5.18588, 5.24288, 5.29532,
2000  5.38934, 5.47089, 5.54358, 5.81583, 6.00051, 6.12958, 6.22719, 6.30481, 6.36834,
2001  6.42071, 6.46467
2002  },
2003  {
2004  3.15063, 3.24612, 3.32981, 3.40521, 3.47377, 3.53702, 3.59448, 3.64870, 3.69893,
2005  3.74545, 3.83160, 3.90828, 3.97790, 4.04270, 4.10137, 4.25416, 4.45524, 4.61295,
2006  4.74271, 4.85235, 4.94766, 5.03135, 5.10605, 5.17345, 5.23487, 5.29134, 5.34279,
2007  5.43586, 5.51710, 5.58867, 5.85781, 6.04066, 6.17299, 6.26986, 6.34671, 6.40850,
2008  6.46147, 6.50563
2009  },
2010  {
2011  3.21016, 3.30294, 3.38508, 3.45856, 3.52591, 3.58723, 3.64391, 3.69590, 3.74545,
2012  3.79091, 3.87521, 3.95154, 4.02017, 4.08341, 4.14144, 4.29182, 4.49006, 4.64573,
2013  4.77389, 4.88257, 4.97660, 5.05969, 5.13365, 5.20028, 5.26150, 5.31699, 5.36820,
2014  5.46025, 5.54103, 5.61234, 5.88082, 6.06189, 6.19358, 6.28987, 6.36543, 6.42842,
2015  6.47923, 6.52420
2016  },
2017  {
2018  3.21763, 3.31113, 3.39323, 3.46734, 3.53530, 3.59630, 3.65351, 3.70603, 3.75609,
2019  3.80205, 3.88733, 3.96332, 4.03137, 4.09535, 4.15250, 4.30451, 4.50329, 4.65963,
2020  4.78819, 4.89720, 4.99157, 5.07477, 5.14904, 5.21582, 5.27656, 5.33239, 5.38388,
2021  5.47625, 5.55644, 5.62821, 5.89615, 6.07811, 6.20962, 6.30481, 6.38155, 6.44402,
2022  6.49565, 6.53965
2023  },
2024  {
2025  3.26035, 3.35455, 3.43812, 3.51325, 3.58092, 3.64391, 3.70095, 3.75395, 3.80429,
2026  3.85022, 3.93478, 4.01184, 4.08044, 4.14459, 4.20304, 4.35363, 4.55234, 4.70859,
2027  4.83679, 4.94555, 5.03942, 5.12227, 5.19666, 5.26343, 5.32415, 5.37953, 5.43071,
2028  5.52271, 5.60349, 5.67447, 5.94172, 6.12044, 6.24507, 6.34102, 6.41611, 6.47923,
2029  6.53103, 6.57307
2030  }
2031  };
2032 
2033  int i;
2034  static double y2a[18][38];
2035  static double* psa2[18], *py2a[18];
2036  double sa2ln;
2037  double le;
2038 
2039  if (!isw5) {
2040  for (i = 0 ; i < 18 ; i++) {
2041  psa2[i] = &(sa2[i])[0];
2042  py2a[i] = &(y2a[i])[0];
2043  }
2044  splie2(el, za, &psa2[0], 38, 18, &py2a[0]);
2045  isw5 = 1;
2046  }
2047  le = log(e);
2048  splin2(el, za, &psa2[0], &py2a[0], 38, 18, le, zt, &sa2ln);
2049  return exp(-sa2ln);
2050  }
2051 
2052 
2053 
2054 
2056 
2057  double polint(double* xa, double* ya, int n, double x, double* dy)
2058  {
2059 
2060  double y, c[n], d[n];
2061  int i, m, ns = 1;
2062  double den, dif, dift, ho, hp, w;
2063 
2064  dif = fabs(x - *xa);
2065 
2066  for (i = 0 ; i < n ; i++) {
2067  dift = fabs(x - * (xa + i));
2068  if (dift < dif) {
2069  ns = i + 1;
2070  dif = dift;
2071  }
2072  c[i] = d[i] = *(ya + i);
2073  }
2074  y = *(ya + ns - 1);
2075  ns--;
2076  for (m = 0 ; m < n - 1 ; m++) {
2077  for (i = 0 ; i < n - m - 1 ; i++) {
2078  ho = *(xa + i) - x;
2079  hp = *(xa + i + m + 1) - x;
2080  w = c[i + 1] - d[i];
2081  den = ho - hp;
2082  if (den == 0.0)
2083  exit(0);
2084  den = w / den;
2085  d[i] = hp * den;
2086  c[i] = ho * den;
2087  }
2088  if (2 * ns < n - m - 1)
2089  *dy = c[ns];
2090  else {
2091  *dy = d[ns - 1];
2092  ns--;
2093  }
2094  y += *dy;
2095  }
2096  *dy = fabs(*dy);
2097  return y;
2098  }
2099 
2100 
2101 
2102 
2104 
2105  unsigned int locate(double y[], int n, double x)
2106  {
2107 
2108  unsigned int jl, jm, ju;
2109 
2110  jl = 0;
2111  ju = n;
2112 
2113  while ((ju - jl) > 1) {
2114  jm = (ju + jl) / 2;
2115  if ((y[n - 1] > y[1]) && (x > y[jm]))
2116  jl = jm;
2117  else
2118  ju = jm;
2119  }
2120  return jl;
2121  }
2122 
2123 
2124 
2125 
2127 
2128  void splie2(double [], double x2a[], double* ya[],
2129  int m, int n, double* y2a[])
2130  {
2131 
2132  void spline(double x[], double y[], int n, double yp1, double ypn, double * y2);
2133 
2134  double ytmp[n], y2tmp[n];
2135  int i, j;
2136 
2137  for (j = 0 ; j < m ; j++) {
2138  for (i = 0 ; i < n ; i++) {
2139  ytmp[i] = *(ya[i] + j);
2140  }
2141 
2142  spline(x2a, ytmp, n, 1.0e30, 1.0e30, &y2tmp[0]);
2143  for (i = 0 ; i < n ; i++) {
2144  *(y2a[i] + j) = y2tmp[i];
2145  }
2146  }
2147  }
2148 
2149 
2150 
2151 
2153 
2154  void splin2(double x1a[], double x2a[], double* ya[], double* y2a[],
2155  int m, int n, double x1, double x2, double* y)
2156  {
2157 
2158  void spline(double x[], double y[], int n, double yp1, double ypn, double * y2);
2159  void splint(double xa[], double ya[], double y2a[],
2160  int n, double x, double * y);
2161 
2162  double ytmp[n], y2tmp[n], yytmp[m];
2163  int i, j;
2164 
2165  for (j = 0 ; j < m ; j++) {
2166  for (i = 0 ; i < n ; i++) {
2167  ytmp[i] = *(ya[i] + j);
2168  y2tmp[i] = *(y2a[i] + j);
2169  }
2170  splint(x2a, ytmp, y2tmp, n, x2, &yytmp[j]);
2171  }
2172  spline(x1a, yytmp, m, 1.0e30, 1.0e30, &y2tmp[0]);
2173  splint(x1a, yytmp, y2tmp, m, x1, y);
2174  }
2175 
2176 
2177 
2178 
2180 
2181  void spline(double x[], double y[], int n, double yp1, double ypn, double* y2)
2182  {
2183 
2184  int k;
2185  double p, qn, sig, un, u[200];
2186  int m = n - 1;
2187 
2188  if (yp1 > 0.99e30)
2189  *y2 = u[0] = 0.0;
2190  else {
2191  *y2 = -0.5;
2192  u[0] = (3.0 / (x[1] - x[0])) * ((y[1] - y[0]) / (x[1] - x[0]) - yp1);
2193  }
2194  for (k = 1 ; k < n - 1 ; k++) {
2195  sig = (x[k] - x[k - 1]) / (x[k + 1] - x[k - 1]);
2196  p = *(y2 + k - 1) * sig + 2.0;
2197  *(y2 + k) = (sig - 1.0) / p;
2198  u[k] = (6.0 * ((y[k + 1] - y[k]) / (x[k + 1] - x[k]) -
2199  (y[k] - y[k - 1]) / (x[k] - x[k - 1])) /
2200  (x[k + 1] - x[k - 1]) - sig * u[k - 1]) / p;
2201  }
2202  if (ypn > 0.99e30)
2203  qn = un = 0.0;
2204  else {
2205  qn = 0.5;
2206  un = (3.0 / (x[m] - x[m - 1])) *
2207  (ypn - (y[m] - y[m - 1]) / (x[m] - x[m - 1]));
2208  }
2209  *(y2 + m) = (un - qn * u[m - 1]) / (*(y2 + m - 1) * qn + 1.0);
2210  for (k = m - 1 ; k >= 0 ; k--) {
2211  *(y2 + k) *= *(y2 + k + 1);
2212  *(y2 + k) += u[k];
2213  }
2214  }
2215 
2216 
2217 
2218 
2220 
2221  void splint(double xa[], double ya[], double y2a[],
2222  int n, double x, double* y)
2223  {
2224 
2225  int k, klo, khi;
2226  double a, b, h;
2227 
2228  klo = 1;
2229  khi = n;
2230 
2231  while (khi - klo > 1) {
2232  k = (khi + klo) >> 1;
2233  if (xa[k - 1] > x)
2234  khi = k;
2235  else
2236  klo = k;
2237  }
2238  klo--;
2239  khi--;
2240  h = xa[khi] - xa[klo];
2241  if (h == 0.0) {
2242  printf("Bad xa input in splint.\n");
2243  exit(0);
2244  }
2245  a = (xa[khi] - x) / h;
2246  b = (x - xa[klo]) / h;
2247  *y = a * ya[klo] + b * ya[khi] +
2248  ((pow(a, 3) - a) * y2a[klo] + (pow(b, 3) - b) * y2a[khi]) * (h * h) / 6.0;
2249  }
2250 
2251 }
2252 
int Int_t
ClassImp(KVPartitionList) void KVPartitionList
Initialisation.
#define FMT
#define NMAX
#define NELMAX
#define SMOOTHERSTEP(x)
#define NSAV
ROOT::R::TRInterface & r
#define d(i)
#define b(i)
#define f(i)
#define c(i)
#define e(i)
char Char_t
double Double_t
double pow(double, double)
double log10(double)
double exp(double)
double log(double)
char * Form(const char *fmt,...)
const Char_t * GetType() const
Definition: KVBase.h:170
Material for use in energy loss & range calculations.
TF1 * fDeltaE
function parameterising energy loss in material
const Char_t * GetSymbol() const
TF1 * fEres
function parameterising residual energy after crossing material
TF1 * fRange
function parameterising range of charged particles in material
KVList * fComposition
composition of compound/mixture
Abstract base class for calculation of range & energy loss of charged particles in matter.
Handles lists of named parameters with different types, a list of KVNamedParameter objects.
Int_t GetIntValue(const Char_t *name) const
Double_t GetDoubleValue(const Char_t *name) const
Description of properties and kinematics of atomic nuclei.
Definition: KVNucleus.h:125
const Char_t * GetSymbol(Option_t *opt="") const
Definition: KVNucleus.cpp:81
Description of absorber for the Range dE/dx and range library.
TF1 * GetRangeFunction(Int_t Z, Int_t A, Double_t isoAmat=0)
TF1 * GetEResFunction(Double_t e, Int_t Z, Int_t A, Double_t isoAmat=0)
Int_t Ap
Z,A of incident projectile ion.
Double_t thickness
in g/cm**2
Int_t fNelem
number of elements in material
Int_t fTableType
=0 for Northcliffe-Schilling (<12 MeV/u), =1 for Hubert et al (2.5<E/A<500 MeV), =2 for interpolated ...
void PrepareRangeLibVariables(Int_t Z, Int_t A)
KVRangeYanezMaterial()
Default constructor.
TF1 * GetDeltaEFunction(Double_t e, Int_t Z, Int_t A, Double_t isoAmat=0)
Int_t iabso
value of iabso argument for function calls
Double_t RangeFunc(Double_t *, Double_t *)
virtual ~KVRangeYanezMaterial()
Destructor.
void Copy(TObject &) const
Double_t EResFunc(Double_t *, Double_t *)
Double_t DeltaEFunc(Double_t *, Double_t *)
Double_t error
calculated error in MeV
struct KVRangeYanezMaterial::Elem fAbsorb[10]
list of elements
virtual Double_t GetEIncFromEResOfIon(Int_t Z, Int_t A, Double_t Eres, Double_t e, Double_t isoAmat=0.)
void SaveMaterial(ofstream &matfile)
virtual TObject * FindObject(const char *name) const
const char * AsString() const
virtual Double_t GetMinimumX(Double_t xmin=0, Double_t xmax=0, Double_t epsilon=1.E-10, Int_t maxiter=100, Bool_t logx=false) const
virtual void SetRange(Double_t xmin, Double_t xmax)
virtual void SetNpx(Int_t npx=100)
virtual const char * GetName() const
const char * Data() const
VecExpr< UnaryOp< Sqrt< T >, SVector< T, D >, T >, T, D > sqrt(const SVector< T, D > &rhs)
VecExpr< UnaryOp< Fabs< T >, SVector< T, D >, T >, T, D > fabs(const SVector< T, D > &rhs)
Double_t y[n]
Double_t x[n]
const Int_t n
TH1 * h
const long double s
Definition: KVUnits.h:94
const long double mg
Definition: KVUnits.h:74
const long double fm
Definition: KVUnits.h:67
const long double m
Definition: KVUnits.h:70
constexpr Double_t E()
constexpr Double_t R()
Double_t Max(Double_t a, Double_t b)
double polint(double *xa, double *ya, int n, double x, double *dy)
double ededxh(double e, int zp, int zt)
void gfact(double *le, int zt, double *f)
struct range::elem absorb[NELMAX]
double thickn(int icorr, int zp, int ap, int iabso, int zt, int at, double ein, double delen)
void splie2(double[], double x2a[], double *ya[], int m, int n, double *y2a[])
void alref(double le, double *lz, double *dedx)
void splint(double xa[], double ya[], double y2a[], int n, double x, double *y)
void def_absorber(int zt, int at, int iabso)
void splin2(double x1a[], double x2a[], double *ya[], double *y2a[], int m, int n, double x1, double x2, double *y)
double rangen(int icorr, int zp, int ap, int iabso, int zt, int at, double ein)
double dedx(int icorr, double e, int zp, int ap, int zt, int at)
double egassap(int icorr, int zp, int ap, int iabso, int zt, int at, double t, double eut, double *err)
void alion(int zp, double *dedxz2)
double ededx(double e, int zp, int zt)
void rangetab(int icorr, int zp, int ap, int iabso, int zt, int at, double *em, double *r, int *n)
struct elem cmpnd[NELMAX]
void mpyers(double *le, int zt, double *f)
void dedxtab(int icorr, int zp, int ap, int iabso, int zt, int at, double e, double *tdedxe, double *tdedxn)
double ndedx(double e, int zp, int ap, int zt, int at)
double passage(int icorr, int zp, int ap, int iabso, int zt, int at, double ein, double t, double *err)
double s2az(double e, int zt)
void spline(double x[], double y[], int n, double yp1, double ypn, double *y2)
unsigned int locate(double y[], int n, double x)
auto * a