KaliVeda  1.12/06
Heavy-Ion Analysis Toolkit
KVedaLossRangeFitter.cpp
Go to the documentation of this file.
1 //Created by KVClassFactory on Thu Dec 20 14:56:27 2012
2 //Author: John Frankland,,,
3 
4 #include "KVedaLossRangeFitter.h"
5 #include "TGraph.h"
6 #include "TSystem.h"
7 #include "TCanvas.h"
8 #include "Riostream.h"
9 #include <math.h>
10 using namespace::std;
11 
13 
14 
15 
17 static Double_t energy[] = {
18  0.1, .2, 0.5, 1, 2, 5, 10, 25, 50, 100, 250, 500, -1
19 };
20 
21 
22 
25 
27 {
28  // express logR as a polynomial of log(E/A)
29  Double_t lr = a[5];
30  for (int i = 4; i >= 0; --i) lr = e[0] * lr + a[i];
31  return lr;
32 }
33 
34 
35 
38 
40 {
41  // Default constructor
42  fRangeFunction = new TF1("VedaRangeFit", this, &KVedaLossRangeFitter::range, -10., 10., 6);
43 }
44 
45 
46 
49 
51 {
52  // Destructor
53 }
54 
55 
56 
59 
61 {
62  // Sets range table to fit. Also finds material with closest Z in VEDALOSS library.
63  fMaterial = m;
64  Double_t zmat = fMaterial->GetZ();
65  unique_ptr<TObjArray> mats(VEDALOSS.GetListOfMaterials());
66  TString closest;
67  Double_t closestZ = 100;
68  TNamed* mat;
69  TIter next(mats.get());
70  while ((mat = (TNamed*)next())) {
72  Double_t yZ = y->GetZ();
73  if (TMath::Abs(yZ - zmat) < TMath::Abs(closestZ - zmat)) {
74  closestZ = yZ;
75  closest = mat->GetName();
76  }
77  }
79  Info("SetMaterial", "Initial fit parameters will be taken from:");
81 }
82 
83 
84 
88 
90 {
91  // Set initial parameters for this Z by using closest known material in
92  // VedaLoss range tables
93 
94  std::vector<Double_t> pars;
96  int npar = fRangeFunction->GetNpar();
97  for (int i = 0; i < npar; ++i) {
98  fRangeFunction->SetParameter(i, pars[i]);
99  }
100 }
101 
102 
103 
109 
111 {
112  // Create TGraph containing log(range) vs. log (E/A) for ions of given
113  // atomic number (the mass used is the reference mass found in the VEDALOSS
114  // tables).
115  // Convert range to mg/cm**2 (units of internal VEDALOSS range function)
116 
117  TGraph* r = new TGraph;
118  r->SetMarkerStyle(24);
119  r->SetTitle(Form("Z = %d", Z));
120  int i = 0, ip = 0;
121  while (1) {
122  if (energy[i] < 0.) break;
123  Double_t logE = log(energy[i]);
125  if (R > 0.) {
126  r->SetPoint(ip++, logE, log(R));
127  }
128  i++;
129  }
130  return r;
131 }
132 
133 
134 
139 
141 {
142  // Create TGraph containing log(range) vs. log (E/A) for ions of given
143  // atomic number using current VEDALOSS reference material.
144  // Convert range to mg/cm**2 (units of internal VEDALOSS range function)
145  TGraph* r = new TGraph;
146  r->SetMarkerStyle(20);
147  r->SetMarkerColor(kBlue);
148  r->SetTitle(Form("VEDA Z = %d", Z));
149  int i = 0, ip = 0;
150  while (1) {
151  if (energy[i] < 0.) break;
152  Double_t logE = log(energy[i]);
154  if (R > 0.) {
155  r->SetPoint(ip++, logE, log(R));
156  }
157  i++;
158  }
159  return r;
160 }
161 
162 
163 
167 
169 {
170  // Fit ranges in TGraph
171  // return value = 0 if fit is good
172 
173  return (Int_t)R->Fit(fRangeFunction, "WQ");
174 }
175 
176 
177 
180 
181 void KVedaLossRangeFitter::DoFits(TString output_file, Int_t Zmin, Int_t Zmax)
182 {
183  // Perform fits to range tables for elements from Zmin to Zmax
184  TGraph* g = 0;
185  TGraph* v = 0;
186  new TCanvas;
187 
188  ofstream results(output_file.Data());
189 
190  PrintFitHeader(results);
191  for (int Z = Zmin; Z <= Zmax; Z++) {
192  gPad->Clear();
194  if (g) delete g;
195  if (v) delete v;
196  g = GenerateRangeTable(Z);
197  g->Draw("AP");
198  Int_t fitStatus = FitRangeTable(g);
200  v->Draw("P");
201  printf("Z = %d : fit status ", Z);
202  if (fitStatus == 0) {
203  printf("OK\n");
204  }
205  else
206  printf("PROBLEM (%d)\n", fitStatus);
207  PrintFitParameters(Z, results);
208  gPad->Modified();
209  gPad->Update();
210  gSystem->Sleep(500);
211  }
212  results.close();
213 }
214 
215 
216 
218 
220 {
221  output << setw(4) << Z << "." << setw(4) << Aref << ". ";
222  output.precision(4);
223  for (int i = 0; i < 6; i++) output << uppercase << scientific << fRangeFunction->GetParameter(i) << " ";
224  output << endl << " ";
225  for (int i = 0; i < 6; i++) output << uppercase << scientific << fRangeFunction->GetParameter(i) << " ";
226  output << endl;
227 }
228 
229 
230 
251 
253 {
254 // + Si Silicon solid 2.33 14.0 28.0855 0. 0.
255 // ELEMENT
256 // Z = 1,2 0.1 < E/A < 400 MeV
257 // Z = 3,100 0.1 < E/A < 250 MeV
258 
259 // + Myl Mylar solid 1.395 4.545 8.735 0. 0.
260 // COMPOUND
261 // 3
262 // 6 12 10
263 // 1 1 8
264 // 8 16 4
265 // Z = 1,2 0.1 < E/A < 400 MeV
266 // Z = 3,100 0.1 < E/A < 250 MeV
267 
268 // + NE102 Plastic solid 1.032 3.5 6.509 0. 0.
269 // MIXTURE
270 // 2
271 // 1 1 1 5.25
272 // 6 12 1 4.73
273 // Z = 1,2 0.1 < E/A < 400 MeV
274 // Z = 3,100 0.1 < E/A < 250 MeV
275  output << "+ " << fMaterial->GetType() << " " << fMaterial->GetName();
276  if (fMaterial->IsGas()) output << " gas 0";
277  else output << " solid " << fMaterial->GetDensity();
278  output << " " << fMaterial->GetZ() << " " << fMaterial->GetMass();
279  if (fMaterial->IsGas()) output << " " << fMaterial->GetMoleWt() << " 19." << endl;
280  else output << " 0. 0." << endl;
281  fMaterial->PrintComposition(output);
282  output << "Z = 1,2 0.1 < E/A < 400 MeV" << endl << "Z = 3,100 0.1 < E/A < 250 MeV" << endl;
283 }
284 
285 
int Int_t
ClassImp(KVPartitionList) void KVPartitionList
Initialisation.
static Double_t energy[]
ROOT::R::TRInterface & r
#define e(i)
double Double_t
kBlue
double log(double)
char * Form(const char *fmt,...)
R__EXTERN TSystem * gSystem
#define gPad
const Char_t * GetType() const
Definition: KVBase.h:170
Material for use in energy loss & range calculations.
void PrintComposition(std::ostream &) const
Print to stream the composition of this material, in a format compatible with the VEDALOSS parameter ...
void Print(Option_t *="") const
virtual Double_t GetRangeOfIon(Int_t Z, Int_t A, Double_t E, Double_t isoAmat=0.)
KVIonRangeTableMaterial * GetMaterial(const Char_t *material) const
Returns pointer to material of given name or type.
Description of material in the KVedaLoss range table.
virtual Double_t GetRangeOfIon(Int_t Z, Int_t A, Double_t E, Double_t isoAmat=0.)
void GetParameters(Int_t Zion, Int_t &Aion, std::vector< Double_t > &rangepar)
Fit a range table using the VEDALOSS functional.
TGraph * GenerateRangeTable(Int_t Z)
void PrintFitParameters(Int_t, std::ostream &)
KVIonRangeTableMaterial * fMaterial
range table to fit
void SetMaterial(KVIonRangeTableMaterial *m)
Sets range table to fit. Also finds material with closest Z in VEDALOSS library.
KVedaLossRangeFitter()
Default constructor.
void DoFits(TString output_file, Int_t Zmin=1, Int_t Zmax=100)
Perform fits to range tables for elements from Zmin to Zmax.
TGraph * GenerateVEDALOSSRangeTable(Int_t Z)
virtual ~KVedaLossRangeFitter()
Destructor.
void PrintFitHeader(std::ostream &)
KVedaLossMaterial * fClosestVedaMat
closest known VEDALOSS material
void SetInitialParameters(Int_t Z)
Double_t range(Double_t *, Double_t *)
express logR as a polynomial of log(E/A)
TObjArray * GetListOfMaterials()
Definition: KVedaLoss.cpp:325
virtual Double_t GetParameter(const TString &name) const
virtual Int_t GetNpar() const
virtual void SetParameter(const TString &name, Double_t value)
virtual const char * GetName() const
virtual void Info(const char *method, const char *msgfmt,...) const
const char * Data() const
virtual void Sleep(UInt_t milliSec)
Double_t y[n]
const long double mg
Definition: KVUnits.h:74
const long double m
Definition: KVUnits.h:70
const long double g
masses
Definition: KVUnits.h:72
constexpr Double_t R()
Double_t Abs(Double_t d)
v
auto * a