void errCheck(const char *desc="") { char fname[100]; sprintf(fname, "result%s.root", desc); TFile *inFile = TFile::Open(fname); const int debug = 1; const bool kTimeFormat = false; //const bool kTimeFormat = true; // can't seem to get the time format to work... const int kSelectNoise = 3; // 1: first measurement, 2: 2nd measurement, 3: best of 1 and 2 const int kMassive = 4; // const int kMassive = 30; // cuts on channel level: should be same as in checklog.pl const float kMinPed = 40; const float kMaxPed = 110; const float kMinRms = 0.6; const float kMaxRms = 1.3; const float kMaxRms31 = 2.0; const float kMinGain20mV = 18.8; const float kMaxGain20mV = 20.2; // constants for arrays const int kNChan = 32; const int kNQR = 26; const int kNVRef = 6; const int kNACurr = 5; const int kNSync = 8; const int kNSync2 = 2; TTree *tree = (TTree*) inFile->Get("tree"); //Declaration of leaves types //Declaration of leaves types Char_t filename[200]; Char_t datetime[100]; Int_t iCtime; Int_t iMtime; Char_t cQR[kNQR]; Int_t iChip; Int_t iSta; Float_t fVRef[kNVRef]; Float_t fVCurr[kNACurr]; Float_t fACurr[kNACurr]; Float_t fGain20mV[32]; Float_t fGain30mV[32]; Float_t fGainRT20mV[32]; Float_t fGainRT30mV[32]; Float_t fRT20mV[32]; Float_t fRT30mV[32]; Float_t fPed20mV[32]; Float_t fPed30mV[32]; Float_t fRms20mV[32]; Float_t fRms30mV[32]; Float_t fPedAna20mV[32]; Float_t fPedAna30mV[32]; Float_t fRmsAna20mV[32]; Float_t fRmsAna30mV[32]; Float_t fX20mVeven; Float_t fX20mVodd; Float_t fX30mVeven; Float_t fX30mVodd; Int_t iSync[kNSync]; Int_t iDFT; Int_t iJtag; Int_t iMem; Float_t fRingOsc; Int_t i2cErr; Int_t iSync2[2]; Int_t iMem2; Float_t fRingOsc2; Int_t i2cErr2; Float_t fPed20mV2[32]; Float_t fPed30mV2[32]; Float_t fRms20mV2[32]; Float_t fRms30mV2[32]; Float_t fPedAna20mV2[32]; Float_t fPedAna30mV2[32]; Float_t fRmsAna20mV2[32]; Float_t fRmsAna30mV2[32]; Int_t iErrCode; Int_t iRCode; // Set branch addresses. tree->SetBranchAddress("filename",filename); tree->SetBranchAddress("datetime",datetime); tree->SetBranchAddress("iCtime",&iCtime); tree->SetBranchAddress("iMtime",&iMtime); tree->SetBranchAddress("cQR",&cQR); tree->SetBranchAddress("iChip",&iChip); tree->SetBranchAddress("iSta",&iSta); tree->SetBranchAddress("fVRef",fVRef); tree->SetBranchAddress("fVCurr",fVCurr); tree->SetBranchAddress("fACurr",fACurr); tree->SetBranchAddress("fGain20mV",fGain20mV); tree->SetBranchAddress("fGain30mV",fGain30mV); tree->SetBranchAddress("fGainRT20mV",fGainRT20mV); tree->SetBranchAddress("fGainRT30mV",fGainRT30mV); tree->SetBranchAddress("fRT20mV",fRT20mV); tree->SetBranchAddress("fRT30mV",fRT30mV); tree->SetBranchAddress("fPed20mV",fPed20mV); tree->SetBranchAddress("fPed30mV",fPed30mV); tree->SetBranchAddress("fRms20mV",fRms20mV); tree->SetBranchAddress("fRms30mV",fRms30mV); tree->SetBranchAddress("fPedAna20mV",fPedAna20mV); tree->SetBranchAddress("fPedAna30mV",fPedAna30mV); tree->SetBranchAddress("fRmsAna20mV",fRmsAna20mV); tree->SetBranchAddress("fRmsAna30mV",fRmsAna30mV); tree->SetBranchAddress("fX20mVeven",&fX20mVeven); tree->SetBranchAddress("fX20mVodd",&fX20mVodd); tree->SetBranchAddress("fX30mVeven",&fX30mVeven); tree->SetBranchAddress("fX30mVodd",&fX30mVodd); tree->SetBranchAddress("iSync",iSync); tree->SetBranchAddress("iDFT",&iDFT); tree->SetBranchAddress("iJtag",&iJtag); tree->SetBranchAddress("iMem",&iMem); tree->SetBranchAddress("fRingOsc",&fRingOsc); tree->SetBranchAddress("i2cErr",&i2cErr); tree->SetBranchAddress("iSync2",iSync2); tree->SetBranchAddress("iMem2",&iMem2); tree->SetBranchAddress("fRingOsc2",&fRingOsc2); tree->SetBranchAddress("i2cErr2",&i2cErr2); tree->SetBranchAddress("fPed20mV2",fPed20mV2); tree->SetBranchAddress("fPed30mV2",fPed30mV2); tree->SetBranchAddress("fRms20mV2",fRms20mV2); tree->SetBranchAddress("fRms30mV2",fRms30mV2); tree->SetBranchAddress("fPedAna20mV2",fPedAna20mV2); tree->SetBranchAddress("fPedAna30mV2",fPedAna30mV2); tree->SetBranchAddress("fRmsAna20mV2",fRmsAna20mV2); tree->SetBranchAddress("fRmsAna30mV2",fRmsAna30mV2); tree->SetBranchAddress("iErrCode",&iErrCode); tree->SetBranchAddress("iRCode",&iRCode); // This is the loop skeleton // To read only selected branches, Insert statements like: // tree->SetBranchStatus("*",0); // disable all branches // TTreePlayer->SetBranchStatus("branchname",1); // activate branchname Long64_t nentries = tree->GetEntries(); tree->GetEntry(0); int firstTime = iCtime; tree->GetEntry(nentries-1); int lastTime = iCtime; int diffTimeSec = lastTime - firstTime; int diffTimeMin = diffTimeSec / 60; int totDiffTimeMin = diffTimeMin; cout << " diffTime : sec " << diffTimeSec << " min " << diffTimeMin << endl; const int kNSta = 2; const int kNErrBits = 15; // check for 15 different errors const char *kBitStr[] = { "FileCount", "VRef", "ACurr", "Sync", // 0x1, 0x2, 0x4, 0x8 "PedAna", "RmsAna", "Gain", "RiseTime", // 0x10, 0x20, 0x40, 0x80 "Xtalk", "RingOsc", "i2c", "Jtag", // 0x100, 0x200, 0x400, 0x800 "Mem", "DFT", "BitCheck" // 0x1000, 0x2000, 0x4000 }; const int kFirstErrBit = 2; const int kFirstErrBitVal = 2; TGraphErrors *gRmsChan[kNSta][kNChan]; int nRmsChan[kNSta][kNChan] = {0}; TGraphErrors *gGainChan[kNSta][kNChan]; int nGainChan[kNSta][kNChan] = {0}; TH2F *hGainRms[kNSta]; TH2F *hGainGainRT[kNSta]; TH2F *hRTGain[kNSta]; TH2F *hRTGainRT[kNSta]; TH2F *hRTRms[kNSta]; const int kNChips = 100000; // max number of chips so far, for any station const int kChipOffset = 100000; int locChip = 0; int nTestsChip[kNChips] = {0}; for (locChip = 0; locChipSetMarkerStyle(20); gRmsChan[ista][ichan]->SetTitle( Form("RMS vs Time - Station %d Chan %d", ista+1, ichan) ); nRmsChan[ista][ichan] = 0; gGainChan[ista][ichan] = new TGraphErrors(nentries); gGainChan[ista][ichan]->SetMarkerStyle(20); gGainChan[ista][ichan]->SetTitle( Form("Gain vs Time - Station %d Chan %d", ista+1, ichan) ); nGainChan[ista][ichan] = 0; } hGainRms[ista] = new TH2F( Form("hGainRmsSta%d", ista+1), Form("Gain vs Rms - Station %d", ista+1), 200, 0, 2, 200, 17.5, 22.5 ); hGainGainRT[ista] = new TH2F( Form("hGainGainRTSta%d", ista+1), Form("Gain vs GainRT - Station %d", ista+1), 200, 17.5, 22.5, 200, 17.5, 22.5 ); hRTGain[ista] = new TH2F( Form("hRTGainSta%d", ista+1), Form("RiseTime vs Gain - Station %d", ista+1), 200, 17.5, 22.5, 200, 150, 200 ); hRTGainRT[ista] = new TH2F( Form("hRTGainRTSta%d", ista+1), Form("RiseTime vs GainRT - Station %d", ista+1), 200, 17.5, 22.5, 200, 150, 200 ); hRTRms[ista] = new TH2F( Form("hRTRmsSta%d", ista+1), Form("RiseTime vs Rms - Station %d", ista+1), 200, 0, 2, 200, 150, 200 ); } int minChip = 999999; int maxChip = 0; int nbytes = 0; vector errorCodes[kNChips]; vector testStation[kNChips]; int nFailRms = 0; int nOKRms = 0; int nTotRms = 0; for (Long64_t i=0; iGetEntry(i); if (debug>1) cout << " entry i " << i << " iSta " << iSta << endl; ista = iSta - 1; if (ista<0 || ista>1) { cout << " bad entry i " << i << " ista " << ista << endl; } locChip = iChip - kChipOffset; if ( (locChip>=0) && (locChip < kNChips) ) { // right range of chips if (minChip>locChip) minChip = locChip; if (maxChipkMaxRms) ) nChanRmsErr++; if ( (mynoise>kMaxRms) ) nChanRmsErr++; if (kTimeFormat) { gRmsChan[ista][ichan]->SetPoint(nRmsChan[ista][ichan], mytime, mynoise); gGainChan[ista][ichan]->SetPoint(nGainChan[ista][ichan], mytime, fGain20mV[ichan]); } else { gRmsChan[ista][ichan]->SetPoint(nRmsChan[ista][ichan], diffTimeMin, mynoise); gGainChan[ista][ichan]->SetPoint(nGainChan[ista][ichan], diffTimeMin, fGain20mV[ichan]); } gRmsChan[ista][ichan]->SetPointError(nRmsChan[ista][ichan], 0.3, 0.01); nRmsChan[ista][ichan]++; gGainChan[ista][ichan]->SetPointError(nGainChan[ista][ichan], 0.3, 0.25); nGainChan[ista][ichan]++; hGainRms[ista]->Fill(mynoise, fGain20mV[ichan]); hGainGainRT[ista]->Fill(fGainRT20mV[ichan], fGain20mV[ichan]); hRTGain[ista]->Fill(fGain20mV[ichan], fRT20mV[ichan]); hRTGainRT[ista]->Fill(fGainRT20mV[ichan], fRT20mV[ichan]); hRTRms[ista]->Fill(mynoise, fRT20mV[ichan]); } if (nChanRmsErr>0) nFailRms++; if (nChanRmsErr==0) nOKRms++; nTotRms++; } } nTests[ista]++; if (iErrCode > kFirstErrBitVal) { // skip FileCount & VRef checks nFail[ista]++; for (ibit=kFirstErrBit; ibit 0 ) { nFailBit[ista][ibit]++; } } if ( ((iErrCode & 0x00f0)>0) && ((iErrCode & 0x0008)==0) ) { // some channel issue: check pedestal, gain and rms values, and not any Sync errors int nChanErr = 0; for (ichan=0; ichankMaxPed) || (fRmsAna20mV[ichan]kMaxRms)) || ((ichan>=30) && (fRmsAna20mV[ichan]>kMaxRms31)) ) || (fGain20mV[ichan]kMaxGain20mV) ) { nChanErr++; } } if (nChanErr < kMassive) { // not a chip with many channel errors for (ichan=0; ichankMaxPed) || (fRmsAna20mV[ichan]kMaxRms)) || ((ichan>=30) && (fRmsAna20mV[ichan]>kMaxRms31)) ) || (fGain20mV[ichan]kMaxGain20mV) ) { nFailChan[ista][ichan]++; } } } } // channel error } // some error } // entries printf("kSelectNoise %d nTotRms %d nFailRms %d nOKRms %d \n", kSelectNoise, nTotRms, nFailRms, nOKRms); const int kNChanLines = 8; int chanPerLine = kNChan / kNChanLines; int iline = 0; // report for (ista=0; ista 0) { int nOK = nTests[ista] - nFail[ista]; float percPass = (100.0 * nOK) / nTests[ista]; printf("\nStation %d nTests %d nFail %d -- pass rate %5.2f %% \n", ista+1, nTests[ista], nFail[ista], percPass); for (ibit=kFirstErrBit; ibit 0) { float percFail = (100.0 * nFailBit[ista][ibit]) / nTests[ista]; printf(" & %3d (%5.2f \\%%)", nFailBit[ista][ibit], percFail); } } printf("\\\\ \n"); } printf(" \\end{tabular}\n \\end{center} \n \\end{table} \n"); printf("\nminChip %d maxChip %d\n", minChip+kChipOffset, maxChip+kChipOffset); int nTestedChips = 0; int nOKOnly = 0; int nBadOnly = 0; int nMixed = 0; // report also on test result mismatches int nMismatchBit[kNSta][kNErrBits] = {0}; for (ista=0; ista 0) { nErrCodes = (int) errorCodes[locChip].size(); if (nTestsChip[locChip] == nErrCodes) { nTestedChips++; int nOK = 0; int nBad = 0; for (itest=0; itest 0) && (nBad == 0) ) nOKOnly++; else if ( (nOK == 0) && (nBad > 0) ) nBadOnly++; else nMixed++; if (nErrCodes > 1) { // something to compare between itest = 1; int firstErrCode = errorCodes[locChip][0]; while (itest < nErrCodes) { if (errorCodes[locChip][itest] != firstErrCode) { if (debug>1) printf("iChip %d ErrCode mismatch : firstErr 0x%04x vs 0x%04x for itest %d\n", iChip, firstErrCode, errorCodes[locChip][itest], itest); nErrCodeMismatch++; // which bits are different between the two tests? use bitwise XOR ^ int diff = firstErrCode ^ errorCodes[locChip][itest]; // which bits changed from the first test? and second int changeFirst = diff & firstErrCode; ista = testStation[locChip][0]; for (ibit=kFirstErrBit; ibit 0 ) { nMismatchBit[ista][ibit]++; } } // and for the other test int changeOther = diff & errorCodes[locChip][itest]; ista = testStation[locChip][itest]; for (ibit=kFirstErrBit; ibit 0 ) { nMismatchBit[ista][ibit]++; } } } // code mismatch itest++; } } } else { printf("iChip %d nErr mismatch : nTests %d nErrorCodes %d\n", iChip, nTestsChip[locChip], nErrCodes); nErrMismatch++; } } } printf("nErrMismatch %d nErrCodeMismatch %d\n", nErrMismatch, nErrCodeMismatch); printf("nTestedChips %d nOKOnly %d nBadOnly %d nMixed %d\n", nTestedChips, nOKOnly, nBadOnly, nMixed); float norm = 100.0 / nTestedChips; printf("=> OK with one pass: %5.2f %%, OK after two passes: %5.2f %% \n", norm*nOKOnly, norm*(nOKOnly + nMixed)); for (ista=0; ista 0) { printf("\nStation %d - bit mismatches to other tests \n", ista+1); for (ibit=kFirstErrBit; ibitcd(); c1->SetLogz(0); hGainRms[ista]->GetXaxis()->SetTitle("RMS (ADC)"); hGainRms[ista]->GetYaxis()->SetTitle("Gain (mV/fC)"); hGainRms[ista]->Draw("colz"); c1->Modified(); sprintf(name, "png/%s/liny/gain_vs_rms_sta%d.png", desc, ista+1); c1->SaveAs(name); hGainGainRT[ista]->GetXaxis()->SetTitle("GainRT (mV/fC)"); hGainGainRT[ista]->GetYaxis()->SetTitle("Gain (mV/fC)"); hGainGainRT[ista]->Draw("colz"); c1->Modified(); sprintf(name, "png/%s/liny/gain_vs_gainrt_sta%d.png", desc, ista+1); c1->SaveAs(name); hRTGain[ista]->GetXaxis()->SetTitle("Gain (mV/fC)"); hRTGain[ista]->GetYaxis()->SetTitle("RiseTime (ns)"); hRTGain[ista]->Draw("colz"); c1->Modified(); sprintf(name, "png/%s/liny/risetime_vs_gain_sta%d.png", desc, ista+1); c1->SaveAs(name); hRTGainRT[ista]->GetXaxis()->SetTitle("GainRT (mV/fC)"); hRTGainRT[ista]->GetYaxis()->SetTitle("RiseTime (ns)"); hRTGainRT[ista]->Draw("colz"); c1->Modified(); sprintf(name, "png/%s/liny/risetime_vs_gainrt_sta%d.png", desc, ista+1); c1->SaveAs(name); hRTRms[ista]->GetXaxis()->SetTitle("RMS (ADC)"); hRTRms[ista]->GetYaxis()->SetTitle("RiseTime (ns)"); hRTRms[ista]->Draw("colz"); c1->Modified(); sprintf(name, "png/%s/liny/risetime_vs_rms_sta%d.png", desc, ista+1); c1->SaveAs(name); c1->SetLogz(0); for (ichan=0; ichan 2) { // skip empty plots TF1 *funcRms; if (kTimeFormat) { funcRms = new TF1("funcRms","[0]", firstTime, lastTime); } else { funcRms = new TF1("funcRms","[0]", 0, totDiffTimeMin); } c1->cd(); gRmsChan[ista][ichan]->Fit("funcRms","RQ"); fprintf(foutRms, "%4d %3d %3.2f\n", ista+1, ichan, funcRms->GetParameter(0)); if ( (ichan%2) == 0 ) { meanEvenRms[ista] += funcRms->GetParameter(0); nEvenRms[ista] ++; } else { meanOddRms[ista] += funcRms->GetParameter(0); nOddRms[ista] ++; } if (kTimeFormat) { gRmsChan[ista][ichan]->GetXaxis()->SetTimeDisplay(1); gRmsChan[ista][ichan]->GetXaxis()->SetTimeOffset(firstTime); gRmsChan[ista][ichan]->GetXaxis()->SetTimeFormat("%a:%H:%M"); } else gRmsChan[ista][ichan]->GetXaxis()->SetTitle("Time (min)"); gRmsChan[ista][ichan]->GetYaxis()->SetTitle("RMS (ADC)"); gRmsChan[ista][ichan]->Draw("A*"); c1->Modified(); sprintf(name, "png/%s/liny/rmsChan_sta%d_chan%02d.png", desc, ista+1, ichan); c1->SaveAs(name); if (funcRms) delete funcRms; } if (nGainChan[ista][ichan] > 2) { // skip empty plots TF1 *funcGain; if (kTimeFormat) { funcGain = new TF1("funcGain","[0]", firstTime, lastTime); } else { funcGain = new TF1("funcGain","[0]", 0, totDiffTimeMin); } c1->cd(); gGainChan[ista][ichan]->Fit("funcGain","RQ"); fprintf(foutGain, "%4d %3d %3.2f\n", ista+1, ichan, funcGain->GetParameter(0)); if ( (funcGain->GetParameter(0) > 1) && (funcGain->GetParameter(0) < 100) ) { if ( (ichan%2) == 0 ) { meanEvenGain[ista] += funcGain->GetParameter(0); nEvenGain[ista] ++; } else { meanOddGain[ista] += funcGain->GetParameter(0); nOddGain[ista] ++; } } if (kTimeFormat) { gGainChan[ista][ichan]->GetXaxis()->SetTimeDisplay(1); gGainChan[ista][ichan]->GetXaxis()->SetTimeOffset(firstTime); gGainChan[ista][ichan]->GetXaxis()->SetTimeFormat("%a:%H:%M"); } else gGainChan[ista][ichan]->GetXaxis()->SetTitle("Time (min)"); gGainChan[ista][ichan]->GetYaxis()->SetTitle("RMS (ADC)"); gGainChan[ista][ichan]->Draw("A*"); c1->Modified(); sprintf(name, "png/%s/liny/gainChan_sta%d_chan%02d.png", desc, ista+1, ichan); c1->SaveAs(name); if (funcGain) delete funcGain; } } } fprintf(foutRms, "ista type n rms --- averages:\n"); for (ista=0; ista 0) fprintf(foutRms, "%4d even %2d %3.2f\n", ista+1, nEvenRms[ista], meanEvenRms[ista]/nEvenRms[ista] ); if (nOddRms[ista] > 0) fprintf(foutRms, "%4d odd %2d %3.2f\n", ista+1, nOddRms[ista], meanOddRms[ista]/nOddRms[ista] ); } fclose(foutRms); fprintf(foutGain, "ista type n gain --- averages:\n"); for (ista=0; ista 0) fprintf(foutGain, "%4d even %2d %3.2f\n", ista+1, nEvenGain[ista], meanEvenGain[ista]/nEvenGain[ista] ); if (nOddGain[ista] > 0) fprintf(foutGain, "%4d odd %2d %3.2f\n", ista+1, nOddGain[ista], meanOddGain[ista]/nOddGain[ista] ); } fclose(foutGain); }