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 
258 
260  const Char_t* name, const Char_t* symbol,
261  Int_t nelem, Int_t* z, Int_t* a, Int_t* natoms, Double_t density) const
262 {
263  // Adds a compound material with a simple formula composed of different elements
264  //
265  // \param[in] name name for the new compound (no spaces)
266  // \param[in] symbol chemical symbol for compound
267  // \param[in] nelem number of elements in compound
268  // \param[in] z[nelem] atomic numbers of elements
269  // \param[in] a[nelem] mass numbers of elements
270  // \param[in] natoms[nelem] number of atoms of each element
271  // \param[in] density in \f$g/cm^{3}\f$, only required if compound is a solid
272 
273  TString state = "gas";
274  if (density > 0) state = "solid";
275  KVRangeYanezMaterial* mat =
276  new KVRangeYanezMaterial(this, name, symbol, state, density);
277  for (int i = 0; i < nelem; i++) {
278  mat->AddCompoundElement(z[i], a[i], natoms[i]);
279  }
280  mat->Initialize();
282  fMaterials->Add(mat);
284  return mat;
285 }
286 
287 
288 
300 
302  const Char_t* name, const Char_t* symbol,
303  Int_t nelem, Int_t* z, Int_t* a, Int_t* natoms, Double_t* proportion, Double_t density) const
304 {
305  // Adds a material which is a mixture of either elements or compounds:
306  //
307  // \param[in] name name for the new mixture (no spaces)
308  // \param[in] symbol chemical symbol for mixture
309  // \param[in] nelem number of elements in mixture
310  // \param[in] z[nelem] atomic numbers of elements
311  // \param[in] a[nelem] mass numbers of elements
312  // \param[in] natoms[nelem] number of atoms of each element
313  // \param[in] proportion[nelem] proportion by mass in mixture of element
314  // \param[in] density in \f$g/cm^{3}\f$, if mixture is a solid
315 
316  TString state = "gas";
317  if (density > 0) state = "solid";
318  KVRangeYanezMaterial* mat =
319  new KVRangeYanezMaterial(this, name, symbol, state, density);
320  for (int i = 0; i < nelem; i++) {
321  mat->AddMixtureElement(z[i], a[i], natoms[i], proportion[i]);
322  }
323  mat->Initialize();
325  fMaterials->Add(mat);
327  return mat;
328 }
329 
330 
331 
341 
343 {
344  // Create a material containing the naturally occuring isotopes of the given element,
345  // weighted according to their abundance.
346  //
347  // \param[in] z atomic number of element
348  // \param[out] a mass number of unique isotope, if 100% abundance
349  //
350  // if there is only one naturally occurring isotope of the element we set `a` to this isotope
351  // and don't create any material
352 
353  if (!gNDTManager) {
354  Error("MakeNaturallyOccuringElementMixture",
355  "Nuclear data tables have not been initialised");
356  return nullptr;
357  }
358  KVElementDensity* ed = (KVElementDensity*)gNDTManager->GetData(z, z, "ElementDensity");
359  if (!ed) {
360  Error("AddElementalMaterial",
361  "No element found in ElementDensity NDT-table with Z=%d", z);
362  return nullptr;
363  }
364 
365  KVNucleus nuc(z);
366  KVNumberList isotopes = nuc.GetKnownARange();
367  isotopes.Begin();
368  while (!isotopes.End()) {
369  nuc.SetA(isotopes.Next());
370  if (nuc.GetAbundance() == 100.) {
371  a = nuc.GetA();
372  return nullptr;
373  }
374  }
375 
376  TString state = "solid";
377  if (ed->IsGas()) state = "gas";
378  KVRangeYanezMaterial* mat =
379  new KVRangeYanezMaterial(this,
380  ed->GetElementName(),
381  ed->GetElementSymbol(),
382  state, ed->GetValue());
383  isotopes.Begin();
384  while (!isotopes.End()) {
385  nuc.SetA(isotopes.Next());
386  Double_t abundance = nuc.GetAbundance() / 100.;
387  if (abundance > 0.) mat->AddMixtureElement(z, nuc.GetA(), 1, abundance);
388  }
389  mat->Initialize();
390  return (KVIonRangeTableMaterial*)mat;
391 }
392 
393 
394 
397 
399 {
400  // Read materials from file whose name is given
401 
402  TString DataFilePath = filename;
403 
404  ifstream filestream;
405  if (!SearchAndOpenKVFile(DataFilePath, filestream, "data")) {
406  Error("ReadPredefinedMaterials", "Cannot open %s for reading", DataFilePath.Data());
407  return kFALSE;
408  }
409  Info("ReadPredefinedMaterials", "Reading materials in file : %s", filename);
410 
411  fDoNotSaveMaterials = kTRUE; //don't write what we just read!!
412 
413  Bool_t compound, mixture;
414  compound = mixture = kFALSE;
415 
416  KVString line;
417  while (filestream.good()) {
418  line.ReadLine(filestream);
419  if (filestream.good()) {
420  if (line.BeginsWith("//")) continue;
421  if (line.BeginsWith("COMPOUND")) {
422  compound = kTRUE;
423  mixture = kFALSE;
424  }
425  else if (line.BeginsWith("MIXTURE")) {
426  compound = kFALSE;
427  mixture = kTRUE;
428  }
429  else if (line.BeginsWith("ELEMENT")) {
430  compound = mixture = kFALSE;
431  }
432  if (compound || mixture) {
433  // new compound or mixed material
434  KVString name, symbol, state;
435  Double_t density = -1;
436  KVString element[10];
437  Int_t natoms[10];
438  Int_t z[10], a[10];
439  Double_t proportion[10];
440  Int_t nelem = 0;
441  line.ReadLine(filestream);
442  while (filestream.good() && !line.IsWhitespace() && line != "\n") {
443  line.Begin("=");
444  KVString next = line.Next();
445  if (next == "name") name = line.Next();
446  else if (next == "symbol") symbol = line.Next();
447  else if (next == "state") state = line.Next();
448  else if (next == "density") density = line.Next().Atof();
449  else if (next == "nelem") {
450  nelem = line.Next().Atoi();
451  for (int i = 0; i < nelem; i++) {
452  line.ReadLine(filestream);
453  line.Begin(" ");
454  element[i] = line.Next();
455  a[i] = KVNucleus::IsMassGiven(element[i]);
456  KVNucleus n(element[i]);
457  z[i] = n.GetZ();
458  if (!a[i]) a[i] = TMath::Nint(n.GetNaturalA());
459  natoms[i] = line.Next().Atoi();
460  if (mixture) proportion[i] = line.Next().Atof();
461  }
462  }
463  line.ReadLine(filestream, kFALSE); //do not skip 'whitespace'
464  }
465  if (compound) AddCompoundMaterial(name, symbol, nelem, z, a, natoms, density);
466  else if (mixture) AddMixedMaterial(name, symbol, nelem, z, a, natoms, proportion, density);
467  compound = mixture = kFALSE;
468  }
469  else {
470  // new isotopically pure material
471  KVString name, symbol, state;
472  line.ReadLine(filestream);
473  while (filestream.good() && !line.IsWhitespace() && line != "\n") {
474  line.Begin("=");
475  KVString next = line.Next();
476  if (next == "name") name = line.Next();
477  else if (next == "symbol") symbol = line.Next();
478  else if (next == "state") state = line.Next();
479  line.ReadLine(filestream, kFALSE); //do not skip 'whitespace'
480  }
481  KVNucleus nuc(symbol);
482  AddElementalMaterial(nuc.GetZ(), nuc.GetA());
483  }
484  }
485  }
487  return kTRUE;
488 }
489 
490 
491 
499 
501 {
502  // Write definition of material in a file in the directory
503  //
504  // $(WORKING_DIR)/RANGE
505  //
506  // All files in this directory are read when the table is initialised
507 
508  // make directory if needed
512  }
513  TString matfilename(mat->GetName());
514  matfilename.ReplaceAll(" ", "_"); // no spaces in filenames
515  matfilename += ".dat";
516  ofstream matfil;
517  if (SearchAndOpenKVFile(matfilename, matfil, fLocalMaterialsDirectory)) {
518  dynamic_cast<KVRangeYanezMaterial*>(mat)->SaveMaterial(matfil);
519  matfil.close();
520  }
521 }
522 
523 
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:177
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: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:126
Int_t GetA() const
Definition: KVNucleus.cpp:802
static Int_t IsMassGiven(const Char_t *)
Definition: KVNucleus.cpp:147
void SetA(Int_t a)
Definition: KVNucleus.cpp:658
KVNumberList GetKnownARange(Int_t z=-1, Double_t tmin=0) const
Definition: KVNucleus.cpp:1401
Double_t GetAbundance(Int_t z=-1, Int_t a=-1) const
Definition: KVNucleus.cpp:1215
Int_t GetZ() const
Return the number of proton / atomic number.
Definition: KVNucleus.cpp:773
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
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:31
TString fLocalMaterialsDirectory
Definition: KVRangeYanez.h:30
static KVHashList * fMaterials
static list of all currently defined materials
Definition: KVRangeYanez.h:27
void SaveMaterial(KVIonRangeTableMaterial *mat) const
TObjArray * GetListOfMaterials()
KVIonRangeTableMaterial * GetMaterialWithNameOrType(const Char_t *material) const
void Print(Option_t *="") const
void Copy(TObject &) const
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: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.
virtual TList * GetListOfFiles() const
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 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)
TArc a
ClassImp(TPyArg)