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 shared_ptr<AnalysisAlgorithm> RxThresholdBasedOnConfigRegisterAlgorithm::clone(const TestData& testData, const string& moduleName) const throw() {
00025 return shared_ptr<AnalysisAlgorithm>(new RxThresholdBasedOnConfigRegisterAlgorithm(testData, moduleName, *this));
00026 }
00027
00028 void RxThresholdBasedOnConfigRegisterAlgorithm::loadData() {
00029 loadAllRaws();
00030 }
00031
00032
00033 bool RxThresholdBasedOnConfigRegisterAlgorithm::canAnalyze() const{
00034 return hasAllRaws();
00035 }
00036
00037 shared_ptr<TestResult> RxThresholdBasedOnConfigRegisterAlgorithm::createTestResult() const {
00038 return shared_ptr<RxThresholdBasedOnConfigRegisterTestResult> (new RxThresholdBasedOnConfigRegisterTestResult());
00039 }
00040
00041
00042 typedef enum {undecided,white,black,blackAndWhite,coloured} Category;
00043
00044 std::string categoryToString(const Category & category) {
00045 return
00046 category==undecided ? "undecided" :
00047 category==white ? "white" :
00048 category==black ? "black" :
00049 category==blackAndWhite ? "blackAndWhite" :
00050 category==coloured ? "coloured" :
00051 "couldNotFigureCategoryOut";
00052 };
00053
00054 struct Wadge {
00055 Category category;
00056 unsigned int initialThreshIndex;
00057 unsigned int width;
00058 unsigned int from() const { return initialThreshIndex; };
00059 unsigned int to() const { return initialThreshIndex+width-1; };
00060 void reset(const Category & cat, const unsigned int index) {
00061 category = cat;
00062 initialThreshIndex = index;
00063 width=1;
00064 };
00065 bool is(const Category & cat) const { return cat == category; };
00066 void increment() {
00067 ++width;
00068 };
00069 void makeEmpty() {
00070 width=0;
00071 };
00072 bool isEmpty() const {
00073 return width==0;
00074 };
00075 Wadge() {
00076 makeEmpty();
00077 };
00078 bool operator<(const Wadge & other) const {
00079 return (this->width)<(other.width);
00080 };
00081 };
00082
00083 void RxThresholdBasedOnConfigRegisterAlgorithm::analyze() {
00084 RxThresholdBasedOnConfigRegisterTestResult & result = *dynamic_pointer_cast<RxThresholdBasedOnConfigRegisterTestResult> ( getTestResult() );
00085
00086 const RawScanResult& raw = *getRaw(0);
00087 result.setScanVariable(raw.getHeader().getVariable());
00088
00089 const SctData::ScanPoints& points=raw.getPoints();
00090 const unsigned int numberOfScanPoints = points.getNPoints();
00091
00092 for (short unsigned int ilink=0; ilink<nLinkModule; ++ilink ) {
00093 const TH2& data = raw.getScanData(ilink);
00094 const unsigned nx = data.GetNbinsX();
00095 const unsigned ny = data.GetNbinsY();
00096 if(!(ny==numberOfScanPoints)) {
00097 throw IllegalStateError("This should not be!",__FILE__,__LINE__);
00098 };
00099 if(ny<=0) {
00100 throw IllegalStateError("This should not be!",__FILE__,__LINE__);
00101 };
00102
00103
00104
00105 typedef unsigned int Width;
00106 typedef std::multiset<Wadge> Wadges;
00107
00108 Wadges blackAndWhiteWadges;
00109 {
00110 Wadge currentWadge;
00111
00112 for (unsigned int threshIndex = 0;
00113 threshIndex < ny;
00114 ++threshIndex) {
00115 const unsigned int nTriggers = points.getNEvents(threshIndex);
00116 const double rxThresh = points.getPoint(threshIndex);
00117
00118 Category category = undecided;
00119 bool sawZero = false;
00120 bool sawSaturation = false;
00121 for (unsigned int x=0; x<nx && category==undecided; ++x) {
00122 const Stat_t binContent_t = data.GetBinContent(x+1, threshIndex+1);
00123 const unsigned int binContent = static_cast<unsigned int>(binContent_t);
00124 if (static_cast<Stat_t>(binContent) != binContent_t) {
00125 throw IllegalStateError("This cannot be!",__FILE__,__LINE__);
00126 };
00127
00128 if (binContent != 0 && binContent != nTriggers) {
00129 category = coloured;
00130 break;
00131 };
00132
00133 if (binContent == 0) {
00134 sawZero = true;
00135 continue;
00136 } else if (binContent == nTriggers) {
00137 sawSaturation = true;
00138 continue;
00139 };
00140 };
00141
00142 if (category==undecided) {
00143 if (sawZero && !sawSaturation) {
00144 category = white;
00145 } else if (sawSaturation && !sawZero) {
00146 category = black;
00147 } else if (sawSaturation && sawZero) {
00148 category = blackAndWhite;
00149 } else {
00150 throw IllegalStateError("This cannot be!",__FILE__,__LINE__);
00151 };
00152 };
00153
00154 if (category==undecided) {
00155 throw IllegalStateError("This cannot be!",__FILE__,__LINE__);
00156 };
00157
00158
00159
00160 {
00161 const bool debug=false;
00162 if (debug) {
00163 const std::string lineType =
00164 std::string("lineType was ") + categoryToString(category);
00165
00166 std::ostringstream os;
00167 os << "Rx thresh " << rxThresh << " lineType " << lineType << " ntriggers " << nTriggers;
00168 std::string message = os.str();
00169 SctNames::Mrs()<< "RXTHRESHBASEDONCON" << MRS_INFORMATION<< MRS_TEXT(message.c_str())<< ENDM;
00170 };
00171 };
00172
00173 if (currentWadge.isEmpty()) {
00174 currentWadge.reset(category, threshIndex);
00175 } else {
00176
00177 if (currentWadge.is(category)) {
00178 currentWadge.increment();
00179 } else {
00180
00181
00182
00183 if (currentWadge.is(blackAndWhite)) {
00184 blackAndWhiteWadges.insert(currentWadge);
00185 };
00186
00187
00188 currentWadge.reset(category, threshIndex);
00189 };
00190 };
00191
00192 };
00193 if (currentWadge.is(blackAndWhite)) {
00194 blackAndWhiteWadges.insert(currentWadge);
00195 };
00196 };
00197
00198
00199 {
00200 const bool debug=true;
00201 if (debug) {
00202 for (Wadges::const_iterator it = blackAndWhiteWadges.begin();
00203 it!=blackAndWhiteWadges.end();
00204 ++it) {
00205 const Wadge & wadge = *it;
00206 std::ostringstream os;
00207 os << categoryToString(wadge.category) << " wadge of width " << wadge.width << " from " << wadge.from() << " to " << wadge.to();
00208 const std::string message = os.str();
00209 SctNames::Mrs()<< "RXTHRESHBASEDONCON" << MRS_INFORMATION<< MRS_TEXT(message.c_str())<< ENDM;
00210 };
00211 };
00212 };
00213
00214 {
00215 const bool debug=true;
00216 if (debug) {
00217 if (blackAndWhiteWadges.empty()) {
00218 SctNames::Mrs()<< "RXTHRESHBASEDONCON"<< MRS_INFORMATION<< MRS_TEXT("There were no blackAndWhite wadges for this stream!") << ENDM;
00219 } else {
00220 const Wadge & largestWadge = *(blackAndWhiteWadges.rbegin());
00221 std::ostringstream os;
00222 os << "The largest wadge was " << categoryToString(largestWadge.category) << " and had width " << largestWadge.width << " from " << largestWadge.from() << " to " << largestWadge.to();
00223 const std::string message = os.str();
00224 SctNames::Mrs()<< "RXTHRESHBASEDONCON" << MRS_INFORMATION<< MRS_TEXT(message.c_str())<< ENDM;
00225 };
00226 };
00227 };
00228
00229 {
00230
00231 bool pass=false;
00232 bool problem=false;
00233
00234
00235 RxThresholdBasedOnConfigRegisterTestResult::StreamResult & sr = result.getStreamResult(ilink);
00236 if (blackAndWhiteWadges.empty()) {
00237 problem=true;
00238 sr.setInvalid();
00239 } else {
00240 pass=true;
00241 const Wadge & largestWadge = *(blackAndWhiteWadges.rbegin());
00242 const unsigned int fromIndex = largestWadge.from();
00243 const unsigned int toIndex = largestWadge. to();
00244 const int fromThresh = static_cast<int>(points.getPoint( fromIndex ));
00245 const int toThresh = static_cast<int>(points.getPoint( toIndex ));
00246 const int bestThresh = (fromThresh+toThresh)/2;
00247 sr.setMinErrorFreeRxThresh(fromThresh);
00248 sr.setMaxErrorFreeRxThresh( toThresh);
00249 sr. setBestRxThresh(bestThresh);
00250 };
00251
00252 result.setPassed(pass);
00253 result.setProblem(problem);
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
00326
00327
00328 }
00329 }