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