void fitStudy( const int ichipVer=4, const char *filename="calibWithTree.root" ) { // acceptable limits for P0 and P1 (in ADC units) const double minP0 = -15; const double maxP0 = 15; const double minP1 = 8; // looser for V3 // const double minP1 = 9; // V4 const double maxP1 = 10.2; const int minNDF = 5; const int maxNDF = 11; // wider limits to catch most, if not all, P0 and P1 results const double minP0All = -50; const double maxP0All = 50; const double minP1All = -1; const double maxP1All = 20; const int minNDFAll = 0; const int maxNDFAll = 19; const double ADC2mV = 2.15; // conv. factor char name[100]; char outdir[100]; sprintf(outdir, "png/calib/V%d", ichipVer); char chipVerStr[50]; sprintf(chipVerStr, "V%d", ichipVer); char suffix1[20]; char suffix2[20]; sprintf(suffix1, "pdf"); sprintf(suffix2, "png"); const bool regen_corrplots = false; // const bool regen_corrplots = true; const int kNChips = 1100; // max number of chips for any version so far int iChipOffset = 0; // V2 if (ichipVer == 3) { iChipOffset = 2000; // V3 } if (ichipVer == 4) { iChipOffset = 6000; // V4 } int nOK[kNChips] = {0}; double meanP1[kNChips] = {0}; double rmsP1[kNChips] = {0}; int nFail[kNChips] = {0}; TFile *f = new TFile(filename); cout << " reading file " << filename << endl; TTree *tree = (TTree*) f->Get("tree"); //Declaration of leaves types Int_t iChip; Int_t iChan; Float_t fP0; Float_t fP0Err; Float_t fP1; Float_t fP1Err; Float_t fChi2; Int_t iNDF; // Set branch addresses. tree->SetBranchAddress("iChip",&iChip); tree->SetBranchAddress("iChan",&iChan); tree->SetBranchAddress("fP0",&fP0); tree->SetBranchAddress("fP0Err",&fP0Err); tree->SetBranchAddress("fP1",&fP1); tree->SetBranchAddress("fP1Err",&fP1Err); tree->SetBranchAddress("fChi2",&fChi2); tree->SetBranchAddress("iNDF",&iNDF); int nentries = tree->GetEntries(); // first we do a loop for a channel-by-channel comparisons for P1 TH2F *h2 = new TH2F("h2","Fit Par 1 vs Chan #", 32, -0.5, 31.5, 100, minP1*ADC2mV, maxP1*ADC2mV); TProfile *hp1 = new TProfile("hp1","Fit Par 1 vs Chan #", 32, -0.5, 31.5); cout << " nentries " << nentries << endl; Long64_t nbytes = 0; int minChip = kNChips; int maxChip = 0; int iEntry[kNChips][32] = {0}; int locChip = 0; for (int i=0; iGetEntry(i); locChip = iChip - iChipOffset; if ( (locChip>=0) && (locChip < kNChips) ) { // right range of chips if (minChip>locChip) minChip = locChip; if (maxChipFill(iChan, fP1*ADC2mV); hp1->Fill(iChan, fP1*ADC2mV); } } } // we now know our range of chip numbers int nChips = maxChip - minChip + 1; // calculate a correction factor for each channel double dcorr[32] = {0}; TF1 *func0 = new TF1("func0","[0]", 0, 32); hp1->Fit("func0","RQ"); cout << " func0 " << func0->GetParameter(0) << endl; int ichip = 0; int ich = 0; // chan ofstream fout; fout.open("condcorr.txt"); for (ich = 0; ich<32; ich++) { dcorr[ich] = func0->GetParameter(0) / hp1->GetBinContent(ich+1); cout << " ich " << ich << " center " << hp1->GetBinCenter(ich+1) << " cont " << hp1->GetBinContent(ich+1) << " dcorr " << dcorr[ich] << endl; fout << " " << ich << " " << hp1->GetBinContent(ich+1) << " " << dcorr[ich] << endl; } fout.close(); // exit(1); return; // tmp debug // now, we'll do a second loop, for corrected values... TH1F *h1Corr = new TH1F("h1Corr","Fit Par 1 (Corr)", 100, minP1*ADC2mV, maxP1*ADC2mV); TH2F *h2Corr = new TH2F("h2Corr","Fit Par 1 (Corr) vs Chan #", 32, -0.5, 31.5, 100, minP1*ADC2mV, maxP1*ADC2mV); TProfile *hp1Corr = new TProfile("hp1Corr","Fit Par 1 (Corr, mV) vs Chan #", 32, -0.5, 31.5); TH2F *h2CorrChip = new TH2F("h2CorrChip","Fit Par 1 (Corr, mV) vs Chip #", nChips, minChip-0.5 + iChipOffset, maxChip+0.5 + iChipOffset, 100, minP1*ADC2mV, maxP1*ADC2mV); TProfile *hp1CorrChip = new TProfile("hp1CorrChip","Fit Par 1 (Corr) vs Chip #", nChips, minChip-0.5 + iChipOffset, maxChip+0.5 + iChipOffset); TH2F *h2p0Chip = new TH2F("h2p0Chip","Fit Par 0 vs Chip #", nChips, minChip-0.5 + iChipOffset, maxChip+0.5 + iChipOffset, 100, minP0, maxP0); TProfile *hpp0Chip = new TProfile("hpp0Chip","Fit Par 0 vs Chip #", nChips, minChip-0.5 + iChipOffset, maxChip+0.5 + iChipOffset); TH2F *h2CorrChipAll = new TH2F("h2CorrChipAll","Fit Par 1 (Corr) vs Chip #", nChips, minChip-0.5 + iChipOffset, maxChip+0.5 + iChipOffset, 100, minP1All*ADC2mV, maxP1All*ADC2mV); TProfile *hp1CorrChipAll = new TProfile("hp1CorrChipAll","Fit Par 1 (Corr. mV) vs Chip #", nChips, minChip-0.5 + iChipOffset, maxChip+0.5 + iChipOffset); TH2F *h2p0ChipAll = new TH2F("h2p0ChipAll","Fit Par 0 vs Chip #", nChips, minChip-0.5 + iChipOffset, maxChip+0.5 + iChipOffset, 100, minP0, maxP0); TProfile *hpp0ChipAll = new TProfile("hpp0ChipAll","Fit Par 0 vs Chip #", nChips, minChip-0.5 + iChipOffset, maxChip+0.5 + iChipOffset); // adding some plots for P0 and NDF also (didn't see any useful chi2 cuts yet) TH2F *h2CorrP0All = new TH2F("h2CorrP0All","Fit Par 1 (Corr) vs Fit Par 0 - All", 100, minP0All, maxP0All, 100, minP1All*ADC2mV, maxP1All*ADC2mV); TH2F *h2NDFP0All = new TH2F("h2NDFP0All","NDF vs Fit Par 0 - All", 100, minP0All, maxP0All, maxNDFAll - minNDFAll + 1, minNDFAll-0.5, maxNDFAll+0.5); TH2F *h2CorrP0 = new TH2F("h2CorrP0","Fit Par 1 (Corr) vs Fit Par 0 - Cut", 100, minP0, maxP0, 100, minP1*ADC2mV, maxP1*ADC2mV); TH2F *h2NDFP0 = new TH2F("h2NDFP0","NDF vs Fit Par 0 - Cut", 100, minP0, maxP0, maxNDF - minNDF + 1, minNDF-0.5, maxNDF+0.5); // also possibly redo plots for individual chips TH1F *h1CorrChip[kNChips]; char id[20]; char description[100]; for (ichip = minChip; ichip<=maxChip; ichip++) { sprintf(id, "h1CorrChip%d", ichip); sprintf(description, "Fit Par 1 : Chip %d", ichip + iChipOffset); h1CorrChip[ichip] = new TH1F(id, description, 32, -0.5, 31.5); h1CorrChip[ichip]->GetXaxis()->SetTitle("Chan #"); h1CorrChip[ichip]->GetYaxis()->SetTitle("Fit Par1"); int nSum = 0; double sum = 0; double sum2 = 0; for (ich = 0; ich<32; ich++) { if (iEntry[ichip][ich] > 0) { nbytes += tree->GetEntry(iEntry[ichip][ich]); locChip = iChip - iChipOffset; h2CorrChipAll->Fill(locChip + iChipOffset, fP1 * dcorr[iChan] * ADC2mV); hp1CorrChipAll->Fill(locChip + iChipOffset, fP1 * dcorr[iChan] * ADC2mV); h2p0ChipAll->Fill(locChip + iChipOffset, fP0); hpp0ChipAll->Fill(locChip + iChipOffset, fP0); h2CorrP0All->Fill(fP0, fP1 * dcorr[iChan] * ADC2mV); h2NDFP0All->Fill(fP0, iNDF); sum += fP1 * dcorr[iChan]; sum2 += (fP1 * dcorr[iChan]) * (fP1 * dcorr[iChan]); nSum ++; if ( (minP0Fill(fP1 * dcorr[iChan] * ADC2mV); h2Corr->Fill(iChan, fP1 * dcorr[iChan] * ADC2mV); hp1Corr->Fill(iChan, fP1 * dcorr[iChan] * ADC2mV); h2CorrChip->Fill(locChip + iChipOffset, fP1 * dcorr[iChan] * ADC2mV); hp1CorrChip->Fill(locChip + iChipOffset, fP1 * dcorr[iChan] * ADC2mV); h2p0Chip->Fill(locChip + iChipOffset, fP0); hpp0Chip->Fill(locChip + iChipOffset, fP0); h2CorrP0->Fill(fP0, fP1 * dcorr[iChan] * ADC2mV); h2NDFP0->Fill(fP0, iNDF); nOK[locChip]++; } else { nFail[locChip]++; } if (locChip>=minChip && locChip<=maxChip) { h1CorrChip[locChip]->SetBinContent(iChan+1, fP1 * dcorr[iChan] * ADC2mV); h1CorrChip[locChip]->SetBinError(iChan+1, fP1Err * dcorr[iChan] * ADC2mV); } } } if (nSum>0) { meanP1[locChip] = sum / nSum; rmsP1[locChip] = TMath::Sqrt(TMath::Abs(sum2/nSum - meanP1[locChip]*meanP1[locChip])); } } cout << " histos filled " << endl; hp1Corr->Fit("func0","RQ"); cout << " func0 " << func0->GetParameter(0) << endl; TCanvas* c1 = new TCanvas("c1", "c1", 900, 600); TText* text = new TText(); text->SetTextSize(0.1); text->SetTextColor(2); float xpos = 0.65; float ypos = 0.65; c1->cd(); h1Corr->SetMarkerStyle(20); h1Corr->GetXaxis()->SetTitle("Fit Par 1 (Corr, mV/fC)"); h1Corr->GetYaxis()->SetTitle("Yield"); h1Corr->SetTitle("Fit Par 1 (Corr, mV/fC)"); h1Corr->Draw(); text->DrawTextNDC(xpos, ypos, chipVerStr); c1->Modified(); sprintf(name, "%s/fitpar1_corr.%s", outdir, suffix1); c1->SaveAs(name); sprintf(name, "%s/fitpar1_corr.%s", outdir, suffix2); c1->SaveAs(name); gStyle->SetOptStat(0); c1->cd(); hp1->SetMarkerStyle(20); hp1->GetYaxis()->SetTitle("Fit Par 1 (mV/fC)"); hp1->GetXaxis()->SetTitle("Chan #"); hp1->SetTitle("Fit Par 1 (mV/fC) vs Chan #"); hp1->Draw(); text->DrawTextNDC(xpos, ypos, chipVerStr); c1->Modified(); sprintf(name, "%s/fitpar1_vs_chan.%s", outdir, suffix1); c1->SaveAs(name); sprintf(name, "%s/fitpar1_vs_chan.%s", outdir, suffix2); c1->SaveAs(name); c1->cd(); hp1Corr->SetMarkerStyle(20); hp1Corr->GetYaxis()->SetTitle("Fit Par 1 (Corr, mV/fC)"); hp1Corr->GetXaxis()->SetTitle("Chan #"); hp1Corr->SetTitle("Fit Par 1 (Corr, mV/fC) vs Chan #"); hp1Corr->Draw(); text->DrawTextNDC(xpos, ypos, chipVerStr); c1->Modified(); sprintf(name, "%s/fitpar1_corr_vs_chan.%s", outdir, suffix1); c1->SaveAs(name); sprintf(name, "%s/fitpar1_corr_vs_chan.%s", outdir, suffix2); c1->SaveAs(name); c1->cd(); hp1CorrChip->SetMinimum(minP1 * ADC2mV); hp1CorrChip->SetMaximum(maxP1 * ADC2mV); hp1CorrChip->SetMarkerStyle(20); hp1CorrChip->GetYaxis()->SetTitle("Fit Par 1 (Corr, mV/fC)"); hp1CorrChip->GetXaxis()->SetTitle("Chip #"); hp1CorrChip->SetTitle("Fit Par 1 (Corr, mV/fC) vs Chip #"); hp1CorrChip->Draw(); text->DrawTextNDC(xpos, ypos, chipVerStr); c1->Modified(); sprintf(name, "%s/fitpar1_corr_vs_chip.%s", outdir, suffix1); c1->SaveAs(name); sprintf(name, "%s/fitpar1_corr_vs_chip.%s", outdir, suffix2); c1->SaveAs(name); c1->cd(); hp1CorrChipAll->SetMarkerStyle(20); hp1CorrChipAll->GetYaxis()->SetTitle("Fit Par 1 (Corr, All, mV/fC)"); hp1CorrChipAll->GetXaxis()->SetTitle("Chip #"); hp1CorrChipAll->SetTitle("Fit Par 1 (Corr, All, mV/fC) vs Chip #"); hp1CorrChipAll->Draw(); text->DrawTextNDC(xpos, ypos, chipVerStr); c1->Modified(); sprintf(name, "%s/fitpar1_corr_vs_chip_all.%s", outdir, suffix1); c1->SaveAs(name); sprintf(name, "%s/fitpar1_corr_vs_chip_all.%s", outdir, suffix2); c1->SaveAs(name); c1->cd(); hpp0Chip->SetMinimum(minP0); hpp0Chip->SetMaximum(maxP0); hpp0Chip->SetMarkerStyle(20); hpp0Chip->GetYaxis()->SetTitle("Fit Par 0"); hpp0Chip->GetXaxis()->SetTitle("Chip #"); hpp0Chip->SetTitle("Fit Par 0 vs Chip #"); hpp0Chip->Draw(); text->DrawTextNDC(xpos, ypos, chipVerStr); c1->Modified(); sprintf(name, "%s/fitpar0_vs_chip.%s", outdir, suffix1); c1->SaveAs(name); sprintf(name, "%s/fitpar0_vs_chip.%s", outdir, suffix2); c1->SaveAs(name); c1->cd(); hpp0ChipAll->SetMinimum(minP0*2); hpp0ChipAll->SetMaximum(maxP0*2); hpp0ChipAll->SetMarkerStyle(20); hpp0ChipAll->GetYaxis()->SetTitle("Fit Par 0 (All)"); hpp0ChipAll->GetXaxis()->SetTitle("Chip #"); hpp0ChipAll->SetTitle("Fit Par 0 (All) vs Chip #"); hpp0ChipAll->Draw(); text->DrawTextNDC(xpos, ypos, chipVerStr); c1->Modified(); sprintf(name, "%s/fitpar0_all_vs_chip.%s", outdir, suffix1); c1->SaveAs(name); sprintf(name, "%s/fitpar0_all_vs_chip.%s", outdir, suffix2); c1->SaveAs(name); c1->cd(); h2->GetYaxis()->SetTitle("Fit Par 1 (mV/fC)"); h2->GetXaxis()->SetTitle("Chan #"); h2->SetTitle("Fit Par 1 (mV/fC) vs Chan #"); h2->Draw("colz"); text->DrawTextNDC(xpos, ypos, chipVerStr); c1->Modified(); sprintf(name, "%s/h2_fitpar1_vs_chan.%s", outdir, suffix1); c1->SaveAs(name); sprintf(name, "%s/h2_fitpar1_vs_chan.%s", outdir, suffix2); c1->SaveAs(name); c1->cd(); h2Corr->GetYaxis()->SetTitle("Fit Par 1 (Corr, mV/fC)"); h2Corr->GetXaxis()->SetTitle("Chan #"); h2Corr->SetTitle("Fit Par 1 (Corr, mV/fC) vs Chan #"); h2Corr->Draw("colz"); text->DrawTextNDC(xpos, ypos, chipVerStr); c1->Modified(); sprintf(name, "%s/h2_fitpar1_corr_vs_chan.%s", outdir, suffix1); c1->SaveAs(name); sprintf(name, "%s/h2_fitpar1_corr_vs_chan.%s", outdir, suffix2); c1->SaveAs(name); c1->cd(); h2CorrChip->GetYaxis()->SetTitle("Fit Par 1 (Corr, mV/fC)"); h2CorrChip->GetXaxis()->SetTitle("Chip #"); h2CorrChip->SetTitle("Fit Par 1 (Corr, mV/fC) vs Chip #"); h2CorrChip->Draw("colz"); text->DrawTextNDC(xpos, ypos, chipVerStr); c1->Modified(); sprintf(name, "%s/h2_fitpar1_corr_vs_chip.%s", outdir, suffix1); c1->SaveAs(name); sprintf(name, "%s/h2_fitpar1_corr_vs_chip.%s", outdir, suffix2); c1->SaveAs(name); c1->cd(); h2CorrChipAll->GetYaxis()->SetTitle("Fit Par 1 (Corr, All, mV/fC)"); h2CorrChipAll->GetXaxis()->SetTitle("Chip #"); h2CorrChipAll->SetTitle("Fit Par 1 (Corr, All, mV/fC) vs Chip #"); h2CorrChipAll->Draw("box"); text->DrawTextNDC(xpos, ypos, chipVerStr); c1->Modified(); sprintf(name, "%s/h2_fitpar1_corr_vs_chip_all.%s", outdir, suffix1); c1->SaveAs(name); sprintf(name, "%s/h2_fitpar1_corr_vs_chip_all.%s", outdir, suffix2); c1->SaveAs(name); c1->cd(); h2p0Chip->GetYaxis()->SetTitle("Fit Par 0"); h2p0Chip->GetXaxis()->SetTitle("Chip #"); h2p0Chip->SetTitle("Fit Par 0 vs Chip #"); h2p0Chip->Draw("colz"); text->DrawTextNDC(xpos, ypos, chipVerStr); c1->Modified(); sprintf(name, "%s/h2_fitpar0_vs_chip.%s", outdir, suffix1); c1->SaveAs(name); sprintf(name, "%s/h2_fitpar0_vs_chip.%s", outdir, suffix2); c1->SaveAs(name); c1->cd(); h2p0ChipAll->GetYaxis()->SetTitle("Fit Par 0 (All)"); h2p0ChipAll->GetXaxis()->SetTitle("Chip #"); h2p0ChipAll->SetTitle("Fit Par 0 (All) vs Chip #"); h2p0ChipAll->Draw("colz"); text->DrawTextNDC(xpos, ypos, chipVerStr); c1->Modified(); sprintf(name, "%s/h2_fitpar0_all_vs_chip.%s", outdir, suffix1); c1->SaveAs(name); sprintf(name, "%s/h2_fitpar0_all_vs_chip.%s", outdir, suffix2); c1->SaveAs(name); // P0 corr plots c1->cd(); h2CorrP0All->GetYaxis()->SetTitle("Fit Par 1 (Corr, All, mV/fC)"); h2CorrP0All->GetXaxis()->SetTitle("Fit Par 0"); h2CorrP0All->SetTitle("Fit Par 1 (Corr, All, mV/fC) vs Par 0"); h2CorrP0All->Draw("colz"); text->DrawTextNDC(xpos, ypos, chipVerStr); c1->Modified(); sprintf(name, "%s/h2_fitpar1_corr_vs_par0_all.%s", outdir, suffix1); c1->SaveAs(name); sprintf(name, "%s/h2_fitpar1_corr_vs_par0_all.%s", outdir, suffix2); c1->SaveAs(name); c1->cd(); h2NDFP0All->GetYaxis()->SetTitle("NDF (All)"); h2NDFP0All->GetXaxis()->SetTitle("Fit Par 0"); h2NDFP0All->SetTitle("NDF (All) vs Par 0"); h2NDFP0All->Draw("colz"); text->DrawTextNDC(xpos, ypos, chipVerStr); c1->Modified(); sprintf(name, "%s/h2_ndf_vs_par0_all.%s", outdir, suffix1); c1->SaveAs(name); sprintf(name, "%s/h2_ndf_vs_par0_all.%s", outdir, suffix2); c1->SaveAs(name); c1->cd(); h2CorrP0->GetYaxis()->SetTitle("Fit Par 1 (Corr, Cut, mV/fC)"); h2CorrP0->GetXaxis()->SetTitle("Fit Par 0"); h2CorrP0->SetTitle("Fit Par 1 (Corr, Cut, mV/fC) vs Par 0"); h2CorrP0->Draw("colz"); text->DrawTextNDC(xpos, ypos, chipVerStr); c1->Modified(); sprintf(name, "%s/h2_fitpar1_corr_vs_par0.%s", outdir, suffix1); c1->SaveAs(name); sprintf(name, "%s/h2_fitpar1_corr_vs_par0.%s", outdir, suffix2); c1->SaveAs(name); c1->cd(); h2NDFP0->GetYaxis()->SetTitle("NDF (Cut)"); h2NDFP0->GetXaxis()->SetTitle("Fit Par 0"); h2NDFP0->SetTitle("NDF (Cut) vs Par 0"); h2NDFP0->Draw("colz"); text->DrawTextNDC(xpos, ypos, chipVerStr); c1->Modified(); sprintf(name, "%s/h2_ndf_vs_par0.%s", outdir, suffix1); c1->SaveAs(name); sprintf(name, "%s/h2_ndf_vs_par0.%s", outdir, suffix2); c1->SaveAs(name); if (regen_corrplots) { for (locChip = minChip; locChip<=maxChip; locChip++) { c1->cd(); if ( h1CorrChip[locChip]->GetBinContent(1) > 1 ) { h1CorrChip[locChip]->Draw(); iChip = locChip + iChipOffset; sprintf(outdir, "png/calib/V%d/%d", ichipVer, iChip); c1->Modified(); sprintf(name, "%s/amp_sig_chip_%03d_fitpar1_corr.%s", outdir, iChip, suffix1); c1->SaveAs(name); sprintf(name, "%s/amp_sig_chip_%03d_fitpar1_corr.%s", outdir, iChip, suffix2); c1->SaveAs(name); } } } // Finally, the reporting... cout << endl << " here is a list of good chips (nOK == 32 && nFail == 0) - no failed fits: " << endl; int ngood = 0; for (locChip=minChip; locChip<=maxChip; locChip++) { if (nOK[locChip]==32 && nFail[locChip]==0) { iChip = locChip + iChipOffset; printf("iChip %d meanP1 %4.3f rmsP1 %4.3f\n", iChip, meanP1[locChip], rmsP1[locChip]); ngood++; } } cout << " - number of chips with all good fits: " << ngood << endl; cout << endl << " here is a list of grey zone chips (nOK != 32 && nFail == 0) - no failed fits but wrong number of channels: " << endl; int ngrey = 0; for (locChip=minChip; locChip<=maxChip; locChip++) { if (nOK[locChip]!=32 && nOK[locChip]>0 && nFail[locChip]==0) { iChip = locChip + iChipOffset; printf("iChip %d nOK %02d nFail %02d meanP1 %4.3f rmsP1 %4.3f\n", iChip, nOK[locChip], nFail[locChip], meanP1[locChip], rmsP1[locChip]); ngrey++; } } cout << " - number of chips with all good fits but not right number of channels: " << ngrey << endl; cout << endl << " next is a list of somewhat problematic chips, with 1-3 failed fits: " << endl; int nproblem = 0; for (locChip=minChip; locChip<=maxChip; locChip++) { if (nFail[locChip]>0 && nFail[locChip]<4) { iChip = locChip + iChipOffset; printf("iChip %d nOK %02d nFail %02d meanP1 %4.3f rmsP1 %4.3f\n", iChip, nOK[locChip], nFail[locChip], meanP1[locChip], rmsP1[locChip]); nproblem++; } } cout << " - number of somewhat problematic chips : " << nproblem << endl; cout << endl << " finally a list of more problematic chips, with at least 4 failed fits: " << endl; nproblem = 0; for (locChip=minChip; locChip<=maxChip; locChip++) { if (nFail[locChip]>3) { iChip = locChip + iChipOffset; printf("iChip %d nOK %02d nFail %02d meanP1 %4.3f rmsP1 %4.3f\n", iChip, nOK[locChip], nFail[locChip], meanP1[locChip], rmsP1[locChip]); nproblem++; } } cout << " - number of more problematic chips : " << nproblem << endl; }