00001
00009 #include "SctApi.h"
00010 #include "SctApiConsts.h"
00011 #include "SctApiDebug.h"
00012 #include "SctApiHisto.h"
00013 #include "ScanMonitorImpl.h"
00014 #include "crate.h"
00015 #include "primListWrapper.h"
00016 #include "PrimBuilder.h"
00017 #include "ConfigurationUtility.h"
00018
00019 #include "RodCrate/RodModule.h"
00020 #include "RodCrate/TimDefine.h"
00021 #include "CommonWithDsp/primParams.h"
00022 #include "CommonWithDsp/registerIndices.h"
00023
00024 #include "Sct/AbcdScans.h"
00025 #include "Sct/AbcdChip.h"
00026 #include "Sct/StringStreamer.h"
00027
00028 #include "ScanResultWriter/scan.h"
00029 #include "utility.h"
00030
00031 #include "primUtils.h"
00032
00033 #include "VmeDecode.h"
00034
00035 #ifdef USE_IS
00036 #include <is/infoT.h>
00037 #include "Sct/IoExceptions.h"
00038 #include "ScanResultWriter/ScanResultWriter.h"
00039 #endif
00040 #include "Sct/SctNames.h"
00041
00042 #include "Scan.h"
00043 #include "Trigger.h"
00044 #include "SctApiException.h"
00045
00046 #include <boost/date_time/posix_time/posix_time.hpp>
00047 #include <boost/lexical_cast.hpp>
00048
00049 #include <algorithm>
00050
00051 #include "Sct/MultiMessageDebugStream.h"
00052 #include "Idiosyncrasy.h"
00053 #include "ScanDefImpl.h"
00054
00055 using namespace std;
00056 using namespace Sct;
00057 using namespace SctPixelRod;
00058 using namespace boost::posix_time;
00059 using boost::shared_ptr;
00060
00061 namespace SctApi {
00062
00072 int useCCode(const SctApi& api, const Scan& scan){
00073 if (api.checkDebugOption(DEBUG_SCAN_USE_CCODE)) return 1;
00074 if (scan.getOption(Scan::USE_CCODE)) return 2;
00075 if (scan.getOption(Scan::FULL)) return 3;
00076
00077 if (scan.getOption(Scan::OPE)) return 4;
00078 return 0;
00079 }
00080
00081 void SctApi::validateScan(boost::shared_ptr<const Scan> scan) {
00082
00083 if(scan->getScanPoints2().size() != 0 &&
00084 scan->getScanPoints2().size() != scan->getScanPoints1().size()) {
00085 string message("Can't have two different sized scan points! (unless points(2) is empty)");
00086 cout << message << endl;
00087 if(mrs) {
00088 *mrs << "INVALID_SCAN" << MRS_ERROR
00089 << MRS_QUALIF("SCTAPI") << MRS_QUALIF("doScan")
00090 << MRS_PARAM<int>("ScanPoints(1) size",scan->getScanPoints1().size())
00091 << MRS_PARAM<int>("ScanPoints(2) size",scan->getScanPoints2().size())
00092 << MRS_TEXT(message)
00093 << ENDM;
00094 }
00095 throw SctApiException(message);
00096 }
00097
00098 if(scan->getScanPoints1().empty() && scan->getScanPoints1().empty()){
00099 string message("Scan points are empty!");
00100 cout << message << endl;
00101 if(mrs) {
00102 *mrs << "INVALID_SCAN" << MRS_ERROR
00103 << MRS_QUALIF("SCTAPI") << MRS_QUALIF("doScan")
00104 << MRS_TEXT(message)
00105 << ENDM;
00106 }
00107 throw SctApiException(message);
00108 }
00109
00110 if (scan->getTrigger1()->getRODTriggers().empty()
00111 && scan->getTrigger2()->getRODTriggers().empty()){
00112 string message("Both triggers are empty!");
00113 cout << message << endl;
00114 if(mrs) {
00115 *mrs << "INVALID_TRIGGER" << MRS_ERROR
00116 << MRS_QUALIF("SCTAPI") << MRS_QUALIF("doScan")
00117 << MRS_TEXT(message)
00118 << ENDM;
00119 }
00120 throw SctApiException(message);
00121 }
00122
00123 if (scan->getOption(Scan::TIM) &&
00124 !scan->getTrigger2()->getRODTriggers().empty()){
00125 string message("Can't have second trigger for TIM histogramming");
00126 cout << message << endl;
00127 if(mrs) {
00128 *mrs << "INVALID_TRIGGER" << MRS_ERROR
00129 << MRS_QUALIF("SCTAPI") << MRS_QUALIF("doScan")
00130 << MRS_PARAM<const char*>("Trigger(2)",scan->getTrigger1()->print().c_str())
00131 << MRS_TEXT(message)
00132 << ENDM;
00133 }
00134 throw SctApiException(message);
00135 }
00136
00137 if (scan->getOption(Scan::TIM) &&
00138 !scan->getTrigger1()->isValidTIMTrigger()){
00139 string message("Trigger(1) is not a valid TIM trigger");
00140 if(mrs) {
00141 *mrs << "INVALID_TRIGGER" << MRS_ERROR
00142 << MRS_QUALIF("SCTAPI") << MRS_QUALIF("doScan")
00143 << MRS_TEXT(message)
00144 << MRS_PARAM<const char*>("Trigger(1)",scan->getTrigger1()->print().c_str())
00145 << ENDM;
00146 }
00147 throw SctApiException(message);
00148 }
00149
00150 if(scan->getOption(Scan::TIM)==0 &&
00151 !scan->getTrigger1()->isValidRODTrigger()){
00152 string message("Trigger(1) is not a valid ROD trigger");
00153 cout << message << endl;
00154 if(mrs) {
00155 *mrs << "INVALID_TRIGGER" << MRS_ERROR
00156 << MRS_QUALIF("SCTAPI") << MRS_QUALIF("doScan")
00157 << MRS_TEXT("Trigger(1) is not a valid ROD trigger")
00158 << MRS_PARAM<const char*>("Trigger(1)",scan->getTrigger1()->print().c_str())
00159 << ENDM;
00160 }
00161 throw SctApiException(message);
00162 }
00163
00164 if(scan->getOption(Scan::TIM)==0 &&
00165 !scan->getTrigger2()->getRODTriggers().empty() &&
00166 scan->getTrigger2()->isValidRODTrigger()){
00167 string message("Trigger(2) is not a valid ROD trigger");
00168 cout << message << endl;
00169 if(mrs) {
00170 *mrs << "INVALID_TRIGGER" << MRS_ERROR
00171 << MRS_QUALIF("SCTAPI") << MRS_QUALIF("doScan")
00172 << MRS_TEXT("Trigger(2) is not a valid ROD trigger")
00173 << MRS_PARAM<const char*>("Trigger(2)",scan->getTrigger1()->print().c_str())
00174 << ENDM;
00175 }
00176 throw SctApiException(message);
00177 }
00178 }
00179
00180 boost::shared_ptr<ScanMonitor> SctApi::startAsyncScan(boost::shared_ptr<const Scan> scan) {
00181 return boost::shared_ptr<ScanMonitor> ( new ScanMonitorImpl(startScan(scan, false)));
00182 }
00183
00184 boost::shared_ptr<ScanControl> SctApi::startScan(boost::shared_ptr<const Scan> constScan, bool pollTriggers) {
00185 {
00186 boost::mutex::scoped_lock lock(log().mutex());
00187 log() << "startScan\n";
00188 }
00189
00190 #if USE_CONST_SCAN
00191 boost::shared_ptr<const Scan> scan = constScan;
00192 #else
00193 #warning "Shouldn't do this!!!!"
00194
00195
00196 std::cout << "Copying the constScan to a private version we can modify" << std::endl;
00197 boost::shared_ptr<Scan> scan = ScanDefImpl::clone(constScan);
00198 std::cout << "Finished copying the constScan to a private version we can modify" << std::endl;
00199 #endif
00200
00201
00202 boost::shared_ptr<ScanEx> extra(new ScanEx);
00203
00204 #if USE_CONST_SCAN
00205 extra->setStartTime(second_clock::universal_time());
00206 #else
00207 scan->setStartTime(second_clock::universal_time());
00208 #endif
00209
00210 extra->diagnosticReg = 0;
00211
00212 extra->trimScan = 0;
00213 if(scan->getScanVariable1() == ST_TRIM) {
00214
00215 extra->trimScan = 1;
00216 }
00217
00218 cout << "Do scan " << scanNumber << ":\n";
00219
00220 scan->setRunNumber(runNumber);
00221 scan->setScanNumber(scanNumber);
00222
00223
00224 if(scan->getOption(Scan::FULL)) {
00225
00226 scanNumber += 3;
00227 } else {
00228 scanNumber += 1;
00229 }
00230
00231 if(mrs) {
00232 const std::string s1 = (Sct::StringStreamer << "SCAN_REQSD_" << ucid());
00233 const std::string s2 = (Sct::StringStreamer << "Scan requested on " << ucid());
00234
00235 *mrs << s1 << MRS_INFORMATION
00236 << MRS_PARAM<int>("run", runNumber) << MRS_PARAM<int>("scan", scan->getScanNumber()) << MRS_TEXT(s2) << ENDM;
00237 }
00238
00239 std::cout << scan->print() << std::endl;
00240
00241 validateScan(scan);
00242
00243 if(!checkModuleListsForScan()) {
00244 throw SctApiException("Invalid scan. Module lists check failed");
00245 }
00246
00247 setupScanMasks(*extra, scan->getOption(Scan::DISTSLAVE), scan->getScanPoints2().size() != 0);
00248
00249 RodLabel zeroRod = extra->rodInfo.begin()->first;
00250
00251 #if !USE_CONST_SCAN
00252
00253 for(unsigned int i = 0;
00254 i<extra->groupLists.size();
00255 i++) {
00256 scan->setModuleList(i, extra->groupLists[i]);
00257 }
00258 scan->setNGroups(extra->groupLists.size());
00259 #endif
00260
00261
00262 if(checkDebugOption(DEBUG_DIAG)) {
00263 RodScanEx &rodInfo = extra->rodInfo.find(zeroRod)->second;
00264 cout << hex << "Channels in use: 0x" << rodInfo.channels.mask0 << " 0x" << rodInfo.channels.mask1 << dec << endl;
00265
00266 for(int i=0; i<numSlaves * 2; i++) {
00267 cout << hex << "Group channels: 0x" << rodInfo.groupChannels[i].mask0 << " 0x" << rodInfo.groupChannels[i].mask1 << dec << endl;
00268 }
00269
00270 for(int i=0; i<numSlaves; i++) {
00271 cout << hex << "Slave channels: 0x" << rodInfo.slaveChannels[i].mask0 << " 0x" << rodInfo.slaveChannels[i].mask1 << dec << endl;
00272 }
00273
00274 cout << "Slave DSP bit-field: " << hex << (int)rodInfo.bitFieldDSP << dec << " nSlaves: " << rodInfo.slaves << endl;
00275
00276 hex(cout);
00277 for(int i=0; i<numSlaves; i++) {
00278 cout << "Groups on DSP " << i << ": 0x" << (int)extra->groupDspMap[i] << endl;
00279 }
00280
00281 for(int i=0; i<2; i++) {
00282 cout << "Groups to serial port " << i << ": 0x" << (int)extra->groupSpMap[i] << endl;
00283 }
00284
00285 for(int i=0; i<2; i++) {
00286 cout << "Groups using range list " << i << ": 0x" << (int)extra->groupRangeMap[i] << endl;
00287 }
00288 dec(cout);
00289 }
00290
00291 for(ScanEx::RodInfoMap::const_iterator ri = extra->rodInfo.begin();
00292 ri != extra->rodInfo.end();
00293 ri++) {
00294 if(ri->second.bitFieldDSP & 0xf == 0) {
00295 #warning "Should only abort if no slaves on all RODs?"
00296 cout << "No slaves have been deemed involved in histogramming aborting\n";
00297 if(mrs) {
00298 *mrs << MRS_ERROR
00299 << "SCAN_NODSP"
00300 << MRS_QUALIF("SCTAPI") << MRS_QUALIF("doScan")
00301 << MRS_TEXT("No DSP matched to modules for scan")
00302 << MRS_PARAM<int>("partition", ri->first.partition)
00303 << MRS_PARAM<int>("crate", ri->first.crate)
00304 << MRS_PARAM<int>("rod", ri->first.rod)
00305 << ENDM;
00306 }
00307
00308 throw SctApiException("Invalid scan. A ROD doesn't have any modules attached");
00309 }
00310 }
00311
00312 if (mrs){
00313 ostringstream oss;
00314 oss << ucid() << " Starting pre scan hardware check";
00315 *mrs << MRS_INFORMATION << MRS_QUALIF("SCTAPI") << "HARDWARE_CHECK"
00316 << MRS_TEXT(oss.str()) << ENDM;
00317 };
00318
00319 if (!preScanHardwareCheck(*scan.get(), *extra)) throw SctApiException("Pre scan hardware check failed");
00320
00321 std::cout << ucid() << " Starting pre-scan module setup at TIME " << second_clock::universal_time() << std::endl;
00322
00323 if (mrs){
00324 ostringstream oss;
00325 oss << ucid() << " Starting pre scan module setup";
00326 *mrs << MRS_INFORMATION << MRS_QUALIF("SCTAPI") << "MODULE_SETUP"
00327 << MRS_TEXT(oss.str()) << ENDM;
00328 };
00329
00330 preScanModuleSetup(*scan.get());
00331
00332 {
00333
00334 Trigger::RODTriggers points = scan->getTrigger1()->getRODTriggers();
00335
00336 for(unsigned int i=0; i<points.size(); i++) {
00337 if(points[i].first == SOFT_RESET) {
00338 cout << "Do extra soft reset before trigger to mask soft reset in trigger\n";
00339 extra->diagnosticReg |= 1 << DR_SOFT_BC_RESET;
00340 }
00341 }
00342 }
00343
00344 bool setupGood = true;
00345
00346
00347 if (mrs){
00348 ostringstream oss;
00349 oss << ucid() << " Setting up DSP histogramming tasks";
00350 *mrs << MRS_INFORMATION << MRS_QUALIF("SCTAPI") << "HISTO_SETUP"
00351 << MRS_TEXT(oss.str()) << ENDM;
00352 };
00353
00354
00355 std::cout << ucid() << " Setting up histogramming tasks started at TIME "
00356 << second_clock::universal_time() << std::endl;
00357
00358 try {
00359 cout << "Setup histogramming tasks ...\n";
00360 doHistogramSetup(*scan.get(), *extra);
00361 cout << " ... done setup histogramming tasks\n";
00362 } catch(SctApiException &s) {
00363 setupGood = false;
00364 }
00365
00366
00367 if(mrs) {
00368 const std::string s1 = (Sct::StringStreamer << "SCAN_STARTED_" << ucid());
00369 #if USE_CONST_SCAN
00370 const std::string s2 = (Sct::StringStreamer << "Scan started on " << ucid() << " with nGroups " << extra->getNGroups() );
00371 #else
00372 const std::string s2 = (Sct::StringStreamer << "Scan started on " << ucid() << " with nGroups " << scan->getNGroups() );
00373 #endif
00374 *mrs << s1 << MRS_INFORMATION
00375 << MRS_QUALIF("SCTAPI") << MRS_QUALIF("doScan")
00376 << MRS_TEXT(s2)
00377 << MRS_PARAM<int>("ScanNumber", scan->getScanNumber())
00378 << MRS_PARAM<int>("ScanType1", scan->getScanVariable1())
00379 << MRS_PARAM<int>("ScanType2", scan->getScanVariable2())
00380 << ENDM;
00381 }
00382
00383 boost::shared_ptr<ScanControl> newScanController;
00384
00385 try {
00386 if(setupGood) {
00387
00388 if(!pollTriggers) {
00389 newScanController.reset(new ScanControlAsyncHisto(*this, scan, extra));
00390 } else if(scan->getOption(Scan::TIM)) {
00391 newScanController.reset(new ScanControlTIMHisto(*this, scan, extra));
00392 } else {
00393 newScanController.reset(new ScanControlRODHisto(*this, scan, extra));
00394 }
00395
00396 std::cout << ucid() << " Starting histogramming ... at TIME " << second_clock::universal_time() << std::endl;
00397 newScanController->startHistogramming();
00398 std::cout << ucid() << " Histogramming started at TIME " << second_clock::universal_time() << std::endl;
00399 }
00400 } catch(SctApiException &s) {
00401 setupGood = false;
00402 }
00403
00404 if(setupGood) {
00405
00406
00407 if(pollTriggers) {
00408 scanController = newScanController;
00409 }
00410 }
00411
00412 std::cout << ucid() << " finished histo setup at TIME "
00413 << second_clock::universal_time() << std::endl;
00414
00415 return newScanController;
00416 }
00417
00418 void SctApi::doScan(boost::shared_ptr<const Scan> scan) {
00419 {
00420 boost::mutex::scoped_lock lock(log().mutex());
00421 log() << "doScan\n";
00422 }
00423
00424 boost::shared_ptr<ScanControl> monitor = startScan(scan, true);
00425
00426
00427 #if ( (USE_SCAN_THREAD) ==0 )
00428 if(monitor) {
00429 std::cout << "No scan thread - doing the scan loop polling in same thread!" << std::endl;
00430
00431 scanLoop();
00432 }
00433 #endif
00434 }
00435
00436 void SctApi::awaitScan() {
00437 while((scanController || m_inScanLoop) || m_inRawScanLoop) {
00438 sleep(1);
00439 }
00440 }
00441
00442
00443 void SctApi::scanLoop() {
00444
00445 m_inScanLoop = true;
00446
00447 boost::shared_ptr<ScanControl> control;
00448
00449
00450 swap(control, scanController);
00451
00452
00453 lastScanController = control;
00454
00455 if(!control) {
00456 cout << "Given null scan aborting!\n";
00457 return;
00458 }
00459
00460 control->initialisePolling();
00461
00462 int pollReturn = pollHistogramming(control, 3);
00463
00464 cout << "pollHistogramming complete (" << pollReturn << ")\n";
00465
00466 control->finishHistogram(pollReturn == 0);
00467
00468
00469 m_inScanLoop = false;
00470 }
00471
00472 void SctApi::scanPollingThread() {
00473 cout << "SCAN: Start polling thread\n";
00474 while(!m_stopPolling) {
00475 usleep(500000);
00476 if(scanController) {
00477 scanLoop();
00478 }
00479 }
00480 }
00481
00482 void SctApi::setupEventTrapping(const Scan &scan, const ScanEx &ex, const RodLabel rod, boost::shared_ptr<PrimListWrapper> primList) {
00483 const RodScanEx &rodInfo = ex.getRodScanInfo(rod);
00484
00485
00486 for(int slaveNumber=0; slaveNumber<numSlaves; slaveNumber++) {
00487 if((rodInfo.bitFieldDSP & (1<<slaveNumber)) && getCrate()->slavePresent(rod.rod, slaveNumber)) {
00488 int match;
00489 int modulus;
00490 int remainder;
00491
00492 switch(scan.getOption(Scan::DISTSLAVE)) {
00493 case 0:
00494
00495 match = 0;
00496 modulus = 1;
00497 remainder = 0;
00498
00499 if(scan.getOption(Scan::NTH) > 1) {
00500
00501 modulus = scan.getOption(Scan::NTH);
00502 remainder = scan.getOption(Scan::NTH_REM);
00503 }
00504 break;
00505 case 1:
00506
00507 match = slaveNumber;
00508 modulus = 1;
00509 remainder = 0;
00510 break;
00511 case 2:
00512
00513 match = 0;
00514 modulus = rodInfo.slaves;
00515 remainder = slaveNumber;
00516
00517 if(scan.getOption(Scan::NTH) > 1) {
00518 modulus = rodInfo.slaves * scan.getOption(Scan::NTH);
00519 remainder = slaveNumber * scan.getOption(Scan::NTH) + scan.getOption(Scan::NTH_REM);
00520 }
00521 break;
00522 default:
00523 match = 0;
00524 modulus = 1;
00525 remainder = 0;
00526 break;
00527 }
00528
00529 eventTrapSetup(0x1 << slaveNumber,
00530 match, modulus, remainder,
00531 scan.getOption(Scan::TIM), checkDebugOption(DEBUG_SCAN_ERROR_TRAP_ALL), primList);
00532 }
00533 }
00534 }
00535
00536 void SctApi::setupEventDump(const Scan &scan, const ScanEx &ex, const RodLabel rod, boost::shared_ptr<PrimListWrapper> primList) {
00537 if(!(checkDebugOption(DEBUG_SCAN_ERROR_TRAP) && scan.getOption(Scan::DEBUG))) return;
00538
00539 int slaveNumber = 2;
00540
00541
00542 {
00543
00544 long *evData = new long[sizeof(EVENT_TRAP_SETUP_IN)/sizeof(long)];
00545
00546 EVENT_TRAP_SETUP_IN &primData = *(EVENT_TRAP_SETUP_IN*)evData;
00547
00548 #if R_EVENT_TRAP_SETUP == 103
00549 primData.slvBits = 0x1 << slaveNumber;
00550 primData.numberOfEvents = COLLECT_FOREVER;
00551 primData.timeoutInUsec = 0x30000;
00552
00553 primData.extRouterSetup = 0;
00554
00555
00556
00557 primData.distribute = TRAP_DISTRIB_NEITHER;
00558
00559 primData.releaseFrames = 0;
00560 primData.permitBackPressure = 1;
00561 primData.dataMode = 0;
00562 primData.sLink = 0;
00563
00564 primData.format = TRAP_FMT_ERROR;
00565 primData.trapStray = 1;
00566 primData.iterLimit = 2;
00567
00568
00569 primData.trapConfig[0] = TRAP_CFG_ROD_EVT;
00570 primData.trapExclusionFlag[0] = 0;
00571 primData.trapFunction[0] = TRAP_FXN_RESYNCH;
00572
00573 primData.trapMatch[0] = 0;
00574 primData.trapModulus[0] = 1;
00575 primData.trapRemainder[0] = 0;
00576
00577
00578 primData.trapConfig[1] = TRAP_CFG_IDLE;
00579 primData.trapExclusionFlag[1] = 0;
00580 primData.trapFunction[1] = 0;
00581
00582 primData.trapMatch[1] = 0;
00583 primData.trapModulus[1] = 0;
00584 primData.trapRemainder[1] = 0;
00585 #else
00586 #error "Event trapping not compiled (new Primitive definition)!"
00587 #endif
00588 primList->addPrimitive(RodPrimitive(sizeof(EVENT_TRAP_SETUP_IN)/sizeof(UINT32) + 4,
00589 0, EVENT_TRAP_SETUP, R_EVENT_TRAP_SETUP, evData),
00590 evData);
00591 }
00592
00593
00594 startEventTrap(slaveNumber, primList);
00595
00596
00597 {
00598 long *taskData = new long[sizeof(START_TASK_IN)/sizeof(long)];
00599
00600 for(unsigned int i=0; i<sizeof(START_TASK_IN)/sizeof(long); i++) {
00601 taskData[i] = 0;
00602 }
00603
00604 START_TASK_IN &taskPrim = *(START_TASK_IN *)taskData;
00605
00606 taskPrim.taskType = RESYNCH_TASK;
00607 taskPrim.taskRevision = R_RESYNCH_TASK;
00608 taskPrim.priority = 1;
00609 taskPrim.completionFlag = 1;
00610
00611 RESYNCH_TASK_IN &resynch = taskPrim.taskStruct.resynchTaskIn;
00612
00613 resynch.errorType = 0;
00614
00615 shared_ptr<PrimListWrapper> myList(new PrimListWrapper(4));
00616
00617 myList->addPrimitive(RodPrimitive(4 + sizeof(START_TASK_IN)/sizeof(UINT32),
00618 3, START_TASK, R_START_TASK, taskData),
00619 taskData);
00620
00621 PrimBuilder::instance().slavePrimList(primList, myList, slaveNumber, true, true);
00622 }
00623 }
00624
00625 void SctApi::startEventTrapping(const Scan &scan, const ScanEx &ex, const RodLabel rod, shared_ptr<PrimListWrapper> primList) {
00626 const RodScanEx &rodInfo = ex.getRodScanInfo(rod);
00627
00628 for(int slaveNumber=0; slaveNumber<numSlaves; slaveNumber++) {
00629 if((rodInfo.bitFieldDSP & (1<<slaveNumber)) && getCrate()->slavePresent(rod.rod, slaveNumber)) {
00630 startEventTrap(slaveNumber, primList);
00631 }
00632 }
00633 }
00634
00635 void SctApi::setupHistogramming(const Scan &scan, const ScanEx &ex, const RodLabel rod, bool tim,
00636 boost::shared_ptr<PrimListWrapper> primList) {
00637 const RodScanEx &rodInfo = ex.getRodScanInfo(rod);
00638
00639 int nBins = scan.getScanPoints1().size();
00640 if(!scan.getOption(Scan::BITS32)) {
00641 if(nBins%2 == 1) {
00642 nBins += 1;
00643 }
00644 }
00645
00646 for(int slaveNumber = 0; slaveNumber < 4; slaveNumber ++) {
00647 if((rodInfo.bitFieldDSP & (1<<slaveNumber)) && getCrate()->slavePresent(rod.rod, slaveNumber)) {
00648
00649 long *histoData = new long[sizeof(HISTOGRAM_SETUP_IN)/sizeof(UINT32)];
00650
00651 HISTOGRAM_SETUP_IN &primData = *(HISTOGRAM_SETUP_IN*)histoData;
00652
00653 #if (R_HISTOGRAM_SETUP == 108)
00654 primData.base = (UINT32 *)0xffffffff;
00655 primData.nBins = nBins;
00656
00657 primData.dataType[0] = scan.getScanVariable1();
00658 primData.dataType[1] = scan.getScanVariable2();
00659
00660 primData.binSize = scan.getOption(Scan::BITS32)?HISTOGRAM_32BIT:HISTOGRAM_16BIT;
00661
00662 if(useCCode(*this, scan)) {
00663 primData.routineType = HISTO_ROUTINE_C;
00664 {
00665 Sct::MultiMessageDebugStream m(true,false,true);
00666 m << ucid() << " is using CCODE rather than ASM for histogramming (reason="
00667 << useCCode(*this,scan) << ")";
00668 };
00669 } else {
00670 primData.routineType = HISTO_ROUTINE_ASM;
00671 }
00672
00673
00674
00675
00676 primData.opt[0] = scan.getOption(Scan::OPE)?1:0;
00677
00678
00679 primData.opt[1] = scan.getOption(Scan::FULL)?HISTOGRAM_FULL:HISTOGRAM_CONDENSED;
00680
00681
00682 primData.opt[2] = 0;
00683
00684 primData.opt[3] = 0;
00685
00686 UINT8 groupMap = ex.groupDspMap[slaveNumber];
00687
00688 primData.validModules[0] = 0;
00689 primData.validModules[1] = 0;
00690
00691 primData.moduleRangeMap[0][0] = 0;
00692 primData.moduleRangeMap[0][1] = 0;
00693 primData.moduleRangeMap[1][0] = 0;
00694 primData.moduleRangeMap[1][1] = 0;
00695
00696 for(int i=0; i<8; i++) {
00697 if(groupMap & (1<<i)) {
00698 primData.validModules[0] |= rodInfo.groupChannels[i].mask0;
00699 primData.validModules[1] |= rodInfo.groupChannels[i].mask1;
00700
00701 if(ex.groupSpMap[0] & (1<<i)) {
00702 primData.moduleRangeMap[0][0] |= rodInfo.groupChannels[i].mask0;
00703 primData.moduleRangeMap[0][1] |= rodInfo.groupChannels[i].mask1;
00704 }
00705 if(ex.groupSpMap[1] & (1<<i)) {
00706 primData.moduleRangeMap[1][0] |= rodInfo.groupChannels[i].mask0;
00707 primData.moduleRangeMap[1][1] |= rodInfo.groupChannels[i].mask1;
00708 }
00709 }
00710 }
00711
00712 primData.xPtr[0] = (FLOAT32 *)0xffffffff;
00713 primData.xPtr[1] = (FLOAT32 *)0xffffffff;
00714 #elif (R_HISTOGRAM_SETUP == 105) || (R_HISTOGRAM_SETUP == 107)
00715 primData.base = (UINT32 *)0xffffffff;
00716 primData.nBins = nBins;
00717
00718 primData.padding[0] = 0;
00719 primData.padding[1] = 0;
00720
00721 primData.dataType[0] = scan.getScanVariable1();
00722 primData.dataType[1] = scan.getScanVariable2();
00723
00724 primData.binSize = scan.getOption(Scan::BITS32)?HISTOGRAM_32BIT:HISTOGRAM_16BIT;
00725
00726
00727 primData.opt[0] = HISTOGRAM_SLICE;
00728
00729 primData.opt[1] = scan.getOption(Scan::FULL)?HISTOGRAM_FULL:HISTOGRAM_CONDENSED;
00730
00731 primData.opt[2] = 0;
00732 #if(R_HISTOGRAM_SETUP == 107)
00733 primData.opt[3] = 0;
00734 #endif
00735
00736 UINT8 groupMap = ex.groupDspMap[slaveNumber];
00737
00738 primData.validModules[0] = 0;
00739 primData.validModules[1] = 0;
00740
00741 primData.moduleRangeMap[0][0] = 0;
00742 primData.moduleRangeMap[0][1] = 0;
00743 primData.moduleRangeMap[1][0] = 0;
00744 primData.moduleRangeMap[1][1] = 0;
00745
00746 for(int i=0; i<8; i++) {
00747 if(groupMap & (1<<i)) {
00748 primData.validModules[0] |= rodInfo.groupChannels[i].mask0;
00749 primData.validModules[1] |= rodInfo.groupChannels[i].mask1;
00750
00751 if(ex.groupSpMap[0] & (1<<i)) {
00752 primData.moduleRangeMap[0][0] |= rodInfo.groupChannels[i].mask0;
00753 primData.moduleRangeMap[0][1] |= rodInfo.groupChannels[i].mask1;
00754 }
00755 if(ex.groupSpMap[1] & (1<<i)) {
00756 primData.moduleRangeMap[1][0] |= rodInfo.groupChannels[i].mask0;
00757 primData.moduleRangeMap[1][1] |= rodInfo.groupChannels[i].mask1;
00758 }
00759 }
00760 }
00761
00762 primData.xPtr[0] = (FLOAT32 *)0xffffffff;
00763 primData.xPtr[1] = (FLOAT32 *)0xffffffff;
00764 #elif R_HISTOGRAM_SETUP == 104
00765 primData.base = (UINT32 *)0xffffffff;
00766 primData.rodType = ROD_TYPE_SCT;
00767 primData.nBins = nBins;
00768
00769 primData.padding[0] = 0;
00770 primData.padding[1] = 0;
00771
00772 primData.dataType[0] = scan.getScanVariable1();
00773 primData.dataType[1] = scan.getScanVariable2();
00774
00780 primData.arrangement = HISTOGRAM_SLICE;
00781 primData.dataFormat = scan.getOption(Scan::FULL)?HISTOGRAM_FULL:HISTOGRAM_CONDENSED;
00782 primData.binSize = scan.getOption(Scan::BITS32)?HISTOGRAM_32BIT:HISTOGRAM_16BIT;
00783 primData.unused = 0;
00784
00785 if(scan.getOption(Scan::DISTSLAVE) == 1) {
00786 primData.validModules[0] = rodInfo.groupChannels[slaveNumber][0];
00787 primData.validModules[1] = rodInfo.groupChannels[slaveNumber][1];
00788 primData.moduleRangeMap[0][0] = rodInfo.groupChannels[slaveNumber][0];
00789 primData.moduleRangeMap[0][1] = rodInfo.groupChannels[slaveNumber][1];
00790 } else {
00791 primData.validModules[0] = rodInfo.channels[0];
00792 primData.validModules[1] = rodInfo.channels[1];
00793 primData.moduleRangeMap[0][0] = rodInfo.channels[0];
00794 primData.moduleRangeMap[0][1] = rodInfo.channels[1];
00795 }
00796 primData.moduleRangeMap[1][0] = 0;
00797 primData.moduleRangeMap[1][1] = 0;
00798
00799 primData.xPtr[0] = (FLOAT32 *)0x3f00000;
00800 primData.xPtr[1] = (FLOAT32 *)0x3f01000;
00801 #else
00802 #error "Histogram setup not compiled (new Primitive definition)!"
00803 #endif
00804
00805 long *taskData = new long[sizeof(START_TASK_IN)/sizeof(UINT32)];
00806
00807 for(unsigned int i=0; i<sizeof(START_TASK_IN)/sizeof(UINT32); i++) {
00808 taskData[i] = 0;
00809 }
00810
00811 START_TASK_IN &taskPrim = *(START_TASK_IN *)taskData;
00812
00813 taskPrim.taskType = HISTOGRAM_TASK;
00814 taskPrim.taskRevision = R_HISTOGRAM_TASK;
00815 taskPrim.priority = 1;
00816 taskPrim.completionFlag = 1;
00817
00818 HISTOGRAM_TASK_IN &histoTaskData = taskPrim.taskStruct.histogramTaskIn;
00819
00820 histoTaskData.nEvents = COLLECT_FOREVER;
00821 if(tim) {
00822 histoTaskData.controlFlag = LOCAL_SET_TRIG;
00823 } else {
00824 histoTaskData.controlFlag = MASTER_HREG;
00825 }
00826
00827 boost::shared_ptr<PrimListWrapper> myList(new PrimListWrapper(4));
00828
00829 myList->addPrimitive(RodPrimitive(4 + sizeof(HISTOGRAM_SETUP_IN)/sizeof(UINT32),
00830 2, HISTOGRAM_SETUP, R_HISTOGRAM_SETUP, histoData),
00831 histoData);
00832 myList->addPrimitive(RodPrimitive(4 + sizeof(START_TASK_IN)/sizeof(UINT32),
00833 3, START_TASK, R_START_TASK, taskData),
00834 taskData);
00835
00836 PrimBuilder::instance().slavePrimList(primList, myList, slaveNumber, true, true);
00837 }
00838 }
00839 }
00840
00841 void SctApi::startHistogramTask(const Scan &scan, const ScanEx &ex, const RodLabel rod,
00842 unsigned int startBin, unsigned int nBins, unsigned int nTrigs,
00843 boost::shared_ptr<PrimListWrapper> primList) {
00844 const RodScanEx &rodInfo = ex.getRodScanInfo(rod);
00845
00846
00847 unsigned int allBins = nBins;
00848
00849 long *ctrlData = new long[sizeof(START_TASK_IN)/sizeof(UINT32) + allBins * 2];
00850
00851 for(unsigned int i=0; i<sizeof(START_TASK_IN)/sizeof(UINT32) + allBins * 2; i++) {
00852 ctrlData[i] = 0;
00853 }
00854
00855 struct START_TASK_IN &primData = *(START_TASK_IN*)ctrlData;
00856 struct HISTOGRAM_CTRL_TASK_IN &taskData = primData.taskStruct.histoCtrlTaskIn;
00857
00858 #if (R_HISTOGRAM_CTRL_TASK == 107)
00859 primData.taskType = HISTOGRAM_CTRL_TASK;
00860 primData.taskRevision = R_HISTOGRAM_CTRL_TASK;
00861 primData.priority = 1;
00862 primData.completionFlag = 1;
00863
00864 taskData.slvBits = rodInfo.bitFieldDSP;
00865
00866 if(scan.getScanPoints2().size() > 0) {
00867 taskData.port = SP_BOTH;
00868 } else {
00869
00870
00871
00872
00873
00874 taskData.port = SP0;
00875 }
00876
00877 taskData.configRegister[0] = scan.getScanVariable1();
00878 taskData.configRegister[1] = scan.getScanVariable2();
00879
00880 taskData.configSctSet = Utility::translateBank(SCTAPI_BANK_SCAN);
00881
00882
00883 #if (R_RW_MODULE_DATA>=103)
00884 if(!ex.trimScan) {
00885 taskData.dataSet = CONFIG_MODULE_BASIC;
00886 }else{
00887 taskData.dataSet = CONFIG_MODULE_TRIM;
00888 }
00889 #else
00890 #warning "Using old dataSet values (pre 11 April 2005 dsp code) AJB wonders if this is actually #defined or typedefed to the same values..."
00891 if(!ex.trimScan) {
00892 taskData.dataSet = MODULE_BASIC;
00893 }else{
00894 taskData.dataSet = MODULE_TRIM;
00895 }
00896 #endif
00897
00898 taskData.groupRangeMap[0] = ex.groupRangeMap[0];
00899 taskData.groupRangeMap[1] = ex.groupRangeMap[1];
00900
00901 taskData.groupDSPMap[0] = ex.groupDspMap[0];
00902 taskData.groupDSPMap[1] = ex.groupDspMap[1];
00903 taskData.groupDSPMap[2] = ex.groupDspMap[2];
00904 taskData.groupDSPMap[3] = ex.groupDspMap[3];
00905
00906 taskData.groupSPMap[0] = ex.groupSpMap[0];
00907 taskData.groupSPMap[1] = ex.groupSpMap[1];
00908
00909 taskData.globalCtrl = 0;
00910 taskData.syncLevel = 0;
00911
00912 taskData.histoBase = (UINT32*)0xffffffff;
00913
00914 taskData.doChipOcc = scan.getOption(Scan::OPE)?1:0;
00915 taskData.dataFormat = scan.getOption(Scan::FULL)?HISTOGRAM_FULL:HISTOGRAM_CONDENSED;
00916 taskData.binSize = scan.getOption(Scan::BITS32)?HISTOGRAM_32BIT:HISTOGRAM_16BIT;
00917 taskData.unused1 = 0;
00918
00919 taskData.extSetup = 0xff;
00920 taskData.dataPath = DATA_PATH_NORMAL;
00921 taskData.capture = 0;
00922 taskData.useRangeList = 0;
00923
00924 taskData.repetitions = nTrigs;
00925 taskData.nBins = nBins;
00926 taskData.bin0 = startBin;
00927
00928
00929 for(int i=0; i<5; i++) {
00930 taskData.rangeList[0].xPair[i].x0 = 0.0;
00931 taskData.rangeList[1].xPair[i].x0 = 0.0;
00932 taskData.rangeList[0].xPair[i].delta_x = 0.0;
00933 taskData.rangeList[1].xPair[i].delta_x = 0.0;
00934 }
00935
00936
00937 taskData.dataPtr[0] = (FLOAT32 *)0xffffffff;
00938 taskData.dataPtr[1] = (FLOAT32 *)0xffffffff;
00939
00940
00941 for(int i=0; i<N_CMD_LIST_CMDS; i++) {
00942 taskData.triggerSequence[0].cmd[i] = NO_CMD;
00943 taskData.triggerSequence[1].cmd[i] = NO_CMD;
00944 taskData.triggerSequence[0].data[i] = 0;
00945 taskData.triggerSequence[1].data[i] = 0;
00946 }
00947
00948
00949
00950
00951
00952
00953
00954
00955 Trigger::RODTriggers points = scan.getTrigger1()->getRODTriggers();
00956
00957 for(unsigned int i=0; i<points.size(); i++) {
00958 taskData.triggerSequence[0].cmd[i] = points[i].first;
00959 taskData.triggerSequence[0].data[i] = points[i].second;
00960 }
00961
00962 if(scan.getScanPoints2().size() > 0) {
00963 points = scan.getTrigger2()->getRODTriggers();
00964
00965 for(unsigned int i=0; i<points.size(); i++) {
00966 taskData.triggerSequence[1].cmd[i] = points[i].first;
00967 taskData.triggerSequence[1].data[i] = points[i].second;
00968 }
00969 } else {
00970
00971 }
00972
00973
00974
00975
00976
00977
00978
00979 unsigned short cmd, data;
00980
00981 scan.getTrigger1()->getCommIncr(cmd, data);
00982 taskData.incCmd[0] = cmd;
00983 taskData.incData[0] = data;
00984 scan.getTrigger2()->getCommIncr(cmd, data);
00985 taskData.incCmd[1] = cmd;
00986 taskData.incData[1] = data;
00987
00988 taskData.calLineLoop = scan.getOption(Scan::LOOPCALLINE);
00989 if(scan.getOption(Scan::DISTSLAVE) == 2) {
00990 taskData.distributionToggle = ROUTER_DISTRIB;
00991 } else {
00992 taskData.distributionToggle = MODULE_GROUP;
00993 }
00994
00995 for(int i=0; i<10; i++) {
00996 taskData.genData[i] = 0;
00997 }
00998
00999
01000 taskData.genData[0] = 0xff;
01001
01002 if(scan.getScanPoints2().size() > 0) {
01003 taskData.genData[1] = 1;
01004 taskData.genData[2] = 0x0200;
01005 }
01006
01007 #elif (R_HISTOGRAM_CTRL_TASK == 105)
01008 primData.taskType = HISTOGRAM_CTRL_TASK;
01009 primData.taskRevision = R_HISTOGRAM_CTRL_TASK;
01010 primData.priority = 0;
01011 primData.completionFlag = 1;
01012
01013 taskData.slvBits = 0xf;
01014 taskData.configSctSet = translateBank(SCTAPI_BANK_PHYSICS);
01015
01016
01017
01018 taskData.dataSet = 0;
01019 taskData.useRangeList = 0;
01020 taskData.groupRangeMap[0] = 0;
01021 taskData.groupRangeMap[1] = 0;
01022 taskData.cmdBuff = CMD_BUFFER_BOTH;
01023 taskData.dataPtr[0] = group1Data;
01024 taskData.dataPtr[1] = group2Data;
01025 taskData.repetitions = 10;
01026 taskData.nBins = 10;
01027 taskData.bin0 = 0;
01028
01029 taskData.triggerSequence[0];
01030 taskData.triggerSequence[1];
01031
01032 taskData.incCmd[0] = 0;
01033 taskData.incCmd[1] = 0;
01034 taskData.calLineLoop = 0;
01035
01036 taskData.distributionToggle = 0;
01037 taskData.incData[0] = 1;
01038 taskData.incData[1] = 1;
01039
01040 taskData.groupSPMap[0] = 0;
01041 taskData.groupSPMap[1] = 0;
01042 #else // Unknown R_HISTOGRAM_CTRL_TASK
01043 #error "Histogram Task not compiled (new Primitive definition)!"
01044 #endif
01045
01046 int offset = sizeof(START_TASK_IN)/sizeof(UINT32);
01047
01048
01049 for(unsigned int i=0; i<allBins; i++) {
01050 ctrlData[offset + i] = *(UINT32 *)&(scan.getScanPoints1()[i]);
01051 if(scan.getScanPoints2().size() == 0) {
01052 ctrlData[offset + allBins + i] = *(UINT32*)&(scan.getScanPoints1()[i]);
01053 } else {
01054 ctrlData[offset + allBins + i] = *(UINT32*)&(scan.getScanPoints2()[i]);
01055 }
01056 }
01057
01058 primList->addPrimitive(RodPrimitive(4 + sizeof(START_TASK_IN)/sizeof(UINT32) + allBins * 2,
01059 0, START_TASK, R_START_TASK, ctrlData),
01060 ctrlData);
01061 }
01062
01063
01064
01065
01066
01067
01068
01069 void SctApi::stopHistogramming(const ScanEx &ex) {
01070 for(ScanEx::RodInfoMap::const_iterator ri = ex.rodInfo.begin();
01071 ri != ex.rodInfo.end();
01072 ri++) {
01073 const RodLabel &rod = ri->first;
01074
01075 {
01076 boost::mutex::scoped_lock lock(log().mutex());
01077 log() << "Stop histogramming (controlled)\n";
01078 }
01079
01080
01081
01082
01083
01084
01085 boost::shared_ptr<PrimListWrapper> primList(new PrimListWrapper(2));
01086
01087 PrimBuilder &builder = PrimBuilder::instance();
01088 builder.taskOp(primList, HISTOGRAM_CTRL_TASK, TASK_STOP, 0);
01089
01090 {
01091 boost::mutex::scoped_lock lock(log().mutex());
01092 log() << "Stop histo control task\n";
01093 }
01094 sendPrimList(rod.rod, primList);
01095
01096 awaitResponse(rod.rod, 5);
01097 primList->clear();
01098
01099 cout << "Done kill control task\n";
01100
01101 for(int slaveNumber=0; slaveNumber<numSlaves; slaveNumber++) {
01102
01103 boost::shared_ptr<PrimListWrapper> slList(new PrimListWrapper(1));
01104
01105
01106
01107 builder.taskOp(slList, HISTOGRAM_TASK, TASK_STOP, 0);
01108
01109 PrimBuilder::instance().slavePrimList(primList, slList, slaveNumber, true, true);
01110 {
01111 boost::mutex::scoped_lock lock(log().mutex());
01112 log() << "Stop slave histogram task " << slaveNumber << endl;
01113 }
01114 sendPrimList(rod.rod, primList);
01115 awaitResponse(rod.rod, 5);
01116 slList->clear();
01117 primList->clear();
01118
01119 cout << "Done kill histogram task\n";
01120
01121 stopEventTrap(slaveNumber, primList);
01122
01123 {
01124 boost::mutex::scoped_lock lock(log().mutex());
01125 log() << "Stop Event trapping on slave " << slaveNumber << endl;
01126 }
01127 sendPrimList(rod.rod, primList);
01128
01129 awaitResponse(rod.rod, 5);
01130 primList->clear();
01131
01132 cout << "Done kill event trapping\n";
01133 }
01134 }
01135
01136
01137
01138 cout << "Done kill histogramming tasks\n";
01139 }
01140
01141 ScanControl::ScanControl(SctApi &api) : api(api) {}
01142
01143 #if USE_CONST_SCAN
01144 void ScanControl::setModuleScanCacheToLastPointInScan(SctApi &api, boost::shared_ptr<const Scan> scan,
01145 boost::shared_ptr<const ScanEx> scanEx) {
01146 #else
01147 void ScanControl::setModuleScanCacheToLastPointInScan(SctApi &api, boost::shared_ptr<const Scan> scan) {
01148 #endif
01149 if (api.checkDebugOption(DEBUG_MODULE_CONFIG)) {
01150 std::cout << "setModuleScanCacheToLastPointInScan setting the following values:\n"
01151 << "mid\tsn\tvariable\tvalue\tvar 1/2?" << std::endl;
01152 }
01153
01154 #if USE_CONST_SCAN
01155 for(unsigned int group = 0; group < scanEx->getNGroups(); group ++) {
01156 const ModuleList &groupList = scanEx->getModuleList(group);
01157 #else
01158 for(unsigned int group = 0; group < scan->getNGroups(); group ++) {
01159 const ModuleList &groupList = scan->getModuleList(group);
01160 #endif
01161 for(ModuleList::const_iterator mi = groupList.begin();
01162 mi!=groupList.end();
01163 mi ++) {
01164
01165 string sn = *mi;
01166 UINT32 mid = api.findModule(sn);
01167 {
01168 unsigned int partition, crate, rod, channel;
01169 Utility::getpcrc(mid, partition, crate, rod, channel);
01170 if (api.idiosyncrasy().ucid() != Sct::UCID(partition, crate)) {
01171 std::cout << "\nWARNING!!! I didnt think that sn " << sn << " was on this crate!!!\n"
01172 << __FILE__ << ":" << __LINE__ << std::endl;
01173 continue;
01174 }
01175 }
01176 boost::shared_ptr<SctApiConfigCache::ModuleBanks> banks = api.getModuleConfigCache().getFromMid(mid);
01177 if (!banks.get()){
01178 if (api.mrs) {
01179 *api.mrs << "NO_CACHED_CONFIG" << MRS_ERROR
01180 << MRS_QUALIF("SctApi")
01181 << MRS_PARAM<int>("mid", mid)
01182 << MRS_TEXT("No cache at all available when setting cache at end of scan") << ENDM;
01183 }else{
01184 std::cout << "ERROR! No cache at all available when setting cache at end of scan, mid" << mid << std::endl;
01185 }
01186 continue;
01187 }
01188 boost::shared_ptr<ABCDModule> config = banks->get(SCTAPI_BANK_SCAN);
01189 if (!config.get()){
01190 if (api.mrs) {
01191 *api.mrs << "NO_CACHED_CONFIG" << MRS_ERROR
01192 << MRS_QUALIF("SctApi")
01193 << MRS_PARAM<int>("mid", mid)
01194 << MRS_TEXT("No SCAN cache available when setting cache at end of scan") << ENDM;
01195 }else{
01196 std::cout << "ERROR! No SCAN cache available when setting cache at end of scan, mid" << mid << std::endl;
01197 }
01198 continue;
01199 }
01200
01201 if (group<4){
01202 const ::SctApi::Scan::ScanPoints points = scan->getScanPoints1();
01203 if (!points.empty() && scan->getScanVariable1()!=0 ) {
01204 ConfigUtility::modifyVar(config.get(), scan->getScanVariable1(), points[points.size()-1]);
01205 if(api.checkDebugOption(DEBUG_MODULE_CONFIG)){
01206 std::cout << mid << "\t" << sn << "\t" << scan->getScanVariable1() << "\t"
01207 << points[points.size()-1] << "\t" << "\t[1]" << std::endl;
01208 }
01209 }
01210 }else{
01211 const ::SctApi::Scan::ScanPoints points = scan->getScanPoints2();
01212 if (!points.empty() && scan->getScanVariable2()!=0 ) {
01213 ConfigUtility::modifyVar(config.get(), scan->getScanVariable2(), points[points.size()-1]);
01214 if(api.checkDebugOption(DEBUG_MODULE_CONFIG)){
01215 std::cout << mid << "\t" << sn << "\t" << scan->getScanVariable1() << "\t"
01216 << points[points.size()-1] << "\t" << "\t[2]" << std::endl;
01217 }
01218 }
01219 }
01220 }
01221 }
01222 if(api.checkDebugOption(DEBUG_MODULE_CONFIG)) std::cout << std::endl;
01223 }
01224
01225 void ScanControlRODHisto::readHistograms() {
01226 time_t saveTime;
01227 saveTime = time(NULL);
01228
01229
01230
01231
01232
01233 list<RodLabel> rodList = api.listRods();
01234
01235 for(list<RodLabel>::const_iterator rl = rodList.begin();
01236 rl!=rodList.end();
01237 rl++){
01238
01239 cout << "Reading out modules from ROD " << Sct::URID(rl->partition,
01240 rl->crate,
01241 rl->rod) << " of " << rodList.size() << endl;
01242
01243
01244 #if USE_CONST_SCAN
01245 const unsigned int nGrOuPs = scanEx->getNGroups();
01246 #else
01247 const unsigned int nGrOuPs = scan->getNGroups();
01248 #endif
01249 for(unsigned int group = 0; group < nGrOuPs; group ++) {
01250 #if USE_CONST_SCAN
01251 const ModuleList &groupList = scanEx->getModuleList(group);
01252 #else
01253 const ModuleList &groupList = scan->getModuleList(group);
01254 #endif
01255 cout << "Modules in group " << group << " of " << nGrOuPs << ": count= " << groupList.size() << endl;
01256 for(ModuleList::const_iterator mi = groupList.begin();
01257 mi!=groupList.end();
01258 mi ++) {
01259
01260 string sn = *mi;
01261 cout << "Attempting to find mid for ["<<sn<<"]"<<std::endl;
01262 UINT32 mid = api.findModule(sn);
01263
01264 cout << "serial number is [" << sn << "] mid = " << mid << std::endl;
01265
01266 {
01267 unsigned int partition, crate, rod, channel;
01268 Utility::getpcrc(mid, partition, crate, rod, channel);
01269 if(RodLabel(partition, crate, rod) != *rl) {
01270
01271 cout << "Skipping " << sn << " (in ROD " << Sct::URID(partition,crate,rod) << " not " << Sct::URID(rl->partition, rl->crate, rl->rod) << ")\n";
01272 continue;
01273 }
01274 }
01275
01276 cout << "Module: " << mid << " = " << sn << endl;
01277
01278 try {
01279 if(scan->getOption(Scan::FULL)) {
01280 std::cout << "Readout full mode histograms:" << std::endl;
01281 for(int f=0; f<3; f++) {
01282 std::cout << " (" << f << " of 3)" << std::endl;
01283 scan_result_ptrs result = readHistogramData(mid, f);
01284
01285 result.header.scanNumber += f;
01286
01287
01288 if(checkDebugOption(DEBUG_SAVE_HISTOGRAM)) {
01289 readHistogramToFile(api.ucid(), *scan, *scanEx, mid, api.convertToString(mid), result, saveTime, f);
01290 }
01291
01292 #ifdef USE_IS
01293
01294 if(api.mrs) readHistogramToIS(api.ucid(), *scan, *scanEx, mid, result);
01295 #endif
01296
01297 delete [] (char*)result.data;
01298 delete [] result.points;
01299 delete [] result.nEvents;
01300 delete [] result.nErrorEvents;
01301 }
01302 } else {
01303 std::cout << "Readout non-full mode histogram" << std::endl;
01304 scan_result_ptrs result = readHistogramData(mid, 0);
01305
01306 if(checkDebugOption(DEBUG_SAVE_HISTOGRAM)) {
01307 readHistogramToFile(api.ucid(), *scan, *scanEx, mid, api.convertToString(mid), result, saveTime);
01308 }
01309 #ifdef USE_IS
01310 if(api.mrs)readHistogramToIS(api.ucid(), *scan, *scanEx, mid, result);
01311 #endif
01312 delete [] (char*)result.data;
01313 delete [] result.points;
01314 delete [] result.nEvents;
01315 delete [] result.nErrorEvents;
01316 }
01317 } catch(SctApiException &s) {
01318 std::cout << "Scan readout failed" << std::endl;
01319 if(api.mrs) {
01320 *api.mrs << "SCAN_READOUT_FAIL" << MRS_ERROR
01321 << MRS_QUALIF("SctApi")
01322 << MRS_PARAM<int>("run", scan->getRunNumber())
01323 << MRS_PARAM<int>("scan", scan->getScanNumber())
01324 << MRS_PARAM<int>("mid", mid)
01325 << MRS_TEXT("Module readout failed") << ENDM;
01326 }
01327 }
01328 }
01329 }
01330
01331
01332 for(std::map<std::pair<RodLabel, int>,
01333 Utility::MemoryBlock> :: iterator mapIter = scanEx->histoMap.begin();
01334 mapIter != scanEx->histoMap.end();
01335 mapIter++) {
01336
01337 if(mapIter->first.first == *rl) {
01338 if(api.mrs) {
01339 *api.mrs << "SCAN_READOUT" << MRS_DIAGNOSTIC
01340 << MRS_PARAM<float>("MWords", mapIter->second.size() / 1e6)
01341 << MRS_PARAM<int>("crate", rl->crate)
01342 << MRS_PARAM<int>("rod", rl->rod)
01343 << MRS_TEXT("Releasing memory after histogram readout") << ENDM;
01344 }
01345
01346 mapIter->second = Utility::MemoryBlock();
01347 }
01348 }
01349 }
01350 }
01351
01352 scan_result_ptrs ScanControlRODHisto::readHistogramData(UINT32 mid, int frame) {
01353 scan_result_ptrs scanResult;
01354
01355
01356
01357 scanResult.data = readHistogramRawData(mid, frame);
01358
01359 if(scanResult.data == 0) {
01360 cout << "readHistogramRawData returned 0 in readHistogramData";
01361 throw SctApiException("readHistogramRawData returned 0 in readHistogramData");
01362 }
01363
01364 int nBins = scan->getScanPoints1().size();
01365
01366
01367
01368
01369
01370
01371
01372
01373
01374 ABCDModule moduleConfig;
01375 boost::shared_ptr<SctApiConfigCache::ModuleBanks> the_banks=api.getModuleConfigCache().getFromMid(mid);
01376 if (!the_banks.get()) {
01377 if(api.mrs) {
01378 *api.mrs << "ROD_BANK_CONFIG_CACHE" << MRS_ERROR << MRS_QUALIF("SCTAPI")
01379 << MRS_PARAM<int>("mid", mid)
01380 << MRS_TEXT("Cant return cache for non-existant MID at end of scan") << ENDM;
01381 }else{
01382 cerr << "Non-existant module mid=" << mid << std::endl;
01383 }
01384 } else {
01385 boost::shared_ptr<ABCDModule> scan_config = the_banks->get(SCTAPI_BANK_SCAN);
01386 if (!scan_config.get()){
01387 if(api.mrs) {
01388 *api.mrs << "ROD_BANK_CONFIG_CACHE" << MRS_ERROR << MRS_QUALIF("SCTAPI")
01389 << MRS_PARAM<int>("mid", mid)
01390 << MRS_TEXT("Cant return cache for non-existant SCAN BANK at end of scan") << ENDM;
01391 }else{
01392 cerr << "Non-existant scan bank at end of scan ! mid=" << mid << std::endl;
01393 }
01394 } else {
01395 moduleConfig = *scan_config;
01396 }
01397 }
01398
01399 if(checkDebugOption(DEBUG_MODULE_CONFIG)) {
01400 cout << "Configuration after scan temporarily not available \n";
01401
01402 }
01403
01404 ScanHeader &header = scanResult.header;
01405
01406 header.version = CURRENT_SCANHEADER_VERSION;
01407 header.length = sizeof(ScanHeader);
01408 header.runNumber = scan->getRunNumber();
01409 header.scanNumber = scan->getScanNumber();
01410
01411 strncpy(header.moduleName, api.convertToString(mid).c_str(), 16);
01412 #if USE_CONST_SCAN
01413 strncpy(header.startTime, to_iso_string(scanEx->getStartTime()).c_str(), 16);
01414 strncpy(header.endTime, to_iso_string(scanEx->getEndTime()).c_str(), 16);
01415 #else
01416 strncpy(header.startTime, to_iso_string(scan->getStartTime()).c_str(), 16);
01417 strncpy(header.endTime, to_iso_string(scan->getEndTime()).c_str(), 16);
01418 #endif
01419 header.moduleName[15] = 0;
01420 header.startTime[15] = 0;
01421 header.endTime[15] = 0;
01422
01423
01424
01425 header.scanType = scan->getScanVariable1();
01426 header.npoints = nBins;
01427 header.size = nBins * 2 * 1024 * (scan->getOption(Scan::BITS32)?2:1);
01428 header.dataType = SR_DT_SLICE;
01429
01430 header.width = scan->getOption(Scan::BITS32)?SR_WD_32:SR_WD_16;
01431
01432 header.config = moduleConfig;
01433
01434 header.pntPoints = sizeof(ScanHeader);
01435 header.pntEvents = header.pntPoints + nBins * sizeof(FLOAT32);
01436 header.pntErrors = header.pntEvents + nBins * sizeof(UINT32);
01437 header.pntData = header.pntErrors + nBins * sizeof(UINT32);
01438
01439
01440 FLOAT32 *points = new FLOAT32[nBins];
01441 for(int i=0; i<nBins; i++) {
01442 points[i] = scan->getScanPoints1()[i];
01443 }
01444 scanResult.points = points;
01445
01446
01447 UINT32 *events = new UINT32[nBins];
01448
01449 std::pair<RodLabel, unsigned int> moduleSlave = findModuleSlave(mid);
01450
01451
01452 unsigned long *countChunk = getEventCountChunk(moduleSlave.first, moduleSlave.second);
01453
01454 for(int i=0; i<nBins; i++) {
01455 events[i] = countChunk[i];
01456
01457
01458 if(scan->getOption(Scan::LOOPCALLINE)) {
01459 events[i] >>= 2;
01460 }
01461 }
01462
01463 #if 0
01464
01465 Scan::TrigPoints trigs = scan->getVariableTrigs();
01466
01467 for(int i=0; i<nBins; i++) {
01468 if(i<lastBin[moduleSlave.first]) {
01469 events[i] = trigs[i];
01470 } else if(i == lastBin[moduleSlave.first]) {
01471 events[i] = lastEvent[moduleSlave.first];
01472 } else {
01473 events[i] = 0;
01474 }
01475 }
01476 #endif
01477
01478 scanResult.nEvents = events;
01479
01480
01481 UINT32 *errors = new UINT32[nBins];
01482 for(int i=0; i<nBins; i++) {
01483 #warning "Get real error count (if possible!)"
01484 errors[i] = 0;
01485 }
01486 scanResult.nErrorEvents = errors;
01487
01488 return scanResult;
01489 }
01490
01491 char* ScanControlRODHisto::readHistogramRawData(UINT32 mid, int frame) {
01492 int nBins = scan->getScanPoints1().size();
01493
01494
01495 int rodBins = nBins;
01496 if(!scan->getOption(Scan::BITS32))
01497 if(rodBins%2 == 1) rodBins++;
01498
01499
01500 int binSize = 0x800*(scan->getOption(Scan::BITS32)?4:2);
01501
01502 char *data = new char[nBins * binSize];
01503
01504 bool moduleBlock = false;
01505
01506
01507 unsigned int slaveNumber = 4;
01508
01509 RodLabel rodLabel;
01510 unsigned int channel;
01511 {
01512 unsigned int partition, crate, rod;
01513 Utility::getpcrc(mid, partition, crate, rod, channel);
01514 RodLabel temp(partition, crate, rod);
01515 rodLabel = temp;
01516 }
01517
01518 const RodScanEx &rodInfo = scanEx->getRodScanInfo(rodLabel);
01519
01520 for(int slave=0; slave<4; slave++) {
01521 if((channel<32 && (rodInfo.slaveChannels[slave].mask0 & 1<<channel))
01522 || (channel >= 32 && (rodInfo.slaveChannels[slave].mask1 & 1<<(channel-32)))) {
01523 if(slaveNumber == 4) {
01524 slaveNumber = slave;
01525 } else {
01526 cerr << " ****** Module found on multiple slaves this is an unsupported configuration, the first one will be downloaded??? *****\n";
01527 cerr << " ****** Well you don't expect me to add them all together do you??? *****\n";
01528 #warning "But maybe I should any way"
01529 }
01530 }
01531 }
01532
01533 if(slaveNumber == 4) {
01534 cerr << " ****** Current module not found on any slave, skipping histogram read out *****\n";
01535
01536 throw SctApiException("No mapping from module to DSP found");
01537 }
01538
01539
01540 int index = 0;
01541 int nModules = 0;
01542
01543 for(unsigned int ch=0; ch<48; ch++) {
01544 if(channel == ch) {
01545 index = nModules;
01546 }
01547 if(ch<32) {
01548 if(rodInfo.slaveChannels[slaveNumber].mask0 & 1<<ch) {
01549 nModules ++;
01550 }
01551 } else {
01552 if(rodInfo.slaveChannels[slaveNumber].mask1 & 1<<(ch-32)) {
01553 nModules ++;
01554 }
01555 }
01556 }
01557
01558
01559 unsigned long slaveOffset = 0;
01560
01561 if(moduleBlock) {
01562 slaveOffset += binSize * rodBins;
01563 } else {
01564 slaveOffset += binSize * index;
01565 }
01566
01567
01568 slaveOffset += ((binSize * rodBins * nModules) + binSize) * frame;
01569
01570 bool error = false;
01571
01572 for(int i=0; i<nBins; i++) {
01573 unsigned long *chunk = getHistogramChunk(rodLabel, slaveNumber, slaveOffset, binSize/sizeof(UINT32));
01574 unsigned long *buffer = (unsigned long *)&(data[i*binSize]);
01575
01576 if(chunk) {
01577 for(int b=0; b<binSize/sizeof(UINT32); b++) {
01578 buffer[b] = chunk[b];
01579 }
01580
01581
01582 int bin, module;
01583 int count = sscanf(&((char*)buffer)[binSize-32], "End of bin %d Module %d", &bin, &module);
01584 if(count == 2) {
01585
01586 } else {
01587 if(!error)
01588 printf("Found bad end of histogram bin (%25s)\n", &((char*)buffer)[binSize-32]);
01589 error = true;
01590 }
01591
01592 #warning "Memory leak if sendData didn't work"
01593
01594 } else {
01595 for(int b=0; b<binSize/sizeof(UINT32); b++) {
01596 buffer[b] = 0;
01597 }
01598 }
01599
01600 if(moduleBlock) {
01601 slaveOffset += binSize;
01602 } else {
01603 slaveOffset += binSize * nModules;
01604 }
01605 }
01606
01607 return data;
01608 }
01609
01610 pair<RodLabel, unsigned int> ScanControlRODHisto::findModuleSlave(unsigned int mid) {
01611 RodLabel rodLabel;
01612 unsigned int channel;
01613 {
01614 unsigned int partition, crate, rod;
01615 Utility::getpcrc(mid, partition, crate, rod, channel);
01616 RodLabel temp(partition, crate, rod);
01617 rodLabel = temp;
01618 }
01619
01620 unsigned int slaveNumber = 4;
01621
01622 const RodScanEx &rodInfo = scanEx->getRodScanInfo(rodLabel);
01623
01624 for(int slave=0; slave<4; slave++) {
01625 if((channel<32 && (rodInfo.slaveChannels[slave].mask0 & 1<<channel))
01626 || (channel >= 32 && (rodInfo.slaveChannels[slave].mask1 & 1<<(channel-32)))) {
01627 if(slaveNumber == 4) {
01628 slaveNumber = slave;
01629 } else {
01630 cerr << " ****** Module found on multiple slaves this is an unsupported configuration, the first one will be downloaded??? *****\n";
01631 cerr << " ****** Well you don't expect me to add them all together do you??? *****\n";
01632 #warning "But maybe I should any way"
01633 }
01634 }
01635 }
01636
01637 if(slaveNumber == 4) {
01638 cerr << " ****** Current module not found on any slave, skipping histogram read out *****\n";
01639
01640 throw SctApiException("No mapping from module to DSP found");
01641 }
01642
01643 return make_pair(rodLabel, slaveNumber);
01644 }
01645
01646 void readHistogramToFile(const Sct::UCID & ucid, const Scan &scan, const ScanEx &ex,
01647 UINT32 mid, std::string sn, scan_result_ptrs scanData, time_t saveTime, int frame) {
01648 const int BUFF_SIZE = 50;
01649
01650 struct tm broke;
01651 broke = *(gmtime(&saveTime));
01652
01653 string tempDir = SctNames::getTempDir() + "/";
01654 int bufferLength = BUFF_SIZE + tempDir.length();
01655 char *filename = new char[bufferLength];
01656 strcpy(filename, tempDir.c_str());
01657
01658 cout << "Module: " << mid << " = " << sn << endl;
01659
01660 int written = tempDir.length();
01661 if(scan.getOption(Scan::FULL)) {
01662 written += snprintf(filename + written, bufferLength - written, "Histogram%d_%s", frame, sn.c_str());
01663
01664 strftime(filename + written, bufferLength - written, "_%Y%m%d%H%M%S.bin", &broke);
01665 } else {
01666 written += snprintf(filename + written, bufferLength - written, "Histogram_%s", sn.c_str());
01667
01668 strftime(filename + written, bufferLength - written, "_%Y%m%d%H%M%S.bin", &broke);
01669 }
01670
01671 {
01672 Sct::MultiMessageDebugStream m(true,false,true);
01673 m << ucid << " is writing histogram data to " << filename;
01674 };
01675
01676 saveHistogramToFile(scanData, filename);
01677
01678 cout << "done.\n";
01679
01680 delete [] filename;
01681 }
01682
01683 void saveHistogramToFile(scan_result_ptrs histo, std::string filename) {
01684 ofstream histoout(filename.c_str(), ios::binary);
01685
01686
01687 histoout.write((char*)&histo.header, histo.header.length);
01688
01689
01690 histoout.write((char*)histo.points, histo.header.pntEvents-histo.header.pntPoints);
01691
01692
01693 histoout.write((char*)histo.nEvents, histo.header.pntErrors-histo.header.pntEvents);
01694
01695
01696 histoout.write((char*)histo.nErrorEvents, histo.header.pntData-histo.header.pntErrors);
01697
01698
01699
01700
01701 histoout.write((char*)histo.data, histo.header.size*2);
01702 }
01703
01704 #ifdef USE_IS
01705
01706 void readHistogramToIS(const Sct::UCID & ucid, const Scan &scan, const ScanEx &ex, UINT32 mid, scan_result_ptrs scanData) {
01707
01708
01709
01710
01711
01712 cout << "Writing histogram data to IS\n";
01713
01714
01715
01716 cout << "Module: " << mid << endl;
01717 {
01718 Sct::MultiMessageDebugStream m(true,false,true);
01719 m << ucid << " is writing histogram data to IS for mid " << mid;
01720 };
01721
01722 try {
01723 SctData::ScanResultWriter::publish(scanData);
01724 } catch(Sct::IoException &e) {
01725 cout << "ScanResult publish failed:\n" << e.what() << endl;
01726 e.sendToMrs(MRS_ERROR);
01727 }
01728 }
01729
01730 #endif
01731
01732 int SctApi::pollHistogramming(boost::shared_ptr<ScanControl> controller, int timeout) {
01733 int returnVal = 0;
01734
01735 bool timedout = false;
01736
01737 time_t start_time = time(0);
01738
01739 while(!timedout) {
01740 bool progressMade = false;
01741 bool newBin = false;
01742 if(controller->checkScanComplete(progressMade, newBin)) {
01743
01744 break;
01745 }
01746
01747 if(progressMade) {
01748 start_time = time(0);
01749 }
01750
01751 if(newBin) {
01752 cout << "Controller going to next bin\n";
01753
01754 controller->nextBin();
01755 } else {
01756
01757 #if USE_THREADS
01758
01759 sleep(1);
01760 #else
01761 awaitResponseAll(0);
01762 #endif
01763
01764 if((time(0) - start_time) > timeout) {
01765 timedout = true;
01766 returnVal = -1;
01767
01768 controller->reportTimeout();
01769 controller->reportEventErrors();
01770
01771 break;
01772 }
01773 }
01774 }
01775
01776 #if USE_IS
01777 if(m_isDict) {
01778 m_isDict->remove("SCTAPIServer.currentBin");
01779 m_isDict->remove("SCTAPIServer.maxBin");
01780 }
01781 #endif
01782
01783 return returnVal;
01784 }
01785
01786 void SctApi::doHistogramSetup(const Scan &scan, const ScanEx &extra) {
01787 for(ScanEx::RodInfoMap::const_iterator ri = extra.rodInfo.begin();
01788 ri != extra.rodInfo.end();
01789 ri++) {
01790
01791 const RodLabel &rod = ri->first;
01792
01793
01794
01795 for(int slaveNumber=0; slaveNumber<numSlaves; slaveNumber++) {
01796 if(getCrate()->slavePresent(rod.rod, slaveNumber)) {
01797 if(getCrate()->getRodRevision(rod.rod) >= 0xe) {
01798 #warning "Hard-coded address of incoming event buffer"
01799 setSlaveBlock(rod.rod, slaveNumber, 0x18000, 0x2000, 0);
01800 } else {
01801 setSlaveBlock(rod.rod, slaveNumber, 0x80008000, 0x2000, 0);
01802 }
01803 }
01804 }
01805
01806 boost::shared_ptr<PrimListWrapper> primList(new PrimListWrapper(1));
01807
01808 setupEventTrapping(scan, extra, rod, primList);
01809 startEventTrapping(scan, extra, rod, primList);
01810 setupEventDump(scan, extra, rod, primList);
01811
01812 if(checkDebugOption(DEBUG_EXTRA_DUMPS)) {
01813 standardRegisterDump(rod.rod);
01814
01815 sendPrimList(rod.rod, primList);
01816 awaitResponse(rod.rod, 5);
01817 primList->clear();
01818 }
01819
01820 setupHistogramming(scan, extra, rod, scan.getOption(Scan::TIM), primList);
01821
01822
01823 sendPrimList(rod.rod, primList);
01824 }
01825
01826 for(ScanEx::RodInfoMap::const_iterator ri = extra.rodInfo.begin();
01827 ri != extra.rodInfo.end();
01828 ri++) {
01829 const RodLabel &rod = ri->first;
01830 int responseCode = awaitResponse(rod.rod, 5);
01831 if(responseCode != 0) {
01832 cout << "Histogram setup list failed! (ROD " << rod.rod << ")\n";
01833 throw SctApiException("Histogram setup list failed! (ROD " + boost::lexical_cast<string>(rod.rod) + ")");
01834 } else {
01835 unsigned long length;
01836 unsigned long *result = getResponse(rod.rod, length);
01837
01838 if(result) {
01839 if(result[6] == EVENT_TRAP_SETUP && result[7] == R_EVENT_TRAP_SETUP) {
01840
01841 int numPrims = result[2];
01842 cout << numPrims << " replies from setup primitive list\n";
01843
01844 int offset = 4;
01845 for(int prim = 0; prim<numPrims; prim++) {
01846 cout << prim << ": ";
01847 if(result[offset+2] == EVENT_TRAP_SETUP && result[offset+3] == R_EVENT_TRAP_SETUP) {
01848 cout << "ETS Error code " << result[offset+4] << endl;
01849 } else {
01850 cout << "Unexpected (not ETS) reply from setup primitive list\n";
01851 }
01852 offset += result[offset+0];
01853 }
01854 } else {
01855 cout << "Unexpected output list from histogram setup primitive list\n";
01856 ::SctApi::printOutList(result, length, true, 0, cout,
01857 checkDebugOption(DEBUG_PRINT_UNKNOWN), checkDebugOption(DEBUG_PRINT_RAW));
01858 }
01859 delete [] result;
01860 } else {
01861 cout << "No response to ETS\n";
01862 }
01863 }
01864 }
01865 }
01866
01867 void ScanControlRODHisto::startHistogramming() {
01868 for(ScanEx::RodInfoMap::const_iterator ri = scanEx->rodInfo.begin();
01869 ri != scanEx->rodInfo.end();
01870 ri++) {
01871 const RodLabel &rod = ri->first;
01872
01873
01874 if(scan->getOption(Scan::DEBUG)) {
01875 if(checkDebugOption(DEBUG_SCAN_AUTO_STALL)) {
01876 cout << "** Debug mode setting AUTO_STALL\n";
01877 scanEx->diagnosticReg |= (1<<DR_AUTO_STALL);
01878 }
01879
01880 if(checkDebugOption(DEBUG_SCAN_STEP_MODE)) {
01881 cout << "** Debug mode setting STEP_CTRL\n";
01882 scanEx->diagnosticReg |= (1<<DR_STEP_CTRL);
01883 }
01884
01885 if(checkDebugOption(DEBUG_SCAN_PAUSE_PULSE)) {
01886 #ifdef DR_PULSE_PAUSE
01887 cout << "** Debug mode setting PAUSE_PULSE\n";
01888 scanEx->diagnosticReg |= (1<<DR_PULSE_PAUSE);
01889 #else
01890 cout << "ERROR : Debug mode PAUSE_PAUSE no longer available\n";
01891 #endif
01892 }
01893 }
01894
01895 if(checkDebugOption(DEBUG_SCAN_ROD_MODE_BITS)) {
01896 cout << "Setting up to use ROD mode bits\n";
01897 #ifdef DR_USE_ROD_MASK_LUT
01898 scanEx->diagnosticReg |= (1<<DR_USE_ROD_MASK_LUT);
01899 #else
01900 cout << "ERROR : Cannot set up to use ROD mode bits - USE_ROD_MASK_LUT no longer available!\n";
01901 #endif
01902 }
01903
01904 if(scanEx->diagnosticReg != 0x0) {
01905 cout << "Writing master diag reg: 0x" << hex << scanEx->diagnosticReg << dec << endl;
01906 api.dspSingleWrite(rod.rod, 0x80000010, scanEx->diagnosticReg, -1);
01907 } else {
01908 cout << "Clearing master diag reg\n";
01909 api.dspSingleWrite(rod.rod, 0x80000010, scanEx->diagnosticReg, -1);
01910 }
01911
01912 if(!useCCode(api, *scan)) {
01913
01914 unsigned long SDSP_IDRAM_BASE;
01915 if(api.getRodRevision(rod) >= 0xe) {
01916 SDSP_IDRAM_BASE = 0x10000;
01917 } else {
01918 SDSP_IDRAM_BASE = 0x80000000;
01919 }
01920
01921 for(int s=0; s<numSlaves; s++) {
01922 if(ri->second.bitFieldDSP & (1<<s)) {
01923 try {
01924 unsigned long val = api.dspSingleBlockRead(rod.rod,
01925 SDSP_IDRAM_BASE + 0x10, s);
01926 cout << "Read from slave " << s << " diag register: 0x" << hex << val
01927 << " which should be 0x" << (0) << dec << endl;
01928
01929
01930 unsigned long newVal = val | (1<<19);
01931 api.dspSingleBlockWrite(rod.rod, SDSP_IDRAM_BASE + 0x10, newVal, s);
01932
01933 val = api.dspSingleBlockRead(rod.rod, SDSP_IDRAM_BASE + 0x10, s);
01934 cout << "Read from slave " << s << " diag register: 0x" << hex << val
01935 << " which should be 0x" << (1<<19) << dec << endl;
01936 } catch(VmeException &v) {
01937 Utility::decodeVme(v);
01938 cerr << "VmeException turning on slave " << s << " cache\n";
01939 }
01940 }
01941 }
01942 }
01943
01944 cout << "Histogram starting...\n";
01945
01946 boost::shared_ptr<PrimListWrapper> primList(new PrimListWrapper(1));
01947 api.startHistogramTask(*scan, *scanEx, rod,
01948 sectionStartBin, 1 + sectionEndBin - sectionStartBin, sectionEndTrigger,
01949 primList);
01950
01951
01952
01953
01954
01955 api.sendPrimList(rod.rod, primList);
01956
01957 }
01958
01959 for(ScanEx::RodInfoMap::const_iterator ri = scanEx->rodInfo.begin();
01960 ri != scanEx->rodInfo.end();
01961 ri++) {
01962 const RodLabel &rod = ri->first;
01963 int responseCode = api.awaitResponse(rod.rod, 5);
01964 if(responseCode != 0) {
01965 cout << "Histogram primitive failed! (ROD " << rod.rod << ")\n";
01966 throw SctApiException("Histogram primitive failed! (ROD " + boost::lexical_cast<string>(rod.rod) + ")");
01967 }
01968 }
01969 }
01970
01971 void SctApi::eventTrapSetup(int slaveMask, int trapMatch, int trapMod, int trapRemain, bool tim, bool error,
01972 boost::shared_ptr<PrimListWrapper> primList) {
01973 long *evData = new long[sizeof(EVENT_TRAP_SETUP_IN)/sizeof(UINT32)];
01974
01975 EVENT_TRAP_SETUP_IN &primData = *(EVENT_TRAP_SETUP_IN*)evData;
01976
01977 #if R_EVENT_TRAP_SETUP == 103
01978 primData.slvBits = slaveMask;
01979 primData.numberOfEvents = COLLECT_FOREVER;
01980 primData.timeoutInUsec = 0x30000;
01981
01982 primData.extRouterSetup = 0;
01983
01984
01985
01986 primData.distribute = TRAP_DISTRIB_NEITHER;
01987
01988 primData.releaseFrames = 0;
01989 if(tim) {
01990 primData.permitBackPressure = 0;
01991 } else {
01992 primData.permitBackPressure = 1;
01993 }
01994 primData.dataMode = 0;
01995 if(tim) {
01996 primData.sLink = 1;
01997 } else {
01998 primData.sLink = 0;
01999 }
02000
02001 primData.format = error?TRAP_FMT_ERROR:TRAP_FMT_NORMAL;
02002 primData.trapStray = 1;
02003 primData.iterLimit = 2;
02004
02005 if(tim) {
02006
02007 primData.trapConfig[0] = TRAP_CFG_SLINK_EVT;
02008 } else {
02009
02010 primData.trapConfig[0] = TRAP_CFG_ROD_EVT;
02011 }
02012 primData.trapExclusionFlag[0] = 0;
02013 primData.trapFunction[0] = TRAP_FXN_HISTOGRAM;
02014
02015 primData.trapMatch[0] = trapMatch;
02016 primData.trapModulus[0] = trapMod;
02017 primData.trapRemainder[0] = trapRemain;
02018
02019
02020 primData.trapConfig[1] = TRAP_CFG_IDLE;
02021 primData.trapExclusionFlag[1] = 0;
02022 primData.trapFunction[1] = 0;
02023
02024 primData.trapMatch[1] = 0;
02025 primData.trapModulus[1] = 0;
02026 primData.trapRemainder[1] = 0;
02027 #else
02028 #error "Event trapping not compiled (new Primitive definition)!"
02029 #endif
02030 primList->addPrimitive(RodPrimitive(sizeof(EVENT_TRAP_SETUP_IN)/sizeof(UINT32) + 4,
02031 0, EVENT_TRAP_SETUP, R_EVENT_TRAP_SETUP, evData),
02032 evData);
02033 }
02034
02035 void SctApi::startEventTrap(int slaveNumber, boost::shared_ptr<PrimListWrapper> primList) {
02036 shared_ptr<PrimListWrapper> startList(new PrimListWrapper(1));
02037
02038 PrimBuilder::instance().startEvTrap(startList);
02039
02040 PrimBuilder::instance().slavePrimList(primList, startList, slaveNumber, true, true);
02041 }
02042
02043 void SctApi::stopEventTrap(int slaveNumber, boost::shared_ptr<PrimListWrapper> primList) {
02044 shared_ptr<PrimListWrapper> stopList(new PrimListWrapper(1));
02045
02046 PrimBuilder::instance().stopEvTrap(stopList);
02047
02048 PrimBuilder::instance().slavePrimList(primList, stopList, slaveNumber, true, true);
02049 }
02050
02051 ScanMonitorImpl::ScanMonitorImpl(boost::shared_ptr<ScanControl> control) : controller(control) {
02052 }
02053
02054 ScanMonitorImpl::~ScanMonitorImpl() {
02055 }
02056
02057 void ScanMonitorImpl::newBin(int prevTriggers, int newBin) {
02058 controller->nextBin();
02059 }
02060
02061 void ScanMonitorImpl::finishScan() {
02062 controller->finishHistogram(true);
02063 }
02064
02065
02066 unsigned long *ScanControlRODHisto::getHistogramChunk(RodLabel rodLabel, int slaveNumber,
02067 unsigned long offset, unsigned long size) {
02068 try {
02069 pair<RodLabel, int> key = make_pair(rodLabel, slaveNumber);
02070
02071 Utility::MemoryBlock chunk;
02072 chunk = scanEx->histoMap[key];
02073 if(!chunk) {
02074 pair<UINT32, UINT32> chunkPos = api.sendData(rodLabel.rod, HISTOGRAM_DATA, slaveNumber);
02075
02076 cout << "SendData returned " << chunkPos.first << " " << chunkPos.second << endl;
02077 cout << " need offset " << offset << " length " << size << endl;
02078
02079 if(api.mrs) {
02080
02081 *api.mrs << "SCAN_READOUT" << MRS_DIAGNOSTIC
02082 << MRS_PARAM<float>("MWords", chunkPos.second/4e6)
02083 << MRS_PARAM<int>("crate", rodLabel.crate)
02084 << MRS_PARAM<int>("rod", rodLabel.rod)
02085 << MRS_TEXT("Scan requested histogram readout") << ENDM;
02086 }
02087
02088 unsigned long *block = api.primReadSlaveDsp(rodLabel.rod,
02089 slaveNumber, chunkPos.first, chunkPos.second/sizeof(UINT32));
02090
02091 if(block == 0) {
02092 throw SctApiException("Read of histogram from slave failed");
02093 }
02094
02095 chunk = Utility::MemoryBlock(chunkPos.second/sizeof(UINT32), block);
02096
02097 scanEx->histoMap[key] = chunk;
02098 }
02099
02100 if((offset + size*4) > (chunk.size() * 4)) {
02101 cout << "Asked for chunk +" << offset << " length " << size << " in " << chunk.size() << "words (continuing)\n";
02102 }
02103
02104
02105 return chunk.address() + (offset / 4);
02106 } catch(SctApiException &e) {
02107 cout << "Caught exception in getHistogramChunk: " << e.what() << "\n\ttrying old histogram address\n";
02108 unsigned long slaveAddress;
02109
02110 if(api.getRodRevision(rodLabel) >= 0xe) {
02111 slaveAddress = 0xa00e2000;
02112 } else {
02113 throw SctApiException("Slave histogram read not possible with old (pre-rev-E) rod");
02114 }
02115 return api.primReadSlaveDsp(rodLabel.rod,
02116 slaveNumber, slaveAddress + offset, size);
02117 }
02118 }
02119
02120 unsigned long *ScanControlRODHisto::getEventCountChunk(RodLabel rodLabel, int slaveNumber) {
02121 try {
02122 pair<RodLabel, int> key = make_pair(rodLabel, slaveNumber);
02123
02124 Utility::MemoryBlock chunk = scanEx->evCountMap[key];
02125 if(!chunk) {
02126 pair<UINT32, UINT32> chunkPos = api.sendData(rodLabel.rod, BIN_DATA, slaveNumber);
02127
02128 cout << "SendData bin returned " << chunkPos.first << " " << chunkPos.second << endl;
02129
02130 unsigned long *block = api.primReadSlaveDsp(rodLabel.rod,
02131 slaveNumber, chunkPos.first, chunkPos.second);
02132 chunk = Utility::MemoryBlock(chunkPos.second, block);
02133
02134 scanEx->evCountMap[key] = chunk;
02135 }
02136
02137 return chunk.address();
02138 } catch(SctApiException &e) {
02139 return 0;
02140 }
02141 }
02142
02143
02144 ScanControlRODHisto::ScanControlRODHisto(SctApi &api, boost::shared_ptr<Scan> aScan, boost::shared_ptr<ScanEx> aScanEx) : ScanControl(api), scan(aScan), scanEx(aScanEx), aborting(false) {
02145 int nBins = scan->getScanPoints1().size();
02146
02147 Scan::TrigPoints trigPoints = scan->getVariableTrigs();
02148
02149 finalTrigger = trigPoints[nBins-1];
02150
02151 finalBin = nBins - 1;
02152
02153 UINT32 initialNTrigs = trigPoints[0];
02154
02155 unsigned int i = 0;
02156 while(i<trigPoints.size() && trigPoints[i] >= initialNTrigs)
02157 i++;
02158
02159
02160 sectionStartBin = 0;
02161 sectionEndBin = i - 1;
02162 if(i==trigPoints.size()) {
02163 sectionEndTrigger = trigPoints[i-1];
02164 } else {
02165 sectionEndTrigger = trigPoints[i-1] - trigPoints[i];
02166 }
02167 cout << "Final bin = " << finalBin << " trigger = " << finalTrigger << endl;
02168
02169 cout << "Initial sectionEndBin = " << sectionEndBin << " sectionEndTrigger = " << sectionEndTrigger << endl;
02170
02171
02172 for(ScanEx::RodInfoMap::const_iterator ri = scanEx->rodInfo.begin();
02173 ri != scanEx->rodInfo.end();
02174 ri++) {
02175 const RodLabel &rodLabel = ri->first;
02176 reportedFinished[rodLabel]=false;
02177 }
02178 }
02179
02180 void ScanControlRODHisto::initialisePolling() {
02181 scanStart = time(0);
02182
02183 cout << "Histogram polling started\n";
02184
02185 sleep(1);
02186
02187 cout << "Polling histogramming task\n";
02188 cout << "scan point count " << scan->getScanPoints1().size() << endl;
02189
02190 for(ScanEx::RodInfoMap::const_iterator ri = scanEx->rodInfo.begin();
02191 ri != scanEx->rodInfo.end();
02192 ri++) {
02193 const RodLabel &rodLabel = ri->first;
02194
02195 if(api.mrs) {
02196 const std::string m1 = (Sct::StringStreamer << "POLL_ROD_" << api.ucid()); const std::string m2 = (Sct::StringStreamer << "ROD polling started on " << api.ucid());
02197
02198 *api.mrs << m1 << MRS_DIAGNOSTIC << MRS_QUALIF("SCTAPI")
02199 << MRS_PARAM<int>("partition", rodLabel.partition)
02200 << MRS_PARAM<int>("crate", rodLabel.crate)
02201 << MRS_PARAM<int>("rod", rodLabel.rod)
02202 << MRS_PARAM<int>("run", scan->getRunNumber())
02203 << MRS_PARAM<int>("scan", scan->getScanNumber())
02204 << MRS_PARAM<int>("firstSlave", ri->second.firstSlave)
02205 << MRS_TEXT(m2)
02206 << ENDM;
02207 }
02208 }
02209
02210 #if USE_IS
02211 if(api.m_isDict) {
02212 ISInfoInt binNumber(0);
02213 api.m_isDict->insert("SCTAPIServer.currentBin", binNumber);
02214
02215 ISInfoInt maxNumber(finalBin);
02216 api.m_isDict->insert("SCTAPIServer.maxBin", maxNumber);
02217 }
02218 #endif
02219 }
02220
02221 void ScanControlRODHisto::reportTimeout() {
02222 Sct::MultiMessageDebugStream m(true,false,true);
02223
02224 m << "You are about to get the 'Scan aborted (histogramming stalled)' "
02225 <<"message. Histogram polling timeout being reported in ["
02226 <<__FILE__<<"] at line ["<<__LINE__<<"]. This means that SctApi got bored waiting more than about 5 (search for the second argument of pollHistogramming in SctApiHisto.cxx) seconds for the event counter to be incremented in the rod. ";
02227
02228 RodLabel minROD;
02229 if(scanEx->rodInfo.size() > 0) {
02230 minROD = scanEx->rodInfo.begin()->first;
02231 }
02232
02233 m << "Was expecting: finalBin=" << finalBin << ", finalTrigger=" << finalTrigger;
02234
02235
02236 for(ScanEx::RodInfoMap::const_iterator ri = scanEx->rodInfo.begin();
02237 ri != scanEx->rodInfo.end();
02238 ri++) {
02239 const RodLabel &rodLabel = ri->first;
02240 cout << " ROD (" << rodLabel.partition << ", " << rodLabel.crate << ", " << rodLabel.rod << "): ";
02241 cout << " Event " << lastEvent[rodLabel] << " Bin " << lastBin[rodLabel] << "\n";
02242
02243 if(lastEvent[rodLabel] < lastEvent[minROD]) {
02244 minROD = rodLabel;
02245 } else if(lastEvent[rodLabel] == lastEvent[minROD] && lastBin[rodLabel] < lastBin[minROD]) {
02246 minROD = rodLabel;
02247 }
02248 }
02249
02250
02251 m << ". Problem was perhaps localised to"
02252 << " partition " << minROD.partition
02253 << " crate" << minROD.crate
02254 << " rod" << minROD.rod
02255 << " run" << scan->getRunNumber()
02256 << " scan"<< scan->getScanNumber()
02257 << " bin"<< lastBin[minROD]
02258 << " event"<< lastEvent[minROD];
02259
02260 m.flush();
02261
02262 if(api.mrs) {
02263 *api.mrs << "SCAN_ABORTED" << MRS_ERROR
02264 << MRS_PARAM<int>("partition", minROD.partition)
02265 << MRS_PARAM<int>("crate", minROD.crate)
02266 << MRS_PARAM<int>("rod", minROD.rod)
02267 << MRS_PARAM<int>("run", scan->getRunNumber())
02268 << MRS_PARAM<int>("scan", scan->getScanNumber())
02269 << MRS_PARAM<int>("bin", lastBin[minROD]) << MRS_PARAM<int>("event", lastEvent[minROD])
02270 << MRS_TEXT("Scan aborted (histogramming stalled)") << ENDM;
02271 }
02272 }
02273
02274 void ScanControlRODHisto::nextBin() {
02275
02276 if(findNextSection()) {
02277 finalTrigger = sectionEndTrigger;
02278 finalBin = sectionEndBin;
02279 return;
02280 }
02281
02282 for(ScanEx::RodInfoMap::const_iterator ri = scanEx->rodInfo.begin();
02283 ri != scanEx->rodInfo.end();
02284 ri++) {
02285 const RodLabel &rod = ri->first;
02286
02287 cout << "New histogram control task...\n";
02288
02289 boost::shared_ptr<PrimListWrapper> primList(new PrimListWrapper(1));
02290 api.startHistogramTask(*scan, *scanEx, rod,
02291 sectionStartBin, 1 + sectionEndBin - sectionStartBin, sectionEndTrigger,
02292 primList);
02293
02294 api.sendPrimList(rod.rod, primList);
02295 int responseCode = api.awaitResponse(rod.rod, 5);
02296
02297 if(responseCode != 0) {
02298 cout << "Histogram primitive failed! (ROD " << rod.rod << ")\n";
02299 throw SctApiException("Histogram primitive failed! (ROD " + boost::lexical_cast<string>(rod.rod) + ")");
02300 }
02301 }
02302 }
02303
02304 bool ScanControlRODHisto::findNextSection() {
02305
02306 Scan::TrigPoints trigPoints = scan->getVariableTrigs();
02307
02308 unsigned int i = sectionEndBin + 1;
02309
02310 if(i==trigPoints.size()) {
02311
02312
02313 return true;
02314 }
02315
02316 UINT32 initialNTrigs = trigPoints[i];
02317
02318 while(i<trigPoints.size() && trigPoints[i] >= initialNTrigs)
02319 i ++;
02320
02321 bool done = false;
02322
02323 sectionStartBin = 0;
02324 sectionEndBin = i - 1;
02325
02326 if(i == trigPoints.size()) {
02327 sectionEndTrigger = trigPoints[i-1];
02328 } else {
02329 sectionEndTrigger = trigPoints[i-1] - trigPoints[i];
02330
02331
02332
02333
02334 }
02335
02336 #if 0
02337
02338 unsigned int i = sectionEndBin + 1;
02339 UINT32 initialNTrigs = trigPoints[i];
02340 while(i<trigPoints.size() && trigPoints[i] == initialNTrigs)
02341 i++;
02342
02343 sectionStartBin = sectionEndBin + 1;
02344 sectionEndBin = i - 1;
02345 sectionEndTrigger = scan->getVariableTrigs()[i-1];
02346
02347 done = false;
02348 #endif
02349
02350 cout << "Next sectionStartBin = " << sectionStartBin << " sectionEndBin = " << sectionEndBin << " sectionEndTrigger = " << sectionEndTrigger << endl;
02351
02352 return done;
02353 }
02354
02355 bool ScanControlRODHisto::checkScanComplete(bool &progressMade, bool &newBin) {
02356 if(aborting) {
02357 return true;
02358 }
02359
02360 progressMade = false;
02361 newBin = false;
02362
02363 bool result = true;
02364
02365 int totalBin = 0;
02366
02367 map<RodLabel, bool> rodNewBinMap;
02368
02369 for(ScanEx::RodInfoMap::const_iterator ri = scanEx->rodInfo.begin();
02370 ri != scanEx->rodInfo.end();
02371 ri++) {
02372 const RodLabel &rodLabel = ri->first;
02373
02374 bool rodNewBin = false;
02375
02376 if(!checkScanCompleteROD(rodLabel, progressMade, rodNewBin, totalBin)) {
02377 result = false;
02378 }
02379
02380 rodNewBinMap[rodLabel] = rodNewBin;
02381 }
02382
02383
02384 newBin = true;
02385 for(map<RodLabel, bool>::const_iterator mapIter = rodNewBinMap.begin();
02386 mapIter != rodNewBinMap.end();
02387 mapIter++) {
02388 if(mapIter->second == false) {
02389 newBin = false;
02390 } else {
02391 cout << "New bin requested by ROD (" << mapIter->first.partition << ", " << mapIter->first.crate << ", " << mapIter->first.rod << ")\n";
02392 }
02393 }
02394
02395 if(progressMade) {
02396 int progressBin = totalBin / scanEx->rodInfo.size();
02397
02398 #if USE_IS
02399 if(api.m_isDict) {
02400 ISInfoInt binNumber(progressBin);
02401 api.m_isDict->update("SCTAPIServer.currentBin", binNumber);
02402 }
02403 #endif
02404 }
02405
02406 return result;
02407 }
02408
02409 void ScanControlRODHisto::abort() {
02410 aborting = true;
02411 }
02412
02413 #warning "32 bit version unreliable!!"
02414 unsigned int ScanControlRODHisto::getEventCounter(const RodLabel &rodLabel, int slave, bool fromMaster) {
02415 if(fromMaster) {
02416
02417 #if defined(HSSTAT_REG_0)
02418 unsigned long address=0;
02419 switch (slave){
02420 case 0: address=HSSTAT_REG_0; break;
02421 case 1: address=HSSTAT_REG_1; break;
02422 case 2: address=HSSTAT_REG_2; break;
02423 case 3: address=HSSTAT_REG_3; break;
02424 default: cerr << "get event counter for bad slave number : " << slave << std::endl; return 0;
02425 }
02426 unsigned long reg = api.dspSingleRead(rodLabel.rod, address, -1);
02427
02428
02429
02430 unsigned currEvent = (unsigned) (reg & 0xffff);
02431 #else
02432 #warning "AJB Hard-coded memory address for checking SDSP event count"
02433
02434
02435
02436 unsigned long reg = api.dspSingleRead(rodLabel.rod,
02437 0x8000002c - (slave & 2) * 2, -1);
02438 unsigned int currEvent = (unsigned int) ((reg >> (16*(slave&1))) & 0xffff);
02439 #endif
02440 return currEvent;
02441 } else {
02442
02443 unsigned long reg = api.dspSingleRead(rodLabel.rod,
02444 0x8000002c, slave);
02445 return (unsigned int) reg;
02446 }
02447 }
02448
02449 bool ScanControlRODHisto::checkScanCompleteROD(const RodLabel &rodLabel, bool &progressMade, bool &newBin, int &totalBin) {
02450 int partition = rodLabel.partition;
02451 int crate = rodLabel.crate;
02452 int rod = rodLabel.rod;
02453
02454 int currBin = 0;
02455 int currEvent = 0;
02456
02457
02458 #warning "AJB does not like the look of this hard-coded memory address for the bin number - not one little bit!"
02459
02460 long reg = api.dspSingleRead(rod, 0x80000020, -1);
02461 currBin = (reg & 0xff);
02462
02463 RodScanEx &rodInfo = scanEx->rodInfo[rodLabel];
02464
02465
02466 currEvent = getEventCounter(rodLabel, rodInfo.firstSlave, true);
02467
02468 if(currBin != lastBin[rodLabel]) {
02469 lastBin[rodLabel] = currBin;
02470 lastEvent[rodLabel] = currEvent;
02471 cout << "Next bin " << currBin << "+" << currEvent << " on ROD (" << partition << ", " << crate << ", " << rod << ")\n";
02472
02473 progressMade = true;
02474 } else if(currEvent != lastEvent[rodLabel]) {
02475 lastEvent[rodLabel] = currEvent;
02476 cout << "Next event " << currEvent << " (bin " << currBin << ") on ROD (" << partition << ", " << crate << ", " << rod << ")\n";
02477
02478 progressMade = true;
02479 }
02480
02481 totalBin += currBin;
02482
02483
02484 if(currBin == sectionEndBin && currEvent == sectionEndTrigger) {
02485
02486 newBin = true;
02487
02488
02489 for(int s=0; s<4; s++) {
02490 if(rodInfo.bitFieldDSP & (1<<s)) {
02491 int slaveEvent = getEventCounter(rodLabel, s, true);
02492
02493 if(slaveEvent != sectionEndTrigger) {
02494 cout << " Slave " << s << " completed only " << slaveEvent << "/" << sectionEndTrigger << " triggers\n";
02495 newBin = false;
02496 }
02497 }
02498 }
02499 } else if(currBin == sectionEndBin && currEvent == (sectionEndTrigger%65536)) {
02500
02501
02502
02503 if(!progressMade) {
02504
02505 newBin = true;
02506
02507
02508 for(int s=0; s<4; s++) {
02509 if(rodInfo.bitFieldDSP & (1<<s)) {
02510 int slaveEvent = getEventCounter(rodLabel, s, true);
02511
02512 if(slaveEvent != (sectionEndTrigger % 65536)) {
02513 cout << " Slave " << s << " completed only " << slaveEvent << "/" << sectionEndTrigger << " triggers\n";
02514 newBin = false;
02515 }
02516 }
02517 }
02518 }
02519 }
02520
02521
02522 if(((currBin == finalBin) && (currEvent == finalTrigger))
02523 || ((currBin == finalBin) && (currEvent == (finalTrigger%65536)) && !progressMade)) {
02524
02525
02526 lastEvent[rodLabel] = finalTrigger;
02527
02528 if(api.mrs && !reportedFinished[rodLabel]) {
02529 reportedFinished[rodLabel]=true;
02530 *api.mrs << "HISTO_SUCCESS" << MRS_DIAGNOSTIC << MRS_QUALIF("SCTAPI")
02531 << MRS_PARAM<int>("partition", rodLabel.partition)
02532 << MRS_PARAM<int>("crate", rodLabel.crate)
02533 << MRS_PARAM<int>("rod", rodLabel.rod)
02534 << MRS_TEXT("Histogramming successfully complete")
02535 << ENDM;
02536 }
02537
02538 cout << "Histogramming completed successfully on rod " << rod << "\n";
02539
02540 return true;
02541 }
02542
02543 return false;
02544 }
02545
02546 void ScanControlTIMHisto::finishHistogram(bool success) {
02547 printVetoStatus();
02548 this->ScanControlRODHisto::finishHistogram(success);
02549 }
02550
02551 void ScanControlAsyncHisto::finishHistogram(bool success) {
02552 printVetoStatus();
02553 this->ScanControlRODHisto::finishHistogram(success);
02554 }
02555
02556 void ScanControl::printVetoStatus(){
02557
02558 long long loCount = api.timReadRegister(0x74);
02559 long long hiCount = api.timReadRegister(0x76);
02560 long long extCount = api.timReadRegister(0x78);
02561 long long count = loCount + (hiCount << 16) + ((extCount << 16) << 16);
02562
02563
02564 long loVeto = api.timReadRegister(0x7c);
02565 long hiVeto = api.timReadRegister(0x7e);
02566 long veto = loVeto + (hiVeto << 16);
02567
02568
02569 long loVetos = api.timReadRegister(0x84);
02570 long hiVetos = api.timReadRegister(0x86);
02571 long vetos = loVetos + (hiVetos << 16);
02572
02573 std::ostringstream vetostatus;
02574 vetostatus << "TIM FFTV Software disable:" << (bool)(api.timReadRegister(0x9c) & 0x100);
02575 vetostatus << "; Hardware disable:" << (bool)(api.timReadRegister(0x5a) & 0x8000);
02576 vetostatus << "; Veto on:" << (bool)(api.timReadRegister(0x5a) & 0x4000) << std::endl;
02577
02578 std::ostringstream oss;
02579 oss << std::hex << count << std::dec;
02580
02581 std::cout << vetostatus.str();
02582 printf("TIM FFTV: Clocks spent vetoed %lld Vetoed triggers %ld Veto applications %ld\n", count, veto, vetos);
02583
02584 if (api.mrs) {
02585 *api.mrs << MRS_INFORMATION << MRS_QUALIF("SCTAPI") << "TIM_FFTV_STATUS"
02586 << MRS_TEXT("TIM module fixed-frequency veto status")
02587 << MRS_PARAM<const char*>("Number of clocks with veto applied",oss.str().c_str())
02588 << MRS_PARAM<long>("Number of triggers vetoed",veto)
02589 << MRS_PARAM<long>("Number of times veto applied",vetos)
02590 << MRS_PARAM<const char*>("Status",vetostatus.str().c_str())
02591 << ENDM;
02592 }
02593 }
02594
02595 void ScanControlRODHisto::finishHistogram(bool success) {
02596 time_t scanEnd = time(0);
02597
02598 #if USE_CONST_SCAN
02599 scanEx->setEndTime(second_clock::universal_time());
02600 #else
02601 scan->setEndTime(second_clock::universal_time());
02602 #endif
02603
02604 std::cout << api.ucid() << " finished histogramming at TIME " << second_clock::universal_time() << std::endl;
02605
02606 if(!useCCode(api, *scan)) {
02607 for(ScanEx::RodInfoMap::const_iterator ri = scanEx->rodInfo.begin();
02608 ri != scanEx->rodInfo.end();
02609 ri++) {
02610 const RodLabel &rod = ri->first;
02611 const RodScanEx &rodInfo = ri->second;
02612
02613 unsigned long SDSP_IDRAM_BASE;
02614 if(api.getRodRevision(rod) >= 0xe) {
02615 SDSP_IDRAM_BASE = 0x10000;
02616 } else {
02617 SDSP_IDRAM_BASE = 0x80000000;
02618 }
02619
02620 for(int s=0; s<numSlaves; s++) {
02621 if(rodInfo.bitFieldDSP & (1<<s)) {
02622 try {
02623 #warning "Hard coded reads of diagnostic register"
02624 unsigned long val = api.dspSingleBlockRead(rod.rod,
02625 SDSP_IDRAM_BASE + 0x10, s);
02626 cout << "Read from slave " << s << " diag register: 0x" << hex << val
02627 << " which should be 0x" << (1<<19) << dec << endl;
02628
02629
02630 unsigned long newVal = val | 1<<17;
02631 api.dspSingleBlockWrite(rod.rod, SDSP_IDRAM_BASE + 0x10, newVal, s);
02632 val = api.dspSingleBlockRead(rod.rod, SDSP_IDRAM_BASE + 0x10, s);
02633 cout << "Read from slave " << s << " diag register: 0x" << hex << val
02634 << " which should be 0x" << (1<<17) << dec << endl;
02635
02636
02637 newVal = val | 1<<19;
02638 api.dspSingleBlockWrite(rod.rod, SDSP_IDRAM_BASE + 0x10, newVal, s);
02639 val = api.dspSingleBlockRead(rod.rod, SDSP_IDRAM_BASE + 0x10, s);
02640 cout << "Read from slave " << s << " diag register: 0x" << hex << val
02641 << " which should be 0x" << (0) << dec << endl;
02642 } catch(VmeException &v) {
02643 Utility::decodeVme(v);
02644 cerr << "VmeException turning off slave " << s << " cache\n";
02645 }
02646 }
02647 }
02648 }
02649 }
02650
02651 #if USE_CONST_SCAN
02652 setModuleScanCacheToLastPointInScan(api, scan, scanEx);
02653 #else
02654 setModuleScanCacheToLastPointInScan(api, scan);
02655 #endif
02656
02657 std::cout << api.ucid() << " Done setModuleScanCacheToLastPointInScan at TIME " << second_clock::universal_time() << std::endl;
02658
02659
02660
02661 if(!scan->getOption(Scan::DEBUG) || success == true) {
02662 if(api.mrs) {
02663 *api.mrs << "SCAN_FINISHED" << MRS_INFORMATION
02664 << MRS_QUALIF("SCTAPI") << MRS_QUALIF("doScan")
02665 << MRS_TEXT("Scan finished")
02666 << MRS_PARAM<int>("ScanNumber", scan->getScanNumber())
02667 << MRS_PARAM<int>("ScanType1", scan->getScanVariable1())
02668 << MRS_PARAM<int>("ScanType2", scan->getScanVariable2())
02669 << MRS_PARAM<int>("ScanTime", scanEnd - scanStart)
02670 << ENDM;
02671 }
02672
02673 cout << api.ucid() << " Histogramming complete, " << (scanEnd - scanStart) << " seconds, tidying up...\n";
02674
02675
02676
02677
02678
02679 cout << api.ucid() << " Starting to read histograms at TIME " << second_clock::universal_time() << std::endl;
02680
02681 readHistograms();
02682
02683 cout << api.ucid() << " Histograms read finished at TIME " << second_clock::universal_time() << std::endl;
02684 } else {
02685 if(!scan->getOption(Scan::DEBUG)) {
02686 cout << "Histogram polling failed\n";
02687
02688 if(api.mrs) {
02689 *api.mrs << "SCAN_FAILED" << MRS_INFORMATION
02690 << MRS_QUALIF("SCTAPI") << MRS_QUALIF("doScan")
02691 << MRS_TEXT("Scan polling failed")
02692 << MRS_PARAM<int>("ScanNumber", scan->getScanNumber())
02693 << MRS_PARAM<int>("ScanTime", scanEnd - scanStart)
02694 << ENDM;
02695 }
02696 }
02697 }
02698
02699 if(checkDebugOption(DEBUG_PRINT_CALIB)) {
02700 RodLabel zeroRod = scanEx->rodInfo.begin()->first;
02701
02702 api.print_calib(zeroRod.rod);
02703 }
02704
02705 if(!scan->getOption(Scan::DEBUG)) {
02706 api.stopHistogramming(*scanEx);
02707
02708
02709 postScanModuleSetup();
02710 } else {
02711 if(api.mrs) {
02712 *api.mrs << "SCAN_DEBUG" << MRS_INFORMATION
02713 << MRS_QUALIF("SCTAPI") << MRS_QUALIF("doScan")
02714 << MRS_TEXT("Scan done in debug mode, probably best to be at the command line to sort it out!")
02715 << ENDM;
02716 }
02717
02718 cout << "** In debug mode, you're responsible for terminating histogram and for readout\n";
02719 }
02720
02721 if(checkDebugOption(DEBUG_PRINT_CALIB)) {
02722 RodLabel zeroRod = scanEx->rodInfo.begin()->first;
02723
02724 api.print_calib(zeroRod.rod);
02725 }
02726
02727
02728 std::cout << scan->print();
02729
02730 #if USE_IS
02731 if(api.m_isDict)
02732 api.m_isDict->remove(api.idiosyncrasy().infoServiceNameOfScanStatusObject());
02733 #endif
02734
02735 if(api.mrs)
02736 *api.mrs << "SCAN_COMPLETE" << MRS_INFORMATION << MRS_QUALIF("SctApi") << MRS_TEXT("Scan has completed") << ENDM;
02737 }
02738
02739 void ScanControlRODHisto::postScanModuleSetup() {
02740 api.setErrorMasks();
02741 }
02742
02743 bool ScanControlRODHisto::checkDebugOption(int opt) {
02744 return Debug::getInstance()->checkDebugOption((DebugOptions)opt);
02745 }
02746
02747 void ScanControlRODHisto::reportEventErrors() {
02748 api.reportEventErrors();
02749 }
02750
02751 unsigned int ScanControlRODHisto::getProcTime(const RodLabel rlabel, int dsp) {
02752 if(dsp == -1) {
02753 throw SctApiException("Can't getProcTime on MDSP");
02754 } else {
02755 int procTime;
02756
02757 unsigned long SDSP_IDRAM_BASE;
02758 if(api.getRodRevision(rlabel) >= 0xe) {
02759 SDSP_IDRAM_BASE = 0x10000;
02760 } else {
02761 SDSP_IDRAM_BASE = 0x80000000;
02762 }
02763
02764 unsigned long length;
02765
02766 #warning "Hard-coded address, sdsp histogram status block"
02767 unsigned long *regs = api.dspBlockRead(rlabel.rod,
02768 SDSP_IDRAM_BASE + 0x10, 20, dsp, length);
02769
02770 if(regs) {
02771 long reg;
02772
02773
02774 reg = regs[6];
02775 procTime = ((reg >> 16) & 0xffff);
02776 } else {
02777 throw SctApiException("Failed to read getProcTime from DSP");
02778 }
02779
02780 return procTime;
02781 }
02782 }
02783
02784 ScanControlRODHisto::TrapBuffers ScanControlRODHisto::getTrapBuffers(const RodLabel rlabel, int dsp) {
02785 if(dsp == -1) {
02786 throw SctApiException("Invaled dsp passed to getTrapBuffers");
02787 } else {
02788 int ihead, itail, xhead, xtail;
02789
02790 unsigned long SDSP_IDRAM_BASE;
02791 if(api.getRodRevision(rlabel) >= 0xe) {
02792 SDSP_IDRAM_BASE = 0x10000;
02793 } else {
02794 SDSP_IDRAM_BASE = 0x80000000;
02795 }
02796
02797 unsigned long length;
02798 #warning "Hard coded address of sdsp trap block"
02799 unsigned long *regs = api.dspBlockRead(rlabel.rod,
02800 SDSP_IDRAM_BASE + 0x10, 20, dsp, length);
02801
02802 if(regs) {
02803 long reg;
02804
02805
02806 reg = regs[1];
02807 itail = ((reg & 0xff0000) >> 16);
02808 xtail = ((reg & 0xff000000) >> 24);
02809
02810
02811 reg = regs[2];
02812 ihead = ((reg & 0xff0000) >> 16);
02813 xhead = ((reg & 0xff000000) >> 24);
02814 } else {
02815 throw SctApiException("Failed to read DSP for getTrapBuffers");
02816 }
02817
02818 return make_pair(make_pair(ihead, itail), make_pair(xhead, xtail));
02819 }
02820 }
02821
02822 void ScanControlRODHisto::dumpHistoStatus(const RodLabel rlabel, int dsp) {
02823 if(dsp == -1) {
02824 const unsigned long MDSP_IDRAM_BASE = 0x80000000;
02825
02826
02827 #ifndef HCMD_STAT_REG_0
02828 #warning "Reading hard-coded HCMD_STAT_REG_0"
02829 long reg = api.dspSingleRead(0, MDSP_IDRAM_BASE + 0x20, -1);
02830 #else
02831 long reg = api.dspSingleRead(0, HCMD_STAT_REG_0, -1);
02832 #endif
02833 cout << "Bin: " << (reg & 0xff)
02834 << " Cal: " << ((reg & 0xff00) >> 8)
02835 << " Errs: " << ((reg & 0xffff0000) >> 16) << endl;
02836
02837
02838 #ifndef HCMD_STAT_REG_1
02839 #warning "Reading hard-coded HCMD_STAT_REG_1"
02840 reg = api.dspSingleRead(0, MDSP_IDRAM_BASE + 0x24, -1);
02841 #else
02842 reg = api.dspSingleRead(0, HCMD_STAT_REG_1, -1);
02843 #endif
02844 cout << "avg. trans " << (reg & 0xff)
02845 << " avg. len " << ((reg & 0xff00) >> 8)
02846 << " avg. proc. " << ((reg & 0xffff0000) >> 16) << endl;
02847
02848
02849 #ifndef HSSTAT_REG_1
02850 #warning "Reading hard-coded HSSTAT_REG_1"
02851 reg = api.dspSingleRead(0, MDSP_IDRAM_BASE + 0x2c, -1);
02852 #else
02853 reg = api.dspSingleRead(0, HSSTAT_REG_1, -1);
02854 #endif
02855 cout << "Slave 0: " << (reg & 0xffff)
02856 << " Slave 1: " << ((reg & 0xffff0000) >> 16) << endl;
02857
02858
02859 #ifndef HSSTAT_REG_0
02860 #warning "Reading hard-coded HSSTAT_REG_0"
02861 reg = api.dspSingleRead(0, MDSP_IDRAM_BASE + 0x28, -1);
02862 #else
02863 reg = api.dspSingleRead(0, HSSTAT_REG_0, -1);
02864 #endif
02865 cout << "Slave 2: " << (reg & 0xffff)
02866 << " Slave 3: " << ((reg & 0xffff0000) >> 16) << endl;
02867 } else {
02868 unsigned long SDSP_IDRAM_BASE;
02869 if(api.getRodRevision(rlabel) >= 0xe) {
02870 SDSP_IDRAM_BASE = 0x10000;
02871 } else {
02872 SDSP_IDRAM_BASE = 0x80000000;
02873 }
02874
02875 unsigned long length;
02876 #warning "Hard coded block of trap status registers"
02877 unsigned long *regs = api.dspBlockRead(rlabel.rod,
02878 SDSP_IDRAM_BASE + 0x10, 20, dsp, length);
02879
02880 if(regs) {
02881 long reg;
02882
02883 cout << "TrapStatus: \n";
02884
02885
02886
02887 reg = regs[1];
02888 int words = ((reg &0xffff) >> 0);
02889 int itail = ((reg & 0xff0000) >> 16);
02890 int xtail = ((reg & 0xff000000) >> 24);
02891
02892 cout << "Event word count: " << words;
02893 cout << " IFrame tail: " << itail;
02894 cout << " XFrame tail: " << xtail << endl;
02895
02896
02897 reg = regs[2];
02898 int ihead = ((reg & 0xff0000) >> 16);
02899 int xhead = ((reg & 0xff000000) >> 24);
02900 cout << " IFrame head: " << ihead;
02901 cout << " XFrame head: " << xhead << endl;
02902
02903
02904 reg = regs[17];
02905 cout << "Trap Command/Status: "
02906 << ((reg & 0x1)?"Trailer ":"")
02907 << ((reg & 0x2)?"Transmit ":"")
02908 << ((reg & 0x4)?"Header ":"")
02909 << ((reg & 0x4)?"ISR active ":"");
02910 cout << ((reg & 0x10)?"\"Data Error\" ":"")
02911 << ((reg & 0x20)?"\"Header Error\" ":"")
02912 << ((reg & 0x40)?"\"Trailer Error\" ":"")
02913 << ((reg & 0x80)?"\"Link Error\" ":"");
02914 cout << ((reg & 0x100)?"\"Error\" ":"")
02915 << ((reg & 0x200)?"\"Overflow(old)\" ":"")
02916 << ((reg & 0x800)?"\"ISR pending\" ":"");
02917 cout << ((reg & 0x4000)?"\"Overflow error\" ":"")
02918 << ((reg & 0x8000)?"\"Overflow\" ":"");
02919 cout << endl;
02920
02921 int errCount = ((reg >> 16) & 0xff);
02922 cout << "\"Error count\": " << errCount << endl;
02923 int evCount = ((reg >> 24) & 0xff);
02924 cout << "\"Event count\": " << evCount << endl;
02925
02926
02927 reg = regs[4];
02928 int currentBin = (reg & 0xff);
02929 cout << "Bin: " << currentBin
02930 << " Cal: " << ((reg & 0x1f00) >> 8)
02931 << ((reg & 0x800)?" Cal enabled":"")
02932 << ((reg & 0x1000)?" New bin":"")
02933 << ((reg & 0x20000)?" New cal":"") << endl;
02934
02935
02936 reg = regs[5];
02937 int numEvents = reg;
02938 cout << "Num events: " << numEvents << endl;
02939
02940
02941 reg = regs[6];
02942 cout << "Histogram status: 0x" << hex << (reg & 0xffff) << dec << " " << ((reg & 0x1)?"Ready ":"")
02943 << ((reg & 0x2)?"Expecting ":"")
02944 << ((reg & 0x4)?"Processing ":"")
02945 << ((reg & 0x8)?"Done ":"") << endl;
02946
02947 int procTime = ((reg >> 16) & 0xffff);
02948 cout << "Bin err: " << ((reg >> 8) & 0xff)
02949 << " proc time: " << ((reg >> 16) & 0xffff) << endl;
02950
02951
02952 reg = regs[7];
02953 int evRecvd = reg;
02954 cout << "Events recvd: " << evRecvd << endl;
02955
02956 ofstream statusOut("TIMStatus.txt", ios_base::out | ios_base::app);
02957 statusOut << currentBin << "\t"
02958 << ihead << "\t" << itail << "\t"
02959 << xhead << "\t" << xtail << "\t"
02960 << errCount << "\t" << evCount << "\t"
02961 << evRecvd << "\t" << words << "\t" << procTime << endl;
02962 }
02963 }
02964 }
02965
02966 ScanControlTIMHisto::ScanControlTIMHisto(SctApi &api, boost::shared_ptr<Scan> aScan, boost::shared_ptr<ScanEx> aScanEx) : ScanControlRODHisto(api, aScan, aScanEx), binCount(0) {
02967 }
02968
02969 void ScanControlTIMHisto::startHistogramming() {
02970
02971 api.timWriteRegister(0x14, 0x3000);
02972
02973
02974 for (unsigned reg=0x74; reg<=0x86; reg+=2){
02975 api.timWriteRegister(reg,0x0);
02976 }
02977
02978 shared_ptr<PrimListWrapper> preTimList(new PrimListWrapper(4));
02979 PrimBuilder::instance().rodMode(preTimList, DATA_TAKING_MODE, 0, 1, 0, 0, 1);
02980
02981 PrimBuilder::instance().writeRegister(preTimList, RTR_CMND_STAT, 7, 1, 1);
02982
02983 for(int f=0; f<8; f++) {
02984
02985
02986 PrimBuilder::instance().writeRegister(preTimList, DM_DFLT_LUT(f), 0, 16, 0x0);
02987 }
02988
02989
02990
02991
02992
02993
02994 cout << "Sending pre TIM setup list\n";
02995 api.synchSendPrimListAll(preTimList);
02996 cout << " done sending pre TIM setup list\n";
02997
02998 hex(cout);
02999 cout << "0x" << RTR_CMND_STAT << ": 0x" << api.readRODRegister(0, RTR_CMND_STAT) << endl;
03000 cout << "0x" << Utility::EfbErrorMask(0, 0) << ": 0x" << api.readRODRegister(0, Utility::EfbErrorMask(0, 0)) << endl;
03001 cout << "0x" << Utility::EfbErrorMask(1, 0) << ": 0x" << api.readRODRegister(0, Utility::EfbErrorMask(1, 0)) << endl;
03002 cout << "0x" << DM_DFLT_LUT(0) << ": 0x" << api.readRODRegister(0, DM_DFLT_LUT(0)) << endl;
03003 cout << "0x" << DM_DFLT_LUT(1) << ": 0x" << api.readRODRegister(0, DM_DFLT_LUT(1)) << endl;
03004 dec(cout);
03005
03006 if(checkDebugOption(DEBUG_TIM_SCAN_STATUS)) {
03007
03008 ofstream statusOut("TIMStatus.txt");
03009 statusOut << "bin\tihead\titail\txhead\txtail\terrCnt\tevCount\tevRecvd\twords\tprocTime\n";
03010 }
03011 }
03012
03013 void ScanControlTIMHisto::nextBin() {
03014 cout << "TIM histo, next bin\n";
03015
03016 unsigned scanvariable1 = scan->getScanVariable1();
03017 if (scanvariable1!=0){
03018 double value = scan->getScanPoints1()[binCount];
03019
03020 if (ConfigUtility::isModuleRegister(scanvariable1)){
03021 std::list<BankType> banks;
03022 banks.push_back(SCTAPI_BANK_SCAN);
03023 api.modifyABCDVarROD(scanvariable1, value, banks);
03024 } else if (ConfigUtility::isTimRegister(scanvariable1) ) {
03025 api.modifyTIMParam(scanvariable1, (int)(value+0.5));
03026 } else if (ConfigUtility::isBocRegister(scanvariable1) ){
03027 api.modifyBOCParam(scanvariable1, (int)(value+0.5));
03028 } else if (ConfigUtility::variableType(scanvariable1)==ConfigUtility::TRIGGER_VAR) {
03029 ;
03030 } else {
03031 if (api.mrs) {
03032 *api.mrs << "BAD_SCAN_VARIABLE" << MRS_TEXT("Unknown scan variable in TIM scan")
03033 << MRS_PARAM<int>("Variable number",scanvariable1) << MRS_WARNING << ENDM;
03034 } else{
03035 std::cout << "Warning - bad scan variable : " << scanvariable1
03036 << " type " << ConfigUtility::variableType(scanvariable1) << std::endl;
03037 }
03038 }
03039 }
03040
03041
03042
03043 api.sendAllABCDModules(SCTAPI_BANK_SCAN);
03044
03045
03046 shared_ptr<PrimListWrapper> setTriggerList(new PrimListWrapper(4));
03047 PrimBuilder::instance().setTrigger(setTriggerList, binCount, Utility::translateBank(SCTAPI_BANK_SCAN));
03048
03049 shared_ptr<PrimListWrapper> binTimList(new PrimListWrapper(4));
03050
03051
03052 for(int s=0; s<4; s++) {
03053 PrimBuilder::instance().slavePrimList(binTimList, setTriggerList, s, 1, 0);
03054 }
03055
03056 PrimBuilder::instance().rodMode(binTimList, DATA_TAKING_MODE, 0, 1, 0, 0, 1);
03057 PrimBuilder::instance().writeRegister(binTimList, RTR_CMND_STAT, 7, 1, 1);
03058
03059 cout << "Sending TIM setup list\n";
03060 api.synchSendPrimListAll(binTimList);
03061 cout << " done sending TIM setup list\n";
03062
03063 if(checkDebugOption(DEBUG_TIM_SCAN_STATUS)) {
03064 cout << "******************* Pre triggers status ********************\n";
03065 dumpHistoStatus(RodLabel(), 0);
03066 }
03067
03068 cout << "Sending soft/bc resets to crate: " << api.ucid() << endl;
03069 api.timSoftReset();
03070 api.timBCReset();
03071
03072 Scan::TrigPoints trigs = scan->getVariableTrigs();
03073
03074 cout << "Want " << trigs[binCount] << " triggers to crate: " << api.ucid() << endl;
03075
03076 const Trigger& trig1 = *scan->getTrigger1();
03077
03078 if(1) {
03079 switch(scan->getOption(Scan::TIM)) {
03080 case 1:
03081
03082 {
03083 api.sendTriggers(&trig1, trigs[binCount], binCount);
03084 }
03085 break;
03086 case 2:
03087 #warning "Assumes ROD 0!!!"
03088
03089 for(unsigned int i=0; i<trigs[binCount]; i++) {
03090 api.timL1A();
03091
03092 TrapBuffers tb = getTrapBuffers(RodLabel(), 0);
03093
03094 if (!(tb.first.first == tb.first.second && tb.second.first == tb.second.second))
03095 sleep(1);
03096 }
03097 break;
03098 case 3:
03099 #warning "Assumes ROD 0!!!"
03100
03101
03102 {
03103 unsigned int sentTriggers = 0;
03104 const unsigned int trigsPerBurst = 20;
03105
03106 while(sentTriggers < trigs[binCount]) {
03107 if(sentTriggers % 1000 < trigsPerBurst) {
03108 cout << "Done " << sentTriggers << " triggers\n";
03109 if(checkDebugOption(DEBUG_TIM_SCAN_STATUS))
03110 dumpHistoStatus(RodLabel(), 0);
03111 }
03112 int ntrigs = min(trigs[binCount]-sentTriggers, trigsPerBurst);
03113 api.sendTimBurst(ntrigs,false);
03114 sentTriggers += ntrigs;
03115
03116
03117 TrapBuffers tb = getTrapBuffers(RodLabel(), 0);
03118
03119 TrapBuffers oldtb;
03120 if (!(tb.first.first == tb.first.second && tb.second.first == tb.second.second))
03121 do {
03122 oldtb = tb;
03123 usleep(trigsPerBurst * 10);
03124 tb = getTrapBuffers(RodLabel(), 0);
03125
03126 if(tb.first.first == tb.first.second && tb.second.first == tb.second.second) break;
03127 if(tb == oldtb) break;
03128 } while(1);
03129 }
03130 }
03131 break;
03132 case 4:
03133 #warning "Assumes ROD 0!!!"
03134
03135
03136 {
03137 unsigned int sentTriggers = 0;
03138
03139 api.timL1A();
03140 sentTriggers ++;
03141
03142
03143
03144
03145 unsigned int procTime = getProcTime(RodLabel(), 0);
03146 double timFrequency = 0.25 * 1e6/procTime;
03147
03148 api.timSetFrequency(min(6.0, timFrequency/1000), 0);
03149
03150 cout << "*** Proc Time for 1 trigger was " << procTime << " setting frequency to " << timFrequency << "Hz\n";
03151
03152 procTime = getProcTime(RodLabel(), 0);
03153 timFrequency = 0.25 * 1e6/procTime;
03154 api.timSetFrequency(min(6.0, timFrequency/1000), 0);
03155
03156 cout << "*** Proc Time after 10 trigs was " << procTime << " setting frequency to " << timFrequency << "Hz\n";
03157
03158 if(trigs[binCount] > sentTriggers)
03159 api.sendTimBurst(trigs[binCount]-sentTriggers,false);
03160
03161 if(checkDebugOption(DEBUG_TIM_SCAN_STATUS)) {
03162 cout << "******************* Post triggers status ********************\n";
03163 dumpHistoStatus(RodLabel(), 0);
03164 }
03165
03166 TrapBuffers tb = getTrapBuffers(RodLabel(), 0);
03167
03168 TrapBuffers oldtb;
03169 if (!(tb.first.first == tb.first.second && tb.second.first == tb.second.second))
03170 do {
03171 oldtb = tb;
03172 sleep(1);
03173 tb = getTrapBuffers(RodLabel(), 0);
03174
03175 if(tb.first.first == tb.first.second && tb.second.first == tb.second.second) break;
03176 if(tb == oldtb) break;
03177 } while(1);
03178 break;
03179 }
03180 default:
03181 {
03182 std::cout << "ERROR - unknown TIM option : "
03183 << (scan->getOption(Scan::TIM)) << std::endl;
03184 break;
03185 }
03186 }
03187 }
03188 if(checkDebugOption(DEBUG_TIM_SCAN_STATUS)) {
03189 cout << "******************* Post triggers status 2 ******************\n";
03190 dumpHistoStatus(RodLabel(), 0);
03191 }
03192
03193
03194
03195
03196
03197 binCount ++;
03198 }
03199
03200
03201
03202 bool ScanControlTIMHisto::checkScanCompleteROD(const RodLabel &rodLabel, bool &progressMade, bool &newBin, int &totalBin) {
03203
03204 cout << "Checking TIM scan complete\n";
03205
03206 progressMade = true;
03207
03208
03209 newBin = true;
03210
03211 totalBin += binCount-1;
03212
03213
03214
03215 if((binCount-1 >= finalBin)) {
03216 return true;
03217 }
03218
03219 return false;
03220 }
03221
03222
03223
03224
03225
03226 ScanControlAsyncHisto::ScanControlAsyncHisto(SctApi &api, boost::shared_ptr<Scan> aScan, boost::shared_ptr<ScanEx> aScanEx) : ScanControlRODHisto(api, aScan, aScanEx), binCount(0) {
03227 }
03228
03229 void ScanControlAsyncHisto::startHistogramming() {
03230 #warning "Should we check we're in physics mode?"
03231 if(checkDebugOption(DEBUG_TIM_SCAN_STATUS)) {
03232
03233 ofstream statusOut("TIMStatus.txt");
03234 statusOut << "bin\tihead\titail\txhead\txtail\terrCnt\tevCount\tevRecvd\twords\tprocTime\n";
03235 }
03236 }
03237
03238 void ScanControlAsyncHisto::nextBin() {
03239 cout << "Asynchronous histo, next bin\n";
03240
03241 if (scan->getScanVariable1()!=0){
03242 std::list<BankType> banks;
03243 banks.push_back(SCTAPI_BANK_SCAN);
03244
03245 api.modifyABCDVarROD(scan->getScanVariable1(), scan->getScanPoints1()[binCount], banks);
03246 }
03247
03248 if(0) {
03249
03250
03251 api.sendAllABCDModules(SCTAPI_BANK_SCAN);
03252 }
03253
03254
03255 shared_ptr<PrimListWrapper> setTriggerList(new PrimListWrapper(4));
03256 PrimBuilder::instance().setTrigger(setTriggerList, binCount, Utility::translateBank(SCTAPI_BANK_SCAN));
03257
03258 shared_ptr<PrimListWrapper> binTimList(new PrimListWrapper(4));
03259
03260
03261 for(int s=0; s<4; s++) {
03262 PrimBuilder::instance().slavePrimList(binTimList, setTriggerList, s, 1, 0);
03263 }
03264
03265
03266
03267
03268
03269 cout << "Sending async TIM set trigger list\n";
03270 api.synchSendPrimListAll(binTimList);
03271 cout << " done sending async TIM set trigger list\n";
03272
03273 if(checkDebugOption(DEBUG_TIM_SCAN_STATUS)) {
03274 cout << "******************* Next bin triggers status ********************\n";
03275 dumpHistoStatus(RodLabel(), 0);
03276 }
03277
03278
03279
03280
03281
03282 binCount ++;
03283 }
03284
03285 }