void FirstContour() { TString dir = gSystem->UnixPathName(__FILE__); dir.ReplaceAll("FirstContour.C","../hsimple.C"); dir.ReplaceAll("/./","/"); if (!gInterpreter->IsLoaded(dir.Data())) gInterpreter->LoadMacro(dir.Data()); TFile *file = (TFile*)gROOT->ProcessLineFast("hsimple(1)"); if (!file) return; TTree *ntuple = (TTree*)file->Get("ntuple"); TCanvas *c1 = new TCanvas("c1","Contours",10,10,800,600); gStyle->SetPalette(1); ntuple->Draw("py:px","px*px+py*py < 20", "contz,list"); //we must call Update to force the canvas to be painted. When //painting the contour plot, the list of contours is generated //and a reference to it added to the Root list of special objects c1->Update(); TCanvas *c2 = new TCanvas("c2","First contour",100,100,800,600); TObjArray *contours = (TObjArray*)gROOT->GetListOfSpecials()->FindObject("contours"); if (!contours) return; TList *lcontour1 = (TList*)contours->At(0); if (!lcontour1) return; TGraph *gc1 = (TGraph*)lcontour1->First(); if (!gc1) return; if (gc1->GetN() < 10) return; gc1->SetMarkerStyle(21); gc1->Draw("alp"); //We make a TCutG object with the array obtained from this graph TCutG *cutg = new TCutG("cutg",gc1->GetN(),gc1->GetX(),gc1->GetY()); //We create a polymarker object with npmax points. const Int_t npmax = 50000; TPolyMarker *pm = new TPolyMarker(npmax); Int_t np = 0; while(1) { Double_t x = -4 +8*gRandom->Rndm(); Double_t y = -4 +8*gRandom->Rndm(); if (cutg->IsInside(x,y)) { pm->SetPoint(np,x,y); np++; if (np == npmax) break; } } pm->Draw(); }
void monplots(TString runno, TString filename, TString module, TWISMacroResult & results) { Double_t maxenerms = 1.5; Double_t maxpedrms = 0.8; TString defdir = "castor/cern.ch/user/t/tilebeam/commissioning/"; TString deffile = "tiletb_"+runno+"_MonoCis.0.root"; if(filename == ""){ filename = defdir+deffile; } TFile *f = TFile::Open(filename); TTree *t = (TTree*)f->Get("TileRec/h1000"); Float_t efit[48], pedfit[48]; Int_t cispar[16]; TString vare = "Efit"+module; TString varp = "Pedfit"+module; TString varc = "Cispar"; t->SetBranchAddress(vare, &efit); t->SetBranchAddress(varp, &pedfit); t->SetBranchAddress(varc, &cispar); Int_t nevt = t->GetEntries(); Int_t nevt_for_2D = (nevt>MAXEVT_FOR_2D) ? MAXEVT_FOR_2D : nevt; Int_t i, j; /********** MonExpert **********/ Int_t samp[48][9]; TString var = "Sample"+module; t->SetBranchAddress(var, &samp); TH1F *h[48]; TH2F *c[48]; TString hname, htitle; TString cname, ctitle; /*******************************/ t->GetEntry(100); Double_t charge = 2*4.096*cispar[6]*cispar[7]/1023; Double_t uphist = charge +20; Double_t minmean = charge - 10; TH1F *hene[48], *hped[48]; TString nene, tene, nped, tped; for(j=0;j<48;j++){ nene = "ene"; nene += j; tene = "Energy "; tene += j; hene[j]=new TH1F(nene, tene, 100, 0, uphist); nped = "ped"; nped += j; tped = "Pedestal "; tped += j; hped[j]=new TH1F(nped, tped, 100, 0, 100); /********** MonExpert **********/ hname = "Amp"; hname += j; htitle="Sample 3, ch"; htitle += j; h[j]=new TH1F(hname, htitle, 100, 0, 200); cname = "amptime"; cname += j; ctitle="Sample3vsTime,ch"; ctitle += j; c[j]=new TH2F(cname, ctitle, nevt_for_2D/10, 0, nevt_for_2D, 100, 0, 200); /*******************************/ } for(Int_t i=0;i<nevt;i++) { t->GetEntry(i); for(j=0;j<48;j++) { hene[j]->Fill(efit[j]); hped[j]->Fill(pedfit[j]); /********** MonExpert **********/ if (i % 20 == 0 && i < MAXEVT_FOR_2D) { h[j]->Fill(samp[j][3]); c[j]->Fill(i, samp[j][3]); } /*******************************/ } } Double_t chan[48], meanene[48], rmsene[48], meanped[48], rmsped[48]; vector<Int_t> bad; Double_t badMeanEneX[48], badRMSEneX[48], badPedRMSX[48]; Double_t badMeanEneY[48], badRMSEneY[48], badPedRMSY[48]; Int_t NbadMeanEne = 0, NbadRMSEne = 0, NbadPedRMS = 0; for(j=0;j<48;j++){ chan[j]=j; if(j != 31 && j!=32 && j!=43){ meanene[j]=hene[j]->GetMean(); if (meanene[j] < minmean) { badMeanEneX[NbadMeanEne] = j; badMeanEneY[NbadMeanEne] = meanene[j]; NbadMeanEne++; } rmsene[j]=hene[j]->GetRMS(); if (rmsene[j] > maxenerms) { badRMSEneX[NbadRMSEne] = j; badRMSEneY[NbadRMSEne] = rmsene[j]; NbadRMSEne++; } meanped[j]=hped[j]->GetMean(); rmsped[j]=hped[j]->GetRMS(); if (rmsped[j] > maxpedrms) { badPedRMSX[NbadPedRMS] = j; badPedRMSY[NbadPedRMS] = rmsped[j]; NbadPedRMS++; } if(meanene[j] < minmean || rmsene[j] > maxenerms || rmsped[j] > maxpedrms) bad.push_back(j); } else { meanene[j]=0.0; rmsene[j]=0.0; meanped[j]=0.0; rmsped[j]=0.0; } } TLine *lmean = new TLine(0, minmean, 50, minmean); lmean->SetLineColor(2); TLine *lenerms = new TLine(0, maxenerms, 50, maxenerms); lenerms->SetLineColor(2); TLine *lpedrms = new TLine(0, maxpedrms, 50, maxpedrms); lpedrms->SetLineColor(2); TPolyMarker *badMeanEne = new TPolyMarker(NbadMeanEne, badMeanEneX, badMeanEneY, "p"); badMeanEne->SetMarkerColor(2); badMeanEne->SetMarkerStyle(21); TPolyMarker *badRMSEne = new TPolyMarker(NbadRMSEne, badRMSEneX, badRMSEneY, "p"); badRMSEne->SetMarkerColor(2); badRMSEne->SetMarkerStyle(21); TPolyMarker *badPedRMS = new TPolyMarker(NbadPedRMS, badPedRMSX, badPedRMSY, "p"); badPedRMS->SetMarkerColor(2); badPedRMS->SetMarkerStyle(21); TGraph *genemean = new TGraph(48, chan, meanene); genemean->SetMarkerStyle(21); genemean->SetTitle("Mean Energy"); genemean->GetXaxis()->SetTitle("Channel"); TGraph *generms = new TGraph(48, chan, rmsene); generms->SetMarkerStyle(21); generms->SetTitle("RMS Energy"); generms->GetXaxis()->SetTitle("Channel"); TGraph *gpedmean = new TGraph(48, chan, meanped); gpedmean->SetMarkerStyle(21); gpedmean->SetTitle("Mean Pedestal"); gpedmean->GetXaxis()->SetTitle("Channel"); TGraph *gpedrms = new TGraph(48, chan, rmsped); gpedrms->SetMarkerStyle(21); gpedrms->SetTitle("RMS Pedestal"); gpedrms->GetXaxis()->SetTitle("Channel"); TCanvas *cmon= new TCanvas("cmon", "MonoCis", 700, 500); cmon->Divide(2,2); cmon->cd(1); genemean->Draw("AP"); lmean->Draw(); badMeanEne->Draw(); cmon->cd(2); generms->Draw("AP"); lenerms->Draw(); badRMSEne->Draw(); cmon->cd(3); gpedmean->Draw("AP"); cmon->cd(4); gpedrms->Draw("AP"); lpedrms->Draw(); badPedRMS->Draw(); cout.precision(3); //cout<<"Number of bad channels is "<<bad.size()<<"<br />"<<endl; results.addValue("Number of bad channels", bad.size()); if(bad.size() > 0) { //cout<<"Channel"<<'\t'<<"Mean energy"<<'\t'<<"RMS energy"<<'\t'<<"RMS Monocis"<<"<br />"<<endl; TString table; table = "<table class=\"main\" xmlns=\"http://www.w3.org/1999/xhtml\">\n"; table += "<tr><th>Channel</th><th>Mean energy</th><th>RMS energy</th><th>RMS Monocis</th></tr>\n"; for(i=0;i<bad.size();i++) { Int_t ch = bad.at(i); //cout<<ch<<"\t"<<meanene[i]<<"\t\t"<<rmsene[i]<<"\t\t"<<rmsped[i]<<"<br />"<<endl; table += "<tr><td>"; table += ch; table += "</td><td>"; table += meanene[i]; table += "</td><td>"; table += rmsene[i]; table +="</td><td>"; table += rmsped[i]; table +="</td></tr>\n"; } table += "</table>\n"; results.addTable("Bad channels", table); } TString moduleDir = "LB" + module + "/"; TString filenameps = outputDir + moduleDir +"r"+runno+"_"+module+"_MonoCis.ps"; TString filenamepng = outputDir + moduleDir +"r"+runno+"_"+module+"_MonoCis.png"; cmon->Print(filenameps); cmon->Print(filenamepng); TString plotFilename = outputWebDir + moduleDir + "r"+runno+"_"+module+"_MonoCis.png"; TString plotPsFilename = outputWebDir + moduleDir + "r"+runno+"_"+module+"_MonoCis.ps"; TString completeModuleName = "LB" + module; wis2Tilecomm(runno.Data(), completeModuleName.Data(), plotFilename.Data(), results); wis2Tilecomm(runno.Data(), completeModuleName.Data(), plotPsFilename.Data(), results); TString linkTitle = "Send results to QC Sheet"; TString linkHref = "http://atlasmonitor.web.cern.ch/atlasmonitor/saveValuesExample.jsp?module="; linkHref += "LB" + module + "&run=" + runno + "&badChannels="; linkHref += bad.size(); //results.addLink(linkTitle, linkHref); results.addPlot("", plotFilename); /********** MonExpert **********/ TCanvas *c1 = new TCanvas("c1", "Amp,1-24", 900, 900); c1->Divide(4,6); TCanvas *c5 = new TCanvas("c5", "Amp,25-48", 900, 900); c5->Divide(4,6); TCanvas *c3 = new TCanvas("c3", "AmpTime,1-24", 900, 900); c3->Divide(4,6); TCanvas *c7 = new TCanvas("c7", "AmpTime,25-48",900,900); c7->Divide(4,6); for(j = 0; j < 24; j++) { c1->cd(j+1); gPad->SetLogy(); h[j]->Draw(); c5->cd(j+1); gPad->SetLogy(); h[j+24]->Draw(); c3->cd(j+1); c[j]->Draw(); c7->cd(j+1); c[j+24]->Draw(); } // Saving plots to disk filenamepng = outputDir + "expert/" + moduleDir + "r" + runno + "_" + module + "_MonoCis_Expert_Amp1-24.png"; c1->Print(filenamepng); filenamepng = outputDir + "expert/" + moduleDir + "r" + runno + "_" + module + "_MonoCis_Expert_Amp25-48.png"; c5->Print(filenamepng); filenamepng = outputDir + "expert/" + moduleDir + "r" + runno + "_" + module + "_MonoCis_Expert_AmpTime1-24.png"; c3->Print(filenamepng); filenamepng = outputDir + "expert/" + moduleDir + "r" + runno + "_" + module + "_MonoCis_Expert_AmpTime25-48.png"; c7->Print(filenamepng); completeModuleName = "LB" + module; // Saving plots to Results Database (TileComm Analysis) TString plot1 = outputWebDir + "expert/" + moduleDir + "r"+runno+"_"+module+"_MonoCis_Expert_Amp1-24.png"; wis2Tilecomm(runno.Data(), completeModuleName.Data(), plot1.Data(), results); TString plot2 = outputWebDir + "expert/" + moduleDir + "r"+runno+"_"+module+"_MonoCis_Expert_Amp25-48.png"; wis2Tilecomm(runno.Data(), completeModuleName.Data(), plot2.Data(), results); TString plot3 = outputWebDir + "expert/" + moduleDir + "r"+runno+"_"+module+"_MonoCis_Expert_AmpTime1-24.png"; wis2Tilecomm(runno.Data(), completeModuleName.Data(), plot3.Data(), results); TString plot4 = outputWebDir + "expert/" + moduleDir + "r"+runno+"_"+module+"_MonoCis_Expert_AmpTime25-48.png"; wis2Tilecomm(runno.Data(), completeModuleName.Data(), plot4.Data(), results); // Showing links in macro results page results.addValue("MonoCis Expert Plots", ""); results.addLink("Amp Channels 1-24", plot1); results.addLink("Amp Channels 25-48", plot2); results.addLink("AmpTime Channels 1-24", plot3); results.addLink("AmpTime Channels 25-48", plot4); /*******************************/ }
void laserCalibration( char* filename = "frascatirun", //input file int filenum = 1081, //file number int channel = 3, //trace channel int flagChannel = 5, //laser flag channel Double_t entriesN = 10, //number of entries for prcessing int sleep = 10, //sleep time between 2 processed entries, helpful for viewing traces bool gui = true //enable or disable trace visualization ) { caen_5742 caen; Int_t nbins = 1024; Double_t entries = entriesN; Int_t bin; TCanvas *c1 = new TCanvas("c1","frascatirun",900,700); c1->Divide(1,2); c1->cd(1); TGraph* g = new TGraph(); TH1F* lmPeaks = new TH1F("lm","Peaks Ratio", 1000, 0, 5000); TH1F* d = new TH1F("d","",nbins,0,nbins); TH1F* back = new TH1F("Back","",nbins,0,nbins); // input file char fname[100]=0; sprintf(fname,"%s_0%i.root",filename,filenum); TFile* infile = new TFile(fname); TTree *t = (TTree*) infile->Get("t"); t->SetBranchAddress("caen_5742", &caen.system_clock); t->Print(); if(entriesN<=0) entries = t->GetEntries(); //out file char foutname[100]=0; int lm=0; if (channel ==3)lm=1; if (channel ==4)lm=2; sprintf(foutname,"./calibration/LM%i_out_0%i.root",lm,filenum); outfile = new TFile(foutname,"RECREATE"); outTree = new TTree("LM","frascatirun output"); calibTree = new TTree("LM_cal","frascatirun output"); outTree->Branch("LM_PX1",&fPositionX1,"PX1/D"); outTree->Branch("LM_PX2",&fPositionX2,"PX2/D"); outTree->Branch("LM_PY1",&fPositionY1,"PY1/D"); outTree->Branch("LM_PY2",&fPositionY2,"PY2/D"); //outTree->Branch("baseline",baseline,"baseline[1024]/F"); outTree->Branch("time",&timeline,"time/D"); outTree->Branch("LM_P2_Integral",&integralP2,"IP2/D"); calibTree->Branch("LM_P2_Integral_mean",&integralP2_mean,"IP2_mean/D"); calibTree->Branch("LM_P2_Integral_mean_error",&integralP2_mean_error,"IP2_mean_error/D"); calibTree->Branch("LM_P2_Integral_sigma",&integralP2_sigma,"IP2_sigma/D"); calibTree->Branch("LM_P2_Integral_sigma_error",&integralP2_sigma_error,"IP2_sigma_error/D"); /************************************** * read entries ************************************** */ for (int j = 0; j < entries; ++j){ gSystem->Sleep (sleep); t->GetEntry(j); //TRIGGER SELECTION if(caen.trace[flagChannel][400]>1000 && caen.trace[flagChannel][800]<3000){ timeline = caen.system_clock; /************************************** * Peaks estimation ************************************** */ for (int i = 0; i < nbins; ++i){ g->SetPoint(i, i, caen.trace[channel][i]); } Double_t y_max = TMath::MaxElement(g->GetN(),g->GetY()); Float_t * source = new Float_t[nbins]; Float_t * dest = new Float_t[nbins]; for (int i = 0; i < nbins; ++i){ source[i]=y_max-caen.trace[channel][i]; g->SetPoint(i, i, source[i]); } //Use TSpectrum to find the peak candidates TSpectrum *s = new TSpectrum(); Int_t nfound = s->SearchHighRes(source, dest, nbins, 3, 2, kTRUE, 2, kFALSE, 5); /************************************** * Background estimation ************************************** */ Int_t ssize = nbins; Int_t numberIterations = 20; Int_t direction = s->kBackIncreasingWindow; Int_t filterOrder = s->kBackOrder2; bool smoothing = kFALSE; Int_t smoothWindow = s->kBackSmoothing3; bool compton = kFALSE; for (int i = 0; i < nbins; ++i) baseline[i] = source[i]; s->Background(baseline, ssize, numberIterations, direction, filterOrder, smoothing, smoothWindow, compton); /************************************** * Peaks and integral estimation ************************************** */ Double_t px[2], py[2]; for (int i = 0; i < nbins; ++i) dest[i] = source[i]-baseline[i]; if(nfound==2){ bin = s->GetPositionX()[0]; fPositionX1 = bin; fPositionY1 = dest[bin]; px[0] = bin; py[0] = dest[bin]; bin = s->GetPositionX()[1]; fPositionX2 = bin; fPositionY2 = dest[bin]; px[1] = bin; py[1] = dest[bin]; } int posxa=6; int posxb=9; switch (filenum){ case 1081: posxa=6; posxb=9; break; case 1082: posxa=5; posxb=7; break; case 1083: posxa=5; posxb=8; break; case 1084: posxa=5; posxb=7; break; case 1085: posxa=5; posxb=7; break; case 1086: posxa=5; posxb=5; break; case 1087: posxa=4; posxb=4; break; case 1088: posxa=3; posxb=4; break; case 1089: posxa=3; posxb=3; break; default: posxa=6; posxb=9; } integralP2 = g->Integral (fPositionX2-posxa,fPositionX2+posxb); /************************************** * print and update the canvas ************************************** */ if(gui==true){ TH1F* gh = g->GetHistogram(); gh->FillN(nbins,g->GetX(),g->GetY()); g->Draw(); TPolyMarker* pm = (TPolyMarker*)gh->GetListOfFunctions()->FindObject("TPolyMarker"); if (pm) { gh->GetListOfFunctions()->Remove(pm); delete pm; } pm = new TPolyMarker(nfound, px, py); gh->GetListOfFunctions()->Add(pm); pm->SetMarkerStyle(23); pm->SetMarkerColor(kBlue); pm->SetMarkerSize(1.3); for (i = 0; i < nbins; i++) d->SetBinContent(i,dest[i]); d->SetLineColor(kRed); d->Draw("SAME"); for (i = 0; i < nbins; i++) back->SetBinContent(i,baseline[i]); back->SetLineColor(kGreen); back->Draw("SAME"); c1->Update(); } /************************************** * Fill tree and peaks data Histogram ************************************** */ if(nfound==2) { lmPeaks->Fill(integralP2); outTree->Fill(); } //printf("time= %d, posx1= %d, posy1= %d\n",time, fPositionX1, fPositionY1); //printf("time= %d, posx2= %d, posy2= %d\n",time, fPositionX2, fPositionY2); //for (int i=0;i<nbins;i++) printf("time = %d\n",baseline[i]); } } /************************************** * switch to the bottom pan and Draw Histogram ************************************** */ c1->cd(2); //lmPeaks->SetAxisRange(TMath::MinElement(entries,binmin),TMath::MaxElement(entries,binmax)+100); //lmPeaks->SetAxisRange(0,3000); lmPeaks->Fit("gaus"); integralP2_mean = lmPeaks->GetFunction("gaus")->GetParameter(1); integralP2_sigma = lmPeaks->GetFunction("gaus")->GetParameter(2); integralP2_mean_error = lmPeaks->GetFunction("gaus")->GetParError(1); integralP2_sigma_error = lmPeaks->GetFunction("gaus")->GetParError(2); //printf("mean = %f\n",integralP2_mean); //printf("sigma = %f\n",integralP2_sigma); calibTree->Fill(); lmPeaks->Draw(); c1->Update(); outfile->cd(); gROOT->GetList()->Write(); outTree->Write(); calibTree->Write(); outfile->Close(); }
//-------------------------------------- //function to calculate sampling factors std::pair<Double_t,Double_t> g4_sample(int snum, Double_t energy, bool do_pion, bool do_show, bool do_print=false, bool set_val=true){ Sample* sp = sample_map[snum]; if(!sp) { std::cout << "Sample " << snum << " is not loaded." << std::endl; return std::pair<Double_t,Double_t>(0.,0.); } //select correct file std::string fpre = sp->fpre; if(do_pion) fpre += "_pion"; else fpre += "_elec"; //make filenames std::stringstream drawname, fname, piname; fname << sp->dir << "/" << fpre << "_" << energy << "gev_10k.root"; if(do_pion) piname << "#pi^{-} " << energy << " GeV"; else piname << "e^{-} " << energy << " GeV"; //open file and tree TFile* _file; _file = TFile::Open((fname.str()).c_str()); TTree* totalTree = (TTree*)_file->Get("Total"); //get histo from tree (no display) //define mip as sam_ecal*ecal < 1 gev = 1000 mev (for pions in HCAL) if(sp->det==Hcal) drawname << "(hcal+" << sp->zeroWt << "*zero)/1000>>hsam(200)"; else drawname << "(ecal)/1000>>hsam(200)"; totalTree->Draw((drawname.str()).c_str(),"","hist goff"); TH1F* hsam = (TH1F*)gDirectory->Get("hsam"); //use parameters from histo to start fit TSpectrum* spec = new TSpectrum(5); spec->Search(hsam,5,"nodraw goff"); Float_t* xpos = spec->GetPositionX(); Float_t* ypos = spec->GetPositionY(); Double_t m = xpos[0]; Double_t me = hsam->GetMeanError(); Double_t N = hsam->GetEntries(); std::stringstream s_mean; s_mean.precision(3); Double_t f = energy/m; Double_t f_err = energy*(me/(m*m)); s_mean << f << " #pm " << f_err; TPolyMarker* pm = new TPolyMarker(1, xpos, ypos); hsam->GetListOfFunctions()->Add(pm); pm->SetMarkerStyle(23); pm->SetMarkerColor(kRed); pm->SetMarkerSize(1.3); std::cout.precision(6); std::cout << "f_" << (do_pion ? "pion" : "elec") << " = " << f << " +/- " << f_err << std::endl; //plotting and printing if (do_show){ TCanvas* can = new TCanvas("sample","sample",700,500); can->cd(); TPad* pad = new TPad("graph","",0,0,1,1); pad->SetMargin(0.12,0.05,0.15,0.05); pad->Draw(); pad->cd(); //formatting hsam->SetTitle(""); hsam->GetXaxis()->SetTitle("Energy [GeV]"); //hsam->SetStats(kTRUE); //gStyle->SetOptStat("mr"); hsam->SetLineWidth(2); hsam->SetLineColor(kBlack); hsam->GetYaxis()->SetTitleSize(32/(pad->GetWh()*pad->GetAbsHNDC())); hsam->GetYaxis()->SetLabelSize(28/(pad->GetWh()*pad->GetAbsHNDC())); hsam->GetXaxis()->SetTitleSize(32/(pad->GetWh()*pad->GetAbsHNDC())); hsam->GetXaxis()->SetLabelSize(28/(pad->GetWh()*pad->GetAbsHNDC())); hsam->GetYaxis()->SetTickLength(12/(pad->GetWh()*pad->GetAbsHNDC())); hsam->GetXaxis()->SetTickLength(12/(pad->GetWh()*pad->GetAbsHNDC())); hsam->Draw(); std::stringstream Nname; Nname << "N = " << N; //determine placing of pave Double_t xmin; if (m/((hsam->GetXaxis()->GetXmax() + hsam->GetXaxis()->GetXmin())/2) < 1) xmin = 0.65; else xmin = 0.2; //legend TPaveText *pave = new TPaveText(xmin,0.65,xmin+0.2,0.85,"NDC"); pave->AddText((piname.str()).c_str()); pave->AddText((Nname.str()).c_str()); pave->AddText("Peak sampling factor:"); pave->AddText((s_mean.str()).c_str()); pave->SetFillColor(0); pave->SetBorderSize(0); pave->SetTextFont(42); pave->SetTextSize(0.05); pave->Draw("same"); if(do_print) { std::stringstream oname; oname << pdir << "/" << fpre << "_sample_" << energy << "gev_peak.png"; can->Print((oname.str()).c_str(),"png"); } } else _file->Close(); //store value in sample if(set_val){ if(do_pion) sp->sam_pion = f; else sp->sam_elec = f; } return std::pair<Double_t,Double_t>(f,f_err); }