00001
00009 #include "SctApi.h"
00010 #include "SctApiConsts.h"
00011 #include "SctApiDebug.h"
00012 #include "SctApiHisto.h"
00013 #include "crate.h"
00014 #include "primListWrapper.h"
00015 #include "PrimBuilder.h"
00016
00017 #include "RodCrate/RodModule.h"
00018
00019 #include "CommonWithDsp/primParams.h"
00020 #include "CommonWithDsp/registerIndices.h"
00021
00022 #include "ABCD/ABCDscans.h"
00023 #include "ABCD/ABCDchip.h"
00024
00025 #include "ScanResultWriter/scan.h"
00026 #include "utility.h"
00027
00028 #include "VmeDecode.h"
00029
00030 #ifdef USE_IS
00031 #include "Sct/IoExceptions.h"
00032 #include "ScanResultWriter/ScanResultWriter.h"
00033 #endif
00034 #include "Sct/SctNames.h"
00035
00036 #include <boost/date_time/posix_time/posix_time.hpp>
00037 #include <boost/lexical_cast.hpp>
00038
00039 #include <algorithm>
00040
00041 using namespace std;
00042 using namespace Sct;
00043 using namespace SctPixelRod;
00044 using namespace boost::posix_time;
00045 using boost::shared_ptr;
00046
00047 namespace SctApi {
00048 void SctApi::doScan(boost::shared_ptr<Scan> scan) {
00049 {
00050 boost::mutex::scoped_lock lock(logMutex);
00051 log << "doScan\n";
00052 }
00053
00054 scan->setStartTime(second_clock::universal_time());
00055
00056
00057 boost::shared_ptr<ScanEx> extra(new ScanEx);
00058 extra->diagnosticReg = 0;
00059
00060 extra->trimScan = 0;
00061 if(scan->getScanVariable1() == ST_TRIM) {
00062
00063 extra->trimScan = 1;
00064 }
00065
00066 cout << "Do scan " << scanNumber << ":\n";
00067 scan->setRunNumber(runNumber);
00068 scan->setScanNumber(scanNumber);
00069
00070
00071 if(scan->getOption(Scan::FULL)) {
00072
00073 scanNumber += 3;
00074 } else {
00075 scanNumber += 1;
00076 }
00077
00078 if(mrs) {
00079 *mrs << "SCAN_REQUESTED" << MRS_INFORMATION
00080 << MRS_PARAM<int>("run", runNumber) << MRS_PARAM<int>("scan", scan->getScanNumber()) << MRS_TEXT("Scan requested") << ENDM;
00081 }
00082
00083 scan->print();
00084
00085
00086 if(scan->getScanPoints2().size() != 0 && scan->getScanPoints2().size() != scan->getScanPoints1().size()) {
00087 cout << "Can't have two different sized scan points lists!\n";
00088 if(mrs) {
00089 *mrs << "SCAN_MISMATCH" << MRS_ERROR
00090 << MRS_QUALIF("SCTAPI") << MRS_QUALIF("doScan")
00091 << MRS_TEXT("doScan supplied with two different sized scan points lists!")
00092 << ENDM;
00093 }
00094 throw SctApiException("Invalid scan. Scan points mismatch");
00095 }
00096
00097 if(!checkModuleListsForScan()) {
00098 throw SctApiException("Invalid scan. Module lists check failed");
00099 }
00100
00101
00102 setupScanMasks(*extra, scan->getOption(Scan::DISTSLAVE), scan->getScanPoints2().size() != 0);
00103
00104
00105 RodLabel zeroRod = extra->rodInfo.begin()->first;
00106
00107
00108 for(unsigned int i = 0;
00109 i<extra->groupLists.size();
00110 i++) {
00111 scan->setModuleList(i, extra->groupLists[i]);
00112 }
00113 scan->setNGroups(extra->groupLists.size());
00114
00115
00116 if(checkDebugOption(DEBUG_DIAG)) {
00117 RodScanEx &rodInfo = extra->rodInfo.find(zeroRod)->second;
00118 cout << hex << "Channels in use: 0x" << rodInfo.channels.mask0 << " 0x" << rodInfo.channels.mask1 << dec << endl;
00119
00120 for(int i=0; i<numSlaves * 2; i++) {
00121 cout << hex << "Group channels: 0x" << rodInfo.groupChannels[i].mask0 << " 0x" << rodInfo.groupChannels[i].mask1 << dec << endl;
00122 }
00123
00124 for(int i=0; i<numSlaves; i++) {
00125 cout << hex << "Slave channels: 0x" << rodInfo.slaveChannels[i].mask0 << " 0x" << rodInfo.slaveChannels[i].mask1 << dec << endl;
00126 }
00127
00128 cout << "Slave DSP bit-field: " << hex << (int)rodInfo.bitFieldDSP << dec << " nSlaves: " << rodInfo.slaves << endl;
00129
00130 hex(cout);
00131 for(int i=0; i<numSlaves; i++) {
00132 cout << "Groups on DSP " << i << ": 0x" << (int)extra->groupDspMap[i] << endl;
00133 }
00134
00135 for(int i=0; i<2; i++) {
00136 cout << "Groups to serial port " << i << ": 0x" << (int)extra->groupSpMap[i] << endl;
00137 }
00138
00139 for(int i=0; i<2; i++) {
00140 cout << "Groups using range list " << i << ": 0x" << (int)extra->groupRangeMap[i] << endl;
00141 }
00142 dec(cout);
00143 }
00144
00145 for(ScanEx::RodInfoMap::const_iterator ri = extra->rodInfo.begin();
00146 ri != extra->rodInfo.end();
00147 ri++) {
00148 if(ri->second.bitFieldDSP & 0xf == 0) {
00149 #warning "Should only abort if no slaves on all RODs?"
00150 cout << "No slaves have been deemed involved in histogramming aborting\n";
00151 if(mrs) {
00152 *mrs << MRS_ERROR
00153 << "SCAN_NODSP"
00154 << MRS_QUALIF("SCTAPI") << MRS_QUALIF("doScan")
00155 << MRS_TEXT("No DSP matched to modules for scan")
00156 << MRS_PARAM<int>("partition", ri->first.partition)
00157 << MRS_PARAM<int>("crate", ri->first.crate)
00158 << MRS_PARAM<int>("rod", ri->first.rod)
00159 << ENDM;
00160 }
00161
00162 throw SctApiException("Invalid scan. A ROD doesn't have any modules attached");
00163 }
00164 }
00165
00166 if (!preScanHardwareCheck(*scan.get(), *extra)) throw SctApiException("Pre scan hardware check failed");
00167
00168 preScanModuleSetup(*scan.get());
00169
00170 {
00171
00172 Trigger::RODTriggers points = scan->getTrigger1()->getRODTriggers();
00173
00174 for(unsigned int i=0; i<points.size(); i++) {
00175 if(points[i].first == SOFT_RESET) {
00176 cout << "Do extra soft reset before trigger to mask soft reset in trigger\n";
00177 extra->diagnosticReg |= 1 << DR_SOFT_BC_RESET;
00178 }
00179 }
00180 }
00181
00182 bool setupGood = true;
00183
00184 try {
00185 cout << "Setup histogramming tasks ...\n";
00186 doHistogramSetup(*scan.get(), *extra);
00187 cout << " ... done setup histogramming tasks\n";
00188 } catch(SctApiException &s) {
00189 setupGood = false;
00190 }
00191
00192
00193 if(mrs) {
00194 *mrs << "SCAN_STARTED" << MRS_INFORMATION
00195 << MRS_QUALIF("SCTAPI") << MRS_QUALIF("doScan")
00196 << MRS_TEXT("Scan started")
00197 << MRS_PARAM<int>("ScanNumber", scan->getScanNumber())
00198 << MRS_PARAM<int>("ScanType1", scan->getScanVariable1())
00199 << MRS_PARAM<int>("ScanType2", scan->getScanVariable2())
00200 << ENDM;
00201 }
00202
00203 try {
00204 if(setupGood) {
00205
00206 if(scan->getOption(Scan::TIM)) {
00207 scanController.reset(new ScanControlTIMHisto(*this, scan, extra));
00208 } else {
00209 scanController.reset(new ScanControlRODHisto(*this, scan, extra));
00210 }
00211
00212 cout << "Starting histogramming ...\n";
00213 scanController->startHistogramming();
00214 cout << " ... histogramming started\n";
00215 }
00216 } catch(SctApiException &s) {
00217 setupGood = false;
00218 }
00219
00220 #ifndef USE_SCAN_THREAD
00221 if(setupGood) {
00222
00223 scanLoop();
00224 }
00225 #endif
00226 }
00227
00228 void SctApi::awaitScan() {
00229 while((scanController || m_inScanLoop) || m_inRawScanLoop) {
00230 sleep(1);
00231 }
00232 }
00233
00234
00235 void SctApi::scanLoop() {
00236
00237 m_inScanLoop = true;
00238
00239 boost::shared_ptr<ScanControl> control;
00240
00241 swap(control, scanController);
00242
00243
00244 lastScanController = control;
00245
00246 if(!control) {
00247 cout << "Given null scan aborting!\n";
00248 return;
00249 }
00250
00251 control->initialisePolling();
00252
00253 int pollReturn = pollHistogramming(control, 3);
00254
00255 cout << "pollHistogramming complete (" << pollReturn << ")\n";
00256
00257 control->finishHistogram(pollReturn == 0);
00258
00259
00260 m_inScanLoop = false;
00261 }
00262
00263 void SctApi::scanPollingThread() {
00264 cout << "SCAN: Start polling thread\n";
00265
00266 while(!m_stopPolling) {
00267 sleep(1);
00268 if(scanController) {
00269 scanLoop();
00270 }
00271 }
00272 }
00273
00274 void SctApi::setupEventTrapping(const Scan &scan, const ScanEx &ex, const RodLabel rod, boost::shared_ptr<PrimListWrapper> primList) {
00275 const RodScanEx &rodInfo = ex.getRodScanInfo(rod);
00276
00277
00278 for(int slaveNumber=0; slaveNumber<numSlaves; slaveNumber++) {
00279 if((rodInfo.bitFieldDSP & (1<<slaveNumber)) && getCrate(rod.partition, rod.crate)->slavePresent(rod.rod, slaveNumber)) {
00280 int match;
00281 int modulus;
00282 int remainder;
00283
00284 switch(scan.getOption(Scan::DISTSLAVE)) {
00285 case 0:
00286
00287 match = 0;
00288 modulus = 1;
00289 remainder = 0;
00290
00291 if(scan.getOption(Scan::NTH) > 1) {
00292
00293 modulus = scan.getOption(Scan::NTH);
00294 remainder = scan.getOption(Scan::NTH_REM);
00295 }
00296 break;
00297 case 1:
00298
00299 match = slaveNumber;
00300 modulus = 1;
00301 remainder = 0;
00302 break;
00303 case 2:
00304
00305 match = 0;
00306 modulus = rodInfo.slaves;
00307 remainder = slaveNumber;
00308
00309 if(scan.getOption(Scan::NTH) > 1) {
00310 modulus = rodInfo.slaves * scan.getOption(Scan::NTH);
00311 remainder = slaveNumber * scan.getOption(Scan::NTH) + scan.getOption(Scan::NTH_REM);
00312 }
00313 break;
00314 default:
00315 match = 0;
00316 modulus = 1;
00317 remainder = 0;
00318 break;
00319 }
00320
00321 eventTrapSetup(0x1 << slaveNumber,
00322 match, modulus, remainder,
00323 scan.getOption(Scan::TIM), checkDebugOption(DEBUG_SCAN_ERROR_TRAP_ALL), primList);
00324 }
00325 }
00326 }
00327
00328 void SctApi::setupEventDump(const Scan &scan, const ScanEx &ex, const RodLabel rod, boost::shared_ptr<PrimListWrapper> primList) {
00329 if(!(checkDebugOption(DEBUG_SCAN_ERROR_TRAP) && scan.getOption(Scan::DEBUG))) return;
00330
00331 int slaveNumber = 2;
00332
00333
00334 {
00335
00336 long *evData = new long[sizeof(EVENT_TRAP_SETUP_IN)/4];
00337
00338 EVENT_TRAP_SETUP_IN &primData = *(EVENT_TRAP_SETUP_IN*)evData;
00339
00340 #if R_EVENT_TRAP_SETUP == 103
00341 primData.slvBits = 0x1 << slaveNumber;
00342 primData.numberOfEvents = COLLECT_FOREVER;
00343 primData.timeoutInUsec = 0x30000;
00344
00345 primData.extRouterSetup = 0;
00346
00347
00348
00349 primData.distribute = TRAP_DISTRIB_NEITHER;
00350
00351 primData.releaseFrames = 0;
00352 primData.permitBackPressure = 1;
00353 primData.dataMode = 0;
00354 primData.sLink = 0;
00355
00356 primData.format = TRAP_FMT_ERROR;
00357 primData.trapStray = 1;
00358 primData.iterLimit = 2;
00359
00360
00361 primData.trapConfig[0] = TRAP_CFG_ROD_EVT;
00362 primData.trapExclusionFlag[0] = 0;
00363 primData.trapFunction[0] = TRAP_FXN_RESYNCH;
00364
00365 primData.trapMatch[0] = 0;
00366 primData.trapModulus[0] = 1;
00367 primData.trapRemainder[0] = 0;
00368
00369
00370 primData.trapConfig[1] = TRAP_CFG_IDLE;
00371 primData.trapExclusionFlag[1] = 0;
00372 primData.trapFunction[1] = 0;
00373
00374 primData.trapMatch[1] = 0;
00375 primData.trapModulus[1] = 0;
00376 primData.trapRemainder[1] = 0;
00377 #else
00378 #error "Event trapping not compiled (new Primitive definition)!"
00379 #endif
00380 primList->addPrimitive(RodPrimitive(sizeof(EVENT_TRAP_SETUP_IN)/sizeof(UINT32) + 4,
00381 0, EVENT_TRAP_SETUP, R_EVENT_TRAP_SETUP, evData),
00382 evData);
00383 }
00384
00385
00386 startEventTrap(slaveNumber, primList);
00387
00388
00389 {
00390 long *taskData = new long[sizeof(START_TASK_IN)/4];
00391
00392 for(unsigned int i=0; i<sizeof(START_TASK_IN)/4; i++) {
00393 taskData[i] = 0;
00394 }
00395
00396 START_TASK_IN &taskPrim = *(START_TASK_IN *)taskData;
00397
00398 taskPrim.taskType = RESYNCH_TASK;
00399 taskPrim.taskRevision = R_RESYNCH_TASK;
00400 taskPrim.priority = 1;
00401 taskPrim.completionFlag = 1;
00402
00403 RESYNCH_TASK_IN &resynch = taskPrim.taskStruct.resynchTaskIn;
00404
00405 resynch.errorType = 0;
00406
00407 shared_ptr<PrimListWrapper> myList(new PrimListWrapper(4));
00408
00409 myList->addPrimitive(RodPrimitive(4 + sizeof(START_TASK_IN)/4,
00410 3, START_TASK, R_START_TASK, taskData),
00411 taskData);
00412
00413 PrimBuilder::instance().slavePrimList(primList, myList, slaveNumber, true, true);
00414 }
00415 }
00416
00417 void SctApi::startEventTrapping(const Scan &scan, const ScanEx &ex, const RodLabel rod, shared_ptr<PrimListWrapper> primList) {
00418 const RodScanEx &rodInfo = ex.getRodScanInfo(rod);
00419
00420 for(int slaveNumber=0; slaveNumber<numSlaves; slaveNumber++) {
00421 if((rodInfo.bitFieldDSP & (1<<slaveNumber)) && getCrate(rod.partition, rod.crate)->slavePresent(rod.rod, slaveNumber)) {
00422 startEventTrap(slaveNumber, primList);
00423 }
00424 }
00425 }
00426
00427 void SctApi::setupHistogramming(const Scan &scan, const ScanEx &ex, const RodLabel rod, bool tim,
00428 boost::shared_ptr<PrimListWrapper> primList) {
00429 const RodScanEx &rodInfo = ex.getRodScanInfo(rod);
00430
00431 int nBins = scan.getScanPoints1().size();
00432 if(!scan.getOption(Scan::BITS32)) {
00433 if(nBins%2 == 1) {
00434 nBins += 1;
00435 }
00436 }
00437
00438 for(int slaveNumber = 0; slaveNumber < 4; slaveNumber ++) {
00439 if((rodInfo.bitFieldDSP & (1<<slaveNumber)) && getCrate(rod.partition, rod.crate)->slavePresent(rod.rod, slaveNumber)) {
00440
00441 long *histoData = new long[sizeof(HISTOGRAM_SETUP_IN)/4];
00442
00443 HISTOGRAM_SETUP_IN &primData = *(HISTOGRAM_SETUP_IN*)histoData;
00444
00445 #if (R_HISTOGRAM_SETUP == 108)
00446 primData.base = (UINT32 *)0xffffffff;
00447 primData.nBins = nBins;
00448
00449 primData.dataType[0] = scan.getScanVariable1();
00450 primData.dataType[1] = scan.getScanVariable2();
00451
00452 primData.binSize = scan.getOption(Scan::BITS32)?HISTOGRAM_32BIT:HISTOGRAM_16BIT;
00453
00454 if(checkDebugOption(DEBUG_SCAN_USE_ASSEMBLER)) {
00455 primData.routineType = HISTO_ROUTINE_ASM;
00456 } else {
00457 primData.routineType = HISTO_ROUTINE_C;
00458 }
00459
00460
00461 primData.opt[0] = 0;
00462
00463 primData.opt[1] = scan.getOption(Scan::FULL)?HISTOGRAM_FULL:HISTOGRAM_CONDENSED;
00464
00465 primData.opt[2] = 0;
00466 primData.opt[3] = 0;
00467
00468 UINT8 groupMap = ex.groupDspMap[slaveNumber];
00469
00470 primData.validModules[0] = 0;
00471 primData.validModules[1] = 0;
00472
00473 primData.moduleRangeMap[0][0] = 0;
00474 primData.moduleRangeMap[0][1] = 0;
00475 primData.moduleRangeMap[1][0] = 0;
00476 primData.moduleRangeMap[1][1] = 0;
00477
00478 for(int i=0; i<8; i++) {
00479 if(groupMap & (1<<i)) {
00480 primData.validModules[0] |= rodInfo.groupChannels[i].mask0;
00481 primData.validModules[1] |= rodInfo.groupChannels[i].mask1;
00482
00483 if(ex.groupSpMap[0] & (1<<i)) {
00484 primData.moduleRangeMap[0][0] |= rodInfo.groupChannels[i].mask0;
00485 primData.moduleRangeMap[0][1] |= rodInfo.groupChannels[i].mask1;
00486 }
00487 if(ex.groupSpMap[1] & (1<<i)) {
00488 primData.moduleRangeMap[1][0] |= rodInfo.groupChannels[i].mask0;
00489 primData.moduleRangeMap[1][1] |= rodInfo.groupChannels[i].mask1;
00490 }
00491 }
00492 }
00493
00494 primData.xPtr[0] = (FLOAT32 *)0xffffffff;
00495 primData.xPtr[1] = (FLOAT32 *)0xffffffff;
00496 #elif (R_HISTOGRAM_SETUP == 105) || (R_HISTOGRAM_SETUP == 107)
00497 primData.base = (UINT32 *)0xffffffff;
00498 primData.nBins = nBins;
00499
00500 primData.padding[0] = 0;
00501 primData.padding[1] = 0;
00502
00503 primData.dataType[0] = scan.getScanVariable1();
00504 primData.dataType[1] = scan.getScanVariable2();
00505
00506 primData.binSize = scan.getOption(Scan::BITS32)?HISTOGRAM_32BIT:HISTOGRAM_16BIT;
00507
00508
00509 primData.opt[0] = HISTOGRAM_SLICE;
00510
00511 primData.opt[1] = scan.getOption(Scan::FULL)?HISTOGRAM_FULL:HISTOGRAM_CONDENSED;
00512
00513 primData.opt[2] = 0;
00514 #if(R_HISTOGRAM_SETUP == 107)
00515 primData.opt[3] = 0;
00516 #endif
00517
00518 UINT8 groupMap = ex.groupDspMap[slaveNumber];
00519
00520 primData.validModules[0] = 0;
00521 primData.validModules[1] = 0;
00522
00523 primData.moduleRangeMap[0][0] = 0;
00524 primData.moduleRangeMap[0][1] = 0;
00525 primData.moduleRangeMap[1][0] = 0;
00526 primData.moduleRangeMap[1][1] = 0;
00527
00528 for(int i=0; i<8; i++) {
00529 if(groupMap & (1<<i)) {
00530 primData.validModules[0] |= rodInfo.groupChannels[i].mask0;
00531 primData.validModules[1] |= rodInfo.groupChannels[i].mask1;
00532
00533 if(ex.groupSpMap[0] & (1<<i)) {
00534 primData.moduleRangeMap[0][0] |= rodInfo.groupChannels[i].mask0;
00535 primData.moduleRangeMap[0][1] |= rodInfo.groupChannels[i].mask1;
00536 }
00537 if(ex.groupSpMap[1] & (1<<i)) {
00538 primData.moduleRangeMap[1][0] |= rodInfo.groupChannels[i].mask0;
00539 primData.moduleRangeMap[1][1] |= rodInfo.groupChannels[i].mask1;
00540 }
00541 }
00542 }
00543
00544 primData.xPtr[0] = (FLOAT32 *)0xffffffff;
00545 primData.xPtr[1] = (FLOAT32 *)0xffffffff;
00546 #elif R_HISTOGRAM_SETUP == 104
00547 primData.base = (UINT32 *)0xffffffff;
00548 primData.rodType = ROD_TYPE_SCT;
00549 primData.nBins = nBins;
00550
00551 primData.padding[0] = 0;
00552 primData.padding[1] = 0;
00553
00554 primData.dataType[0] = scan.getScanVariable1();
00555 primData.dataType[1] = scan.getScanVariable2();
00556
00562 primData.arrangement = HISTOGRAM_SLICE;
00563 primData.dataFormat = scan.getOption(Scan::FULL)?HISTOGRAM_FULL:HISTOGRAM_CONDENSED;
00564 primData.binSize = scan.getOption(Scan::BITS32)?HISTOGRAM_32BIT:HISTOGRAM_16BIT;
00565 primData.unused = 0;
00566
00567 if(scan.getOption(Scan::DISTSLAVE) == 1) {
00568 primData.validModules[0] = rodInfo.groupChannels[slaveNumber][0];
00569 primData.validModules[1] = rodInfo.groupChannels[slaveNumber][1];
00570 primData.moduleRangeMap[0][0] = rodInfo.groupChannels[slaveNumber][0];
00571 primData.moduleRangeMap[0][1] = rodInfo.groupChannels[slaveNumber][1];
00572 } else {
00573 primData.validModules[0] = rodInfo.channels[0];
00574 primData.validModules[1] = rodInfo.channels[1];
00575 primData.moduleRangeMap[0][0] = rodInfo.channels[0];
00576 primData.moduleRangeMap[0][1] = rodInfo.channels[1];
00577 }
00578 primData.moduleRangeMap[1][0] = 0;
00579 primData.moduleRangeMap[1][1] = 0;
00580
00581 primData.xPtr[0] = (FLOAT32 *)0x3f00000;
00582 primData.xPtr[1] = (FLOAT32 *)0x3f01000;
00583 #else
00584 #error "Histogram setup not compiled (new Primitive definition)!"
00585 #endif
00586
00587 long *taskData = new long[sizeof(START_TASK_IN)/4];
00588
00589 for(unsigned int i=0; i<sizeof(START_TASK_IN)/4; i++) {
00590 taskData[i] = 0;
00591 }
00592
00593 START_TASK_IN &taskPrim = *(START_TASK_IN *)taskData;
00594
00595 taskPrim.taskType = HISTOGRAM_TASK;
00596 taskPrim.taskRevision = R_HISTOGRAM_TASK;
00597 taskPrim.priority = 1;
00598 taskPrim.completionFlag = 1;
00599
00600 HISTOGRAM_TASK_IN &histoTaskData = taskPrim.taskStruct.histogramTaskIn;
00601
00602 histoTaskData.nEvents = COLLECT_FOREVER;
00603 if(tim) {
00604 histoTaskData.controlFlag = LOCAL_SET_TRIG;
00605 } else {
00606 histoTaskData.controlFlag = MASTER_HREG;
00607 }
00608
00609 boost::shared_ptr<PrimListWrapper> myList(new PrimListWrapper(4));
00610
00611 myList->addPrimitive(RodPrimitive(4 + sizeof(HISTOGRAM_SETUP_IN)/sizeof(UINT32),
00612 2, HISTOGRAM_SETUP, R_HISTOGRAM_SETUP, histoData),
00613 histoData);
00614 myList->addPrimitive(RodPrimitive(4 + sizeof(START_TASK_IN)/4,
00615 3, START_TASK, R_START_TASK, taskData),
00616 taskData);
00617
00618 PrimBuilder::instance().slavePrimList(primList, myList, slaveNumber, true, true);
00619 }
00620 }
00621 }
00622
00623 void SctApi::startHistogramTask(const Scan &scan, const ScanEx &ex, const RodLabel rod,
00624 unsigned int startBin, unsigned int nBins, unsigned int nTrigs,
00625 boost::shared_ptr<PrimListWrapper> primList) {
00626 const RodScanEx &rodInfo = ex.getRodScanInfo(rod);
00627
00628
00629 unsigned int allBins = nBins;
00630
00631 long *ctrlData = new long[sizeof(START_TASK_IN)/4 + allBins * 2];
00632
00633 for(unsigned int i=0; i<sizeof(START_TASK_IN)/4 + allBins * 2; i++) {
00634 ctrlData[i] = 0;
00635 }
00636
00637 struct START_TASK_IN &primData = *(START_TASK_IN*)ctrlData;
00638 struct HISTOGRAM_CTRL_TASK_IN &taskData = primData.taskStruct.histoCtrlTaskIn;
00639
00640 #if (R_HISTOGRAM_CTRL_TASK == 107)
00641 primData.taskType = HISTOGRAM_CTRL_TASK;
00642 primData.taskRevision = R_HISTOGRAM_CTRL_TASK;
00643 primData.priority = 1;
00644 primData.completionFlag = 1;
00645
00646 taskData.slvBits = rodInfo.bitFieldDSP;
00647
00648 if(scan.getScanPoints2().size() > 0) {
00649 taskData.port = SP_BOTH;
00650 } else {
00651
00652
00653 taskData.port = SP0;
00654 }
00655
00656 taskData.configRegister[0] = scan.getScanVariable1();
00657 taskData.configRegister[1] = scan.getScanVariable2();
00658
00659 taskData.configSctSet = Utility::translateBank(SCTAPI_BANK_SCAN);
00660
00661
00662 if(!ex.trimScan)
00663 taskData.dataSet = MODULE_BASIC;
00664 else
00665 taskData.dataSet = MODULE_TRIM;
00666
00667 taskData.groupRangeMap[0] = ex.groupRangeMap[0];
00668 taskData.groupRangeMap[1] = ex.groupRangeMap[1];
00669
00670 taskData.groupDSPMap[0] = ex.groupDspMap[0];
00671 taskData.groupDSPMap[1] = ex.groupDspMap[1];
00672 taskData.groupDSPMap[2] = ex.groupDspMap[2];
00673 taskData.groupDSPMap[3] = ex.groupDspMap[3];
00674
00675 taskData.groupSPMap[0] = ex.groupSpMap[0];
00676 taskData.groupSPMap[1] = ex.groupSpMap[1];
00677
00678 taskData.globalCtrl = 0;
00679 taskData.syncLevel = 0;
00680
00681 taskData.histoBase = (UINT32*)0xffffffff;
00682
00683 taskData.doChipOcc = 1;
00684 taskData.dataFormat = scan.getOption(Scan::FULL)?HISTOGRAM_FULL:HISTOGRAM_CONDENSED;
00685 taskData.binSize = scan.getOption(Scan::BITS32)?HISTOGRAM_32BIT:HISTOGRAM_16BIT;
00686 taskData.unused1 = 0;
00687
00688 taskData.extSetup = 0xff;
00689 taskData.dataPath = DATA_PATH_NORMAL;
00690 taskData.capture = 0;
00691 taskData.useRangeList = 0;
00692
00693 taskData.repetitions = nTrigs;
00694 taskData.nBins = nBins;
00695 taskData.bin0 = startBin;
00696
00697
00698 for(int i=0; i<5; i++) {
00699 taskData.rangeList[0].xPair[i].x0 = 0.0;
00700 taskData.rangeList[1].xPair[i].x0 = 0.0;
00701 taskData.rangeList[0].xPair[i].delta_x = 0.0;
00702 taskData.rangeList[1].xPair[i].delta_x = 0.0;
00703 }
00704
00705
00706 taskData.dataPtr[0] = (FLOAT32 *)0xffffffff;
00707 taskData.dataPtr[1] = (FLOAT32 *)0xffffffff;
00708
00709
00710 for(int i=0; i<N_CMD_LIST_CMDS; i++) {
00711 taskData.triggerSequence[0].cmd[i] = NO_CMD;
00712 taskData.triggerSequence[1].cmd[i] = NO_CMD;
00713 taskData.triggerSequence[0].data[i] = 0;
00714 taskData.triggerSequence[1].data[i] = 0;
00715 }
00716
00717
00718
00719
00720
00721
00722
00723
00724 Trigger::RODTriggers points = scan.getTrigger1()->getRODTriggers();
00725
00726 for(unsigned int i=0; i<points.size(); i++) {
00727 taskData.triggerSequence[0].cmd[i] = points[i].first;
00728 taskData.triggerSequence[0].data[i] = points[i].second;
00729 }
00730
00731 if(scan.getScanPoints2().size() > 0) {
00732 points = scan.getTrigger2()->getRODTriggers();
00733
00734 for(unsigned int i=0; i<points.size(); i++) {
00735 taskData.triggerSequence[1].cmd[i] = points[i].first;
00736 taskData.triggerSequence[1].data[i] = points[i].second;
00737 }
00738 } else {
00739
00740 }
00741
00742
00743
00744
00745
00746
00747
00748 unsigned short cmd, data;
00749
00750 scan.getTrigger1()->getCommIncr(cmd, data);
00751 taskData.incCmd[0] = cmd;
00752 taskData.incData[0] = data;
00753 scan.getTrigger2()->getCommIncr(cmd, data);
00754 taskData.incCmd[1] = cmd;
00755 taskData.incData[1] = data;
00756
00757 taskData.calLineLoop = scan.getOption(Scan::LOOPCALLINE);
00758 if(scan.getOption(Scan::DISTSLAVE) == 2) {
00759 taskData.distributionToggle = ROUTER_DISTRIB;
00760 } else {
00761 taskData.distributionToggle = MODULE_GROUP;
00762 }
00763
00764 for(int i=0; i<10; i++) {
00765 taskData.genData[i] = 0;
00766 }
00767
00768
00769 taskData.genData[0] = 0xff;
00770
00771 if(scan.getScanPoints2().size() > 0) {
00772 taskData.genData[1] = 1;
00773 taskData.genData[2] = 0x0200;
00774 }
00775
00776 #elif (R_HISTOGRAM_CTRL_TASK == 105)
00777 primData.taskType = HISTOGRAM_CTRL_TASK;
00778 primData.taskRevision = R_HISTOGRAM_CTRL_TASK;
00779 primData.priority = 0;
00780 primData.completionFlag = 1;
00781
00782 taskData.slvBits = 0xf;
00783 taskData.configSctSet = translateBank(SCTAPI_BANK_PHYSICS);
00784
00785
00786
00787 taskData.dataSet = 0;
00788 taskData.useRangeList = 0;
00789 taskData.groupRangeMap[0] = 0;
00790 taskData.groupRangeMap[1] = 0;
00791 taskData.cmdBuff = CMD_BUFFER_BOTH;
00792 taskData.dataPtr[0] = group1Data;
00793 taskData.dataPtr[1] = group2Data;
00794 taskData.repetitions = 10;
00795 taskData.nBins = 10;
00796 taskData.bin0 = 0;
00797
00798 taskData.triggerSequence[0];
00799 taskData.triggerSequence[1];
00800
00801 taskData.incCmd[0] = 0;
00802 taskData.incCmd[1] = 0;
00803 taskData.calLineLoop = 0;
00804
00805 taskData.distributionToggle = 0;
00806 taskData.incData[0] = 1;
00807 taskData.incData[1] = 1;
00808
00809 taskData.groupSPMap[0] = 0;
00810 taskData.groupSPMap[1] = 0;
00811 #else // Unknown R_HISTOGRAM_CTRL_TASK
00812 #error "Histogram Task not compiled (new Primitive definition)!"
00813 #endif
00814
00815 int offset = sizeof(START_TASK_IN)/4;
00816
00817
00818 for(unsigned int i=0; i<allBins; i++) {
00819 ctrlData[offset + i] = *(UINT32 *)&(scan.getScanPoints1()[i]);
00820 if(scan.getScanPoints2().size() == 0) {
00821 ctrlData[offset + allBins + i] = *(UINT32*)&(scan.getScanPoints1()[i]);
00822 } else {
00823 ctrlData[offset + allBins + i] = *(UINT32*)&(scan.getScanPoints2()[i]);
00824 }
00825 }
00826
00827 primList->addPrimitive(RodPrimitive(4 + sizeof(START_TASK_IN)/sizeof(UINT32) + allBins * 2,
00828 0, START_TASK, R_START_TASK, ctrlData),
00829 ctrlData);
00830 }
00831
00832
00833
00834
00835
00836
00837
00838 void SctApi::stopHistogramming(const ScanEx &ex) {
00839 for(ScanEx::RodInfoMap::const_iterator ri = ex.rodInfo.begin();
00840 ri != ex.rodInfo.end();
00841 ri++) {
00842 const RodLabel &rod = ri->first;
00843
00844 {
00845 boost::mutex::scoped_lock lock(logMutex);
00846 log << "Stop histogramming (controlled)\n";
00847 }
00848
00849
00850
00851
00852
00853
00854 boost::shared_ptr<PrimListWrapper> primList(new PrimListWrapper(2));
00855
00856 PrimBuilder &builder = PrimBuilder::instance();
00857 builder.taskOp(primList, HISTOGRAM_CTRL_TASK, TASK_STOP, 0);
00858
00859 {
00860 boost::mutex::scoped_lock lock(logMutex);
00861 log << "Stop histo control task\n";
00862 }
00863 sendPrimList(rod.partition, rod.crate, rod.rod, primList);
00864
00865 awaitResponse(rod.partition, rod.crate, rod.rod, 5);
00866 primList->clear();
00867
00868 cout << "Done kill control task\n";
00869
00870 for(int slaveNumber=0; slaveNumber<numSlaves; slaveNumber++) {
00871
00872 boost::shared_ptr<PrimListWrapper> slList(new PrimListWrapper(1));
00873
00874
00875
00876 builder.taskOp(slList, HISTOGRAM_TASK, TASK_STOP, 0);
00877
00878 PrimBuilder::instance().slavePrimList(primList, slList, slaveNumber, true, true);
00879 {
00880 boost::mutex::scoped_lock lock(logMutex);
00881 log << "Stop slave histogram task " << slaveNumber << endl;
00882 }
00883 sendPrimList(rod.partition, rod.crate, rod.rod, primList);
00884 awaitResponse(rod.partition, rod.crate, rod.rod, 5);
00885 slList->clear();
00886 primList->clear();
00887
00888 cout << "Done kill histogram task\n";
00889
00890 stopEventTrap(slaveNumber, primList);
00891
00892 {
00893 boost::mutex::scoped_lock lock(logMutex);
00894 log << "Stop Event trapping on slave " << slaveNumber << endl;
00895 }
00896 sendPrimList(rod.partition, rod.crate, rod.rod, primList);
00897
00898 awaitResponse(rod.partition, rod.crate, rod.rod, 5);
00899 primList->clear();
00900
00901 cout << "Done kill event trapping\n";
00902 }
00903 }
00904
00905
00906
00907 cout << "Done kill histogramming tasks\n";
00908 }
00909
00910 ScanControl::ScanControl(SctApi &api) : api(api) {}
00911
00912 void ScanControlRODHisto::readHistograms() {
00913 time_t saveTime;
00914 saveTime = time(NULL);
00915
00916
00917
00918
00919
00920 list<RodLabel> rodList = api.listRods();
00921
00922 for(list<RodLabel>::const_iterator rl = rodList.begin();
00923 rl!=rodList.end();
00924 rl++){
00925
00926 cout << "Reading out modules from ROD " << rl->rod << endl;
00927
00928
00929 for(unsigned int group = 0; group < scan->getNGroups(); group ++) {
00930 const list<string> &groupList = scan->getModuleList(group);
00931 cout << "Modules in group " << group << " count: " << groupList.size() << endl;
00932 for(list<string>::const_iterator mi = groupList.begin();
00933 mi!=groupList.end();
00934 mi ++) {
00935
00936 string sn = *mi;
00937 UINT32 mid = api.findModule(sn);
00938
00939 {
00940 unsigned int partition, crate, rod, channel;
00941 Utility::getpcrc(mid, partition, crate, rod, channel);
00942 if(RodLabel(partition, crate, rod) != *rl) {
00943
00944
00945 continue;
00946 }
00947 }
00948
00949 cout << "Module: " << mid << " " << sn << endl;
00950
00951 try {
00952 if(scan->getOption(Scan::FULL)) {
00953 for(int f=0; f<3; f++) {
00954 scan_result_ptrs result = readHistogramData(mid, f);
00955
00956 result.header.scanNumber += f;
00957
00958
00959 if(checkDebugOption(DEBUG_SAVE_HISTOGRAM)) {
00960 readHistogramToFile(*scan, *scanEx, mid, api.convertToString(mid), result, saveTime, f);
00961 }
00962
00963 #ifdef USE_IS
00964
00965 readHistogramToIS(*scan, *scanEx, mid, result);
00966 #endif
00967
00968 delete [] (char*)result.data;
00969 delete [] result.points;
00970 delete [] result.nEvents;
00971 delete [] result.nErrorEvents;
00972 }
00973 } else {
00974 scan_result_ptrs result = readHistogramData(mid, 0);
00975
00976 if(checkDebugOption(DEBUG_SAVE_HISTOGRAM)) {
00977 readHistogramToFile(*scan, *scanEx, mid, api.convertToString(mid), result, saveTime);
00978 }
00979 #ifdef USE_IS
00980 readHistogramToIS(*scan, *scanEx, mid, result);
00981 #endif
00982 delete [] (char*)result.data;
00983 delete [] result.points;
00984 delete [] result.nEvents;
00985 delete [] result.nErrorEvents;
00986 }
00987 } catch(SctApiException &s) {
00988 if(api.mrs) {
00989 *api.mrs << "SCAN_READOUT_FAIL" << MRS_ERROR
00990 << MRS_QUALIF("SctApi")
00991 << MRS_PARAM<int>("run", scan->getRunNumber())
00992 << MRS_PARAM<int>("scan", scan->getScanNumber())
00993 << MRS_PARAM<int>("mid", mid)
00994 << MRS_TEXT("Module readout failed") << ENDM;
00995 }
00996 }
00997 }
00998 }
00999
01000
01001 for(std::map<std::pair<RodLabel, int>,
01002 Utility::MemoryBlock> :: iterator mapIter = scanEx->histoMap.begin();
01003 mapIter != scanEx->histoMap.end();
01004 mapIter++) {
01005
01006 if(mapIter->first.first == *rl) {
01007 if(api.mrs) {
01008 *api.mrs << "SCAN_READOUT" << MRS_DIAGNOSTIC
01009 << MRS_PARAM<float>("MWords", mapIter->second.size() / 1e6)
01010 << MRS_PARAM<int>("crate", rl->crate)
01011 << MRS_PARAM<int>("rod", rl->rod)
01012 << MRS_TEXT("Releasing memory after histogram readout") << ENDM;
01013 }
01014
01015 mapIter->second = Utility::MemoryBlock();
01016 }
01017 }
01018 }
01019 }
01020
01021 scan_result_ptrs ScanControlRODHisto::readHistogramData(UINT32 mid, int frame) {
01022 scan_result_ptrs scanResult;
01023
01024
01025
01026 scanResult.data = readHistogramRawData(mid, frame);
01027
01028 int nBins = scan->getScanPoints1().size();
01029
01030
01031 api.getABCDModule(mid, SCTAPI_BANK_SCAN);
01032
01033
01034 ABCDModule moduleConfig = *api.retrieveModule(mid);
01035
01036 if(checkDebugOption(DEBUG_MODULE_CONFIG)) {
01037 cout << "Configuration after scan:\n";
01038 api.printABCDModule(mid);
01039 }
01040
01041
01042
01043
01044 ScanHeader &header = scanResult.header;
01045
01046 header.version = CURRENT_SCANHEADER_VERSION;
01047 header.length = sizeof(ScanHeader);
01048 header.runNumber = scan->getRunNumber();
01049 header.scanNumber = scan->getScanNumber();
01050
01051 strncpy(header.moduleName, api.convertToString(mid).c_str(), 16);
01052 strncpy(header.startTime, to_iso_string(scan->getStartTime()).c_str(), 16);
01053 strncpy(header.endTime, to_iso_string(scan->getEndTime()).c_str(), 16);
01054 header.moduleName[15] = 0;
01055 header.startTime[15] = 0;
01056 header.endTime[15] = 0;
01057
01058
01059
01060 header.scanType = scan->getScanVariable1();
01061 header.npoints = nBins;
01062 header.size = nBins * 2 * 1024 * (scan->getOption(Scan::BITS32)?2:1);
01063 header.dataType = SR_DT_SLICE;
01064
01065 header.width = scan->getOption(Scan::BITS32)?SR_WD_32:SR_WD_16;
01066
01067 header.config = moduleConfig;
01068
01069 header.pntPoints = sizeof(ScanHeader);
01070 header.pntEvents = header.pntPoints + nBins * sizeof(FLOAT32);
01071 header.pntErrors = header.pntEvents + nBins * sizeof(UINT32);
01072 header.pntData = header.pntErrors + nBins * sizeof(UINT32);
01073
01074
01075 FLOAT32 *points = new FLOAT32[nBins];
01076 for(int i=0; i<nBins; i++) {
01077 points[i] = scan->getScanPoints1()[i];
01078 }
01079 scanResult.points = points;
01080
01081
01082 UINT32 *events = new UINT32[nBins];
01083
01084 std::pair<RodLabel, unsigned int> moduleSlave = findModuleSlave(mid);
01085
01086
01087 unsigned long *countChunk = getEventCountChunk(moduleSlave.first, moduleSlave.second);
01088
01089 for(int i=0; i<nBins; i++) {
01090 events[i] = countChunk[i];
01091
01092
01093 if(scan->getOption(Scan::LOOPCALLINE)) {
01094 events[i] >>= 2;
01095 }
01096 }
01097
01098 #if 0
01099
01100 Scan::TrigPoints trigs = scan->getVariableTrigs();
01101
01102 for(int i=0; i<nBins; i++) {
01103 if(i<lastBin[moduleSlave.first]) {
01104 events[i] = trigs[i];
01105 } else if(i == lastBin[moduleSlave.first]) {
01106 events[i] = lastEvent[moduleSlave.first];
01107 } else {
01108 events[i] = 0;
01109 }
01110 }
01111 #endif
01112
01113 scanResult.nEvents = events;
01114
01115
01116 UINT32 *errors = new UINT32[nBins];
01117 for(int i=0; i<nBins; i++) {
01118 #warning "Get real error count (if possible!)"
01119 errors[i] = 0;
01120 }
01121 scanResult.nErrorEvents = errors;
01122
01123 return scanResult;
01124 }
01125
01126 char* ScanControlRODHisto::readHistogramRawData(UINT32 mid, int frame) {
01127 int nBins = scan->getScanPoints1().size();
01128
01129
01130 int rodBins = nBins;
01131 if(!scan->getOption(Scan::BITS32))
01132 if(rodBins%2 == 1) rodBins++;
01133
01134
01135 int binSize = 0x800*(scan->getOption(Scan::BITS32)?4:2);
01136
01137 char *data = new char[nBins * binSize];
01138
01139 bool moduleBlock = false;
01140
01141
01142 unsigned int slaveNumber = 4;
01143
01144 RodLabel rodLabel;
01145 unsigned int channel;
01146 {
01147 unsigned int partition, crate, rod;
01148 Utility::getpcrc(mid, partition, crate, rod, channel);
01149 RodLabel temp(partition, crate, rod);
01150 rodLabel = temp;
01151 }
01152
01153 const RodScanEx &rodInfo = scanEx->getRodScanInfo(rodLabel);
01154
01155 for(int slave=0; slave<4; slave++) {
01156 if((channel<32 && (rodInfo.slaveChannels[slave].mask0 & 1<<channel))
01157 || (channel >= 32 && (rodInfo.slaveChannels[slave].mask1 & 1<<(channel-32)))) {
01158 if(slaveNumber == 4) {
01159 slaveNumber = slave;
01160 } else {
01161 cerr << " ****** Module found on multiple slaves this is an unsupported configuration, the first one will be downloaded??? *****\n";
01162 cerr << " ****** Well you don't expect me to add them all together do you??? *****\n";
01163 #warning "But maybe I should any way"
01164 }
01165 }
01166 }
01167
01168 if(slaveNumber == 4) {
01169 cerr << " ****** Current module not found on any slave, skipping histogram read out *****\n";
01170
01171 throw SctApiException("No mapping from module to DSP found");
01172 }
01173
01174
01175 int index = 0;
01176 int nModules = 0;
01177
01178 for(unsigned int ch=0; ch<48; ch++) {
01179 if(channel == ch) {
01180 index = nModules;
01181 }
01182 if(ch<32) {
01183 if(rodInfo.slaveChannels[slaveNumber].mask0 & 1<<ch) {
01184 nModules ++;
01185 }
01186 } else {
01187 if(rodInfo.slaveChannels[slaveNumber].mask1 & 1<<(ch-32)) {
01188 nModules ++;
01189 }
01190 }
01191 }
01192
01193
01194 unsigned long slaveOffset = 0;
01195
01196 if(moduleBlock) {
01197 slaveOffset += binSize * rodBins;
01198 } else {
01199 slaveOffset += binSize * index;
01200 }
01201
01202
01203 slaveOffset += ((binSize * rodBins * nModules) + binSize) * frame;
01204
01205 bool error = false;
01206
01207 for(int i=0; i<nBins; i++) {
01208 unsigned long *chunk = getHistogramChunk(rodLabel, slaveNumber, slaveOffset, binSize/4);
01209 unsigned long *buffer = (unsigned long *)&(data[i*binSize]);
01210
01211 if(chunk) {
01212 for(int b=0; b<binSize/4; b++) {
01213 buffer[b] = chunk[b];
01214 }
01215
01216
01217 int bin, module;
01218 int count = sscanf(&((char*)buffer)[binSize-32], "End of bin %d Module %d", &bin, &module);
01219 if(count == 2) {
01220
01221 } else {
01222 if(!error)
01223 printf("Found bad end of histogram bin (%25s)\n", &((char*)buffer)[binSize-32]);
01224 error = true;
01225 }
01226
01227 #warning "Memory leak if sendData didn't work"
01228
01229 } else {
01230 for(int b=0; b<binSize/4; b++) {
01231 buffer[b] = 0;
01232 }
01233 }
01234
01235 if(moduleBlock) {
01236 slaveOffset += binSize;
01237 } else {
01238 slaveOffset += binSize * nModules;
01239 }
01240 }
01241
01242 return data;
01243 }
01244
01245 pair<RodLabel, unsigned int> ScanControlRODHisto::findModuleSlave(unsigned int mid) {
01246 RodLabel rodLabel;
01247 unsigned int channel;
01248 {
01249 unsigned int partition, crate, rod;
01250 Utility::getpcrc(mid, partition, crate, rod, channel);
01251 RodLabel temp(partition, crate, rod);
01252 rodLabel = temp;
01253 }
01254
01255 unsigned int slaveNumber = 4;
01256
01257 const RodScanEx &rodInfo = scanEx->getRodScanInfo(rodLabel);
01258
01259 for(int slave=0; slave<4; slave++) {
01260 if((channel<32 && (rodInfo.slaveChannels[slave].mask0 & 1<<channel))
01261 || (channel >= 32 && (rodInfo.slaveChannels[slave].mask1 & 1<<(channel-32)))) {
01262 if(slaveNumber == 4) {
01263 slaveNumber = slave;
01264 } else {
01265 cerr << " ****** Module found on multiple slaves this is an unsupported configuration, the first one will be downloaded??? *****\n";
01266 cerr << " ****** Well you don't expect me to add them all together do you??? *****\n";
01267 #warning "But maybe I should any way"
01268 }
01269 }
01270 }
01271
01272 if(slaveNumber == 4) {
01273 cerr << " ****** Current module not found on any slave, skipping histogram read out *****\n";
01274
01275 throw SctApiException("No mapping from module to DSP found");
01276 }
01277
01278 return make_pair(rodLabel, slaveNumber);
01279 }
01280
01281 void readHistogramToFile(const Scan &scan, const ScanEx &ex,
01282 UINT32 mid, std::string sn, scan_result_ptrs scanData, time_t saveTime, int frame) {
01283 const int BUFF_SIZE = 50;
01284
01285 struct tm broke;
01286 broke = *(gmtime(&saveTime));
01287
01288 string tempDir = SctNames::getTempDir() + "/";
01289 int bufferLength = BUFF_SIZE + tempDir.length();
01290 char *filename = new char[bufferLength];
01291 strcpy(filename, tempDir.c_str());
01292
01293 cout << "Module: " << mid << " " << sn << endl;
01294
01295 int written = tempDir.length();
01296 if(scan.getOption(Scan::FULL)) {
01297 written += snprintf(filename + written, bufferLength - written, "Histogram%d_%s", frame, sn.c_str());
01298
01299 strftime(filename + written, bufferLength - written, "_%Y%m%d%H%M%S.bin", &broke);
01300 } else {
01301 written += snprintf(filename + written, bufferLength - written, "Histogram_%s", sn.c_str());
01302
01303 strftime(filename + written, bufferLength - written, "_%Y%m%d%H%M%S.bin", &broke);
01304 }
01305
01306 cout << "Writing histogram data to " << filename << endl;
01307
01308 saveHistogramToFile(scanData, filename);
01309
01310 cout << "done.\n";
01311
01312 delete [] filename;
01313 }
01314
01315 void saveHistogramToFile(scan_result_ptrs histo, std::string filename) {
01316 ofstream histoout(filename.c_str(), ios::binary);
01317
01318
01319 histoout.write((char*)&histo.header, histo.header.length);
01320
01321
01322 histoout.write((char*)histo.points, histo.header.pntEvents-histo.header.pntPoints);
01323
01324
01325 histoout.write((char*)histo.nEvents, histo.header.pntErrors-histo.header.pntEvents);
01326
01327
01328 histoout.write((char*)histo.nErrorEvents, histo.header.pntData-histo.header.pntErrors);
01329
01330
01331
01332
01333 histoout.write((char*)histo.data, histo.header.size*2);
01334 }
01335
01336 #ifdef USE_IS
01337
01338 void readHistogramToIS(const Scan &scan, const ScanEx &ex, UINT32 mid, scan_result_ptrs scanData) {
01339
01340
01341
01342
01343
01344 cout << "Writing histogram data to IS\n";
01345
01346
01347
01348 cout << "Module: " << mid << endl;
01349
01350 try {
01351 SctData::ScanResultWriter::publish(scanData);
01352 } catch(Sct::IoException &e) {
01353 cout << "ScanResult publish failed:\n" << e.what() << endl;
01354 e.sendToMrs(MRS_ERROR);
01355 }
01356 }
01357
01358 #endif
01359
01360 int SctApi::pollHistogramming(boost::shared_ptr<ScanControl> controller, int timeout) {
01361 int returnVal = 0;
01362
01363 bool timedout = false;
01364
01365 time_t start_time = time(0);
01366
01367 while(!timedout) {
01368 bool progressMade = false;
01369 bool newBin = false;
01370 if(controller->checkScanComplete(progressMade, newBin)) {
01371
01372 break;
01373 }
01374
01375 if(progressMade) {
01376 start_time = time(0);
01377 }
01378
01379 if(newBin) {
01380 cout << "Controller going to next bin\n";
01381
01382 controller->nextBin();
01383 } else {
01384
01385 #if USE_THREADS
01386
01387 sleep(1);
01388 #else
01389 awaitResponse(partition, crate, rod, 0);
01390 #endif
01391
01392 if((time(0) - start_time) > timeout) {
01393 timedout = true;
01394 returnVal = -1;
01395
01396 controller->reportTimeout();
01397 controller->reportEventErrors();
01398
01399 break;
01400 }
01401 }
01402 }
01403
01404 #if USE_IS
01405 if(m_isDict) {
01406 m_isDict->remove("SCTAPIServer.currentBin");
01407 m_isDict->remove("SCTAPIServer.maxBin");
01408 }
01409 #endif
01410
01411 return returnVal;
01412 }
01413
01414 void SctApi::doHistogramSetup(const Scan &scan, const ScanEx &extra) {
01415 for(ScanEx::RodInfoMap::const_iterator ri = extra.rodInfo.begin();
01416 ri != extra.rodInfo.end();
01417 ri++) {
01418
01419 const RodLabel &rod = ri->first;
01420
01421
01422
01423 for(int slaveNumber=0; slaveNumber<numSlaves; slaveNumber++) {
01424 if(getCrate(rod.partition, rod.crate)->slavePresent(rod.rod, slaveNumber)) {
01425 if(getCrate(rod.partition, rod.crate)->getRodRevision(rod.rod) >= 0xe) {
01426 setSlaveBlock(rod.partition, rod.crate, rod.rod, slaveNumber, 0x18000, 0x2000, 0);
01427 } else {
01428 setSlaveBlock(rod.partition, rod.crate, rod.rod, slaveNumber, 0x80008000, 0x2000, 0);
01429 }
01430 }
01431 }
01432
01433 cout << "Setup event trapping...\n";
01434
01435 boost::shared_ptr<PrimListWrapper> primList(new PrimListWrapper(1));
01436
01437 setupEventTrapping(scan, extra, rod, primList);
01438 startEventTrapping(scan, extra, rod, primList);
01439
01440 setupEventDump(scan, extra, rod, primList);
01441
01442 if(checkDebugOption(DEBUG_EXTRA_DUMPS)) {
01443 standardRegisterDump(rod.partition, rod.crate, rod.rod);
01444
01445 sendPrimList(rod.partition, rod.crate, rod.rod, primList);
01446 awaitResponse(rod.partition, rod.crate, rod.rod, 5);
01447
01448 primList->clear();
01449 }
01450
01451 cout << "Histogramming setup...\n";
01452
01453 setupHistogramming(scan, extra, rod, scan.getOption(Scan::TIM), primList);
01454
01455
01456 sendPrimList(rod.partition, rod.crate, rod.rod, primList);
01457
01458 int responseCode = awaitResponse(rod.partition, rod.crate, rod.rod, 5);
01459 if(responseCode != 0) {
01460 cout << "Histogram setup list failed! (ROD " << rod.rod << ")\n";
01461 throw SctApiException("Histogram setup list failed! (ROD " + boost::lexical_cast<string>(rod.rod) + ")");
01462 }
01463 }
01464 }
01465
01466 void ScanControlRODHisto::startHistogramming() {
01467 for(ScanEx::RodInfoMap::const_iterator ri = scanEx->rodInfo.begin();
01468 ri != scanEx->rodInfo.end();
01469 ri++) {
01470 const RodLabel &rod = ri->first;
01471
01472
01473 if(scan->getOption(Scan::DEBUG)) {
01474 if(checkDebugOption(DEBUG_SCAN_AUTO_STALL)) {
01475 cout << "** Debug mode setting AUTO_STALL\n";
01476 scanEx->diagnosticReg |= (1<<DR_AUTO_STALL);
01477 }
01478
01479 if(checkDebugOption(DEBUG_SCAN_STEP_MODE)) {
01480 cout << "** Debug mode setting STEP_CTRL\n";
01481 scanEx->diagnosticReg |= (1<<DR_STEP_CTRL);
01482 }
01483
01484 if(checkDebugOption(DEBUG_SCAN_PAUSE_PULSE)) {
01485 cout << "** Debug mode setting PAUSE_PULSE\n";
01486 scanEx->diagnosticReg |= (1<<DR_PULSE_PAUSE);
01487 }
01488 }
01489
01490 if(checkDebugOption(DEBUG_SCAN_ROD_MODE_BITS)) {
01491 cout << "Setting up to use ROD mode bits\n";
01492 scanEx->diagnosticReg |= (1<<DR_USE_ROD_MASK_LUT);
01493 }
01494
01495 if(scanEx->diagnosticReg != 0x0) {
01496 cout << "Writing master diag reg: 0x" << hex << scanEx->diagnosticReg << dec << endl;
01497 api.dspSingleWrite(rod.partition, rod.crate, rod.rod, 0x80000010, scanEx->diagnosticReg, -1);
01498 } else {
01499 cout << "Clearing master diag reg\n";
01500 api.dspSingleWrite(rod.partition, rod.crate, rod.rod, 0x80000010, scanEx->diagnosticReg, -1);
01501 }
01502
01503 if(checkDebugOption(DEBUG_SCAN_USE_ASSEMBLER)) {
01504 unsigned long SDSP_IDRAM_BASE;
01505 if(api.getRodRevision(rod) >= 0xe) {
01506 SDSP_IDRAM_BASE = 0x10000;
01507 } else {
01508 SDSP_IDRAM_BASE = 0x80000000;
01509 }
01510
01511 for(int s=0; s<numSlaves; s++) {
01512 if(ri->second.bitFieldDSP & (1<<s)) {
01513 try {
01514 unsigned long val = api.dspSingleBlockRead(rod.partition, rod.crate, rod.rod,
01515 SDSP_IDRAM_BASE + 0x10, s);
01516 cout << "Read from slave " << s << " diag register: 0x" << hex << val
01517 << " which should be 0x" << (0) << dec << endl;
01518
01519
01520 unsigned long newVal = val | (1<<19);
01521 api.dspSingleBlockWrite(rod.partition, rod.crate, rod.rod, SDSP_IDRAM_BASE + 0x10, newVal, s);
01522
01523 val = api.dspSingleBlockRead(rod.partition, rod.crate, rod.rod, SDSP_IDRAM_BASE + 0x10, s);
01524 cout << "Read from slave " << s << " diag register: 0x" << hex << val
01525 << " which should be 0x" << (1<<19) << dec << endl;
01526 } catch(VmeException &v) {
01527 Utility::decodeVme(v);
01528 cerr << "VmeException turning on slave " << s << " cache\n";
01529 }
01530 }
01531 }
01532 }
01533
01534 cout << "Histogram starting...\n";
01535
01536 boost::shared_ptr<PrimListWrapper> primList(new PrimListWrapper(1));
01537 api.startHistogramTask(*scan, *scanEx, rod,
01538 sectionStartBin, 1 + sectionEndBin - sectionStartBin, sectionEndTrigger,
01539 primList);
01540
01541
01542
01543
01544
01545 api.sendPrimList(rod.partition, rod.crate, rod.rod, primList);
01546 int responseCode = api.awaitResponse(rod.partition, rod.crate, rod.rod, 5);
01547
01548 if(responseCode != 0) {
01549 cout << "Histogram primitive failed! (ROD " << rod.rod << ")\n";
01550 throw SctApiException("Histogram primitive failed! (ROD " + boost::lexical_cast<string>(rod.rod) + ")");
01551 }
01552 }
01553 }
01554
01555 void SctApi::eventTrapSetup(int slaveMask, int trapMatch, int trapMod, int trapRemain, bool tim, bool error,
01556 boost::shared_ptr<PrimListWrapper> primList) {
01557 long *evData = new long[sizeof(EVENT_TRAP_SETUP_IN)/4];
01558
01559 EVENT_TRAP_SETUP_IN &primData = *(EVENT_TRAP_SETUP_IN*)evData;
01560
01561 #if R_EVENT_TRAP_SETUP == 103
01562 primData.slvBits = slaveMask;
01563 primData.numberOfEvents = COLLECT_FOREVER;
01564 primData.timeoutInUsec = 0x30000;
01565
01566 primData.extRouterSetup = 0;
01567
01568
01569
01570 primData.distribute = TRAP_DISTRIB_NEITHER;
01571
01572 primData.releaseFrames = 0;
01573 if(tim) {
01574 primData.permitBackPressure = 0;
01575 } else {
01576 primData.permitBackPressure = 1;
01577 }
01578 primData.dataMode = 0;
01579 if(tim) {
01580 primData.sLink = 1;
01581 } else {
01582 primData.sLink = 0;
01583 }
01584
01585 primData.format = error?TRAP_FMT_ERROR:TRAP_FMT_NORMAL;
01586 primData.trapStray = 1;
01587 primData.iterLimit = 2;
01588
01589 if(tim) {
01590
01591 primData.trapConfig[0] = TRAP_CFG_SLINK_EVT;
01592 } else {
01593
01594 primData.trapConfig[0] = TRAP_CFG_ROD_EVT;
01595 }
01596 primData.trapExclusionFlag[0] = 0;
01597 primData.trapFunction[0] = TRAP_FXN_HISTOGRAM;
01598
01599 primData.trapMatch[0] = trapMatch;
01600 primData.trapModulus[0] = trapMod;
01601 primData.trapRemainder[0] = trapRemain;
01602
01603
01604 primData.trapConfig[1] = TRAP_CFG_IDLE;
01605 primData.trapExclusionFlag[1] = 0;
01606 primData.trapFunction[1] = 0;
01607
01608 primData.trapMatch[1] = 0;
01609 primData.trapModulus[1] = 0;
01610 primData.trapRemainder[1] = 0;
01611 #else
01612 #error "Event trapping not compiled (new Primitive definition)!"
01613 #endif
01614 primList->addPrimitive(RodPrimitive(sizeof(EVENT_TRAP_SETUP_IN)/4 + 4,
01615 0, EVENT_TRAP_SETUP, R_EVENT_TRAP_SETUP, evData),
01616 evData);
01617 }
01618
01619 void SctApi::startEventTrap(int slaveNumber, boost::shared_ptr<PrimListWrapper> primList) {
01620 shared_ptr<PrimListWrapper> startList(new PrimListWrapper(1));
01621
01622 PrimBuilder::instance().startEvTrap(startList);
01623
01624 PrimBuilder::instance().slavePrimList(primList, startList, slaveNumber, true, true);
01625 }
01626
01627 void SctApi::stopEventTrap(int slaveNumber, boost::shared_ptr<PrimListWrapper> primList) {
01628 shared_ptr<PrimListWrapper> stopList(new PrimListWrapper(1));
01629
01630 PrimBuilder::instance().stopEvTrap(stopList);
01631
01632 PrimBuilder::instance().slavePrimList(primList, stopList, slaveNumber, true, true);
01633 }
01634
01635
01636 unsigned long *ScanControlRODHisto::getHistogramChunk(RodLabel rodLabel, int slaveNumber,
01637 unsigned long offset, unsigned long size) {
01638 try {
01639 pair<RodLabel, int> key = make_pair(rodLabel, slaveNumber);
01640
01641 Utility::MemoryBlock chunk;
01642 chunk = scanEx->histoMap[key];
01643 if(!chunk) {
01644 pair<UINT32, UINT32> chunkPos = api.sendData(rodLabel.partition, rodLabel.crate, rodLabel.rod, HISTOGRAM_DATA, slaveNumber);
01645
01646 cout << "SendData returned " << chunkPos.first << " " << chunkPos.second << endl;
01647 cout << " need offset " << offset << " length " << size << endl;
01648
01649 if(api.mrs) {
01650
01651 *api.mrs << "SCAN_READOUT" << MRS_DIAGNOSTIC
01652 << MRS_PARAM<float>("MWords", chunkPos.second/4e6)
01653 << MRS_PARAM<int>("crate", rodLabel.crate)
01654 << MRS_PARAM<int>("rod", rodLabel.rod)
01655 << MRS_TEXT("Scan requested histogram readout") << ENDM;
01656 }
01657
01658 unsigned long *block = api.primReadSlaveDsp(rodLabel.partition, rodLabel.crate, rodLabel.rod,
01659 slaveNumber, chunkPos.first, chunkPos.second/4);
01660 chunk = Utility::MemoryBlock(chunkPos.second/4, block);
01661
01662 scanEx->histoMap[key] = chunk;
01663 }
01664
01665 if((offset + size*4) > (chunk.size() * 4)) {
01666 cout << "Asked for chunk +" << offset << " length " << size << " in " << chunk.size() << "words (continuing)\n";
01667 }
01668
01669
01670 return chunk.address() + (offset / 4);
01671 } catch(SctApiException &e) {
01672 unsigned long slaveAddress;
01673
01674 if(api.getRodRevision(rodLabel) >= 0xe) {
01675 slaveAddress = 0xa00e2000;
01676 } else {
01677 slaveAddress = HISTOGRAM_DEFAULT_BASE;
01678 }
01679
01680 return api.primReadSlaveDsp(rodLabel.partition, rodLabel.crate, rodLabel.rod,
01681 slaveNumber, slaveAddress + offset, size);
01682 }
01683 }
01684
01685 unsigned long *ScanControlRODHisto::getEventCountChunk(RodLabel rodLabel, int slaveNumber) {
01686 try {
01687 pair<RodLabel, int> key = make_pair(rodLabel, slaveNumber);
01688
01689 Utility::MemoryBlock chunk = scanEx->evCountMap[key];
01690 if(!chunk) {
01691 pair<UINT32, UINT32> chunkPos = api.sendData(rodLabel.partition, rodLabel.crate, rodLabel.rod, BIN_DATA, slaveNumber);
01692
01693 cout << "SendData bin returned " << chunkPos.first << " " << chunkPos.second << endl;
01694
01695 unsigned long *block = api.primReadSlaveDsp(rodLabel.partition, rodLabel.crate, rodLabel.rod,
01696 slaveNumber, chunkPos.first, chunkPos.second);
01697 chunk = Utility::MemoryBlock(chunkPos.second, block);
01698
01699 scanEx->evCountMap[key] = chunk;
01700 }
01701
01702 return chunk.address();
01703 } catch(SctApiException &e) {
01704 return 0;
01705 }
01706 }
01707
01708
01709 ScanControlRODHisto::ScanControlRODHisto(SctApi &api, boost::shared_ptr<Scan> aScan, boost::shared_ptr<ScanEx> aScanEx) : ScanControl(api), scan(aScan), scanEx(aScanEx), aborting(false) {
01710 int nBins = scan->getScanPoints1().size();
01711
01712 Scan::TrigPoints trigPoints = scan->getVariableTrigs();
01713
01714 finalTrigger = trigPoints[nBins-1];
01715
01716 finalBin = nBins - 1;
01717
01718 UINT32 initialNTrigs = trigPoints[0];
01719
01720 unsigned int i = 0;
01721 while(i<trigPoints.size() && trigPoints[i] >= initialNTrigs)
01722 i++;
01723
01724
01725 sectionStartBin = 0;
01726 sectionEndBin = i - 1;
01727 if(i==trigPoints.size()) {
01728 sectionEndTrigger = scan->getVariableTrigs()[i-1];
01729 } else {
01730 sectionEndTrigger = scan->getVariableTrigs()[i-1] - scan->getVariableTrigs()[i];
01731 }
01732 cout << "Final bin = " << finalBin << " trigger = " << finalTrigger << endl;
01733
01734 cout << "Initial sectionEndBin = " << sectionEndBin << " sectionEndTrigger = " << sectionEndTrigger << endl;
01735 }
01736
01737 void ScanControlRODHisto::initialisePolling() {
01738 scanStart = time(0);
01739
01740 cout << "Histogram polling started\n";
01741
01742 sleep(1);
01743
01744 cout << "Polling histogramming task\n";
01745 cout << "scan point count " << scan->getScanPoints1().size() << endl;
01746
01747 for(ScanEx::RodInfoMap::const_iterator ri = scanEx->rodInfo.begin();
01748 ri != scanEx->rodInfo.end();
01749 ri++) {
01750 const RodLabel &rodLabel = ri->first;
01751
01752 if(api.mrs) {
01753 *api.mrs << "POLL_ROD" << MRS_DIAGNOSTIC << MRS_QUALIF("SCTAPI")
01754 << MRS_PARAM<int>("partition", rodLabel.partition)
01755 << MRS_PARAM<int>("crate", rodLabel.crate)
01756 << MRS_PARAM<int>("rod", rodLabel.rod)
01757 << MRS_PARAM<int>("run", scan->getRunNumber())
01758 << MRS_PARAM<int>("scan", scan->getScanNumber())
01759 << MRS_PARAM<int>("firstSlave", ri->second.firstSlave)
01760 << MRS_TEXT("ROD polling started")
01761 << ENDM;
01762 }
01763 }
01764
01765 #if USE_IS
01766 if(api.m_isDict) {
01767 ISInfoInt binNumber(0);
01768 api.m_isDict->insert("SCTAPIServer.currentBin", binNumber);
01769
01770 ISInfoInt maxNumber(finalBin);
01771 api.m_isDict->insert("SCTAPIServer.maxBin", maxNumber);
01772 }
01773 #endif
01774 }
01775
01776 void ScanControlRODHisto::reportTimeout() {
01777 cout << "Histogram polling timeout\n";
01778
01779 RodLabel minROD;
01780 if(scanEx->rodInfo.size() > 0) {
01781 minROD = scanEx->rodInfo.begin()->first;
01782 }
01783
01784 cout << "Expecting: " << finalBin << " " << finalTrigger << endl;
01785
01786
01787 for(ScanEx::RodInfoMap::const_iterator ri = scanEx->rodInfo.begin();
01788 ri != scanEx->rodInfo.end();
01789 ri++) {
01790 const RodLabel &rodLabel = ri->first;
01791 cout << " ROD (" << rodLabel.partition << ", " << rodLabel.crate << ", " << rodLabel.rod << "): ";
01792 cout << " Event " << lastEvent[rodLabel] << " Bin " << lastBin[rodLabel] << "\n";
01793
01794 if(lastEvent[rodLabel] < lastEvent[minROD]) {
01795 minROD = rodLabel;
01796 } else if(lastEvent[rodLabel] == lastEvent[minROD] && lastBin[rodLabel] < lastBin[minROD]) {
01797 minROD = rodLabel;
01798 }
01799 }
01800
01801 if(api.mrs) {
01802 *api.mrs << "SCAN_ABORTED" << MRS_ERROR
01803 << MRS_PARAM<int>("partition", minROD.partition)
01804 << MRS_PARAM<int>("crate", minROD.crate)
01805 << MRS_PARAM<int>("rod", minROD.rod)
01806 << MRS_PARAM<int>("run", scan->getRunNumber())
01807 << MRS_PARAM<int>("scan", scan->getScanNumber())
01808 << MRS_PARAM<int>("bin", lastBin[minROD]) << MRS_PARAM<int>("event", lastEvent[minROD])
01809 << MRS_TEXT("Scan aborted (histogramming stalled)") << ENDM;
01810 }
01811 }
01812
01813 void ScanControlRODHisto::nextBin() {
01814
01815 if(findNextSection()) {
01816 finalTrigger = sectionEndTrigger;
01817 finalBin = sectionEndBin;
01818 return;
01819 }
01820
01821 for(ScanEx::RodInfoMap::const_iterator ri = scanEx->rodInfo.begin();
01822 ri != scanEx->rodInfo.end();
01823 ri++) {
01824 const RodLabel &rod = ri->first;
01825
01826 cout << "New histogram control task...\n";
01827
01828 boost::shared_ptr<PrimListWrapper> primList(new PrimListWrapper(1));
01829 api.startHistogramTask(*scan, *scanEx, rod,
01830 sectionStartBin, 1 + sectionEndBin - sectionStartBin, sectionEndTrigger,
01831 primList);
01832
01833 api.sendPrimList(rod.partition, rod.crate, rod.rod, primList);
01834 int responseCode = api.awaitResponse(rod.partition, rod.crate, rod.rod, 5);
01835
01836 if(responseCode != 0) {
01837 cout << "Histogram primitive failed! (ROD " << rod.rod << ")\n";
01838 throw SctApiException("Histogram primitive failed! (ROD " + boost::lexical_cast<string>(rod.rod) + ")");
01839 }
01840 }
01841 }
01842
01843 bool ScanControlRODHisto::findNextSection() {
01844
01845 Scan::TrigPoints trigPoints = scan->getVariableTrigs();
01846
01847 unsigned int i = sectionEndBin + 1;
01848
01849 if(i==trigPoints.size()) {
01850
01851
01852 return true;
01853 }
01854
01855 UINT32 initialNTrigs = trigPoints[i];
01856
01857 while(i<trigPoints.size() && trigPoints[i] >= initialNTrigs)
01858 i ++;
01859
01860 bool done = false;
01861
01862 sectionStartBin = 0;
01863 sectionEndBin = i - 1;
01864
01865 if(i == trigPoints.size()) {
01866 sectionEndTrigger = scan->getVariableTrigs()[i-1];
01867 } else {
01868 sectionEndTrigger = scan->getVariableTrigs()[i-1] - scan->getVariableTrigs()[i];
01869
01870
01871
01872
01873 }
01874
01875 #if 0
01876
01877 unsigned int i = sectionEndBin + 1;
01878 UINT32 initialNTrigs = trigPoints[i];
01879 while(i<trigPoints.size() && trigPoints[i] == initialNTrigs)
01880 i++;
01881
01882 sectionStartBin = sectionEndBin + 1;
01883 sectionEndBin = i - 1;
01884 sectionEndTrigger = scan->getVariableTrigs()[i-1];
01885
01886 done = false;
01887 #endif
01888
01889 cout << "Next sectionStartBin = " << sectionStartBin << " sectionEndBin = " << sectionEndBin << " sectionEndTrigger = " << sectionEndTrigger << endl;
01890
01891 return done;
01892 }
01893
01894 bool ScanControlRODHisto::checkScanComplete(bool &progressMade, bool &newBin) {
01895 if(aborting) {
01896 return true;
01897 }
01898
01899 progressMade = false;
01900 newBin = false;
01901
01902 bool result = true;
01903
01904 int totalBin = 0;
01905
01906 map<RodLabel, bool> rodNewBinMap;
01907
01908 for(ScanEx::RodInfoMap::const_iterator ri = scanEx->rodInfo.begin();
01909 ri != scanEx->rodInfo.end();
01910 ri++) {
01911 const RodLabel &rodLabel = ri->first;
01912
01913 bool rodNewBin = false;
01914
01915 if(!checkScanCompleteROD(rodLabel, progressMade, rodNewBin, totalBin)) {
01916 result = false;
01917 }
01918
01919 rodNewBinMap[rodLabel] = rodNewBin;
01920 }
01921
01922
01923 newBin = true;
01924 for(map<RodLabel, bool>::const_iterator mapIter = rodNewBinMap.begin();
01925 mapIter != rodNewBinMap.end();
01926 mapIter++) {
01927 if(mapIter->second == false) {
01928 newBin = false;
01929 } else {
01930 cout << "New bin requested by ROD (" << mapIter->first.partition << ", " << mapIter->first.crate << ", " << mapIter->first.rod << ")\n";
01931 }
01932 }
01933
01934 if(progressMade) {
01935 int progressBin = totalBin / scanEx->rodInfo.size();
01936
01937 #if USE_IS
01938 if(api.m_isDict) {
01939 ISInfoInt binNumber(progressBin);
01940 api.m_isDict->update("SCTAPIServer.currentBin", binNumber);
01941 }
01942 #endif
01943 }
01944
01945 return result;
01946 }
01947
01948 void ScanControlRODHisto::abort() {
01949 aborting = true;
01950 }
01951
01952 #warning "32 bit version unreliable!!"
01953 unsigned int ScanControlRODHisto::getEventCounter(const RodLabel &rodLabel, int slave, bool fromMaster) {
01954 if(fromMaster) {
01955
01956 unsigned long reg = api.dspSingleRead(rodLabel.partition, rodLabel.crate, rodLabel.rod,
01957 0x8000002c - (slave & 2) * 2, -1);
01958 unsigned int currEvent = (unsigned int) ((reg >> (16*(slave&1))) & 0xffff);
01959
01960 return currEvent;
01961 } else {
01962
01963 unsigned long reg = api.dspSingleRead(rodLabel.partition, rodLabel.crate, rodLabel.rod,
01964 0x8000002c, slave);
01965 return (unsigned int) reg;
01966 }
01967 }
01968
01969 bool ScanControlRODHisto::checkScanCompleteROD(const RodLabel &rodLabel, bool &progressMade, bool &newBin, int &totalBin) {
01970 int partition = rodLabel.partition;
01971 int crate = rodLabel.crate;
01972 int rod = rodLabel.rod;
01973
01974 int currBin = 0;
01975 int currEvent = 0;
01976
01977
01978 long reg = api.dspSingleRead(partition, crate, rod, 0x80000020, -1);
01979 currBin = (reg & 0xff);
01980
01981 RodScanEx &rodInfo = scanEx->rodInfo[rodLabel];
01982
01983
01984 currEvent = getEventCounter(rodLabel, rodInfo.firstSlave, true);
01985
01986 if(currBin != lastBin[rodLabel]) {
01987 lastBin[rodLabel] = currBin;
01988 lastEvent[rodLabel] = currEvent;
01989 cout << "Next bin " << currBin << "+" << currEvent << " on ROD (" << partition << ", " << crate << ", " << rod << ")\n";
01990
01991 progressMade = true;
01992 } else if(currEvent != lastEvent[rodLabel]) {
01993 lastEvent[rodLabel] = currEvent;
01994 cout << "Next event " << currEvent << " (bin " << currBin << ") on ROD (" << partition << ", " << crate << ", " << rod << ")\n";
01995
01996 progressMade = true;
01997 }
01998
01999 totalBin += currBin;
02000
02001
02002 if(currBin == sectionEndBin && currEvent == sectionEndTrigger) {
02003
02004 newBin = true;
02005
02006
02007 for(int s=0; s<4; s++) {
02008 if(rodInfo.bitFieldDSP & (1<<s)) {
02009 int slaveEvent = getEventCounter(rodLabel, s, true);
02010
02011 if(slaveEvent != sectionEndTrigger) {
02012 cout << " Slave " << s << " completed only " << slaveEvent << "/" << sectionEndTrigger << " triggers\n";
02013 newBin = false;
02014 }
02015 }
02016 }
02017 } else if(currBin == sectionEndBin && currEvent == (sectionEndTrigger%65536)) {
02018
02019
02020
02021 if(!progressMade) {
02022
02023 newBin = true;
02024 }
02025 }
02026
02027 if(((currBin == finalBin) && (currEvent == finalTrigger))
02028 || ((currBin == finalBin) && (currEvent == (finalTrigger%65536)) && !progressMade)) {
02029
02030
02031 lastEvent[rodLabel] = finalTrigger;
02032
02033
02034 if(api.mrs) {
02035 *api.mrs << "HISTO_SUCCESS" << MRS_DIAGNOSTIC << MRS_QUALIF("SCTAPI")
02036 << MRS_PARAM<int>("partition", rodLabel.partition)
02037 << MRS_PARAM<int>("crate", rodLabel.crate)
02038 << MRS_PARAM<int>("rod", rodLabel.rod)
02039 << MRS_TEXT("Histogramming successfully complete")
02040 << ENDM;
02041 }
02042
02043 cout << "Histogramming completed successfully\n";
02044
02045 return true;
02046 }
02047
02048 return false;
02049 }
02050
02051 void ScanControlRODHisto::finishHistogram(bool success) {
02052 time_t scanEnd = time(0);
02053
02054 scan->setEndTime(second_clock::universal_time());
02055
02056 if(checkDebugOption(DEBUG_SCAN_USE_ASSEMBLER)) {
02057 for(ScanEx::RodInfoMap::const_iterator ri = scanEx->rodInfo.begin();
02058 ri != scanEx->rodInfo.end();
02059 ri++) {
02060 const RodLabel &rod = ri->first;
02061 const RodScanEx &rodInfo = ri->second;
02062
02063 unsigned long SDSP_IDRAM_BASE;
02064 if(api.getRodRevision(rod) >= 0xe) {
02065 SDSP_IDRAM_BASE = 0x10000;
02066 } else {
02067 SDSP_IDRAM_BASE = 0x80000000;
02068 }
02069
02070 for(int s=0; s<numSlaves; s++) {
02071 if(rodInfo.bitFieldDSP & (1<<s)) {
02072 try {
02073 unsigned long val = api.dspSingleBlockRead(rod.partition, rod.crate, rod.rod,
02074 SDSP_IDRAM_BASE + 0x10, s);
02075 cout << "Read from slave " << s << " diag register: 0x" << hex << val
02076 << " which should be 0x" << (1<<19) << dec << endl;
02077
02078
02079 unsigned long newVal = val | 1<<17;
02080 api.dspSingleBlockWrite(rod.partition, rod.crate, rod.rod, SDSP_IDRAM_BASE + 0x10, newVal, s);
02081 val = api.dspSingleBlockRead(rod.partition, rod.crate, rod.rod, SDSP_IDRAM_BASE + 0x10, s);
02082 cout << "Read from slave " << s << " diag register: 0x" << hex << val
02083 << " which should be 0x" << (1<<17) << endl;
02084
02085
02086 newVal = val | 1<<19;
02087 api.dspSingleBlockWrite(rod.partition, rod.crate, rod.rod, SDSP_IDRAM_BASE + 0x10, newVal, s);
02088 val = api.dspSingleBlockRead(rod.partition, rod.crate, rod.rod, SDSP_IDRAM_BASE + 0x10, s);
02089 cout << "Read from slave " << s << " diag register: 0x" << hex << val
02090 << " which should be 0x" << (0) << endl;
02091 } catch(VmeException &v) {
02092 Utility::decodeVme(v);
02093 cerr << "VmeException turning off slave " << s << " cache\n";
02094 }
02095 }
02096 }
02097 }
02098 }
02099
02100
02101
02102 if(!scan->getOption(Scan::DEBUG) || success == true) {
02103 if(api.mrs) {
02104 *api.mrs << "SCAN_FINISHED" << MRS_INFORMATION
02105 << MRS_QUALIF("SCTAPI") << MRS_QUALIF("doScan")
02106 << MRS_TEXT("Scan finished")
02107 << MRS_PARAM<int>("ScanNumber", scan->getScanNumber())
02108 << MRS_PARAM<int>("ScanType1", scan->getScanVariable1())
02109 << MRS_PARAM<int>("ScanType2", scan->getScanVariable2())
02110 << MRS_PARAM<int>("ScanTime", scanEnd - scanStart)
02111 << ENDM;
02112 }
02113
02114 cout << "Histogramming complete, " << (scanEnd - scanStart) << " seconds, tidying up...\n";
02115
02116
02117
02118
02119
02120 cout << "Reading histograms...\n";
02121
02122 readHistograms();
02123
02124 cout << "... histograms read\n";
02125 } else {
02126 if(!scan->getOption(Scan::DEBUG)) {
02127 cout << "Histogram polling failed\n";
02128
02129 if(api.mrs) {
02130 *api.mrs << "SCAN_FAILED" << MRS_INFORMATION
02131 << MRS_QUALIF("SCTAPI") << MRS_QUALIF("doScan")
02132 << MRS_TEXT("Scan polling failed")
02133 << MRS_PARAM<int>("ScanNumber", scan->getScanNumber())
02134 << MRS_PARAM<int>("ScanTime", scanEnd - scanStart)
02135 << ENDM;
02136 }
02137 }
02138 }
02139
02140 if(checkDebugOption(DEBUG_PRINT_CALIB)) {
02141 RodLabel zeroRod = scanEx->rodInfo.begin()->first;
02142
02143 api.print_calib(zeroRod.partition, zeroRod.crate, zeroRod.rod);
02144 }
02145
02146 if(!scan->getOption(Scan::DEBUG)) {
02147 api.stopHistogramming(*scanEx);
02148
02149
02150 postScanModuleSetup();
02151 } else {
02152 if(api.mrs) {
02153 *api.mrs << "SCAN_DEBUG" << MRS_INFORMATION
02154 << MRS_QUALIF("SCTAPI") << MRS_QUALIF("doScan")
02155 << MRS_TEXT("Scan done in debug mode, probably best to be at the command line to sort it out!")
02156 << ENDM;
02157 }
02158
02159 cout << "** In debug mode, you're responsible for terminating histogram and for readout\n";
02160 }
02161
02162 if(checkDebugOption(DEBUG_PRINT_CALIB)) {
02163 RodLabel zeroRod = scanEx->rodInfo.begin()->first;
02164
02165 api.print_calib(zeroRod.partition, zeroRod.crate, zeroRod.rod);
02166 }
02167
02168
02169 scan->print();
02170
02171 #if USE_IS
02172 if(api.m_isDict)
02173 api.m_isDict->remove("SCTAPIServer.scanning");
02174 #endif
02175
02176 if(api.mrs)
02177 *api.mrs << "SCAN_COMPLETE" << MRS_INFORMATION << MRS_QUALIF("SctApi") << MRS_TEXT("Scan has completed") << ENDM;
02178 }
02179
02180 void ScanControlRODHisto::postScanModuleSetup() {
02181 PrimBuilder &builder = PrimBuilder::instance();
02182
02183 if(scan->getScanVariable1() == ST_TOKEN
02184 || scan->getScanVariable1() == ST_BYPASS) {
02185
02186 shared_ptr<PrimListWrapper> chipSeqList(new PrimListWrapper(1));
02187 for(int i=0; i<48; i++) {
02188 builder.writeRegister(chipSeqList, ERROR_MASK(0, i), 10, 1, 0);
02189 builder.writeRegister(chipSeqList, ERROR_MASK(1, i), 10, 1, 0);
02190 }
02191
02192 if(api.synchSendPrimListAllCrates(chipSeqList)) {
02193 cout << "Chip sequence error list failed!\n";
02194 }
02195
02196 cout << "EFB chip sequence detection turned back on\n";
02197 }
02198
02199
02200 {
02201 Trigger::RODTriggers points = scan->getTrigger1()->getRODTriggers();
02202
02203 int triggerCount = 0;
02204
02205 for(unsigned int i=0; i<points.size(); i++) {
02206
02207 if(points[i].first == L1_TRIGGER) {
02208 triggerCount++;
02209 }
02210 }
02211
02212
02213 if(triggerCount > 1 && scan->getOption(Scan::DISTSLAVE) < 3) {
02214 shared_ptr<PrimListWrapper> dblIdCheckList(new PrimListWrapper(1));
02215
02216
02217 for(int f=0; f<48; f++) {
02218
02219 builder.writeRegister(dblIdCheckList, ERROR_MASK(0, f), 5, 1, 0);
02220 builder.writeRegister(dblIdCheckList, ERROR_MASK(1, f), 5, 1, 0);
02221
02222
02223 builder.writeRegister(dblIdCheckList, ERROR_MASK(0, f), 6, 1, 0);
02224 builder.writeRegister(dblIdCheckList, ERROR_MASK(1, f), 6, 1, 0);
02225 }
02226
02227 if(api.synchSendPrimListAllCrates(dblIdCheckList)) {
02228 cout << "Double trigger BC check list failed!\n";
02229 }
02230
02231 cout << "L1 and BCID checks restored after double triggers\n";
02232 }
02233 }
02234
02235
02236
02237 }
02238
02239 bool ScanControlRODHisto::checkDebugOption(int opt) {
02240 return Debug::getInstance()->checkDebugOption((DebugOptions)opt);
02241 }
02242
02243 void ScanControlRODHisto::reportEventErrors() {
02244 api.reportEventErrors();
02245 }
02246
02247 unsigned int ScanControlRODHisto::getProcTime(const RodLabel rlabel, int dsp) {
02248 if(dsp == -1) {
02249 throw SctApiException("Can't getProcTime on MDSP");
02250 } else {
02251 int procTime;
02252
02253 unsigned long SDSP_IDRAM_BASE;
02254 if(api.getRodRevision(rlabel) >= 0xe) {
02255 SDSP_IDRAM_BASE = 0x10000;
02256 } else {
02257 SDSP_IDRAM_BASE = 0x80000000;
02258 }
02259
02260 unsigned long length;
02261 unsigned long *regs = api.dspBlockRead(rlabel.partition, rlabel.crate, rlabel.rod,
02262 SDSP_IDRAM_BASE + 0x10, 20, dsp, length);
02263
02264 if(regs) {
02265 long reg;
02266
02267
02268 reg = regs[6];
02269 procTime = ((reg >> 16) & 0xffff);
02270 } else {
02271 throw SctApiException("Failed to read getProcTime from DSP");
02272 }
02273
02274 return procTime;
02275 }
02276 }
02277
02278 ScanControlRODHisto::TrapBuffers ScanControlRODHisto::getTrapBuffers(const RodLabel rlabel, int dsp) {
02279 if(dsp == -1) {
02280 throw SctApiException("Invaled dsp passed to getTrapBuffers");
02281 } else {
02282 int ihead, itail, xhead, xtail;
02283
02284 unsigned long SDSP_IDRAM_BASE;
02285 if(api.getRodRevision(rlabel) >= 0xe) {
02286 SDSP_IDRAM_BASE = 0x10000;
02287 } else {
02288 SDSP_IDRAM_BASE = 0x80000000;
02289 }
02290
02291 unsigned long length;
02292 unsigned long *regs = api.dspBlockRead(rlabel.partition, rlabel.crate, rlabel.rod,
02293 SDSP_IDRAM_BASE + 0x10, 20, dsp, length);
02294
02295 if(regs) {
02296 long reg;
02297
02298
02299 reg = regs[1];
02300 itail = ((reg & 0xff0000) >> 16);
02301 xtail = ((reg & 0xff000000) >> 24);
02302
02303
02304 reg = regs[2];
02305 ihead = ((reg & 0xff0000) >> 16);
02306 xhead = ((reg & 0xff000000) >> 24);
02307 } else {
02308 throw SctApiException("Failed to read DSP for getTrapBuffers");
02309 }
02310
02311 return make_pair(make_pair(ihead, itail), make_pair(xhead, xtail));
02312 }
02313 }
02314
02315 void ScanControlRODHisto::dumpHistoStatus(const RodLabel rlabel, int dsp) {
02316 if(dsp == -1) {
02317 const unsigned long MDSP_IDRAM_BASE = 0x80000000;
02318
02319
02320 long reg = api.dspSingleRead(0, 0, 0, MDSP_IDRAM_BASE + 0x20, -1);
02321 cout << "Bin: " << (reg & 0xff)
02322 << " Cal: " << ((reg & 0xff00) >> 8)
02323 << " Errs: " << ((reg & 0xffff0000) >> 16) << endl;
02324
02325
02326 reg = api.dspSingleRead(0, 0, 0, MDSP_IDRAM_BASE + 0x24, -1);
02327 cout << "avg. trans " << (reg & 0xff)
02328 << " avg. len " << ((reg & 0xff00) >> 8)
02329 << " avg. proc. " << ((reg & 0xffff0000) >> 16) << endl;
02330
02331
02332 reg = api.dspSingleRead(0, 0, 0, MDSP_IDRAM_BASE + 0x2c, -1);
02333 cout << "Slave 0: " << (reg & 0xffff)
02334 << " Slave 1: " << ((reg & 0xffff0000) >> 16) << endl;
02335
02336
02337 reg = api.dspSingleRead(0, 0, 0, MDSP_IDRAM_BASE + 0x28, -1);
02338 cout << "Slave 2: " << (reg & 0xffff)
02339 << " Slave 3: " << ((reg & 0xffff0000) >> 16) << endl;
02340 } else {
02341 unsigned long SDSP_IDRAM_BASE;
02342 if(api.getRodRevision(rlabel) >= 0xe) {
02343 SDSP_IDRAM_BASE = 0x10000;
02344 } else {
02345 SDSP_IDRAM_BASE = 0x80000000;
02346 }
02347
02348 unsigned long length;
02349 unsigned long *regs = api.dspBlockRead(rlabel.partition, rlabel.crate, rlabel.rod,
02350 SDSP_IDRAM_BASE + 0x10, 20, dsp, length);
02351
02352 if(regs) {
02353 long reg;
02354
02355 cout << "TrapStatus: \n";
02356
02357
02358
02359 reg = regs[1];
02360 int words = ((reg &0xffff) >> 0);
02361 int itail = ((reg & 0xff0000) >> 16);
02362 int xtail = ((reg & 0xff000000) >> 24);
02363
02364 cout << "Event word count: " << words;
02365 cout << " IFrame tail: " << itail;
02366 cout << " XFrame tail: " << xtail << endl;
02367
02368
02369 reg = regs[2];
02370 int ihead = ((reg & 0xff0000) >> 16);
02371 int xhead = ((reg & 0xff000000) >> 24);
02372 cout << " IFrame head: " << ihead;
02373 cout << " XFrame head: " << xhead << endl;
02374
02375
02376 reg = regs[17];
02377 cout << "Trap Command/Status: "
02378 << ((reg & 0x1)?"Trailer ":"")
02379 << ((reg & 0x2)?"Transmit ":"")
02380 << ((reg & 0x4)?"Header ":"")
02381 << ((reg & 0x4)?"ISR active ":"");
02382 cout << ((reg & 0x10)?"\"Data Error\" ":"")
02383 << ((reg & 0x20)?"\"Header Error\" ":"")
02384 << ((reg & 0x40)?"\"Trailer Error\" ":"")
02385 << ((reg & 0x80)?"\"Link Error\" ":"");
02386 cout << ((reg & 0x100)?"\"Error\" ":"")
02387 << ((reg & 0x200)?"\"Overflow(old)\" ":"")
02388 << ((reg & 0x800)?"\"ISR pending\" ":"");
02389 cout << ((reg & 0x4000)?"\"Overflow error\" ":"")
02390 << ((reg & 0x8000)?"\"Overflow\" ":"");
02391 cout << endl;
02392
02393 int errCount = ((reg >> 16) & 0xff);
02394 cout << "\"Error count\": " << errCount << endl;
02395 int evCount = ((reg >> 24) & 0xff);
02396 cout << "\"Event count\": " << evCount << endl;
02397
02398
02399 reg = regs[4];
02400 int currentBin = (reg & 0xff);
02401 cout << "Bin: " << currentBin
02402 << " Cal: " << ((reg & 0x1f00) >> 8)
02403 << ((reg & 0x800)?" Cal enabled":"")
02404 << ((reg & 0x1000)?" New bin":"")
02405 << ((reg & 0x20000)?" New cal":"") << endl;
02406
02407
02408 reg = regs[5];
02409 int numEvents = reg;
02410 cout << "Num events: " << numEvents << endl;
02411
02412
02413 reg = regs[6];
02414 cout << "Histogram status: 0x" << hex << (reg & 0xffff) << dec << " " << ((reg & 0x1)?"Ready ":"")
02415 << ((reg & 0x2)?"Expecting ":"")
02416 << ((reg & 0x4)?"Processing ":"")
02417 << ((reg & 0x8)?"Done ":"") << endl;
02418
02419 int procTime = ((reg >> 16) & 0xffff);
02420 cout << "Bin err: " << ((reg >> 8) & 0xff)
02421 << " proc time: " << ((reg >> 16) & 0xffff) << endl;
02422
02423
02424 reg = regs[7];
02425 int evRecvd = reg;
02426 cout << "Events recvd: " << evRecvd << endl;
02427
02428 ofstream statusOut("TIMStatus.txt", ios_base::out | ios_base::app);
02429 statusOut << currentBin << "\t"
02430 << ihead << "\t" << itail << "\t"
02431 << xhead << "\t" << xtail << "\t"
02432 << errCount << "\t" << evCount << "\t"
02433 << evRecvd << "\t" << words << "\t" << procTime << endl;
02434 }
02435 }
02436 }
02437
02438 ScanControlTIMHisto::ScanControlTIMHisto(SctApi &api, boost::shared_ptr<Scan> aScan, boost::shared_ptr<ScanEx> aScanEx) : ScanControlRODHisto(api, aScan, aScanEx), binCount(0) {
02439 }
02440
02441 void ScanControlTIMHisto::startHistogramming() {
02442
02443 api.timWriteRegister(0, 0, 0x14, 0x3000);
02444
02445 shared_ptr<PrimListWrapper> preTimList(new PrimListWrapper(4));
02446 PrimBuilder::instance().rodMode(preTimList, DATA_TAKING_MODE, 0, 1, 0, 0, 1);
02447
02448 PrimBuilder::instance().writeRegister(preTimList, RTR_CMND_STAT, 7, 1, 1);
02449
02450 for(int f=0; f<8; f++) {
02451
02452
02453 PrimBuilder::instance().writeRegister(preTimList, DM_DFLT_LUT(f), 0, 16, 0x0);
02454 }
02455
02456
02457
02458
02459
02460
02461 cout << "Sending pre TIM setup list\n";
02462 api.synchSendPrimListAllCrates(preTimList);
02463 cout << " done sending pre TIM setup list\n";
02464
02465 hex(cout);
02466 cout << "0x" << RTR_CMND_STAT << ": 0x" << api.readRODRegister(0, 0, 0, RTR_CMND_STAT) << endl;
02467 cout << "0x" << ERROR_MASK(0, 0) << ": 0x" << api.readRODRegister(0, 0, 0, ERROR_MASK(0, 0)) << endl;
02468 cout << "0x" << ERROR_MASK(1, 0) << ": 0x" << api.readRODRegister(0, 0, 0, ERROR_MASK(1, 0)) << endl;
02469 cout << "0x" << DM_DFLT_LUT(0) << ": 0x" << api.readRODRegister(0, 0, 0, DM_DFLT_LUT(0)) << endl;
02470 cout << "0x" << DM_DFLT_LUT(1) << ": 0x" << api.readRODRegister(0, 0, 0, DM_DFLT_LUT(1)) << endl;
02471 dec(cout);
02472
02473 if(checkDebugOption(DEBUG_TIM_SCAN_STATUS)) {
02474
02475 ofstream statusOut("TIMStatus.txt");
02476 statusOut << "bin\tihead\titail\txhead\txtail\terrCnt\tevCount\tevRecvd\twords\tprocTime\n";
02477 }
02478 }
02479
02480 void ScanControlTIMHisto::nextBin() {
02481 cout << "TIM histo, next bin\n";
02482
02483 api.modifyABCDVarROD(scan->getScanVariable1(), scan->getScanPoints1()[binCount], SCTAPI_BANK_SCAN);
02484 api.sendAllABCDModules(SCTAPI_BANK_SCAN);
02485
02486
02487 shared_ptr<PrimListWrapper> setTriggerList(new PrimListWrapper(4));
02488 PrimBuilder::instance().setTrigger(setTriggerList, binCount, Utility::translateBank(SCTAPI_BANK_SCAN));
02489
02490 shared_ptr<PrimListWrapper> binTimList(new PrimListWrapper(4));
02491
02492
02493 for(int s=0; s<4; s++) {
02494 PrimBuilder::instance().slavePrimList(binTimList, setTriggerList,
02495 s, 1, 0);
02496 }
02497
02498 PrimBuilder::instance().rodMode(binTimList, 0x20000, 0, 1, 0, 0, 1);
02499 PrimBuilder::instance().writeRegister(binTimList, RTR_CMND_STAT, 7, 1, 1);
02500
02501 cout << "Sending TIM setup list\n";
02502 api.synchSendPrimListAllCrates(binTimList);
02503 cout << " done sending TIM setup list\n";
02504
02505 if(checkDebugOption(DEBUG_TIM_SCAN_STATUS)) {
02506 cout << "******************* Pre triggers status ********************\n";
02507 dumpHistoStatus(RodLabel(), 0);
02508 }
02509
02510 const list<CrateLabel> crates = api.listCrates();
02511 for(list<CrateLabel>::const_iterator i = crates.begin();
02512 i != crates.end();
02513 i ++){
02514 unsigned int partition = i->partition;
02515 unsigned int crate = i->crate;
02516 api.timSoftReset(partition, crate);
02517 api.timBCReset(partition, crate);
02518 }
02519
02520 Scan::TrigPoints trigs = scan->getVariableTrigs();
02521
02522 cout << "Sending " << trigs[binCount] << " triggers to one crate " << endl;
02523
02524 switch(scan->getOption(Scan::TIM)) {
02525 case 1:
02526
02527 api.sendTimBurst(0, 0, trigs[binCount]);
02528 break;
02529 case 2:
02530
02531 for(unsigned int i=0; i<trigs[binCount]; i++) {
02532 api.timL1A(0, 0);
02533
02534 TrapBuffers tb = getTrapBuffers(RodLabel(), 0);
02535
02536 if (!(tb.first.first == tb.first.second && tb.second.first == tb.second.second))
02537 sleep(1);
02538 }
02539 break;
02540 case 3:
02541
02542
02543 {
02544 unsigned int sentTriggers = 0;
02545 const unsigned int trigsPerBurst = 20;
02546
02547 while(sentTriggers < trigs[binCount]) {
02548 if(sentTriggers % 1000 < trigsPerBurst) {
02549 cout << "Done " << sentTriggers << " triggers\n";
02550 if(checkDebugOption(DEBUG_TIM_SCAN_STATUS))
02551 dumpHistoStatus(RodLabel(), 0);
02552 }
02553 int ntrigs = min(trigs[binCount]-sentTriggers, trigsPerBurst);
02554 api.sendTimBurst(0, 0, ntrigs);
02555 sentTriggers += ntrigs;
02556
02557
02558 TrapBuffers tb = getTrapBuffers(RodLabel(), 0);
02559
02560 TrapBuffers oldtb;
02561 if (!(tb.first.first == tb.first.second && tb.second.first == tb.second.second))
02562 do {
02563 oldtb = tb;
02564 usleep(trigsPerBurst * 10);
02565 tb = getTrapBuffers(RodLabel(), 0);
02566
02567 if(tb.first.first == tb.first.second && tb.second.first == tb.second.second) break;
02568 if(tb == oldtb) break;
02569 } while(1);
02570 }
02571 }
02572 break;
02573 case 4:
02574
02575
02576 {
02577 unsigned int sentTriggers = 0;
02578
02579 api.timL1A(0, 0);
02580 sentTriggers ++;
02581
02582
02583
02584
02585 unsigned int procTime = getProcTime(RodLabel(), 0);
02586 double timFrequency = 0.25 * 1e6/procTime;
02587
02588 api.timSetFrequency(0, 0, min(6.0, timFrequency/1000), 0);
02589
02590 cout << "*** Proc Time for 1 trigger was " << procTime << " setting frequency to " << timFrequency << "Hz\n";
02591
02592 procTime = getProcTime(RodLabel(), 0);
02593 timFrequency = 0.25 * 1e6/procTime;
02594 api.timSetFrequency(0, 0, min(6.0, timFrequency/1000), 0);
02595
02596 cout << "*** Proc Time after 10 trigs was " << procTime << " setting frequency to " << timFrequency << "Hz\n";
02597
02598 if(trigs[binCount] > sentTriggers)
02599 api.sendTimBurst(0, 0, trigs[binCount]-sentTriggers);
02600
02601 if(checkDebugOption(DEBUG_TIM_SCAN_STATUS)) {
02602 cout << "******************* Post triggers status ********************\n";
02603 dumpHistoStatus(RodLabel(), 0);
02604 }
02605
02606 TrapBuffers tb = getTrapBuffers(RodLabel(), 0);
02607
02608 TrapBuffers oldtb;
02609 if (!(tb.first.first == tb.first.second && tb.second.first == tb.second.second))
02610 do {
02611 oldtb = tb;
02612 sleep(1);
02613 tb = getTrapBuffers(RodLabel(), 0);
02614
02615 if(tb.first.first == tb.first.second && tb.second.first == tb.second.second) break;
02616 if(tb == oldtb) break;
02617 } while(1);
02618 break;
02619 }
02620 }
02621
02622 if(checkDebugOption(DEBUG_TIM_SCAN_STATUS)) {
02623 cout << "******************* Post triggers status 2 ******************\n";
02624 dumpHistoStatus(RodLabel(), 0);
02625 }
02626
02627
02628
02629
02630
02631
02632 binCount ++;
02633 }
02634
02635
02636
02637 bool ScanControlTIMHisto::checkScanCompleteROD(const RodLabel &rodLabel, bool &progressMade, bool &newBin, int &totalBin) {
02638
02639 cout << "Checking TIM scan complete\n";
02640
02641 progressMade = true;
02642
02643
02644 newBin = true;
02645
02646 totalBin += binCount-1;
02647
02648
02649
02650 if((binCount-1 >= finalBin)) {
02651 return true;
02652 }
02653
02654 return false;
02655 }
02656
02657
02658
02659
02660
02661 }