00001 #include "RxThresholdBasedOnConfigRegisterAlgorithm.h"
00002 #include "AnalysisAlgorithmMap.h"
00003 #include "SctData/RxThresholdBasedOnConfigRegisterTestResult.h"
00004
00005
00006 #include "SctData/RawScanResult.h"
00007 #include <cfloat>
00008 #include "TH2.h"
00009 #include "Sct/SctNames.h"
00010
00011
00012 #include <cmath>
00013 #include <set>
00014
00015 using namespace std;
00016 using namespace boost;
00017 using namespace SctData;
00018 using namespace Sct;
00019
00020 namespace SctAnalysis {
00021
00022 bool RxThresholdBasedOnConfigRegisterAlgorithm::inMap = AnalysisAlgorithmMap::instance().setAlgorithm("RxThresholdBasedOnConfigRegisterTest", auto_ptr<AnalysisAlgorithm>(new RxThresholdBasedOnConfigRegisterAlgorithm()));
00023
00024
00025
00026 RxThresholdBasedOnConfigRegisterAlgorithm::RxThresholdBasedOnConfigRegisterAlgorithm(shared_ptr<const TestData> testData, const string& moduleName, const AnalysisAlgorithm& alg) throw() : AnalysisAlgorithm(testData, moduleName, alg), m_fraction(0.7) {}
00027
00028 shared_ptr<AnalysisAlgorithm> RxThresholdBasedOnConfigRegisterAlgorithm::clone(shared_ptr<const TestData> testData, const string& moduleName) const throw() {
00029 return shared_ptr<AnalysisAlgorithm>(new RxThresholdBasedOnConfigRegisterAlgorithm(testData, moduleName, *this));
00030 }
00031
00032 void RxThresholdBasedOnConfigRegisterAlgorithm::loadData() {
00033 loadAllRaws();
00034 }
00035
00036
00037 bool RxThresholdBasedOnConfigRegisterAlgorithm::canAnalyze() const{
00038 return hasAllRaws();
00039 }
00040
00041 shared_ptr<TestResult> RxThresholdBasedOnConfigRegisterAlgorithm::createTestResult() const {
00042 return shared_ptr<RxThresholdBasedOnConfigRegisterTestResult> (new RxThresholdBasedOnConfigRegisterTestResult());
00043 }
00044
00045 struct Wadge {
00046 RxThresholdBasedOnConfigRegisterAlgorithm::Category category;
00047 unsigned int initialThreshIndex;
00048 unsigned int width;
00049 unsigned int from() const { return initialThreshIndex; };
00050 unsigned int to() const { return initialThreshIndex+width-1; };
00051 void reset(const RxThresholdBasedOnConfigRegisterAlgorithm::Category & cat, const unsigned int index) {
00052 category = cat;
00053 initialThreshIndex = index;
00054 width=1;
00055 };
00056 bool is(const RxThresholdBasedOnConfigRegisterAlgorithm::Category & cat) const { return cat == category; };
00057 void increment() {
00058 ++width;
00059 };
00060 void makeEmpty() {
00061 width=0;
00062 };
00063 bool isEmpty() const {
00064 return width==0;
00065 };
00066 Wadge() {
00067 makeEmpty();
00068 };
00069 bool operator<(const Wadge & other) const {
00070 return (this->width)<(other.width);
00071 };
00072 };
00073
00074 void RxThresholdBasedOnConfigRegisterAlgorithm::analyze() {
00075 RxThresholdBasedOnConfigRegisterTestResult & result = *dynamic_pointer_cast<RxThresholdBasedOnConfigRegisterTestResult> ( getTestResult() );
00076
00077 const RawScanResult& raw = *getRaw(0);
00078 result.setScanVariable(raw.getHeader().getVariable());
00079
00080 const SctData::ScanPoints& points=raw.getPoints();
00081 const unsigned int numberOfScanPoints = points.getNPoints();
00082
00083 for (short unsigned int ilink=0; ilink<nLinkModule; ++ilink ) {
00084 const TH2& data = raw.getScanData(ilink);
00085 const unsigned nx = data.GetNbinsX();
00086 const unsigned ny = data.GetNbinsY();
00087 if(!(ny==numberOfScanPoints)) {
00088 throw IllegalStateError("This should not be!",__FILE__,__LINE__);
00089 };
00090 if(ny<=0) {
00091 throw IllegalStateError("This should not be!",__FILE__,__LINE__);
00092 };
00093
00094
00095
00096 typedef unsigned int Width;
00097 typedef std::multiset<Wadge> Wadges;
00098
00099 Wadges blackAndWhiteWadges;
00100 {
00101 Wadge currentWadge;
00102
00103 for (unsigned int threshIndex = 0;
00104 threshIndex < ny;
00105 ++threshIndex) {
00106 const unsigned int nTriggers = points.getNEvents(threshIndex);
00107 const double rxThresh = points.getPoint(threshIndex);
00108
00109 RxThresholdBasedOnConfigRegisterAlgorithm::Category category = undecided;
00110 bool sawZero = false;
00111 bool sawSaturation = false;
00112 for (unsigned int x=0; x<nx && category==undecided; ++x) {
00113 const Stat_t binContent_t = data.GetBinContent(x+1, threshIndex+1);
00114 const unsigned int binContent = static_cast<unsigned int>(binContent_t);
00115 if (static_cast<Stat_t>(binContent) != binContent_t) {
00116 throw IllegalStateError("This cannot be!",__FILE__,__LINE__);
00117 };
00118
00119 if (binContent != 0 && binContent != nTriggers) {
00120 category = coloured;
00121 break;
00122 };
00123
00124 if (binContent == 0) {
00125 sawZero = true;
00126 continue;
00127 } else if (binContent == nTriggers) {
00128 sawSaturation = true;
00129 continue;
00130 };
00131 };
00132
00133 if (category==undecided) {
00134 if (sawZero && !sawSaturation) {
00135 category = white;
00136 } else if (sawSaturation && !sawZero) {
00137 category = black;
00138 } else if (sawSaturation && sawZero) {
00139 category = blackAndWhite;
00140 } else {
00141 throw IllegalStateError("This cannot be!",__FILE__,__LINE__);
00142 };
00143 };
00144
00145 if (category==undecided) {
00146 throw IllegalStateError("This cannot be!",__FILE__,__LINE__);
00147 };
00148
00149
00150
00151 {
00152 const bool debug=false;
00153 if (debug) {
00154 const std::string lineType =
00155 std::string("lineType was ") + RxThresholdBasedOnConfigRegisterAlgorithm::categoryToString(category);
00156
00157 std::ostringstream os;
00158 os << "Rx thresh " << rxThresh << " lineType " << lineType << " ntriggers " << nTriggers;
00159 std::string message = os.str();
00160 SctNames::Mrs()<< "RXTHRESHBASEDONCON" << MRS_INFORMATION<< MRS_TEXT(message.c_str())<< ENDM;
00161 };
00162 };
00163
00164 if (currentWadge.isEmpty()) {
00165 currentWadge.reset(category, threshIndex);
00166 } else {
00167
00168 if (currentWadge.is(category)) {
00169 currentWadge.increment();
00170 } else {
00171
00172
00173
00174 if (currentWadge.is(blackAndWhite)) {
00175 blackAndWhiteWadges.insert(currentWadge);
00176 };
00177
00178
00179 currentWadge.reset(category, threshIndex);
00180 };
00181 };
00182
00183 };
00184 if (currentWadge.is(blackAndWhite)) {
00185 blackAndWhiteWadges.insert(currentWadge);
00186 };
00187 };
00188
00189
00190 {
00191 const bool debug=false;
00192 if (debug) {
00193 for (Wadges::const_iterator it = blackAndWhiteWadges.begin();
00194 it!=blackAndWhiteWadges.end();
00195 ++it) {
00196 const Wadge & wadge = *it;
00197 std::ostringstream os;
00198 os << RxThresholdBasedOnConfigRegisterAlgorithm::categoryToString(wadge.category) << " wadge of width " << wadge.width << " from " << wadge.from() << " to " << wadge.to();
00199 const std::string message = os.str();
00200 SctNames::Mrs()<< "RXTHRESHBASEDONCON" << MRS_INFORMATION<< MRS_TEXT(message.c_str())<< ENDM;
00201 };
00202 };
00203 };
00204
00205 {
00206 const bool debug=false;
00207 if (debug) {
00208 if (blackAndWhiteWadges.empty()) {
00209 SctNames::Mrs()<< "RXTHRESHBASEDONCON"<< MRS_INFORMATION<< MRS_TEXT("There were no blackAndWhite wadges for this stream!") << ENDM;
00210 } else {
00211 const Wadge & largestWadge = *(blackAndWhiteWadges.rbegin());
00212 std::ostringstream os;
00213 os << "The largest wadge was " << RxThresholdBasedOnConfigRegisterAlgorithm::categoryToString(largestWadge.category) << " and had width " << largestWadge.width << " from " << largestWadge.from() << " to " << largestWadge.to();
00214 const std::string message = os.str();
00215 SctNames::Mrs()<< "RXTHRESHBASEDONCON" << MRS_INFORMATION<< MRS_TEXT(message.c_str())<< ENDM;
00216 };
00217 };
00218 };
00219
00220 {
00221
00222 bool pass=false;
00223 bool problem=false;
00224
00225
00226 RxThresholdBasedOnConfigRegisterTestResult::StreamResult & sr = result.getStreamResult(ilink);
00227 if (blackAndWhiteWadges.empty()) {
00228 problem=true;
00229 sr.setInvalid();
00230 } else {
00231 pass=true;
00232 const Wadge & largestWadge = *(blackAndWhiteWadges.rbegin());
00233 const unsigned int fromIndex = largestWadge.from();
00234 const unsigned int toIndex = largestWadge. to();
00235 const int fromThresh = static_cast<int>(points.getPoint( fromIndex ));
00236 const int toThresh = static_cast<int>(points.getPoint( toIndex ));
00237 const int low = min(fromThresh, toThresh);
00238 const int high = max(fromThresh, toThresh);
00239 float fraction = getFraction();
00240 const int bestThresh = (int) ( ((1.-fraction)*(float)low)
00241 +((fraction)*(float)high) );
00242
00243 sr.setMinErrorFreeRxThresh(low);
00244 sr.setMaxErrorFreeRxThresh(high);
00245 sr. setBestRxThresh(bestThresh);
00246 };
00247
00248 result.setPassed(pass);
00249 result.setProblem(problem);
00250
00251 };
00252
00253
00254
00255 };
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324 }
00325 }