#include "include/guide.h"
#include "src/raySimulator.cpp"
#include "TFile.h"
#include "TPolyMarker3D.h"
#include "TCanvas.h"
//extern int show_3d;
//extern int show_data;
// Set the simulation parameters
void showVisual(int b) {show_3d = b;}
void showData(int b) {show_data = b;}
// Set the initial detector parameters (a, b, d, activeDetector, n1, n2, n3, gap, badCoupling)
DetectorParameters parameters(3.0, 5.0, 3.0, 3.0, 1, 1.53, 1.46, TVector3(0.3, 0, 0), false);
// Print the detector parameters
void getParameters();
//void SetLGType(int in = 1, int side = 1, int out = 0)
//{detector->SetLGType(in, side, out);}
void setLG(double SiPM0 = 3.0, double b0 = 5.0, double d0 = 3.0, double n1 = 1.0, double n2 = 1.53, double n3 = 1.46)
{ parameters.setGuide(SiPM0, b0, d0);
parameters.setIndices(n1, n2, n3); }
void setGap(double x_gap0 = 0.3, double y_gap0 = 0.0, double z_gap0 = 0.0)
{ parameters.setGap(x_gap0, y_gap0, z_gap0); }
void setGlass(double glassOn, double glassD)
{ parameters.setGlass(glassOn, glassD); };
void setPlate(int plateOn = 1, double plateWidth = 1)
{ parameters.setPlate(plateOn, plateWidth); }
void setFresnel(int fresnel = 1) { parameters.setFresnel(fresnel); }
// Refractive Indices
// n1 - around light guide - air
// n2 - light guide (plate) material - k9 glass
// n3 - the material at the exit - optical grease, epoxy, air, etc.
void setIndices(double n1, double n2, double n3) {parameters.setIndices(n1, n2, n3);}
int save_ary = 0;
//------------------------------------------------------------------------------------------
void Help()
{
printf("void SetCenter(x, y, z)\n");
printf("void SetLGType(in, side, out)\n");
printf("SURF_DUMMY 0, ");
printf("SURF_REFRA 1, ");
printf("SURF_REFLE 2, ");
printf("SURF_TOTAL 3, ");
printf("SURF_IMPER 4\n");
printf("void SetLG(SiPM0, M0, d0, n10, n20, n30, R0)\n");
printf("void SetR(R0)\n");
printf("void SetGlass(glass_on0, glass_d0)\n");
printf("void SetGap(x_gap0, y_gap0, z_gap0)\n");
printf("LGG(NN, theta)\n");
printf("LGR(NN, theta, phi)\n");
printf("LGI(NN, theta)\n");
printf("LGI_gap(NN, min, max, steps, theta)\n");
printf("LGR_gap(NN, min, max, steps, theta, phi)\n");
printf("LGR_th(NN, min, max, steps, phi)\n");
printf("LGG_th(NN, min, max, steps)\n");
printf("LGI_ad(NN, mina, maxa, mind, maxd, steps(memory dependent), theta)");
}
//------------------------------------------------------------------------------------------
int show_in_steps = 0;
void SetShowInSteps(int in = 1)
{
show_in_steps = in;
}
//------------------------------------------------------------------------------------------
int gs_set = 0;
void SetGS()
{
const UInt_t Number = 2;
Double_t Red[Number] = { 1.00, 0.00};
Double_t Green[Number] = { 1.00, 0.00};
Double_t Blue[Number] = { 1.00, 0.00};
Double_t Stops[Number] = { 0.00, 1.00};
Int_t nb=50;
if(!gs_set) {
TColor::CreateGradientColorTable(Number,Stops,Red,Green,Blue,nb);
gs_set = 1;
}
}
//------------------------------------------------------------------------------------------
void Draw1(CDetector *detector, int gs = 0, double range = 0.0)
{
if(gs) SetGS();
TCanvas *cdata = new TCanvas("cdata", "2dscan", 350, 0, 500, 500);
gStyle->SetOptTitle(0);
gStyle->SetOptStat(0);
cdata->cd(0);
if(range > 0.1) {
((detector->GetHLaser())->GetXaxis())->SetRangeUser(-range,range);
((detector->GetHLaser())->GetYaxis())->SetRangeUser(-range,range);
}
(detector->GetHLaser())->SetTitle("Hits at LG entrance; x [mm]; y [mm]");
(detector->GetHLaser())->Draw("COLZ");
cdata->SaveAs("2dscan.gif");
//gStyle->SetOptTitle(1);
//gStyle->SetOptStat(1);
}
//------------------------------------------------------------------------------------------
// Test function
// creates an optical boundary surface
// shows the propagation of light ray
// and polarization state of the incident ray (green)
// and surface normal (blue)
void PolTest(double theta = 0.0)
{
int p_type = SURF_REFRA;
double p_n1 = parameters.getN1();
double p_n2 = parameters.getN2();
theta = 3.141593*theta/180.0;
if(theta < 1e-6) theta = 1e-6;
Init();
double cx = 0.0;
TVector3 vodnik_edge[4];
double t = 3.0;
vodnik_edge[0].SetXYZ(cx, t,-t);
vodnik_edge[1].SetXYZ(cx, t, t);
vodnik_edge[2].SetXYZ(cx,-t, t);
vodnik_edge[3].SetXYZ(cx,-t,-t);
CSurface *surf = new CSurface(p_type, vodnik_edge, p_n1, p_n2, 0.96);
surf->FlipN();
surf->SetFresnel(1);
surf->Draw();
CRay *ray = new CRay(cx, 0.0, 0.0, TMath::Cos(theta), 0.0, TMath::Sin(theta));
ray->SetColor(kRed);
//p_pol = rotatey(p_pol0, -theta);
TVector3 sE(0,1,0);
TVector3 pE(0,0,1);
TVector3 p_pol = pE;
p_pol.RotateY(-theta);
//printf("p_pol = "); printv(p_pol);
ray->setPolarization(p_pol);
ray->DrawS(cx, -5.0);
CRay *out = new CRay;
out->SetColor(kBlack);
TVector3 *inters = new TVector3;
surf->PropagateRay(*ray, out, inters);
printf(" n1 = %f, n2 = %f\n", p_n1, p_n2);
//if(fate == 1) out->DrawS(cx, 5.0);
out->DrawS(cx, 5.0);
CRay *incidentPolarization = new CRay;
incidentPolarization->SetColor(kGreen);
incidentPolarization->Set(ray->GetR(), p_pol);
incidentPolarization->DrawS(cx, 1.0);
printf(" GREEN: polarization vector\n");
CRay *surfaceNormal = new CRay;
surfaceNormal->SetColor(kBlue);
surfaceNormal->Set(ray->GetR(), surf->GetN());
surfaceNormal->DrawS(cx, 1.0);
printf(" BLUE: surface normal vector\n");
}
void ptt()
{
for(double th = 0.0; th < 91.0; th += 5.0) {
printf("%lf ", th);
PolTest(th);
}
}
//------------------------------------------------------------------------------------------
// Propagate single ray and show the statistics
void LGS(double xh = 0.0, double yh = 0.0, double zh = 0.0, double theta = 0.0, double phi = 0.0)
{
CDetector *detector = new CDetector(CENTER, parameters);
Init();
double izkoristek = Single(detector, parameters, TVector3(xh,yh,zh),theta, phi);
PrintGuideHead();
PrintGuideStat(izkoristek);
DrawData(detector, parameters, theta, izkoristek);
}
//------------------------------------------------------------------------------------------
// Propagate NN rays generated as grid and show the statistics
void LGG(int NN=10, double theta=0.0, bool coupling=false)
{
parameters.setCoupling(coupling);
CDetector *detector = new CDetector(CENTER, parameters);
Init();
double izkoristek = Grid(detector, parameters, NN, theta);
//printf("izkoristek = %.3lf\n", izkoristek);
PrintGuideHead();
PrintGuideStat(izkoristek);
DrawData(detector, parameters, theta, izkoristek);
}
//------------------------------------------------------------------------------------------
// Propagate NN rays genarated under the same angle theta, phi with random spacing and statistics
void LGR(int NN = 1e4, double theta = 0.0, double phi = 0.0)
{
CDetector *detector = new CDetector(CENTER, parameters);
Init();
double izkoristek = RandYZ(detector, parameters, NN, theta, phi, 30);
//printf("izkoristek = %.3lf\n", izkoristek);
PrintGuideHead(); PrintGuideStat(izkoristek);
DrawData(detector, parameters, theta, izkoristek);
}
//------------------------------------------------------------------------------------------
// Propagate NN rays isotropically generated in solid angle theta and show the statistics
void LGI(int NN = 1e4, double theta = 30.0, int nnrays = 30, int showr = 0)
{
Init();
CDetector *detector = new CDetector(CENTER, parameters);
//CDetector detector = new CDetector();
double izkoristek = RandIso(detector, parameters, NN, 0.0, theta, nnrays, showr);
//printf("izkoristek = %.3lf\n", izkoristek);
PrintGuideHead();
PrintGuideStat(izkoristek);
DrawData(detector, parameters, theta, izkoristek);
//TCanvas *canvasDetector = new TCanvas("canvasDetector","canvasDetector",500,500);
//canvasDetector->cd();
//detector->Draw();
}
void LGB(int NN = 1e4, double phiMin=-19.4, double phiMax=19.4, bool coupling=true, int nnrays = 30, int showr = 0)
{
Init();
parameters.setCoupling(coupling);
CDetector *detector = new CDetector(CENTER, parameters);
const double theta = 18.5;
double izkoristek = beamtest(detector, parameters, NN, theta, phiMin, phiMax, nnrays, showr);
PrintGuideHead();
PrintGuideStat(izkoristek);
DrawData(detector, parameters, 18.5, izkoristek);
//TCanvas *canvasDetector = new TCanvas("canvasDetector","canvasDetector",500,500);
//canvasDetector->cd();
//detector->Draw();
}
//------------------------------------------------------------------------------------------
void LGI_gap(int NN = 1e4, double min = 0.0, double max = 2.0, const int steps = 10, double theta = 30.0)
{
int tmp3d = show_3d, tmpdata = show_data;
double step[steps], acc[steps];
show_3d = 0; show_data = 0;
//printf(" x_gap | acceptance \n");
PrintGuideHead();
for(int i=0; i<=steps; i++) {
step[i] = min + i*(max - min)/(double)steps;
parameters.setGap(step[i], 0.0, 0.0);
CDetector *detector = new CDetector(CENTER, parameters);
Init();
acc[i] = RandIso(detector, parameters, NN, 0, theta);
//printf("%6.2lf |%6.1lf\n", step[i], acc[i]*100.0);
PrintGuideStat(acc[i]);
}
//char sbuff[256];
//sprintf(sbuff, "SiPM = %.1lf, M = %.1lf, d = %.1lf | gap(y,z) = (%.1lf, %.1lf) | #theta = %.1lf",
// detector->GetSiPM(), detector->GetM(), detector->GetD(),
// (detector->GetVGap()).y(), (detector->GetVGap()).z(), theta);
DrawAcc(steps+1, step, acc, (char*)"; x_gap;Acceptance", min, max);
show_3d = tmp3d; show_data = tmpdata;
}
//------------------------------------------------------------------------------------------
void LGR_th(int NN = 1e4, double min = 0.0, double max = 30.0, const int steps = 15, double phi = 0)
{
//int tmp3d = show_3d, tmpdata = show_data;
double show_rays = 10;
double step[steps], acc[steps];
//show_3d = 0; show_data = 0;
//printf(" theta | acceptance \n");
PrintGuideHead();
for(int i=0; i<=steps; i++) {
Init();
step[i] = min + i*(max - min)/(double)steps;
CDetector *detector = new CDetector(TVector3(-2,0,0), parameters);
acc[i] = RandYZ(detector, parameters, NN, step[i], phi, show_rays);
//printf("%6.1lf |%6.1lf\n", step[i], acc[i]*100.0);
PrintGuideStat(acc[i]);
delete detector;
}
//char sbuff[256];
//sprintf(sbuff, "SiPM = %.1lf, M = %.1lf, d = %.1lf | gap = (%.1lf, %.1lf, %.1lf)",
// detector->GetSiPM(), detector->GetM(), detector->GetD(),
// (detector->GetVGap()).x(), (detector->GetVGap()).y(), (detector->GetVGap()).z());
DrawAcc(steps+1, step, acc, (char*)"; #theta [deg];Acceptance", min, max);
//show_3d = tmp3d; show_data = tmpdata;
}
//------------------------------------------------------------------------------------------
//void LGR_th(int NN = 1e4, double min = 0.0, double max = 30.0, const int steps = 15, double phi = 0)
void LGI_th(int NN = 1e4, double min = 0.0, double max = 30.0, const int steps = 15)
{
//int tmp3d = show_3d, tmpdata = show_data;
double step[steps], acc[steps];
//show_3d = 0; show_data = 0;
//printf(" theta | acceptance \n");
PrintGuideHead();
for(int i=0; i<=steps; i++) {
Init();
step[i] = min + i*(max - min)/(double)steps;
CDetector *detector = new CDetector(TVector3(-2,0,0), parameters);
//acc[i] = RandYZ(detector, parameters, NN, step[i], phi, 30);
acc[i] = RandIso(detector, parameters, NN, 0, step[i], 30, show_3d);
//printf("%6.1lf |%6.1lf\n", step[i], acc[i]*100.0);
PrintGuideStat(acc[i]);
delete detector;
}
//char sbuff[256];
//sprintf(sbuff, "SiPM = %.1lf, M = %.1lf, d = %.1lf | gap = (%.1lf, %.1lf, %.1lf)",
// detector->GetSiPM(), detector->GetM(), detector->GetD(),
// (detector->GetVGap()).x(), (detector->GetVGap()).y(), (detector->GetVGap()).z());
DrawAcc(steps+1, step, acc, (char*)"; #theta [deg];Acceptance", min, max);
//show_3d = tmp3d; show_data = tmpdata;
}
//------------------------------------------------------------------------------------------
void LGR_phi(int NN = 1e4, double maxTheta = 10.0, double maxPhi = 10.0, int steps = 10)
{
int tmp3d = show_3d, tmpdata = show_data;
show_3d = 1; show_data = 0;
//PrintGuideHead();
TH2F *hAcceptance = new TH2F("hAcceptance","Acceptance;#theta;#phi", steps, 0, maxTheta, steps, 0, maxPhi);
double min = 0.0;
printf("\nWait, this takes a while ");
for(int i=0; i<=steps; i++) {
double theta = min + i*(maxTheta - min) / (double)steps;
for (int j=0; j<=steps; j++) {
Init();
double phi = min + j*(maxPhi - min) / (double)steps;
CDetector *detector = new CDetector(TVector3(-2,0,0), parameters);
double acc = RandYZ(detector, parameters, NN, theta, phi, 30);
//PrintGuideStat(acc);
hAcceptance->Fill(i, j, acc);
//printf("Acc: %f ", acc);
delete detector;
}
printf(".");
}
printf("\n");
//DrawAcc(steps+1, step, acc, (char*)"; #theta [deg];Acceptance", min, max);
show_3d = tmp3d; show_data = tmpdata;
TCanvas *cp = new TCanvas("Acceptance", "Acceptance", 0, 0, 1000, 1000);
cp->cd();
hAcceptance->Draw("COLZ");
}
// a vs. d
void LGI_ad(int NN = 1e4, double min = 2.5, double max = 3.5, double minD = 1, double maxD = 6, const int steps = 10, double theta = 30.0)
{
//char sbuff[256];
//show_3d = 0; // don't show simulations
//show_data = 1;
//double d = detector->GetD();
const double b = parameters.getB(); // upper side of LG
//const double SiPM = 3.0; // the length of the detector itself
//double reflectivity = detector->guide->getR();
TH2F *hAcceptance = new TH2F("hAcceptance","Acceptance",steps-1,minD,maxD,steps-1,min,max);
// Use the Fresnel eq. instead of fixed reflectivity 96%
//detector->SetFresnel(1);
//printf(" d | a | Acceptance\n");
getParameters();
printf("Wait, this takes a while ");
for(int i=0; i<steps; i++) {
const double d = hAcceptance->GetXaxis()->GetBinCenter(i);
for(int j=0; j<steps; j++) {
Init();
const double a = hAcceptance->GetYaxis()->GetBinCenter(j);
//const double M = b/a;
parameters.setGuide(a, b, d);
CDetector *detector = new CDetector(CENTER, parameters);
//detector->guide->setLG(y, M, x);
//Init(); exclude simulation
double acceptance = RandIso(detector, parameters, NN, 0, theta, 30, show_3d);
//double acceptance = Grid(NN, theta);
//double acceptance = -1.0;
hAcceptance->Fill(d, a, acceptance);
//printf("%.2lf | %.2lf | ", d, a);
//PrintGuideStat(acceptance);
delete detector; //works fine, 50x50 grid takes ~4MB of RAM
}
printf(".");
}
printf("\n");
TCanvas *cp = new TCanvas("Acceptance", "Acceptance", 0, 0, 1200, 1200);
cp->cd();
//TVirtualPad *pacc = cp->cd(0);
/*
pacc->SetRightMargin(0.10);
pacc->SetLeftMargin(0.10);
pacc->SetTopMargin(0.10);
pacc->SetBottomMargin(0.10);
*/
TFile *file = new TFile("acceptance.root","RECREATE");
hAcceptance->Write();
file->Close();
//delete file;
//hAcceptance->SetContour(100);
//gStyle->SetPalette(1,0);
hAcceptance->SetTitle(";d [mm];a [mm]");
hAcceptance->GetXaxis()->SetRangeUser(minD,maxD);
hAcceptance->Draw("COLZ");
char filename[128];
sprintf(filename,"LGI_ad%d.C", steps);
cp->SaveAs(filename);
}
//------------------------------------------------------------------------------------------
// collection efficiency vs length
// a changes, b rests the same, d changes
// still can't use this function, it has hardcoded tan 10 deg
// !very stupid!
// new 3D graph NEEDED
// d vs a vs acceptance
void LGI_d2(int NN = 1e4, double min = 0.5, double max = 3.0, const int steps = 25, double theta = 30.0)
{
TVector3 gapGuideSiPM(0.3, 0, 0);
CDetector *detector = new CDetector(TVector3(-2,0,0), parameters);
int tmp3d = show_3d, tmpdata = show_data;
double step[steps], acc[steps];
double sipm_d, M0;
char sbuff[256];
show_3d = 1; show_data = 1;
M0 = parameters.getM();
PrintGuideHead();
for(int i=0; i<=steps; i++) {
step[i] = min + i*(max - min)/(double)steps;
sipm_d = M0 - 2.0*step[i]*0.199819;//tan 11.3 deg
parameters.setGuide(sipm_d, M0*sipm_d, step[i]);
//printf("sipm = %lf, M = %lf, d = %lf\n", detector->GetSiPM(), detector->GetM(), step[i]);
printf("%.1lf | %.2lf | ", step[i], sipm_d);
Init();
acc[i] = RandIso(detector, parameters, NN, 0, theta);
PrintGuideStat(acc[i]);
sprintf(sbuff, "d%2d.gif", i);
//c3dview->SaveAs(sbuff);
}
//sprintf(sbuff, "SiPM = %.1lf, M = %.1lf, d = %.1lf | gap(y,z) = (%.1lf, %.1lf) | #theta = %.1lf",
// detector->GetSiPM(), detector->GetM(), detector->GetD(),
// (detector->GetVGap()).y(), (detector->GetVGap()).z(), theta);
//DrawAcc(steps+1, step, acc, sbuff, (char*)"; d;Acceptance", min, max);
TCanvas *cp = new TCanvas("Acceptance", "Acceptance", 0, 0, 640, 480);
TVirtualPad *pacc = cp->cd(0);
pacc->SetRightMargin(0.05);
pacc->SetLeftMargin(0.13);
pacc->SetTopMargin(0.08);
TGraph *gacceptance = new TGraph(steps+1, step, acc);
gacceptance->SetTitle("; d [mm];Collection efficiency");
gacceptance->SetMarkerStyle(8);
gacceptance->SetLineColor(12);
gacceptance->SetLineWidth(1);
(gacceptance->GetXaxis())->SetRangeUser(min, max);
//(gacceptance->GetYaxis())->SetRangeUser(ymin, ymax);
gacceptance->Draw("ACP");
show_3d = tmp3d; show_data = tmpdata;
}
//------------------------------------------------------------------------------------------
// Acceptance vs. the length
// The magnification ratio M rests the same all the time
void LGI_d(int NN = 1e4, double min = 1, double max = 6.0, const int steps = 25, double theta = 30.0)
{
int tmp3d = show_3d, tmpdata = show_data;
double step[steps], acc[steps];
const double a = parameters.getA();
const double magnif = parameters.getM();
//show_3d = show_in_steps; show_data = 1;
// Use Fresnel equations
//detector->SetFresnel(1);
// Set glass (n=1.5) at the exit
//detector->SetGlass(1,0);
PrintGuideHead();
for(int i=0; i<=steps; i++) {
step[i] = min + i*(max - min)/(double)steps;
//parameters.setGuide(a, magnif, step[i]);
parameters.setGuide(a, magnif, step[i]);
CDetector *detector = new CDetector(CENTER, parameters);
//printf("sipm = %lf, M = %lf, d = %lf\n", detector->GetSiPM(), detector->GetM(), step[i]);
printf("%.1lf | ", step[i]);
Init();
acc[i] = RandIso(detector, parameters, NN, 0, theta);
PrintGuideStat(acc[i]);
delete detector;
}
//char sbuff[256];
//sprintf(sbuff, "SiPM = %.1lf, M = %.1lf, d = %.1lf | gap(y,z) = (%.1lf, %.1lf) | #theta = %.1lf",
// detector->GetSiPM(), detector->GetM(), detector->GetD(),
// (detector->GetVGap()).y(), (detector->GetVGap()).z(), theta);
DrawAcc(steps+1, step, acc, (char*)"; d [mm];Acceptance", min, max);
show_3d = tmp3d; show_data = tmpdata;
}
//------------------------------------------------------------------------------------------
// Magnification optimization. a and d are fixed, M and b change in steps
void LGI_M(int NN = 1e4, double min = 1.0, double max = 3.0, const int steps = 30, double theta = 30.0)
{
int tmp3d = show_3d, tmpdata = show_data;
double step[steps], acc[steps];
const double a = parameters.getA();
const double d = parameters.getD();
show_3d = 0; show_data = 0;
PrintGuideHead();
for(int i=0; i<=steps; i++) {
step[i] = min + i*(max - min)/(double)steps;
//parameters.setGuide(a, step[i], d);
parameters.setGuide(a, a*step[i], d);
CDetector *detector = new CDetector(CENTER, parameters);
Init();
acc[i] = RandIso(detector, parameters, NN, 0, theta);
PrintGuideStat(acc[i]);
}
//char sbuff[256];
//sprintf(sbuff, "SiPM = %.1lf, M = %.1lf, d = %.1lf | gap(y,z) = (%.1lf, %.1lf) | #theta = %.1lf",
// detector->GetSiPM(), detector->GetM(), detector->GetD(),
// (detector->GetVGap()).y(), (detector->GetVGap()).z(), theta);
DrawAcc(steps+1, step, acc, (char*)"; M;Acceptance", min, max);
show_3d = tmp3d; show_data = tmpdata;
}
//------------------------------------------------------------------------------------------
void getParameters()
{
printf("LIGHT GUIDE\n"
" b=%f mm, d=%f mm, a=%f mm\n", parameters.getB(), parameters.getD(), parameters.getA());
printf("MATERIAL REFRACITVE INDICES\n"
" n1=%f, n2=%f, n3=%f\n", parameters.getN1(), parameters.getN2(), parameters.getN3());
printf("PLATE\n"
" ON: %d, width=%f mm\nUSES FRESNEL EQUATIONS: %d\n", parameters.getPlateOn(), parameters.getPlateWidth(), parameters.getFresnel());
return;
}