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 <Sct/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(shared_ptr<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 debug=false;
00051 shared_ptr<NoiseOccupancyTestResult> result = dynamic_pointer_cast<NoiseOccupancyTestResult>(getTestResult());
00052 const SctData::ConfigurationVariable& scanVariable = getRaw(0)->getHeader().getVariable();
00053 result->setScanVariable(scanVariable);
00054 const ModuleConfiguration config=getRaw(0)->getConfiguration();
00055
00056 m_scanVariable = SctData::ConfigurationVariableIOHelper::getTypeRep(scanVariable);
00057
00058
00059
00060 for (unsigned int ichip=0; ichip<nChipModule; ++ichip) {
00061
00062 OccupancyProjector opr(*getRaw(0) );
00063
00064 DefectList& fitdefects=getFit(0)->getDefects();
00065
00066
00067 if (fitdefects.defectSeverityAffectingElement(ModuleElement::Module()) < SERIOUS ) opr.vetoSeriousDefects(fitdefects);
00068
00069
00070 const ChipConfiguration& chipconfig=config.getChipConfiguration(ichip);
00071
00072 DefectList& defects = result->getDefects();
00073 result->getChipResult(ichip) = analyzeChip(ichip, opr, chipconfig, defects);
00074
00075 const float fittedOffset = getFit(0)->getChipFit(ichip).getParameter(1);
00076 switch(m_scanVariable) {
00077 case ST_VTHR:
00078 result->getChipResult(ichip).offset = fittedOffset;
00079 break;
00080 case ST_TTHR:
00081 result->getChipResult(ichip).offset = fittedOffset + config.getChipConfiguration(ichip).getTrimTarget()*2.5;
00082 break;
00083 case ST_QTHR: {
00084 auto_ptr<ResponseCurve> rc = ResponseCurveMap::getMap().get(config.getChipConfiguration(ichip));
00085 result->getChipResult(ichip).offset = rc->getFunction()->Eval(fittedOffset);
00086 }
00087 break;
00088 default: {
00089 ostringstream oss;
00090 oss << "Internal Error: NoiseOccupancy Algorithm doesn't know how to deal with scan of type : " << m_scanVariable;
00091 throw Sct::UnsupportedOperationError(oss.str(), __FILE__, __LINE__);
00092 }
00093 }
00094 }
00095 OpeTool tool;
00096 shared_ptr<SctData::OpeResult> ope = tool.analyzeModule(*getRaw(0));
00097 result->setOpeResult(ope);
00098 result->setPassed(true);
00099
00100
00101 if (ope.get()) {
00102 for (unsigned int ichip=0; ichip<nChipModule; ++ichip) {
00103 SctData::ChipOpeResult& chipOpe=ope->getChipResult(ichip);
00104 if (chipOpe.badmax > 2.0) {
00105 result->getDefects().addDefect(Defect(StandardDefects::BAD_OPE, ModuleElement::Chip(ichip)));
00106 result->setProblem(true);
00107 }
00108 }
00109 }
00110 }
00111
00112
00113
00114 ChipNOResult NoiseOccupancyAlgorithm::analyzeChip(const unsigned ichip, const OccupancyProjector& opr, const ChipConfiguration& chipconfig, DefectList& defects) {
00115
00116 auto_ptr<TH1> occ = opr.getOccupancy("temp", ModuleElement::Chip(ichip)) ;
00117 auto_ptr<ResponseCurve> rc = ResponseCurveMap::getMap().get(chipconfig);
00118 shared_ptr<TF1> invFn = rc->getInverseFunction();
00119
00120 if (debug) cout << "Config RC: " << (int)chipconfig.getRcFunctionIndex() << " params: " << chipconfig.getRcParam(0) << " " << chipconfig.getRcParam(1) << " " << chipconfig.getRcParam(2) << endl;
00121 if (debug) cout << "RC: " << rc->getIndex() << " params: " << rc->getFunction()->GetParameter(0) << " " << rc->getFunction()->GetParameter(1) << " " << rc->getFunction()->GetParameter(2) << endl;
00122
00123 int ttbin=-1;
00124 int fcbin=-1;
00125
00126 const float mVstep=2.5;
00127 const float trimTargetmV=chipconfig.getTrimTarget()*mVstep;
00128
00129 if (m_scanVariable==ST_VTHR){
00130 ttbin = occ->GetXaxis()->FindBin(chipconfig.getTrimTarget()*mVstep);
00131 fcbin = occ->GetXaxis()->FindBin(rc->getFunction()->Eval(1.));
00132 }else if(m_scanVariable==ST_TTHR){
00133 ttbin = occ->GetXaxis()->FindBin(0.);
00134 fcbin = occ->GetXaxis()->FindBin(rc->getFunction()->Eval(1.)-trimTargetmV);
00135 }else if(m_scanVariable==ST_QTHR){
00136 ttbin = occ->GetXaxis()->FindBin(invFn->Eval(trimTargetmV));
00137 fcbin = occ->GetXaxis()->FindBin(1.);
00138 }else{
00139 ostringstream oss;
00140 oss << "Internal Error: NoiseOccupancy Algorithm doesn't know how to deal with scan of type : " << m_scanVariable;
00141 throw Sct::UnsupportedOperationError(oss.str(), __FILE__, __LINE__);
00142 }
00143
00144 if (debug) cout << "TrimTarget: " << chipconfig.getTrimTarget()*2.5 << " mV, bin: " << ttbin << " Occ: " << occ->GetBinContent(ttbin) << endl;
00145 if (debug) cout << "1fC: " << rc->getFunction()->Eval(1.) << " mV, bin: " << fcbin << " Occ: " << occ->GetBinContent(fcbin) << endl;
00146
00147
00148
00149
00150
00151 double x[occ->GetNbinsX()];
00152 double xUpperErr[occ->GetNbinsX()];
00153 double xLowerErr[occ->GetNbinsX()];
00154 double yUpperErr[occ->GetNbinsX()];
00155 double yLowerErr[occ->GetNbinsX()];
00156 double y[occ->GetNbinsX()];
00157 unsigned int nBins = 0;
00158
00159 double factor = 1;
00160
00161 for(int bin=1; bin<=occ->GetNbinsX(); ++bin){
00162
00163 if (occ->GetBinContent(bin) > 0 && occ->GetBinContent(bin) < 0.5 ) {
00164 y[nBins] = log(occ->GetBinContent(bin));
00165 yUpperErr[nBins] = log(occ->GetBinContent(bin) + factor*occ->GetBinError(bin)) - y[nBins];
00166 if (occ->GetBinContent(bin) - factor*occ->GetBinError(bin) > 0) {
00167 yLowerErr[nBins] = y[nBins] - log(occ->GetBinContent(bin) - factor*occ->GetBinError(bin));
00168 } else {
00169 yLowerErr[nBins] = yUpperErr[nBins];
00170
00171
00172 }
00173
00174
00175 switch(m_scanVariable) {
00176
00177 case ST_VTHR:
00178 x[nBins] = invFn->Eval((int)((occ->GetBinCenter(bin)+1.25)/2.5)*2.5);
00179 break;
00180 case ST_TTHR:
00181 x[nBins] = invFn->Eval((int)((occ->GetBinCenter(bin)+1.25)/2.5)*2.5+trimTargetmV);
00182 break;
00183 case ST_QTHR:
00184 x[nBins] = invFn->Eval((int)(((rc->getFunction()->Eval(occ->GetBinCenter(bin)))+1.25)/2.5)*2.5);
00185
00186 break;
00187 default:
00188 ostringstream oss;
00189 oss << "Internal Error: NoiseOccupancy Algorithm doesn't know how to deal with scan of type : " << m_scanVariable;
00190 throw Sct::UnsupportedOperationError(oss.str(), __FILE__, __LINE__);
00191 }
00192
00193 x[nBins] *= x[nBins];
00194 xUpperErr[nBins] = xLowerErr[nBins] = 0;
00195
00196 nBins++;
00197 }
00198 }
00199
00200 auto_ptr<TF1> f = NoiseOccupancyTestResult::createFitFunction();
00201
00202
00203 if (nBins == 0 && defects.defectSeverityEncompassingElement(ModuleElement::Chip(ichip)) < SERIOUS ) {
00204 defects.addDefect(Defect(StandardDefects::DEAD, ModuleElement::Chip(ichip)));
00205 shared_ptr<TGraphAsymmErrors> g( new TGraphAsymmErrors());
00206 return ChipNOResult(g, shared_ptr<TF1>(f), 0, 0);
00207 }
00208
00209 shared_ptr<TGraphAsymmErrors> g( new TGraphAsymmErrors(nBins, x, y, xLowerErr, xUpperErr, yLowerErr, yUpperErr));
00210
00211
00212 AnalysisService::instance().getFitStrategy().fitTGraphAsymmErrors(*g, *f);
00213
00214
00215
00216
00217
00218
00219 Stats<double> occAtOnefC(nChannelChip);
00220 for (unsigned ichan=0; ichan < nChannelChip ; ++ichan ){
00221 unsigned channelInModule = ichip*nChannelChip + ichan;
00222
00223
00224 char name[10];
00225 sprintf(name,"temp%d",channelInModule);
00226 auto_ptr<TH1> occChannel = opr.getOccupancy(name, ModuleElement::Channel(channelInModule)) ;
00227
00228
00229 int bin = 0;
00230 switch(m_scanVariable) {
00231 case ST_VTHR: {
00232 double vthr = rc->getFunction()->Eval(1.);
00233 bin = occChannel->GetXaxis()->FindBin(vthr);
00234 } break;
00235 case ST_TTHR: {
00236 double vthr = rc->getFunction()->Eval(1.);
00237 bin = occChannel->GetXaxis()->FindBin(vthr-trimTargetmV);
00238 } break;
00239 case ST_QTHR:
00240 bin = occChannel->GetXaxis()->FindBin(1.0);
00241 break;
00242 default:
00243 ostringstream oss;
00244 oss << "Internal Error: NoiseOccupancy Algorithm doesn't know how to deal with scan of type : " << m_scanVariable;
00245 throw Sct::UnsupportedOperationError(oss.str(), __FILE__, __LINE__);
00246 }
00247
00248
00249 occAtOnefC.modifyAt(ichan).value = occChannel->GetBinContent(bin);
00250
00251
00252
00253
00254 if (occAtOnefC.getAt(ichan).value > StandardDefects::NO_HI.getParameter() ){
00255 defects.addDefect(Defect(StandardDefects::NO_HI, ModuleElement::Channel(channelInModule)));
00256 occAtOnefC.modifyAt(ichan).valid=false;
00257 }
00258 }
00259 double mean = occAtOnefC.mean();
00260
00261 double rms = sqrt( occAtOnefC.var() );
00262
00263 return ChipNOResult(g,shared_ptr<TF1>(f),mean,rms);
00264 }
00265 }