From b1aa18174269e71764c407ce0674507e1ddfb57d Mon Sep 17 00:00:00 2001 From: Charlie Paxman <cp00474@surrey.ac.uk> Date: Wed, 9 Feb 2022 11:48:28 +0000 Subject: [PATCH] * e793s - CS() expanded to any given state --- Projects/e793s/macro/CS2.h | 102 ++++++--- Projects/e793s/macro/DrawPlots.C | 2 +- Projects/e793s/macro/DrawPlots.h | 38 +++- Projects/e793s/macro/KnownPeakFitter.h | 243 ++++------------------ Projects/e793s/macro/minimizer.cxx | 276 ++++++++++++++++++++----- 5 files changed, 365 insertions(+), 296 deletions(-) mode change 100644 => 100755 Projects/e793s/macro/minimizer.cxx diff --git a/Projects/e793s/macro/CS2.h b/Projects/e793s/macro/CS2.h index 2fabc6730..e3f0e915b 100644 --- a/Projects/e793s/macro/CS2.h +++ b/Projects/e793s/macro/CS2.h @@ -9,35 +9,58 @@ vector<Double_t> anglecentres, anglewidth; TGraph* currentThry; TGraphErrors* staticExp; -//BASIC RUN: CS(0.143,2,1,1.5,1) +int indexE; +bool loud = 0; //////////////////////////////////////////////////////////////////////////////// void CS(double Energy, double Spin, double spdf, double angmom, double nodes){ + + /* BASIC RUN: CS(0.143,2,1,1.5,1) */ + // p3/5 -> spdf = 1, angmom = 1.5 // J0 is incident spin, which is 47K g.s. therefore J0 = 1/2 double J0 = 0.5; + /* Retrieve array index of the entered peak energy */ + /* numpeaks and Energy[] defined globally in KnownPeakFitter.h */ + bool found = 0; + for(int i=0;i<numPeaks;i++){ + if(abs(Energy-means[i])<0.01){ + cout << "========================================================" << endl; + cout << "Identified as state #" << i << ", E = " << means[i] << endl; + indexE = i; + found = 1; + } + } + if(!found){ + cout << "========================================================" << endl; + cout << "NO STATE AT THAT ENERGY INDENTIFIED!! CHECK KNOWN PEAKS!!" << endl; + return; + } + /* Solid Angle (from simulation) */ auto file = new TFile("../SolidAngle_HistFile_06Dec_47Kdp.root"); TH1F* SolidAngle = (TH1F*) file->FindObjectAny("SolidAngle_Lab_MG"); TCanvas* c_SolidAngle = new TCanvas("c_SolidAngle","c_SolidAngle",1000,1000); SolidAngle->Draw(); + // canvas deleted after Area/SA calculation /* Area of experimental peaks */ TCanvas* c_PeakArea = new TCanvas("c_PeakArea","c_PeakArea",1000,1000); - vector<vector<double>> areaArray = ExpDiffCross(0.143); - //cout << std::setprecision(3) << std::fixed; + vector<vector<double>> areaArray = ExpDiffCross(means[indexE]); delete c_PeakArea; - // Array: i, peakenergy, peakarea, areaerror, anglemin, anglemax -// for(int i=0; i<areaArray.size();i++){ -// cout << i << " " -// << areaArray[i][0] << " " -// << areaArray[i][1] << " " -// << areaArray[i][2] << " " -// << areaArray[i][3] << " " -// << areaArray[i][4] << endl; -// } + // Array: peakenergy, peakarea, areaerror, anglemin, anglemax + if(loud){ + for(int i=0; i<areaArray.size();i++){ + cout << i << " " + << areaArray[i][0] << " " + << areaArray[i][1] << " " + << areaArray[i][2] << " " + << areaArray[i][3] << " " + << areaArray[i][4] << endl; + } + } /* Area over Solid Angle */ vector<Double_t> AoSA, AoSAerr; @@ -52,15 +75,19 @@ void CS(double Energy, double Spin, double spdf, double angmom, double nodes){ double SA = 1000. * SolidAngle->IntegralAndError(binmin,binmax,SAerr); //SAerr = SAerr*1000.; //???? - AoSA.push_back(areaArray[i][1] / SA); + AoSA.push_back(areaArray[i][1]/SA); AoSAerr.push_back((areaArray[i][1]/SA) * sqrt( pow(areaArray[i][2]/areaArray[i][1],2) + pow(SAerr/SA,2) ) ); - cout << "Angle " << areaArray[i][3] << " to " << areaArray[i][4] - << ", centre " << anglecentres[i] - << ": SA = " << SA << " +- " << SAerr - << " Area/SA = " << AoSA[i] << " +- " << AoSAerr[i] << " counts/msr"<< endl; + if(loud){ + cout << "Angle " << areaArray[i][3] << " to " << areaArray[i][4] + << ", centre " << anglecentres[i] + << ": Area = " << areaArray[i][1] << " +- " << areaArray[i][2] + << " SA = " << SA << " +- " << SAerr + << " Area/SA = " << AoSA[i] << " +- " << AoSAerr[i] << " counts/msr"<< endl; + } } + delete c_SolidAngle; TCanvas* c_AoSA = new TCanvas("c_AoSA","c_AoSA",1000,1000); TGraphErrors* gAoSA = new TGraphErrors( @@ -75,7 +102,7 @@ void CS(double Energy, double Spin, double spdf, double angmom, double nodes){ /* TWOFNR diff. cross section */ TCanvas* c_TWOFNR = new TCanvas("c_TWOFNR","c_TWOFNR",1000,1000); - TGraph* DiffCross = TWOFNR(Energy, J0, Spin, nodes, spdf, angmom); + TGraph* DiffCross = TWOFNR(means[indexE], J0, Spin, nodes, spdf, angmom); DiffCross->Draw(); /* Scaled and compared on same plot */ @@ -103,12 +130,9 @@ void CS(double Energy, double Spin, double spdf, double angmom, double nodes){ Final->Draw("SAME"); } - - //////////////////////////////////////////////////////////////////////////////// vector<vector<double>> ExpDiffCross(double Energy){ cout << "========================================================" << endl; - // Implement some kind of energy selection later, for now, hard code that we are selecting 0.143, array index 1 vector<vector<double>> AllPeaks_OneGate; vector<vector<double>> OnePeak_AllGates; int numbins = 10; @@ -120,15 +144,27 @@ vector<vector<double>> ExpDiffCross(double Energy){ cout << "===================================" << endl; cout << "min: " << min << " max: " << max << endl; + /* Retrieve theta-gated Ex TH1F from file GateThetaLabHistograms.root */ + /* To change angle gates, run GateThetaLab_MultiWrite() */ TH1F* gate = PullThetaLabHist(i,105.,5.); + + /* Retrieve array containing all fits, for one angle gate. * + * Specific peak of interest selected from the vector by * + * global variable indexE */ AllPeaks_OneGate = FitKnownPeaks_RtrnArry(gate); - //cout << "area of " << peakAreas[1][0] << " = " << peakAreas[1][1] - cout << "area of 0.143 = " << AllPeaks_OneGate[1][1] - << " +- " << AllPeaks_OneGate[1][2] + + /* Check correct OneGate vector is selected */ + cout << "area of " << means[indexE] << " = " + << AllPeaks_OneGate[indexE][1] + << " +- " << AllPeaks_OneGate[indexE][2] << endl; - AllPeaks_OneGate[1].push_back(min); - AllPeaks_OneGate[1].push_back(max); - OnePeak_AllGates.push_back(AllPeaks_OneGate[1]); + + /* Add min and max angle to end of relevant OneGate vector */ + AllPeaks_OneGate[indexE].push_back(min); + AllPeaks_OneGate[indexE].push_back(max); + + /* Push relevant OneGate vector to end of AllGates vector */ + OnePeak_AllGates.push_back(AllPeaks_OneGate[indexE]); } return OnePeak_AllGates; } @@ -174,6 +210,8 @@ void Scale(TGraph* g , TGraphErrors* ex){ //////////////////////////////////////////////////////////////////////////////// TGraph* TWOFNR(double E, double J0, double J, double n, double l, double j){ + /* This function mved between directories in order to run TWOFNR in proper * + * location. This is, weirdly, the least tempremental way of doing this. */ cout << "========================================================" << endl; char origDirchar[200]; @@ -181,7 +219,6 @@ TGraph* TWOFNR(double E, double J0, double J, double n, double l, double j){ string origDir{origDirchar}; string twofnrDir = "/home/charlottepaxman/Programs/TWOFNR"; cout << "Current directory " << origDir << endl; - cout << "Moving to directory " << twofnrDir << endl; chdir(twofnrDir.c_str()); //Check @@ -228,23 +265,20 @@ TGraph* TWOFNR(double E, double J0, double J, double n, double l, double j){ cout << "Filled front input file." << endl; cout << "Executing front20..." << endl; system("(exec ~/Programs/TWOFNR/front20 < in.front > /dev/null)"); + cout << "-> front20 complete!" << endl; cout << "Executing twofnr20..." << endl; system("(exec ~/Programs/TWOFNR/twofnr20 < in.twofnr > /dev/null)"); - - cout << "twofnr20 complete." << endl; - + cout << "-> twofnr20 complete!" << endl; TGraph* CS = new TGraph("24.jjj"); cout << "===================================" << endl; cout << "Current directory " << twofnrDir << endl; - cout << "Moving to directory " << origDir << endl; chdir(origDir.c_str()); system("pwd"); cout << "========================================================" << endl; - return CS; } @@ -259,7 +293,7 @@ double Chi2(TGraph* theory , TGraphErrors* exper){ Chi2 +=chi*chi; } } - cout << "Chi2 = " << Chi2 << endl; + if(loud){cout << "Chi2 = " << Chi2 << endl;} return Chi2; } diff --git a/Projects/e793s/macro/DrawPlots.C b/Projects/e793s/macro/DrawPlots.C index 314a6b4dd..9ec479d5d 100755 --- a/Projects/e793s/macro/DrawPlots.C +++ b/Projects/e793s/macro/DrawPlots.C @@ -554,8 +554,8 @@ cout << " 2D Matrices " << endl; cout << ""<< endl; cout << " Analysis functions" << endl; cout << "\t- FitKnownPeaks(histogram) "<< endl; - cout << "\t\t-- Fits Ex peaks to an excitation spectrum "<< endl; cout << "\t- AGATA_efficiency(double Energy_kev) "<< endl; + cout << "\t- CorrectForAGATAEffic(TH1F* hist) "<< endl; cout << ""<< endl; cout << "==========================================" << endl; diff --git a/Projects/e793s/macro/DrawPlots.h b/Projects/e793s/macro/DrawPlots.h index 9c6462d00..55122547f 100755 --- a/Projects/e793s/macro/DrawPlots.h +++ b/Projects/e793s/macro/DrawPlots.h @@ -21,6 +21,11 @@ NPL::Reaction Ti12C12C("47Ti(12C,12C)47Ti@355"); void KnownLines_Ex(bool isVertical, double rangemin, double rangemax, Style_t lType, Color_t lColour); /* BASE FUNCTIONS */ +TF1* f_efficAGATA(){ + TF1 *f_E = new TF1("fit_1","TMath::Exp([0]+[1]*TMath::Log(x)+[2]*pow(TMath::Log(x),2.0)+[3]*pow(TMath::Log(x),3.0)+[4]*pow(TMath::Log(x),4.0))",10,6000); + f_E->SetParameters(-6.34543e+01, +4.24746e+01, -1.00304e+01, +1.03468e+00, -3.97076e-02); + return f_E; +} TChain* Chain(std::string TreeName, std::vector<std::string>& file, bool EventList){ TChain* chain = new TChain(TreeName.c_str()); @@ -54,6 +59,24 @@ void LoadChainNP(){ chain = Chain("PhysicsTree",files,true); } +void CorrectForAGATAEffic(TH1F* hist){ + int nbins = hist->GetNbinsX(); + TF1* effic_keV = f_efficAGATA(); + + for(int i=1;i<nbins+1;i++){ + double x = hist->GetBinCenter(i); + double val = effic_keV->Eval(x*1000.); +// cout << x << " " << val << endl; + + double bincontent = hist->GetBinContent(i); + bincontent = bincontent/(val/100.); + hist->SetBinContent(i,bincontent); + } + hist->SetFillStyle(3244); + hist->SetFillColor(kBlue); + hist->Draw(); +} + void DrawParticleStates(TCanvas* canvas){ canvas->cd(); @@ -1134,17 +1157,10 @@ void AGATA_efficiency(){ } void AGATA_efficiency(double Energy_keV){ - TF1 *fit_1 = new TF1("fit_1","TMath::Exp([0]+[1]*TMath::Log(x)+[2]*pow(TMath::Log(x),2.0)+[3]*pow(TMath::Log(x),3.0)+[4]*pow(TMath::Log(x),4.0))",10,5000); - fit_1->SetParameters(-6.34543e+01, - +4.24746e+01, - -1.00304e+01, - +1.03468e+00, - -3.97076e-02); - fit_1->Draw(); - cout << "At E = " - << Energy_keV - << " keV, AGATA efficiency = " - << fit_1->Eval(Energy_keV) + TF1* func = f_efficAGATA(); + func->Draw(); + cout << "At E = " << Energy_keV + << " keV, AGATA efficiency = " << func->Eval(Energy_keV) << " %" << endl; } diff --git a/Projects/e793s/macro/KnownPeakFitter.h b/Projects/e793s/macro/KnownPeakFitter.h index a249438cf..2c24c4395 100644 --- a/Projects/e793s/macro/KnownPeakFitter.h +++ b/Projects/e793s/macro/KnownPeakFitter.h @@ -3,37 +3,8 @@ #include <cmath> #include "stdlib.h" -void FitKnownPeaks(TH1F* hist){ - double minFit=-1.0, maxFit=5.0; - double binWidth = hist->GetXaxis()->GetBinWidth(3); - double sigma = 0.14; - - string nameBase = "Peak "; - string function = "([2]/([0]*sqrt(2*pi)))*exp(-0.5*pow((x-[1])/[0],2))"; - - /* 11 KNOWN PEAKS as of 12/10/21 - * 0.000 - * 0.143 - * 0.279 - * 0.728 - * 0.968 - * 1.410 - * 1.981 - * 2.410 - * 2.910 - * 3.605 - * 3.792 - * ... - * NEW: - * 3.2 - * 4.1 - * 4.4 - * - */ - - //Assign peak centroids - const int numPeaks = 14; - array<double,14> means = { 0.000, + const int numPeaks = 14; + array<double,14> means = { 0.000, 0.143, 0.279, 0.728, @@ -49,122 +20,6 @@ void FitKnownPeaks(TH1F* hist){ 4.4 }; - //Build individual peak fit functions - TF1 **allPeaks = new TF1*[numPeaks]; - for(int i=0; i<numPeaks; i++) { - string nameHere = nameBase; - nameHere +=to_string(i); - - allPeaks[i] = new TF1(nameHere.c_str(), function.c_str(), -1, 5); - allPeaks[i]->SetLineColor(kBlack); - allPeaks[i]->SetLineStyle(7); - allPeaks[i]->SetParNames("Sigma", "Mean", "Area*BinWidth"); - } - - //Build background function - TF1 *bg = new TF1 ("bg","[0]",minFit, maxFit); - bg->SetLineColor(kGreen); - bg->SetLineStyle(9); - bg->SetParNames("Background"); - - //Build total function - TF1 *full = new TF1("fitAllPeaks", - " ([2]/([0]*sqrt(2*pi)))*exp(-0.5*pow((x-[1])/[0],2)) " - "+ ([4]/([0]*sqrt(2*pi)))*exp(-0.5*pow((x-[3])/[0],2)) " - "+ ([6]/([0]*sqrt(2*pi)))*exp(-0.5*pow((x-[5])/[0],2)) " - "+ ([8]/([0]*sqrt(2*pi)))*exp(-0.5*pow((x-[7])/[0],2)) " - "+ ([10]/([0]*sqrt(2*pi)))*exp(-0.5*pow((x-[9])/[0],2)) " - "+ ([12]/([0]*sqrt(2*pi)))*exp(-0.5*pow((x-[11])/[0],2)) " - "+ ([14]/([0]*sqrt(2*pi)))*exp(-0.5*pow((x-[13])/[0],2)) " - "+ ([16]/([0]*sqrt(2*pi)))*exp(-0.5*pow((x-[15])/[0],2)) " - "+ ([18]/([0]*sqrt(2*pi)))*exp(-0.5*pow((x-[17])/[0],2)) " - "+ ([20]/([0]*sqrt(2*pi)))*exp(-0.5*pow((x-[19])/[0],2)) " - "+ ([22]/([0]*sqrt(2*pi)))*exp(-0.5*pow((x-[21])/[0],2)) " - "+ ([24]/([0]*sqrt(2*pi)))*exp(-0.5*pow((x-[23])/[0],2)) " - "+ ([26]/([0]*sqrt(2*pi)))*exp(-0.5*pow((x-[25])/[0],2)) " - "+ ([28]/([0]*sqrt(2*pi)))*exp(-0.5*pow((x-[27])/[0],2)) " - "+ [29]" , minFit, maxFit); - full->SetLineColor(kRed); - - //Annoyingly long parameter name assignment - //(SetParNames only works for up to 11 variables) - full->SetParName(0,"Sigma"); - full->SetParName(1,"Mean 01"); full->SetParName(2,"Area*BinWidth 01"); - full->SetParName(3,"Mean 02"); full->SetParName(4,"Area*BinWidth 02"); - full->SetParName(5,"Mean 03"); full->SetParName(6,"Area*BinWidth 03"); - full->SetParName(7,"Mean 04"); full->SetParName(8,"Area*BinWidth 04"); - full->SetParName(9,"Mean 05"); full->SetParName(10,"Area*BinWidth 05"); - full->SetParName(11,"Mean 06"); full->SetParName(12,"Area*BinWidth 06"); - full->SetParName(13,"Mean 07"); full->SetParName(14,"Area*BinWidth 07"); - full->SetParName(15,"Mean 08"); full->SetParName(16,"Area*BinWidth 08"); - full->SetParName(17,"Mean 09"); full->SetParName(18,"Area*BinWidth 09"); - full->SetParName(19,"Mean 10"); full->SetParName(20,"Area*BinWidth 10"); - full->SetParName(21,"Mean 11"); full->SetParName(22,"Area*BinWidth 11"); - full->SetParName(23,"Mean 12"); full->SetParName(24,"Area*BinWidth 12"); - full->SetParName(25,"Mean 13"); full->SetParName(26,"Area*BinWidth 13"); - full->SetParName(27,"Mean 14"); full->SetParName(28,"Area*BinWidth 14"); - full->SetParName(29,"Background"); - - //Fix sigma & centroid, only allow area to vary - const int numParams = (numPeaks*2)+2; - full->FixParameter(0, sigma); - for(int i=0; i<numPeaks; i++) { - full->FixParameter(2*i+1,means.at(i)); - full->SetParameter(2*i+2,1.0); - full->SetParLimits(2*i+2,0.0,1e5); - } - //full->FixParameter(numParams-1,0.0); - full->SetParameter(numParams-1,1.0); - full->SetParLimits(numParams-1,0.0,1e1); - - //Fit full function tohistogram - hist->Fit(full, "WWR", "", minFit, maxFit); - hist->Draw(); - - //Extract fitted variables, assign them to individual fits, and draw them - Double_t finalPar[numParams]; - Double_t finalErr[numParams]; - full->GetParameters(&finalPar[0]); - for (int i=0; i<numPeaks; i++){ - finalErr[2*i+1] = full->GetParError(2*i+1); - finalErr[2*i+2] = full->GetParError(2*i+2); - - allPeaks[i]->SetParameters(sigma, means.at(i), finalPar[2*i+2]); - } - bg->SetParameter(0,finalPar[numParams-1]); - bg->Draw("SAME"); - full->Draw("SAME"); - - for (int i=0; i<numPeaks; i++){ - allPeaks[i]->Draw("SAME"); - } - - - /* Error propogation: - * (Abin) +- deltaAbin, B+-0 (no uncertainty) - * A = Abin/B - * deltaA/A = deltaAbin/Abin - * deltaA = A x deltaAbin/Abin - */ - - //Write to screen - cout << "===========================" << endl; - cout << "== PEAK =========== AREA ==" << endl; - - for(int i=0; i<numPeaks; i++){ - cout << fixed << setprecision(3) << finalPar[2*i+1] - << "\t" << setprecision(0)<< finalPar[2*i+2]/binWidth - << "\t+- " << (finalPar[2*i+2]/binWidth)*(finalErr[2*i+2]/finalPar[2*i+2]) - << endl; - } - -} - - - - - - Double_t f_bg(Double_t *x, Double_t *par){ // Flat bg [0] + semicircle [1]*sqrt(6.183^2 - (x-10.829)^2) Float_t xx = x[0]; @@ -176,6 +31,12 @@ Double_t f_bg(Double_t *x, Double_t *par){ return f; } +Double_t f_peak(Double_t *x, Double_t *par){ + Float_t xx = x[0]; + Double_t f = (par[2]/(par[0]*sqrt(2*pi)))*exp(-0.5*pow((xx-par[1])/par[0],2)); + return f; +} + Double_t f_full(Double_t *x, Double_t *par){ Float_t xx = x[0]; Double_t f; @@ -204,8 +65,6 @@ Double_t f_full(Double_t *x, Double_t *par){ return f; } - - vector<vector<double>> FitKnownPeaks_RtrnArry(TH1F* hist){ double minFit=-1.0, maxFit=5.0; double binWidth = hist->GetXaxis()->GetBinWidth(3); @@ -214,42 +73,23 @@ vector<vector<double>> FitKnownPeaks_RtrnArry(TH1F* hist){ string nameBase = "Peak "; string function = "([2]/([0]*sqrt(2*pi)))*exp(-0.5*pow((x-[1])/[0],2))"; - /* 11 KNOWN PEAKS as of 12/10/21 - * 0.000 - * 0.143 - * 0.279 - * 0.728 - * 0.968 - * 1.410 - * 1.981 - * 2.410 - * 2.910 - * 3.605 - * 3.792 - * ... - * NEW: - * 3.2 - * 4.1 - * 4.4 - * - */ //Assign peak centroids - const int numPeaks = 14; - array<double,14> means = { 0.000, - 0.143, - 0.279, - 0.728, - 0.968, - 1.410, - 1.981, - 2.410, - 2.910, - 3.2, - 3.605, - 3.792, - 4.1, - 4.4 - }; +// const int numPeaks = 14; +// array<double,14> means = { 0.000, +// 0.143, +// 0.279, +// 0.728, +// 0.968, +// 1.410, +// 1.981, +// 2.410, +// 2.910, +// 3.2, +// 3.605, +// 3.792, +// 4.1, +// 4.4 +// }; //Build individual peak fit functions TF1 **allPeaks = new TF1*[numPeaks]; @@ -258,6 +98,7 @@ vector<vector<double>> FitKnownPeaks_RtrnArry(TH1F* hist){ nameHere +=to_string(i); allPeaks[i] = new TF1(nameHere.c_str(), function.c_str(), -1, 5); + //allPeaks[i] = new TF1(nameHere.c_str(), f_peak, -1, 5); allPeaks[i]->SetLineColor(kBlack); allPeaks[i]->SetLineStyle(7); allPeaks[i]->SetParNames("Sigma", "Mean", "Area*BinWidth"); @@ -332,17 +173,13 @@ vector<vector<double>> FitKnownPeaks_RtrnArry(TH1F* hist){ full->SetParLimits(numParams-1,0.0,1e1); //Fit full function to histogram - hist->Fit(full, "WWRQ", "", minFit, maxFit); + hist->Fit(full, "RQ", "", minFit, maxFit); hist->Draw(); - + //Extract fitted variables, assign them to individual fits, and draw them - Double_t finalPar[numParams]; - Double_t finalErr[numParams]; - full->GetParameters(&finalPar[0]); + const Double_t* finalPar = full->GetParameters(); + const Double_t* finalErr = full->GetParErrors(); for (int i=0; i<numPeaks; i++){ - finalErr[2*i+1] = full->GetParError(2*i+1); - finalErr[2*i+2] = full->GetParError(2*i+2); - allPeaks[i]->SetParameters(sigma, means.at(i), finalPar[2*i+2]); } bg->SetParameter(0,finalPar[numParams-1]); @@ -366,18 +203,26 @@ vector<vector<double>> FitKnownPeaks_RtrnArry(TH1F* hist){ vector<vector<double>> allpeaks; for(int i=0; i<numPeaks; i++){ - cout << fixed << setprecision(3) << finalPar[2*i+1] - << "\t" << setprecision(0)<< finalPar[2*i+2]/binWidth - << "\t+- " << (finalPar[2*i+2]/binWidth)*(finalErr[2*i+2]/finalPar[2*i+2]) - << setprecision(3) << endl; + double A = finalPar[2*i+2]/binWidth; + double deltaA = A * (finalErr[2*i+2]/finalPar[2*i+2]); + + cout << fixed << setprecision(3) + << " #" << i << " " + << finalPar[2*i+1] << "\t" << setprecision(0) + << A << "\t+- " + << deltaA << setprecision(3) + << endl; vector<double> onepeak; //energy, area and error for one peak onepeak.push_back(finalPar[2*i+1]); - onepeak.push_back(finalPar[2*i+2]/binWidth); - onepeak.push_back((finalPar[2*i+2]/binWidth)*(finalErr[2*i+2]/finalPar[2*i+2])); + onepeak.push_back(A); + onepeak.push_back(deltaA); allpeaks.push_back(onepeak); } return allpeaks; } - +void FitKnownPeaks(TH1F* hist){ + //Shell function to call Rtrn_Arry without writing vector<vector<double>> to screen + vector<vector<double>> shell = FitKnownPeaks_RtrnArry(hist); +} diff --git a/Projects/e793s/macro/minimizer.cxx b/Projects/e793s/macro/minimizer.cxx old mode 100644 new mode 100755 index 6fb732460..2056cb4d3 --- a/Projects/e793s/macro/minimizer.cxx +++ b/Projects/e793s/macro/minimizer.cxx @@ -1,46 +1,200 @@ +#include "Math/Minimizer.h" +#include "Math/Factory.h" +#include "Math/Functor.h" +#include "TRandom2.h" +#include "TError.h" +#include <iostream> -double ref = 0.143; // the energy of the selected states +double refE = 0.143; // the energy of the selected states vector<TVector3*> pos; vector<double> energy; +vector<int> detnum; NPL::EnergyLoss CD2("proton_CD2.G4table","G4Table",100); NPL::EnergyLoss Al("proton_Al.G4table","G4Table",100); +using namespace std; + +bool flagDraw = 0; +static auto h = new TH1D("h","h", 80,-1.,1.); +static auto h1 = new TH1D("h1","h1", 40,-1.,1.); +static auto h2 = new TH1D("h2","h2", 40,-1.,1.); +static auto h3 = new TH1D("h3","h3", 40,-1.,1.); +static auto h4 = new TH1D("h4","h4", 40,-1.,1.); +static auto h5 = new TH1D("h5","h5", 40,-1.,1.); +static auto h7 = new TH1D("h7","h7", 40,-1.,1.); + +void InitiliseCanvas(){ + TCanvas *canv = new TCanvas("canv","Ex Histograms",20,20,1600,800); + gStyle->SetOptStat(0); + canv->Divide(2,1,0.005,0.005,0); + canv->cd(1)->SetLeftMargin(0.15); + canv->cd(1)->SetBottomMargin(0.15); + gPad->SetTickx(); + gPad->SetTicky(); + canv->cd(2)->SetLeftMargin(0.15); + canv->cd(2)->SetBottomMargin(0.15); + gPad->SetTickx(); + gPad->SetTicky(); + + canv->cd(1); + h1->SetMaximum(75.); + h1->GetXaxis()->SetTitle("Ex [MeV]"); + h1->GetYaxis()->SetTitle("Counts"); + + // ----- MG1 ----- + h1->SetStats(0); + h1->SetLineColor(kRed); + h1->SetFillStyle(3244); + h1->SetFillColor(kRed); + h1->Draw(); + h1->Fit("gaus","WQ"); //add N to stop it drawing + + // ----- MG2 ----- + h2->SetStats(0); + h2->SetLineColor(kOrange); + h2->SetFillStyle(3244); + h2->SetFillColor(kOrange); + h2->Draw("same"); + h2->Fit("gaus","WQ"); //add N to stop it drawing + + // ----- MG3 ----- + h3->SetStats(0); + h3->SetLineColor(kGreen); + h3->SetFillStyle(3344); + h3->SetFillColor(kGreen); + h3->Draw("same"); + h3->Fit("gaus","WQ"); //add N to stop it drawing + + // ----- MG4 ----- + h4->SetStats(0); + h4->SetLineColor(kTeal); + h4->SetFillStyle(3444); + h4->SetFillColor(kTeal); + h4->Draw("same"); + h4->Fit("gaus","WQ"); //add N to stop it drawing + + // ----- MG5 ----- + h5->SetStats(0); + h5->SetLineColor(kBlue); + h5->SetFillStyle(3544); + h5->SetFillColor(kBlue); + h5->Draw("same"); + h5->Fit("gaus","WQ"); //add N to stop it drawing + + // ----- MG7 ----- + h7->SetStats(0); + h7->SetLineColor(kViolet); + h7->SetFillStyle(3644); + h7->SetFillColor(kViolet); + h7->Draw("same"); + h7->Fit("gaus","WQ"); //add N to stop it drawing + + // Format legend + auto legend = new TLegend(0.15,0.7,0.35,0.9); + legend->AddEntry(h1,"MUGAST 1","f"); + legend->AddEntry(h2,"MUGAST 2","f"); + legend->AddEntry(h3,"MUGAST 3","f"); + legend->AddEntry(h4,"MUGAST 4","f"); + legend->AddEntry(h5,"MUGAST 5","f"); + legend->AddEntry(h7,"MUGAST 7","f"); + legend->Draw(); + + // ----- ALL ----- + canv->cd(2); + h->SetStats(0); + h->GetXaxis()->SetTitle("Ex [MeV]"); + h->GetYaxis()->SetTitle("Counts"); + h->Draw(); + h->Fit("gaus", "WQ"); + gPad->Update(); + //delete c1; + //c1 = 0; +} //////////////////////////////////////////////////////////////////////////////// double devE(const double* parameter){ - // My reaction at 8A MeV*47A=376 MeV - static NPL::Reaction reaction("47K(d,p)48K@376"); - // Return the standard deviation in Brho - unsigned int size = pos1.size(); + //Beam energy: 7.7 [MeV/A] * 47 [A] = 361.9 [MeV] + static NPL::Reaction reaction("47K(d,p)48K@362"); + //Beam spot offset TVector3 offset(parameter[0],parameter[1],parameter[2]); + unsigned int size = pos.size(); double dE,Theta; TVector3 dir; - static auto h = new TH1D("h","h", 1000,-0,100); + + //Initilize histogram h->Reset(); + h1->Reset(); + h2->Reset(); + h3->Reset(); + h4->Reset(); + h5->Reset(); + h7->Reset(); + + //Loop over events for(unsigned int i = 0 ; i < size ; i++){ - dir=*(pos[i])-o1; + //Particle path vector + dir=*(pos[i])-offset; + + //Detected energy, and angle of particle leaving target double Theta= dir.Angle(TVector3(0,0,1)); double Energy = energy[i]; - // do some energy loss correction here: - // This need to take parameter[4]*0.5*micrometer as the target thickness - Energy=CD2.EvaluateInitialEnergy(Energy,0,5*parameter[4]*micrometer,Theta); - - double Ex=reaction->ReconstructRelativistic(Energy,Theta); - //cout << (pB-pM).Mag2() << " " << dR << endl; - h->Fill(Ex-ref); - } - cout << h->GetMean() << " " << h->GetStdDev() << " " << parameter[4] << endl; + + //NOTE!!! Not calucualting energy loss in Al??? + //Energy loss in target + Energy=CD2.EvaluateInitialEnergy( + Energy, //energy after leaving target + 0.5*parameter[4]*micrometer, //pass through half target + Theta); //angle leaving target + + //Final value of Ex + double Ex = reaction.ReconstructRelativistic(Energy,Theta); + + //Fill histogram with ERROR in Ex! + //h->Fill(Ex-refE); + h->Fill(Ex); + + switch(detnum[i]){ + case 1: + h1->Fill(Ex); + break; + case 2: + h2->Fill(Ex); + break; + case 3: + h3->Fill(Ex); + break; + case 4: + h4->Fill(Ex); + break; + case 5: + h5->Fill(Ex); + break; + case 7: + h7->Fill(Ex); + break; + default: + cout << "ERROR! Invalid detnum: " << detnum[i] << " @" << i << endl; + return 1; // Exit code + } + + } + //End loop over events + + //Write vals to screen + cout << "Mean: " << h->GetMean() << "\t StdDev: " << h->GetStdDev() << "\t Thickness??: " << parameter[4] << endl; h->Draw(); - gPad->Update(); - // adapt the metric as needed - return (h->GetMean()+h->GetStdDev() ); + + if(flagDraw){ InitiliseCanvas(); } + + //Adapt the metric as needed + return sqrt( pow(h->GetMean()-refE,2) + pow(0.1*h->GetStdDev(),2) ); } //////////////////////////////////////////////////////////////////////////////// void LoadFile(){ - - ifstream file("myFile.txt"); + // Open XYZE gamma-gated file + ifstream file("BeamSpot/XYZE_Full_02June.txt"); if(!file.is_open()){ cout << "fail to load file" << endl; exit(1); @@ -49,44 +203,64 @@ void LoadFile(){ cout << "Success opening file" << endl; } + // Read in + int mg; double x,y,z,e; - - while(file >> x >> y >> z >> e ){ - auto p1 = new TVector3(x,y,z); - double e; - pos.push_back(p1); + while(file >> mg >> x >> y >> z >> e ){ + auto p = new TVector3(x,y,z); + detnum.push_back(mg); + pos.push_back(p); energy.push_back(e); +// cout << "MG" << mg << " X " << x << " Y " << y << " Z " << z << " E " << e << endl; } file.close(); } //////////////////////////////////////////////////////////////////////////////// -void BDC(){ +void minimizer(){ + flagDraw = 0; //stop from drawing canvas on every run, just minimized one + + gErrorIgnoreLevel = kWarning; - // Data + // Read data in LoadFile(); - // Minimizer - auto min=ROOT::Math::Factory::CreateMinimizer("Minuit2", "Migrad"); + // Start with beam (0,0,0) and 4.7um 0.5mg/c2 target + double parameter[4] = {0.0, 0.0, 0.0, 4.7}; + devE(parameter); + // Function with 4 parameter XYZ and Target thickness - auto func=ROOT::Math::Functor(&devE,4); - min->SetFunction(func); - min->SetPrintLevel(0); - min->SetPrecision(1e-10); - // Start value: Center beam (0,0,0) and 4.7um target 0.5mg/cm2 target - double parameter[6]={0,0,0,4.7}; - devR(parameter); - - // min->SetLimitedVariable(0,"AM",parameter[0],1,-90,90); - min->SetLimitedVariable(0,"X",parameter[0],0.1,-10,10); - min->SetLimitedVariable(1,"Y",parameter[1],0.1,-10,10); - min->SetLimitedVariable(2,"Z",parameter[2],0.1,-5,5); - min->SetLimitedVariable(3,"T",parameter[3],0.1,parameter[2]-0.1*parameter[2],parameter[2]+0.1*parameter[2]); - min->Minimize(); - - const double* x = min->X(); - cout << "X =" << x[0]<<endl; - cout << "Y =" << x[1]<<endl; - cout << "Z =" << x[2]<<endl; - cout << "Y =" << x[3]<<endl; - cout << "Minimum: " << devR(x) << endl; + auto func = ROOT::Math::Functor(&devE,4); + + // Minimizer + auto minim = ROOT::Math::Factory::CreateMinimizer("Minuit2","Migrad"); + + minim->SetPrintLevel(0); + minim->SetPrecision(1e-10); + + // Set minimizer function + minim->SetFunction(func); + + // Assign variable limits + minim->SetLimitedVariable(0,"X",parameter[0],0.01,-10,10); + minim->SetLimitedVariable(1,"Y",parameter[1],0.01,-10,10); + minim->SetLimitedVariable(2,"Z",parameter[2],0.01,-5,5); + minim->SetLimitedVariable(3,"T",parameter[3],0.01,4.7-3.0,4.7+3.0); +// parameter[2]-0.1*parameter[2], +// parameter[2]+0.1*parameter[2]); + + // Shrink it, babeyyy + minim->Minimize(); + + // Draw minimal value + flagDraw = 1; + + // Pull values from minimizer + const double* x = minim->X(); + cout << "========================================" << endl; + cout << "\t\tX =" << x[0] << endl; + cout << "\t\tY =" << x[1] << endl; + cout << "\t\tZ =" << x[2] << endl; + cout << "\t\tT =" << x[3] << endl; + cout << "Minimum: " << devE(x) << endl; + cout << "========================================" << endl; } -- GitLab