00001 #include "NoiseOccupancyAlgorithm.h"
00002 #include "AnalysisAlgorithmMap.h"
00003 #include "AnalysisService.h"
00004 #include "OpeTool.h"
00005 #include "SctData/Stat.h"
00006 #include "SctData/NoiseOccupancyTestResult.h"
00007 #include "SctData/OccupancyProjector.h"
00008 #include "SctData/FitScanResult.h"
00009 #include "SctData/FitObject.h"
00010 #include "SctData/ResponseCurve.h"
00011 #include "SctData/StandardDefects.h"
00012 #include "SctData/ConfigurationVariable.h"
00013 #include "Sct/UnsupportedOperationError.h"
00014 #include <CommonWithDsp/ABCD/ABCDscans.h>
00015 #include <TH1.h>
00016 #include <TGraphAsymmErrors.h>
00017 #include <string>
00018
00019 using namespace std;
00020 using namespace boost;
00021 using namespace SctData;
00022 using namespace Sct;
00023
00024 namespace SctAnalysis {
00025
00026 NoiseOccupancyAlgorithm::~NoiseOccupancyAlgorithm() throw() {}
00027
00028 shared_ptr<AnalysisAlgorithm> NoiseOccupancyAlgorithm::clone(const TestData& testData, const string& moduleName) const throw() {
00029 return shared_ptr<AnalysisAlgorithm>(new NoiseOccupancyAlgorithm(testData, moduleName, *this));
00030 }
00031
00032 bool NoiseOccupancyAlgorithm::inMap = AnalysisAlgorithmMap::instance().setAlgorithm("NoiseOccupancyTest", auto_ptr<AnalysisAlgorithm>(new NoiseOccupancyAlgorithm()));
00033
00034
00035
00036 void NoiseOccupancyAlgorithm::loadData() {
00037 loadAllRaws();
00038 loadAllFits();
00039 }
00040
00041 bool NoiseOccupancyAlgorithm::canAnalyze() const {
00042 return hasAllFits() && hasAllRaws();
00043 }
00044
00045 shared_ptr<SctData::TestResult> NoiseOccupancyAlgorithm::createTestResult() const {
00046 return shared_ptr<TestResult>(new NoiseOccupancyTestResult());
00047 }
00048
00049 void NoiseOccupancyAlgorithm::analyze() {
00050 shared_ptr<NoiseOccupancyTestResult> result = dynamic_pointer_cast<NoiseOccupancyTestResult>(getTestResult());
00051 const SctData::ConfigurationVariable& scanVariable = getRaw(0)->getHeader().getVariable();
00052 result->setScanVariable(scanVariable);
00053 const ModuleConfiguration config=getRaw(0)->getConfiguration();
00054
00055 m_scanVariable = SctData::ConfigurationVariableIOHelper::getTypeRep(scanVariable);
00056
00057
00058
00059 for (unsigned int ichip=0; ichip<nChipModule; ++ichip) {
00060
00061 OccupancyProjector opr(*getRaw(0) );
00062
00063 DefectList& fitdefects=getFit(0)->getDefects();
00064
00065
00066 if (fitdefects.defectSeverityAffectingElement(ModuleElement::Module()) < SERIOUS ) opr.vetoSeriousDefects(fitdefects);
00067
00068
00069 const ChipConfiguration& chipconfig=config.getChipConfiguration(ichip);
00070
00071 DefectList& defects = result->getDefects();
00072 result->getChipResult(ichip) = analyzeChip(ichip, opr, chipconfig, defects);
00073
00074 const float fittedOffset = getFit(0)->getChipFit(ichip).getParameter(1);
00075 switch(m_scanVariable) {
00076 case ST_VTHR:
00077 result->getChipResult(ichip).offset = fittedOffset;
00078 break;
00079 case ST_TTHR:
00080 result->getChipResult(ichip).offset = fittedOffset + config.getChipConfiguration(ichip).getTrimTarget()*2.5;
00081 break;
00082 case ST_QTHR: {
00083 auto_ptr<ResponseCurve> rc = ResponseCurveMap::getMap().get(config.getChipConfiguration(ichip));
00084 result->getChipResult(ichip).offset = rc->getFunction()->Eval(fittedOffset);
00085 }
00086 break;
00087 default: {
00088 ostringstream oss;
00089 oss << "Internal Error: NoiseOccupancy Algorithm doesn't know how to deal with scan of type : " << m_scanVariable;
00090 throw Sct::UnsupportedOperationError(oss.str(), __FILE__, __LINE__);
00091 }
00092 }
00093 }
00094 OpeTool tool;
00095 shared_ptr<SctData::OpeResult> ope = tool.analyzeModule(*getRaw(0));
00096 result->setOpeResult(ope);
00097 result->setPassed(true);
00098
00099
00100 if (ope.get()) {
00101 for (unsigned int ichip=0; ichip<nChipModule; ++ichip) {
00102 SctData::ChipOpeResult& chipOpe=ope->getChipResult(ichip);
00103 if (chipOpe.badmax > 2.0) {
00104 result->getDefects().addDefect(Defect(StandardDefects::BAD_OPE, ModuleElement::Chip(ichip)));
00105 result->setProblem(true);
00106 }
00107 }
00108 }
00109 }
00110
00111 ChipNOResult NoiseOccupancyAlgorithm::analyzeChip(const unsigned ichip, const OccupancyProjector& opr, const ChipConfiguration& chipconfig, DefectList& defects) {
00112
00113 auto_ptr<TH1> occ = opr.getOccupancy("temp", ModuleElement::Chip(ichip)) ;
00114 auto_ptr<ResponseCurve> rc = ResponseCurveMap::getMap().get(chipconfig);
00115 shared_ptr<TF1> invFn = rc->getInverseFunction();
00116
00117
00118
00119
00120 int ttbin=-1;
00121 int fcbin=-1;
00122
00123 const float mVstep=2.5;
00124 const float trimTargetmV=chipconfig.getTrimTarget()*mVstep;
00125
00126 if (m_scanVariable==ST_VTHR){
00127 ttbin = occ->GetXaxis()->FindBin(chipconfig.getTrimTarget()*mVstep);
00128 fcbin = occ->GetXaxis()->FindBin(rc->getFunction()->Eval(1.));
00129 }else if(m_scanVariable==ST_TTHR){
00130 ttbin = occ->GetXaxis()->FindBin(0.);
00131 fcbin = occ->GetXaxis()->FindBin(rc->getFunction()->Eval(1.)-trimTargetmV);
00132 }else if(m_scanVariable==ST_QTHR){
00133 ttbin = occ->GetXaxis()->FindBin(invFn->Eval(trimTargetmV));
00134 fcbin = occ->GetXaxis()->FindBin(1.);
00135 }else{
00136 ostringstream oss;
00137 oss << "Internal Error: NoiseOccupancy Algorithm doesn't know how to deal with scan of type : " << m_scanVariable;
00138 throw Sct::UnsupportedOperationError(oss.str(), __FILE__, __LINE__);
00139 }
00140
00141
00142
00143
00144
00145
00146
00147
00148 double x[occ->GetNbinsX()];
00149 double xUpperErr[occ->GetNbinsX()];
00150 double xLowerErr[occ->GetNbinsX()];
00151 double yUpperErr[occ->GetNbinsX()];
00152 double yLowerErr[occ->GetNbinsX()];
00153 double y[occ->GetNbinsX()];
00154 unsigned int nBins = 0;
00155
00156 double factor = 1;
00157
00158 for(int bin=1; bin<=occ->GetNbinsX(); ++bin){
00159
00160 if (occ->GetBinContent(bin) > 0 && occ->GetBinContent(bin) < 0.5 ) {
00161 y[nBins] = log(occ->GetBinContent(bin));
00162 yUpperErr[nBins] = log(occ->GetBinContent(bin) + factor*occ->GetBinError(bin)) - y[nBins];
00163 if (occ->GetBinContent(bin) - factor*occ->GetBinError(bin) > 0) {
00164 yLowerErr[nBins] = y[nBins] - log(occ->GetBinContent(bin) - factor*occ->GetBinError(bin));
00165 } else {
00166 yLowerErr[nBins] = yUpperErr[nBins];
00167
00168
00169 }
00170
00171
00172 switch(m_scanVariable) {
00173 case ST_VTHR:
00174 x[nBins] = invFn->Eval(occ->GetBinCenter(bin));
00175 break;
00176 case ST_TTHR:
00177 x[nBins] = invFn->Eval(occ->GetBinCenter(bin)+trimTargetmV);
00178 break;
00179 case ST_QTHR:
00180 x[nBins] = occ->GetBinCenter(bin);
00181 break;
00182 default:
00183 ostringstream oss;
00184 oss << "Internal Error: NoiseOccupancy Algorithm doesn't know how to deal with scan of type : " << m_scanVariable;
00185 throw Sct::UnsupportedOperationError(oss.str(), __FILE__, __LINE__);
00186 }
00187
00188 x[nBins] *= x[nBins];
00189 xUpperErr[nBins] = xLowerErr[nBins] = 0;
00190
00191 nBins++;
00192 }
00193 }
00194
00195 auto_ptr<TF1> f = NoiseOccupancyTestResult::createFitFunction();
00196
00197
00198 if (nBins == 0 && defects.defectSeverityEncompassingElement(ModuleElement::Chip(ichip)) < SERIOUS ) {
00199 defects.addDefect(Defect(StandardDefects::DEAD, ModuleElement::Chip(ichip)));
00200 shared_ptr<TGraphAsymmErrors> g( new TGraphAsymmErrors());
00201 return ChipNOResult(g, shared_ptr<TF1>(f), 0, 0);
00202 }
00203
00204 shared_ptr<TGraphAsymmErrors> g( new TGraphAsymmErrors(nBins, x, y, xLowerErr, xUpperErr, yLowerErr, yUpperErr));
00205
00206
00207
00208 g->Fit(f.get(), "NQR");
00209
00210
00211 Stats<double> occAtOnefC(nChannelChip);
00212 for (unsigned ichan=0; ichan < nChannelChip ; ++ichan ){
00213 unsigned channelInModule = ichip*nChannelChip + ichan;
00214
00215
00216 char name[10];
00217 sprintf(name,"temp%d",channelInModule);
00218 auto_ptr<TH1> occChannel = opr.getOccupancy(name, ModuleElement::Channel(channelInModule)) ;
00219
00220
00221 int bin = 0;
00222 switch(m_scanVariable) {
00223 case ST_VTHR: {
00224 double vthr = rc->getFunction()->Eval(1.);
00225 bin = occChannel->GetXaxis()->FindBin(vthr);
00226 } break;
00227 case ST_TTHR: {
00228 double vthr = rc->getFunction()->Eval(1.);
00229 bin = occChannel->GetXaxis()->FindBin(vthr-trimTargetmV);
00230 } break;
00231 case ST_QTHR:
00232 bin = occChannel->GetXaxis()->FindBin(1.0);
00233 break;
00234 default:
00235 ostringstream oss;
00236 oss << "Internal Error: NoiseOccupancy Algorithm doesn't know how to deal with scan of type : " << m_scanVariable;
00237 throw Sct::UnsupportedOperationError(oss.str(), __FILE__, __LINE__);
00238 }
00239
00240
00241 occAtOnefC.modifyAt(ichan).value = occChannel->GetBinContent(bin);
00242
00243
00244
00245
00246 if (occAtOnefC.getAt(ichan).value > StandardDefects::NO_HI.getParameter() ){
00247 defects.addDefect(Defect(StandardDefects::NO_HI, ModuleElement::Channel(channelInModule)));
00248 occAtOnefC.modifyAt(ichan).valid=false;
00249 }
00250 }
00251 double mean = occAtOnefC.mean();
00252
00253 double rms = sqrt( occAtOnefC.var() );
00254
00255 return ChipNOResult(g,shared_ptr<TF1>(f),mean,rms);
00256 }
00257 }