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 bool RxThresholdBasedOnConfigRegisterAlgorithm::
00075 canRead(const std::vector<char> & wanted,
00076 const std::vector<bool> & have,
00077 std::vector<bool>::const_iterator & externalPos,
00078 const bool showDebug) {
00079 if (wanted.empty()) {
00080 if (showDebug) {
00081 std::cout << " MATCH\n";
00082 };
00083 return true;
00084 };
00085
00086
00087 std::vector<bool>::const_iterator localPos = externalPos;
00088
00089 for(std::vector<char>::const_iterator wantedPos = wanted.begin();
00090 wantedPos != wanted.end();
00091 (++wantedPos, ++localPos)) {
00092
00093 if (localPos == have.end()) {
00094 if (showDebug) {
00095 std::cout << "[EOD]\n";
00096 };
00097 return false;
00098 };
00099
00100 const char wantedChar = *wantedPos;
00101
00102 if (wantedChar == 2) {
00103
00104 if (showDebug) {
00105 std::cout << ( (*localPos) ? "D" : "d" );
00106 };
00107 continue;
00108 };
00109
00110 const bool bit = *localPos;
00111
00112 if (wantedChar == 0 && !bit ||
00113 wantedChar == 1 && bit) {
00114
00115 if (showDebug) {
00116 std::cout << bit;
00117 };
00118 continue;
00119 } else {
00120
00121 if (showDebug) {
00122 std::cout << "[W:" << (wantedChar ? "1" : "0") << ",G:" << bit << "]\n";
00123 };
00124 return false;
00125 };
00126 };
00127
00128
00129 externalPos = localPos;
00130 if (showDebug) {
00131 std::cout << " MATCH\n";
00132 };
00133 return true;
00134 };
00135
00136
00137 void RxThresholdBasedOnConfigRegisterAlgorithm::analyze() {
00138 RxThresholdBasedOnConfigRegisterTestResult & result = *dynamic_pointer_cast<RxThresholdBasedOnConfigRegisterTestResult> ( getTestResult() );
00139
00140 const RawScanResult& raw = *getRaw(0);
00141 result.setScanVariable(raw.getHeader().getVariable());
00142
00143 const SctData::ScanPoints& points=raw.getPoints();
00144 const unsigned int numberOfScanPoints = points.getNPoints();
00145
00146
00147 for (short unsigned int ilink=0; ilink<nLinkModule; ++ilink ) {
00148 const TH2& data = raw.getScanData(ilink);
00149 const unsigned nx = data.GetNbinsX();
00150 const unsigned ny = data.GetNbinsY();
00151 if(!(ny==numberOfScanPoints)) {
00152 throw IllegalStateError("This should not be!",__FILE__,__LINE__);
00153 };
00154 if(ny<=0) {
00155 throw IllegalStateError("This should not be!",__FILE__,__LINE__);
00156 };
00157
00158
00159
00160 typedef unsigned int Width;
00161 typedef std::multiset<Wadge> Wadges;
00162
00163
00164
00165 int riseTime = 0;
00166
00167 Wadges blackAndWhiteWadges;
00168 Wadges meaningfulDataWadges;
00169 {
00170 Wadge currentWadge;
00171
00172
00173 int unsigned beginNonZero[ny];
00174 int unsigned maxNonZeroThreshIndex = 0;
00175
00176 for (unsigned int threshIndex = 0; threshIndex < ny; ++threshIndex) {
00177 std::vector<bool> bwCopy(nx);
00178
00179 const unsigned int nTriggers = points.getNEvents(threshIndex);
00180 const double rxThresh = points.getPoint(threshIndex);
00181
00182 beginNonZero[threshIndex] = 0;
00183
00184 RxThresholdBasedOnConfigRegisterAlgorithm::Category category = undecided;
00185 bool sawZero = false;
00186 bool sawSaturation = false;
00187 for (unsigned int x=0; x<nx && category==undecided; ++x) {
00188 const Stat_t binContent_t = data.GetBinContent(x+1, threshIndex+1);
00189 const unsigned int binContent = static_cast<unsigned int>(binContent_t);
00190 if (static_cast<Stat_t>(binContent) != binContent_t) {
00191 throw IllegalStateError("This cannot be!",__FILE__,__LINE__);
00192 };
00193
00194 if (binContent != 0 ) {
00195 if (beginNonZero[threshIndex] == 0) {
00196 beginNonZero[threshIndex] = x;
00197
00198 }
00199 }
00200
00201 if (binContent != 0 && binContent != nTriggers) {
00202 category = coloured;
00203 break;
00204 };
00205
00206 if (binContent == 0) {
00207 sawZero = true;
00208 bwCopy[x] = false;
00209 continue;
00210 } else if (binContent == nTriggers) {
00211 sawSaturation = true;
00212 bwCopy[x] = true;
00213 continue;
00214 };
00215 };
00216
00217 if (beginNonZero[threshIndex] != 0) {
00218 maxNonZeroThreshIndex = threshIndex;
00219 }
00220
00221 if (category==undecided) {
00222 if (sawZero && !sawSaturation) {
00223 category = white;
00224 } else if (sawSaturation && !sawZero) {
00225 category = black;
00226 } else if (sawSaturation && sawZero) {
00227 category = blackAndWhite;
00228 } else {
00229 throw IllegalStateError("This cannot be!",__FILE__,__LINE__);
00230 };
00231 };
00232
00233 if (category==undecided) {
00234 throw IllegalStateError("This cannot be!",__FILE__,__LINE__);
00235 };
00236
00237
00238 {
00239 const bool debug=false;
00240 if (debug) {
00241 const std::string lineType =
00242 std::string("lineType was ") + RxThresholdBasedOnConfigRegisterAlgorithm::categoryToString(category);
00243
00244 std::ostringstream os;
00245 os << "Rx thresh " << rxThresh << " lineType " << lineType << " ntriggers " << nTriggers;
00246 std::string message = os.str();
00247 SctNames::Mrs()<< "RXTHRESHBASEDONCON" << MRS_INFORMATION<< MRS_TEXT(message.c_str())<< ENDM;
00248 };
00249 };
00250
00251
00252
00253
00254 if (category==blackAndWhite) {
00255
00256 static const char startPacketArr[] = {
00257 1,1,1,0,1,
00258 0,
00259 2,2,2,2,
00260 2,2,2,2,2,2,2,2,
00261 1
00262 };
00263 static const char confDataPacketArr[] = {
00264 0,0,0,
00265 2,2,2,2,
00266 1,1,1,
00267 2,2,2,2,2,2,2,2,
00268 1,
00269 2,2,2,2,2,2,2,2,
00270 1
00271 };
00272 static const char trailerPacketArr[] = {
00273 1,0,0,0,
00274 0,0,0,0,
00275 0,0,0,0,
00276 0,0,0,0
00277 };
00278
00279 static const std::vector<char> startPacket(startPacketArr, startPacketArr+sizeof(startPacketArr));
00280 static const std::vector<char> confDataPacket(confDataPacketArr, confDataPacketArr+sizeof(confDataPacketArr));
00281 static const std::vector<char> trailerPacket(trailerPacketArr, trailerPacketArr+sizeof(trailerPacketArr));
00282
00283 const bool showDebug = false;
00284
00285
00286 std::vector<bool>::const_iterator startPosIt = bwCopy.begin();
00287 bool foundValidData=false;
00288 unsigned int validStartPosWas=0;
00289 for (unsigned int startPos=0;
00290 startPos<50 && startPosIt != bwCopy.end() && !foundValidData;
00291 (++startPos, ++startPosIt) ) {
00292
00293 std::vector<bool>::const_iterator currentPos = startPosIt;
00294
00295
00296 if (showDebug) {
00297 std::cout << "Looking for start packet at " << startPos << " on thr " << rxThresh << " ...\n";
00298 }
00299 if (!(this->canRead(startPacket,
00300 bwCopy,
00301 currentPos,
00302 showDebug))) {
00303
00304 continue;
00305 };
00306
00307
00308
00309 if (showDebug) {
00310 std::cout << "Looking for payload ...\n";
00311 }
00312 unsigned int payload=0;
00313 while (this->canRead(confDataPacket,
00314 bwCopy,
00315 currentPos,
00316 showDebug)) {
00317 ++payload;
00318 };
00319
00320 if (payload==0) {
00321
00322 continue;
00323 };
00324
00325
00326 if (showDebug) {
00327 std::cout << "Looking for trailer ...\n";
00328 }
00329 if (!(this->canRead(trailerPacket,
00330 bwCopy,
00331 currentPos,
00332 showDebug))) {
00333
00334 continue;
00335 };
00336
00337
00338 foundValidData=true;
00339 validStartPosWas=startPos;
00340
00341 };
00342
00343
00344
00345
00346
00347 if (foundValidData) {
00348
00349 category = meaningfulData;
00350 };
00351
00352 };
00353
00354
00355
00356 {
00357 const bool debug=false;
00358 if (debug) {
00359 const std::string lineType =
00360 std::string("lineType was ") + RxThresholdBasedOnConfigRegisterAlgorithm::categoryToString(category);
00361
00362 std::ostringstream os;
00363 os << "Rx thresh " << rxThresh << " beginNonZero " << beginNonZero[threshIndex] ;
00364 std::string message = os.str();
00365 SctNames::Mrs()<< "RXTHRESHBASEDONCON" << MRS_INFORMATION<< MRS_TEXT(message.c_str())<< ENDM;
00366 };
00367 };
00368
00369
00370 if (currentWadge.isEmpty()) {
00371 currentWadge.reset(category, threshIndex);
00372 } else {
00373
00374 if (currentWadge.is(category)) {
00375 currentWadge.increment();
00376 } else {
00377
00378
00379
00380 if (currentWadge.is(blackAndWhite) || currentWadge.is(meaningfulData)) {
00381 blackAndWhiteWadges.insert(currentWadge);
00382 };
00383
00384
00385 if (currentWadge.is(meaningfulData)) {
00386 meaningfulDataWadges.insert(currentWadge);
00387 };
00388
00389
00390 currentWadge.reset(category, threshIndex);
00391 };
00392 };
00393
00394
00395 };
00396
00397
00398 int unsigned beginSlope = ((int)(maxNonZeroThreshIndex*0.25/5))*5;
00399 int unsigned endSlope = ((int)(maxNonZeroThreshIndex*0.75/5))*5;
00400 riseTime = beginNonZero[endSlope] - beginNonZero[beginSlope];
00401
00402 {
00403 const bool debug=false;
00404 if (debug) {
00405 std::ostringstream os;
00406 os << "beginSlope: " << beginSlope << " endSlope: " << endSlope << " riseTime: " << riseTime;
00407 std::string message = os.str();
00408 SctNames::Mrs()<< "RXTHRESHBASEDONCON" << MRS_INFORMATION<< MRS_TEXT(message.c_str())<< ENDM;
00409 }
00410 }
00411
00412
00413
00414 if (currentWadge.is(blackAndWhite) || currentWadge.is(meaningfulData)) {
00415 blackAndWhiteWadges.insert(currentWadge);
00416 };
00417
00418
00419 if (currentWadge.is(meaningfulData)) {
00420 meaningfulDataWadges.insert(currentWadge);
00421 };
00422
00423 };
00424
00425
00426 {
00427 const bool debug=false;
00428 if (debug) {
00429 for (Wadges::const_iterator it = blackAndWhiteWadges.begin();
00430 it!=blackAndWhiteWadges.end();
00431 ++it) {
00432 const Wadge & wadge = *it;
00433 std::ostringstream os;
00434 os << RxThresholdBasedOnConfigRegisterAlgorithm::categoryToString(wadge.category) << " wadge of width " << wadge.width << " from " << wadge.from() << " to " << wadge.to();
00435 const std::string message = os.str();
00436 SctNames::Mrs()<< "RXTHRESHBASEDONCON" << MRS_INFORMATION<< MRS_TEXT(message.c_str())<< ENDM;
00437 };
00438 };
00439 };
00440
00441 {
00442 const bool debug=false;
00443 if (debug) {
00444 if (blackAndWhiteWadges.empty()) {
00445 SctNames::Mrs()<< "RXTHRESHBASEDONCON"<< MRS_INFORMATION<< MRS_TEXT("There were no blackAndWhite wadges for this stream!") << ENDM;
00446 } else {
00447 const Wadge & largestWadge = *(blackAndWhiteWadges.rbegin());
00448 std::ostringstream os;
00449 os << "The largest wadge was " << RxThresholdBasedOnConfigRegisterAlgorithm::categoryToString(largestWadge.category) << " and had width " << largestWadge.width << " from " << largestWadge.from() << " to " << largestWadge.to();
00450 const std::string message = os.str();
00451 SctNames::Mrs()<< "RXTHRESHBASEDONCON" << MRS_INFORMATION<< MRS_TEXT(message.c_str())<< ENDM;
00452 };
00453 };
00454 };
00455
00456 {
00457 const bool debug=false;
00458 if (debug) {
00459 for (Wadges::const_iterator it = meaningfulDataWadges.begin();
00460 it!=meaningfulDataWadges.end();
00461 ++it) {
00462 const Wadge & wadge = *it;
00463 std::ostringstream os;
00464 os << RxThresholdBasedOnConfigRegisterAlgorithm::categoryToString(wadge.category) << " wadge of width " << wadge.width << " from " << wadge.from() << " to " << wadge.to();
00465 const std::string message = os.str();
00466 SctNames::Mrs()<< "RXTHRESHBASEDONCON" << MRS_INFORMATION<< MRS_TEXT(message.c_str())<< ENDM;
00467 };
00468 };
00469 };
00470
00471 {
00472 const bool debug=false;
00473 if (debug) {
00474 if (meaningfulDataWadges.empty()) {
00475 SctNames::Mrs()<< "RXTHRESHBASEDONCON"<< MRS_INFORMATION<< MRS_TEXT("There were no meaningfulData wadges for this stream!") << ENDM;
00476 } else {
00477 const Wadge & largestWadge = *(meaningfulDataWadges.rbegin());
00478 std::ostringstream os;
00479 os << "The largest wadge was " << RxThresholdBasedOnConfigRegisterAlgorithm::categoryToString(largestWadge.category) << " and had width " << largestWadge.width << " from " << largestWadge.from() << " to " << largestWadge.to();
00480 const std::string message = os.str();
00481 SctNames::Mrs()<< "RXTHRESHBASEDONCON" << MRS_INFORMATION<< MRS_TEXT(message.c_str())<< ENDM;
00482 };
00483 };
00484 };
00485
00486 {
00487
00488 bool pass=false;
00489 bool problem=false;
00490
00491
00492 RxThresholdBasedOnConfigRegisterTestResult::StreamResult & sr = result.getStreamResult(ilink);
00493 if (meaningfulDataWadges.empty() ) {
00494 problem=true;
00495 sr.setInvalid();
00496 } else {
00497 pass=true;
00498 const Wadge & largestWadge = *(meaningfulDataWadges.rbegin());
00499 const unsigned int fromIndex = largestWadge.from();
00500 const unsigned int toIndex = largestWadge. to();
00501 const int fromThresh = static_cast<int>(points.getPoint( fromIndex ));
00502 const int toThresh = static_cast<int>(points.getPoint( toIndex ));
00503 const int low = min(fromThresh, toThresh);
00504 const int high = max(fromThresh, toThresh);
00505 float fraction = getFraction();
00506 const int bestThresh = (int) ( ((1.-fraction)*(float)low)
00507 +((fraction)*(float)high) );
00508
00509 sr.setMinErrorFreeRxThresh(low);
00510 sr.setMaxErrorFreeRxThresh(high);
00511 sr.setBestRxThresh(bestThresh);
00512
00513 sr.setRiseTime(riseTime);
00514
00515
00516
00517
00518
00519
00520
00521 };
00522
00523 result.setPassed(pass);
00524 result.setProblem(problem);
00525
00526 };
00527
00528
00529 };
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597
00598 }
00599 }