KaliVeda
Toolkit for HIC analysis
KVRangeYanez.cpp
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"
7 #include "KVElementDensityTable.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 
202 
204 {
205  // Adds a material composed of a single chemical element.
206  //
207  // \param[in] z atomic number \f$Z\f$ of element
208  // \param[in] a [optional] mass number \f$A\f$ of isotope
209  //
210  // If the mass number of the isotope \f$A\f$ is not specified, we create a material containing the naturally
211  // occuring isotopes of the given element, weighted according to natural abundance.
212  //
213  // If the mass is given, the material name will be `"Xxx-A"` where `Xxx` is the name of the element
214  // - e.g. `"Calcium-48"`, `"Tin-124"`, etc.
215  //
216  // Otherwise, we just use the element symbol and name for naturally-occurring
217  // mixtures of atomic elements (`"Ca"`, `"Calcium"`, etc.).
218 
220  if (!a) mat = MakeNaturallyOccuringElementMixture(z, a); // this may set a!=0 if only one isotope exists in nature
221  if (a) {
222  if (!gNDTManager) {
223  Error("AddElementalMaterial",
224  "Nuclear data tables have not been initialised");
225  return nullptr;
226  }
227  KVElementDensity* ed = (KVElementDensity*)gNDTManager->GetData(z, a, "ElementDensity");
228  if (!ed) {
229  Error("AddElementalMaterial",
230  "No element found in ElementDensity NDT-table with Z=%d", z);
231  return nullptr;
232  }
233  TString state = "solid";
234  if (ed->IsGas()) state = "gas";
235  mat = new KVRangeYanezMaterial(this, Form("%s-%d", ed->GetElementName(), a),
236  ed->GetElementSymbol(),
237  state, ed->GetValue(), z, a);
238  mat->Initialize();
239  }
241  fMaterials->Add(mat);
243  return mat;
244 }
245 
246 
247 
263 
265  const std::vector<CompoundFormulaElement>& elements, 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] elements vector of elemental components
272  // \param[in] density in \f$g/cm^{3}\f$, only required if compound is a solid
273  //
274  // Example of use:
275  //
276  //~~~{.cpp}
277  // KVRangeYanez irt;
278  // irt.AddCompoundMaterial("polyethylene", "CH2", {{6,12,1},{1,1,2}}, 0.940);
279  //~~~
280  //
281 
282  TString state = "gas";
283  if (density > 0) state = "solid";
284  KVRangeYanezMaterial* mat =
285  new KVRangeYanezMaterial(this, name, symbol, state, density);
286  for (auto& el : elements) {
287  mat->AddCompoundElement(el.Z, el.A, el.natoms);
288  }
289  mat->Initialize();
291  fMaterials->Add(mat);
293  return mat;
294 }
295 
296 
297 
311 
313  const std::vector<MixtureFormulaElement>& elements, Double_t density) const
314 {
315  // Adds a material which is a mixture of either elements or compounds:
316  //
317  // \param[in] name name for the new mixture (no spaces)
318  // \param[in] symbol chemical symbol for mixture
319  // \param[in] elements vector of elemental components
320  // \param[in] density in \f$g/cm^{3}\f$, if mixture is a solid
321  // Example of use:
322  //
323  //~~~{.cpp}
324  // KVRangeYanez irt;
325  // irt.AddMixedMaterial("Air", "Air", {{7,14,2,0.78},{8,16,2,0.21},{18,40,1,0.01}});
326  //~~~
327 
328  TString state = "gas";
329  if (density > 0) state = "solid";
330  KVRangeYanezMaterial* mat =
331  new KVRangeYanezMaterial(this, name, symbol, state, density);
332  for (auto& el : elements) {
333  mat->AddMixtureElement(el.Z, el.A, el.natoms, el.proportion);
334  }
335  mat->Initialize();
337  fMaterials->Add(mat);
339  return mat;
340 }
341 
342 
343 
353 
355 {
356  // Create a material containing the naturally occuring isotopes of the given element,
357  // weighted according to their abundance.
358  //
359  // \param[in] z atomic number of element
360  // \param[out] a mass number of unique isotope, if 100% abundance
361  //
362  // if there is only one naturally occurring isotope of the element we set `a` to this isotope
363  // and don't create any material
364 
365  if (!gNDTManager) {
366  Error("MakeNaturallyOccuringElementMixture",
367  "Nuclear data tables have not been initialised");
368  return nullptr;
369  }
370  KVElementDensity* ed = (KVElementDensity*)gNDTManager->GetData(z, z, "ElementDensity");
371  if (!ed) {
372  Error("AddElementalMaterial",
373  "No element found in ElementDensity NDT-table with Z=%d", z);
374  return nullptr;
375  }
376 
377  KVNucleus nuc(z);
378  KVNumberList isotopes = nuc.GetKnownARange();
379  isotopes.Begin();
380  while (!isotopes.End()) {
381  nuc.SetA(isotopes.Next());
382  if (nuc.GetAbundance() == 100.) {
383  a = nuc.GetA();
384  return nullptr;
385  }
386  }
387 
388  TString state = "solid";
389  if (ed->IsGas()) state = "gas";
390  KVRangeYanezMaterial* mat =
391  new KVRangeYanezMaterial(this,
392  ed->GetElementName(),
393  ed->GetElementSymbol(),
394  state, ed->GetValue());
395  isotopes.Begin();
396  while (!isotopes.End()) {
397  nuc.SetA(isotopes.Next());
398  Double_t abundance = nuc.GetAbundance() / 100.;
399  if (abundance > 0.) mat->AddMixtureElement(z, nuc.GetA(), 1, abundance);
400  }
401  mat->Initialize();
402  return (KVIonRangeTableMaterial*)mat;
403 }
404 
405 
406 
409 
411 {
412  // Read materials from file whose name is given
413 
414  TString DataFilePath = filename;
415 
416  ifstream filestream;
417  if (!SearchAndOpenKVFile(DataFilePath, filestream, "data")) {
418  Error("ReadPredefinedMaterials", "Cannot open %s for reading", DataFilePath.Data());
419  return kFALSE;
420  }
421  Info("ReadPredefinedMaterials", "Reading materials in file : %s", filename);
422 
423  fDoNotSaveMaterials = kTRUE; //don't write what we just read!!
424 
425  Bool_t compound, mixture;
426  compound = mixture = kFALSE;
427 
428  KVString line;
429  while (filestream.good()) {
430  line.ReadLine(filestream);
431  if (filestream.good()) {
432  if (line.BeginsWith("//")) continue;
433  if (line.BeginsWith("COMPOUND")) {
434  compound = kTRUE;
435  mixture = kFALSE;
436  }
437  else if (line.BeginsWith("MIXTURE")) {
438  compound = kFALSE;
439  mixture = kTRUE;
440  }
441  else if (line.BeginsWith("ELEMENT")) {
442  compound = mixture = kFALSE;
443  }
444  if (compound || mixture) {
445  // new compound or mixed material
446  KVString name, symbol, state;
447  Double_t density = -1;
448  KVString element;
449  std::vector<CompoundFormulaElement> compound_elements;
450  std::vector<MixtureFormulaElement> mixture_elements;
451  Int_t nelem = 0;
452  line.ReadLine(filestream);
453  while (filestream.good() && !line.IsWhitespace() && line != "\n") {
454  line.Begin("=");
455  KVString next = line.Next();
456  if (next == "name") name = line.Next();
457  else if (next == "symbol") symbol = line.Next();
458  else if (next == "state") state = line.Next();
459  else if (next == "density") density = line.Next().Atof();
460  else if (next == "nelem") {
461  nelem = line.Next().Atoi();
462  for (int i = 0; i < nelem; i++) {
463  line.ReadLine(filestream);
464  line.Begin(" ");
465  element = line.Next();
466  auto a = KVNucleus::IsMassGiven(element);
467  KVNucleus n(element);
468  auto z = n.GetZ();
469  if (!a) a = TMath::Nint(n.GetNaturalA());
470  auto natoms = line.Next().Atoi();
471  if (mixture) {
472  auto proportion = line.Next().Atof();
473  mixture_elements.push_back({z, a, natoms, proportion});
474  }
475  else {
476  compound_elements.push_back({z, a, natoms});
477  }
478  }
479  }
480  line.ReadLine(filestream, kFALSE); //do not skip 'whitespace'
481  }
482  if (compound) AddCompoundMaterial(name, symbol, compound_elements, density);
483  else if (mixture) AddMixedMaterial(name, symbol, mixture_elements, density);
484  compound = mixture = kFALSE;
485  }
486  else {
487  // new isotopically pure material
488  KVString name, symbol, state;
489  line.ReadLine(filestream);
490  while (filestream.good() && !line.IsWhitespace() && line != "\n") {
491  line.Begin("=");
492  KVString next = line.Next();
493  if (next == "name") name = line.Next();
494  else if (next == "symbol") symbol = line.Next();
495  else if (next == "state") state = line.Next();
496  line.ReadLine(filestream, kFALSE); //do not skip 'whitespace'
497  }
498  KVNucleus nuc(symbol);
499  AddElementalMaterial(nuc.GetZ(), nuc.GetA());
500  }
501  }
502  }
504  return kTRUE;
505 }
506 
507 
508 
516 
518 {
519  // Write definition of material in a file in the directory
520  //
521  // $(WORKING_DIR)/RANGE
522  //
523  // All files in this directory are read when the table is initialised
524 
525  // make directory if needed
529  }
530  TString matfilename(mat->GetName());
531  matfilename.ReplaceAll(" ", "_"); // no spaces in filenames
532  matfilename += ".dat";
533  ofstream matfil;
534  if (SearchAndOpenKVFile(matfilename, matfil, fLocalMaterialsDirectory)) {
535  dynamic_cast<KVRangeYanezMaterial*>(mat)->SaveMaterial(matfil);
536  matfil.close();
537  }
538 }
539 
540 
int Int_t
bool Bool_t
char Char_t
constexpr Bool_t kFALSE
double Double_t
constexpr Bool_t kTRUE
const char Option_t
R__EXTERN TEnv * gEnv
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char filename
char name[80]
char * Form(const char *fmt,...)
R__EXTERN TSystem * gSystem
virtual const Char_t * GetType() const
Definition: KVBase.h:176
void Error(const char *method, const char *msgfmt,...) const override
Definition: KVBase.cpp:1650
static const Char_t * GetWORKDIRFilePath(const Char_t *namefile="")
Definition: KVBase.cpp:121
void Copy(TObject &) const override
Make a copy of this object.
Definition: KVBase.cpp:373
static Bool_t SearchAndOpenKVFile(const Char_t *name, KVSQLite::database &dbfile, const Char_t *kvsubdir="")
Definition: KVBase.cpp:628
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:29
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:123
Int_t GetA() const
Definition: KVNucleus.cpp:792
static Int_t IsMassGiven(const Char_t *)
Definition: KVNucleus.cpp:137
void SetA(Int_t a)
Definition: KVNucleus.cpp:647
KVNumberList GetKnownARange(Int_t z=-1, Double_t tmin=0) const
Definition: KVNucleus.cpp:1391
Double_t GetAbundance(Int_t z=-1, Int_t a=-1) const
Definition: KVNucleus.cpp:1205
Int_t GetZ() const
Return the number of proton / atomic number.
Definition: KVNucleus.cpp:763
Strings used to represent a set of ranges of values.
Definition: KVNumberList.h:85
Bool_t End(void) const
Definition: KVNumberList.h:199
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:26
void Copy(TObject &) const override
Bool_t fDoNotSaveMaterials
Definition: KVRangeYanez.h:31
TString fLocalMaterialsDirectory
Definition: KVRangeYanez.h:30
static KVHashList * fMaterials
static list of all currently defined materials
Definition: KVRangeYanez.h:27
Bool_t ReadMaterials(const Char_t *filename) const override
Read materials from file whose name is given.
void SaveMaterial(KVIonRangeTableMaterial *mat) const
void Print(Option_t *="") const override
KVIonRangeTableMaterial * GetMaterialWithNameOrType(const Char_t *material) const override
TObjArray * GetListOfMaterials() override
KVIonRangeTableMaterial * AddElementalMaterial(Int_t z, Int_t a=0) const override
virtual KVIonRangeTableMaterial * AddMixedMaterial(const Char_t *name, const Char_t *symbol, const std::vector< MixtureFormulaElement > &elements, Double_t density=-1.0) const override
virtual KVIonRangeTableMaterial * AddCompoundMaterial(const Char_t *name, const Char_t *symbol, const std::vector< CompoundFormulaElement > &elements, Double_t density=-1.0) const override
KVIonRangeTableMaterial * MakeNaturallyOccuringElementMixture(Int_t z, Int_t &a) const
void CheckMaterialsList() const
void Add(TObject *obj) override
TObject * FindObject(const char *name) const override
void SetOwner(Bool_t enable=kTRUE) override
virtual TObject * FindObjectByType(const Char_t *) const
Extension of ROOT TString class which allows backwards compatibility with ROOT v3....
Definition: KVString.h:73
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.
TList * GetListOfFiles() const override
Extended ROOT TSystemFile with added info on file size etc.
Definition: KVSystemFile.h:18
const Char_t * GetFullPath() const
Definition: KVSystemFile.h:49
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
const char * GetName() const override
const char * GetTitle() const override
void Add(TObject *obj) override
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)
TArc a
ClassImp(TPyArg)