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

NoiseOccupancyAlgorithm.cpp

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/StandardDefects.h"
00011 #include "SctData/ConfigurationVariable.h"
00012 #include "Sct/UnsupportedOperationError.h"
00013 #include <CommonWithDsp/ABCD/ABCDscans.h>
00014 #include <TH1.h>
00015 #include <TGraphAsymmErrors.h>
00016 #include <string>
00017 
00018 using namespace std;
00019 using namespace boost;
00020 using namespace SctData;
00021 using namespace Sct;
00022 
00023 namespace SctAnalysis {
00024     
00025     NoiseOccupancyAlgorithm::~NoiseOccupancyAlgorithm() throw() {}
00026 
00027     shared_ptr<AnalysisAlgorithm> NoiseOccupancyAlgorithm::clone(const TestData& testData, const string& moduleName) const throw() {
00028     return shared_ptr<AnalysisAlgorithm>(new NoiseOccupancyAlgorithm(testData, moduleName, *this));
00029     }
00030 
00031     bool NoiseOccupancyAlgorithm::inMap = AnalysisAlgorithmMap::instance().setAlgorithm("NoiseOccupancyTest", auto_ptr<AnalysisAlgorithm>(new NoiseOccupancyAlgorithm()));
00032 
00033     //----------------------------------------------------------------------
00034     
00035     void NoiseOccupancyAlgorithm::loadData() {
00036     loadAllRaws();
00037     loadAllFits();
00038     }
00039     
00040     bool NoiseOccupancyAlgorithm::canAnalyze() const {
00041     return hasAllFits() && hasAllRaws();
00042     }
00043     
00044     shared_ptr<SctData::TestResult> NoiseOccupancyAlgorithm::createTestResult() const {
00045     return shared_ptr<TestResult>(new NoiseOccupancyTestResult());
00046     }
00047 
00048     void NoiseOccupancyAlgorithm::analyze() {
00049     shared_ptr<NoiseOccupancyTestResult> result = dynamic_pointer_cast<NoiseOccupancyTestResult>(getTestResult());
00050     const SctData::ConfigurationVariable& scanVariable = getRaw(0)->getHeader().getVariable();
00051     result->setScanVariable(scanVariable);
00052     const ModuleConfiguration config=getRaw(0)->getConfiguration();
00053     
00054     m_scanVariable = SctData::ConfigurationVariableIOHelper::getTypeRep(scanVariable);
00055     
00056     //cout << " NoiseOccupancyAlgorithm::analyze()" << endl;
00057     //Loop over chips
00058     for (unsigned int ichip=0; ichip<nChipModule; ++ichip) {
00059         // get an raw result occupany projector 
00060         OccupancyProjector opr(*getRaw(0) );
00061         opr.vetoSeriousDefects(getFit(0)->getDefects());
00062         // get the chip configuration
00063         const ChipConfiguration& chipconfig=config.getChipConfiguration(ichip);
00064         // get the new defects
00065         DefectList& defects = result->getDefects();
00066         result->getChipResult(ichip) = analyzeChip(ichip, opr, chipconfig, defects);
00067 
00068         const float fittedOffset = getFit(0)->getChipFit(ichip).getParameter(1);
00069         switch(m_scanVariable) {
00070         case ST_VTHR:
00071         result->getChipResult(ichip).offset = fittedOffset;
00072         break;
00073         case ST_TTHR:
00074         result->getChipResult(ichip).offset = fittedOffset + config.getChipConfiguration(ichip).getTrimTarget()*2.5;
00075         break;
00076         case ST_QTHR: {
00077         auto_ptr<ResponseCurve> rc = ResponseCurveMap::getMap().get(config.getChipConfiguration(ichip));
00078         result->getChipResult(ichip).offset = rc->getFunction()->Eval(fittedOffset);
00079             }
00080         break;
00081         default: {
00082             ostringstream oss;
00083         oss << "Internal Error: NoiseOccupancy Algorithm doesn't know how to deal with scan of type : " << m_scanVariable;
00084         throw Sct::UnsupportedOperationError(oss.str(), __FILE__, __LINE__);
00085             }
00086         }
00087     }
00088     result->setPassed(true);
00089     }
00090     
00091     ChipNOResult NoiseOccupancyAlgorithm::analyzeChip(const unsigned ichip, const OccupancyProjector& opr, const ChipConfiguration& chipconfig, DefectList& defects) {
00092     
00093     auto_ptr<TH1> occ = opr.getOccupancy("temp", ModuleElement::Chip(ichip)) ;
00094     auto_ptr<ResponseCurve> rc = ResponseCurveMap::getMap().get(chipconfig);
00095     shared_ptr<TF1> invFn = rc->getInverseFunction();
00096     
00097     //cout << "Config RC: " << (int)chipconfig.getRcFunctionIndex() << " params: " << chipconfig.getRcParam(0) << "  " << chipconfig.getRcParam(1) << "  " << chipconfig.getRcParam(2) << endl;
00098     //cout << "RC: " << rc->getIndex() << " params: " << rc->getFunction()->GetParameter(0) << "  " << rc->getFunction()->GetParameter(1) << "  " << rc->getFunction()->GetParameter(2) << endl;
00099 
00100     int ttbin=-1; //< trim target bin
00101     int fcbin=-1; //< 1 fC bin
00102 
00103     const float mVstep=2.5;  // number of mv per threshold step
00104     const float trimTargetmV=chipconfig.getTrimTarget()*mVstep;
00105 
00106     if (m_scanVariable==ST_VTHR){
00107       ttbin = occ->GetXaxis()->FindBin(chipconfig.getTrimTarget()*mVstep);
00108       fcbin = occ->GetXaxis()->FindBin(rc->getFunction()->Eval(1.));
00109     }else if(m_scanVariable==ST_TTHR){
00110       ttbin = occ->GetXaxis()->FindBin(0.);
00111       fcbin = occ->GetXaxis()->FindBin(rc->getFunction()->Eval(1.)-trimTargetmV);
00112     }else if(m_scanVariable==ST_QTHR){
00113       ttbin = occ->GetXaxis()->FindBin(invFn->Eval(trimTargetmV));
00114       fcbin = occ->GetXaxis()->FindBin(1.);
00115     }else{
00116       ostringstream oss;
00117       oss << "Internal Error: NoiseOccupancy Algorithm doesn't know how to deal with scan of type : " << m_scanVariable;
00118       throw Sct::UnsupportedOperationError(oss.str(), __FILE__, __LINE__);
00119     }
00120 
00121     //cout << "TrimTarget: " << chipconfig.getTrimTarget()*2.5 << " mV, bin: " << ttbin << " Occ: " << occ->GetBinContent(ttbin) << endl;
00122     //cout << "1fC: " << rc->getFunction()->Eval(1.) << " mV, bin: " << fcbin << " Occ: " << occ->GetBinContent(fcbin) << endl;
00123     
00124     // Construct TGraph of log occupancy against thr^2
00125     // project raw data from scan 0 of the test
00126     // Construction of TGraphAsymmetricErrors in this way because root is so 
00127     // inefficient at re-allocating memory for graphs
00128     double x[occ->GetNbinsX()];
00129     double xUpperErr[occ->GetNbinsX()];
00130     double xLowerErr[occ->GetNbinsX()];
00131     double yUpperErr[occ->GetNbinsX()];
00132     double yLowerErr[occ->GetNbinsX()];
00133     double y[occ->GetNbinsX()];
00134     unsigned int nBins = 0;
00135     
00136     double factor = 1;//11.3;  //warning - Should be 1.  Use 11.3 to simulate SCTDAQ
00137     
00138     for(int bin=1; bin<=occ->GetNbinsX(); ++bin){
00139         //We only want the "bottom" half of the threshold scan (occupancy < 50%)
00140         if (occ->GetBinContent(bin) > 0 && occ->GetBinContent(bin) < 0.5 ) {
00141         y[nBins] = log(occ->GetBinContent(bin));            
00142         yUpperErr[nBins] = log(occ->GetBinContent(bin) + factor*occ->GetBinError(bin)) - y[nBins];
00143         if (occ->GetBinContent(bin) - factor*occ->GetBinError(bin) > 0) {
00144             yLowerErr[nBins] = y[nBins] - log(occ->GetBinContent(bin) - factor*occ->GetBinError(bin));
00145         } else {
00146             yLowerErr[nBins] = yUpperErr[nBins];//occ->GetBinContent(bin);
00147             //yLowerErr[nBins] = 50;
00148             //cout << yLowerErr[nBins] << endl;         
00149         } 
00150         
00151         //Convert into fC:
00152         switch(m_scanVariable) {
00153         case ST_VTHR:
00154             x[nBins] = invFn->Eval(occ->GetBinCenter(bin));
00155             break;
00156         case ST_TTHR:
00157             x[nBins] = invFn->Eval(occ->GetBinCenter(bin)+trimTargetmV);
00158             break;
00159         case ST_QTHR:
00160             x[nBins] = occ->GetBinCenter(bin);
00161             break;
00162         default:
00163             ostringstream oss;
00164             oss << "Internal Error: NoiseOccupancy Algorithm doesn't know how to deal with scan of type : " << m_scanVariable;
00165             throw Sct::UnsupportedOperationError(oss.str(), __FILE__, __LINE__);
00166         }
00167         
00168         x[nBins] *= x[nBins];
00169         xUpperErr[nBins] = xLowerErr[nBins] = 0;            
00170                 
00171         nBins++;
00172         }
00173     }
00174 
00175         auto_ptr<TF1> f = NoiseOccupancyTestResult::createFitFunction();
00176 
00177         //Check for a dead chip
00178         if (nBins == 0) {
00179             defects.addDefect(Defect(StandardDefects::DEAD, ModuleElement::Chip(ichip)));
00180             shared_ptr<TGraphAsymmErrors> g( new TGraphAsymmErrors());
00181             return ChipNOResult(g, shared_ptr<TF1>(f), 0, 0);
00182         }
00183 
00184     shared_ptr<TGraphAsymmErrors> g( new TGraphAsymmErrors(nBins, x, y, xLowerErr, xUpperErr, yLowerErr, yUpperErr));
00185 
00186     //Don't use FitStrategy because there is no asymm errors method
00187 //  AnalysisService::instance().getFitStrategy().fitTGraphAsymmErrors(*g, *f);
00188     g->Fit(f.get(), "NQR");
00189 
00190     // Calculate mean and RMS NO at 1fC for channels in this chip
00191     Stats<double> occAtOnefC(nChannelChip);
00192     for (unsigned ichan=0; ichan < nChannelChip ; ++ichan ){
00193         unsigned channelInModule = ichip*nChannelChip + ichan;
00194 
00195         // get chip projection:
00196         char name[10];
00197         sprintf(name,"temp%d",channelInModule);
00198         auto_ptr<TH1> occChannel = opr.getOccupancy(name, ModuleElement::Channel(channelInModule)) ;
00199         
00200         // find 1 fC point - gets threshold in mV
00201         int bin = 0;
00202         switch(m_scanVariable) {
00203         case ST_VTHR: {
00204         double vthr = rc->getFunction()->Eval(1.);
00205         bin = occChannel->GetXaxis()->FindBin(vthr);        
00206             } break;
00207         case ST_TTHR: {
00208         double vthr = rc->getFunction()->Eval(1.);
00209         bin = occChannel->GetXaxis()->FindBin(vthr-trimTargetmV);       
00210             } break;
00211         case ST_QTHR:
00212         bin = occChannel->GetXaxis()->FindBin(1.0);
00213         break;
00214         default:
00215         ostringstream oss;
00216         oss << "Internal Error: NoiseOccupancy Algorithm doesn't know how to deal with scan of type : " << m_scanVariable;
00217         throw Sct::UnsupportedOperationError(oss.str(), __FILE__, __LINE__);
00218         }       
00219         
00220         //cout << "Thr bin="<<bin<<endl;
00221         occAtOnefC.modifyAt(ichan).value = occChannel->GetBinContent(bin);
00222         
00223         //cout << ichip << "\t " << ichan << "\t" << occAtOnefC.getAt(ichan).value << endl;
00224         
00225         // check for defects:
00226         if (occAtOnefC.getAt(ichan).value > StandardDefects::NO_HI.getParameter() ){
00227         defects.addDefect(Defect(StandardDefects::NO_HI, ModuleElement::Channel(channelInModule)));
00228                 occAtOnefC.modifyAt(ichan).valid=false;
00229         }
00230     }
00231     double mean = occAtOnefC.mean();
00232     //cout << "NoiseOcc mean = " << mean << endl;
00233     double rms  = sqrt( occAtOnefC.var() );
00234     
00235     return ChipNOResult(g,shared_ptr<TF1>(f),mean,rms);
00236     }
00237 } // end of namespace SctAnalysis

Generated on Thu Jul 15 09:50:48 2004 for SCT DAQ/DCS Software - C++ by doxygen 1.3.5