/***************************************************************************** * Project: CMS TIB/TOB Silicon Testing * Package: * Authors: * Stephen Levy (SL), levys@slac.stanford.edu * Riccardo Ranieri, ranieri@fi.infn.it * History: * 05-Apr-2004 Macro Version 3.0.0 - Automatic recognisement of nChip, border chip channels are excluded from the bad channel summary if and only if they are noisy * CMS Week March 2004 bugfix to run with 6 chips modules * Tracker Week February 2004 changes in labels, minor fixes to run with Root 4.00.01 * 10-Sep-2003 CM Removed Gain Plots, added PeakTime cuts * 31-Mar-2003 SL Created initial version * 24-Apr-2003 SL Update (major rework) * 31-Apr-2003 SL * Make summary ascii for PeakOn,DecOn * Read in separate cuts for PeakOn,DecOn from single config file * Include pulseheight stats in ascii file * 07-May-2003 SL * Add plots taken in all modes for a given test to one canvas * Reading a recordNum of -1 from configFile means the latest Record * will be used * Change chip numbering convention in summary ascii file (1,512) * * Description: * Macro to make gain, noise, pedestal, pulseheight, pinhole, etc., * plots from a root file created with Aachen ARCS software 7.0 * which is used to test CMS TIB/TOB silicon modules/hybrids. The ARCS * software may be downloaded from: * http://www.physik.rwth-aachen.de/group/IIIphys/CMS/tracker/en/index.html * * PLEASE NOTE: This macro will _not_ work with ARCS software * versions prior to release 6.0 beta. * * Takes name of configuration ascii file as only required argument. * Format of configuration ascii file is as follows: * * RootFileInfo * * * * * # * PedestalCuts * * PeakOn * * * DecOn * * * # * NoiseCuts * * PeakOn * * * * * DecOn * * * * * # * GainCuts * * PeakOn * * * * * DecOn * * * * * # * PinholeCuts * * PeakOn * * * DecOn * * * # * PulseHeightCuts * * PeakOn * * * DecOn * * * * The macro will search the configuration file for the string * 'RootFileInfo' and then it will proceed to read in 4 lines whose * meaning are specified above. For each set of cuts, the macro looks * for the tag line (eg, 'GainCuts'). Then it reads whether the cuts * will be Absolute or Percentage cuts. It needs to find 'PeakOn' and * the expected cuts and then 'DecOn' and the expected cuts (there are * different numbers of cuts defined for each test). The comment * lines (designated #) are aesthetic only and not required. * * When the same module is tested more than once, the Aachen software * stores the results in separate TDirectories of the same root file * called RecordX, where X is an integer. This integer is supplied in * the fourth line below RootFileInfo in the config file. Using a * value of -1 in this field will retrieve RecordX_{max} where X_{max} * is the largest integer (less than 1000) for which a Record exists. * * Conventions: * The macro looks for noise, gain, pedestal, noise, and pulseheight * plots taken in the PeakInvOn, DecInvOn, PeakInvOff, DecInvOff * mode. It searches for the pinhole test plots taken in the * PeakInvOff mode since this seems to be the only way to take the * test with the arcs 6.0 beta version. Failure to find these hists * should not result in a crash -- just no output plot. * * Specifying a recordNum of -1 causes latest record to be used (see * above). * * Percentage cuts should be specified as a decimal. * * Running: * One can run the macro from a unix command line (assuming root is * installed) as follows: * * unix> root -b -l -q 'arcs_macro_6_1.cc("configTestA.dat","CTA",0)' * * where the example configuration file is named configTestA.dat. * Note that the second argument "CTA" is optional -- it is a string * that will be appended to the ascii output file and hist names for * convenience. The third integer argument is also optional and will * output useful debug information to the screen if it is non-zero. * * Output: * Example of output files when using command line shown above and * reading in root file "module_XXXX.root" which has hists in Record2 * h_pedestal_module_XXXX_Rec2_CTA_pctCut.eps * h_pulseheight_module_XXXX_Rec2_CTA_eps * h_noise_module_XXXX_Rec2_CTA_pctCut.eps * h_gainSlope_module_XXXX_Rec2_CTA_pctCut.eps * h_gainChiSq_module_XXXX_Rec2_CTA_pctCut.eps * h_gainOffset_module_XXXX_Rec2_CTA_pctCut.eps * h_pinhole_module_XXXX_Rec2_CTA_pctCut.eps * Summary_module_XXXX_Rec2_PeakOn_CTA.dat * Summary_module_XXXX_Rec2_DecOn_CTA.dat * * The histogram names may have "pctCut" replaced by "absCut" if * absolute cuts are specified in the configuration file instead of * percentage cuts. * ******************************************************************************/ #include // ------------------ // Global definitions // ------------------ const Int_t max_nChip(6), nChanPerChip(128); Int_t nChip; enum modeType{ PeakOn=1, PeakOff=2, DecOn=3, DecOff=4 }; modeType mode; const char* rrVersion = "3.0.0"; // header vars const char *defChar = "Unknown"; const char *date=defChar; const char *modName=defChar; const char *oper=defChar; const char *testCenter=defChar; const char *swVer=defChar; Int_t recordNum; Double_t yTitleOffset(1.2); // cut vars peak on Double_t minPedCutPk(-999.), maxPedCutPk(-999.); Double_t minGainCutPk(-999.), maxGainCutPk(-999.); Double_t minNoiseCutPk(-999.), maxNoiseCutPk(-999.); Double_t minPeakTimeCutPk(-999.), maxPeakTimeCutPk(-999.); Double_t minOSGainCutPk(-999.),maxPHGainCutPk(-999.); Double_t maxLowPHCutPk(-999.), maxHighPHCutPk(-999.); Double_t minPulseCutPk(-999.), maxPulseCutPk(-999.); Double_t minOneSensNoiseCutPk(-999.), minTwoSensNoiseCutPk(-999.); Double_t minOneSensPeakTimeCutPk(-999.), minTwoSensPeakTimeCutPk(-999.); // cut vars dec on Double_t minPedCutDc(-999.), maxPedCutDc(-999.); Double_t minGainCutDc(-999.), maxGainCutDc(-999.); Double_t minOSGainCutDc(-999.),maxPHGainCutDc(-999.); Double_t maxLowPHCutDc(-999.), maxHighPHCutDc(-999.); Double_t minPulseCutDc(-999.), maxPulseCutDc(-999.); Double_t minOneSensNoiseCutDc(-999.), minTwoSensNoiseCutDc(-999.); Double_t minNoiseCutDc(-999.), maxNoiseCutDc(-999.); Double_t minOneSensPeakTimeCutDc(-999.), minTwoSensPeakTimeCutDc(-999.); Double_t minPeakTimeCutDc(-999.), maxPeakTimeCutDc(-999.); // hist borders Double_t pedHistMin(0.0), pedHistMax(130.); Double_t noiseHistMin(0.1), noiseHistMax(4.8); Double_t peaktimeHistMin(-100.), peaktimeHistMax(20.0); Double_t gainHistMin(0.9), gainHistMax(1.5); Double_t xMinLab(0.6),yMinLab(0.9),xMaxLab(0.9),yMaxLab(1.0); // arrays to store cut results Int_t pedStatPkOn[nChanPerChip*max_nChip], pedStatDcOn[nChanPerChip*max_nChip]; Int_t pedStatPkOff[nChanPerChip*max_nChip], pedStatDcOff[nChanPerChip*max_nChip]; Int_t noiStatPkOn[nChanPerChip*max_nChip], noiStatDcOn[nChanPerChip*max_nChip]; Int_t noiStatPkOff[nChanPerChip*max_nChip], noiStatDcOff[nChanPerChip*max_nChip]; Int_t peaktimeStatPkOn[nChanPerChip*max_nChip], peaktimeStatDcOn[nChanPerChip*max_nChip]; Int_t peaktimeStatPkOff[nChanPerChip*max_nChip], peaktimeStatDcOff[nChanPerChip*max_nChip]; Int_t gainStatPkOn[nChanPerChip*max_nChip], gainStatDcOn[nChanPerChip*max_nChip]; Int_t gainStatPkOff[nChanPerChip*max_nChip], gainStatDcOff[nChanPerChip*max_nChip]; Int_t pulseStatPkOn[nChanPerChip*max_nChip], pulseStatDcOn[nChanPerChip*max_nChip]; Int_t pulseStatPkOff[nChanPerChip*max_nChip], pulseStatDcOff[nChanPerChip*max_nChip]; Int_t phStatPkOff[nChanPerChip*max_nChip]; // bad channel type storage Int_t badchan[nChanPerChip*max_nChip]; Int_t badchanpkoff[nChanPerChip*max_nChip]; Int_t badchanpkon[nChanPerChip*max_nChip]; Int_t badchandcoff[nChanPerChip*max_nChip]; Int_t badchandcon[nChanPerChip*max_nChip]; // cut strings TString noiseCutType, pedCutType, gainCutType, phCutType, pulseCutType,peaktimeCutType; // status histograms TH1F h_stat_pkon("h_stat_pkon", "Status peakOn", nChanPerChip*max_nChip,1.,nChanPerChip*max_nChip+1.0); TH1F h_stat_pkoff("h_stat_pkoff","Status peakOff",nChanPerChip*max_nChip,1.,nChanPerChip*max_nChip+1.0); TH1F h_stat_dcon("h_stat_dcon", "Status decOn", nChanPerChip*max_nChip,1.,nChanPerChip*max_nChip+1.0); TH1F h_stat_dcoff("h_stat_dcoff","Status decOff", nChanPerChip*max_nChip,1.,nChanPerChip*max_nChip+1.0); // ------------------ // Begin macro // ------------------ arcs_macro(const char *configFile="ARCS_TIB.dat", const char* label="", Int_t verbose=0) { TStopwatch watch; watch.Start(); initArrays(); // --- open configFile ifstream datafile; datafile.open(configFile); if ( !datafile.good() ) { cout << endl << "arcs_macro: ERROR: configFile " << configFile << " unreadable; ABORT" << endl << endl; return; } char *tagname = "RootFileInfo"; Int_t len=100; Int_t j; char line[100]; Bool_t tag = kFALSE; while(!tag){ if ( datafile.eof() || !datafile.good() ) break ; datafile.getline(line,len); TString fline(line); tag = ( fline.Contains(tagname) ); } TString rootFile, inDir, outDir; TString modeName; // --- read initialization if (tag) { char temp[256]; datafile >> temp; inDir = temp; datafile >> temp; rootFile = temp; datafile >> temp; outDir = temp; datafile >> recordNum; cout << endl; cout << "--- Found tagname '" << tagname << "' in configFile " << configFile << endl; cout << Form("%25s","inDir = ") << inDir.Data() << endl; cout << Form("%25s","rootFile = ") << rootFile.Data() << endl; cout << Form("%25s","outDir = ") << outDir.Data() << endl; cout << Form("%25s","recordNum = ") << recordNum << endl << endl; } else { cout << "arcs_macro: ERROR : Could not find tag " << tagname << " in confileFile " << configFile << ": ABORT" << endl; return; } // --- read PedestalCuts tagname = "PedestalCuts"; tag = kFALSE; while (!tag) { if ( datafile.eof() || !datafile.good() ) break ; datafile.getline(line,len); TString fline(line); tag = ( fline.Contains(tagname) ); } if ( tag ) { char temp[256]; datafile >> temp; pedCutType = temp; if ( !isValCutType(pedCutType) ) return; datafile >> temp; modeName = temp; if ( !isValMode(modeName,modeType::PeakOn) ) return; datafile >> minPedCutPk; datafile >> maxPedCutPk; datafile >> temp; modeName = temp; if ( !isValMode(modeName,modeType::DecOn) ) return; datafile >> minPedCutDc; datafile >> maxPedCutDc; if ( verbose==1 ) { cout << "--- Found tagname '" << tagname << "' in configFile " << configFile << endl; cout << Form("%25s","pedCutType = ") << pedCutType.Data() << endl; cout << Form("%25s","minPedCutPk = ") << minPedCutPk << endl; cout << Form("%25s","maxPedCutPk = ") << maxPedCutPk << endl; cout << Form("%25s","minPedCutDc = ") << minPedCutDc << endl; cout << Form("%25s","maxPedCutDc = ") << maxPedCutDc << endl << endl; } } else { cout << "arcs_macro: ERROR : Could not find tag '" << tagname << "' in configFile " << configFile << ": ABORT" << endl; return; } // --- read NoiseCuts tagname = "NoiseCuts"; tag = kFALSE; while (!tag) { if ( datafile.eof() || !datafile.good() ) break ; datafile.getline(line,len); TString fline(line); tag = ( fline.Contains(tagname) ); } if ( tag ) { char temp[256]; datafile >> temp; noiseCutType = temp; if ( !isValCutType(noiseCutType) ) return; datafile >> temp; modeName = temp; if ( !isValMode(modeName,modeType::PeakOn) ) return; datafile >> minTwoSensNoiseCutPk; datafile >> minOneSensNoiseCutPk; datafile >> minNoiseCutPk; datafile >> maxNoiseCutPk; datafile >> temp; modeName = temp; if ( !isValMode(modeName,modeType::DecOn) ) return; datafile >> minTwoSensNoiseCutDc; datafile >> minOneSensNoiseCutDc; datafile >> minNoiseCutDc; datafile >> maxNoiseCutDc; if ( verbose==1 ) { cout << "--- Found tagname '" << tagname << "' in configFile " << configFile << endl; cout << Form("%25s","noiseCutType = ") << noiseCutType.Data() << endl; cout << Form("%25s","minTwoSensNoiseCutPk = ") << minTwoSensNoiseCutPk << endl; cout << Form("%25s","minOneSensNoiseCutPk = ") << minOneSensNoiseCutPk << endl; cout << Form("%25s","minNoiseCutPk = ") << minNoiseCutPk << endl; cout << Form("%25s","maxNoiseCutPk = ") << maxNoiseCutPk << endl; cout << Form("%25s","minTwoSensNoiseCutDc = ") << minTwoSensNoiseCutDc << endl; cout << Form("%25s","minOneSensNoiseCutDc = ") << minOneSensNoiseCutDc << endl; cout << Form("%25s","minNoiseCutDc = ") << minNoiseCutDc << endl; cout << Form("%25s","maxNoiseCutDc = ") << maxNoiseCutDc << endl << endl; } } else { cout << "arcs_macro: ERROR : Could not find tag '" << tagname << "' in configFile " << configFile << ": ABORT" << endl; return; } // --- read PeakTimeCuts tagname = "PeakTimeCuts"; tag = kFALSE; while (!tag) { if ( datafile.eof() || !datafile.good() ) break ; datafile.getline(line,len); TString fline(line); tag = ( fline.Contains(tagname) ); } if ( tag ) { char temp[256]; datafile >> temp; peaktimeCutType = temp; if ( !isValCutType(peaktimeCutType) ) return; datafile >> temp; modeName = temp; if ( !isValMode(modeName,modeType::PeakOn) ) return; datafile >> minTwoSensPeakTimeCutPk; datafile >> minOneSensPeakTimeCutPk; datafile >> minPeakTimeCutPk; datafile >> maxPeakTimeCutPk; datafile >> temp; modeName = temp; if ( !isValMode(modeName,modeType::DecOn) ) return; datafile >> minTwoSensPeakTimeCutDc; datafile >> minOneSensPeakTimeCutDc; datafile >> minPeakTimeCutDc; datafile >> maxPeakTimeCutDc; if ( verbose==1 ) { cout << "--- Found tagname '" << tagname << "' in configFile " << configFile << endl; cout << Form("%25s","peaktimeCutType = ") << peaktimeCutType.Data() << endl; cout << Form("%25s","minTwoSensPeakTimeCutPk = ") << minTwoSensPeakTimeCutPk << endl; cout << Form("%25s","minOneSensPeakTimeCutPk = ") << minOneSensPeakTimeCutPk << endl; cout << Form("%25s","minPeakTimeCutPk = ") << minPeakTimeCutPk << endl; cout << Form("%25s","maxPeakTimeCutPk = ") << maxPeakTimeCutPk << endl; cout << Form("%25s","minTwoSensPeakTimeCutDc = ") << minTwoSensPeakTimeCutDc << endl; cout << Form("%25s","minOneSensPeakTimeCutDc = ") << minOneSensPeakTimeCutDc << endl; cout << Form("%25s","minPeakTimeCutDc = ") << minPeakTimeCutDc << endl; cout << Form("%25s","maxPeakTimeCutDc = ") << maxPeakTimeCutDc << endl << endl; } } else { cout << "arcs_macro: ERROR : Could not find tag '" << tagname << "' in configFile " << configFile << ": ABORT" << endl; return; } // --- read GainCuts tagname = "GainCuts"; tag = kFALSE; while (!tag) { if ( datafile.eof() || !datafile.good() ) break ; datafile.getline(line,len); TString fline(line); tag = ( fline.Contains(tagname) ); } if ( tag ) { char temp[256]; datafile >> temp; gainCutType = temp; if ( !isValCutType(gainCutType) ) return; datafile >> temp; modeName = temp; if ( !isValMode(modeName,modeType::PeakOn) ) return; datafile >> minOSGainCutPk; datafile >> minGainCutPk; datafile >> maxGainCutPk; datafile >> maxPHGainCutPk; datafile >> temp; modeName = temp; if ( !isValMode(modeName,modeType::DecOn) ) return; datafile >> minOSGainCutDc; datafile >> minGainCutDc; datafile >> maxGainCutDc; datafile >> maxPHGainCutDc; if ( verbose==1 ) { cout << "--- Found tagname '" << tagname << "' in configFile " << configFile << endl; cout << Form("%25s","gainCutType = ") << gainCutType.Data() << endl; cout << Form("%25s","minOSGainCutPk = ") << minOSGainCutPk << endl; cout << Form("%25s","minGainCutPk = ") << minGainCutPk << endl; cout << Form("%25s","maxGainCutPk = ") << maxGainCutPk << endl; cout << Form("%25s","maxPHGainCutPk = ") << maxPHGainCutPk << endl; cout << Form("%25s","minOSGainCutDc = ") << minOSGainCutDc << endl; cout << Form("%25s","minGainCutDc = ") << minGainCutDc << endl; cout << Form("%25s","maxGainCutDc = ") << maxGainCutDc << endl; cout << Form("%25s","maxPHGainCutDc = ") << maxPHGainCutDc << endl << endl; } } else { cout << "arcs_macro: ERROR : Could not find tag '" << tagname << "' in configFile " << configFile << ": ABORT" << endl; return; } // --- read PinholeCuts tagname = "PinholeCuts"; tag = kFALSE; while (!tag) { if ( datafile.eof() || !datafile.good() ) break ; datafile.getline(line,len); TString fline(line); tag = ( fline.Contains(tagname) ); } if ( tag ) { char temp[256]; datafile >> temp; phCutType = temp; if ( !isValCutType(phCutType) ) return; datafile >> temp; modeName = temp; if ( !isValMode(modeName,modeType::PeakOn) ) return; datafile >> maxLowPHCutPk; datafile >> maxHighPHCutPk; datafile >> temp; modeName = temp; if ( !isValMode(modeName,modeType::DecOn) ) return; datafile >> maxLowPHCutDc; datafile >> maxHighPHCutDc; if ( verbose==1 ) { cout << "--- Found tagname '" << tagname << "' in configFile " << configFile << endl; cout << Form("%25s","phCutType = ") << phCutType.Data() << endl; cout << Form("%25s","maxLowPHCutPk = ") << maxLowPHCutPk << endl; cout << Form("%25s","maxHighPHCutPk = ") << maxHighPHCutPk << endl; cout << Form("%25s","maxLowPHCutDc = ") << maxLowPHCutDc << endl; cout << Form("%25s","maxHighPHCutDc = ") << maxHighPHCutDc << endl << endl; } } else { cout << "arcs_macro: ERROR : Could not find tag '" << tagname << "' in configFile " << configFile << ": ABORT" << endl; return; } // --- read PulseHeightCuts tagname = "PulseHeightCuts"; tag = kFALSE; while (!tag) { if ( datafile.eof() || !datafile.good() ) break ; datafile.getline(line,len); TString fline(line); tag = ( fline.Contains(tagname) ); } if ( tag ) { char temp[256]; datafile >> temp; pulseCutType = temp; if ( !isValCutType(pulseCutType) ) return; datafile >> temp; modeName = temp; if ( !isValMode(modeName,modeType::PeakOn) ) return; datafile >> minPulseCutPk; datafile >> maxPulseCutPk; datafile >> temp; modeName = temp; if ( !isValMode(modeName,modeType::DecOn) ) return; datafile >> minPulseCutDc; datafile >> maxPulseCutDc; if ( verbose==1 ) { cout << "--- Found tagname '" << tagname << "' in configFile " << configFile << endl; cout << Form("%25s","pulseCutType = ") << pulseCutType.Data() << endl; cout << Form("%25s","minPulseCutPk = ") << minPulseCutPk << endl; cout << Form("%25s","maxPulseCutPk = ") << maxPulseCutPk << endl; cout << Form("%25s","minPulseCutDc = ") << minPulseCutDc << endl; cout << Form("%25s","maxPulseCutDc = ") << maxPulseCutDc << endl << endl; } } else { cout << "arcs_macro: ERROR : Could not find tag '" << tagname << "' in configFile " << configFile << ": ABORT" << endl; return; } // -- open root file const char *filename = Form("%s/%s",inDir.Data(),rootFile.Data()); if ( rootFile.Contains(".root") ) rootFile.ReplaceAll(".root",""); TFile inf(filename); if ( gDirectory->GetListOfKeys()->GetSize() == 0 ) { cout << "arcs_macro: ERROR : No TKeys found in root file " << filename << endl; return; } // --- Record, PeakInvOn, DecInvOn dir if ( recordNum == -1 ) recordNum = getMaxRecord(); TDirectory *rec_dir = (TDirectory*) inf.Get(Form("Record%d",recordNum)); cout << "Searching " << Form("Record%d",recordNum) << " for histograms." << endl << endl; if ( !rec_dir ) { cout << "arcs_macro: ERROR : Unable to find Record" << recordNum << " in root file " << filename << endl << " Must be a config error." << endl << " ABORTING." << endl << endl; return; } TDirectory *pkInvOn_dir = (TDirectory*) rec_dir->Get("PeakInvOn"); TDirectory *dcInvOn_dir = (TDirectory*) rec_dir->Get("DecInvOn"); TDirectory *pkInvOff_dir = (TDirectory*) rec_dir->Get("PeakInvOff"); TDirectory *dcInvOff_dir = (TDirectory*) rec_dir->Get("DecInvOff"); TDirectory *header_dir = (TDirectory*) rec_dir->Get("Header"); // --- Read header configuration if ( !header_dir ) { cout << "arcs_macro: ERROR : Unable to find Header sub-directory." << endl << " Documentation will be incomplete." << endl << endl; } else { date = (header_dir->Get("Date_C"))->GetTitle(); modName = (header_dir->Get("Object_C"))->GetTitle(); oper = (header_dir->Get("Operator_C"))->GetTitle(); swVer = (header_dir->Get("Version_C"))->GetTitle(); testCenter = (header_dir->Get("TestCenter_C"))->GetTitle(); } // --- PeakInvOn Subdirectories TDirectory *ped_pkon_dir, *noi_pkon_dir, *gain_pkon_dir,*pulse_pkon_dir; if ( !pkInvOn_dir ) { cout << "arcs_macro: WARNING : Unable to find PeakInvOn sub-directory." << endl << " Skip it. Some output will be missing." << endl << endl; } else { ped_pkon_dir = (TDirectory*) pkInvOn_dir->Get("Pedestals"); noi_pkon_dir = (TDirectory*) pkInvOn_dir->Get("Noise"); gain_pkon_dir = (TDirectory*) pkInvOn_dir->Get("Gain"); pulse_pkon_dir = (TDirectory*) pkInvOn_dir->Get("PulseShape"); } // --- Number of Chips can be only 4 or 6 TH1* rrChipHist = (TH1*) noi_pkon_dir->Get("CMSubtractedNoise"); nChip = (rrChipHist->GetNbinsX())/nChanPerChip; cout << "Found " << nChip << " APVs" << endl; if(nChip!=4 && nChip!=6) cout << "Error: Number of APVs different from 4 or 6, it is " << nChip << endl; // --- PeakInvOff Subdirectories TDirectory *ped_pkoff_dir, *noi_pkoff_dir, *gain_pkoff_dir,*pulse_pkoff_dir, *pinhole_pkoff_dir; if ( !pkInvOff_dir ) { cout << "arcs_macro: WARNING : Unable to find PeakInvOff sub-directory." << endl << " Skip it. Some output will be missing." << endl << endl; } else { ped_pkoff_dir = (TDirectory*) pkInvOff_dir->Get("Pedestals"); noi_pkoff_dir = (TDirectory*) pkInvOff_dir->Get("Noise"); gain_pkoff_dir = (TDirectory*) pkInvOff_dir->Get("Gain"); pulse_pkoff_dir = (TDirectory*) pkInvOff_dir->Get("PulseShape"); pinhole_pkoff_dir = (TDirectory*) pkInvOff_dir->Get("Pinhole"); } // --- DecInvOn Subdirectories TDirectory *ped_dcon_dir, *noi_dcon_dir, *gain_dcon_dir, *pulse_dcon_dir; if ( !dcInvOn_dir ) { cout << "arcs_macro: WARNING : Unable to find DecInvOn sub-directory." << endl << " Skip it. Some output will be missing." << endl << endl; } else { ped_dcon_dir = (TDirectory*) dcInvOn_dir->Get("Pedestals"); noi_dcon_dir = (TDirectory*) dcInvOn_dir->Get("Noise"); gain_dcon_dir = (TDirectory*) dcInvOn_dir->Get("Gain"); pulse_dcon_dir = (TDirectory*) dcInvOn_dir->Get("PulseShape"); } // --- DecInvOff Subdirectories TDirectory *ped_dcoff_dir, *noi_dcoff_dir, *gain_dcoff_dir, *pulse_dcoff_dir; if ( !dcInvOff_dir ) { cout << "arcs_macro: WARNING : Unable to find DecInvOff sub-directory." << endl << " Skip it. Some output will be missing." << endl << endl; } else { ped_dcoff_dir = (TDirectory*) dcInvOff_dir->Get("Pedestals"); noi_dcoff_dir = (TDirectory*) dcInvOff_dir->Get("Noise"); gain_dcoff_dir = (TDirectory*) dcInvOff_dir->Get("Gain"); pulse_dcoff_dir = (TDirectory*) dcInvOff_dir->Get("PulseShape"); } // -- Canvas for all plots TCanvas can("can","can",1600,1600); can.Range(0,0,25,25); TPaveLabel canHeader(5,23.5,20,24.5,Form("%s; Record%d; %s",modName,recordNum,date),"br"); canHeader.SetFillColor(18); TPad pad1("pad1","pad1",0.02,0.49,0.48,0.92); TPad pad2("pad2","pad2",0.52,0.49,0.98,0.92); TPad pad3("pad3","pad3",0.02,0.02,0.48,0.45); TPad pad4("pad4","pad4",0.52,0.02,0.98,0.45); pad1.Draw(); pad2.Draw(); pad3.Draw(); pad4.Draw(); TPaveText* pkOnLabel = new TPaveText(xMinLab,yMinLab,xMaxLab,yMaxLab,"ndc"); pkOnLabel->AddText("Peak InvOn"); pkOnLabel->SetTextColor(2); TPaveText* pkOffLabel = new TPaveText(xMinLab,yMinLab,xMaxLab,yMaxLab,"ndc"); pkOffLabel->AddText("Peak InvOff"); pkOffLabel->SetTextColor(2); TPaveText* dcOnLabel = new TPaveText(xMinLab,yMinLab,xMaxLab,yMaxLab,"ndc"); dcOnLabel->AddText("Dec InvOn"); dcOnLabel->SetTextColor(2); TPaveText* dcOffLabel = new TPaveText(xMinLab,yMinLab,xMaxLab,yMaxLab,"ndc"); dcOffLabel->AddText("Dec InvOff"); dcOffLabel->SetTextColor(2); char *histType; TString outputName; char *cutType = "absCut"; canHeader.Draw(); // --- plot peaktime histType = "peaktime"; cutType="pctCut"; outputName = Form("%s/h_%s_%s_Rec%d_%s_%s.eps",outDir.Data(),histType,rootFile.Data(),recordNum,cutType,label); pad1.cd(); if ( pulse_pkon_dir ) plotPeakTime(pulse_pkon_dir,"PeakOn", &h_stat_pkon); pkOnLabel->Draw(); pad2.cd(); if ( pulse_pkoff_dir ) plotPeakTime(pulse_pkoff_dir,"PeakOff", &h_stat_pkoff); pkOffLabel->Draw(); pad3.cd(); if ( pulse_dcon_dir ) plotPeakTime(pulse_dcon_dir,"DecOn", &h_stat_dcon); dcOnLabel->Draw(); pad4.cd(); if ( pulse_dcoff_dir ) plotPeakTime(pulse_dcoff_dir,"DecOff", &h_stat_dcoff); dcOffLabel->Draw(); can.Update(); can.SaveAs(outputName); clearPads(pad1,pad2,pad3,pad4); resetStatHists(); // --- plot pedestal histType = "pedestal"; if ( !pedCutType.CompareTo("Percentage") ) cutType="pctCut"; outputName = Form("%s/h_%s_%s_Rec%d_%s_%s.eps",outDir.Data(),histType,rootFile.Data(),recordNum,cutType,label); pad1.cd(); if ( ped_pkon_dir ) plotPedestal(ped_pkon_dir,"PeakOn", &h_stat_pkon); pkOnLabel->Draw(); pad2.cd(); if ( ped_pkoff_dir ) plotPedestal(ped_pkoff_dir,"PeakOff", &h_stat_pkoff); pkOffLabel->Draw(); pad3.cd(); if ( ped_dcon_dir ) plotPedestal(ped_dcon_dir,"DecOn", &h_stat_dcon); dcOnLabel->Draw(); pad4.cd(); if ( ped_dcoff_dir ) plotPedestal(ped_dcoff_dir,"DecOff", &h_stat_dcoff); dcOffLabel->Draw(); can.Update(); can.SaveAs(outputName); clearPads(pad1,pad2,pad3,pad4); resetStatHists(); // --- plot pulseshape histType = "pulseheight"; if ( !pulseCutType.CompareTo("Percentage") ) cutType="pctCut"; outputName = Form("%s/h_%s_%s_Rec%d_%s_%s.eps",outDir.Data(),histType,rootFile.Data(),recordNum,cutType,label); pad1.cd(); if ( pulse_pkon_dir ) plotPulseHeight(pulse_pkon_dir,"PeakOn", &h_stat_pkon); pkOnLabel->Draw(); pad2.cd(); if ( pulse_pkoff_dir ) plotPulseHeight(pulse_pkoff_dir,"PeakOff", &h_stat_pkoff); pkOffLabel->Draw(); pad3.cd(); if ( pulse_dcon_dir ) plotPulseHeight(pulse_dcon_dir,"DecOn",&h_stat_dcon); dcOnLabel->Draw(); pad4.cd(); if ( pulse_dcoff_dir ) plotPulseHeight(pulse_dcoff_dir,"DecOff", &h_stat_dcoff); dcOffLabel->Draw(); can.Update(); can.SaveAs(outputName); clearPads(pad1,pad2,pad3,pad4); resetStatHists(); // --- plot noise histType = "noise"; outputName = Form("%s/h_%s_%s_Rec%d_%s_%s.eps",outDir.Data(),histType,rootFile.Data(),recordNum,cutType,label); if ( !noiseCutType.CompareTo("Percentage") ) cutType="pctCut"; pad1.cd(); if ( noi_pkon_dir ) plotNoise(noi_pkon_dir, "PeakOn", &h_stat_pkon); pkOnLabel->Draw(); pad2.cd(); if ( noi_pkoff_dir ) plotNoise(noi_pkoff_dir, "PeakOff", &h_stat_pkoff); pkOffLabel->Draw(); pad3.cd(); if ( noi_dcon_dir ) plotNoise(noi_dcon_dir, "DecOn", &h_stat_dcon); dcOnLabel->Draw(); pad4.cd(); if ( noi_dcoff_dir ) plotNoise(noi_dcoff_dir, "DecOff", &h_stat_dcoff); dcOffLabel->Draw(); can.Update(); can.SaveAs(outputName); clearPads(pad1,pad2,pad3,pad4); resetStatHists(); // --- plot gain slope histType = "gainSlope"; outputName = Form("%s/h_%s_%s_Rec%d_%s_%s.eps",outDir.Data(),histType,rootFile.Data(),recordNum,cutType,label); if ( !gainCutType.CompareTo("Percentage") ) cutType="pctCut"; pad1.cd(); if ( gain_pkon_dir ) plotGain(gain_pkon_dir, "PeakOn", &h_stat_pkon); pkOnLabel->Draw(); pad2.cd(); if ( gain_pkoff_dir ) plotGain(gain_pkoff_dir, "PeakOff", &h_stat_pkoff); pkOffLabel->Draw(); pad3.cd(); if ( gain_dcon_dir ) plotGain(gain_dcon_dir, "DecOn", &h_stat_dcon); dcOnLabel->Draw(); pad4.cd(); if ( gain_dcoff_dir ) plotGain(gain_dcoff_dir, "DecOff", &h_stat_dcoff); dcOffLabel->Draw(); can.Update(); //can.SaveAs(outputName); clearPads(pad1,pad2,pad3,pad4); resetStatHists(); // --- plot gain chiSquared histType = "gainChiSq"; outputName = Form("%s/h_%s_%s_Rec%d_%s_%s.eps",outDir.Data(),histType,rootFile.Data(),recordNum,cutType,label); if ( !gainCutType.CompareTo("Percentage") ) cutType="pctCut"; pad1.cd(); if ( gain_pkon_dir ) plotGain(gain_pkon_dir, 0, &h_stat_pkon, "chiSquared"); pkOnLabel->Draw(); pad2.cd(); if ( gain_pkoff_dir ) plotGain(gain_pkoff_dir, 0, &h_stat_pkoff, "chiSquared"); pkOffLabel->Draw(); pad3.cd(); if ( gain_dcon_dir ) plotGain(gain_dcon_dir, 0, &h_stat_dcon, "chiSquared"); dcOnLabel->Draw(); pad4.cd(); if ( gain_dcoff_dir ) plotGain(gain_dcoff_dir, 0, &h_stat_dcoff, "chiSquared"); dcOffLabel->Draw(); can.Update(); //can.SaveAs(outputName); clearPads(pad1,pad2,pad3,pad4); resetStatHists(); // --- plot gain offset histType = "gainOffset"; outputName = Form("%s/h_%s_%s_Rec%d_%s_%s.eps",outDir.Data(),histType,rootFile.Data(),recordNum,cutType,label); if ( !gainCutType.CompareTo("Percentage") ) cutType="pctCut"; pad1.cd(); if ( gain_pkon_dir ) plotGain(gain_pkon_dir, 0, &h_stat_pkon, "offset"); pkOnLabel->Draw(); pad2.cd(); if ( gain_pkoff_dir ) plotGain(gain_pkoff_dir, 0, &h_stat_pkoff, "offset"); pkOffLabel->Draw(); pad3.cd(); if ( gain_dcon_dir ) plotGain(gain_dcon_dir, 0, &h_stat_dcon, "offset"); dcOnLabel->Draw(); pad4.cd(); if ( gain_dcoff_dir ) plotGain(gain_dcoff_dir, 0, &h_stat_dcoff, "offset"); dcOffLabel->Draw(); can.Update(); //can.SaveAs(outputName); clearPads(pad1,pad2,pad3,pad4); resetStatHists(); // --- plot pinhole TCanvas phCan("phCan","phCan",800,800); phCan.Range(0,0,25,25); canHeader.Draw(); TPad phPad1("phPad1","phPad1",0.02,0.49,0.98,0.92); TPad phPad2("phPad2","phPad1",0.02,0.02,0.98,0.45); phPad1.Draw(); phPad2.Draw(); histType = "pinhole"; if ( !phCutType.CompareTo("Percentage") ) cutType="pctCut"; outputName = Form("%s/h_%s_%s_Rec%d_%s_%s.eps",outDir.Data(),histType,rootFile.Data(),recordNum,cutType,label); if ( pinhole_pkoff_dir ) { plotPinHole(pinhole_pkoff_dir,"PkOff", &h_stat_pkoff, &phPad1, &phPad2, pkOffLabel); phCan.Update(); phCan.SaveAs(outputName); } // --- create output summary file char *ofileNamePkOn = Form("%s/Summary_%s_Rec%d_PeakOn_%s.dat",outDir.Data(),rootFile.Data(),recordNum,label); char *ofileNameDcOn = Form("%s/Summary_%s_Rec%d_DecOn_%s.dat",outDir.Data(),rootFile.Data(),recordNum,label); char *ofileNamePkOff = Form("%s/Summary_%s_Rec%d_PeakOff_%s.dat",outDir.Data(),rootFile.Data(),recordNum,label); char *ofileNameDcOff = Form("%s/Summary_%s_Rec%d_DecOff_%s.dat",outDir.Data(),rootFile.Data(),recordNum,label); ofstream outFilePkOn(ofileNamePkOn, ios::out); ofstream outFileDcOn(ofileNameDcOn, ios::out); ofstream outFilePkOff(ofileNamePkOff, ios::out); ofstream outFileDcOff(ofileNameDcOff, ios::out); if ( outFilePkOn.bad() ) { cout << "arcs_macro : ERROR : Unable to open output file " << ofileNamePkOn << endl << " ABORT." << endl; return; } if ( outFileDcOn.bad() ) { cout << "arcs_macro : ERROR : Unable to open output file " << ofileNameDcOn << endl << " ABORT." << endl; return; } if ( outFilePkOff.bad() ) { cout << "arcs_macro : ERROR : Unable to open output file " << ofileNamePkOn << endl << " ABORT." << endl; return; } if ( outFileDcOff.bad() ) { cout << "arcs_macro : ERROR : Unable to open output file " << ofileNameDcOn << endl << " ABORT." << endl; return; } printHeader(modeType::PeakOn, configFile, outFilePkOn); outFilePkOn << endl << endl << endl; printSummary(modeType::PeakOn, outFilePkOn); outFilePkOn.close(); for (j=0;j= 10 ) { counter = 0; ++deca; if ( deca >= 10 ) { deca = 0; ++hecto; } } } os << digiStream << endl; return; } void printStat(ofstream& os, TString label, Int_t chipNum, modeType mode, Bool_t isFirstHalf=kTRUE) { Int_t ind,j; Int_t offset = chipNum*nChanPerChip; Int_t lowBound = offset; Int_t highBound = nChanPerChip/2 + offset; if ( !isFirstHalf ) { lowBound=nChanPerChip/2 + offset; highBound=nChanPerChip + offset; } Int_t *noiPtr, *gainPtr, *phPtr, *pedPtr, *pulsPtr,*peaktimePtr; switch (mode) { case PeakOn: noiPtr = noiStatPkOn; gainPtr = gainStatPkOn; pedPtr = pedStatPkOn; pulsPtr = pulseStatPkOn; phPtr = phStatPkOff; // pulse height only exists as PkOff peaktimePtr = peaktimeStatPkOn; break; case PeakOff: noiPtr = noiStatPkOff; gainPtr = gainStatPkOff; pedPtr = pedStatPkOff; pulsPtr = pulseStatPkOff; phPtr = phStatPkOff; // pulse height only exists as PkOff peaktimePtr = peaktimeStatPkOff; break; case DecOn: noiPtr = noiStatDcOn; gainPtr = gainStatDcOn; pedPtr = pedStatDcOn; pulsPtr = pulseStatDcOn; phPtr = phStatPkOff; // pulse height only exists as PkOff peaktimePtr = peaktimeStatDcOn; break; case DecOff: noiPtr = noiStatDcOff; gainPtr = gainStatDcOff; pedPtr = pedStatDcOff; pulsPtr = pulseStatDcOff; phPtr = phStatPkOff; // pulse height only exists as PkOff peaktimePtr = peaktimeStatDcOff; break; default: cout << "arcs_macro : PrintStat : modeType " << mode << " is not used for ascii file output" << endl << " Unable to generate proper output." << endl; break; } noiPtr+=lowBound; gainPtr+=lowBound; phPtr+=lowBound; pedPtr+=lowBound; pulsPtr+=lowBound;peaktimePtr+=lowBound; for (ind=lowBound;indSetX1NDC(0.7); Int_t i,j; Double_t maxCut1[max_nChip], maxCut2[max_nChip]; Double_t phChipAvg[max_nChip]; if ( !dir ) { cout << "arcs_macro::plotPinHole: WARNING : directory not found" << endl; return; } char *cutType = "absCut"; TH1* h_pinh_diff = (TH1*) dir->Get("Pinhole_Diff"); TH1* h_pinh_max = (TH1*) dir->Get("Pinhole_Max"); if ( !h_pinh_diff || !h_pinh_max ) { cout << "arcs_macro::plotPinHole: WARNING : dir " << dir->GetName() << " is missing plot(s) Pinhole_Diff,Pinhole_Max" << endl; return; } // --- channel status determination calcChipAvg(h_pinh_diff,phChipAvg); for (j=0;jcd(); h_pinh_diff->Draw(); // to change title and axis labels gStyle->SetOptStat("0"); h_pinh_diff->GetXaxis()->SetTitle("Channel"); h_pinh_diff->GetYaxis()->SetTitle("Maximal Pulse Height Difference [ADC counts]"); h_pinh_diff->SetTitle("Difference between max and min Pulse Height vs. Channel"); h_stat->SetLineColor(kRed); h_stat->SetFillColor(kRed); h_stat->Draw("same"); drawChipLines(nChanPerChip,h_pinh_diff->GetMinimum(),h_pinh_diff->GetMaximum()); drawCutLines(nChanPerChip,maxCut2,maxCut1); tpave->Draw(); pad2->cd(); // to change title and axis labels gStyle->SetOptStat("0"); h_pinh_max->GetXaxis()->SetTitle("Channel"); h_pinh_max->GetYaxis()->SetTitle("Maximal Pulse Height [ADC counts]"); h_pinh_max->SetTitle("Maximum Pulse Height vs. Channel"); h_pinh_max->Draw(); drawChipLines(nChanPerChip,h_pinh_max->GetMinimum(),h_pinh_max->GetMaximum()); outName.Append(cutType); outName.Append(".eps"); } void plotPedestal( TDirectory *dir, TString outName, TH1F *h_stat) { Int_t i,j; Double_t minCut[max_nChip], maxCut[max_nChip]; Double_t pedChipAvg[max_nChip]; // --- sanity checks if ( !dir ) { cout << "arcs_macro::plotPedestal: WARNING : directory not found" << endl; return; } TH1* h_ped = (TH1*) dir->Get("Pedestal"); if ( !h_ped ) { cout << "arcs_macro::plotPedestal: WARNING : dir " << dir->GetName() << " is missing plot(s) Pedestal" << endl; return; } h_ped->SetMinimum(pedHistMin); h_ped->SetMaximum(pedHistMax); // --- channel status determination calcChipAvg(h_ped,pedChipAvg); for (j=0;jGetYaxis()->SetTitleOffset(yTitleOffset); // to change title and axis labels gStyle->SetOptStat("0"); h_ped->GetXaxis()->SetTitle("Channel"); h_ped->GetYaxis()->SetTitle("Pedestal [ADC counts]"); h_ped->SetTitle("Pedestal vs. Channel"); h_ped->Draw(); h_stat->SetLineColor(kRed); h_stat->SetFillColor(kRed); h_stat->Draw("same"); drawCutLines(nChanPerChip,maxCut,minCut); drawChipLines(nChanPerChip,pedHistMin,pedHistMax); return; } void plotPulseHeight( TDirectory *dir, TString outName, TH1F* h_stat ) { if ( !dir ) { cout << "arcs_macro::plotPulseHeight: WARNING : directory not found" << endl; return; } Int_t j; Double_t minCut[max_nChip], maxCut[max_nChip]; Double_t pulseChipAvg[max_nChip]; TH1* h_pulse = (TH1*) dir->Get("PulseHeight"); if ( !h_pulse ) { cout << "arcs_macro::plotPulseHeight: WARNING : dir " << dir->GetName() << " is missing plot(s) PulseHeight" << endl; return; } Double_t sign = h_pulse->GetMinimum(); // --- channel status determination calcChipAvg(h_pulse,pulseChipAvg); for (j=0;jGetYaxis()->SetTitleOffset(yTitleOffset); // to change title and axis labels gStyle->SetOptStat("0"); h_pulse->GetXaxis()->SetTitle("Channel"); h_pulse->GetYaxis()->SetTitle("Pulse Peak [ADC counts]"); h_pulse->SetTitle("Pulse Peak vs. Channel"); h_pulse->Draw(); h_stat->SetLineColor(kRed); h_stat->SetFillColor(kRed); if ( sign < 0 ) h_stat->Draw("esame"); else h_stat->Draw("same"); drawCutLines(nChanPerChip,maxCut,minCut); drawChipLines(nChanPerChip,h_pulse->GetMinimum(),h_pulse->GetMaximum()); return; } void plotNoise( TDirectory *dir, TString outName, TH1F *h_stat ) { Int_t i,j; Double_t noiChipAvg[max_nChip]; // --- sanity checks if ( !dir ) { cout << "arcs_macro::plotNoise: WARNING : directory not found" << endl; return; } TH1* h_noi_raw = (TH1*) dir->Get("RawNoise"); TH1* h_noi_cms = (TH1*) dir->Get("CMSubtractedNoise"); if ( !h_noi_raw || !h_noi_cms ) { cout << "arcs_macro::plotNoise: WARNING : dir " << dir->GetName() << " is missing plot(s) RawNoise, CMSubtractedNoise" << endl; return; } h_noi_raw->SetMinimum(noiseHistMin); h_noi_raw->SetMaximum(noiseHistMax); // --- calculate avg noise calcChipAvg(h_noi_cms,noiChipAvg); // --- get cut values Double_t maxCut[max_nChip], minCut[max_nChip], minOSCut[max_nChip], minTSCut[max_nChip]; for (j=0;jSetLineColor(kRed); h_noi_raw->GetYaxis()->SetTitleOffset(yTitleOffset); // to change title and axis labels gStyle->SetOptStat("0"); h_noi_raw->GetXaxis()->SetTitle("Channel"); h_noi_raw->GetYaxis()->SetTitle("Noise [ADC counts]"); h_noi_raw->SetTitle("Noise vs. Channel"); h_noi_raw->Draw(); h_noi_cms->SetLineColor(kBlue); h_noi_cms->Draw("same"); h_stat->SetLineColor(kRed); h_stat->SetFillColor(kRed); h_stat->Draw("same"); drawCutLines(nChanPerChip,maxCut,minCut,minOSCut,minTSCut ); drawChipLines(nChanPerChip,noiseHistMin,noiseHistMax); TLegend *text = new TLegend(0.2,0.75,0.5,0.85); text->SetFillColor(0); text->AddEntry(h_noi_raw,"Raw Noise","l"); text->AddEntry(h_noi_cms,"CMS Noise","l"); text->SetTextSize(0.05); text->SetTextAlign(11); text->Draw("same"); return; } void plotPeakTime( TDirectory *dir, TString outName, TH1F *h_stat ) { Int_t i,j; Double_t peaktimeChipAvg[max_nChip]; TH1F* h_peaktimeave; h_peaktimeave = new TH1F("h_peaktimeave","Averaged Rise Time",nChanPerChip*nChip,0.5,nChanPerChip*nChip+0.5); TH1F* h_peaktimeavesub; h_peaktimeavesub = new TH1F("h_peaktimeavesub","Ave Sub Peak Time",nChanPerChip*nChip,0.5,nChanPerChip*nChip+0.5); // --- sanity checks if ( !dir ) { cout << "arcs_macro::plotNoise: WARNING : directory not found" << endl; return; } TH1* h_peaktime = (TH1*) dir->Get("PeakTime"); if ( !h_peaktime ) { cout << "arcs_macro::plotNoise: WARNING : dir " << dir->GetName() << " is missing plot(s) PeakTime" << endl; return; } // --- calculate avg peaktime calcChipAvg(h_peaktime,peaktimeChipAvg); for (j=1;jFill(j+i*nChanPerChip,-1.*peaktimeChipAvg[i]); }} h_peaktimeavesub->Add(h_peaktime,h_peaktimeave,1.,1.); h_peaktimeavesub->SetMinimum(peaktimeHistMin); h_peaktimeavesub->SetMaximum(peaktimeHistMax); // --- get cut values Double_t maxCut[max_nChip], minCut[max_nChip], minOSCut[max_nChip], minTSCut[max_nChip]; for (j=0;jSetLineColor(kBlack); h_peaktimeavesub->GetYaxis()->SetTitleOffset(yTitleOffset); // to change title and axis labels gStyle->SetOptStat("0"); h_peaktimeavesub->GetXaxis()->SetTitle("Channel"); h_peaktimeavesub->GetYaxis()->SetTitle("Average Subtracted Peak Time [ADC counts]"); h_peaktimeavesub->SetTitle("Avg Sub Peak Time vs. Channel"); h_peaktimeavesub->Draw(); h_stat->SetLineColor(kRed); h_stat->SetFillColor(kRed); h_stat->Draw("same"); drawCutLines(nChanPerChip,maxCut,minCut,minOSCut,minTSCut ); drawChipLines(nChanPerChip,peaktimeHistMin,peaktimeHistMax); return; } void plotGain( TDirectory *dir, TString outName, TH1F *h_stat, TString whichGain="default" ) { Int_t i,j; Double_t minCut[nChip], maxCut[nChip], maxPHCut[nChip], minOSCut[nChip]; Double_t gainChipAvg[nChip]; // --- sanity checks if ( !dir ) { cout << "arcs_macro::plotGain: WARNING : directory not found" << endl; return; } TH1* h_gain_slope = (TH1*) dir->Get("Gain_Slope"); TH1* h_gain_off = (TH1*) dir->Get("Gain_Offset"); TH1* h_gain_chi = (TH1*) dir->Get("Gain_Chi2"); if ( !h_gain_slope || !h_gain_off || !h_gain_chi ) { cout << "arcs_macro::plotGain: WARNING : dir " << dir->GetName() << " is missing plot(s) Gain_Slope, Gain_Offset, Gain_Chi2" << endl; return; } if ( !whichGain.CompareTo("chiSquared") ) { h_gain_chi->Draw(); drawChipLines(nChanPerChip,h_gain_chi->GetMinimum(),h_gain_chi->GetMaximum()); return; } if ( !whichGain.CompareTo("offset") ) { h_gain_off->Draw(); drawChipLines(nChanPerChip,h_gain_off->GetMinimum(),h_gain_off->GetMaximum()); return; } h_gain_slope->SetMinimum(gainHistMin); h_gain_slope->SetMaximum(gainHistMax); Double_t sign = h_gain_slope->GetMinimum(); // --- calculate avg noise calcChipAvg(h_gain_slope,gainChipAvg); for (j=0;jSetLineColor(kBlack); h_gain_slope->GetYaxis()->SetTitleOffset(yTitleOffset); // to change title and axis labels gStyle->SetOptStat("0"); h_gain_slope->GetXaxis()->SetTitle("MIPs"); h_gain_slope->GetYaxis()->SetTitle("Gain [ADC counts]"); h_gain_slope->SetTitle("Gain vs. MIP"); h_gain_slope->Draw(); h_stat->SetLineColor(kRed); h_stat->SetFillColor(kRed); if ( sign < 0 ) h_stat->Draw("esame"); else h_stat->Draw("same"); drawCutLines(nChanPerChip,maxCut,minCut,minOSCut,maxPHCut); drawChipLines(nChanPerChip,h_gain_slope->GetMinimum(),h_gain_slope->GetMaximum()); return; } void calcChipAvg( const TH1* hist, Double_t chipAvg[], Int_t verbose=0) { Int_t i,j; for (j=0;jGetBinContent(channel+1); sum += hval; sumSq += sum*sum; } chipAvg[j]=sum/nChanPerChip; if ( verbose ) cout << "avg for chip " << j << " = " << chipAvg[j] << endl; } return; } void calcNGStatus( const TH1* hist, TH1F *h_stat, Int_t status[], Double_t maxCut[], Double_t minCut[], Double_t minOSCut[]=0, Double_t minTSCut[]=0, Int_t verbose=0 ) { Double_t peaktimeChipAvg[max_nChip]; Double_t histMin = hist->GetMinimum(); Double_t histMax = hist->GetMaximum(); if ( verbose ) { cout << "histMin = " << histMin << endl; cout << "histMax = " << histMax << endl; } Bool_t isGain= kFALSE; Bool_t isNoise=kFALSE; Bool_t isPH=kFALSE; Bool_t isPeakTime=kFALSE; TString hName(hist->GetName()) ; cout << "calcNGStatus : histogram name " << hName << endl; if ( !hName.CompareTo("Gain_Slope") ) isGain=kTRUE; if ( !hName.CompareTo("CMSubtractedNoise") ) isNoise=kTRUE; if ( !hName.CompareTo("Pinhole_Diff") ) isPH=kTRUE; if ( !hName.CompareTo("PeakTime") ) isPeakTime=kTRUE; Int_t i,j; for (j=0;jSetBinContent(channel+1,0.); Double_t val = hist->GetBinContent(channel+1); TString hName(hist->GetName()) ; if ( isNoise ) { histMin=0.; histMax=3.; if ( val > maxCut[j] ) status[channel]=4; // high noise else if ( val < minCut[j] && val > minOSCut[j] ) status[channel]=1; // one sensor unbonded noise else if ( val < minOSCut[j] && val > minTSCut[j] ) status[channel]=2; // two sensor unbonded noise else if ( val < minTSCut[j] ) status[channel]=3; // low noise (ph?) } elseif ( isPeakTime ) { calcChipAvg(hist,peaktimeChipAvg); histMin=-100.; histMax=200. ; if ( val-peaktimeChipAvg[j] > maxCut[j] ) status[channel]=4; // high peaktime else if ( val-peaktimeChipAvg[j] < minCut[j] && val-peaktimeChipAvg[j] > minOSCut[j] ) status[channel]=1; // one sensor unbonded peaktime else if ( val-peaktimeChipAvg[j] < minOSCut[j] && val-peaktimeChipAvg[j] > minTSCut[j] ) status[channel]=2; // two sensor unbonded peaktime else if ( val-peaktimeChipAvg[j] < minTSCut[j] ) status[channel]=3; // low peaktime (ph?) } else if ( isGain ) { if ( val > maxCut[j] ) status[channel]=4; // two sensor gain (ph) else if ( val < maxCut[j] && val > minCut[j] ) status[channel]=3; // high gain else if ( val < minOSCut[j] && val > minTSCut[j] ) status[channel]=1; // one sensor unbonded gain else if ( val < minTSCut[j] ) status[channel]=2; // two sensor unbonded gain } else if ( isPH ) { if ( val > maxCut[j] ) status[channel]=2; // ph else if ( val > minCut[j] ) status[channel]=1; // high ph reading } else { cout << "calcNGStatus : ERROR : histogram name " << hist->GetName() << " not expected!" << endl << " ABORT calculation" << endl; return; } if ( status[channel]!=0 ) { Double_t statFillVal = histMin+0.07*fabs(histMax-histMin); Double_t statFillErr = 0.07*fabs(histMax-histMin); h_stat->SetBinContent(channel+1,statFillVal); h_stat->SetBinError(channel+1,statFillErr); if ( verbose ) cout << "arcs_macro::calcNGStatus : set bin content " << channel+1 << " = " << statFillVal << " +- " << statFillErr << endl; } } // channel loop } // chip loop } void calcStatus( const TH1* hist, Double_t chipAvg[], Int_t chanStatus[], Double_t minCut[], Double_t maxCut[], TH1F *h_stat, Int_t verbose=0) { Int_t i,j; Double_t histMin = hist->GetMinimum(); Double_t histMax = hist->GetMaximum(); if ( verbose ) { cout << "histMin = " << histMin << endl; cout << "histMax = " << histMax << endl; } for (j=0;jSetBinContent(channel+1,1000); chanStatus[channel]=0; // pass status = 0 Double_t val = hist->GetBinContent(channel+1); if ( val < minCut[j] ) chanStatus[channel]=1; // below min cut failure = 1 if ( val > maxCut[j] ) chanStatus[channel]=2; // above max cut failure = 2 if ( chanStatus[channel]!=0 ) { Double_t statFillVal = histMin+0.07*fabs(histMax-histMin); Double_t statFillErr = 0.07*fabs(histMax-histMin); h_stat->SetBinError(channel+1,statFillErr); h_stat->SetBinContent(channel+1,statFillVal); if ( verbose ) cout << "arcs_macro::calcStatus : set bin content " << channel+1 << " = " << statFillVal << endl; } } } return; } void drawCutLines( const int nChanPerChip, Double_t hCut[], Double_t lCut[], Double_t aCut[]=0, Double_t bCut[]=0, const int lineStyle=2, const char* option="same") { TLine *hCutLine0, *lCutLine0, *hCutLine1, *lCutLine1, *hCutLine2, *lCutLine2, *hCutLine3, *lCutLine3, *hCutLine4, *lCutLine4, *hCutLine5, *lCutLine5; hCutLine0 = new TLine(0*nChanPerChip+1.0,hCut[0],1*nChanPerChip+1.0,hCut[0]); lCutLine0 = new TLine(0*nChanPerChip+1.0,lCut[0],1*nChanPerChip+1.0,lCut[0]); hCutLine1 = new TLine(1*nChanPerChip+1.0,hCut[1],2*nChanPerChip+1.0,hCut[1]); lCutLine1 = new TLine(1*nChanPerChip+1.0,lCut[1],2*nChanPerChip+1.0,lCut[1]); hCutLine2 = new TLine(2*nChanPerChip+1.0,hCut[2],3*nChanPerChip+1.0,hCut[2]); lCutLine2 = new TLine(2*nChanPerChip+1.0,lCut[2],3*nChanPerChip+1.0,lCut[2]); hCutLine3 = new TLine(3*nChanPerChip+1.0,hCut[3],4*nChanPerChip+1.0,hCut[3]); lCutLine3 = new TLine(3*nChanPerChip+1.0,lCut[3],4*nChanPerChip+1.0,lCut[3]); if(nChip==6) { hCutLine4 = new TLine(4*nChanPerChip+1.0,hCut[4],5*nChanPerChip+1.0,hCut[4]); lCutLine4 = new TLine(4*nChanPerChip+1.0,lCut[4],5*nChanPerChip+1.0,lCut[4]); hCutLine5 = new TLine(5*nChanPerChip+1.0,hCut[5],6*nChanPerChip+1.0,hCut[5]); lCutLine5 = new TLine(5*nChanPerChip+1.0,lCut[5],6*nChanPerChip+1.0,lCut[5]); } TLine *aCutLine0, *aCutLine1, *aCutLine2, *aCutLine3, *aCutLine4, *aCutLine5; if ( aCut[0] ) { aCutLine0 = new TLine(0*nChanPerChip+1.0,aCut[0],1*nChanPerChip+1.0,aCut[0]); aCutLine1 = new TLine(1*nChanPerChip+1.0,aCut[1],2*nChanPerChip+1.0,aCut[1]); aCutLine2 = new TLine(2*nChanPerChip+1.0,aCut[2],3*nChanPerChip+1.0,aCut[2]); aCutLine3 = new TLine(3*nChanPerChip+1.0,aCut[3],4*nChanPerChip+1.0,aCut[3]); if(nChip==6) { aCutLine4 = new TLine(4*nChanPerChip+1.0,aCut[4],5*nChanPerChip+1.0,aCut[4]); aCutLine5 = new TLine(5*nChanPerChip+1.0,aCut[5],6*nChanPerChip+1.0,aCut[5]); } aCutLine0->SetLineStyle(lineStyle); aCutLine0->Draw(option); aCutLine1->SetLineStyle(lineStyle); aCutLine1->Draw(option); aCutLine2->SetLineStyle(lineStyle); aCutLine2->Draw(option); aCutLine3->SetLineStyle(lineStyle); aCutLine3->Draw(option); if(nChip==6) { aCutLine4->SetLineStyle(lineStyle); aCutLine4->Draw(option); aCutLine5->SetLineStyle(lineStyle); aCutLine5->Draw(option); } } TLine *bCutLine0, *bCutLine1, *bCutLine2, *bCutLine3, *bCutLine4, *bCutLine5; if ( bCut[0] ) { bCutLine0 = new TLine(0*nChanPerChip+1.0,bCut[0],1*nChanPerChip+1.0,bCut[0]); bCutLine1 = new TLine(1*nChanPerChip+1.0,bCut[1],2*nChanPerChip+1.0,bCut[1]); bCutLine2 = new TLine(2*nChanPerChip+1.0,bCut[2],3*nChanPerChip+1.0,bCut[2]); bCutLine3 = new TLine(3*nChanPerChip+1.0,bCut[3],4*nChanPerChip+1.0,bCut[3]); if(nChip==6) { bCutLine4 = new TLine(4*nChanPerChip+1.0,bCut[4],5*nChanPerChip+1.0,bCut[4]); bCutLine5 = new TLine(5*nChanPerChip+1.0,bCut[5],6*nChanPerChip+1.0,bCut[5]); } bCutLine0->SetLineStyle(lineStyle); bCutLine0->Draw(option); bCutLine1->SetLineStyle(lineStyle); bCutLine1->Draw(option); bCutLine2->SetLineStyle(lineStyle); bCutLine2->Draw(option); bCutLine3->SetLineStyle(lineStyle); bCutLine3->Draw(option); if(nChip==6) { bCutLine4->SetLineStyle(lineStyle); bCutLine4->Draw(option); bCutLine5->SetLineStyle(lineStyle); bCutLine5->Draw(option); } } hCutLine0->SetLineStyle(lineStyle); lCutLine0->SetLineStyle(lineStyle); hCutLine1->SetLineStyle(lineStyle); lCutLine1->SetLineStyle(lineStyle); hCutLine2->SetLineStyle(lineStyle); lCutLine2->SetLineStyle(lineStyle); hCutLine3->SetLineStyle(lineStyle); lCutLine3->SetLineStyle(lineStyle); if(nChip==6) { hCutLine4->SetLineStyle(lineStyle); lCutLine4->SetLineStyle(lineStyle); hCutLine5->SetLineStyle(lineStyle); lCutLine5->SetLineStyle(lineStyle); } hCutLine0->Draw(option); lCutLine0->Draw(option); hCutLine1->Draw(option); lCutLine1->Draw(option); hCutLine2->Draw(option); lCutLine2->Draw(option); hCutLine3->Draw(option); lCutLine3->Draw(option); if(nChip==6) { hCutLine4->Draw(option); lCutLine4->Draw(option); hCutLine5->Draw(option); lCutLine5->Draw(option); } return; } void drawChipLines(const int nChanPerChip, Double_t histMin, Double_t histMax, const int lineStyle=3, const char* option="same") { TLine *chip1b, *chip2b, *chip3b, *chip4b, *chip5b; chip1b = new TLine(1*nChanPerChip+1.5,histMin,1*nChanPerChip+1.5,histMax); chip2b = new TLine(2*nChanPerChip+1.5,histMin,2*nChanPerChip+1.5,histMax); chip3b = new TLine(3*nChanPerChip+1.5,histMin,3*nChanPerChip+1.5,histMax); if(nChip==6) { chip4b = new TLine(4*nChanPerChip+1.5,histMin,4*nChanPerChip+1.5,histMax); chip5b = new TLine(5*nChanPerChip+1.5,histMin,5*nChanPerChip+1.5,histMax); } chip1b->SetLineStyle(lineStyle); chip1b->Draw(option); chip2b->SetLineStyle(lineStyle); chip2b->Draw(option); chip3b->SetLineStyle(lineStyle); chip3b->Draw(option); if(nChip==6) { chip4b->SetLineStyle(lineStyle); chip4b->Draw(option); chip5b->SetLineStyle(lineStyle); chip5b->Draw(option); } return; } Bool_t isValCutType( TString cutType ) { if ( cutType.CompareTo("Percentage") && cutType.CompareTo("Absolute") ) { cout << "arcs_macro: isValCutType : ERROR : cutType " << cutType.Data() << " not valid" << endl << " Please fix configuration file -- ABORTING." << endl << endl; return kFALSE; } return kTRUE; } Bool_t isValMode( TString modeName, modeType goodMode ) { modeType thisMode = getModeType(modeName); if ( thisMode == goodMode ) return kTRUE; else { cout << "arcs_macro : isValMode : ERROR : modeType " << thisMode << " does not match" << endl << " expected type " << goodMode << " -- ABORT." << endl; return kFALSE; } } void initArrays() { Int_t i; for (i=0;i0;i--) { TObject *rec_obj = gDirectory->Get(Form("Record%d",i)); if ( rec_obj ) { if ( i==nMaxRec ) { cout << "arcs_macro : getMaxRecord : WARNING, latest record found is at maximum : " << nMaxRec << endl << " Perhaps the hardwired limit should be increased." << endl; } return i; } } cout << "arcs_macro : getMaxRecord : Unable to find any records in range [1," << nMaxRec << "]" << endl << " Must be a configuration error. Please fix." << endl; return -1; } void clearPads(TPad &pad1, TPad &pad2, TPad &pad3, TPad &pad4) { pad1.Clear(); pad2.Clear(); pad3.Clear(); pad4.Clear(); return; } void resetStatHists() { h_stat_pkon.Reset("ICE"); h_stat_pkoff.Reset("ICE"); h_stat_dcon.Reset("ICE"); h_stat_dcoff.Reset("ICE"); }