18 m_hasExternalCanvas(false),
34 m_labele(
"electric field [V/cm]"),
35 m_labelb(
"magnetic field [T]"),
36 m_labela(
"magnetic field angle [rad]"),
37 m_labelv(
"drift velocity [cm/ns]"),
38 m_labeld(
"diffusion coefficient [#sqrt{cm}]") {
40 m_className =
"ViewMedium";
46 if (!m_hasExternalCanvas && m_canvas)
delete m_canvas;
52 std::cerr << m_className <<
"::SetCanvas: Null pointer.\n";
55 if (!m_hasExternalCanvas && m_canvas) {
60 m_hasExternalCanvas =
true;
66 std::cerr << m_className <<
"::SetMedium: Null pointer.\n";
75 if (emin >= emax || emin < 0.) {
76 std::cerr << m_className <<
"::SetElectricFieldRange: Incorrect range.\n";
86 if (bmin >= bmax || bmin < 0.) {
87 std::cerr << m_className <<
"::SetMagneticFieldRange: Incorrect range.\n";
97 if (amin >= amax || amin < 0.) {
98 std::cerr << m_className <<
"::SetBAngleRange: Incorrect range.\n";
108 if (vmin >= vmax || vmin < 0.) {
109 std::cerr << m_className <<
"::SetFunctionRange: Incorrect range.\n";
120 const double b,
const double a) {
123 double min = 0., max = 0.;
124 std::string title =
"";
129 }
else if (xaxis ==
'b') {
133 }
else if (xaxis ==
'a') {
139 AddFunction(min, max, m_vMin, m_vMax, keep, title, m_labelv,
142 AddFunction(min, max, m_vMin, m_vMax, keep, title, m_labelv,
145 AddFunction(min, max, m_vMin, m_vMax, keep, title, m_labelv,
151 const double b,
const double a) {
154 double min = 0., max = 0.;
155 std::string title =
"";
160 }
else if (xaxis ==
'b') {
164 }
else if (xaxis ==
'a') {
170 AddFunction(min, max, m_vMin, m_vMax, keep, title, m_labelv,
173 AddFunction(min, max, m_vMin, m_vMax, keep, title, m_labelv,
176 AddFunction(min, max, m_vMin, m_vMax, keep, title, m_labelv,
182 const double b,
const double a) {
186 AddFunction(m_eMin, m_eMax, m_vMin, m_vMax, keep, m_labele, m_labelv,
192 const double b,
const double a) {
196 AddFunction(m_eMin, m_eMax, m_vMin, m_vMax, keep, m_labele, m_labeld,
199 AddFunction(m_eMin, m_eMax, m_vMin, m_vMax, keep, m_labele, m_labeld,
206 const double b,
const double a) {
210 AddFunction(m_eMin, m_eMax, m_vMin, m_vMax, keep, m_labele, m_labeld,
213 AddFunction(m_eMin, m_eMax, m_vMin, m_vMax, keep, m_labele, m_labeld,
219 const double b,
const double a) {
223 AddFunction(m_eMin, m_eMax, m_vMin, m_vMax, keep, m_labele, m_labeld,
226 AddFunction(m_eMin, m_eMax, m_vMin, m_vMax, keep, m_labele, m_labeld,
232 const double b,
const double a) {
236 AddFunction(m_eMin, m_eMax, 0., 0., keep, m_labele,
242 const double b,
const double a) {
246 AddFunction(m_eMin, m_eMax, 0., 0., keep, m_labele,
247 "Townsend coefficient [1/cm]",
HoleTownsend, xaxis, e, b, a);
252 const double b,
const double a) {
256 AddFunction(m_eMin, m_eMax, 0., 0., keep, m_labele,
257 "Attachment coefficient [1/cm]",
263 const double b,
const double a) {
267 AddFunction(m_eMin, m_eMax, 0., 0., keep, m_labele,
273 const double b,
const double a) {
277 AddFunction(m_eMin, m_eMax, 0., 0., keep, m_labele,
285 std::cerr << m_className <<
"::PlotElectronCrossSections:\n";
286 std::cerr <<
" Function not yet implemented.\n";
290void ViewMedium::SetupCanvas() {
293 m_canvas =
new TCanvas();
294 m_canvas->SetTitle(
"Medium View");
295 if (m_hasExternalCanvas) m_hasExternalCanvas =
false;
298 gPad->SetLeftMargin(0.15);
301void ViewMedium::AddFunction(
const double xmin,
const double xmax,
302 const double ymin,
const double ymax,
303 const bool keep,
const std::string& xlabel,
304 const std::string& ylabel,
const int type,
305 const char xaxis,
const double e,
const double b,
310 std::cerr << m_className <<
"::AddFunction: Medium is not defined.\n";
316 std::string fname =
"fMediumView_0";
317 while (gROOT->GetListOfFunctions()->FindObject(fname.c_str())) {
319 std::stringstream ss;
320 ss <<
"fMediumView_";
325 std::cout << m_className <<
"::AddFunction:\n";
326 std::cout <<
" Adding function " << fname <<
"\n";
340 xmin, xmax, 2,
"ViewMedium",
"EvaluateFunction"));
341 m_functions.back().SetNpx(1000);
342 const std::string title = m_medium->
GetName() +
";" + xlabel +
";" + ylabel;
343 m_functions.back().SetRange(xmin, xmax);
344 if ((
fabs(ymax - ymin) > 0.)) {
345 m_functions.back().SetMinimum(ymin);
346 m_functions.back().SetMaximum(ymax);
348 m_functions.back().GetXaxis()->SetTitle(xlabel.c_str());
349 m_functions.back().GetXaxis()->SetTitleOffset(1.2);
350 m_functions.back().GetYaxis()->SetTitle(ylabel.c_str());
351 m_functions.back().SetTitle(title.c_str());
352 m_functions.back().SetParameter(0, type);
353 m_functions.back().SetParameter(1, xaxis);
357 if (type == 2 || type == 4) {
359 }
else if (type == 12 || type == 14 || type == 22) {
361 }
else if (type < 10) {
363 }
else if (type == 23) {
365 }
else if (type == 24) {
367 }
else if (type < 20 || type == 25 || type == 26) {
372 m_functions.back().SetLineColor(color);
374 std::vector<double> efields;
375 std::vector<double> bfields;
376 std::vector<double> bangles;
378 const unsigned int nEfields = efields.size();
379 const unsigned int nBfields = bfields.size();
380 const unsigned int nBangles = bangles.size();
381 bool withGraph = (nEfields > 0 && nBfields > 0 && nBangles > 0);
389 }
else if (xaxis ==
'b') {
392 }
else if (xaxis ==
'a') {
396 std::cerr << m_className <<
"::AddFunction:\n"
397 <<
" Error specifying X-axis. Invalid parameter type.\n";
400 graph.SetMarkerStyle(marker);
401 graph.SetMarkerColor(color);
411 for (
int i = 0; i < n; ++i) {
412 if (
fabs(efields[i] - m_efield) <= m_etolerance) {
417 for (
int i = 0; i < n; ++i) {
418 if (
fabs(bfields[i] - m_bfield) <= m_btolerance) {
423 for (
int i = 0; i < n; ++i) {
424 if (
fabs(bangles[i] - m_angle) <= m_atolerance) {
429 if ((xaxis ==
'e' && (bpoint == -1 || apoint == -1)) ||
430 (xaxis ==
'b' && (epoint == -1 || apoint == -1)) ||
431 (xaxis ==
'a' && (epoint == -1 || bpoint == -1)))
434 for (
int i = 0; i < n; ++i) {
437 double alongx = 0, alongy = 0., alongz = 0.;
446 else if (xaxis ==
'b')
448 else if (xaxis ==
'a')
511 efields[i] *
sin(bangles[apoint]),
512 0, bfields[bpoint], 0, 0, value,
514 else if (xaxis ==
'b')
516 efields[epoint] *
cos(bangles[apoint]),
517 efields[epoint] *
sin(bangles[apoint]), 0, bfields[i], 0, 0,
518 value, alongy, alongz);
519 else if (xaxis ==
'a') {
521 efields[epoint] *
sin(bangles[i]),
522 0, bfields[bpoint], 0, 0, value,
531 efields[i] *
sin(bangles[apoint]),
532 0, bfields[bpoint], 0, 0, alongx,
534 else if (xaxis ==
'b')
536 efields[epoint] *
cos(bangles[apoint]),
537 efields[epoint] *
sin(bangles[apoint]), 0, bfields[i], 0, 0,
538 alongx, alongy, value);
539 else if (xaxis ==
'a')
541 m_efield *
cos(bangles[i]), m_efield *
sin(bangles[i]), 0,
542 m_bfield, 0, 0, alongx, alongy, value);
550 efields[i] *
sin(bangles[apoint]), 0,
551 bfields[bpoint], 0, 0, value, alongy,
553 else if (xaxis ==
'b')
555 efields[epoint] *
sin(bangles[apoint]),
556 0, bfields[i], 0, 0, value, alongy,
558 else if (xaxis ==
'a')
560 efields[epoint] *
sin(bangles[i]), 0,
561 bfields[bpoint], 0, 0, value, alongy,
567 efields[i] *
sin(bangles[apoint]), 0,
568 bfields[bpoint], 0, 0, alongx, alongy,
570 else if (xaxis ==
'b')
572 efields[epoint] *
sin(bangles[apoint]),
573 0, bfields[i], 0, 0, alongx, alongy,
575 else if (xaxis ==
'a')
577 m_efield *
sin(bangles[i]), 0, m_bfield,
578 0, 0, alongx, alongy, value);
586 else if (xaxis ==
'b')
587 graph.SetPoint(i, bfields[i], value);
588 else if (xaxis ==
'a')
589 graph.SetPoint(i, bangles[i], value);
592 m_graphs.push_back(graph);
594 std::cerr << m_className <<
"::AddFunction:\n";
595 std::cerr <<
" Error retrieving data table.\n";
596 std::cerr <<
" Suppress plotting of graph.\n";
600 if (keep && m_functions.size() > 1) {
601 m_functions[0].GetYaxis()->SetTitleOffset(1.5);
602 m_functions[0].Draw(
"");
603 const unsigned int nFunctions = m_functions.size();
604 for (
unsigned int i = 1; i < nFunctions; ++i) {
605 m_functions[i].Draw(
"lsame");
608 m_functions.back().GetYaxis()->SetTitleOffset(1.5);
609 m_functions.back().Draw(
"");
611 if (!m_graphs.empty()) {
612 const unsigned int nGraphs = m_graphs.size();
613 for (
unsigned int i = 0; i < nGraphs; ++i) {
614 m_graphs[i].Draw(
"p");
622 if (m_medium == 0)
return 0.;
623 int type = int(par[0]);
624 char xaxis = char(par[1]);
625 const double x = pos[0];
629 double value = 0., a = 0., b = 0., c = 0.;
630 double alongx = 0., alongy = 0., alongz = 0.;
637 m_bfield * sin(m_angle), 0, a, b, c))
639 }
else if (xaxis ==
'b') {
642 x * sin(m_angle), 0, a, b, c))
644 }
else if (xaxis ==
'a') {
647 m_bfield * sin(x), 0, a, b, c))
673 if (!m_medium->
HoleVelocity(x, 0, 0, 0, 0, 0, a, b, c))
return 0.;
677 if (!m_medium->
HoleDiffusion(x, 0, 0, 0, 0, 0, a, b))
return 0.;
681 if (!m_medium->
HoleDiffusion(x, 0, 0, 0, 0, 0, a, b))
return 0.;
685 if (!m_medium->
HoleTownsend(x, 0, 0, 0, 0, 0, a))
return 0.;
693 if (!m_medium->
IonVelocity(x, 0, 0, 0, 0, 0, a, b, c))
return 0.;
697 if (!m_medium->
IonDiffusion(x, 0, 0, 0, 0, 0, a, b))
return 0.;
701 if (!m_medium->
IonDiffusion(x, 0, 0, 0, 0, 0, a, b))
return 0.;
708 m_bfield, 0, 0, value, alongy, alongz))
710 }
else if (xaxis ==
'b') {
713 m_efield * sin(m_angle), 0, x, 0, 0,
714 value, alongy, alongz))
716 }
else if (xaxis ==
'a') {
719 m_bfield, 0, 0, value, alongy, alongz))
728 m_bfield, 0, 0, alongx, alongy, value))
730 }
else if (xaxis ==
'b') {
733 m_efield * sin(m_angle), 0, x, 0, 0,
734 alongx, alongy, value))
736 }
else if (xaxis ==
'a') {
739 m_bfield, 0, 0, alongx, alongy, value))
747 if (!m_medium->
HoleVelocity(x * cos(m_angle), x * sin(m_angle), 0,
748 m_bfield, 0, 0, value, alongy, alongz))
750 }
else if (xaxis ==
'b') {
753 m_efield * sin(m_angle), 0, x, 0, 0, value,
756 }
else if (xaxis ==
'a') {
758 if (!m_medium->
HoleVelocity(m_efield * cos(x), m_efield * sin(x), 0,
759 m_bfield, 0, 0, value, alongy, alongz))
767 if (!m_medium->
HoleVelocity(x * cos(m_angle), x * sin(m_angle), 0,
768 m_bfield, 0, 0, alongx, alongy, value))
770 }
else if (xaxis ==
'b') {
773 m_efield * sin(m_angle), 0, x, 0, 0, alongx,
776 }
else if (xaxis ==
'a') {
778 if (!m_medium->
HoleVelocity(m_efield * cos(x), m_efield * sin(x), 0,
779 m_bfield, 0, 0, alongx, alongy, value))
785 std::cerr << m_className <<
"::EvaluateFunction:\n";
786 std::cerr <<
" Unknown type of transport coefficient requested.\n";
787 std::cerr <<
" Program bug!\n";
794int ViewMedium::GetColor(
const unsigned int prop)
const {
Abstract base class for media.
virtual double UnScaleElectricField(const double e) const
virtual double ScaleVelocity(const double v) const
bool GetElectronVelocityE(const unsigned int ie, const unsigned int ib, const unsigned int ia, double &v)
virtual bool HoleTownsend(const double ex, const double ey, const double ez, const double bx, const double by, const double bz, double &alpha)
virtual double ScaleAttachment(const double eta) const
virtual double ScaleDiffusion(const double d) const
virtual bool HoleVelocity(const double ex, const double ey, const double ez, const double bx, const double by, const double bz, double &vx, double &vy, double &vz)
virtual double ScaleLorentzAngle(const double lor) const
virtual bool ElectronLorentzAngle(const double ex, const double ey, const double ez, const double bx, const double by, const double bz, double &lor)
bool GetIonLongitudinalDiffusion(const unsigned int ie, const unsigned int ib, const unsigned int ia, double &dl)
bool GetHoleAttachment(const unsigned int ie, const unsigned int ib, const unsigned int ia, double &eta)
bool GetElectronAttachment(const unsigned int ie, const unsigned int ib, const unsigned int ia, double &eta)
virtual bool ElectronVelocity(const double ex, const double ey, const double ez, const double bx, const double by, const double bz, double &vx, double &vy, double &vz)
virtual bool IonVelocity(const double ex, const double ey, const double ez, const double bx, const double by, const double bz, double &vx, double &vy, double &vz)
bool GetIonMobility(const unsigned int ie, const unsigned int ib, const unsigned int ia, double &mu)
bool GetElectronTownsend(const unsigned int ie, const unsigned int ib, const unsigned int ia, double &alpha)
bool GetElectronLorentzAngle(const unsigned int ie, const unsigned int ib, const unsigned int ia, double &lor)
virtual double ScaleTownsend(const double alpha) const
bool GetHoleTownsend(const unsigned int ie, const unsigned int ib, const unsigned int ia, double &alpha)
virtual bool ElectronDiffusion(const double ex, const double ey, const double ez, const double bx, const double by, const double bz, double &dl, double &dt)
void GetFieldGrid(std::vector< double > &efields, std::vector< double > &bfields, std::vector< double > &angles)
virtual bool ElectronTownsend(const double ex, const double ey, const double ez, const double bx, const double by, const double bz, double &alpha)
const std::string & GetName() const
bool GetElectronTransverseDiffusion(const unsigned int ie, const unsigned int ib, const unsigned int ia, double &dt)
virtual bool ElectronAttachment(const double ex, const double ey, const double ez, const double bx, const double by, const double bz, double &eta)
bool GetHoleVelocityE(const unsigned int ie, const unsigned int ib, const unsigned int ia, double &v)
bool GetHoleTransverseDiffusion(const unsigned int ie, const unsigned int ib, const unsigned int ia, double &dt)
bool GetElectronLongitudinalDiffusion(const unsigned int ie, const unsigned int ib, const unsigned int ia, double &dl)
virtual bool HoleDiffusion(const double ex, const double ey, const double ez, const double bx, const double by, const double bz, double &dl, double &dt)
bool GetHoleLongitudinalDiffusion(const unsigned int ie, const unsigned int ib, const unsigned int ia, double &dl)
virtual bool HoleAttachment(const double ex, const double ey, const double ez, const double bx, const double by, const double bz, double &eta)
virtual bool IonDiffusion(const double ex, const double ey, const double ez, const double bx, const double by, const double bz, double &dl, double &dt)
bool GetIonTransverseDiffusion(const unsigned int ie, const unsigned int ib, const unsigned int ia, double &dt)
int GetRootColorElectron()
double EvaluateFunction(double *pos, double *par)
void PlotElectronVelocity(const char xaxis, const double e, const double b, const double a=HalfPi)
void SetMedium(Medium *m)
void PlotIonDiffusion(const char xaxis, const double e, const double b, const double a=HalfPi)
void SetElectricFieldRange(const double emin, const double emax)
Set the limits of the electric field.
void PlotHoleTownsend(const char xaxis, const double e, const double b, const double a=HalfPi)
void PlotIonVelocity(const char xaxis, const double e, const double b, const double a=HalfPi)
void PlotElectronLorentzAngle(const char xaxis, const double e, const double b, const double a=HalfPi)
void PlotElectronTownsend(const char xaxis, const double e, const double b, const double a=HalfPi)
void PlotHoleVelocity(const char xaxis, const double e, const double b, const double a=HalfPi)
void PlotHoleAttachment(const char xaxis, const double e, const double b, const double a=HalfPi)
@ HoleTransverseDiffusion
@ HoleLongitudinalDiffusion
@ ElectronTransverseDiffusion
@ ElectronLongitudinalDiffusion
@ IonLongitudinalDiffusion
void PlotElectronCrossSections()
void SetCanvas(TCanvas *c)
Set the canvas to be painted on.
void PlotElectronAttachment(const char xaxis, const double e, const double b, const double a=HalfPi)
void SetFunctionRange()
Use the default function range.
void SetMagneticFieldRange(const double bmin, const double bmax)
Set the limits of the magnetic field.
void PlotElectronDiffusion(const char xaxis, const double e, const double b, const double a=HalfPi)
void PlotHoleDiffusion(const char xaxis, const double e, const double b, const double a=HalfPi)
void SetBAngleRange(const double amin, const double amax)
Set the limits of the angle between electric and magnetic field.
PlottingEngineRoot plottingEngine
DoubleAc cos(const DoubleAc &f)
DoubleAc exp(const DoubleAc &f)
DoubleAc fabs(const DoubleAc &f)
DoubleAc sin(const DoubleAc &f)