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