KaliVeda  1.12/06
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 
204 
206 {
207  // Adds a material composed of a single isotope of a chemical element.
208  //
209  // \param[in] z atomic number of element
210  // \param[in] a mass number of element
211  //
212  // If the mass number of the isotope \f$A\f$ is not specified, we create a material containing the naturally
213  // occuring isotopes of the given element, weighted according to natural abundance.
214  //
215  // If the mass is given, the material symbol will be `"AX"` where `X` is the symbol for the element
216  // e.g. `"48Ca"`, `"124Sn"`, etc.
217  // and the material name will be `"Xxx-A"` where `Xxx` is the name of the element
218  // e.g. `"Calcium-48"`, `"Tin-124"`, etc.
219  //
220  // Otherwise, we just use the element symbol and name for naturally-occurring
221  // mixtures of atomic elements (`"Ca"`, `"Calcium"`, etc.).
222 
224  if (!a) mat = MakeNaturallyOccuringElementMixture(z, a); // this may set a!=0 if only one isotope exists in nature
225  if (a) {
226  if (!gNDTManager) {
227  Error("AddElementalMaterial",
228  "Nuclear data tables have not been initialised");
229  return nullptr;
230  }
231  KVElementDensity* ed = (KVElementDensity*)gNDTManager->GetData(z, a, "ElementDensity");
232  if (!ed) {
233  Error("AddElementalMaterial",
234  "No element found in ElementDensity NDT-table with Z=%d", z);
235  return nullptr;
236  }
237  TString state = "solid";
238  if (ed->IsGas()) state = "gas";
239  mat = new KVRangeYanezMaterial(this, Form("%s-%d", ed->GetElementName(), a),
240  Form("%d%s", a, ed->GetElementSymbol()),
241  state, ed->GetValue(), z, a);
242  mat->Initialize();
243  }
245  fMaterials->Add(mat);
247  return mat;
248 }
249 
250 
251 
262 
264  const Char_t* name, const Char_t* symbol,
265  Int_t nelem, Int_t* z, Int_t* a, Int_t* natoms, Double_t density) const
266 {
267  // Adds a compound material with a simple formula composed of different elements
268  //
269  // \param[in] name name for the new compound (no spaces)
270  // \param[in] symbol chemical symbol for compound
271  // \param[in] nelem number of elements in compound
272  // \param[in] z[nelem] atomic numbers of elements
273  // \param[in] a[nelem] mass numbers of elements
274  // \param[in] natoms[nelem] number of atoms of each element
275  // \param[in] density in \f$g/cm^{3}\f$, if compound is a solid
276 
277  TString state = "gas";
278  if (density > 0) state = "solid";
279  KVRangeYanezMaterial* mat =
280  new KVRangeYanezMaterial(this, name, symbol, state, density);
281  for (int i = 0; i < nelem; i++) {
282  mat->AddCompoundElement(z[i], a[i], natoms[i]);
283  }
284  mat->Initialize();
286  fMaterials->Add(mat);
288  return mat;
289 }
290 
291 
292 
304 
306  const Char_t* name, const Char_t* symbol,
307  Int_t nelem, Int_t* z, Int_t* a, Int_t* natoms, Double_t* proportion, Double_t density) const
308 {
309  // Adds a material which is a mixture of either elements or compounds:
310  //
311  // \param[in] name name for the new mixture (no spaces)
312  // \param[in] symbol chemical symbol for mixture
313  // \param[in] nelem number of elements in mixture
314  // \param[in] z[nelem] atomic numbers of elements
315  // \param[in] a[nelem] mass numbers of elements
316  // \param[in] natoms[nelem] number of atoms of each element
317  // \param[in] proportion[nelem] proportion by mass in mixture of element
318  // \param[in] density in \f$g/cm^{3}\f$, if mixture is a solid
319 
320  TString state = "gas";
321  if (density > 0) state = "solid";
322  KVRangeYanezMaterial* mat =
323  new KVRangeYanezMaterial(this, name, symbol, state, density);
324  for (int i = 0; i < nelem; i++) {
325  mat->AddMixtureElement(z[i], a[i], natoms[i], proportion[i]);
326  }
327  mat->Initialize();
329  fMaterials->Add(mat);
331  return mat;
332 }
333 
334 
335 
345 
347 {
348  // Create a material containing the naturally occuring isotopes of the given element,
349  // weighted according to their abundance.
350  //
351  // \param[in] z atomic number of element
352  // \param[out] a mass number of unique isotope, if 100% abundance
353  //
354  // if there is only one naturally occurring isotope of the element we set `a` to this isotope
355  // and don't create any material
356 
357  if (!gNDTManager) {
358  Error("MakeNaturallyOccuringElementMixture",
359  "Nuclear data tables have not been initialised");
360  return nullptr;
361  }
362  KVElementDensity* ed = (KVElementDensity*)gNDTManager->GetData(z, z, "ElementDensity");
363  if (!ed) {
364  Error("AddElementalMaterial",
365  "No element found in ElementDensity NDT-table with Z=%d", z);
366  return nullptr;
367  }
368 
369  KVNucleus nuc(z);
370  KVNumberList isotopes = nuc.GetKnownARange();
371  isotopes.Begin();
372  while (!isotopes.End()) {
373  nuc.SetA(isotopes.Next());
374  if (nuc.GetAbundance() == 100.) {
375  a = nuc.GetA();
376  return nullptr;
377  }
378  }
379 
380  TString state = "solid";
381  if (ed->IsGas()) state = "gas";
382  KVRangeYanezMaterial* mat =
383  new KVRangeYanezMaterial(this,
384  ed->GetElementName(),
385  ed->GetElementSymbol(),
386  state, ed->GetValue());
387  isotopes.Begin();
388  while (!isotopes.End()) {
389  nuc.SetA(isotopes.Next());
390  Double_t abundance = nuc.GetAbundance() / 100.;
391  if (abundance > 0.) mat->AddMixtureElement(z, nuc.GetA(), 1, abundance);
392  }
393  mat->Initialize();
394  return (KVIonRangeTableMaterial*)mat;
395 }
396 
397 
398 
401 
403 {
404  // Read materials from file whose name is given
405 
406  TString DataFilePath = filename;
407 
408  ifstream filestream;
409  if (!SearchAndOpenKVFile(DataFilePath, filestream, "data")) {
410  Error("ReadPredefinedMaterials", "Cannot open %s for reading", DataFilePath.Data());
411  return kFALSE;
412  }
413  Info("ReadPredefinedMaterials", "Reading materials in file : %s", filename);
414 
415  fDoNotSaveMaterials = kTRUE; //don't write what we just read!!
416 
417  Bool_t compound, mixture;
418  compound = mixture = kFALSE;
419 
420  KVString line;
421  while (filestream.good()) {
422  line.ReadLine(filestream);
423  if (filestream.good()) {
424  if (line.BeginsWith("//")) continue;
425  if (line.BeginsWith("COMPOUND")) {
426  compound = kTRUE;
427  mixture = kFALSE;
428  }
429  else if (line.BeginsWith("MIXTURE")) {
430  compound = kFALSE;
431  mixture = kTRUE;
432  }
433  else if (line.BeginsWith("ELEMENT")) {
434  compound = mixture = kFALSE;
435  }
436  if (compound || mixture) {
437  // new compound or mixed material
438  KVString name, symbol, state;
439  Double_t density = -1;
440  KVString element[10];
441  Int_t natoms[10];
442  Int_t z[10], a[10];
443  Double_t proportion[10];
444  Int_t nelem = 0;
445  line.ReadLine(filestream);
446  while (filestream.good() && !line.IsWhitespace() && line != "\n") {
447  line.Begin("=");
448  KVString next = line.Next();
449  if (next == "name") name = line.Next();
450  else if (next == "symbol") symbol = line.Next();
451  else if (next == "state") state = line.Next();
452  else if (next == "density") density = line.Next().Atof();
453  else if (next == "nelem") {
454  nelem = line.Next().Atoi();
455  for (int i = 0; i < nelem; i++) {
456  line.ReadLine(filestream);
457  line.Begin(" ");
458  element[i] = line.Next();
459  a[i] = KVNucleus::IsMassGiven(element[i]);
460  KVNucleus n(element[i]);
461  z[i] = n.GetZ();
462  if (!a[i]) a[i] = TMath::Nint(n.GetNaturalA());
463  natoms[i] = line.Next().Atoi();
464  if (mixture) proportion[i] = line.Next().Atof();
465  }
466  }
467  line.ReadLine(filestream, kFALSE); //do not skip 'whitespace'
468  }
469  if (compound) AddCompoundMaterial(name, symbol, nelem, z, a, natoms, density);
470  else if (mixture) AddMixedMaterial(name, symbol, nelem, z, a, natoms, proportion, density);
471  compound = mixture = kFALSE;
472  }
473  else {
474  // new isotopically pure material
475  KVString name, symbol, state;
476  line.ReadLine(filestream);
477  while (filestream.good() && !line.IsWhitespace() && line != "\n") {
478  line.Begin("=");
479  KVString next = line.Next();
480  if (next == "name") name = line.Next();
481  else if (next == "symbol") symbol = line.Next();
482  else if (next == "state") state = line.Next();
483  line.ReadLine(filestream, kFALSE); //do not skip 'whitespace'
484  }
485  KVNucleus nuc(symbol);
486  AddElementalMaterial(nuc.GetZ(), nuc.GetA());
487  }
488  }
489  }
491  return kTRUE;
492 }
493 
494 
495 
503 
505 {
506  // Write definition of material in a file in the directory
507  //
508  // $(WORKING_DIR)/RANGE
509  //
510  // All files in this directory are read when the table is initialised
511 
512  // make directory if needed
516  }
517  TString matfilename(mat->GetName());
518  matfilename.ReplaceAll(" ", "_"); // no spaces in filenames
519  matfilename += ".dat";
520  ofstream matfil;
521  if (SearchAndOpenKVFile(matfilename, matfil, fLocalMaterialsDirectory)) {
522  dynamic_cast<KVRangeYanezMaterial*>(mat)->SaveMaterial(matfil);
523  matfil.close();
524  }
525 }
526 
527 
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
static const Char_t * GetWORKDIRFilePath(const Char_t *namefile="")
Definition: KVBase.cpp:127
const Char_t * GetType() const
Definition: KVBase.h:170
static Bool_t SearchAndOpenKVFile(const Char_t *name, std::ifstream &file, const Char_t *kvsubdir="", KVLockfile *locks=0)
Definition: KVBase.cpp:601
virtual void Copy(TObject &) const
Make a copy of this object.
Definition: KVBase.cpp:397
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:196
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:562
Bool_t End() const
Definition: KVString.cpp:625
KVString Next(Bool_t strip_whitespace=kFALSE) const
Definition: KVString.cpp:675
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