00001 #include "MarkSpaceRatioAlgorithm.h"
00002 #include "AnalysisAlgorithmMap.h"
00003 #include "SctData/MarkSpaceRatioTestResult.h"
00004 #include "SctData/RawScanResult.h"
00005 #include <cfloat>
00006 #include "TH2.h"
00007 #include "Sct/SctNames.h"
00008 #include <set>
00009
00010 using namespace std;
00011 using namespace boost;
00012 using namespace SctData;
00013 using namespace Sct;
00014
00015 namespace SctAnalysis {
00016
00017 bool MarkSpaceRatioAlgorithm::inMap = AnalysisAlgorithmMap::instance().setAlgorithm("MarkSpaceRatioTest", auto_ptr<AnalysisAlgorithm>(new MarkSpaceRatioAlgorithm()));
00018
00019 shared_ptr<AnalysisAlgorithm> MarkSpaceRatioAlgorithm::clone(shared_ptr<const TestData> testData, const string& moduleName) const throw() {
00020 return shared_ptr<AnalysisAlgorithm>(new MarkSpaceRatioAlgorithm(testData, moduleName, *this));
00021 }
00022
00023 void MarkSpaceRatioAlgorithm::loadData() {
00024 loadAllRaws();
00025 }
00026
00027
00028 bool MarkSpaceRatioAlgorithm::canAnalyze() const{
00029 return hasAllRaws();
00030 }
00031
00032 shared_ptr<TestResult> MarkSpaceRatioAlgorithm::createTestResult() const {
00033 return shared_ptr<MarkSpaceRatioTestResult> (new MarkSpaceRatioTestResult());
00034 }
00035
00036 void MarkSpaceRatioAlgorithm::analyze() {
00037 MarkSpaceRatioTestResult & result = *dynamic_pointer_cast<MarkSpaceRatioTestResult> ( getTestResult() );
00038 const unsigned nscans=result.getNScans();
00039
00040
00041
00042
00043 if (nscans<4 || nscans%2!=0){
00044 std::ostringstream msg;
00045 msg << "MarkSpaceRatio should have even number of scans (>=4) here we have " << nscans;
00046
00047 throw Sct::LogicError(msg.str(), __FILE__, __LINE__);
00048 }
00049 for (unsigned iscan=0; iscan<nscans/2; ++iscan){
00050 MarkSpaceRatioTestResult::MsrPoint p;
00051 boost::shared_ptr<const RawScanResult> raw1 = getRaw(iscan);
00052 boost::shared_ptr<const RawScanResult> raw2 = getRaw(iscan+nscans/2);
00053
00054
00055 p.occ0=getAverageOccupancy(*raw1,0);
00056 p.occ0flip=getAverageOccupancy(*raw2,0);
00057
00058
00059 p.occ1=getAverageOccupancy(*raw1,1);
00060 p.occ1flip=getAverageOccupancy(*raw2,1);
00061
00062 p.msr=static_cast<short int>(floor(result.getTestPointAt(iscan)+0.5));
00063 result.addPoint(p);
00064
00065
00066
00067
00068 }
00069 fixOptimum(result);
00070 }
00071
00072 void MarkSpaceRatioAlgorithm::fixOptimum(MarkSpaceRatioTestResult& r){
00073 double c[2]={0.,0.};
00074 double m[2]={0.,0.};
00075 double opt[2]={0.,0.};
00076 bool good[2]={false, false};
00077
00078 for (unsigned ilink=0; ilink<2; ++ilink){
00079 float xbar=0.;
00080 float ybar=0.;
00081 float x2bar=0.;
00082 float y2bar=0.;
00083 float xybar=0.;
00084
00085 const unsigned& n=r.getNPoints();
00086 for (unsigned ipoint=0; ipoint<n; ++ipoint){
00087 const MarkSpaceRatioTestResult::MsrPoint& p = r.getPoint(ipoint);
00088
00089 const double diff=p.getOccupancy(ilink) - p.getOccupancyFlipped(ilink);
00090
00091 ybar += diff;
00092 y2bar += diff*diff;
00093 xbar += p.msr;
00094 x2bar += p.msr*p.msr;
00095 xybar += p.msr*diff;
00096 }
00097
00098 const float det=n*x2bar-xbar*xbar;
00099 if (det>0.){
00100 c[ilink] = (x2bar*ybar - xbar*xybar) / det;
00101 m[ilink] = (n*xybar - xbar*ybar) / det;;
00102 }
00103 if ( m[ilink] !=0.) {
00104 opt[ilink] = -c[ilink]/m[ilink];
00105 good[ilink]=true;
00106 }
00107 }
00108
00109
00110 double numerator=0.;
00111 double denominator=0.;
00112 unsigned ngood=0;
00113 for (unsigned ilink=0; ilink<2; ++ilink){
00114 if (good[ilink]){
00115 ngood++;
00116 numerator+=opt[ilink];
00117 }
00118 }
00119
00120 if(ngood==0){
00121 r.setPassed(false);
00122 return;
00123 }
00124
00125 double optimum=numerator/ngood;
00126 r.setOptimum(optimum);
00127 if (optimum<-1. || optimum>33.) {
00128 r.setPassed(false);
00129 } else if (optimum<3. || optimum > 29){
00130 r.setProblem(true);
00131 }else{
00132 r.setPassed(true);
00133 }
00134 }
00135
00136 double MarkSpaceRatioAlgorithm::getAverageOccupancy(const RawScanResult& raw, unsigned short ilink){
00137 double contents=0.;
00138 double trigs=0.;
00139 const TH2& hist= raw.getScanData(ilink);
00140 const ScanPoints& points=raw.getPoints();
00141
00143 for (unsigned iy=1;iy<=hist.GetNbinsY(); ++iy){
00144 for (unsigned ix=4;ix<=hist.GetNbinsX(); ++ix){
00145 contents += hist.GetBinContent(ix,iy);
00146 }
00147 unsigned ipt = points.ascending() ? iy-1 : points.getNPoints()-iy;
00148 trigs += points.getNEvents(ipt)*hist.GetNbinsX();
00149 }
00150 if (trigs<0.0001) return 0.;
00151 return contents/trigs;
00152 }
00153
00154 }