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