Main Page   Modules   Namespace List   Class Hierarchy   Data Structures   File List   Namespace Members   Data Fields   Globals   Related Pages  

NoiseOccupancyAlgorithm.cpp

Go to the documentation of this file.
00001 #include "NoiseOccupancyAlgorithm.h"
00002 #include "AnalysisAlgorithmMap.h"
00003 #include "AnalysisService.h"
00004 #include "SctData/Stat.h"
00005 #include "SctData/NoiseOccupancyTestResult.h"
00006 #include "SctData/OccupancyProjector.h"
00007 #include "SctData/FitScanResult.h"
00008 #include "SctData/FitObject.h"
00009 #include "SctData/ResponseCurve.h"
00010 #include "SctData/ModuleDefect.h"
00011 #include <TH1.h>
00012 #include <TGraphAsymmErrors.h>
00013 #include <string>
00014 
00015 using namespace std;
00016 using namespace boost;
00017 using namespace SctData;
00018 using namespace Sct;
00019 
00020 namespace SctAnalysis {
00021     
00022     NoiseOccupancyAlgorithm::~NoiseOccupancyAlgorithm() throw() {}
00023 
00024     shared_ptr<AnalysisAlgorithm> NoiseOccupancyAlgorithm::clone(const TestData& testData, const string& moduleName) const throw() {
00025     return shared_ptr<AnalysisAlgorithm>(new NoiseOccupancyAlgorithm(testData, moduleName));
00026     }
00027 
00028     bool NoiseOccupancyAlgorithm::inMap = AnalysisAlgorithmMap::instance().setAlgorithm("NoiseOccupancyTest", auto_ptr<AnalysisAlgorithm>(new NoiseOccupancyAlgorithm()));
00029 
00030     //----------------------------------------------------------------------
00031     
00032     void NoiseOccupancyAlgorithm::init() throw(){
00033     if (getTestResult().get()==0){
00034         setTestResult(shared_ptr<TestResult>(new NoiseOccupancyTestResult() ));
00035         initializeTestResult();
00036     }
00037     }
00038 
00039     void NoiseOccupancyAlgorithm::canAddFitScanResult(const string& name) throw(Sct::LogicError, Sct::IoError){
00040     init();
00041     addFit(name);
00042     analyze();
00043     }
00044 
00045     void NoiseOccupancyAlgorithm::canAddRawScanResult(const string& name) throw(Sct::LogicError, Sct::IoError){
00046     init();
00047     addRaw(name);
00048     analyze();
00049     }
00050 
00051     void NoiseOccupancyAlgorithm::analyze() throw(Sct::LogicError){
00052     if (!getTestResult()->hasAllFits() || !getTestResult()->hasAllRaws() ) return;
00053 
00054     shared_ptr<NoiseOccupancyTestResult> result = dynamic_pointer_cast<NoiseOccupancyTestResult>(getTestResult());
00055 
00056     const ModuleConfiguration config=result->getRaw(0)->getConfiguration();
00057     
00058     //Loop over chips
00059     for (unsigned int ichip=0; ichip<nChipModule; ++ichip) {
00060         // get an raw result occupany projector 
00061         OccupancyProjector opr(*result->getRaw(0) );
00062         opr.vetoSevereDefects(result->getFit(0)->getDefects());
00063         // get the chip configuration
00064         const ChipConfiguration& chipconfig=config.getChipConfiguration(ichip);
00065         // get the new defects
00066         ModuleDefectList& defects = result->getDefects();
00067         result->getChipResult(ichip) = analyzeChip(ichip, opr, chipconfig, defects);
00068         result->getChipResult(ichip).offset = result->getFit(0)->getChipFit(ichip).getParameter(1);
00069     }
00070     result->setPassed(true);
00071     finish();
00072     }
00073     
00074     ChipNOResult NoiseOccupancyAlgorithm::analyzeChip(const unsigned ichip, const OccupancyProjector& opr, const ChipConfiguration& chipconfig, ModuleDefectList& defects) throw(LogicError){
00075     
00076     auto_ptr<TH1> occ = opr.getOccupancy("temp", Chip(ichip)) ;
00077     auto_ptr<ResponseCurve> rc = ResponseCurveMap::getMap().get(chipconfig);
00078     shared_ptr<TF1> invFn = rc->getInverseFunction();
00079     
00080     //cout << "Response Curve params: " << chipconfig.getRcParam(0) << "  " << chipconfig.getRcParam(1) << "  " << chipconfig.getRcParam(2) << endl;
00081     
00082     // Construct TGraph of log occupancy against thr^2
00083     // project raw data from scan 0 of the test
00084     // Construction of TGraphAsymmetricErrors in this way because root is so 
00085     // inefficient at re-allocating memory for graphs
00086     double x[occ->GetNbinsX()];
00087     double xUpperErr[occ->GetNbinsX()];
00088     double xLowerErr[occ->GetNbinsX()];
00089     double yUpperErr[occ->GetNbinsX()];
00090     double yLowerErr[occ->GetNbinsX()];
00091     double y[occ->GetNbinsX()];
00092     int nBins = 0;
00093     
00094     double factor = 1;//11.3;  //warning - Should be 1.  Use 11.3 to simulate SCTDAQ
00095     
00096     for(int bin=1; bin<=occ->GetNbinsX(); ++bin){
00097         //We only want the "bottom" half of the threshold scan (occupancy < 50%)
00098         if (occ->GetBinContent(bin) > 0 && occ->GetBinContent(bin) < 0.5 ) {
00099         y[nBins] = log(occ->GetBinContent(bin));            
00100         yUpperErr[nBins] = log(occ->GetBinContent(bin) + factor*occ->GetBinError(bin)) - y[nBins];
00101         if (occ->GetBinContent(bin) - factor*occ->GetBinError(bin) > 0) {
00102             yLowerErr[nBins] = y[nBins] - log(occ->GetBinContent(bin) - factor*occ->GetBinError(bin));
00103         } else {
00104             yLowerErr[nBins] = yUpperErr[nBins];//occ->GetBinContent(bin);
00105             //yLowerErr[nBins] = 50;
00106             //cout << yLowerErr[nBins] << endl;         
00107         } 
00108         
00109         //Convert thr in mV to thr in fC
00110         x[nBins] = invFn->Eval(occ->GetBinCenter(bin));
00111         x[nBins] *= x[nBins];
00112         xUpperErr[nBins] = xLowerErr[nBins] = 0;            
00113                 
00114         nBins++;
00115         }
00116     }
00117     shared_ptr<TGraphAsymmErrors> g( new TGraphAsymmErrors(nBins, x, y, xLowerErr, xUpperErr, yLowerErr, yUpperErr));
00118     
00120     auto_ptr<TF1> f = NoiseOccupancyTestResult::createFitFunction();
00121 
00122 //  AnalysisService::instance().getFitStrategy().fitTGraphAsymmErrors(*g, *f);
00123     g->Fit(f.get(), "NQR");
00124 
00125     // Calculate mean and RMS NO at 1fC for channels in this chip
00126     Stats<double> occAtOnefC(nChannelChip);
00127     for (unsigned ichan=0; ichan < nChannelChip ; ++ichan ){
00128         unsigned channelInModule = ichip*nChannelChip + ichan;
00129 
00130         // get chip projection:
00131         char name[10];
00132         sprintf(name,"temp%d",channelInModule);
00133         auto_ptr<TH1> occChannel = opr.getOccupancy(name, Channel(channelInModule)) ;
00134         // find 1 fC point:
00135         double vthr = rc->getFunction()->Eval(1.);
00136         int bin = occChannel->GetXaxis()->FindBin(vthr);
00137 
00138 //      cout << "Vthr=" << vthr << " bin="<<bin<<endl;
00139         occAtOnefC.modifyAt(ichan).value = occChannel->GetBinContent(bin);
00140         
00141 //      cout << ichip << "\t " << ichan << "\t" << occAtOnefC.getAt(ichan).value << endl;
00142         
00143         // check for defects:
00144         if (occAtOnefC.getAt(ichan).value > ModuleDefect::NO_HI.getParameter() ){
00145         defects.addDefect(ModuleDefect::NO_HI,Channel(channelInModule));
00146                 occAtOnefC.modifyAt(ichan).valid=false;
00147         }
00148     }
00149     double mean = occAtOnefC.mean();
00150 //  cout << "NoiseOcc mean = " << mean << endl;
00151     double rms  = sqrt( occAtOnefC.var() );
00152     
00153     return ChipNOResult(g,shared_ptr<TF1>(f),mean,rms);
00154     }
00155 } // end of namespace SctAnalysis

Generated on Mon Dec 15 19:36:08 2003 for SCT DAQ/DCS Software by doxygen1.3-rc3