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
00057
00058 for (unsigned int ichip=0; ichip<nChipModule; ++ichip) {
00059
00060 OccupancyProjector opr(*getRaw(0) );
00061 opr.vetoSeriousDefects(getFit(0)->getDefects());
00062
00063 const ChipConfiguration& chipconfig=config.getChipConfiguration(ichip);
00064
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
00098
00099
00100 int ttbin=-1;
00101 int fcbin=-1;
00102
00103 const float mVstep=2.5;
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
00122
00123
00124
00125
00126
00127
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;
00137
00138 for(int bin=1; bin<=occ->GetNbinsX(); ++bin){
00139
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];
00147
00148
00149 }
00150
00151
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
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
00187
00188 g->Fit(f.get(), "NQR");
00189
00190
00191 Stats<double> occAtOnefC(nChannelChip);
00192 for (unsigned ichan=0; ichan < nChannelChip ; ++ichan ){
00193 unsigned channelInModule = ichip*nChannelChip + ichan;
00194
00195
00196 char name[10];
00197 sprintf(name,"temp%d",channelInModule);
00198 auto_ptr<TH1> occChannel = opr.getOccupancy(name, ModuleElement::Channel(channelInModule)) ;
00199
00200
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
00221 occAtOnefC.modifyAt(ichan).value = occChannel->GetBinContent(bin);
00222
00223
00224
00225
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
00233 double rms = sqrt( occAtOnefC.var() );
00234
00235 return ChipNOResult(g,shared_ptr<TF1>(f),mean,rms);
00236 }
00237 }