diff --git a/Software/AutomatedMeasurements/ElectronicMonkeyFocusing.py b/Software/AutomatedMeasurements/ElectronicMonkeyFocusing.py index e24f7b3..f8135f8 100644 --- a/Software/AutomatedMeasurements/ElectronicMonkeyFocusing.py +++ b/Software/AutomatedMeasurements/ElectronicMonkeyFocusing.py @@ -5,7 +5,7 @@ Description: Automated measurement for focusing. -The script moves the laser to the starting position along x and z and then takes care of the data acquisitions with the Alibava system. +The script takes a pedestal run, moves the laser to the starting position along x and z and then takes care of the data acquisitions with the Alibava system. After the measurement, the position of the laser along x and z is reset. Parameters: @@ -65,7 +65,7 @@ nevents = 10000 -folder = '/home/hep/flionett/TestStand/Data' +folder = '/disk/groups/hep/flionett/TestStand/Data' filename = '' config = '/home/hep/flionett/TestStand/Repository/TestStandRepository/Software/AutomatedMeasurements/FocusingConfig' @@ -108,6 +108,14 @@ ser.write('+02') time.sleep(1) +# Take a pedestal run. +filename = folder+"/Hans410/Alignment/"+str(yyyymmdd)+"-216-"+"ped.ali" +printcommand = "echo alibava-gui --no-gui --nevts="+str(nevents)+" --out="+filename+" --pedestal "+config +command = "alibava-gui --no-gui --nevts="+str(nevents)+" --out="+filename+" --pedestal "+config +print '***' +subprocess.call(printcommand,shell=True) +subprocess.call(command,shell=True) + # Perform the measurement. for posz in range(firstz,lastz+stepz,stepz) : for posx in range(firstx,lastx+stepx,stepx) : diff --git a/Software/CCE/CCE.C b/Software/CCE/CCE.C new file mode 100644 index 0000000..8d5ec99 --- /dev/null +++ b/Software/CCE/CCE.C @@ -0,0 +1,384 @@ +//************************************************ +// Author: Federica Lionetto +// Created on: 24/02/2015 +//************************************************ + +/* +CCE reads all the ROOT files of a given CCE data taking and calculates the CCE. + +The CCE data taking is identified by the following information: +- , that is, the type of sensor (Hans410, ...); +- , that is, the filename excluding the position value and the run type. +- , that is, the position along z; +- , that is, the first position along x; +- , that is, the last position along x; +- , that is, the step between two subsequent data acquisitions in x (1 step = 5 microns). + +Compile with: + +make + +Run with: + +./CCE [sensor] [filename] [z] [firstx] [lastx] [stepx] [additional folder] + +For example: + +./CCE Hans410 ProcessRawData-20141121 0 0 75 3 + +A folder named AnalysisResults will be created in a fixed location and a ROOT file will be saved in there. A folder named Figures will be created inside the folder named AnalysisResults, with some monitoring plots. + +If needed, an additional folder can be specified, that will be created inside the folder named AnalysisResults. +*/ + +#include "../Tools/Lib.C" +#include "../Tools/lhcbStyle.C" +#include "../Tools/Style.C" + +#include "../Tools/FindStrip.C" +#include "../Tools/SCurve.C" +#include "../Tools/Par.C" + +void CCE(char *sensor, char *filename, const Float_t z, const Float_t firstx, const Float_t lastx, const Float_t stepx, char *externalPath=0); + +int main(int argc, char *argv[]) +{ + getLHCbStyle(); + PersonalStyle(); + + if ((argc == 2) && (string(argv[1]) == "--info")) + { + cout << "**************************************************" << endl; + + cout << "Some comments." << endl; + + cout << "**************************************************" << endl; + + return 0; + } + else if (argc < 7) + { + cout << "**************************************************" << endl; + + cout << "Error! Arguments missing..." << endl; + cout << "Please use the following format:" << endl; + cout << "./CCE [1] [2] [3] [4] [5] [6] [7]" << endl; + cout << "with:" << endl; + cout << "[1] = Type of sensor (Hans410, ...);" << endl; + cout << "[2] = Filename, excluding the position value and the run type;" << endl; + cout << "[3] = Position along z;" << endl; + cout << "[4] = First position along x;" << endl; + cout << "[5] = Last position along x" << endl; + cout << "[6] = Step between two subsequent data acquisitions (1 step = 5 microns);" << endl; + cout << "[7] = Additional folder, optional." << endl; + cout << "Type ./CCE --info for more information." << endl; + + cout << "**************************************************" << endl; + + return 0; + } + else + { + cout << "Type of sensor: " << argv[1] << endl; + cout << "Filename: " << argv[2] << endl; + cout << "Position along z: " << argv[3] << endl; + cout << "First position along x: " << argv[4] << endl; + cout << "Last position along x: " << argv[5] << endl; + cout << "Step between two subsequent data acquisitions: " << argv[6] << endl; + if (argc == 7) + CCE(argv[1],argv[2],atoi(argv[3]),atoi(argv[4]),atoi(argv[5]),atoi(argv[6])); + else if (argc == 8) + CCE(argv[1],argv[2],atoi(argv[3]),atoi(argv[4]),atoi(argv[5]),atoi(argv[6]),argv[7]); + else + { + cout << "Error! Too many arguments given..." << endl; + + return 0; + } + + return 0; + } +} + +void CCE(char *sensor, char *filename, const Float_t z, const Float_t firstx, const Float_t lastx, const Float_t stepx, char *externalPath) +{ + cout << "**************************************************" << endl; + cout << "Measuring CCE..." << endl; + cout << "**************************************************" << endl; + + // Do not comment this line. + gROOT->ProcessLine("#include "); + + // Do some fanciness to get the directory right. + // string inputDirectory = "/disk/groups/hep/flionett/TestStand/AnalysisResults/"+string(sensor)+"/CCE"; + // CHANGE inputDirectory!!! + string inputDirectory = "/disk/groups/hep/flionett/TestStand/AnalysisResults/"+string(sensor)+"/Alignment"; + string outputDirectory = "/disk/groups/hep/flionett/TestStand/AnalysisResults/"+string(sensor)+"/CCE"; + if (externalPath!=0) + outputDirectory = string(outputDirectory+"/"+externalPath); + cout << "The input directory is: " << inputDirectory << endl; + cout << "The output directory is: " << outputDirectory << endl; + + // Create the outputDirectory directory if it does not exist. + string path_to_make = "mkdir -p "+outputDirectory; + system(path_to_make.c_str()); + + ostringstream convertx; + ostringstream convertz; + string tempx; + string tempz; + + convertz.str(""); + convertz << z; + tempz = convertz.str(); + + cout << "Figures stored in: " << outputDirectory+"/Figures/"+filename+"-"+tempz+"z" << endl; + + // Create a directory named Figures inside the directory named outputDirectory if it does not exist. + string path_to_make_figures = "mkdir -p "+outputDirectory+"/Figures/"+filename+"-"+tempz+"z"; + system(path_to_make_figures.c_str()); + + TString path_to_figures = (string(path_to_make_figures)).substr((string(path_to_make_figures)).find_last_of(' ')+1); + + int strip; + string direction; + + char char_input_ROOT[200]; + string input_ROOT; + string output_ROOT; + + string inputFindStrip; + string outputFindStrip; + + Float_t noise[N]; + + const Int_t steps = (Int_t)((lastx-firstx)/stepx+1); + Float_t x[steps]; + Float_t signalOverNoise1Left[steps]; + Float_t signalOverNoise1Right[steps]; + Float_t signalOverNoise2[steps]; + Float_t signalOverNoise4[steps]; + + // Parameters of the fitting functions. + Float_t aLeft; + Float_t bLeft; + Float_t muLeft; + Float_t sigmaLeft; + + Float_t aRight; + Float_t bRight; + Float_t muRight; + Float_t sigmaRight; + + // Uncertainties on the parameters of the fitting functions. + // u = uncertainty. + Float_t uaLeft; + Float_t ubLeft; + Float_t umuLeft; + Float_t usigmaLeft; + + Float_t uaRight; + Float_t ubRight; + Float_t umuRight; + Float_t usigmaRight; + + // Open output ROOT file. + output_ROOT = outputDirectory+"/CCE-"+filename+"-"+tempz+"z.root"; + TFile *output = TFile::Open(TString(output_ROOT),"RECREATE"); + + for (Int_t step=0;stepGet("Header"); + int EventsHeader = Header->GetEntries(); + if (EventsHeader != 1) + { + cout << "Error! The ROOT file has been corrupted..." << endl; + + return ; + } + else + { + Header->SetBranchAddress("PedFilename",&PedFilename,&b_PedFilename); + + Header->GetEntry(); + + cout << "Pedestals calculated from: " << *PedFilename << endl; + + // Get the noise of each Beetle channel. + // Open input pedestal&noise text file. + FILE *inputText = fopen(PedFilename->c_str(),"r"); + + // Read noise. + for (int iChannel=0; iChannelGet(Form("hADCPedSub%d",ch1)); + TH1D *hist2 = (TH1D *)input->Get(Form("hADCPedSub%d",ch2)); + TH1D *hist3 = (TH1D *)input->Get(Form("hADCPedSub%d",ch3)); + TH1D *hist4 = (TH1D *)input->Get(Form("hADCPedSub%d",ch4)); + + if (direction == "left") { + signalOverNoise1Left[step] = (hist3->GetMean())/noise[ch3]; + signalOverNoise1Right[step] = (hist1->GetMean())/noise[ch1]; + signalOverNoise2[step] = (hist1->GetMean())/noise[ch1]+(hist3->GetMean())/noise[ch3]; + } + else if (direction == "right") { + signalOverNoise1Left[step] = (hist1->GetMean())/noise[ch1]; + signalOverNoise1Right[step] = (hist2->GetMean())/noise[ch2]; + signalOverNoise2[step] = (hist1->GetMean())/noise[ch1]+(hist2->GetMean())/noise[ch2]; + } + signalOverNoise4[step] = (hist1->GetMean())/noise[ch1]+(hist2->GetMean())/noise[ch2]+(hist3->GetMean())/noise[ch3]+(hist4->GetMean())/noise[ch4]; + + // Close input data ROOT files. + input->Close(); + } + + output->cd(); + + for (Int_t step=0;stepSetMarkerColor(kMagenta); + gCCESignalOverNoise1Right->SetMarkerColor(kOrange); + gCCESignalOverNoise2->SetMarkerColor(kRed); + gCCESignalOverNoise4->SetMarkerColor(kRed+2); + + gCCESignalOverNoise1Left->SetLineColor(kMagenta); + gCCESignalOverNoise1Right->SetLineColor(kOrange); + gCCESignalOverNoise2->SetLineColor(kRed); + gCCESignalOverNoise4->SetLineColor(kRed+2); + + gCCESignalOverNoise1Left->SetLineWidth(2); + gCCESignalOverNoise1Right->SetLineWidth(2); + gCCESignalOverNoise2->SetLineWidth(2); + gCCESignalOverNoise4->SetLineWidth(2); + + TLegend *legCCESignalOverNoise = CreateLegend4(gCCESignalOverNoise1Left,"left strip",gCCESignalOverNoise1Right,"right strip",gCCESignalOverNoise2,"2 strips",gCCESignalOverNoise4,"4 strips","lpw",0.72,0.62,0.92,0.92); + + mgCCESignalOverNoise->Add(gCCESignalOverNoise1Left); + mgCCESignalOverNoise->Add(gCCESignalOverNoise1Right); + mgCCESignalOverNoise->Add(gCCESignalOverNoise2); + mgCCESignalOverNoise->Add(gCCESignalOverNoise4); + + DrawGraphCompare(cCCESignalOverNoise,mgCCESignalOverNoise,legCCESignalOverNoise,"CCE","x (#mum)","S/N","APCE",path_to_figures); + + // Write output ROOT file. + output->Write(); + + // Close output ROOT file. + output->Close(); + + return; +} diff --git a/Software/CCE/Makefile b/Software/CCE/Makefile new file mode 100755 index 0000000..e734801 --- /dev/null +++ b/Software/CCE/Makefile @@ -0,0 +1,34 @@ +# +CC=$(CXX) +glib_cflags=$(shell pkg-config --cflags glib-2.0 gio-2.0) +glib_libs=$(shell pkg-config --libs glib-2.0 gio-2.0) + +ROOTC=$(shell root-config --cflags) +ROOTL=$(shell root-config --libs) +OPT=-g -fno-inline #-std=c++11 +CppFLAGS=$(OPT) -I. $(glib_cflags) +CXXFLAGS=-fPIC $(CppFLAGS) + + +UNAME_S := $(shell uname -s) +ifeq ($(UNAME_S),Linux) + SO=so + SO_FLAGS=-shared + CXXFLAGS += -D LINUX +endif +ifeq ($(UNAME_S),Darwin) + SO=dylib + SO_FLAGS=-dynamiclib -undefined dynamic_lookup -install_name @rpath/$@ + CXXFLAGS += -D OSX +endif + +all: CCE + +CCE: CCE.C + c++ -I$(OPT) $(CXXFLAGS) $(ROOTC) -o $@ $^ $(LDLIBS) $(ROOTL) $(gliblibs) + + +clean: + rm -f *.o CCE + rm -rf *.dSYM + diff --git a/Software/CheckAlignment/CheckAlignment.C b/Software/CheckAlignment/CheckAlignment.C index 6f1c8d1..2ffd59d 100644 --- a/Software/CheckAlignment/CheckAlignment.C +++ b/Software/CheckAlignment/CheckAlignment.C @@ -4,8 +4,12 @@ //************************************************ /* -CheckAlignment reads all the ROOT files of a given alignment data taking, calls FindStrip for each of them to find the Beetle channel corresponding to the strip hit by the laser, calculates the mean of the sum of the ADC counts of four adjacent strips around that hit by the laser as a function of the position along x (horizontal direction), and creates a ROOT file with the following information: -- a graph with the mean of the sum of the ADC counts of four adjacent strips around that hit by the laser as a function of the position along x. +CheckAlignment reads all the ROOT files of a given alignment data taking, calls FindStrip for each of them to find the Beetle channel corresponding to the strip hit by the laser, calculates +- the mean of the sum of the ADC counts of four adjacent strips around that hit by the laser as a function of the position along x (horizontal direction) +- the mean of the sum of the signal over noise ratio (ADC counts/noise) of four adjacent strips around that hit by the laser as a function of the position along x (horizontal direction) +and creates a ROOT file with the following information: +- a graph with the mean of the sum of the ADC counts of four adjacent strips around that hit by the laser as a function of the position along x +- a graph with the mean of the sum of the signal over noise ratio (ADC counts/noise) of four adjacent strips around that hit by the laser as a function of the position along x. The alignment data taking is identified by the following information: - , that is, the type of sensor (Hans410, ...); @@ -150,9 +154,12 @@ string inputFindStrip; string outputFindStrip; + Float_t noise[N]; + const Int_t steps = (Int_t)((lastx-firstx)/stepx+1); Float_t x[steps]; Float_t mean4ADC[steps]; + Float_t signalOverNoise4ADC[steps]; // Open output ROOT file. output_ROOT = outputDirectory+"/Alignment-"+filename+"-"+tempz+"z.root"; @@ -180,8 +187,8 @@ convertx << x[step]; tempx = convertx.str(); outputFindStrip = outputDirectory+"/FindStrip-"+filename+"-"+tempx+"x-"+tempz+"z-las.root"; - FindStrip(inputFindStrip,outputFindStrip,path_to_figures,&strip,&direction); - + FindStrip(inputFindStrip,outputFindStrip,path_to_figures,&strip,&direction); + cout << "Histograms: " << endl; cout << Form("hADCPedSub%d",strip) << endl; cout << Form("hADCPedSub%d",strip+NSkip) << endl; @@ -189,16 +196,58 @@ cout << Form("hADCPedSub%d",strip-2*NSkip) << endl; cout << Form("hADCPedSub%d",strip+2*NSkip) << endl; - // Four adjacent strips. - TH1D *hist1 = (TH1D *)input->Get(Form("hADCPedSub%d",strip)); - TH1D *hist2 = (TH1D *)input->Get(Form("hADCPedSub%d",strip+NSkip)); - TH1D *hist3 = (TH1D *)input->Get(Form("hADCPedSub%d",strip-NSkip)); - TH1D *hist4; + // Find the pedestal run from which pedestals have been calculated and get the noise of each Beetle channel. + string *PedFilename = new string(); + TBranch *b_PedFilename = 0; + + TTree *Header = (TTree *)input->Get("Header"); + int EventsHeader = Header->GetEntries(); + if (EventsHeader != 1) + { + cout << "Error! The ROOT file has been corrupted..." << endl; + + return ; + } + else + { + Header->SetBranchAddress("PedFilename",&PedFilename,&b_PedFilename); + + Header->GetEntry(); + + cout << "Pedestals calculated from: " << *PedFilename << endl; + + // Get the noise of each Beetle channel. + // Open input pedestal&noise text file. + FILE *inputText = fopen(PedFilename->c_str(),"r"); + + // Read noise. + for (int iChannel=0; iChannelGet(Form("hADCPedSub%d",strip-2*NSkip)); + ch4 = strip-2*NSkip; else if (direction == "right") - hist4 = (TH1D *)input->Get(Form("hADCPedSub%d",strip+2*NSkip)); + ch4 = strip+2*NSkip; + + // Four adjacent strips. + TH1D *hist1 = (TH1D *)input->Get(Form("hADCPedSub%d",ch1)); + TH1D *hist2 = (TH1D *)input->Get(Form("hADCPedSub%d",ch2)); + TH1D *hist3 = (TH1D *)input->Get(Form("hADCPedSub%d",ch3)); + TH1D *hist4 = (TH1D *)input->Get(Form("hADCPedSub%d",ch4)); + mean4ADC[step] = hist1->GetMean()+hist2->GetMean()+hist3->GetMean()+hist4->GetMean(); + signalOverNoise4ADC[step] = (hist1->GetMean())/noise[ch1]+(hist2->GetMean())/noise[ch2]+(hist3->GetMean())/noise[ch3]+(hist4->GetMean())/noise[ch4]; // Close input data ROOT files. input->Close(); @@ -210,10 +259,15 @@ x[step] = x[step]*5.; // One step corresponds to 5 microns. // Four adjacent strips. - TGraph *gcheckAlignment4 = new TGraph(steps,x,mean4ADC); - InitGraph(gcheckAlignment4,"Check alignment - 4 adjacent strips","x (#mum)","ADC counts"); - TCanvas *ccheckAlignment4 = new TCanvas(Form("ccheckAlignment4-%s",filename),"",400,300); - DrawGraph(ccheckAlignment4,gcheckAlignment4,"APC",path_to_figures); + TGraph *gcheckAlignmentMean4 = new TGraph(steps,x,mean4ADC); + InitGraph(gcheckAlignmentMean4,"Check alignment - 4 adjacent strips","x (#mum)","ADC counts"); + TCanvas *ccheckAlignmentMean4 = new TCanvas(Form("ccheckAlignmentMean4-%s",filename),"",400,300); + DrawGraph(ccheckAlignmentMean4,gcheckAlignmentMean4,"APC",path_to_figures); + + TGraph *gcheckAlignmentSignalOverNoise4 = new TGraph(steps,x,signalOverNoise4ADC); + InitGraph(gcheckAlignmentSignalOverNoise4,"Check alignment - 4 adjacent strips","x (#mum)","S/N"); + TCanvas *ccheckAlignmentSignalOverNoise4 = new TCanvas(Form("ccheckAlignmentSignalOverNoise4-%s",filename),"",400,300); + DrawGraph(ccheckAlignmentSignalOverNoise4,gcheckAlignmentSignalOverNoise4,"APC",path_to_figures); // Write output ROOT file. output->Write(); diff --git a/Software/Focusing/Focusing.C b/Software/Focusing/Focusing.C index 9ff6485..27ff7b1 100644 --- a/Software/Focusing/Focusing.C +++ b/Software/Focusing/Focusing.C @@ -5,9 +5,10 @@ /* Focusing reads all the ROOT files of a given focusing data taking and calculates the z coordinate of the focus. -For each z position, it fits the s-curve with two erf functions, one for the left side and one for the right side, and returns the mu and sigma, that will be used to calculate the z coordinate of the focus. The starting values and the limits of the parameters of the two erf functions are set according to the filename of the measurement, by using the "assignParInfo" procedure. +For each z position, it fits the s-curve with two erf functions, one for the left side and one for the right side, and returns the mu and sigma, that will be used to calculate the z coordinate of the focus. The starting values and the limits of the parameters of the two erf functions are set according to the filename of the measurement, by using the "assignParInfoSCurves" procedure. The mu and sigma as a function of the z position are fitted by the functions mu = p0+p1*z and sigma = q0*|z-q1|+q2, respectively, and the values returned by the fit are printed out on the screen. +The starting values and the limits of the parameters of the two sigma functions are set according to the filename of the measurement, by using the "assignParInfoSigma" procedure. Knowing p1, the angle alpha = arctan(p1) between the laser and the normal to the surface of the sensor is also determined. Its uncertainty is calculated from its derivative, which is a good estimate for the moment, but not fully correct. The focusing data taking is identified by the following information: @@ -42,17 +43,11 @@ #include "../Tools/Style.C" #include "../Tools/FindStrip.C" +#include "../Tools/SCurve.C" #include "../Tools/Par.C" void Focusing(char *sensor, char *filename, const Float_t firstx, const Float_t lastx, const Float_t stepx, const Float_t firstz, const Float_t lastz, const Float_t stepz, char *externalPath=0); -Double_t fLeft(Double_t *x, Double_t *par); -Double_t fRight(Double_t *x, Double_t *par); - -Double_t fSigma(Double_t *x, Double_t *par); - -void assignParInfo(string filename, Float_t zvalue, Float_t *minRight, Float_t *maxRight, Float_t *minLeft, Float_t *maxLeft, Float_t par[], Int_t length); - int main(int argc, char *argv[]) { getLHCbStyle(); @@ -63,8 +58,9 @@ cout << "**************************************************" << endl; cout << "Focusing reads all the ROOT files of a given focusing data taking and calculates the z coordinate of the focus." << endl; - cout << "For each z position, it fits the s-curve with two erf functions, one for the left side and one for the right side, and returns the mu and sigma, that will be used to calculate the z coordinate of the focus. The starting values and the limits of the parameters of the two erf functions are set according to the filename of the measurement, by using the 'assignParInfo' procedure." << endl; + cout << "For each z position, it fits the s-curve with two erf functions, one for the left side and one for the right side, and returns the mu and sigma, that will be used to calculate the z coordinate of the focus. The starting values and the limits of the parameters of the two erf functions are set according to the filename of the measurement, by using the 'assignParInfoSCurves' procedure." << endl; cout << "The mu and sigma as a function of the z position are fitted by the functions mu = p0+p1*z and sigma = q0*|z-q1|+q2, respectively, and the values returned by the fit are printed out on the screen." << endl; + cout << "The starting values and the limits of the parameters of the two sigma functions are set according to the filename of the measurement, by using the 'assignParInfoSigma' procedure." << endl; cout << "Knowing p1, the angle alpha = arctan(p1) between the laser and the normal to the surface of the sensor is also determined. Its uncertainty is calculated from its derivative, which is a good estimate for the moment, but not fully correct." << endl; cout << "**************************************************" << endl; @@ -195,9 +191,11 @@ string inputFindStrip; string outputFindStrip; + Float_t noise[N]; + const Int_t stepsx = (Int_t)((lastx-firstx)/stepx+1); Float_t x[stepsx]; - Float_t mean4ADC[stepsx]; + Float_t signalOverNoise4[stepsx]; const Int_t stepsz = (Int_t)((lastz-firstz)/stepz+1); Float_t z[stepsz]; @@ -233,8 +231,8 @@ output_ROOT = outputDirectory+"/Focusing-"+filename+".root"; TFile *output = TFile::Open(TString(output_ROOT),"RECREATE"); - TGraph *gcheckAlignment4[stepsz]; - TCanvas *ccheckAlignment4[stepsz]; + TGraph *gcheckAlignmentSignalOverNoise4[stepsz]; + TCanvas *ccheckAlignmentSignalOverNoise4[stepsz]; for (Int_t zcounter=0;zcounterGet(Form("hADCPedSub%d",strip)); - TH1D *hist2 = (TH1D *)input->Get(Form("hADCPedSub%d",strip+NSkip)); - TH1D *hist3 = (TH1D *)input->Get(Form("hADCPedSub%d",strip-NSkip)); - TH1D *hist4; - if (direction == "left") - hist4 = (TH1D *)input->Get(Form("hADCPedSub%d",strip-2*NSkip)); - else if (direction == "right") - hist4 = (TH1D *)input->Get(Form("hADCPedSub%d",strip+2*NSkip)); - mean4ADC[xcounter] = hist1->GetMean()+hist2->GetMean()+hist3->GetMean()+hist4->GetMean(); + // Find the pedestal run from which pedestals have been calculated and get the noise of each Beetle channel. + string *PedFilename = new string(); + TBranch *b_PedFilename = 0; + TTree *Header = (TTree *)input->Get("Header"); + int EventsHeader = Header->GetEntries(); + if (EventsHeader != 1) + { + cout << "Error! The ROOT file has been corrupted..." << endl; + + return ; + } + else + { + Header->SetBranchAddress("PedFilename",&PedFilename,&b_PedFilename); + + Header->GetEntry(); + + cout << "Pedestals calculated from: " << *PedFilename << endl; + + // Get the noise of each Beetle channel. + // Open input pedestal&noise text file. + FILE *inputText = fopen(PedFilename->c_str(),"r"); + + // Read noise. + for (int iChannel=0; iChannelGet(Form("hADCPedSub%d",ch1)); + TH1D *hist2 = (TH1D *)input->Get(Form("hADCPedSub%d",ch2)); + TH1D *hist3 = (TH1D *)input->Get(Form("hADCPedSub%d",ch3)); + TH1D *hist4 = (TH1D *)input->Get(Form("hADCPedSub%d",ch4)); + + signalOverNoise4[xcounter] = (hist1->GetMean())/noise[ch1]+(hist2->GetMean())/noise[ch2]+(hist3->GetMean())/noise[ch3]+(hist4->GetMean())/noise[ch4]; + // Close input data ROOT files. input->Close(); } @@ -301,8 +340,8 @@ x[xcounter] = x[xcounter]*5.; // One step corresponds to 5 microns. // Four adjacent strips. - gcheckAlignment4[zcounter] = new TGraph(stepsx,x,mean4ADC); - InitGraph(gcheckAlignment4[zcounter],Form("Focusing - 4 adjacent strips - z = %d",(int)z[zcounter]),"x (#mum)","ADC counts"); + gcheckAlignmentSignalOverNoise4[zcounter] = new TGraph(stepsx,x,signalOverNoise4); + InitGraph(gcheckAlignmentSignalOverNoise4[zcounter],Form("Focusing - 4 adjacent strips - z = %d",(int)z[zcounter]),"x (#mum)","S/N"); // Fit. @@ -316,66 +355,21 @@ // Array of the parameters necessary for fitting with fitRight and fitLeft. // The array contains par0, par1, par2, par3, par0low, par0high, par1low, par1high, par2low, par2high, par3low, par3high for fitRight and the same for fitLeft. - const Int_t length = 24; - Float_t par[length]; + const Int_t lengthParSCurves = 24; + Float_t parSCurves[lengthParSCurves]; - assignParInfo(string(filename),z[zcounter],&minRight,&maxRight,&minLeft,&maxLeft,par,length); + assignParInfoSCurves(string(filename),z[zcounter],&minRight,&maxRight,&minLeft,&maxLeft,parSCurves,lengthParSCurves); // Right side (increasing y). - TF1 *fitRight = new TF1("fitRight",fRight,minRight,maxRight,4); - fitRight->SetParameter(0,par[0]); - fitRight->SetParameter(1,par[1]); - fitRight->SetParameter(2,par[2]); - fitRight->SetParameter(3,par[3]); - fitRight->SetParLimits(0,par[4],par[5]); - fitRight->SetParLimits(1,par[6],par[7]); - fitRight->SetParLimits(2,par[8],par[9]); - fitRight->SetParLimits(3,par[10],par[11]); - gcheckAlignment4[zcounter]->Fit(fitRight,"BR"); - - aRight[zcounter] = fitRight->GetParameter(0); - muRight[zcounter] = fitRight->GetParameter(1); - sigmaRight[zcounter] = fitRight->GetParameter(2); - bRight[zcounter] = fitRight->GetParameter(3); - - uaRight[zcounter] = fitRight->GetParError(0); - umuRight[zcounter] = fitRight->GetParError(1); - usigmaRight[zcounter] = fitRight->GetParError(2); - ubRight[zcounter] = fitRight->GetParError(3); - - cout << "Right side, z = " << zcounter << ", a = " << aRight[zcounter] << ", mu = " << muRight[zcounter] << ", sigma = " << sigmaRight[zcounter] << ", b = " << bRight[zcounter] << endl; + TF1 *fitSCurveRight = new TF1("fitSCurveRight",fRight,minRight,maxRight,4); + fitSCurve(r,gcheckAlignmentSignalOverNoise4[zcounter],fitSCurveRight,parSCurves,lengthParSCurves,&aRight[zcounter],&muRight[zcounter],&sigmaRight[zcounter],&bRight[zcounter],&uaRight[zcounter],&umuRight[zcounter],&usigmaRight[zcounter],&ubRight[zcounter]); // Left side (decreasing y). - TF1 *fitLeft = new TF1("fitLeft",fLeft,minLeft,maxLeft,4); - fitLeft->SetParameter(0,par[12]); - fitLeft->SetParameter(1,par[13]); - fitLeft->SetParameter(2,par[14]); - fitLeft->SetParameter(3,par[15]); - // fitLeft->SetParLimits(0,90.,170.); - fitLeft->SetParLimits(1,par[18],par[19]); - fitLeft->SetParLimits(2,par[20],par[21]); - // fitLeft->SetParLimits(3,150.,220.); - gcheckAlignment4[zcounter]->Fit(fitLeft,"BR"); + TF1 *fitSCurveLeft = new TF1("fitSCurveLeft",fLeft,minLeft,maxLeft,4); + fitSCurve(l,gcheckAlignmentSignalOverNoise4[zcounter],fitSCurveLeft,parSCurves,lengthParSCurves,&aLeft[zcounter],&muLeft[zcounter],&sigmaLeft[zcounter],&bLeft[zcounter],&uaLeft[zcounter],&umuLeft[zcounter],&usigmaLeft[zcounter],&ubLeft[zcounter]); - aLeft[zcounter] = fitLeft->GetParameter(0); - muLeft[zcounter] = fitLeft->GetParameter(1); - sigmaLeft[zcounter] = fitLeft->GetParameter(2); - bLeft[zcounter] = fitLeft->GetParameter(3); - - uaLeft[zcounter] = fitLeft->GetParError(0); - umuLeft[zcounter] = fitLeft->GetParError(1); - usigmaLeft[zcounter] = fitLeft->GetParError(2); - ubLeft[zcounter] = fitLeft->GetParError(3); - - cout << "Left side, z = " << zcounter << ", a = " << aLeft[zcounter] << ", mu = " << muLeft[zcounter] << ", sigma = " << sigmaLeft[zcounter] << ", b = " << bLeft[zcounter] << endl; - - - - ccheckAlignment4[zcounter] = new TCanvas(Form("ccheckAlignment4-%s-%dz",filename,(int)z[zcounter]),"",400,300); - DrawGraphFunc2(ccheckAlignment4[zcounter],gcheckAlignment4[zcounter],fitRight,fitLeft,"AP",path_to_figures); - - - + ccheckAlignmentSignalOverNoise4[zcounter] = new TCanvas(Form("ccheckAlignmentSignalOverNoise4-%s-%dz",filename,(int)z[zcounter]),"",400,300); + DrawGraphFunc2(ccheckAlignmentSignalOverNoise4[zcounter],gcheckAlignmentSignalOverNoise4[zcounter],fitSCurveRight,fitSCurveLeft,"AP",path_to_figures); } @@ -471,54 +465,33 @@ Float_t minSigma = z[0]; Float_t maxSigma = z[stepsz-1]; + // Array of the parameters necessary for fitting with fitSigmaLeft and fitSigmaRight. + // The array contains par0, par1, par2, par0low, par0high, par1low, par1high, par2low, and par2high for fitSigmaLeft and the same for fitSigmaRight. + const Int_t lengthParSigma = 18; + Float_t parSigma[lengthParSigma]; + + assignParInfoSigma(string(filename),parSigma,lengthParSigma); + // Sigma - left edge. TGraphErrors *gsigmaLeft = new TGraphErrors(stepsz,z,sigmaLeft,uz,usigmaLeft); InitGraphErrors(gsigmaLeft,"Focusing - left side","z (#mum)","#sigma_{left}"); - TCanvas *csigmaLeft = new TCanvas("csigmaLeft","",400,300); gsigmaLeft->GetXaxis()->SetLimits(z[0]-100.,z[stepsz-1]+100.); TF1 *fitSigmaLeft = new TF1("fitSigmaLeft",fSigma,minSigma,maxSigma,3); - fitSigmaLeft->SetParameter(0,5.); - fitSigmaLeft->SetParameter(1,600.); - fitSigmaLeft->SetParameter(2,0.025); - fitSigmaLeft->SetParLimits(0,0.,10.); - fitSigmaLeft->SetParLimits(1,500.,700.); - // fitSigmaLeft->SetParLimits(2,.,.); - fitSigmaLeft->SetLineColor(kRed); - gsigmaLeft->Fit(fitSigmaLeft,"BR"); + fitSigma(l,gsigmaLeft,fitSigmaLeft,parSigma,lengthParSigma,&q0Left,&q1Left,&q2Left,&uq0Left,&uq1Left,&uq2Left); - q0Left = fitSigmaLeft->GetParameter(0); - uq0Left = fitSigmaLeft->GetParError(0); - q1Left = fitSigmaLeft->GetParameter(1); - uq1Left = fitSigmaLeft->GetParError(1); - q2Left = fitSigmaLeft->GetParameter(2); - uq2Left = fitSigmaLeft->GetParError(2); - + TCanvas *csigmaLeft = new TCanvas("csigmaLeft","",400,300); DrawGraphErrors(csigmaLeft,gsigmaLeft,"AP",path_to_figures); // Sigma - right edge. TGraphErrors *gsigmaRight = new TGraphErrors(stepsz,z,sigmaRight,uz,usigmaRight); InitGraphErrors(gsigmaRight,"Focusing - right side","z (#mum)","#sigma_{right}"); - TCanvas *csigmaRight = new TCanvas("csigmaRight","",400,300); gsigmaRight->GetXaxis()->SetLimits(z[0]-100.,z[stepsz-1]+100.); TF1 *fitSigmaRight = new TF1("fitSigmaRight",fSigma,minSigma,maxSigma,3); - fitSigmaRight->SetParameter(0,5.); - fitSigmaRight->SetParameter(1,600.); - fitSigmaRight->SetParameter(2,0.025); - fitSigmaRight->SetParLimits(0,0.,10.); - fitSigmaRight->SetParLimits(1,500.,700.); - // fitSigmaRight->SetParLimits(2,.,.); - fitSigmaRight->SetLineColor(kRed); - gsigmaRight->Fit(fitSigmaRight,"BR"); + fitSigma(r,gsigmaRight,fitSigmaRight,parSigma,lengthParSigma,&q0Right,&q1Right,&q2Right,&uq0Right,&uq1Right,&uq2Right); - q0Right = fitSigmaRight->GetParameter(0); - uq0Right = fitSigmaRight->GetParError(0); - q1Right = fitSigmaRight->GetParameter(1); - uq1Right = fitSigmaRight->GetParError(1); - q2Right = fitSigmaRight->GetParameter(2); - uq2Right = fitSigmaRight->GetParError(2); - + TCanvas *csigmaRight = new TCanvas("csigmaRight","",400,300); DrawGraphErrors(csigmaRight,gsigmaRight,"AP",path_to_figures); @@ -569,238 +542,3 @@ return; } - -// fLeft has four parameters: -// - par[0] is the y-spread around the middle of the curve; -// - par[1] is the x-coordinate of the middle of the curve; -// - par[2] is the steepness of the curve; -// - par[3] is the y-coordinate of the middle of the curve. -Double_t fLeft(Double_t *x, Double_t *par) -{ - return par[0]*(1.-erf((x[0]-par[1])/(sqrt(2.)*par[2])))+par[3]; -} - -// fRight has four parameters: -// - par[0] is the y-spread around the middle of the curve; -// - par[1] is the x-coordinate of the middle of the curve; -// - par[2] is the steepness of the curve; -// - par[3] is the y-coordinate of the middle of the curve. -Double_t fRight(Double_t *x, Double_t *par) -{ -return par[0]*erf((x[0]-par[1])/(sqrt(2.)*par[2]))+par[3]; -} - -// fSigma is used to fit the sigma as a function of the z position and has three parameters: -// - par[0] is is angular coefficient of the two straight lines; -// - par[1] is the x-coordinate of the lowest point; -// - par[2] is the y-coordinate of the lowest point. -Double_t fSigma(Double_t *x, Double_t *par) -{ - return par[0]*abs(x[0]-par[1])+par[2]; -} - -void assignParInfo(string filename, Float_t zvalue, Float_t *minRight, Float_t *maxRight, Float_t *minLeft, Float_t *maxLeft, Float_t par[], Int_t length) -{ - if (filename == "ProcessRawData-201501093-216") { - // Right. - if (zvalue < 120.) - { - *minRight = 70.; - *maxRight = 180.; - } - else - { - *minRight = 60.; - *maxRight = 140.; - } - - // Left. - if (zvalue < 40.) - { - *minLeft = 180.; - *maxLeft = 280.; - } - else if (zvalue < 120.) - { - *minLeft = 180.; - *maxLeft = 270.; - } - else - { - *minLeft = 180.; - *maxLeft = 260.; - } - - // Right. - if (zvalue < 120.) - par[0] = 125.; - else - par[0] = 140.; - par[1] = 95.; - par[2] = 10.; - par[3] = 200.; - - par[4] = 90.; - par[5] = 170.; - par[6] = 70.; - par[7] = 120.; - par[8] = 3.; - par[9] = 20.; - par[10] = 150.; - par[11] = 220.; - - // Left. - if (zvalue < 120.) - par[12] = 125.; - else - par[12] = 140.; - par[13] = 230.; - par[14] = 10.; - par[15] = 200.; - - // fitLeft->SetParLimits(0,90.,170.); - par[18] = 215.; - par[19] = 250.; - par[20] = 3.; - par[21] = 20.; - // fitLeft->SetParLimits(3,150.,220.); - } - - // It does not look very nice. - else if (filename == "ProcessRawData-20150111-216") { - // Right. - if (zvalue < 105.) - { - *minRight = 60.; - *maxRight = 120.; - } - else - { - *minRight = 50.; - *maxRight = 120.; - } - - // Left. - *minLeft = 180.; - *maxLeft = 250.; - - // Right. - par[0] = 140.; - par[1] = 85.; - par[2] = 6.; - par[3] = 175.; - - par[4] = 110.; - par[5] = 170.; - par[6] = 70.; - par[7] = 100.; - par[8] = 3.; - par[9] = 10.; - par[10] = 150.; - par[11] = 200.; - - // Left. - par[12] = 140.; - par[13] = 220.; - par[14] = 6.; - par[15] = 175.; - - // fitLeft->SetParLimits(0,90.,170.); - par[18] = 210.; - par[19] = 230.; - par[20] = 3.; - par[21] = 10.; - // fitLeft->SetParLimits(3,150.,220.); - } - - - - - else if (filename == "ProcessRawData-201501124-216") { - // Right. - if (zvalue < 80.) - { - *minRight = -8440.; - *maxRight = -8350.; - } - else if (zvalue < 180.) - { - *minRight = -8450.; - *maxRight = -8370.; - } - else - { - *minRight = -8460.; - *maxRight = -8370.; - } - - // Left. - if (zvalue == 100.) - { - *minLeft = -8320.; - *maxLeft = -8240.; - } - else if (zvalue < 120.) - { - *minLeft = -8350.; - *maxLeft = -8240.; - } - else if (zvalue < 180.) - { - *minLeft = -8350.; - *maxLeft = -8250.; - } - else - { - *minLeft = -8360.; - *maxLeft = -8260.; - } - - // Right. - if (zvalue < 100.) - par[0] = 100.; - else - par[0] = 130.; - if (zvalue < 100.) - par[1] = -8400.; - else - par[1] = -8420.; - par[2] = 10.; - if (zvalue < 100.) - par[3] = 200.; - else - par[3] = 170.; - - par[4] = 80.; - par[5] = 140.; - par[6] = -8450.; - par[7] = -8370.; - par[8] = 3.; - par[9] = 20.; - par[10] = 150.; - par[11] = 250.; - - // Left. - if (zvalue < 100.) - par[12] = 100.; - else - par[12] = 135.; - par[13] = -8280.; - par[14] = 10.; - if (zvalue < 100.) - par[15] = 200.; - else - par[15] = 180.; - - // fitLeft->SetParLimits(0,90.,170.); - par[18] = -8300.; - par[19] = -8250.; - par[20] = 3.; - par[21] = 20.; - // fitLeft->SetParLimits(3,150.,220.); - } - - - - return; -} diff --git a/Software/IVScan/IVScan.C b/Software/IVScan/IVScan.C index 6910d1d..c75f2fe 100644 --- a/Software/IVScan/IVScan.C +++ b/Software/IVScan/IVScan.C @@ -300,7 +300,7 @@ mgIVScan->Add(gIVScan1); mgIVScan->Add(gIVScan2); - DrawGraphCompare(cIVScan,mgIVScan,legIVScan,"IV scan","Bias voltage (V)","Current (#muA)",path_to_figures); + DrawGraphCompare(cIVScan,mgIVScan,legIVScan,"IV scan","Bias voltage (V)","Current (#muA)","APE",path_to_figures); output->Close(); diff --git a/Software/PulseShapevsV/PulseShapevsV.C b/Software/PulseShapevsV/PulseShapevsV.C index d1cccd2..debedb9 100644 --- a/Software/PulseShapevsV/PulseShapevsV.C +++ b/Software/PulseShapevsV/PulseShapevsV.C @@ -309,9 +309,9 @@ mgaverageADCSignalAtPeakvsV->Add(gaverageADCSignalAtPeakvsV1); mgaverageADCSignalAtPeakvsV->Add(gaverageADCSignalAtPeakvsV2); - DrawGraphCompare(claserDelayAtPeakvsV,mglaserDelayAtPeakvsV,leglaserDelayAtPeakvsV,"Laser delay","Bias voltage (V)","Laser delay (ns)",path_to_figures); + DrawGraphCompare(claserDelayAtPeakvsV,mglaserDelayAtPeakvsV,leglaserDelayAtPeakvsV,"Laser delay","Bias voltage (V)","Laser delay (ns)","APE",path_to_figures); - DrawGraphCompare(caverageADCSignalAtPeakvsV,mgaverageADCSignalAtPeakvsV,legaverageADCSignalAtPeakvsV,"Average ADC signal","Bias voltage (V)"," (ADC counts)",path_to_figures); + DrawGraphCompare(caverageADCSignalAtPeakvsV,mgaverageADCSignalAtPeakvsV,legaverageADCSignalAtPeakvsV,"Average ADC signal","Bias voltage (V)"," (ADC counts)","APE",path_to_figures); output->Close(); diff --git a/Software/Tools/Par.C b/Software/Tools/Par.C index f762785..764678d 100644 --- a/Software/Tools/Par.C +++ b/Software/Tools/Par.C @@ -20,4 +20,8 @@ // Number of Beetle channels to skip to find the next connected Beetle channel + 1. If Beetle channel 0 and Beeetle channel 4 are connected, NSkip = 4. const int NSkip = 4; +// Left and right strings. +string l = "left"; +string r = "right"; + #endif diff --git a/Software/Tools/SCurve.C b/Software/Tools/SCurve.C new file mode 100644 index 0000000..df3db86 --- /dev/null +++ b/Software/Tools/SCurve.C @@ -0,0 +1,589 @@ +//************************************************ +// Author: Federica Lionetto +// Created on: 25/02/2015 +//************************************************ + +/* +SCurve contains some useful functions related to s-curves: +- fLeft describes the falling s-curve; +- fRight describes the rising s-curve; +- fSigma describes the sigma as a function of the z position; +- assignParInfoSCurves sets the starting values and the limits of the parameters of the two erf functions describing the s-curves according to the filename of the measurement; +- assignParInfoSigma sets the starting values and the limits of the parameters of the two sigma functions according to the filename of the measurement; +- fitSCurve fits the s-curve and returns the result of the fit; +- fitSigma fits the sigma as a function of the z position and returns the result of the fit. +*/ + +// Header guard. +#ifndef __SCURVE_C_INCLUDED__ +#define __SCURVE_C_INCLUDED__ + +#include "Lib.C" +#include "lhcbStyle.C" +#include "Style.C" +#include "Par.C" + + + +// Declarations. + +Double_t fLeft(Double_t *x, Double_t *par); + +Double_t fRight(Double_t *x, Double_t *par); + +Double_t fSigma(Double_t *x, Double_t *par); + +void assignParInfoSCurves(string filename, Float_t zvalue, Float_t *minRight, Float_t *maxRight, Float_t *minLeft, Float_t *maxLeft, Float_t parSCurves[], Int_t lengthParSCurves); +void assignParInfoSigma(string filename, Float_t parSigma[], Int_t lengthParSigma); + +void fitSCurve(string edge, TGraph *graph, TF1 *f, Float_t parSCurves[], Int_t lengthParSCurves, Float_t *a, Float_t *mu, Float_t *sigma, Float_t *b, Float_t *ua, Float_t *umu, Float_t *usigma, Float_t *ub); + +void fitSigma(string edge, TGraph *graph, TF1 *f, Float_t parSigma[], Int_t lengthParSigma, Float_t *q0, Float_t *q1, Float_t *q2, Float_t *uq0, Float_t *uq1, Float_t *uq2); + +// Definitions. + +// fLeft has four parameters: +// - par[0] is the y-spread around the middle of the curve; +// - par[1] is the x-coordinate of the middle of the curve; +// - par[2] is the steepness of the curve; +// - par[3] is the y-coordinate of the middle of the curve. +Double_t fLeft(Double_t *x, Double_t *par) +{ + return par[0]*(1.-erf((x[0]-par[1])/(sqrt(2.)*par[2])))+par[3]; +} + +// fRight has four parameters: +// - par[0] is the y-spread around the middle of the curve; +// - par[1] is the x-coordinate of the middle of the curve; +// - par[2] is the steepness of the curve; +// - par[3] is the y-coordinate of the middle of the curve. +Double_t fRight(Double_t *x, Double_t *par) +{ +return par[0]*erf((x[0]-par[1])/(sqrt(2.)*par[2]))+par[3]; +} + +// fSigma is used to fit the sigma as a function of the z position and has three parameters: +// - par[0] is the angular coefficient of the two straight lines; +// - par[1] is the x-coordinate of the lowest point; +// - par[2] is the y-coordinate of the lowest point. +Double_t fSigma(Double_t *x, Double_t *par) +{ + return par[0]*abs(x[0]-par[1])+par[2]; +} + +// assignParInfoSCurves has the following parameters: +// - string filename, the filename of the measurement; +// - Float_t zvalue, the position along z; +// - Float_t *minRight, the lower limit of the fitting range for the fRight function; +// - Float_t *maxRight, the upper limit of the fitting range for the fRight function; +// - Float_t *minLeft, the lower limit of the fitting range for the fLeft function; +// - Float_t *maxLeft, the upper limit of the fitting range for the fLeft function; +// - Float_t parSCurves[], the array containing the parameters of the s-curves; +// - Float_t lengthSCurves, the length of the array containing the parameters of the s-curves. +void assignParInfoSCurves(string filename, Float_t zvalue, Float_t *minRight, Float_t *maxRight, Float_t *minLeft, Float_t *maxLeft, Float_t parSCurves[], Int_t lengthParSCurves) +{ + if (filename == "ProcessRawData-201501093-216") { + // Right. + if (zvalue < 120.) + { + *minRight = 70.; + *maxRight = 180.; + } + else + { + *minRight = 60.; + *maxRight = 140.; + } + + // Left. + if (zvalue < 40.) + { + *minLeft = 180.; + *maxLeft = 280.; + } + else if (zvalue < 120.) + { + *minLeft = 180.; + *maxLeft = 270.; + } + else + { + *minLeft = 180.; + *maxLeft = 260.; + } + + // Right. + if (zvalue < 120.) + parSCurves[0] = 125.; + else + parSCurves[0] = 140.; + parSCurves[1] = 95.; + parSCurves[2] = 10.; + parSCurves[3] = 200.; + + parSCurves[4] = 90.; + parSCurves[5] = 170.; + parSCurves[6] = 70.; + parSCurves[7] = 120.; + parSCurves[8] = 3.; + parSCurves[9] = 20.; + parSCurves[10] = 150.; + parSCurves[11] = 220.; + + // Left. + if (zvalue < 120.) + parSCurves[12] = 125.; + else + parSCurves[12] = 140.; + parSCurves[13] = 230.; + parSCurves[14] = 10.; + parSCurves[15] = 200.; + + // fitLeft->SetParLimits(0,90.,170.); + parSCurves[18] = 215.; + parSCurves[19] = 250.; + parSCurves[20] = 3.; + parSCurves[21] = 20.; + // fitLeft->SetParLimits(3,150.,220.); + } + + + + // It does not look very nice. + else if (filename == "ProcessRawData-20150111-216") { + // Right. + if (zvalue < 105.) + { + *minRight = 60.; + *maxRight = 120.; + } + else + { + *minRight = 50.; + *maxRight = 120.; + } + + // Left. + *minLeft = 180.; + *maxLeft = 250.; + + // Right. + parSCurves[0] = 140.; + parSCurves[1] = 85.; + parSCurves[2] = 6.; + parSCurves[3] = 175.; + + parSCurves[4] = 110.; + parSCurves[5] = 170.; + parSCurves[6] = 70.; + parSCurves[7] = 100.; + parSCurves[8] = 3.; + parSCurves[9] = 10.; + parSCurves[10] = 150.; + parSCurves[11] = 200.; + + // Left. + parSCurves[12] = 140.; + parSCurves[13] = 220.; + parSCurves[14] = 6.; + parSCurves[15] = 175.; + + // fitLeft->SetParLimits(0,90.,170.); + parSCurves[18] = 210.; + parSCurves[19] = 230.; + parSCurves[20] = 3.; + parSCurves[21] = 10.; + // fitLeft->SetParLimits(3,150.,220.); + } + + + + else if (filename == "ProcessRawData-201501124-216") { + // Right. + if (zvalue < 80.) + { + *minRight = -8440.; + *maxRight = -8350.; + } + else if (zvalue < 180.) + { + *minRight = -8450.; + *maxRight = -8370.; + } + else + { + *minRight = -8460.; + *maxRight = -8370.; + } + + // Left. + if (zvalue == 100.) + { + *minLeft = -8320.; + *maxLeft = -8240.; + } + else if (zvalue < 120.) + { + *minLeft = -8350.; + *maxLeft = -8240.; + } + else if (zvalue < 180.) + { + *minLeft = -8350.; + *maxLeft = -8250.; + } + else + { + *minLeft = -8360.; + *maxLeft = -8260.; + } + + // Right. + if (zvalue < 100.) + parSCurves[0] = 100.; + else + parSCurves[0] = 130.; + if (zvalue < 100.) + parSCurves[1] = -8400.; + else + parSCurves[1] = -8420.; + parSCurves[2] = 10.; + if (zvalue < 100.) + parSCurves[3] = 200.; + else + parSCurves[3] = 170.; + + parSCurves[4] = 80.; + parSCurves[5] = 140.; + parSCurves[6] = -8450.; + parSCurves[7] = -8370.; + parSCurves[8] = 3.; + parSCurves[9] = 20.; + parSCurves[10] = 150.; + parSCurves[11] = 250.; + + // Left. + if (zvalue < 100.) + parSCurves[12] = 100.; + else + parSCurves[12] = 135.; + parSCurves[13] = -8280.; + parSCurves[14] = 10.; + if (zvalue < 100.) + parSCurves[15] = 200.; + else + parSCurves[15] = 180.; + + // fitLeft->SetParLimits(0,90.,170.); + parSCurves[18] = -8300.; + parSCurves[19] = -8250.; + parSCurves[20] = 3.; + parSCurves[21] = 20.; + // fitLeft->SetParLimits(3,150.,220.); + } + + + + else if (filename == "ProcessRawData-20150221-216") { + // Right. + if (zvalue < 180.) + { + *minRight = 60.; + *maxRight = 160.; + } + else + { + *minRight = 50.; + *maxRight = 160.; + } + + // Left. + if (zvalue < 180.) + { + *minLeft = 160.; + *maxLeft = 260.; + } + else + { + *minLeft = 160.; + *maxLeft = 250.; + } + + // Right. + parSCurves[0] = 15.; + parSCurves[1] = 100.; + parSCurves[2] = 6.; + parSCurves[3] = 12.; + + // parSCurves[4] = 10.; + // parSCurves[5] = 20.; + parSCurves[6] = 70.; + parSCurves[7] = 110.; + parSCurves[8] = 3.; + parSCurves[9] = 15.; + // parSCurves[10] = 8.; + // parSCurves[11] = 18.; + + // Left. + parSCurves[12] = 17.; + parSCurves[13] = 220.; + parSCurves[14] = 6.; + parSCurves[15] = 10.; + + // fitLeft->SetParLimits(0,90.,170.); + parSCurves[18] = 200.; + parSCurves[19] = 230.; + parSCurves[20] = 3.; + parSCurves[21] = 15.; + // fitLeft->SetParLimits(3,150.,220.); + } + + + + else if (filename == "ProcessRawData-201502235-216") { + // Right. + if (zvalue < 80.) + { + *minRight = 120.; + *maxRight = 240.; + } + else + { + *minRight = 100.; + *maxRight = 230.; + } + + // Left. + if (zvalue < 80.) + { + *minLeft = 240.; + *maxLeft = 330.; + } + else + { + *minLeft = 230.; + *maxLeft = 320.; + } + + // Right. + parSCurves[0] = 16.; + parSCurves[1] = 160.; + parSCurves[2] = 6.; + if (zvalue < 60.) + parSCurves[3] = 12.; + else + parSCurves[3] = 10.; + + // parSCurves[4] = 10.; + // parSCurves[5] = 20.; + parSCurves[6] = 120.; + parSCurves[7] = 200.; + parSCurves[8] = 3.; + parSCurves[9] = 15.; + // parSCurves[10] = 8.; + // parSCurves[11] = 18.; + + // Left. + parSCurves[12] = 16.; + parSCurves[13] = 280.; + parSCurves[14] = 6.; + parSCurves[15] = 12.; + + // fitLeft->SetParLimits(0,90.,170.); + parSCurves[18] = 260.; + parSCurves[19] = 300.; + parSCurves[20] = 3.; + parSCurves[21] = 15.; + // fitLeft->SetParLimits(3,150.,220.); + } + + + + else if (filename == "ProcessRawData-201502253-216") { + // Right. + *minRight = 30.; + *maxRight = 140.; + + // Left. + *minLeft = 140.; + *maxLeft = 230.; + + // Right. + parSCurves[0] = 16.; + parSCurves[1] = 60.; + parSCurves[2] = 6.; + parSCurves[3] = 10.; + + // parSCurves[4] = 10.; + // parSCurves[5] = 20.; + parSCurves[6] = 20.; + parSCurves[7] = 100.; + parSCurves[8] = 3.; + parSCurves[9] = 15.; + // parSCurves[10] = 8.; + // parSCurves[11] = 18.; + + // Left. + parSCurves[12] = 16.; + parSCurves[13] = 190.; + parSCurves[14] = 6.; + parSCurves[15] = 10.; + + // fitLeft->SetParLimits(0,90.,170.); + parSCurves[18] = 170.; + parSCurves[19] = 210.; + parSCurves[20] = 3.; + parSCurves[21] = 15.; + // fitLeft->SetParLimits(3,150.,220.); + } + + return; +} + +// assignParInfoSigma has the following parameters: +// - string filename, the filename of the measurement; +// - Float_t parSigma[], the array containing the parameters of the sigma function; +// - Float_t lengthParSigma, the length of the array containing the parameters of the sigma function. +void assignParInfoSigma(string filename, Float_t parSigma[], Int_t lengthParSigma) +{ + if ((filename == "ProcessRawData-201501093-216") || (filename == "ProcessRawData-20150111-216") || (filename == "ProcessRawData-201501124-216") || (filename == "ProcessRawData-20150221-216")) { + // Sigma left. + parSigma[0] = 5.; + parSigma[1] = 600.; + parSigma[2] = 0.025; + + parSigma[3] = 0.; + parSigma[4] = 10.; + + parSigma[5] = 500.; + parSigma[6] = 700.; + + // parSigma[7] = ?.; + // parSigma[8] = ?.; + + // Sigma right. + parSigma[9] = 5.; + parSigma[10] = 600.; + parSigma[11] = 0.025; + + parSigma[12] = 0.; + parSigma[13] = 10.; + + parSigma[14] = 500.; + parSigma[15] = 700.; + + // parSigma[16] = ?.; + // parSigma[17] = ?.; + } + + else if (filename == "ProcessRawData-201502235-216") { + // Sigma left. + parSigma[0] = 5.; + parSigma[1] = 100.; + parSigma[2] = 6.; + + parSigma[3] = 0.; + parSigma[4] = 10.; + + parSigma[5] = 0.; + parSigma[6] = 200.; + + // parSigma[7] = ?.; + // parSigma[8] = ?.; + + // Sigma right. + parSigma[9] = 5.; + parSigma[10] = 100.; + parSigma[11] = 6.; + + parSigma[12] = 0.; + parSigma[13] = 10.; + + parSigma[14] = 0.; + parSigma[15] = 200.; + + // parSigma[16] = ?.; + // parSigma[17] = ?.; + } + + return; +} + +void fitSCurve(string edge, TGraph *graph, TF1 *f, Float_t parSCurves[], Int_t lengthParSCurves, Float_t *a, Float_t *mu, Float_t *sigma, Float_t *b, Float_t *ua, Float_t *umu, Float_t *usigma, Float_t *ub) { + // Set parameters and parameter limits. + if (edge == "right") { + f->SetParameter(0,parSCurves[0]); + f->SetParameter(1,parSCurves[1]); + f->SetParameter(2,parSCurves[2]); + f->SetParameter(3,parSCurves[3]); + // f->SetParLimits(0,parSCurves[4],parSCurves[5]); + f->SetParLimits(1,parSCurves[6],parSCurves[7]); + f->SetParLimits(2,parSCurves[8],parSCurves[9]); + // f->SetParLimits(3,parSCurves[10],parSCurves[11]); + } + else if (edge == "left") { + f->SetParameter(0,parSCurves[12]); + f->SetParameter(1,parSCurves[13]); + f->SetParameter(2,parSCurves[14]); + f->SetParameter(3,parSCurves[15]); + // f->SetParLimits(0,parSCurves[16],parSCurves[17]); + f->SetParLimits(1,parSCurves[18],parSCurves[19]); + f->SetParLimits(2,parSCurves[20],parSCurves[21]); + // f->SetParLimits(3,parSCurves[22],parSCurves[23]); + } + + // Fit. + graph->Fit(f,"BR"); + + // Get parameters and parameter uncertainties. + *a = f->GetParameter(0); + *mu = f->GetParameter(1); + *sigma = f->GetParameter(2); + *b = f->GetParameter(3); + + *ua = f->GetParError(0); + *umu = f->GetParError(1); + *usigma = f->GetParError(2); + *ub = f->GetParError(3); + + cout << edge << " side, a = " << *a << ", mu = " << *mu << ", sigma = " << *sigma << ", b = " << *b << endl; + + return; +} + +void fitSigma(string edge, TGraph *graph, TF1 *f, Float_t parSigma[], Int_t lengthParSigma, Float_t *q0, Float_t *q1, Float_t *q2, Float_t *uq0, Float_t *uq1, Float_t *uq2) { + // Set parameters and parameter limits. + if (edge == "left") { + f->SetParameter(0,parSigma[0]); + f->SetParameter(1,parSigma[1]); + f->SetParameter(2,parSigma[2]); + f->SetParLimits(0,parSigma[3],parSigma[4]); + f->SetParLimits(1,parSigma[5],parSigma[6]); + // f->SetParLimits(2,parSigma[7],parSigma[8]); + } + else if (edge == "right") { + f->SetParameter(0,parSigma[9]); + f->SetParameter(1,parSigma[10]); + f->SetParameter(2,parSigma[11]); + f->SetParLimits(0,parSigma[12],parSigma[13]); + f->SetParLimits(1,parSigma[14],parSigma[15]); + // f->SetParLimits(2,parSigma[16],parSigma[17]); + } + + // Fit. + f->SetLineColor(kRed); + graph->Fit(f,"BR"); + + // Get parameters and parameter uncertainties. + *q0 = f->GetParameter(0); + *q1 = f->GetParameter(1); + *q2 = f->GetParameter(2); + + *uq0 = f->GetParError(0); + *uq1 = f->GetParError(1); + *uq2 = f->GetParError(2); + + return; +} + +#endif diff --git a/Software/Tools/Style.C b/Software/Tools/Style.C index 762afa8..2f409f7 100644 --- a/Software/Tools/Style.C +++ b/Software/Tools/Style.C @@ -53,7 +53,7 @@ void DrawGraphFunc2(TCanvas *canvas, TGraph *graph, TF1 *func1, TF1 *func2, TString option = "APC", TString folder = ""); -void DrawGraphCompare(TCanvas *canvas, TMultiGraph *graph, TLegend *leg, TString title = "", TString x = "", TString y = "", TString folder = ""); +void DrawGraphCompare(TCanvas *canvas, TMultiGraph *graph, TLegend *leg, TString title = "", TString x = "", TString y = "", TString option = "APE", TString folder = ""); TLegend *CreateLegend2(TObject *obj1, TString lab1, TObject *obj2, TString lab2, TString option = "lpfw", Double_t x1 = 0.64, Double_t y1 = 0.59, Double_t x2 = 0.94, Double_t y2 = 0.89); @@ -553,14 +553,14 @@ } // DrawGraphCompare draws the "graph" graph in the "canvas" canvas and saves the result in the "folder" folder, in a pdf file named "canvas.pdf". -void DrawGraphCompare(TCanvas *canvas, TMultiGraph *graph, TLegend *leg, TString title, TString x, TString y, TString folder) { +void DrawGraphCompare(TCanvas *canvas, TMultiGraph *graph, TLegend *leg, TString title, TString x, TString y, TString option, TString folder) { TString path; path = folder; TString name = canvas->GetName(); canvas->cd(); canvas->SetTickx(1); canvas->SetTicky(1); - graph->Draw("APE"); + graph->Draw(option.Data()); leg->Draw(); // graph->SetFillColor(38); // graph->SetMarkerSize(1);