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 Scan::TrigPoints trigPoints = scan->getVariableTrigs();
01483 for(int i=0; i<nBins; i++) {
01484
01485 errors[i] = trigPoints[i] - events[i];
01486 }
01487 scanResult.nErrorEvents = errors;
01488
01489 return scanResult;
01490 }
01491
01492 char* ScanControlRODHisto::readHistogramRawData(UINT32 mid, int frame) {
01493 int nBins = scan->getScanPoints1().size();
01494
01495
01496 int rodBins = nBins;
01497 if(!scan->getOption(Scan::BITS32))
01498 if(rodBins%2 == 1) rodBins++;
01499
01500
01501 int binSize = 0x800*(scan->getOption(Scan::BITS32)?4:2);
01502
01503 char *data = new char[nBins * binSize];
01504
01505 bool moduleBlock = false;
01506
01507
01508 unsigned int slaveNumber = 4;
01509
01510 RodLabel rodLabel;
01511 unsigned int channel;
01512 {
01513 unsigned int partition, crate, rod;
01514 Utility::getpcrc(mid, partition, crate, rod, channel);
01515 RodLabel temp(partition, crate, rod);
01516 rodLabel = temp;
01517 }
01518
01519 const RodScanEx &rodInfo = scanEx->getRodScanInfo(rodLabel);
01520
01521 for(int slave=0; slave<4; slave++) {
01522 if((channel<32 && (rodInfo.slaveChannels[slave].mask0 & 1<<channel))
01523 || (channel >= 32 && (rodInfo.slaveChannels[slave].mask1 & 1<<(channel-32)))) {
01524 if(slaveNumber == 4) {
01525 slaveNumber = slave;
01526 } else {
01527 cerr << " ****** Module found on multiple slaves this is an unsupported configuration, the first one will be downloaded??? *****\n";
01528 cerr << " ****** Well you don't expect me to add them all together do you??? *****\n";
01529 #warning "But maybe I should any way"
01530 }
01531 }
01532 }
01533
01534 if(slaveNumber == 4) {
01535 cerr << " ****** Current module not found on any slave, skipping histogram read out *****\n";
01536
01537 throw SctApiException("No mapping from module to DSP found");
01538 }
01539
01540
01541 int index = 0;
01542 int nModules = 0;
01543
01544 for(unsigned int ch=0; ch<48; ch++) {
01545 if(channel == ch) {
01546 index = nModules;
01547 }
01548 if(ch<32) {
01549 if(rodInfo.slaveChannels[slaveNumber].mask0 & 1<<ch) {
01550 nModules ++;
01551 }
01552 } else {
01553 if(rodInfo.slaveChannels[slaveNumber].mask1 & 1<<(ch-32)) {
01554 nModules ++;
01555 }
01556 }
01557 }
01558
01559
01560 unsigned long slaveOffset = 0;
01561
01562 if(moduleBlock) {
01563 slaveOffset += binSize * rodBins;
01564 } else {
01565 slaveOffset += binSize * index;
01566 }
01567
01568
01569 slaveOffset += ((binSize * rodBins * nModules) + binSize) * frame;
01570
01571 bool error = false;
01572
01573 for(int i=0; i<nBins; i++) {
01574 unsigned long *chunk = getHistogramChunk(rodLabel, slaveNumber, slaveOffset, binSize/sizeof(UINT32));
01575 unsigned long *buffer = (unsigned long *)&(data[i*binSize]);
01576
01577 if(chunk) {
01578 for(int b=0; b<binSize/sizeof(UINT32); b++) {
01579 buffer[b] = chunk[b];
01580 }
01581
01582
01583 int bin, module;
01584 int count = sscanf(&((char*)buffer)[binSize-32], "End of bin %d Module %d", &bin, &module);
01585 if(count == 2) {
01586
01587 } else {
01588 if(!error)
01589 printf("Found bad end of histogram bin (%25s)\n", &((char*)buffer)[binSize-32]);
01590 error = true;
01591 }
01592
01593 #warning "Memory leak if sendData didn't work"
01594
01595 } else {
01596 for(int b=0; b<binSize/sizeof(UINT32); b++) {
01597 buffer[b] = 0;
01598 }
01599 }
01600
01601 if(moduleBlock) {
01602 slaveOffset += binSize;
01603 } else {
01604 slaveOffset += binSize * nModules;
01605 }
01606 }
01607
01608 return data;
01609 }
01610
01611 pair<RodLabel, unsigned int> ScanControlRODHisto::findModuleSlave(unsigned int mid) {
01612 RodLabel rodLabel;
01613 unsigned int channel;
01614 {
01615 unsigned int partition, crate, rod;
01616 Utility::getpcrc(mid, partition, crate, rod, channel);
01617 RodLabel temp(partition, crate, rod);
01618 rodLabel = temp;
01619 }
01620
01621 unsigned int slaveNumber = 4;
01622
01623 const RodScanEx &rodInfo = scanEx->getRodScanInfo(rodLabel);
01624
01625 for(int slave=0; slave<4; slave++) {
01626 if((channel<32 && (rodInfo.slaveChannels[slave].mask0 & 1<<channel))
01627 || (channel >= 32 && (rodInfo.slaveChannels[slave].mask1 & 1<<(channel-32)))) {
01628 if(slaveNumber == 4) {
01629 slaveNumber = slave;
01630 } else {
01631 cerr << " ****** Module found on multiple slaves this is an unsupported configuration, the first one will be downloaded??? *****\n";
01632 cerr << " ****** Well you don't expect me to add them all together do you??? *****\n";
01633 #warning "But maybe I should any way"
01634 }
01635 }
01636 }
01637
01638 if(slaveNumber == 4) {
01639 cerr << " ****** Current module not found on any slave, skipping histogram read out *****\n";
01640
01641 throw SctApiException("No mapping from module to DSP found");
01642 }
01643
01644 return make_pair(rodLabel, slaveNumber);
01645 }
01646
01647 void readHistogramToFile(const Sct::UCID & ucid, const Scan &scan, const ScanEx &ex,
01648 UINT32 mid, std::string sn, scan_result_ptrs scanData, time_t saveTime, int frame) {
01649 const int BUFF_SIZE = 50;
01650
01651 struct tm broke;
01652 broke = *(gmtime(&saveTime));
01653
01654 string tempDir = SctNames::getTempDir() + "/";
01655 int bufferLength = BUFF_SIZE + tempDir.length();
01656 char *filename = new char[bufferLength];
01657 strcpy(filename, tempDir.c_str());
01658
01659 cout << "Module: " << mid << " = " << sn << endl;
01660
01661 int written = tempDir.length();
01662 if(scan.getOption(Scan::FULL)) {
01663 written += snprintf(filename + written, bufferLength - written, "Histogram%d_%s", frame, sn.c_str());
01664
01665 strftime(filename + written, bufferLength - written, "_%Y%m%d%H%M%S.bin", &broke);
01666 } else {
01667 written += snprintf(filename + written, bufferLength - written, "Histogram_%s", sn.c_str());
01668
01669 strftime(filename + written, bufferLength - written, "_%Y%m%d%H%M%S.bin", &broke);
01670 }
01671
01672 {
01673 Sct::MultiMessageDebugStream m(true,false,true);
01674 m << ucid << " is writing histogram data to " << filename;
01675 };
01676
01677 saveHistogramToFile(scanData, filename);
01678
01679 cout << "done.\n";
01680
01681 delete [] filename;
01682 }
01683
01684 void saveHistogramToFile(scan_result_ptrs histo, std::string filename) {
01685 ofstream histoout(filename.c_str(), ios::binary);
01686
01687
01688 histoout.write((char*)&histo.header, histo.header.length);
01689
01690
01691 histoout.write((char*)histo.points, histo.header.pntEvents-histo.header.pntPoints);
01692
01693
01694 histoout.write((char*)histo.nEvents, histo.header.pntErrors-histo.header.pntEvents);
01695
01696
01697 histoout.write((char*)histo.nErrorEvents, histo.header.pntData-histo.header.pntErrors);
01698
01699
01700
01701
01702 histoout.write((char*)histo.data, histo.header.size*2);
01703 }
01704
01705 #ifdef USE_IS
01706
01707 void readHistogramToIS(const Sct::UCID & ucid, const Scan &scan, const ScanEx &ex, UINT32 mid, scan_result_ptrs scanData) {
01708
01709
01710
01711
01712
01713 cout << "Writing histogram data to IS\n";
01714
01715
01716
01717 cout << "Module: " << mid << endl;
01718 {
01719 Sct::MultiMessageDebugStream m(true,false,true);
01720 m << ucid << " is writing histogram data to IS for mid " << mid;
01721 };
01722
01723 try {
01724 SctData::ScanResultWriter::publish(scanData);
01725 } catch(Sct::IoException &e) {
01726 cout << "ScanResult publish failed:\n" << e.what() << endl;
01727 e.sendToMrs(MRS_ERROR);
01728 }
01729 }
01730
01731 #endif
01732
01733 int SctApi::pollHistogramming(boost::shared_ptr<ScanControl> controller, int timeout) {
01734 int returnVal = 0;
01735
01736 bool timedout = false;
01737
01738 time_t start_time = time(0);
01739
01740 while(!timedout) {
01741 bool progressMade = false;
01742 bool newBin = false;
01743 if(controller->checkScanComplete(progressMade, newBin)) {
01744
01745 break;
01746 }
01747
01748 if(progressMade) {
01749 start_time = time(0);
01750 }
01751
01752 if(newBin) {
01753 cout << "Controller going to next bin\n";
01754
01755 controller->nextBin();
01756 } else {
01757
01758 #if USE_THREADS
01759
01760 sleep(1);
01761 #else
01762 awaitResponseAll(0);
01763 #endif
01764
01765 if((time(0) - start_time) > timeout) {
01766 timedout = true;
01767 returnVal = -1;
01768
01769 controller->reportTimeout();
01770 controller->reportEventErrors();
01771
01772 break;
01773 }
01774 }
01775 }
01776
01777 #if USE_IS
01778 if(m_isDict) {
01779 m_isDict->remove("SCTAPIServer.currentBin");
01780 m_isDict->remove("SCTAPIServer.maxBin");
01781 }
01782 #endif
01783
01784 return returnVal;
01785 }
01786
01787 void SctApi::doHistogramSetup(const Scan &scan, const ScanEx &extra) {
01788 for(ScanEx::RodInfoMap::const_iterator ri = extra.rodInfo.begin();
01789 ri != extra.rodInfo.end();
01790 ri++) {
01791
01792 const RodLabel &rod = ri->first;
01793
01794
01795
01796 for(int slaveNumber=0; slaveNumber<numSlaves; slaveNumber++) {
01797 if(getCrate()->slavePresent(rod.rod, slaveNumber)) {
01798 if(getCrate()->getRodRevision(rod.rod) >= 0xe) {
01799 #warning "Hard-coded address of incoming event buffer"
01800 setSlaveBlock(rod.rod, slaveNumber, 0x18000, 0x2000, 0);
01801 } else {
01802 setSlaveBlock(rod.rod, slaveNumber, 0x80008000, 0x2000, 0);
01803 }
01804 }
01805 }
01806
01807 boost::shared_ptr<PrimListWrapper> primList(new PrimListWrapper(1));
01808
01809 setupEventTrapping(scan, extra, rod, primList);
01810 startEventTrapping(scan, extra, rod, primList);
01811 setupEventDump(scan, extra, rod, primList);
01812
01813 if(checkDebugOption(DEBUG_EXTRA_DUMPS)) {
01814 standardRegisterDump(rod.rod);
01815
01816 sendPrimList(rod.rod, primList);
01817 awaitResponse(rod.rod, 5);
01818 primList->clear();
01819 }
01820
01821 setupHistogramming(scan, extra, rod, scan.getOption(Scan::TIM), primList);
01822
01823
01824 sendPrimList(rod.rod, primList);
01825 }
01826
01827 for(ScanEx::RodInfoMap::const_iterator ri = extra.rodInfo.begin();
01828 ri != extra.rodInfo.end();
01829 ri++) {
01830 const RodLabel &rod = ri->first;
01831 int responseCode = awaitResponse(rod.rod, 5);
01832 if(responseCode != 0) {
01833 cout << "Histogram setup list failed! (ROD " << rod.rod << ")\n";
01834 throw SctApiException("Histogram setup list failed! (ROD " + boost::lexical_cast<string>(rod.rod) + ")");
01835 } else {
01836 unsigned long length;
01837 unsigned long *result = getResponse(rod.rod, length);
01838
01839 if(result) {
01840 if(result[6] == EVENT_TRAP_SETUP && result[7] == R_EVENT_TRAP_SETUP) {
01841
01842 int numPrims = result[2];
01843 cout << numPrims << " replies from setup primitive list\n";
01844
01845 int offset = 4;
01846 for(int prim = 0; prim<numPrims; prim++) {
01847 cout << prim << ": ";
01848 if(result[offset+2] == EVENT_TRAP_SETUP && result[offset+3] == R_EVENT_TRAP_SETUP) {
01849 cout << "ETS Error code " << result[offset+4] << endl;
01850 } else {
01851 cout << "Unexpected (not ETS) reply from setup primitive list\n";
01852 }
01853 offset += result[offset+0];
01854 }
01855 } else {
01856 cout << "Unexpected output list from histogram setup primitive list\n";
01857 ::SctApi::printOutList(result, length, true, 0, cout,
01858 checkDebugOption(DEBUG_PRINT_UNKNOWN), checkDebugOption(DEBUG_PRINT_RAW));
01859 }
01860 delete [] result;
01861 } else {
01862 cout << "No response to ETS\n";
01863 }
01864 }
01865 }
01866 }
01867
01868 void ScanControlRODHisto::startHistogramming() {
01869 for(ScanEx::RodInfoMap::const_iterator ri = scanEx->rodInfo.begin();
01870 ri != scanEx->rodInfo.end();
01871 ri++) {
01872 const RodLabel &rod = ri->first;
01873
01874
01875 if(scan->getOption(Scan::DEBUG)) {
01876 if(checkDebugOption(DEBUG_SCAN_AUTO_STALL)) {
01877 cout << "** Debug mode setting AUTO_STALL\n";
01878 scanEx->diagnosticReg |= (1<<DR_AUTO_STALL);
01879 }
01880
01881 if(checkDebugOption(DEBUG_SCAN_STEP_MODE)) {
01882 cout << "** Debug mode setting STEP_CTRL\n";
01883 scanEx->diagnosticReg |= (1<<DR_STEP_CTRL);
01884 }
01885
01886 if(checkDebugOption(DEBUG_SCAN_PAUSE_PULSE)) {
01887 #ifdef DR_PULSE_PAUSE
01888 cout << "** Debug mode setting PAUSE_PULSE\n";
01889 scanEx->diagnosticReg |= (1<<DR_PULSE_PAUSE);
01890 #else
01891 cout << "ERROR : Debug mode PAUSE_PAUSE no longer available\n";
01892 #endif
01893 }
01894 }
01895
01896 if(checkDebugOption(DEBUG_SCAN_ROD_MODE_BITS)) {
01897 cout << "Setting up to use ROD mode bits\n";
01898 #ifdef DR_USE_ROD_MASK_LUT
01899 scanEx->diagnosticReg |= (1<<DR_USE_ROD_MASK_LUT);
01900 #else
01901 cout << "ERROR : Cannot set up to use ROD mode bits - USE_ROD_MASK_LUT no longer available!\n";
01902 #endif
01903 }
01904
01905 if(scanEx->diagnosticReg != 0x0) {
01906 cout << "Writing master diag reg: 0x" << hex << scanEx->diagnosticReg << dec << endl;
01907 api.dspSingleWrite(rod.rod, 0x80000010, scanEx->diagnosticReg, -1);
01908 } else {
01909 cout << "Clearing master diag reg\n";
01910 api.dspSingleWrite(rod.rod, 0x80000010, scanEx->diagnosticReg, -1);
01911 }
01912
01913 if(!useCCode(api, *scan)) {
01914
01915 unsigned long SDSP_IDRAM_BASE;
01916 if(api.getRodRevision(rod) >= 0xe) {
01917 SDSP_IDRAM_BASE = 0x10000;
01918 } else {
01919 SDSP_IDRAM_BASE = 0x80000000;
01920 }
01921
01922 for(int s=0; s<numSlaves; s++) {
01923 if(ri->second.bitFieldDSP & (1<<s)) {
01924 try {
01925 unsigned long val = api.dspSingleBlockRead(rod.rod,
01926 SDSP_IDRAM_BASE + 0x10, s);
01927 cout << "Read from slave " << s << " diag register: 0x" << hex << val
01928 << " which should be 0x" << (0) << dec << endl;
01929
01930
01931 unsigned long newVal = val | (1<<19);
01932 api.dspSingleBlockWrite(rod.rod, SDSP_IDRAM_BASE + 0x10, newVal, s);
01933
01934 val = api.dspSingleBlockRead(rod.rod, SDSP_IDRAM_BASE + 0x10, s);
01935 cout << "Read from slave " << s << " diag register: 0x" << hex << val
01936 << " which should be 0x" << (1<<19) << dec << endl;
01937 } catch(VmeException &v) {
01938 Utility::decodeVme(v);
01939 cerr << "VmeException turning on slave " << s << " cache\n";
01940 }
01941 }
01942 }
01943 }
01944
01945 cout << "Histogram starting...\n";
01946
01947 boost::shared_ptr<PrimListWrapper> primList(new PrimListWrapper(1));
01948 api.startHistogramTask(*scan, *scanEx, rod,
01949 sectionStartBin, 1 + sectionEndBin - sectionStartBin, sectionEndTrigger,
01950 primList);
01951
01952
01953
01954
01955
01956 api.sendPrimList(rod.rod, primList);
01957
01958 }
01959
01960 for(ScanEx::RodInfoMap::const_iterator ri = scanEx->rodInfo.begin();
01961 ri != scanEx->rodInfo.end();
01962 ri++) {
01963 const RodLabel &rod = ri->first;
01964 int responseCode = api.awaitResponse(rod.rod, 5);
01965 if(responseCode != 0) {
01966 cout << "Histogram primitive failed! (ROD " << rod.rod << ")\n";
01967 throw SctApiException("Histogram primitive failed! (ROD " + boost::lexical_cast<string>(rod.rod) + ")");
01968 }
01969 }
01970 }
01971
01972 void SctApi::eventTrapSetup(int slaveMask, int trapMatch, int trapMod, int trapRemain, bool tim, bool error,
01973 boost::shared_ptr<PrimListWrapper> primList) {
01974 long *evData = new long[sizeof(EVENT_TRAP_SETUP_IN)/sizeof(UINT32)];
01975
01976 EVENT_TRAP_SETUP_IN &primData = *(EVENT_TRAP_SETUP_IN*)evData;
01977
01978 #if R_EVENT_TRAP_SETUP == 103
01979 primData.slvBits = slaveMask;
01980 primData.numberOfEvents = COLLECT_FOREVER;
01981 primData.timeoutInUsec = 0x30000;
01982
01983 primData.extRouterSetup = 0;
01984
01985
01986
01987 primData.distribute = TRAP_DISTRIB_NEITHER;
01988
01989 primData.releaseFrames = 0;
01990 if(tim) {
01991 primData.permitBackPressure = 0;
01992 } else {
01993 primData.permitBackPressure = 1;
01994 }
01995 primData.dataMode = 0;
01996 if(tim) {
01997 primData.sLink = 1;
01998 } else {
01999 primData.sLink = 0;
02000 }
02001
02002 primData.format = error?TRAP_FMT_ERROR:TRAP_FMT_NORMAL;
02003 primData.trapStray = 1;
02004 primData.iterLimit = 2;
02005
02006 if(tim) {
02007
02008 primData.trapConfig[0] = TRAP_CFG_SLINK_EVT;
02009 } else {
02010
02011 primData.trapConfig[0] = TRAP_CFG_ROD_EVT;
02012 }
02013 primData.trapExclusionFlag[0] = 0;
02014 primData.trapFunction[0] = TRAP_FXN_HISTOGRAM;
02015
02016 primData.trapMatch[0] = trapMatch;
02017 primData.trapModulus[0] = trapMod;
02018 primData.trapRemainder[0] = trapRemain;
02019
02020
02021 primData.trapConfig[1] = TRAP_CFG_IDLE;
02022 primData.trapExclusionFlag[1] = 0;
02023 primData.trapFunction[1] = 0;
02024
02025 primData.trapMatch[1] = 0;
02026 primData.trapModulus[1] = 0;
02027 primData.trapRemainder[1] = 0;
02028 #else
02029 #error "Event trapping not compiled (new Primitive definition)!"
02030 #endif
02031 primList->addPrimitive(RodPrimitive(sizeof(EVENT_TRAP_SETUP_IN)/sizeof(UINT32) + 4,
02032 0, EVENT_TRAP_SETUP, R_EVENT_TRAP_SETUP, evData),
02033 evData);
02034 }
02035
02036 void SctApi::startEventTrap(int slaveNumber, boost::shared_ptr<PrimListWrapper> primList) {
02037 shared_ptr<PrimListWrapper> startList(new PrimListWrapper(1));
02038
02039 PrimBuilder::instance().startEvTrap(startList);
02040
02041 PrimBuilder::instance().slavePrimList(primList, startList, slaveNumber, true, true);
02042 }
02043
02044 void SctApi::stopEventTrap(int slaveNumber, boost::shared_ptr<PrimListWrapper> primList) {
02045 shared_ptr<PrimListWrapper> stopList(new PrimListWrapper(1));
02046
02047 PrimBuilder::instance().stopEvTrap(stopList);
02048
02049 PrimBuilder::instance().slavePrimList(primList, stopList, slaveNumber, true, true);
02050 }
02051
02052 ScanMonitorImpl::ScanMonitorImpl(boost::shared_ptr<ScanControl> control) : controller(control) {
02053 }
02054
02055 ScanMonitorImpl::~ScanMonitorImpl() {
02056 }
02057
02058 void ScanMonitorImpl::newBin(int prevTriggers, int newBin) {
02059 controller->nextBin();
02060 }
02061
02062 void ScanMonitorImpl::finishScan() {
02063 controller->finishHistogram(true);
02064 }
02065
02066
02067 unsigned long *ScanControlRODHisto::getHistogramChunk(RodLabel rodLabel, int slaveNumber,
02068 unsigned long offset, unsigned long size) {
02069 try {
02070 pair<RodLabel, int> key = make_pair(rodLabel, slaveNumber);
02071
02072 Utility::MemoryBlock chunk;
02073 chunk = scanEx->histoMap[key];
02074 if(!chunk) {
02075 pair<UINT32, UINT32> chunkPos = api.sendData(rodLabel.rod, HISTOGRAM_DATA, slaveNumber);
02076
02077 cout << "SendData returned " << chunkPos.first << " " << chunkPos.second << endl;
02078 cout << " need offset " << offset << " length " << size << endl;
02079
02080 if(api.mrs) {
02081
02082 *api.mrs << "SCAN_READOUT" << MRS_DIAGNOSTIC
02083 << MRS_PARAM<float>("MWords", chunkPos.second/4e6)
02084 << MRS_PARAM<int>("crate", rodLabel.crate)
02085 << MRS_PARAM<int>("rod", rodLabel.rod)
02086 << MRS_TEXT("Scan requested histogram readout") << ENDM;
02087 }
02088
02089 unsigned long *block = api.primReadSlaveDsp(rodLabel.rod,
02090 slaveNumber, chunkPos.first, chunkPos.second/sizeof(UINT32));
02091
02092 if(block == 0) {
02093 throw SctApiException("Read of histogram from slave failed");
02094 }
02095
02096 chunk = Utility::MemoryBlock(chunkPos.second/sizeof(UINT32), block);
02097
02098 scanEx->histoMap[key] = chunk;
02099 }
02100
02101 if((offset + size*4) > (chunk.size() * 4)) {
02102 cout << "Asked for chunk +" << offset << " length " << size << " in " << chunk.size() << "words (continuing)\n";
02103 }
02104
02105
02106 return chunk.address() + (offset / 4);
02107 } catch(SctApiException &e) {
02108 cout << "Caught exception in getHistogramChunk: " << e.what() << "\n\ttrying old histogram address\n";
02109 unsigned long slaveAddress;
02110
02111 if(api.getRodRevision(rodLabel) >= 0xe) {
02112 slaveAddress = 0xa00e2000;
02113 } else {
02114 throw SctApiException("Slave histogram read not possible with old (pre-rev-E) rod");
02115 }
02116 return api.primReadSlaveDsp(rodLabel.rod,
02117 slaveNumber, slaveAddress + offset, size);
02118 }
02119 }
02120
02121 unsigned long *ScanControlRODHisto::getEventCountChunk(RodLabel rodLabel, int slaveNumber) {
02122 try {
02123 pair<RodLabel, int> key = make_pair(rodLabel, slaveNumber);
02124
02125 Utility::MemoryBlock chunk = scanEx->evCountMap[key];
02126 if(!chunk) {
02127 pair<UINT32, UINT32> chunkPos = api.sendData(rodLabel.rod, BIN_DATA, slaveNumber);
02128
02129 cout << "SendData bin returned " << chunkPos.first << " " << chunkPos.second << endl;
02130
02131 unsigned long *block = api.primReadSlaveDsp(rodLabel.rod,
02132 slaveNumber, chunkPos.first, chunkPos.second);
02133 chunk = Utility::MemoryBlock(chunkPos.second, block);
02134
02135 scanEx->evCountMap[key] = chunk;
02136 }
02137
02138 return chunk.address();
02139 } catch(SctApiException &e) {
02140 return 0;
02141 }
02142 }
02143
02144
02145 ScanControlRODHisto::ScanControlRODHisto(SctApi &api, boost::shared_ptr<Scan> aScan, boost::shared_ptr<ScanEx> aScanEx) : ScanControl(api), scan(aScan), scanEx(aScanEx), aborting(false) {
02146 int nBins = scan->getScanPoints1().size();
02147
02148 Scan::TrigPoints trigPoints = scan->getVariableTrigs();
02149
02150 finalTrigger = trigPoints[nBins-1];
02151
02152 finalBin = nBins - 1;
02153
02154 UINT32 initialNTrigs = trigPoints[0];
02155
02156 unsigned int i = 0;
02157 while(i<trigPoints.size() && trigPoints[i] >= initialNTrigs)
02158 i++;
02159
02160
02161 sectionStartBin = 0;
02162 sectionEndBin = i - 1;
02163 if(i==trigPoints.size()) {
02164 sectionEndTrigger = trigPoints[i-1];
02165 } else {
02166 sectionEndTrigger = trigPoints[i-1] - trigPoints[i];
02167 }
02168 cout << "Final bin = " << finalBin << " trigger = " << finalTrigger << endl;
02169
02170 cout << "Initial sectionEndBin = " << sectionEndBin << " sectionEndTrigger = " << sectionEndTrigger << endl;
02171
02172
02173 for(ScanEx::RodInfoMap::const_iterator ri = scanEx->rodInfo.begin();
02174 ri != scanEx->rodInfo.end();
02175 ri++) {
02176 const RodLabel &rodLabel = ri->first;
02177 reportedFinished[rodLabel]=false;
02178 }
02179 }
02180
02181 void ScanControlRODHisto::initialisePolling() {
02182 scanStart = time(0);
02183
02184 cout << "Histogram polling started\n";
02185
02186 sleep(1);
02187
02188 cout << "Polling histogramming task\n";
02189 cout << "scan point count " << scan->getScanPoints1().size() << endl;
02190
02191 for(ScanEx::RodInfoMap::const_iterator ri = scanEx->rodInfo.begin();
02192 ri != scanEx->rodInfo.end();
02193 ri++) {
02194 const RodLabel &rodLabel = ri->first;
02195
02196 if(api.mrs) {
02197 const std::string m1 = (Sct::StringStreamer << "POLL_ROD_" << api.ucid()); const std::string m2 = (Sct::StringStreamer << "ROD polling started on " << api.ucid());
02198
02199 *api.mrs << m1 << MRS_DIAGNOSTIC << MRS_QUALIF("SCTAPI")
02200 << MRS_PARAM<int>("partition", rodLabel.partition)
02201 << MRS_PARAM<int>("crate", rodLabel.crate)
02202 << MRS_PARAM<int>("rod", rodLabel.rod)
02203 << MRS_PARAM<int>("run", scan->getRunNumber())
02204 << MRS_PARAM<int>("scan", scan->getScanNumber())
02205 << MRS_PARAM<int>("firstSlave", ri->second.firstSlave)
02206 << MRS_TEXT(m2)
02207 << ENDM;
02208 }
02209 }
02210
02211 #if USE_IS
02212 if(api.m_isDict) {
02213 ISInfoInt binNumber(0);
02214 api.m_isDict->insert("SCTAPIServer.currentBin", binNumber);
02215
02216 ISInfoInt maxNumber(finalBin);
02217 api.m_isDict->insert("SCTAPIServer.maxBin", maxNumber);
02218 }
02219 #endif
02220 }
02221
02222 void ScanControlRODHisto::reportTimeout() {
02223 Sct::MultiMessageDebugStream m(true,false,true);
02224
02225 m << "You are about to get the 'Scan aborted (histogramming stalled)' "
02226 <<"message. Histogram polling timeout being reported in ["
02227 <<__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. ";
02228
02229 RodLabel minROD;
02230 if(scanEx->rodInfo.size() > 0) {
02231 minROD = scanEx->rodInfo.begin()->first;
02232 }
02233
02234 m << "Was expecting: finalBin=" << finalBin << ", finalTrigger=" << finalTrigger;
02235
02236
02237 for(ScanEx::RodInfoMap::const_iterator ri = scanEx->rodInfo.begin();
02238 ri != scanEx->rodInfo.end();
02239 ri++) {
02240 const RodLabel &rodLabel = ri->first;
02241 cout << " ROD (" << rodLabel.partition << ", " << rodLabel.crate << ", " << rodLabel.rod << "): ";
02242 cout << " Event " << lastEvent[rodLabel] << " Bin " << lastBin[rodLabel] << "\n";
02243
02244 if(lastEvent[rodLabel] < lastEvent[minROD]) {
02245 minROD = rodLabel;
02246 } else if(lastEvent[rodLabel] == lastEvent[minROD] && lastBin[rodLabel] < lastBin[minROD]) {
02247 minROD = rodLabel;
02248 }
02249 }
02250
02251
02252 m << ". Problem was perhaps localised to"
02253 << " partition " << minROD.partition
02254 << " crate" << minROD.crate
02255 << " rod" << minROD.rod
02256 << " run" << scan->getRunNumber()
02257 << " scan"<< scan->getScanNumber()
02258 << " bin"<< lastBin[minROD]
02259 << " event"<< lastEvent[minROD];
02260
02261 m.flush();
02262
02263 if(api.mrs) {
02264 *api.mrs << "SCAN_ABORTED" << MRS_ERROR
02265 << MRS_PARAM<int>("partition", minROD.partition)
02266 << MRS_PARAM<int>("crate", minROD.crate)
02267 << MRS_PARAM<int>("rod", minROD.rod)
02268 << MRS_PARAM<int>("run", scan->getRunNumber())
02269 << MRS_PARAM<int>("scan", scan->getScanNumber())
02270 << MRS_PARAM<int>("bin", lastBin[minROD]) << MRS_PARAM<int>("event", lastEvent[minROD])
02271 << MRS_TEXT("Scan aborted (histogramming stalled)") << ENDM;
02272 }
02273 }
02274
02275 void ScanControlRODHisto::nextBin() {
02276
02277 if(findNextSection()) {
02278 finalTrigger = sectionEndTrigger;
02279 finalBin = sectionEndBin;
02280 return;
02281 }
02282
02283 for(ScanEx::RodInfoMap::const_iterator ri = scanEx->rodInfo.begin();
02284 ri != scanEx->rodInfo.end();
02285 ri++) {
02286 const RodLabel &rod = ri->first;
02287
02288 cout << "New histogram control task...\n";
02289
02290 boost::shared_ptr<PrimListWrapper> primList(new PrimListWrapper(1));
02291 api.startHistogramTask(*scan, *scanEx, rod,
02292 sectionStartBin, 1 + sectionEndBin - sectionStartBin, sectionEndTrigger,
02293 primList);
02294
02295 api.sendPrimList(rod.rod, primList);
02296 int responseCode = api.awaitResponse(rod.rod, 5);
02297
02298 if(responseCode != 0) {
02299 cout << "Histogram primitive failed! (ROD " << rod.rod << ")\n";
02300 throw SctApiException("Histogram primitive failed! (ROD " + boost::lexical_cast<string>(rod.rod) + ")");
02301 }
02302 }
02303 }
02304
02305 bool ScanControlRODHisto::findNextSection() {
02306
02307 Scan::TrigPoints trigPoints = scan->getVariableTrigs();
02308
02309 unsigned int i = sectionEndBin + 1;
02310
02311 if(i==trigPoints.size()) {
02312
02313
02314 return true;
02315 }
02316
02317 UINT32 initialNTrigs = trigPoints[i];
02318
02319 while(i<trigPoints.size() && trigPoints[i] >= initialNTrigs)
02320 i ++;
02321
02322 bool done = false;
02323
02324 sectionStartBin = 0;
02325 sectionEndBin = i - 1;
02326
02327 if(i == trigPoints.size()) {
02328 sectionEndTrigger = trigPoints[i-1];
02329 } else {
02330 sectionEndTrigger = trigPoints[i-1] - trigPoints[i];
02331
02332
02333
02334
02335 }
02336
02337 #if 0
02338
02339 unsigned int i = sectionEndBin + 1;
02340 UINT32 initialNTrigs = trigPoints[i];
02341 while(i<trigPoints.size() && trigPoints[i] == initialNTrigs)
02342 i++;
02343
02344 sectionStartBin = sectionEndBin + 1;
02345 sectionEndBin = i - 1;
02346 sectionEndTrigger = scan->getVariableTrigs()[i-1];
02347
02348 done = false;
02349 #endif
02350
02351 cout << "Next sectionStartBin = " << sectionStartBin << " sectionEndBin = " << sectionEndBin << " sectionEndTrigger = " << sectionEndTrigger << endl;
02352
02353 return done;
02354 }
02355
02356 bool ScanControlRODHisto::checkScanComplete(bool &progressMade, bool &newBin) {
02357 if(aborting) {
02358 return true;
02359 }
02360
02361 progressMade = false;
02362 newBin = false;
02363
02364 bool result = true;
02365
02366 int totalBin = 0;
02367
02368 map<RodLabel, bool> rodNewBinMap;
02369
02370 for(ScanEx::RodInfoMap::const_iterator ri = scanEx->rodInfo.begin();
02371 ri != scanEx->rodInfo.end();
02372 ri++) {
02373 const RodLabel &rodLabel = ri->first;
02374
02375 bool rodNewBin = false;
02376
02377 if(!checkScanCompleteROD(rodLabel, progressMade, rodNewBin, totalBin)) {
02378 result = false;
02379 }
02380
02381 rodNewBinMap[rodLabel] = rodNewBin;
02382 }
02383
02384
02385 newBin = true;
02386 for(map<RodLabel, bool>::const_iterator mapIter = rodNewBinMap.begin();
02387 mapIter != rodNewBinMap.end();
02388 mapIter++) {
02389 if(mapIter->second == false) {
02390 newBin = false;
02391 } else {
02392 cout << "New bin requested by ROD (" << mapIter->first.partition << ", " << mapIter->first.crate << ", " << mapIter->first.rod << ")\n";
02393 }
02394 }
02395
02396 if(progressMade) {
02397 int progressBin = totalBin / scanEx->rodInfo.size();
02398
02399 #if USE_IS
02400 if(api.m_isDict) {
02401 ISInfoInt binNumber(progressBin);
02402 api.m_isDict->update("SCTAPIServer.currentBin", binNumber);
02403 }
02404 #endif
02405 }
02406
02407 return result;
02408 }
02409
02410 void ScanControlRODHisto::abort() {
02411 aborting = true;
02412 }
02413
02414 #warning "32 bit version unreliable!!"
02415 unsigned int ScanControlRODHisto::getEventCounter(const RodLabel &rodLabel, int slave, bool fromMaster) {
02416 if(fromMaster) {
02417
02418 #if defined(HSSTAT_REG_0)
02419 unsigned long address=0;
02420 switch (slave){
02421 case 0: address=HSSTAT_REG_0; break;
02422 case 1: address=HSSTAT_REG_1; break;
02423 case 2: address=HSSTAT_REG_2; break;
02424 case 3: address=HSSTAT_REG_3; break;
02425 default: cerr << "get event counter for bad slave number : " << slave << std::endl; return 0;
02426 }
02427 unsigned long reg = api.dspSingleRead(rodLabel.rod, address, -1);
02428
02429
02430
02431 unsigned currEvent = (unsigned) (reg & 0xffff);
02432 #else
02433 #warning "AJB Hard-coded memory address for checking SDSP event count"
02434
02435
02436
02437 unsigned long reg = api.dspSingleRead(rodLabel.rod,
02438 0x8000002c - (slave & 2) * 2, -1);
02439 unsigned int currEvent = (unsigned int) ((reg >> (16*(slave&1))) & 0xffff);
02440 #endif
02441 return currEvent;
02442 } else {
02443
02444
02445 unsigned long reg = api.dspSingleBlockRead(rodLabel.rod,
02446 0x8000002c, slave);
02447 return (unsigned int) reg;
02448 }
02449 }
02450
02451 bool ScanControlRODHisto::checkScanCompleteROD(const RodLabel &rodLabel, bool &progressMade, bool &newBin, int &totalBin) {
02452 int partition = rodLabel.partition;
02453 int crate = rodLabel.crate;
02454 int rod = rodLabel.rod;
02455
02456 int currBin = 0;
02457 int currEvent = 0;
02458
02459
02460 #warning "AJB does not like the look of this hard-coded memory address for the bin number - not one little bit!"
02461
02462 long reg = api.dspSingleRead(rod, 0x80000020, -1);
02463 currBin = (reg & 0xff);
02464
02465 RodScanEx &rodInfo = scanEx->rodInfo[rodLabel];
02466
02467
02468 currEvent = getEventCounter(rodLabel, rodInfo.firstSlave, true);
02469
02470 if(currBin != lastBin[rodLabel]) {
02471 lastBin[rodLabel] = currBin;
02472 lastEvent[rodLabel] = currEvent;
02473 cout << "Next bin " << currBin << "+" << currEvent << " on ROD (" << partition << ", " << crate << ", " << rod << ")\n";
02474
02475 progressMade = true;
02476 } else if(currEvent != lastEvent[rodLabel]) {
02477 lastEvent[rodLabel] = currEvent;
02478 cout << "Next event " << currEvent << " (bin " << currBin << ") on ROD (" << partition << ", " << crate << ", " << rod << ")\n";
02479
02480 progressMade = true;
02481 }
02482
02483 totalBin += currBin;
02484
02485
02486 if(currBin == sectionEndBin && currEvent == sectionEndTrigger) {
02487
02488 newBin = true;
02489
02490
02491 for(int s=0; s<4; s++) {
02492 if(rodInfo.bitFieldDSP & (1<<s)) {
02493 int slaveEvent = getEventCounter(rodLabel, s, false);
02494
02495 if(slaveEvent != sectionEndTrigger) {
02496 cout << " Slave " << s << " completed only " << slaveEvent << "/" << sectionEndTrigger << " triggers\n";
02497 newBin = false;
02498 }
02499 }
02500 }
02501 } else if(currBin == sectionEndBin && currEvent == (sectionEndTrigger%65536)) {
02502
02503
02504
02505 if(!progressMade) {
02506
02507 newBin = true;
02508
02509
02510 for(int s=0; s<4; s++) {
02511 if(rodInfo.bitFieldDSP & (1<<s)) {
02512 int slaveEvent = getEventCounter(rodLabel, s, false);
02513
02514 if(slaveEvent != sectionEndTrigger) {
02515 cout << " Slave " << s << " completed only " << slaveEvent << "/" << sectionEndTrigger << " triggers\n";
02516 newBin = false;
02517 }
02518 }
02519 }
02520 }
02521 }
02522
02523
02524 if(((currBin == finalBin) && (currEvent == finalTrigger))
02525 || ((currBin == finalBin) && (currEvent == (finalTrigger%65536)) && !progressMade)) {
02526
02527
02528 lastEvent[rodLabel] = finalTrigger;
02529
02530 if(api.mrs && !reportedFinished[rodLabel]) {
02531 reportedFinished[rodLabel]=true;
02532 *api.mrs << "HISTO_SUCCESS" << MRS_DIAGNOSTIC << MRS_QUALIF("SCTAPI")
02533 << MRS_PARAM<int>("partition", rodLabel.partition)
02534 << MRS_PARAM<int>("crate", rodLabel.crate)
02535 << MRS_PARAM<int>("rod", rodLabel.rod)
02536 << MRS_TEXT("Histogramming successfully complete")
02537 << ENDM;
02538 }
02539
02540 cout << "Histogramming completed successfully on rod " << rod << "\n";
02541
02542 return true;
02543 }
02544
02545 return false;
02546 }
02547
02548 void ScanControlTIMHisto::finishHistogram(bool success) {
02549 printVetoStatus();
02550 this->ScanControlRODHisto::finishHistogram(success);
02551 }
02552
02553 void ScanControlAsyncHisto::finishHistogram(bool success) {
02554 printVetoStatus();
02555 this->ScanControlRODHisto::finishHistogram(success);
02556 }
02557
02558 void ScanControl::printVetoStatus(){
02559
02560 long long loCount = api.timReadRegister(0x74);
02561 long long hiCount = api.timReadRegister(0x76);
02562 long long extCount = api.timReadRegister(0x78);
02563 long long count = loCount + (hiCount << 16) + ((extCount << 16) << 16);
02564
02565
02566 long loVeto = api.timReadRegister(0x7c);
02567 long hiVeto = api.timReadRegister(0x7e);
02568 long veto = loVeto + (hiVeto << 16);
02569
02570
02571 long loVetos = api.timReadRegister(0x84);
02572 long hiVetos = api.timReadRegister(0x86);
02573 long vetos = loVetos + (hiVetos << 16);
02574
02575 std::ostringstream vetostatus;
02576 vetostatus << "TIM FFTV Software disable:" << (bool)(api.timReadRegister(0x9c) & 0x100);
02577 vetostatus << "; Hardware disable:" << (bool)(api.timReadRegister(0x5a) & 0x8000);
02578 vetostatus << "; Veto on:" << (bool)(api.timReadRegister(0x5a) & 0x4000) << std::endl;
02579
02580 std::ostringstream oss;
02581 oss << std::hex << count << std::dec;
02582
02583 std::cout << vetostatus.str();
02584 printf("TIM FFTV: Clocks spent vetoed %lld Vetoed triggers %ld Veto applications %ld\n", count, veto, vetos);
02585
02586 if (api.mrs) {
02587 *api.mrs << MRS_INFORMATION << MRS_QUALIF("SCTAPI") << "TIM_FFTV_STATUS"
02588 << MRS_TEXT("TIM module fixed-frequency veto status")
02589 << MRS_PARAM<const char*>("Number of clocks with veto applied",oss.str().c_str())
02590 << MRS_PARAM<long>("Number of triggers vetoed",veto)
02591 << MRS_PARAM<long>("Number of times veto applied",vetos)
02592 << MRS_PARAM<const char*>("Status",vetostatus.str().c_str())
02593 << ENDM;
02594 }
02595 }
02596
02597 void ScanControlRODHisto::finishHistogram(bool success) {
02598 time_t scanEnd = time(0);
02599
02600 #if USE_CONST_SCAN
02601 scanEx->setEndTime(second_clock::universal_time());
02602 #else
02603 scan->setEndTime(second_clock::universal_time());
02604 #endif
02605
02606 std::cout << api.ucid() << " finished histogramming at TIME " << second_clock::universal_time() << std::endl;
02607
02608 if(!useCCode(api, *scan)) {
02609 for(ScanEx::RodInfoMap::const_iterator ri = scanEx->rodInfo.begin();
02610 ri != scanEx->rodInfo.end();
02611 ri++) {
02612 const RodLabel &rod = ri->first;
02613 const RodScanEx &rodInfo = ri->second;
02614
02615 unsigned long SDSP_IDRAM_BASE;
02616 if(api.getRodRevision(rod) >= 0xe) {
02617 SDSP_IDRAM_BASE = 0x10000;
02618 } else {
02619 SDSP_IDRAM_BASE = 0x80000000;
02620 }
02621
02622 for(int s=0; s<numSlaves; s++) {
02623 if(rodInfo.bitFieldDSP & (1<<s)) {
02624 try {
02625 #warning "Hard coded reads of diagnostic register"
02626 unsigned long val = api.dspSingleBlockRead(rod.rod,
02627 SDSP_IDRAM_BASE + 0x10, s);
02628 cout << "Read from slave " << s << " diag register: 0x" << hex << val
02629 << " which should be 0x" << (1<<19) << dec << endl;
02630
02631
02632 unsigned long newVal = val | 1<<17;
02633 api.dspSingleBlockWrite(rod.rod, SDSP_IDRAM_BASE + 0x10, newVal, s);
02634 val = api.dspSingleBlockRead(rod.rod, SDSP_IDRAM_BASE + 0x10, s);
02635 cout << "Read from slave " << s << " diag register: 0x" << hex << val
02636 << " which should be 0x" << (1<<17) << dec << endl;
02637
02638
02639 newVal = val | 1<<19;
02640 api.dspSingleBlockWrite(rod.rod, SDSP_IDRAM_BASE + 0x10, newVal, s);
02641 val = api.dspSingleBlockRead(rod.rod, SDSP_IDRAM_BASE + 0x10, s);
02642 cout << "Read from slave " << s << " diag register: 0x" << hex << val
02643 << " which should be 0x" << (0) << dec << endl;
02644 } catch(VmeException &v) {
02645 Utility::decodeVme(v);
02646 cerr << "VmeException turning off slave " << s << " cache\n";
02647 }
02648 }
02649 }
02650 }
02651 }
02652
02653 #if USE_CONST_SCAN
02654 setModuleScanCacheToLastPointInScan(api, scan, scanEx);
02655 #else
02656 setModuleScanCacheToLastPointInScan(api, scan);
02657 #endif
02658
02659 std::cout << api.ucid() << " Done setModuleScanCacheToLastPointInScan at TIME " << second_clock::universal_time() << std::endl;
02660
02661
02662
02663 if(!scan->getOption(Scan::DEBUG) || success == true) {
02664 if(api.mrs) {
02665 *api.mrs << "SCAN_FINISHED" << MRS_INFORMATION
02666 << MRS_QUALIF("SCTAPI") << MRS_QUALIF("doScan")
02667 << MRS_TEXT("Scan finished")
02668 << MRS_PARAM<int>("ScanNumber", scan->getScanNumber())
02669 << MRS_PARAM<int>("ScanType1", scan->getScanVariable1())
02670 << MRS_PARAM<int>("ScanType2", scan->getScanVariable2())
02671 << MRS_PARAM<int>("ScanTime", scanEnd - scanStart)
02672 << ENDM;
02673 }
02674
02675 cout << api.ucid() << " Histogramming complete, " << (scanEnd - scanStart) << " seconds, tidying up...\n";
02676
02677
02678
02679
02680
02681 cout << api.ucid() << " Starting to read histograms at TIME " << second_clock::universal_time() << std::endl;
02682
02683 readHistograms();
02684
02685 cout << api.ucid() << " Histograms read finished at TIME " << second_clock::universal_time() << std::endl;
02686 } else {
02687 if(!scan->getOption(Scan::DEBUG)) {
02688 cout << "Histogram polling failed\n";
02689
02690 if(api.mrs) {
02691 *api.mrs << "SCAN_FAILED" << MRS_INFORMATION
02692 << MRS_QUALIF("SCTAPI") << MRS_QUALIF("doScan")
02693 << MRS_TEXT("Scan polling failed")
02694 << MRS_PARAM<int>("ScanNumber", scan->getScanNumber())
02695 << MRS_PARAM<int>("ScanTime", scanEnd - scanStart)
02696 << ENDM;
02697 }
02698 }
02699 }
02700
02701 if(checkDebugOption(DEBUG_PRINT_CALIB)) {
02702 RodLabel zeroRod = scanEx->rodInfo.begin()->first;
02703
02704 api.print_calib(zeroRod.rod);
02705 }
02706
02707 if(!scan->getOption(Scan::DEBUG)) {
02708 api.stopHistogramming(*scanEx);
02709
02710
02711 postScanModuleSetup();
02712 } else {
02713 if(api.mrs) {
02714 *api.mrs << "SCAN_DEBUG" << MRS_INFORMATION
02715 << MRS_QUALIF("SCTAPI") << MRS_QUALIF("doScan")
02716 << MRS_TEXT("Scan done in debug mode, probably best to be at the command line to sort it out!")
02717 << ENDM;
02718 }
02719
02720 cout << "** In debug mode, you're responsible for terminating histogram and for readout\n";
02721 }
02722
02723 if(checkDebugOption(DEBUG_PRINT_CALIB)) {
02724 RodLabel zeroRod = scanEx->rodInfo.begin()->first;
02725
02726 api.print_calib(zeroRod.rod);
02727 }
02728
02729
02730 std::cout << scan->print();
02731
02732 #if USE_IS
02733 if(api.m_isDict)
02734 api.m_isDict->remove(api.idiosyncrasy().infoServiceNameOfScanStatusObject());
02735 #endif
02736
02737 if(api.mrs)
02738 *api.mrs << "SCAN_COMPLETE" << MRS_INFORMATION << MRS_QUALIF("SctApi") << MRS_TEXT("Scan has completed") << ENDM;
02739 }
02740
02741 void ScanControlRODHisto::postScanModuleSetup() {
02742 api.setErrorMasks();
02743 }
02744
02745 bool ScanControlRODHisto::checkDebugOption(int opt) {
02746 return Debug::getInstance()->checkDebugOption((DebugOptions)opt);
02747 }
02748
02749 void ScanControlRODHisto::reportEventErrors() {
02750 api.reportEventErrors();
02751 }
02752
02753 unsigned int ScanControlRODHisto::getProcTime(const RodLabel rlabel, int dsp) {
02754 if(dsp == -1) {
02755 throw SctApiException("Can't getProcTime on MDSP");
02756 } else {
02757 int procTime;
02758
02759 unsigned long SDSP_IDRAM_BASE;
02760 if(api.getRodRevision(rlabel) >= 0xe) {
02761 SDSP_IDRAM_BASE = 0x10000;
02762 } else {
02763 SDSP_IDRAM_BASE = 0x80000000;
02764 }
02765
02766 unsigned long length;
02767
02768 #warning "Hard-coded address, sdsp histogram status block"
02769 unsigned long *regs = api.dspBlockRead(rlabel.rod,
02770 SDSP_IDRAM_BASE + 0x10, 20, dsp, length);
02771
02772 if(regs) {
02773 long reg;
02774
02775
02776 reg = regs[6];
02777 procTime = ((reg >> 16) & 0xffff);
02778 } else {
02779 throw SctApiException("Failed to read getProcTime from DSP");
02780 }
02781
02782 return procTime;
02783 }
02784 }
02785
02786 ScanControlRODHisto::TrapBuffers ScanControlRODHisto::getTrapBuffers(const RodLabel rlabel, int dsp) {
02787 if(dsp == -1) {
02788 throw SctApiException("Invaled dsp passed to getTrapBuffers");
02789 } else {
02790 int ihead, itail, xhead, xtail;
02791
02792 unsigned long SDSP_IDRAM_BASE;
02793 if(api.getRodRevision(rlabel) >= 0xe) {
02794 SDSP_IDRAM_BASE = 0x10000;
02795 } else {
02796 SDSP_IDRAM_BASE = 0x80000000;
02797 }
02798
02799 unsigned long length;
02800 #warning "Hard coded address of sdsp trap block"
02801 unsigned long *regs = api.dspBlockRead(rlabel.rod,
02802 SDSP_IDRAM_BASE + 0x10, 20, dsp, length);
02803
02804 if(regs) {
02805 long reg;
02806
02807
02808 reg = regs[1];
02809 itail = ((reg & 0xff0000) >> 16);
02810 xtail = ((reg & 0xff000000) >> 24);
02811
02812
02813 reg = regs[2];
02814 ihead = ((reg & 0xff0000) >> 16);
02815 xhead = ((reg & 0xff000000) >> 24);
02816 } else {
02817 throw SctApiException("Failed to read DSP for getTrapBuffers");
02818 }
02819
02820 return make_pair(make_pair(ihead, itail), make_pair(xhead, xtail));
02821 }
02822 }
02823
02824 void ScanControlRODHisto::dumpHistoStatus(const RodLabel rlabel, int dsp) {
02825 if(dsp == -1) {
02826 const unsigned long MDSP_IDRAM_BASE = 0x80000000;
02827
02828
02829 #ifndef HCMD_STAT_REG_0
02830 #warning "Reading hard-coded HCMD_STAT_REG_0"
02831 long reg = api.dspSingleRead(0, MDSP_IDRAM_BASE + 0x20, -1);
02832 #else
02833 long reg = api.dspSingleRead(0, HCMD_STAT_REG_0, -1);
02834 #endif
02835 cout << "Bin: " << (reg & 0xff)
02836 << " Cal: " << ((reg & 0xff00) >> 8)
02837 << " Errs: " << ((reg & 0xffff0000) >> 16) << endl;
02838
02839
02840 #ifndef HCMD_STAT_REG_1
02841 #warning "Reading hard-coded HCMD_STAT_REG_1"
02842 reg = api.dspSingleRead(0, MDSP_IDRAM_BASE + 0x24, -1);
02843 #else
02844 reg = api.dspSingleRead(0, HCMD_STAT_REG_1, -1);
02845 #endif
02846 cout << "avg. trans " << (reg & 0xff)
02847 << " avg. len " << ((reg & 0xff00) >> 8)
02848 << " avg. proc. " << ((reg & 0xffff0000) >> 16) << endl;
02849
02850
02851 #ifndef HSSTAT_REG_1
02852 #warning "Reading hard-coded HSSTAT_REG_1"
02853 reg = api.dspSingleRead(0, MDSP_IDRAM_BASE + 0x2c, -1);
02854 #else
02855 reg = api.dspSingleRead(0, HSSTAT_REG_1, -1);
02856 #endif
02857 cout << "Slave 0: " << (reg & 0xffff)
02858 << " Slave 1: " << ((reg & 0xffff0000) >> 16) << endl;
02859
02860
02861 #ifndef HSSTAT_REG_0
02862 #warning "Reading hard-coded HSSTAT_REG_0"
02863 reg = api.dspSingleRead(0, MDSP_IDRAM_BASE + 0x28, -1);
02864 #else
02865 reg = api.dspSingleRead(0, HSSTAT_REG_0, -1);
02866 #endif
02867 cout << "Slave 2: " << (reg & 0xffff)
02868 << " Slave 3: " << ((reg & 0xffff0000) >> 16) << endl;
02869 } else {
02870 unsigned long SDSP_IDRAM_BASE;
02871 if(api.getRodRevision(rlabel) >= 0xe) {
02872 SDSP_IDRAM_BASE = 0x10000;
02873 } else {
02874 SDSP_IDRAM_BASE = 0x80000000;
02875 }
02876
02877 unsigned long length;
02878 #warning "Hard coded block of trap status registers"
02879 unsigned long *regs = api.dspBlockRead(rlabel.rod,
02880 SDSP_IDRAM_BASE + 0x10, 20, dsp, length);
02881
02882 if(regs) {
02883 long reg;
02884
02885 cout << "TrapStatus: \n";
02886
02887
02888
02889 reg = regs[1];
02890 int words = ((reg &0xffff) >> 0);
02891 int itail = ((reg & 0xff0000) >> 16);
02892 int xtail = ((reg & 0xff000000) >> 24);
02893
02894 cout << "Event word count: " << words;
02895 cout << " IFrame tail: " << itail;
02896 cout << " XFrame tail: " << xtail << endl;
02897
02898
02899 reg = regs[2];
02900 int ihead = ((reg & 0xff0000) >> 16);
02901 int xhead = ((reg & 0xff000000) >> 24);
02902 cout << " IFrame head: " << ihead;
02903 cout << " XFrame head: " << xhead << endl;
02904
02905
02906 reg = regs[17];
02907 cout << "Trap Command/Status: "
02908 << ((reg & 0x1)?"Trailer ":"")
02909 << ((reg & 0x2)?"Transmit ":"")
02910 << ((reg & 0x4)?"Header ":"")
02911 << ((reg & 0x4)?"ISR active ":"");
02912 cout << ((reg & 0x10)?"\"Data Error\" ":"")
02913 << ((reg & 0x20)?"\"Header Error\" ":"")
02914 << ((reg & 0x40)?"\"Trailer Error\" ":"")
02915 << ((reg & 0x80)?"\"Link Error\" ":"");
02916 cout << ((reg & 0x100)?"\"Error\" ":"")
02917 << ((reg & 0x200)?"\"Overflow(old)\" ":"")
02918 << ((reg & 0x800)?"\"ISR pending\" ":"");
02919 cout << ((reg & 0x4000)?"\"Overflow error\" ":"")
02920 << ((reg & 0x8000)?"\"Overflow\" ":"");
02921 cout << endl;
02922
02923 int errCount = ((reg >> 16) & 0xff);
02924 cout << "\"Error count\": " << errCount << endl;
02925 int evCount = ((reg >> 24) & 0xff);
02926 cout << "\"Event count\": " << evCount << endl;
02927
02928
02929 reg = regs[4];
02930 int currentBin = (reg & 0xff);
02931 cout << "Bin: " << currentBin
02932 << " Cal: " << ((reg & 0x1f00) >> 8)
02933 << ((reg & 0x800)?" Cal enabled":"")
02934 << ((reg & 0x1000)?" New bin":"")
02935 << ((reg & 0x20000)?" New cal":"") << endl;
02936
02937
02938 reg = regs[5];
02939 int numEvents = reg;
02940 cout << "Num events: " << numEvents << endl;
02941
02942
02943 reg = regs[6];
02944 cout << "Histogram status: 0x" << hex << (reg & 0xffff) << dec << " " << ((reg & 0x1)?"Ready ":"")
02945 << ((reg & 0x2)?"Expecting ":"")
02946 << ((reg & 0x4)?"Processing ":"")
02947 << ((reg & 0x8)?"Done ":"") << endl;
02948
02949 int procTime = ((reg >> 16) & 0xffff);
02950 cout << "Bin err: " << ((reg >> 8) & 0xff)
02951 << " proc time: " << ((reg >> 16) & 0xffff) << endl;
02952
02953
02954 reg = regs[7];
02955 int evRecvd = reg;
02956 cout << "Events recvd: " << evRecvd << endl;
02957
02958 ofstream statusOut("TIMStatus.txt", ios_base::out | ios_base::app);
02959 statusOut << currentBin << "\t"
02960 << ihead << "\t" << itail << "\t"
02961 << xhead << "\t" << xtail << "\t"
02962 << errCount << "\t" << evCount << "\t"
02963 << evRecvd << "\t" << words << "\t" << procTime << endl;
02964 }
02965 }
02966 }
02967
02968 ScanControlTIMHisto::ScanControlTIMHisto(SctApi &api, boost::shared_ptr<Scan> aScan, boost::shared_ptr<ScanEx> aScanEx) : ScanControlRODHisto(api, aScan, aScanEx), binCount(0) {
02969 }
02970
02971 void ScanControlTIMHisto::startHistogramming() {
02972
02973 api.timWriteRegister(0x14, 0x3000);
02974
02975
02976 for (unsigned reg=0x74; reg<=0x86; reg+=2){
02977 api.timWriteRegister(reg,0x0);
02978 }
02979
02980 shared_ptr<PrimListWrapper> preTimList(new PrimListWrapper(4));
02981 PrimBuilder::instance().rodMode(preTimList, DATA_TAKING_MODE, 0, 1, 0, 0, 1);
02982
02983 PrimBuilder::instance().writeRegister(preTimList, RTR_CMND_STAT, 7, 1, 1);
02984
02985 for(int f=0; f<8; f++) {
02986
02987
02988 PrimBuilder::instance().writeRegister(preTimList, DM_DFLT_LUT(f), 0, 16, 0x0);
02989 }
02990
02991
02992
02993
02994
02995
02996 cout << "Sending pre TIM setup list\n";
02997 api.synchSendPrimListAll(preTimList);
02998 cout << " done sending pre TIM setup list\n";
02999
03000 hex(cout);
03001 cout << "0x" << RTR_CMND_STAT << ": 0x" << api.readRODRegister(0, RTR_CMND_STAT) << endl;
03002 cout << "0x" << Utility::EfbErrorMask(0, 0) << ": 0x" << api.readRODRegister(0, Utility::EfbErrorMask(0, 0)) << endl;
03003 cout << "0x" << Utility::EfbErrorMask(1, 0) << ": 0x" << api.readRODRegister(0, Utility::EfbErrorMask(1, 0)) << endl;
03004 cout << "0x" << DM_DFLT_LUT(0) << ": 0x" << api.readRODRegister(0, DM_DFLT_LUT(0)) << endl;
03005 cout << "0x" << DM_DFLT_LUT(1) << ": 0x" << api.readRODRegister(0, DM_DFLT_LUT(1)) << endl;
03006 dec(cout);
03007
03008 if(checkDebugOption(DEBUG_TIM_SCAN_STATUS)) {
03009
03010 ofstream statusOut("TIMStatus.txt");
03011 statusOut << "bin\tihead\titail\txhead\txtail\terrCnt\tevCount\tevRecvd\twords\tprocTime\n";
03012 }
03013 }
03014
03015 void ScanControlTIMHisto::nextBin() {
03016 cout << "TIM histo, next bin\n";
03017
03018 unsigned scanvariable1 = scan->getScanVariable1();
03019 if (scanvariable1!=0){
03020 double value = scan->getScanPoints1()[binCount];
03021
03022 if (ConfigUtility::isModuleRegister(scanvariable1)){
03023 std::list<BankType> banks;
03024 banks.push_back(SCTAPI_BANK_SCAN);
03025 api.modifyABCDVarROD(scanvariable1, value, banks);
03026 } else if (ConfigUtility::isTimRegister(scanvariable1) ) {
03027 api.modifyTIMParam(scanvariable1, (int)(value+0.5));
03028 } else if (ConfigUtility::isBocRegister(scanvariable1) ){
03029 api.modifyBOCParam(scanvariable1, (int)(value+0.5));
03030 } else if (ConfigUtility::variableType(scanvariable1)==ConfigUtility::TRIGGER_VAR) {
03031 ;
03032 } else {
03033 if (api.mrs) {
03034 *api.mrs << "BAD_SCAN_VARIABLE" << MRS_TEXT("Unknown scan variable in TIM scan")
03035 << MRS_PARAM<int>("Variable number",scanvariable1) << MRS_WARNING << ENDM;
03036 } else{
03037 std::cout << "Warning - bad scan variable : " << scanvariable1
03038 << " type " << ConfigUtility::variableType(scanvariable1) << std::endl;
03039 }
03040 }
03041 }
03042
03043
03044
03045 api.sendAllABCDModules(SCTAPI_BANK_SCAN);
03046
03047
03048 shared_ptr<PrimListWrapper> setTriggerList(new PrimListWrapper(4));
03049 PrimBuilder::instance().setTrigger(setTriggerList, binCount, Utility::translateBank(SCTAPI_BANK_SCAN));
03050
03051 shared_ptr<PrimListWrapper> binTimList(new PrimListWrapper(4));
03052
03053
03054 for(int s=0; s<4; s++) {
03055 PrimBuilder::instance().slavePrimList(binTimList, setTriggerList, s, 1, 0);
03056 }
03057
03058 PrimBuilder::instance().rodMode(binTimList, DATA_TAKING_MODE, 0, 1, 0, 0, 1);
03059 PrimBuilder::instance().writeRegister(binTimList, RTR_CMND_STAT, 7, 1, 1);
03060
03061 cout << "Sending TIM setup list\n";
03062 api.synchSendPrimListAll(binTimList);
03063 cout << " done sending TIM setup list\n";
03064
03065 if(checkDebugOption(DEBUG_TIM_SCAN_STATUS)) {
03066 cout << "******************* Pre triggers status ********************\n";
03067 dumpHistoStatus(RodLabel(), 0);
03068 }
03069
03070 cout << "Sending soft/bc resets to crate: " << api.ucid() << endl;
03071 api.timSoftReset();
03072 api.timBCReset();
03073
03074 Scan::TrigPoints trigs = scan->getVariableTrigs();
03075
03076 cout << "Want " << trigs[binCount] << " triggers to crate: " << api.ucid() << endl;
03077
03078 const Trigger& trig1 = *scan->getTrigger1();
03079
03080 if(1) {
03081 switch(scan->getOption(Scan::TIM)) {
03082 case 1:
03083
03084 {
03085 api.sendTriggers(&trig1, trigs[binCount], binCount);
03086 }
03087 break;
03088 case 2:
03089 #warning "Assumes ROD 0!!!"
03090
03091 for(unsigned int i=0; i<trigs[binCount]; i++) {
03092 api.timL1A();
03093
03094 TrapBuffers tb = getTrapBuffers(RodLabel(), 0);
03095
03096 if (!(tb.first.first == tb.first.second && tb.second.first == tb.second.second))
03097 sleep(1);
03098 }
03099 break;
03100 case 3:
03101 #warning "Assumes ROD 0!!!"
03102
03103
03104 {
03105 unsigned int sentTriggers = 0;
03106 const unsigned int trigsPerBurst = 20;
03107
03108 while(sentTriggers < trigs[binCount]) {
03109 if(sentTriggers % 1000 < trigsPerBurst) {
03110 cout << "Done " << sentTriggers << " triggers\n";
03111 if(checkDebugOption(DEBUG_TIM_SCAN_STATUS))
03112 dumpHistoStatus(RodLabel(), 0);
03113 }
03114 int ntrigs = min(trigs[binCount]-sentTriggers, trigsPerBurst);
03115 api.sendTimBurst(ntrigs,false);
03116 sentTriggers += ntrigs;
03117
03118
03119 TrapBuffers tb = getTrapBuffers(RodLabel(), 0);
03120
03121 TrapBuffers oldtb;
03122 if (!(tb.first.first == tb.first.second && tb.second.first == tb.second.second))
03123 do {
03124 oldtb = tb;
03125 usleep(trigsPerBurst * 10);
03126 tb = getTrapBuffers(RodLabel(), 0);
03127
03128 if(tb.first.first == tb.first.second && tb.second.first == tb.second.second) break;
03129 if(tb == oldtb) break;
03130 } while(1);
03131 }
03132 }
03133 break;
03134 case 4:
03135 #warning "Assumes ROD 0!!!"
03136
03137
03138 {
03139 unsigned int sentTriggers = 0;
03140
03141 api.timL1A();
03142 sentTriggers ++;
03143
03144
03145
03146
03147 unsigned int procTime = getProcTime(RodLabel(), 0);
03148 double timFrequency = 0.25 * 1e6/procTime;
03149
03150 api.timSetFrequency(min(6.0, timFrequency/1000), 0);
03151
03152 cout << "*** Proc Time for 1 trigger was " << procTime << " setting frequency to " << timFrequency << "Hz\n";
03153
03154 procTime = getProcTime(RodLabel(), 0);
03155 timFrequency = 0.25 * 1e6/procTime;
03156 api.timSetFrequency(min(6.0, timFrequency/1000), 0);
03157
03158 cout << "*** Proc Time after 10 trigs was " << procTime << " setting frequency to " << timFrequency << "Hz\n";
03159
03160 if(trigs[binCount] > sentTriggers)
03161 api.sendTimBurst(trigs[binCount]-sentTriggers,false);
03162
03163 if(checkDebugOption(DEBUG_TIM_SCAN_STATUS)) {
03164 cout << "******************* Post triggers status ********************\n";
03165 dumpHistoStatus(RodLabel(), 0);
03166 }
03167
03168 TrapBuffers tb = getTrapBuffers(RodLabel(), 0);
03169
03170 TrapBuffers oldtb;
03171 if (!(tb.first.first == tb.first.second && tb.second.first == tb.second.second))
03172 do {
03173 oldtb = tb;
03174 sleep(1);
03175 tb = getTrapBuffers(RodLabel(), 0);
03176
03177 if(tb.first.first == tb.first.second && tb.second.first == tb.second.second) break;
03178 if(tb == oldtb) break;
03179 } while(1);
03180 break;
03181 }
03182 default:
03183 {
03184 std::cout << "ERROR - unknown TIM option : "
03185 << (scan->getOption(Scan::TIM)) << std::endl;
03186 break;
03187 }
03188 }
03189 }
03190 if(checkDebugOption(DEBUG_TIM_SCAN_STATUS)) {
03191 cout << "******************* Post triggers status 2 ******************\n";
03192 dumpHistoStatus(RodLabel(), 0);
03193 }
03194
03195
03196
03197
03198
03199 binCount ++;
03200 }
03201
03202
03203
03204 bool ScanControlTIMHisto::checkScanCompleteROD(const RodLabel &rodLabel, bool &progressMade, bool &newBin, int &totalBin) {
03205
03206 cout << "Checking TIM scan complete\n";
03207
03208 progressMade = true;
03209
03210
03211 newBin = true;
03212
03213 totalBin += binCount-1;
03214
03215
03216
03217 if((binCount-1 >= finalBin)) {
03218 return true;
03219 }
03220
03221 return false;
03222 }
03223
03224
03225
03226
03227
03228 ScanControlAsyncHisto::ScanControlAsyncHisto(SctApi &api, boost::shared_ptr<Scan> aScan, boost::shared_ptr<ScanEx> aScanEx) : ScanControlRODHisto(api, aScan, aScanEx), binCount(0) {
03229 }
03230
03231 void ScanControlAsyncHisto::startHistogramming() {
03232 #warning "Should we check we're in physics mode?"
03233 if(checkDebugOption(DEBUG_TIM_SCAN_STATUS)) {
03234
03235 ofstream statusOut("TIMStatus.txt");
03236 statusOut << "bin\tihead\titail\txhead\txtail\terrCnt\tevCount\tevRecvd\twords\tprocTime\n";
03237 }
03238 }
03239
03240 void ScanControlAsyncHisto::nextBin() {
03241 cout << "Asynchronous histo, next bin\n";
03242
03243 if (scan->getScanVariable1()!=0){
03244 std::list<BankType> banks;
03245 banks.push_back(SCTAPI_BANK_SCAN);
03246
03247 api.modifyABCDVarROD(scan->getScanVariable1(), scan->getScanPoints1()[binCount], banks);
03248 }
03249
03250 if(0) {
03251
03252
03253 api.sendAllABCDModules(SCTAPI_BANK_SCAN);
03254 }
03255
03256
03257 shared_ptr<PrimListWrapper> setTriggerList(new PrimListWrapper(4));
03258 PrimBuilder::instance().setTrigger(setTriggerList, binCount, Utility::translateBank(SCTAPI_BANK_SCAN));
03259
03260 shared_ptr<PrimListWrapper> binTimList(new PrimListWrapper(4));
03261
03262
03263 for(int s=0; s<4; s++) {
03264 PrimBuilder::instance().slavePrimList(binTimList, setTriggerList, s, 1, 0);
03265 }
03266
03267
03268
03269
03270
03271 cout << "Sending async TIM set trigger list\n";
03272 api.synchSendPrimListAll(binTimList);
03273 cout << " done sending async TIM set trigger list\n";
03274
03275 if(checkDebugOption(DEBUG_TIM_SCAN_STATUS)) {
03276 cout << "******************* Next bin triggers status ********************\n";
03277 dumpHistoStatus(RodLabel(), 0);
03278 }
03279
03280
03281
03282
03283
03284 binCount ++;
03285 }
03286
03287 }