Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Data Structures | File List | Namespace Members | Data Fields | Related Pages

SctApiRaw.cxx

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

Generated on Fri Sep 16 18:01:58 2005 for SCT DAQ/DCS Software - C++ by doxygen 1.3.5