Skip to content
Snippets Groups Projects
Commit db68e3bf authored by pospelov's avatar pospelov
Browse files

TestFresnelCoeff improved drawing of T,R fresnel coefficients for test...

TestFresnelCoeff improved drawing of T,R fresnel coefficients for test samples, DrawHelper added drawing of sample
parent e8945efa
No related branches found
No related tags found
No related merge requests found
......@@ -18,6 +18,8 @@
class TCanvas;
class MultiLayer;
class TPad;
//- -------------------------------------------------------------------
//! @class DrawHelper
......@@ -44,6 +46,9 @@ public:
//! process double click in canvas to magnify given pad
void ExecuteMagnifier(Int_t event, Int_t px, Int_t py, TObject *sel);
//! draw multilayer structure in TPad
void DrawMultilayer(const MultiLayer *sample);
private:
/// prevents client from creating a copy of the singleton
DrawHelper();
......
......@@ -20,25 +20,23 @@
#include "OutputData.h"
//- -------------------------------------------------------------------
//! @class TestFresnelCoeff
//! @brief Calculate Fresnel coefficients for several typical multilayer
//! samples and produce validation plots
//- -------------------------------------------------------------------
class TestFresnelCoeff : public IAlgorithm
{
public:
TestFresnelCoeff();
// class MyData {
// public:
// double alpha_i;
// OpticalFresnel::MultiLayerCoeff_t coeffs;
// };
// typedef std::vector<MyData > MyDataSet_t;
void execute();
// void Draw(const MultiLayer *sample, const MyDataSet_t &data);
void Draw(const MultiLayer *sample);
private:
OutputData<OpticalFresnel::MultiLayerCoeff_t > *m_coeffs;
void draw();
private:
MultiLayer *m_sample; //!< pointer to multilayer sample
OutputData<OpticalFresnel::MultiLayerCoeff_t > *m_coeffs; //!< output data structure
};
......
#include "DrawHelper.h"
#include "Exceptions.h"
#include "MultiLayer.h"
#include <iostream>
#include <vector>
#include <map>
#include <string>
#include <list>
#include "TROOT.h"
#include "TCanvas.h"
#include "TObject.h"
#include "TStyle.h"
#include "TKey.h"
#include "TLine.h"
#include "TBox.h"
#include "TLatex.h"
#include "TH1F.h"
DrawHelper *DrawHelper::m_instance = 0;
bool DrawHelper::m_destroyed = false;
......@@ -70,7 +79,7 @@ void DrawHelper::onDeadReference() {
/* ************************************************************************* */
// assign function to handle mouse events inside canvas
// assign function to canvas to handle mouse events inside canvas
/* ************************************************************************* */
void DrawHelper::SetMagnifier(TCanvas *canvas)
{
......@@ -83,11 +92,9 @@ void DrawHelper::SetMagnifier(TCanvas *canvas)
/* ************************************************************************* */
void DrawHelper::ExecuteMagnifier(int event, int px, int py, TObject *sel)
{
TCanvas *c = (TCanvas *) gTQSender;
if(sel) {
// we do not need it for the moment
}
(void)sel;
if ( (event == kButton1Double) ) {
TCanvas *c = (TCanvas *) gTQSender;
char cname[256];
sprintf(cname,"%s_%d",c->GetTitle(),(int)time(0));
TPad *pad = c->Pick(px, py, 0);
......@@ -98,7 +105,6 @@ void DrawHelper::ExecuteMagnifier(int event, int px, int py, TObject *sel)
pad_new->SetEditable(kTRUE);
pad_new->Draw();
pad_new->Modified();
//gVirtualX->SetCursor(gPad->GetId() , gVirtualX->CreateCursor(kWatch));
pad_new->Update();
c1->RaiseWindow();
}
......@@ -248,4 +254,93 @@ void DrawHelper::SaveReport()
}
/* ************************************************************************* */
// Draw multilayer structure in gPad
/* ************************************************************************* */
void DrawHelper::DrawMultilayer(const MultiLayer *sample)
{
size_t nlayers = sample->getNumberOfLayers();
if(nlayers < 1) return;
double z1 = sample->getLayerBottomZ(0);
double z2 = sample->getLayerBottomZ(nlayers-1);
double size = std::abs(z2 - z1); // typical size of sample
double margin = size*0.02; // safety margin to avoid overlapping of layers
double fake_thickness = size*0.3; // thickness for layers without defined thickness (like ambience&substrate)
// frame to draw
TH1F *h1 = gPad->DrawFrame(-size, -size*2., size, size*1.0);
h1->GetXaxis()->SetTitle("X, [nm]");
h1->GetYaxis()->SetTitle("Y, [nm]");
h1->GetYaxis()->SetTitleOffset(1.4);
// drawing properties for interfaces, material and their names
TLine interface;
interface.SetLineWidth(3);
interface.SetLineStyle(3);
interface.SetLineColor(kRed);
TBox bulk;
bulk.SetFillStyle(1001);
TLatex tex;
tex.SetNDC(false);
tex.SetTextAlign(12);
tex.SetTextSize(0.04);
// defining set of good colors
int a_colors[]={kOrange, kAzure+1, kViolet-9, kCyan+2, kViolet+6, kRed+1, kOrange-3, kBlue-9};
std::list<int> good_colors(a_colors, a_colors+sizeof(a_colors)/sizeof(int));
// map of correspondance between material with given name and used color
// two colors are reserved for materials with name 'substrate' and 'ambience'
std::map<std::string, int> colors;
colors["substrate"] = kOrange-5;
colors["ambience"] = kCyan-10;
// loop over layers and drawing
for(size_t i_layer = 0; i_layer<nlayers; i_layer++) {
const Layer *layer = sample->getLayer(i_layer);
double z = sample->getLayerBottomZ(i_layer);
double thickness = layer->getThickness();
//calculating size of box representing layer
double x1(0), x2(0), y1(0), y2(0);
x1 = -size*0.5;
x2 = size*0.5;
y1 = z;
y2 = z+thickness;
// but top and bottom layers need special treatment, since they thickness==0
if(i_layer==0) { // ambience normally doesn't have thickness
y1=z;
y2=z+fake_thickness;
}
if(i_layer==nlayers-1) { // substrate normally doesn't have thickness and has wrong zbottom
y2=z;
y1=z-fake_thickness;
}
// selecting colors for bulk material, materials with same name will have same color
int color = kBlack;
std::string matname = layer->getMaterial()->getName();
std::map<std::string, int>::iterator pos = colors.find(matname);
if(pos != colors.end()) {
// existing material
color = pos->second;
}else{
// new material
color = good_colors.front(); // taking color from list of good colors
good_colors.remove(color); // this color want be used anymore
colors[matname] = color; // saving correspondance of selected color and material
}
bulk.SetFillColor(color);
bulk.DrawBox(x1,y1+margin,x2,y2-margin);
tex.DrawLatex(x2+margin, (y1+y2)/2., matname.c_str());
if(sample->getLayerBottomInterface(i_layer)) interface.DrawLine(x1,y1,x2,y1);
}
gPad->Update();
}
......@@ -98,7 +98,7 @@ ISample *StandardSamples::SimpleMultilayer()
// adding layers
mySample->addLayer(lAmbience);
const unsigned nrepetitions = 1;
const unsigned nrepetitions = 2;
for(unsigned i=0; i<nrepetitions; ++i) {
mySample->addLayer(lAg1);
mySample->addLayer(lCr1);
......
......@@ -4,6 +4,8 @@
#include "TGraph.h"
#include "TH1F.h"
#include "TApplication.h"
#include "TLatex.h"
#include "TLegend.h"
#include "Layer.h"
#include "MultiLayer.h"
......@@ -28,9 +30,10 @@ void TestFresnelCoeff::execute()
{
std::cout << "TestFresnelCoeff::execute() -> Info." << std::endl;
//size_t nsamples = SampleFactory::instance().getNumberOfSamples();
for(int i_sample=0; i_sample<2; i_sample++){
MultiLayer *mySample = dynamic_cast<MultiLayer *>(SampleFactory::instance().createStandard(i_sample));
// loop over standard samples defined in SampleFactory and StandardSamples
size_t nsamples = SampleFactory::instance().getNumberOfSamples();
for(size_t i_sample=0; i_sample<nsamples; i_sample++){
m_sample = dynamic_cast<MultiLayer *>(SampleFactory::instance().createStandard(i_sample));
m_coeffs = new OutputData<OpticalFresnel::MultiLayerCoeff_t >;
......@@ -45,34 +48,41 @@ void TestFresnelCoeff::execute()
kvector_t kvec = kvector_t::LambdaAlphaPhi(1.54*Units::angstrom, -alpha_i, 0.0);
OpticalFresnel::MultiLayerCoeff_t coeffs;
OpticalFresnel::execute(*mySample, kvec, coeffs);
OpticalFresnel::execute(*m_sample, kvec, coeffs);
m_coeffs->currentValue() = coeffs;
++index;
} // alpha_i
Draw(mySample);
draw();
delete mySample;
delete m_sample;
delete m_coeffs;
} // i_sample
}
void TestFresnelCoeff::Draw(const MultiLayer *sample)
void TestFresnelCoeff::draw()
{
static int ncall = 0;
//size_t nlayers = data.front().coeffs.size();
size_t nlayers = sample->getNumberOfLayers();
// creation of graphics to plot R,T coefficients in layers as a function of alpha_i
std::vector<TGraph *> gr_absR;
std::vector<TGraph *> gr_absT;
size_t nlayers = m_sample->getNumberOfLayers();
// graphics for R,T coefficients in layers as a function of alpha_i
size_t ncoeffs = 2;
enum key_coeffs { kCoeffR, kCoeffT};
const char *coeffs_title[]={" |R| "," |T| "};
int coeffs_color[] = {kBlue, kRed};
std::vector<std::vector<TGraph *> > gr_coeff; // [nlayers][ncoeffs]
gr_coeff.resize(nlayers);
for(size_t i_layer=0; i_layer<nlayers; i_layer++) {
gr_absR.push_back(new TGraph() );
gr_absT.push_back(new TGraph() );
gr_coeff[i_layer].resize(ncoeffs,0);
for(size_t i_coeff=0; i_coeff<ncoeffs; i_coeff++) {
gr_coeff[i_layer][i_coeff] = new TGraph();
}
}
TGraph *gr_absSum = new TGraph(); // |R_top|+|T_bottom|
......@@ -88,15 +98,14 @@ void TestFresnelCoeff::Draw(const MultiLayer *sample)
// Filling graphics for R,T as a function of alpha_i
for(size_t i_layer=0; i_layer<nlayers; ++i_layer ) {
gr_absR[i_layer]->SetPoint(i_point, Units::rad2deg(alpha_i), std::abs(coeffs[i_layer].R) );
gr_absT[i_layer]->SetPoint(i_point, Units::rad2deg(alpha_i), std::abs(coeffs[i_layer].T) );
//std::cout << Units::rad2deg(alpha_i) << " l:" << i_layer << " R:" << std::abs(coeffs[i_layer].R) << "T:" << std::abs(coeffs[i_layer].T) << std::endl;
gr_coeff[i_layer][kCoeffR]->SetPoint(i_point, Units::rad2deg(alpha_i), std::abs(coeffs[i_layer].R) );
gr_coeff[i_layer][kCoeffT]->SetPoint(i_point, Units::rad2deg(alpha_i), std::abs(coeffs[i_layer].T) );
}
// Filling graphics for |R|+|T| as a function of alpha_i taking R from the top and T from the bottom layers
int nlast = nlayers - 1;
complex_t nx = sample->getLayer(nlast)->getRefractiveIndex();
complex_t n1 = sample->getLayer(0)->getRefractiveIndex();
complex_t nx = m_sample->getLayer(nlast)->getRefractiveIndex();
complex_t n1 = m_sample->getLayer(0)->getRefractiveIndex();
//std::complex<double> kk = (1./(n1*std::sin(theta_i)))*std::sqrt(std::pow(nx,2)-cos(theta_i)*cos(theta_i)*std::pow(n1,2));
complex_t kk = std::sqrt((complex_t(1,0) - cos(alpha_i)*cos(alpha_i)/nx/nx) ) / sin(alpha_i);
double sum = std::norm(coeffs[0].R) + std::abs(kk)*std::norm(coeffs[nlast].T);
......@@ -113,42 +122,55 @@ void TestFresnelCoeff::Draw(const MultiLayer *sample)
// create name of canvas different for each new call of this method
std::ostringstream os;
os << (ncall++) << std::endl;
std::string cname = std::string("c1_test_fresnel")+os.str();
std::string cname = std::string("c1_test_fresnel_sample")+os.str();
TCanvas *c1 = new TCanvas(cname.c_str(),"Fresnel Coefficients in Multilayer",1024,768);
//DrawHelper::instance().SetMagnifier(c1);
int ndivy = sqrt(nlayers);
int ndivx = nlayers/ndivy + 1;
//c1->Divide(ndivx, ndivy);
c1->Divide(2,2);
TH1F *h1ref = new TH1F("h1ref","h1ref",100,0.0,2.0);
h1ref->SetMinimum(0.01);
h1ref->SetMaximum(3.0);
h1ref->SetStats(0);
h1ref->SetTitle("");
DrawHelper::instance().SetMagnifier(c1);
// estimate subdivision of canvas (we need place for 'nlayers' and for one sample picture)
int ndiv(2);
if( nlayers+1 > 4 ) ndiv = int(sqrt(nlayers+1)+1);
c1->Divide(ndiv,ndiv);
for(size_t i_layer=0; i_layer<nlayers; i_layer++) {
c1->cd(i_layer+1);
//gPad->SetLogy();
h1ref->Draw();
TGraph *gr = gr_absR[i_layer];
gr->SetLineColor(kBlue);
gr->SetMarkerColor(kBlue);
gr->SetMarkerStyle(21);
gr->SetMarkerSize(0.2);
gr->Draw("pl same");
gr = gr_absT[i_layer];
gr->SetMarkerStyle(21);
gr->SetMarkerSize(0.2);
gr->SetLineColor(kRed);
gr->SetMarkerColor(kRed);
gr->Draw("pl same");
double xmin, ymin, xmax, ymax;
gr->ComputeRange(xmin, ymin, xmax, ymax);
std::cout << i_layer << " xmin:" << xmin << " ymin:" << ymin << " xmax:" << xmax << " ymax:" << ymax << std::endl;
c1->cd(i_layer+1);
// calculating histogram limits common for all graphs on given pad
double xmin(0), ymin(0), xmax(0), ymax(0);
for(size_t i_coeff=0; i_coeff<ncoeffs; i_coeff++){
double x1(0), y1(0), x2(0), y2(0);
gr_coeff[i_layer][kCoeffT]->ComputeRange(x1, y1, x2, y2);
if(x1 < xmin ) xmin= x1;
if(x2 > xmax ) xmax = x2;
if(y1 < ymin ) ymin = y1;
if(y2 > ymax ) ymax = y2;
}
TH1F h1ref("h1ref","h1ref",100, xmin, xmax);
h1ref.SetMinimum(ymin);
h1ref.SetMaximum(ymax*1.1);
h1ref.SetStats(0);
h1ref.SetTitle("");
h1ref.GetXaxis()->SetTitle("angle, deg");
h1ref.GetYaxis()->SetTitle("|R|, |T|");
h1ref.DrawCopy();
TLegend *leg = new TLegend(0.725,0.7,0.89,0.88);
leg->SetTextSize(0.04);
leg->SetBorderSize(1);
leg->SetFillStyle(0);
std::ostringstream os;
os << " layer #" << i_layer;
leg->SetHeader(os.str().c_str());
for(size_t i_coeff=0; i_coeff<ncoeffs; i_coeff++) {
TGraph *gr = gr_coeff[i_layer][i_coeff];
gr->SetLineColor( coeffs_color[i_coeff] );
gr->SetMarkerColor( coeffs_color[i_coeff] );
gr->SetMarkerStyle(21);
gr->SetMarkerSize(0.2);
gr->Draw("pl same");
leg->AddEntry(gr, coeffs_title[i_coeff],"pl");
}
leg->Draw();
}
TGraph *gr = gr_absSum;
gr->SetMarkerStyle(21);
......@@ -156,7 +178,16 @@ void TestFresnelCoeff::Draw(const MultiLayer *sample)
gr->SetLineColor(kMagenta);
gr->SetMarkerColor(kMagenta);
gr->Draw("pl same");
TLegend *leg = new TLegend(0.625,0.6,0.89,0.69);
leg->SetTextSize(0.04);
leg->SetBorderSize(0);
leg->SetFillStyle(0);
leg->AddEntry(gr, "|R_top|+|T_bottom|","pl");
leg->Draw();
// drawing sample geometry
c1->cd(nlayers+1);
DrawHelper::instance().DrawMultilayer(m_sample);
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment