00001
00009 #include <algorithm>
00010
00011 #include <unistd.h>
00012 #include <sys/stat.h>
00013 #include <sys/types.h>
00014
00015 #include "primListWrapper.h"
00016 #include "PrimBuilder.h"
00017 #include "sctConf/configuration.h"
00018 #include "SctApi.h"
00019 #include "SctApiDebug.h"
00020 #include "crate.h"
00021 #include "ScanResultWriter/scan.h"
00022 #include "utility.h"
00023
00024 #include "SctApiHisto.h"
00025
00026 #ifdef USE_IS
00027 #include "Sct/IoExceptions.h"
00028 #include "ScanResultWriter/ScanResultWriter.h"
00029 #endif
00030
00031 #include "Sct/SctNames.h"
00032
00033 #include "CommonWithDsp/primParams.h"
00034 #include "CommonWithDsp/registerIndices.h"
00035
00036 #include "Scan.h"
00037 #include "SctApiException.h"
00038 #include "Idiosyncrasy.h"
00039
00040 #include <boost/date_time/posix_time/posix_time.hpp>
00041 #include <boost/bind.hpp>
00042
00043 using namespace std;
00044 using namespace SctConfiguration;
00045 using namespace boost::posix_time;
00046
00047 namespace SctApi {
00048
00049 int SctApi::setupRawData(unsigned int rod,
00050 int delay, int units, bool setMask, const Trigger *trig) {
00051 int success = 1;
00052
00053 PrimBuilder &builder = PrimBuilder::instance();
00054
00055 #if (R_SET_ROD_MODE < 101)
00056 #error "Old form (update primParams.h)"
00057 #else
00058 boost::shared_ptr<PrimListWrapper> setupList(new PrimListWrapper(2));
00059
00060
00061 rodMode(rod, CALIBRATION_MODE + INMEM_EVT_CAPTURE_MODE, 0, 1, units+1, delay, 0);
00062
00063
00064 for(int i=0; i<8; i++) {
00065 builder.writeRegister(setupList, FMT_LINK_EN(i), 0, 12, 0x0);
00066 }
00067
00068
00069
00070
00071 if(setMask) {
00072
00073 builder.writeRegister(setupList, FE_CMND_MASK_0_LO, 0, 32, 0xffffffff);
00074 builder.writeRegister(setupList, FE_CMND_MASK_0_HI, 0, 16, 0xffff);
00075 builder.writeRegister(setupList, FE_CMND_MASK_1_LO, 0, 32, 0xffffffff);
00076 builder.writeRegister(setupList, FE_CMND_MASK_1_HI, 0, 16, 0xffff);
00077
00078
00079
00080
00081 builder.writeRegister(setupList, RRIF_CMND_1, 2, 1, 0x1);
00082 }
00083
00084 sendPrimList(rod, setupList);
00085 int responseCode = awaitResponse(rod, 10);
00086 if(responseCode == 0) {
00087
00088 if(trig) {
00089 sendTrigger(rod, trig);
00090 } else {
00091 sendL1A(rod);
00092 }
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103 } else {
00104 success = 0;
00105 }
00106 #endif
00107
00108 return success;
00109 }
00110
00111 void SctApi::dumpRawEvent(unsigned int rod, int units,
00112 unsigned long *bufferA, unsigned long *bufferB) {
00113 static int captureCount = 0;
00114
00115 cout << "Dumping RAW FIFOs to file, count " << captureCount << endl;
00116
00117 string dirName = Sct::SctNames::getTempDir() + "/Captures";
00118
00119
00120 mkdir(dirName.c_str(), S_IRUSR|S_IWUSR|S_IXUSR);
00121
00122 char *saveDir = getcwd(NULL, 0);
00123 chdir(dirName.c_str());
00124
00125 char fileName[100];
00126 sprintf(fileName, "RawCaptureA_%05d.bin", captureCount);
00127
00128 ofstream foutA(fileName, ios::binary | ios::trunc);
00129 foutA.write((char*)&bufferA[0], units*4);
00130
00131
00132 sprintf(fileName, "RawCaptureB_%05d.bin", captureCount++);
00133
00134 ofstream foutB(fileName, ios::binary | ios::trunc);
00135 foutB.write((char*)&bufferB[0], units*4);
00136
00137 chdir(saveDir);
00138
00139 free(saveDir);
00140 }
00141
00143 static int lookupFifoHit(UINT16 *bufA, UINT16 *bufB,
00144 int channel, int pos) {
00145 int word = (channel / 16) % 3;
00146 int bit = channel % 16;
00147
00148 int val = 0;
00149 if(channel<48) {
00150 if(bufA)
00151 val = ((bufA[pos*3 + word] >> bit) & 0x1);
00152 } else if(channel<96) {
00153 if(bufB)
00154 val = ((bufB[pos*3 + word] >> bit) & 0x1);
00155 }
00156
00157 return val;
00158 }
00159
00160 void SctApi::rawData(unsigned int rod,
00161 int delay, int units, bool setMask, const Trigger *trig) {
00162 setupRawData(rod, delay, units, setMask, trig);
00163
00164 unsigned long *bufferA = readFifo(rod, 0, 0, units);
00165 unsigned long *bufferB = readFifo(rod, 0, 1, units);
00166
00167 for(int ch=0; ch<96; ch++) {
00168 cout << "Ch ";
00169 cout.width(2);
00170 cout << ch << ": ";
00171 for(int i=0; i<units; i++) {
00172
00173 cout.width(1);
00174 cout << lookupFifoHit((UINT16*)bufferA, (UINT16*)bufferB, ch, i);
00175 }
00176 cout << endl;
00177 }
00178
00179 delete [] bufferA;
00180 delete [] bufferB;
00181
00182 if(setMask) {
00183
00184 calib_init();
00185 }
00186 }
00187
00188
00189 void SctApi::doRawScan(boost::shared_ptr<Scan> scan, int delay, int width, bool configure, bool clkBy2) {
00190
00191 m_inRawScanLoop = true;
00192
00193 {
00194 boost::mutex::scoped_lock lock(log().mutex());
00195 log() << "doRawScan\n";
00196 }
00197
00198 boost::thread theActualThread(boost::bind(&SctApi::doRawScanThread, this, scan, delay, width, configure, clkBy2));
00199 }
00200
00201 void SctApi::doRawScanThread(boost::shared_ptr<Scan> scan, int delay, int width, bool configure, bool clkBy2) {
00202
00203
00204
00205 try {
00206
00207 doRawScanThreadInnards(scan, delay, width, configure, clkBy2);
00208
00209 } catch (const SctApiException & s) {
00210
00211 std::ostringstream os;
00212 os << "WARNING: doRawScan failed: SctApiException with message ["<<s.what()<<"] caught in doRawScanThread in file " << __FILE__ << " at line " << __LINE__<< ".";
00213 if (mrs) {
00214 *mrs << MRS_WARNING << MRS_QUALIF("doRawScan") << MRS_TEXT(os.str()) << ENDM;
00215 };
00216 cout << os.str() << std::endl;
00217
00218 } catch (const ConfigurationException & c) {
00219
00220 std::ostringstream os;
00221 os << "WARNING: doRawScan failed: ConfigurationException with message ["<<c.what()<<"] caught in doRawScanThread in file " << __FILE__ << " at line " << __LINE__<< ".";
00222 if (mrs) {
00223 *mrs << MRS_WARNING << MRS_QUALIF("doRawScan") << MRS_TEXT(os.str()) << ENDM;
00224 };
00225 cout << os.str() << std::endl;
00226
00227 } catch (const std::exception & e) {
00228
00229 std::ostringstream os;
00230 os << "WARNING: doRawScan failed: std::exception with message ["<<e.what()<<"] caught in doRawScanThread in file " << __FILE__ << " at line " << __LINE__<< ".";
00231 if (mrs) {
00232 *mrs << MRS_WARNING << MRS_QUALIF("doRawScan") << MRS_TEXT(os.str()) << ENDM;
00233 };
00234 cout << os.str() << std::endl;
00235
00236 } catch (...) {
00237
00238
00239
00240 std::ostringstream os;
00241 os << "WARNING: doRawScan failed: unknon exception caught in doRawScanThread in file " << __FILE__ << " at line " << __LINE__<< ".";
00242 if (mrs) {
00243 *mrs << MRS_WARNING << MRS_QUALIF("doRawScan") << MRS_TEXT(os.str()) << ENDM;
00244 };
00245 cout << os.str() << std::endl;
00246
00247 };
00248
00249 if(m_isDict) {
00250 m_isDict->remove(m_id->infoServiceNameOfScanStatusObject());
00251 }
00252 m_inRawScanLoop = false;
00253 }
00254
00255 void SctApi::doRawScanThreadInnards(boost::shared_ptr<Scan> scan, int delay, int width, bool configure, bool clkBy2) {
00256 {
00257 boost::mutex::scoped_lock lock(log().mutex());
00258 log() << "doRawScanThread\n";
00259 }
00260
00261 scan->setStartTime(second_clock::universal_time());
00262
00263 scan->setRunNumber(runNumber);
00264 scan->setScanNumber(scanNumber);
00265
00266 scanNumber ++;
00267
00268 scan->print();
00269
00270 const int realUnits = width;
00271 int units;
00272
00273 if(checkDebugOption(DEBUG_SAVE_RAW_CAPTURE)) {
00274 units = 0x8000;
00275 } else {
00276 units = realUnits;
00277 }
00278
00279 int nBins = scan->getScanPoints1().size();
00280
00281 map<UINT32, UINT32 *> dataMap;
00282
00283 for(map<UINT32, ABCDModule> ::const_iterator iter = moduleMap.begin();
00284 iter != moduleMap.end();
00285 iter ++) {
00286 UINT32 *rawData = new UINT32[nBins * realUnits * 2];
00287
00288 for(int i=0; i<nBins*realUnits*2; i++) {
00289 rawData[i] = 0;
00290 }
00291
00292 dataMap.insert(make_pair(iter->first, rawData));
00293 }
00294
00295 map<RodLabel, unsigned char *> fibreMappings;
00296
00297
00298 for(list<RodLabel>::const_iterator rl = rodList.begin();
00299 rl!=rodList.end();
00300 rl++){
00301 int crate = rl->crate;
00302 int rod = rl->rod;
00303
00304 if(!getCrate()->checkBOCLasersOn(rod)) {
00305 cout << "Continuing raw scan using BOC that has its lasers cut out\n";
00306 if(mrs) {
00307 *mrs << "BOC_INTERLOCKED" << MRS_WARNING << MRS_QUALIF("SCTAPI")
00308 << MRS_PARAM<int>("crate", crate)
00309 << MRS_PARAM<int>("rod", rod)
00310 << MRS_TEXT("Continuing raw scan (BOC may be interlocked)") << ENDM;
00311 }
00312 }
00313
00314 try {
00315 fibreMappings[*rl] = config->getFibreMappings(rl->partition, rl->crate, rl->rod);
00316 } catch(ConfigurationException &c) {
00317 cout << "No fibre mappings for appropriate module: \n";
00318 cout << c.what() << endl;
00319
00320 {
00321 boost::mutex::scoped_lock lock(log().mutex());
00322 log() << " (Not found)\n";
00323 }
00324
00325 if(mrs) {
00326 *mrs << "SCAN_ABORT" << MRS_ERROR
00327 << MRS_QUALIF("SCTAPI") << MRS_QUALIF("doRawScan")
00328 << MRS_TEXT("Aborting scan due to missing fibre mappings")
00329 << ENDM;
00330 }
00331
00332 std::ostringstream os;
00333 os << "Aborting raw scan due to missing fibre mappings in " << __FILE__ << " at line " << __LINE__ << ".";
00334
00335 throw SctApiException(os.str());
00336 }
00337
00338 if(clkBy2)
00339 getCrate()->enterBOCClockBy2Mode(rod);
00340 }
00341
00342 if(configure) {
00343 cout << "Configure modules for scan\n";
00344 } else {
00345 cout << "Don't configure module\n";
00346 }
00347
00348
00349
00350 Scan::TrigPoints trigs = scan->getVariableTrigs();
00351
00352 int bin = 0;
00353 vector<FLOAT32> scanPoints = scan->getScanPoints1();
00354
00355 const boost::shared_ptr<Trigger> trigger = scan->getTrigger1();
00356
00357 #if USE_IS
00358 if(m_isDict) {
00359 ISInfoInt binNumber(0);
00360 m_isDict->insert("SCTAPIServer.currentBin", binNumber);
00361
00362 ISInfoInt maxNumber(scanPoints.size()-1);
00363 m_isDict->insert("SCTAPIServer.maxBin", maxNumber);
00364 }
00365 #endif
00366
00367 for(vector<FLOAT32>::const_iterator point_iter = scanPoints.begin();
00368 point_iter != scanPoints.end();
00369 point_iter++, bin++) {
00370
00371 cout << "Bin: " << bin << endl;
00372
00373 #if USE_IS
00374 if(m_isDict) {
00375 ISInfoInt binNumber(bin);
00376 m_isDict->update("SCTAPIServer.currentBin", binNumber);
00377 }
00378 #endif
00379
00380 modifyABCDVar(scan->getScanVariable1(), *point_iter);
00381 if(configure) {
00382 std::cout << "Sending SCAN bank to all modules" << std::endl;
00383 setABCDModules(std::list<BankType>(1,SCTAPI_BANK_SCAN));
00384 const bool enableDataMode = scan->getOption(Scan::ENABLE_DATA_MODE);
00385 sendAllABCDModules(SCTAPI_BANK_SCAN, SCTAPI_CONFIG_ALL, enableDataMode);
00386 }
00387
00388 for(unsigned int t=0; t<trigs[bin]; t++) {
00389 for(list<RodLabel>::const_iterator rl = rodList.begin();
00390 rl!=rodList.end();
00391 rl++){
00392 unsigned int partition = rl->partition;
00393 unsigned int crate = rl->crate;
00394 unsigned int rod = rl->rod;
00395
00396 const RodLabel &rodLabel = *rl;
00397
00398 if(checkDebugOption(DEBUG_DIAG)) {
00399 cout << "doRawScan bin: " << bin << " trigger: " << t << " on (" << partition << ", " << crate << ", " << rod << ")\n";
00400 }
00401
00402 setupRawData(rod, delay, units, false, trigger.get());
00403
00404 unsigned long* bufferA = readFifo(rod, 0, 0, units);
00405 unsigned long* bufferB = readFifo(rod, 0, 1, units);
00406
00407 if(!bufferA || !bufferB) {
00408 cout << "Failed to read FIFO\n";
00409
00410 std::ostringstream os;
00411 os << "Aborting raw scan due to FIFO read failure in " << __FILE__ << " at line " << __LINE__ << ".";
00412
00413 throw SctApiException(os.str());
00414 }
00415
00416 if(checkDebugOption(DEBUG_SAVE_RAW_CAPTURE)) {
00417 dumpRawEvent(rod, units, bufferA, bufferB);
00418 }
00419
00420 for(map<UINT32, ABCDModule> ::const_iterator iter = moduleMap.begin();
00421 iter != moduleMap.end();
00422 iter ++) {
00423
00424 UINT32 mid = iter->first;
00425
00426 unsigned int thisPartition, thisCrate, thisRod, channel;
00427 Utility::getpcrc(mid, thisPartition, thisCrate, thisRod, channel);
00428
00429
00430 if(!(thisRod == rod && thisCrate == crate && thisPartition == partition)) {
00431 continue;
00432 }
00433
00434 UINT32 *rawData = dataMap.find(mid)->second;
00435
00436 if(!rawData) {
00437 cout << "Can't find preallocated memory!\n";
00438
00439 std::ostringstream os;
00440 os << "Aborting raw scan due failure to find preallocated memory in " << __FILE__ << " at line " << __LINE__ << ".";
00441
00442 throw SctApiException(os.str());
00443 }
00444
00445 for(int link=0; link<2; link++) {
00446 int fibre = fibreMappings[rodLabel][channel * 3 + link + 1];
00447
00448 for(int i=0; i<realUnits; i++) {
00449 int val = lookupFifoHit((UINT16*)bufferA, (UINT16*)bufferB, fibre, i);
00450 rawData[bin * (realUnits*2) + (realUnits * link) + i] += val?1:0;
00451 }
00452 }
00453 }
00454 delete [] bufferA;
00455 delete [] bufferB;
00456 }
00457 }
00458 }
00459
00460
00461
00462 scan->setEndTime(second_clock::universal_time());
00463
00464
00465
00466
00467 #if USE_IS
00468 if(m_isDict) {
00469 m_isDict->remove("SCTAPIServer.currentBin");
00470 m_isDict->remove("SCTAPIServer.maxBin");
00471 }
00472 #endif
00473
00474 for(list<RodLabel>::const_iterator rl = rodList.begin();
00475 rl!=rodList.end();
00476 rl++){
00477 delete [] fibreMappings[*rl];
00478
00479 if(clkBy2)
00480 getCrate()->leaveBOCClockBy2Mode(rl->rod);
00481
00482 if(checkDebugOption(DEBUG_BOC_SETUP))
00483 printBOCSetup(rl->rod);
00484
00485 getCrate()->configureBOC(rl->rod);
00486 }
00487
00488
00489
00490
00491
00492 scan_result_ptrs scanResult;
00493
00494 ScanHeader &header = scanResult.header;
00495
00496
00497 header.version = CURRENT_SCANHEADER_VERSION;
00498 header.length = sizeof(ScanHeader);
00499 header.runNumber = scan->getRunNumber();
00500 header.scanNumber = scan->getScanNumber();
00501
00502 strncpy(header.startTime, to_iso_string(scan->getStartTime()).c_str(), 16);
00503 strncpy(header.endTime, to_iso_string(scan->getEndTime()).c_str(), 16);
00504 header.startTime[15] = 0;
00505 header.endTime[15] = 0;
00506
00507 header.scanType = scan->getScanVariable1();
00508 header.npoints = nBins;
00509 header.size = nBins * 2 * realUnits * 2;
00510 header.dataType = SR_DT_RAWHIST;
00511
00512 header.width = SR_WD_32;
00513 header.pntPoints = sizeof(ScanHeader);
00514 header.pntEvents = header.pntPoints + nBins * sizeof(FLOAT32);
00515 header.pntErrors = header.pntEvents + nBins * sizeof(UINT32);
00516 header.pntData = header.pntErrors + nBins * sizeof(UINT32);
00517
00518
00519 FLOAT32 *points = new FLOAT32[nBins];
00520 for(int i=0; i<nBins; i++) {
00521 points[i] = scan->getScanPoints1()[i];
00522 }
00523 scanResult.points = points;
00524
00525
00526 UINT32 *events = new UINT32[nBins];
00527 for(int i=0; i<nBins; i++) {
00528 events[i] = trigs[i];
00529 }
00530 #warning "Could be counted (raw scan)?"
00531 scanResult.nEvents = events;
00532
00533
00534 #warning "What errors should be recorded in raw scan?"
00535
00536 UINT32 *errors = new UINT32[nBins];
00537 for(int i=0; i<nBins; i++) {
00538 errors[i] = 0;
00539 }
00540 scanResult.nErrorEvents = errors;
00541
00542
00543 time_t secs;
00544 secs = time(NULL);
00545 struct tm broke;
00546 broke = *(gmtime(&secs));
00547
00548
00549 for(map<UINT32, ABCDModule> ::const_iterator iter = moduleMap.begin();
00550 iter != moduleMap.end();
00551 iter ++) {
00552
00553
00554
00555 strncpy(header.moduleName, convertToString(iter->first).c_str(), 16);
00556 header.moduleName[15] = 0;
00557 header.config = iter->second;
00558
00559 scanResult.data = dataMap.find(iter->first)->second;
00560
00561
00562
00563 if(checkDebugOption(DEBUG_SAVE_HISTOGRAM)) {
00564 const int BUFF_SIZE = 50;
00565 char filename[BUFF_SIZE];
00566
00567 int written = snprintf(filename, BUFF_SIZE, "RawHistogram_%s", convertToString(iter->first).c_str());
00568
00569 strftime(filename + written, BUFF_SIZE - written, "_%Y%m%d%H%M%S.bin", &broke);
00570
00571 cout << "Saving raw histogram: " << filename << endl;
00572 saveHistogramToFile(scanResult, filename);
00573 }
00574
00575 #if USE_IS
00576 cout << "Writing raw data to IS\n";
00577
00578 try {
00579 SctData::ScanResultWriter::publish(scanResult);
00580 } catch(Sct::IoException &e) {
00581 cout << "ScanResult publish failed:\n" << e.what() << endl;
00582 e.sendToMrs(MRS_ERROR);
00583 }
00584 #endif
00585
00586 delete [] dataMap.find(iter->first)->second;
00587
00588 dataMap.find(iter->first)->second = 0;
00589 }
00590
00591 delete [] scanResult.points;
00592 delete [] scanResult.nEvents;
00593 delete [] scanResult.nErrorEvents;
00594
00595
00596 for(map<UINT32, UINT32 *> ::const_iterator iter = dataMap.begin();
00597 iter != dataMap.end();
00598 iter ++) {
00599 if(iter->second) {
00600 delete [] iter->second;
00601 }
00602 }
00603 }
00604
00605 #warning "Should this stay, or become something better..."
00606
00607 void SctApi::readRawData(unsigned int rod,
00608 int delay, bool setMask) {
00609 {
00610 boost::mutex::scoped_lock lock(log().mutex());
00611 log() << "Raw histogram of all ROD data\n";
00612 }
00613
00614 int units = 768 * 2;
00615
00616 scan_result_ptrs scanResult;
00617
00618
00619 time_t secs;
00620 secs = time(NULL);
00621 struct tm broke;
00622 broke = *(gmtime(&secs));
00623
00624 int nBins = 96;
00625
00626 ScanHeader &header = scanResult.header;
00627
00628 header.version = 0;
00629 header.length = sizeof(ScanHeader);
00630 header.runNumber = runNumber;
00631 header.scanNumber = scanNumber;
00632 strncpy(header.moduleName, "raw link data", 16);
00633 header.moduleName[15] = 0;
00634 header.scanType = 0;
00635 header.npoints = nBins;
00636 header.size = nBins * 2 * 1024 * 2;
00637 #warning "Need new type for this (readRawData)"
00638 header.dataType = SR_DT_SLICE;
00639
00640
00641 header.width = SR_WD_32;
00642
00643
00644 unsigned long *startAddress = (unsigned long*)&header.config;
00645 fill(startAddress, startAddress + sizeof(ABCDModule)/sizeof(unsigned long), 0);
00646
00647 header.pntPoints = sizeof(ScanHeader);
00648 header.pntEvents = header.pntPoints + nBins * sizeof(FLOAT32);
00649 header.pntErrors = header.pntEvents + nBins * sizeof(UINT32);
00650 header.pntData = header.pntErrors + nBins * sizeof(UINT32);
00651
00652
00653 FLOAT32 *points = new FLOAT32[nBins];
00654 for(int i=0; i<nBins; i++) {
00655 points[i] = i;
00656 }
00657 scanResult.points = points;
00658
00659
00660 UINT32 *events = new UINT32[nBins];
00661 for(int i=0; i<nBins; i++) {
00662 events[i] = 1;
00663 }
00664 scanResult.nEvents = events;
00665
00666
00667 UINT32 *errors = new UINT32[nBins];
00668 for(int i=0; i<nBins; i++) {
00669 #warning "More 0 error counts (readRawData)"
00670 errors[i] = 0;
00671 }
00672 scanResult.nErrorEvents = errors;
00673
00674
00675 int binSize = 0x800*4;
00676
00677 setupRawData(rod, delay, units, setMask);
00678
00679 unsigned long *bufferA = readFifo(rod, 0, 0, units);
00680 unsigned long *bufferB = readFifo(rod, 0, 1, units);
00681
00682 char *data = new char[nBins * binSize];
00683
00684 unsigned long *longData = (unsigned long *)data;
00685
00686 for(int ch=0; ch<96; ch++) {
00687 for(int i=0; i<units; i++) {
00688 int val = lookupFifoHit((UINT16*)bufferA, (UINT16*)bufferB, ch, i);
00689 longData[ch * (units) + i] = val;
00690 }
00691 cout << endl;
00692 }
00693
00694 delete [] bufferA;
00695 delete [] bufferB;
00696
00697 scanResult.data = data;
00698
00699
00700 const int BUFF_SIZE = 50;
00701 char filename[BUFF_SIZE];
00702
00703 int written = snprintf(filename, BUFF_SIZE, "RawHistogramFull");
00704
00705 strftime(filename + written, BUFF_SIZE - written, "_%Y%m%d%H%M%S.bin", &broke);
00706
00707 cout << "Saving raw histogram: " << filename << endl;
00708
00709 saveHistogramToFile(scanResult, filename);
00710 }
00711
00712 vector<char> SctApi::probeWithTrigger(unsigned int rod,
00713 const Trigger *trigger, signed int harness) {
00714 int delay = 5;
00715 const int realUnits = 100;
00716 int units;
00717
00718 if(checkDebugOption(DEBUG_SAVE_RAW_CAPTURE)) {
00719 units = 0x8000;
00720 } else {
00721 units = realUnits;
00722 }
00723
00724 int startCh = 0;
00725 int endCh = 47;
00726
00727 if(harness != -1) {
00728 startCh = harness*6;
00729 endCh = harness*6 + 5;
00730 }
00731
00732
00733 int numLinks = ((endCh+1) - startCh) * 2;
00734 vector<char> result(numLinks);
00735
00736 if(!getCrate()) {
00737 cout << "Aborting probe on nonexistant crate!\n";
00738 if(mrs) {
00739 *mrs << "CRATE_NOTEXIST" << MRS_ERROR << MRS_QUALIF("SCTAPI")
00740 << MRS_PARAM<int>("crate", crt())
00741 << MRS_TEXT("Aborting probe (Crate does not exist)") << ENDM;
00742 }
00743 return result;
00744 }
00745
00746 if(!getCrate()->RODPresent(rod)) {
00747 cout << "No configured ROD ! Aborting probe\n";
00748 if(mrs) {
00749 *mrs << "ROD_NONEXIST" << MRS_ERROR << MRS_QUALIF("SCTAPI")
00750 << MRS_PARAM<int>("crate", crt())
00751 << MRS_PARAM<int>("rod", rod)
00752 << MRS_TEXT("Aborting probe (ROD not configured)") << ENDM;
00753 }
00754
00755 return result;
00756 }
00757
00758 if(!getCrate()->checkBOCLasersOn(rod)) {
00759 cout << "Continuing probe using BOC that has its lasers cut out\n";
00760 if(mrs) {
00761 *mrs << "BOC_INTERLOCKED" << MRS_WARNING << MRS_QUALIF("SCTAPI")
00762 << MRS_PARAM<int>("crate", crt())
00763 << MRS_PARAM<int>("rod", rod)
00764 << MRS_TEXT("Continuing probe (BOC interlocked)") << ENDM;
00765 }
00766 }
00767
00768
00769 int setupSuccess = setupRawData(rod, delay, units, true, trigger);
00770
00771 if(!setupSuccess) {
00772 cout << "Probe failed!";
00773 for(int i = 0; i<numLinks; i++) {
00774 result[i] = 'X';
00775 }
00776 return result;
00777 }
00778
00779 unsigned long *bufferA = readFifo(rod, 0, 0, units);
00780 unsigned long *bufferB = readFifo(rod, 0, 1, units);
00781
00782 if(!bufferA && !bufferB) {
00783 cout << "No data refusing to analyse probe!\n";
00784 return vector<char>();
00785 }
00786
00787 if(checkDebugOption(DEBUG_SAVE_RAW_CAPTURE)) {
00788 dumpRawEvent(rod, units, bufferA, bufferB);
00789 }
00790
00791
00792 units = realUnits;
00793
00794 char *data = new char[units];
00795
00796 for(int index=0; index<numLinks; index++) {
00797 int link = index + startCh*2;
00798 bool same = true;
00799 bool clock2 = true;
00800 bool clock4 = true;
00801 signed char lastValue2 = -1;
00802 signed char lastValue = -1;
00803
00804 int headerState = 0;
00805
00806
00807 int eventStart = -1;
00808
00809 for(int i=0; i<units; i++) {
00810 int val = lookupFifoHit((UINT16*)bufferA, (UINT16*)bufferB, link, i);
00811
00812 if(i > 0) {
00813 if(same && lastValue != val) {
00814 same = false;
00815 }
00816 if(clock2 && lastValue == val) {
00817 clock2 = false;
00818 }
00819 if(clock4 && lastValue2 == val) {
00820 clock4 = false;
00821 }
00822 lastValue2 = lastValue;
00823 }
00824
00825 lastValue = val;
00826 data[i] = val;
00827
00828 switch(headerState) {
00829 case 0:
00830 if(val == 1) headerState = 1;
00831 break;
00832 case 1:
00833 if(val == 0) headerState = 10;
00834 else headerState = 2;
00835 break;
00836 case 2:
00837 if(val == 0) headerState = 20;
00838 else headerState = 3;
00839 break;
00840 case 3:
00841 if(val == 0) headerState = 4;
00842 else headerState = 99;
00843 break;
00844 case 4:
00845 if(val == 1) {
00846 headerState = 21;
00847 eventStart = i-4;
00848 } else headerState = 99;
00849 break;
00850 case 10:
00851 if(val == 1) headerState = 11;
00852 else headerState = 99;
00853 break;
00854 case 11:
00855 if(val == 0) headerState = 12;
00856 else headerState = 99;
00857 break;
00858 case 12:
00859 if(val == 1) headerState = 13;
00860 else headerState = 15;
00861 break;
00862 case 13:
00863 if(val == 0) headerState = 14;
00864 else headerState = 99;
00865 break;
00866 case 14:
00867 if(val == 0) headerState = 22;
00868 else headerState = 99;
00869 break;
00870 case 15:
00871 if(val == 1) headerState = 16;
00872 else headerState = 99;
00873 break;
00874 case 16:
00875 if(val == 0) headerState = 23;
00876 else headerState = 99;
00877 break;
00878 case 20:
00879
00880 if(val == 1) headerState = 31;
00881 break;
00882 case 22:
00883 case 23:
00884
00885 if(val == 1) headerState = 99;
00886 break;
00887 case 31:
00888 if(val == 0) headerState = 99;
00889 else headerState = 32;
00890 break;
00891 case 32:
00892 if(val == 0) headerState = 33;
00893 else headerState = 99;
00894 break;
00895 case 33:
00896
00897 if(val == 1) headerState = 99;
00898 break;
00899 default:
00900
00901
00902 break;
00903 }
00904 }
00905
00906 bool verbose = checkDebugOption(DEBUG_VERBOSE_PROBE);
00907
00908 if(verbose) {
00909 cout.width(2);
00910 cout << (link/2) << " (" << link%2 << ") ";
00911 }
00912
00913 if(same) {
00914 result[index] = int(lastValue) + '0';
00915 if(verbose) cout << "All " << int(lastValue) << "'s\n";
00916 } else if(clock2) {
00917 result[index] = '2';
00918 if(verbose) cout << "Clock by 2\n";
00919 } else if(clock4) {
00920 result[index] = '4';
00921 if(verbose) cout << "Clock by 4\n";
00922 } else {
00923 switch(headerState) {
00924 case 20:
00925 result[index] = 'L';
00926 if(verbose) cout << "L1A\n";
00927 break;
00928 case 21:
00929 result[index] = 'E';
00930 if(verbose) {
00931 cout << "Event Header ";
00932
00933 int l1 = 0;
00934 for (int i=6; i<=9; i++) {
00935 l1 = (l1 << 1) + data[i+eventStart];
00936 }
00937 cout << "L1 = " << l1;
00938
00939
00940 int bc = 0;
00941 for (int i=10; i<=17; i++) {
00942 bc = (bc << 1) + data[i+eventStart];
00943 }
00944 cout << " BC = " << bc << endl;
00945 }
00946 break;
00947 case 22:
00948 result[index] = 'S';
00949 if(verbose) cout << "Soft Reset\n";
00950 break;
00951 case 23:
00952 result[index] = 'B';
00953 if(verbose) cout << "BC Reset\n";
00954 break;
00955 case 33:
00956 result[index] = 'l';
00957 if(verbose) cout << "2 * L1A\n";
00958 break;
00959 default:
00960 result[index] = 'J';
00961 if(verbose) cout << "Junk\n";
00962 break;
00963 }
00964 if(verbose) {
00965 cout << " ";
00966 for(int i=0; i<min(units, 60); i++) {
00967 cout << int(data[i]);
00968 }
00969 cout << endl;
00970 }
00971 }
00972 }
00973
00974 delete [] bufferA;
00975 delete [] bufferB;
00976
00977 delete [] data;
00978
00979 return result;
00980 }
00981
00982 vector<char> SctApi::probe(unsigned int rod,
00983 signed int harness) {
00984 return probeWithTrigger(rod, 0, harness);
00985 }
00986
00987 vector<vector<char> > SctApi::probeScan(unsigned int rod,
00988 boost::shared_ptr<Scan> scan, signed int harness) {
00989 {
00990 boost::mutex::scoped_lock lock(log().mutex());
00991 log() << "probeScan\n";
00992 }
00993
00994 scan->setRunNumber(runNumber);
00995 scan->setScanNumber(scanNumber);
00996
00997 scan->print();
00998
00999 vector<FLOAT32> scanPoints = scan->getScanPoints1();
01000
01001 const boost::shared_ptr<Trigger> trigger = scan->getTrigger1();
01002
01003 vector<vector<char> > result(scanPoints.size());
01004
01005 if(scanPoints.size() == 0) {
01006 cout << "Asked for probeScan with 0 scan points\n";
01007 }
01008
01009 for(unsigned int point = 0; point < scanPoints.size(); point ++) {
01010 FLOAT32 val = scanPoints[point];
01011
01012 try {
01013 modifyABCDVar(scan->getScanVariable1(), val);
01014 } catch(SctApiException &s) {
01015 std::cout << "SctApi Exception thrown by modifyABCDVar in probeScan:\n";
01016 std::cout << s.what() << std::endl;
01017 }
01018
01019 result[point] = probeWithTrigger(rod, trigger.get(), harness);
01020 }
01021
01022 if(checkDebugOption(DEBUG_BOC_SETUP))
01023 printBOCSetup(rod);
01024
01025 getCrate()->configureBOC(rod);
01026
01027 return result;
01028 }
01029
01030 bool SctApi::checkAllModulesProbe(string value) {
01031 bool result = true;
01032
01033 for(list<RodLabel>::const_iterator rl = rodList.begin();
01034 rl!=rodList.end();
01035 rl++){
01036 vector<char> values = probe(rl->rod);
01037
01038
01039 #warning "Slightly inefficient (all modules for each ROD)"
01040 for(map<UINT32, ABCDModule>::const_iterator mi = moduleMap.begin();
01041 mi!=moduleMap.end();
01042 mi ++) {
01043 UINT32 currMid = mi->first;
01044
01045 #warning "Only checks non redundant links"
01046
01047
01048
01049 unsigned int partition, crate, rod, channel;
01050 ::SctApi::Utility::getpcrc(currMid, partition, crate, rod, channel);
01051
01052 if(partition == rl->partition && crate == rl->crate && rod == rl->rod) {
01053 unsigned char *mappings = config->getFibreMappings(partition, crate, rod);
01054
01055 if(mappings[channel * 3 + 1] != (unsigned char)DATA_LINK_OFF) {
01056 char link0 = values[mappings[channel * 3 + 1]];
01057 if(find(value.begin(), value.end(), link0) == value.end()) {
01058 result = false;
01059 cout << "Failed on link 0 of " << currMid << " (" << link0 << ")\n";
01060
01061 if(mrs) {
01062
01063 char link0str[2];
01064 link0str[0] = link0;
01065 link0str[1] = 0;
01066 *mrs << "MODULE_STATE" << MRS_INFORMATION << MRS_QUALIF("SCTAPI")
01067 << MRS_PARAM<int>("moduleID", currMid)
01068 << MRS_PARAM<const char *>("sn", convertToString(currMid).c_str())
01069 << MRS_PARAM<const char *>("required", value.c_str())
01070 << MRS_PARAM<const char *>("found", link0str)
01071 << MRS_TEXT("Link0 of module not in required state") << ENDM;
01072 }
01073
01074 break;
01075 }
01076 }
01077
01078 if(mappings[channel * 3 + 2] != (unsigned char)DATA_LINK_OFF) {
01079 char link1 = values[mappings[channel * 3 + 2]];
01080 if(find(value.begin(), value.end(), link1) == value.end()) {
01081 result = false;
01082 cout << "Failed on link 1 of " << currMid << " (" << link1 << ")\n";
01083 if(mrs) {
01084
01085 char link1str[2];
01086 link1str[0] = link1;
01087 link1str[1] = 0;
01088 *mrs << "MODULE_STATE" << MRS_INFORMATION << MRS_QUALIF("SCTAPI")
01089 << MRS_PARAM<int>("moduleID", currMid)
01090 << MRS_PARAM<const char *>("sn", convertToString(currMid).c_str())
01091 << MRS_PARAM<const char *>("required", value.c_str())
01092 << MRS_PARAM<const char *>("found", link1str)
01093 << MRS_TEXT("Link1 of module not in required state") << ENDM;
01094 }
01095
01096 break;
01097 }
01098 }
01099 }
01100 }
01101 }
01102
01103 return result;
01104 }
01105
01106 }