KaliVeda  1.13/01
Heavy-Ion Analysis Toolkit
KVRangeYanez.cpp
Go to the documentation of this file.
1 //Created by KVClassFactory on Thu Sep 27 14:48:55 2012
2 //Author: John Frankland,,,
3 
4 #include "KVRangeYanez.h"
5 #include "KVRangeYanezMaterial.h"
6 #include "KVElementDensity.h"
8 #include "KVNDTManager.h"
9 #include "TString.h"
10 #include "KVNucleus.h"
11 #include "KVNumberList.h"
12 #include <KVSystemDirectory.h>
13 #include <KVSystemFile.h>
14 #include <Riostream.h>
15 using namespace std;
16 
18 
20 
21 
40 
42  : KVIonRangeTable("RANGE",
43  "Interface to Range dE/dx and range library (Ricardo Yanez)")
44 {
45  // Default constructor
46  //
47  // Predefined materials are created based on the contents of the file(s) whose
48  // names are given as values of the variable `RANGE.PredefMaterials`
49  //
50  // A default file is specified in the main `.kvrootrc` file.
51  //
52  // If you want to add your own definitions, just put in your `.kvrootrc` file:
53  //~~~~~~~~~~~
54  //+RANGE.PredefMaterials: myfile1.dat
55  //+RANGE.PredefMaterials: myfile2.dat
56  //~~~~~~~~~~~
57  // If you want to override the default definitions:
58  //~~~~~~~~~~~
59  //RANGE.PredefMaterials: myfile1.dat
60  //+RANGE.PredefMaterials: myfile2.dat
61  //~~~~~~~~~~~
62 
63  KVString DataFilePaths = gEnv->GetValue("RANGE.PredefMaterials", "");
64  DataFilePaths.Begin(" ");
65  KVString nextPath;
66  KVString lastPath;
67  while (!DataFilePaths.End()) {
68  nextPath = DataFilePaths.Next();
69  if (nextPath == lastPath) break; //check for double occurrence of last file : TEnv bug?
70  lastPath = nextPath;
71  ReadMaterials(nextPath);
72  }
73 
74  // directory where any materials defined by user are stored
77  // read all materials in directory if it exists
79  TIter nxtfil(matDir.GetListOfFiles());
80  KVSystemFile* fil;
81  while ((fil = (KVSystemFile*)nxtfil())) {
82  if (TString(fil->GetName()).EndsWith(".dat")) ReadMaterials(fil->GetFullPath());
83  }
84  }
86 }
87 
88 
89 
90 
92 
94 {
95  obj.Copy(*this);
96 }
97 
98 
99 
100 
102 
103 void KVRangeYanez::Copy(TObject& obj) const
104 {
106  KVRangeYanez& CastedObj = (KVRangeYanez&)obj;
109 }
110 
111 
112 
117 
119 {
120  // Returns pointer to material of given name or type if it has been defined.
121  //
122  // \param[in] material name or type of material to retrieve
123 
126  if (!M) {
128  }
129  return M;
130 }
131 
132 
133 
135 
137 {
138  printf("KVRangeYanez::%s\n%s\n", GetName(), GetTitle());
139  Int_t n = (fMaterials ? fMaterials->GetEntries() : 0);
140  if (n) {
141  printf("\nEnergy loss & range tables loaded for %d materials:\n\n", fMaterials->GetEntries());
142  fMaterials->Print();
143  }
144  else
145  printf("\nEnergy loss & range tables loaded for 0 materials.\n");
146 }
147 
148 
149 
156 
158 {
159  // Create and fill a list of all materials for which range tables exist.
160  //
161  // Each entry is a TNamed with the name and type (title) of the material.
162  //
163  // User's responsibility to delete list after use (it owns its objects).
164 
165  TObjArray* list = new TObjArray(fMaterials->GetEntries());
166  list->SetOwner(kTRUE);
167  TIter next(fMaterials);
169  while ((mat = (KVIonRangeTableMaterial*)next())) {
170  list->Add(new TNamed(mat->GetName(), mat->GetType()));
171  }
172  return list;
173 }
174 
175 
177 
179 {
180  if (!fMaterials) {
181  fMaterials = new KVHashList;
182  fMaterials->SetName("RANGE materials list");
183  fMaterials->SetOwner();
184  }
185 }
186 
187 
205 
207 {
208  // Adds a material composed of a single chemical element.
209  //
210  // \param[in] z atomic number \f$Z\f$ of element
211  // \param[in] a [optional] mass number \f$A\f$ of isotope
212  //
213  // If the mass number of the isotope \f$A\f$ is not specified, we create a material containing the naturally
214  // occuring isotopes of the given element, weighted according to natural abundance.
215  //
216  // If the mass is given, the material symbol will be `"AX"` where `X` is the symbol for the element
217  // - e.g. `"48Ca"`, `"124Sn"`, etc.
218  //
219  // and the material name will be `"Xxx-A"` where `Xxx` is the name of the element
220  // - e.g. `"Calcium-48"`, `"Tin-124"`, etc.
221  //
222  // Otherwise, we just use the element symbol and name for naturally-occurring
223  // mixtures of atomic elements (`"Ca"`, `"Calcium"`, etc.).
224 
226  if (!a) mat = MakeNaturallyOccuringElementMixture(z, a); // this may set a!=0 if only one isotope exists in nature
227  if (a) {
228  if (!gNDTManager) {
229  Error("AddElementalMaterial",
230  "Nuclear data tables have not been initialised");
231  return nullptr;
232  }
233  KVElementDensity* ed = (KVElementDensity*)gNDTManager->GetData(z, a, "ElementDensity");
234  if (!ed) {
235  Error("AddElementalMaterial",
236  "No element found in ElementDensity NDT-table with Z=%d", z);
237  return nullptr;
238  }
239  TString state = "solid";
240  if (ed->IsGas()) state = "gas";
241  mat = new KVRangeYanezMaterial(this, Form("%s-%d", ed->GetElementName(), a),
242  Form("%d%s", a, ed->GetElementSymbol()),
243  state, ed->GetValue(), z, a);
244  mat->Initialize();
245  }
247  fMaterials->Add(mat);
249  return mat;
250 }
251 
252 
253 
264 
266  const Char_t* name, const Char_t* symbol,
267  Int_t nelem, Int_t* z, Int_t* a, Int_t* natoms, Double_t density) const
268 {
269  // Adds a compound material with a simple formula composed of different elements
270  //
271  // \param[in] name name for the new compound (no spaces)
272  // \param[in] symbol chemical symbol for compound
273  // \param[in] nelem number of elements in compound
274  // \param[in] z[nelem] atomic numbers of elements
275  // \param[in] a[nelem] mass numbers of elements
276  // \param[in] natoms[nelem] number of atoms of each element
277  // \param[in] density in \f$g/cm^{3}\f$, only required if compound is a solid
278 
279  TString state = "gas";
280  if (density > 0) state = "solid";
281  KVRangeYanezMaterial* mat =
282  new KVRangeYanezMaterial(this, name, symbol, state, density);
283  for (int i = 0; i < nelem; i++) {
284  mat->AddCompoundElement(z[i], a[i], natoms[i]);
285  }
286  mat->Initialize();
288  fMaterials->Add(mat);
290  return mat;
291 }
292 
293 
294 
306 
308  const Char_t* name, const Char_t* symbol,
309  Int_t nelem, Int_t* z, Int_t* a, Int_t* natoms, Double_t* proportion, Double_t density) const
310 {
311  // Adds a material which is a mixture of either elements or compounds:
312  //
313  // \param[in] name name for the new mixture (no spaces)
314  // \param[in] symbol chemical symbol for mixture
315  // \param[in] nelem number of elements in mixture
316  // \param[in] z[nelem] atomic numbers of elements
317  // \param[in] a[nelem] mass numbers of elements
318  // \param[in] natoms[nelem] number of atoms of each element
319  // \param[in] proportion[nelem] proportion by mass in mixture of element
320  // \param[in] density in \f$g/cm^{3}\f$, if mixture is a solid
321 
322  TString state = "gas";
323  if (density > 0) state = "solid";
324  KVRangeYanezMaterial* mat =
325  new KVRangeYanezMaterial(this, name, symbol, state, density);
326  for (int i = 0; i < nelem; i++) {
327  mat->AddMixtureElement(z[i], a[i], natoms[i], proportion[i]);
328  }
329  mat->Initialize();
331  fMaterials->Add(mat);
333  return mat;
334 }
335 
336 
337 
347 
349 {
350  // Create a material containing the naturally occuring isotopes of the given element,
351  // weighted according to their abundance.
352  //
353  // \param[in] z atomic number of element
354  // \param[out] a mass number of unique isotope, if 100% abundance
355  //
356  // if there is only one naturally occurring isotope of the element we set `a` to this isotope
357  // and don't create any material
358 
359  if (!gNDTManager) {
360  Error("MakeNaturallyOccuringElementMixture",
361  "Nuclear data tables have not been initialised");
362  return nullptr;
363  }
364  KVElementDensity* ed = (KVElementDensity*)gNDTManager->GetData(z, z, "ElementDensity");
365  if (!ed) {
366  Error("AddElementalMaterial",
367  "No element found in ElementDensity NDT-table with Z=%d", z);
368  return nullptr;
369  }
370 
371  KVNucleus nuc(z);
372  KVNumberList isotopes = nuc.GetKnownARange();
373  isotopes.Begin();
374  while (!isotopes.End()) {
375  nuc.SetA(isotopes.Next());
376  if (nuc.GetAbundance() == 100.) {
377  a = nuc.GetA();
378  return nullptr;
379  }
380  }
381 
382  TString state = "solid";
383  if (ed->IsGas()) state = "gas";
384  KVRangeYanezMaterial* mat =
385  new KVRangeYanezMaterial(this,
386  ed->GetElementName(),
387  ed->GetElementSymbol(),
388  state, ed->GetValue());
389  isotopes.Begin();
390  while (!isotopes.End()) {
391  nuc.SetA(isotopes.Next());
392  Double_t abundance = nuc.GetAbundance() / 100.;
393  if (abundance > 0.) mat->AddMixtureElement(z, nuc.GetA(), 1, abundance);
394  }
395  mat->Initialize();
396  return (KVIonRangeTableMaterial*)mat;
397 }
398 
399 
400 
403 
405 {
406  // Read materials from file whose name is given
407 
408  TString DataFilePath = filename;
409 
410  ifstream filestream;
411  if (!SearchAndOpenKVFile(DataFilePath, filestream, "data")) {
412  Error("ReadPredefinedMaterials", "Cannot open %s for reading", DataFilePath.Data());
413  return kFALSE;
414  }
415  Info("ReadPredefinedMaterials", "Reading materials in file : %s", filename);
416 
417  fDoNotSaveMaterials = kTRUE; //don't write what we just read!!
418 
419  Bool_t compound, mixture;
420  compound = mixture = kFALSE;
421 
422  KVString line;
423  while (filestream.good()) {
424  line.ReadLine(filestream);
425  if (filestream.good()) {
426  if (line.BeginsWith("//")) continue;
427  if (line.BeginsWith("COMPOUND")) {
428  compound = kTRUE;
429  mixture = kFALSE;
430  }
431  else if (line.BeginsWith("MIXTURE")) {
432  compound = kFALSE;
433  mixture = kTRUE;
434  }
435  else if (line.BeginsWith("ELEMENT")) {
436  compound = mixture = kFALSE;
437  }
438  if (compound || mixture) {
439  // new compound or mixed material
440  KVString name, symbol, state;
441  Double_t density = -1;
442  KVString element[10];
443  Int_t natoms[10];
444  Int_t z[10], a[10];
445  Double_t proportion[10];
446  Int_t nelem = 0;
447  line.ReadLine(filestream);
448  while (filestream.good() && !line.IsWhitespace() && line != "\n") {
449  line.Begin("=");
450  KVString next = line.Next();
451  if (next == "name") name = line.Next();
452  else if (next == "symbol") symbol = line.Next();
453  else if (next == "state") state = line.Next();
454  else if (next == "density") density = line.Next().Atof();
455  else if (next == "nelem") {
456  nelem = line.Next().Atoi();
457  for (int i = 0; i < nelem; i++) {
458  line.ReadLine(filestream);
459  line.Begin(" ");
460  element[i] = line.Next();
461  a[i] = KVNucleus::IsMassGiven(element[i]);
462  KVNucleus n(element[i]);
463  z[i] = n.GetZ();
464  if (!a[i]) a[i] = TMath::Nint(n.GetNaturalA());
465  natoms[i] = line.Next().Atoi();
466  if (mixture) proportion[i] = line.Next().Atof();
467  }
468  }
469  line.ReadLine(filestream, kFALSE); //do not skip 'whitespace'
470  }
471  if (compound) AddCompoundMaterial(name, symbol, nelem, z, a, natoms, density);
472  else if (mixture) AddMixedMaterial(name, symbol, nelem, z, a, natoms, proportion, density);
473  compound = mixture = kFALSE;
474  }
475  else {
476  // new isotopically pure material
477  KVString name, symbol, state;
478  line.ReadLine(filestream);
479  while (filestream.good() && !line.IsWhitespace() && line != "\n") {
480  line.Begin("=");
481  KVString next = line.Next();
482  if (next == "name") name = line.Next();
483  else if (next == "symbol") symbol = line.Next();
484  else if (next == "state") state = line.Next();
485  line.ReadLine(filestream, kFALSE); //do not skip 'whitespace'
486  }
487  KVNucleus nuc(symbol);
488  AddElementalMaterial(nuc.GetZ(), nuc.GetA());
489  }
490  }
491  }
493  return kTRUE;
494 }
495 
496 
497 
505 
507 {
508  // Write definition of material in a file in the directory
509  //
510  // $(WORKING_DIR)/RANGE
511  //
512  // All files in this directory are read when the table is initialised
513 
514  // make directory if needed
518  }
519  TString matfilename(mat->GetName());
520  matfilename.ReplaceAll(" ", "_"); // no spaces in filenames
521  matfilename += ".dat";
522  ofstream matfil;
523  if (SearchAndOpenKVFile(matfilename, matfil, fLocalMaterialsDirectory)) {
524  dynamic_cast<KVRangeYanezMaterial*>(mat)->SaveMaterial(matfil);
525  matfil.close();
526  }
527 }
528 
529 
int Int_t
KVIonRangeTableMaterial * M
KVNDTManager * gNDTManager
ClassImp(KVPartitionList) void KVPartitionList
Initialisation.
char Char_t
const Bool_t kFALSE
bool Bool_t
double Double_t
const Bool_t kTRUE
const char Option_t
R__EXTERN TEnv * gEnv
char * Form(const char *fmt,...)
R__EXTERN TSystem * gSystem
virtual const Char_t * GetType() const
Definition: KVBase.h:176
static const Char_t * GetWORKDIRFilePath(const Char_t *namefile="")
Definition: KVBase.cpp:127
static Bool_t SearchAndOpenKVFile(const Char_t *name, KVSQLite::database &dbfile, const Char_t *kvsubdir="")
Definition: KVBase.cpp:649
virtual void Copy(TObject &) const
Make a copy of this object.
Definition: KVBase.cpp:394
Atomic element with name, symbol and density.
const Char_t * GetElementName() const
const Char_t * GetElementSymbol() const
Bool_t IsGas() const
Extended version of ROOT THashList.
Definition: KVHashList.h:28
Material for use in energy loss & range calculations.
void AddCompoundElement(Int_t Z, Int_t A, Int_t Natoms)
void AddMixtureElement(Int_t Z, Int_t A, Int_t Natoms, Double_t Proportion)
Abstract base class for calculation of range & energy loss of charged particles in matter.
KVNuclData * GetData(Int_t zz, Int_t aa, const Char_t *name) const
Double_t GetValue() const
Definition: KVNuclData.cpp:108
Description of properties and kinematics of atomic nuclei.
Definition: KVNucleus.h:125
Int_t GetA() const
Definition: KVNucleus.cpp:799
static Int_t IsMassGiven(const Char_t *)
Definition: KVNucleus.cpp:144
void SetA(Int_t a)
Definition: KVNucleus.cpp:655
KVNumberList GetKnownARange(Int_t z=-1, Double_t tmin=0) const
Definition: KVNucleus.cpp:1398
Double_t GetAbundance(Int_t z=-1, Int_t a=-1) const
Definition: KVNucleus.cpp:1212
Int_t GetZ() const
Return the number of proton / atomic number.
Definition: KVNucleus.cpp:770
Strings used to represent a set of ranges of values.
Definition: KVNumberList.h:83
Bool_t End(void) const
Definition: KVNumberList.h:197
void Begin(void) const
Int_t Next(void) const
Description of absorber for the Range dE/dx and range library.
Interface to Range dE/dx and range library.
Definition: KVRangeYanez.h:25
virtual KVIonRangeTableMaterial * AddMixedMaterial(const Char_t *name, const Char_t *symbol, Int_t nelem, Int_t *z, Int_t *a, Int_t *natoms, Double_t *weight, Double_t density=-1.0) const
Bool_t fDoNotSaveMaterials
Definition: KVRangeYanez.h:30
TString fLocalMaterialsDirectory
Definition: KVRangeYanez.h:29
static KVHashList * fMaterials
static list of all currently defined materials
Definition: KVRangeYanez.h:26
void SaveMaterial(KVIonRangeTableMaterial *mat) const
TObjArray * GetListOfMaterials()
KVIonRangeTableMaterial * GetMaterialWithNameOrType(const Char_t *material) const
void Print(Option_t *="") const
void Copy(TObject &) const
Make a copy of this object.
Bool_t ReadMaterials(const Char_t *filename) const
Read materials from file whose name is given.
virtual KVIonRangeTableMaterial * AddCompoundMaterial(const Char_t *name, const Char_t *symbol, Int_t nelem, Int_t *z, Int_t *a, Int_t *natoms, Double_t density=-1.0) const
KVIonRangeTableMaterial * MakeNaturallyOccuringElementMixture(Int_t z, Int_t &a) const
virtual KVIonRangeTableMaterial * AddElementalMaterial(Int_t z, Int_t a=0) const
void CheckMaterialsList() const
virtual void SetOwner(Bool_t enable=kTRUE)
virtual TObject * FindObjectByType(const Char_t *) const
virtual void Add(TObject *obj)
virtual TObject * FindObject(const char *name) const
Extension of ROOT TString class which allows backwards compatibility with ROOT v3....
Definition: KVString.h:72
void Begin(TString delim) const
Definition: KVString.cpp:565
Bool_t End() const
Definition: KVString.cpp:634
KVString Next(Bool_t strip_whitespace=kFALSE) const
Definition: KVString.cpp:695
Extension of ROOT TSystemDirectory class, handling browsing directories on disk.
virtual TList * GetListOfFiles() const
Extended ROOT TSystemFile with added info on file size etc.
Definition: KVSystemFile.h:17
const Char_t * GetFullPath() const
Definition: KVSystemFile.h:48
virtual void Print(Option_t *option, const char *wildcard, Int_t recurse=1) const
void SetName(const char *name)
virtual Int_t GetEntries() const
virtual void SetOwner(Bool_t enable=kTRUE)
virtual const char * GetValue(const char *name, const char *dflt) const
virtual const char * GetName() const
virtual const char * GetTitle() const
void Add(TObject *obj)
virtual void Error(const char *method, const char *msgfmt,...) const
virtual void Info(const char *method, const char *msgfmt,...) const
const char * Data() const
TString & ReplaceAll(const char *s1, const char *s2)
virtual int Chmod(const char *file, UInt_t mode)
virtual int mkdir(const char *name, Bool_t recursive=kFALSE)
virtual Bool_t AccessPathName(const char *path, EAccessMode mode=kFileExists)
TLine * line
void compound()
const Int_t n
Int_t Nint(T x)
auto * a