/******************************************************************************* * TmsTestData.cpp TMS Test code for a Data Client * T.Barnaby, BEAM Ltd, 2007-10-02 ******************************************************************************* * * This is a simpe test program to fetch data from the TMS system. * This example fetches the Sigma/DeltaX/DeltaY levels from all * pickups. */ #include <iostream> #include <stdio.h> #include <unistd.h> #include <getopt.h> #include <sys/time.h> #include <BFile.h> #include <TmsD.h> #include <TmsC.h> #define DEBUG 0 #if DEBUG #define dprintf(fmt, a...) printf(fmt, ##a); #else #define dprintf(fmt, a...) #endif using namespace Tms; using namespace std; const char* cycleType = "SimBeam3"; const char* testSignalFileName = "beam3-437000-8.psd"; int quiet = 0; // Get current time in seconds double getTime() { struct timeval tp; gettimeofday(&tp, NULL); return ((double) tp.tv_sec + (double) tp.tv_usec * 1e-6); } void dumpData(Data& data, int dump){ BFile file(BString("data") + dump + ".txt", "w"); int n; for(n = 0; n < data.numValues; n++){ file.printf("%d %d %d\n", n, data.dataValues[n].sigma, data.dataValues[n].time); } } BError dataCheck(Data& data){ BError err; BUInt32 c; BUInt32 s; BUInt32 b; BUInt32 bunchValues[] = {8651, 7151, 6070, 4937}; BUInt32 timeStart = 400; BUInt32 numSamples; BUInt32 numSamplesTest; BUInt32 o; BUInt32 t; int numErrorSigma = 0; int numErrorTime = 0; int errorChannel = -1; int errorSample = -1; static int dump = 0; numSamples = data.numValues / data.numBunches / data.numChannels; // Don't look at the last ms of sample sas a harmonic change may have occurred numSamplesTest = numSamples - 437; dprintf("CheckData: NumValues: %d NumChannels: %d NumBunches: %d NumSamples: %d\n", data.numValues, data.numChannels, data.numBunches, numSamples); for(c = 0; c < data.numChannels; c++){ for(s = 0; s < numSamplesTest; s++){ for(b = 0; b < data.numBunches; b++){ o = (c * numSamples * data.numBunches) + (s * data.numBunches) + b; t = timeStart + (s / 437); // printf("%d,%d,%d: %d %d\n", c, b, s, data.dataValues[o].sigma, data.dataValues[o].time); if((data.dataValues[o].sigma > (bunchValues[b] * 1.1)) || data.dataValues[o].sigma < (bunchValues[b] * 0.9)){ dprintf("Sigma out of range: (%d.%d.%d) %d should be: %d\n", c, s, b, data.dataValues[o].sigma, bunchValues[b]); numErrorSigma++; if(errorChannel == -1) errorChannel = c; if(errorSample == -1) errorSample = o; } if((data.dataValues[o].time > (t * 1.1)) || (data.dataValues[o].time < (t * 0.9))){ dprintf("Time out of range: (%d.%d.%d) %u (%x) should be: %u (%x)\n", c, s, b, data.dataValues[o].time, data.dataValues[o].time, t, t); numErrorTime++; if(errorChannel == -1) errorChannel = c; if(errorSample == -1) errorSample = o; } } } } if(numErrorSigma || numErrorTime){ printf("DataErrors: Dump: %d Sigma: %u Time: %u Channel: %u Sample: %d\n", dump, numErrorSigma, numErrorTime, errorChannel, errorSample); dumpData(data, dump++); err.set(1, "Data errors"); } return err; } // Function to get information on Cycle BError tmsInformation(TmsControl& tmsControl, TmsProcess& tmsProcess){ BError err; UInt32 cn; BString ct; CycleInformation info; BIter i; // Get current cycle info if(err = tmsProcess.getCycleInfo(cn, ct)){ return err.set(1, BString("Error: Getting Cycle Number: ") + err.getString()); } printf("CycleNumber: %u CycleType: %s\n", cn, ct.retStr()); if(err = tmsProcess.getCycleInformation(cn, info)){ return err.set(1, BString("Error: Getting Cycle Information: ") + err.getString()); } printf("CycleNumber: %u\n", info.cycleNumber); printf("CycleType: %s\n", info.cycleType.retStr()); for(info.periods.start(i); !info.periods.isEnd(i); info.periods.next(i)){ printf("CyclePeriod: %u StartTime: %u EndTime: %u NumBunches: %u NumValues: %u\n", info.periods[i].cyclePeriod, info.periods[i].startTime, info.periods[i].endTime, info.periods[i].numBunches, info.periods[i].numValues); } return err; } // Function to set system to use simulated timing and data BError tmsSimData(TmsControl& tmsControl, TmsProcess& tmsProcess, int simDataAll){ BError err; UInt32 cn; BString ct; ConfigInfo configInfo; PupeConfig pupeConfig; unsigned int n; BArray<UInt32> data; BFile file; int nb; // Read the test signal file if(err = file.open(testSignalFileName, "r")){ if(err = file.open(BString("/usr/tms/data/") + testSignalFileName, "r")){ return err.set(1, BString("Error: Opening file: ") + testSignalFileName); } } data.resize(1024); if((nb = file.read(&data[0], 1024 * sizeof(UInt32))) <= 0){ return err.set(1, BString("Error: Reading 1024 32bit data items from file: ") + testSignalFileName); } data.resize(nb / sizeof(UInt32)); // Sets the CycleType to match the data // Get current cycle info dprintf("Get Cycle Info\n"); if(err = tmsProcess.getCycleInfo(cn, ct)){ return err.set(1, BString("Error: Getting Cycle Number: ") + err.getString()); } // Set NextCycle type dprintf("Set Next Cycle Info\n"); if(err = tmsControl.setNextCycle(cn + 1, cycleType)){ return err.set(1, BString("Error: Setting Next Cycle: ") + err.getString()); } dprintf("Get Configuration\n"); if(err = tmsControl.getConfiguration(configInfo)){ return err.set(1, BString("Error: getting configuration TMS: ") + err.getString()); } // Sets up the simulated timing system pupeConfig.adcSysclkSync = 0; // pupeConfig.internalTimingMask = 0x7D; // Expects CYCLE_START signal pupeConfig.internalTimingMask = 0x7f; // All internal event signals pupeConfig.disableBlr = 0; if(simDataAll){ for(n = 0; n < configInfo.puReferences.size(); n++){ pupeConfig.internalTimingMask = 0x7f; // All internal event signals dprintf("Set PupeConfig: Channel: %d\n", n + 1); if(err = tmsControl.setPupeConfig(configInfo.puReferences[n], pupeConfig)){ return err.set(1, err.getString()); } } } else { for(n = 0; n < configInfo.puReferences.size(); n++){ if(((n / 3) == 4) || ((n / 3) == 9) || ((n / 3) == 13)){ pupeConfig.internalTimingMask = 0x7f; // All internal event signals } else { pupeConfig.internalTimingMask = 0x01; // Internal SYS_CLOCK signal } dprintf("Set PupeConfig: Channel: %d\n", n + 1); if(err = tmsControl.setPupeConfig(configInfo.puReferences[n], pupeConfig)){ return err.set(1, err.getString()); } } } for(n = 0; n < configInfo.puReferences.size(); n++){ dprintf("Set Test Data Channel: %d\n", n + 1); if(err = tmsControl.setTestData(configInfo.puReferences[n], 1, data)){ return err.set(1, err.getString()); } } return err; } // Function to read some data BError tmsTestSingle(TmsControl& tmsControl, TmsProcess& tmsProcess, int numSamples, int check, int channel){ BError err; DataInfo dataInfo; UInt32 cn = 0; BString ct; Data data; double timeStart = 0; double t1 = 0; double t2 = 0; double timeEnd = 0; int i; int repeat = 4; double r; if(numSamples == 0) numSamples = 1024000; // Find out the current cycle number and type if(err = tmsProcess.getCycleInfo(cn, ct)){ return err.set(1, BString("Error: Getting Cycle Number: ") + err.getString()); } if(!quiet) printf("Getting data from pick-up %d for cycle: %u\n", channel, cn); for(i = 0; i < repeat; i++){ dataInfo.cycleNumber = cn; dataInfo.channel = channel; dataInfo.cyclePeriod = CyclePeriodEvent0; dataInfo.startTime = 0; dataInfo.orbitNumber = 0; dataInfo.bunchNumber = 0; dataInfo.function = DataFunctionRaw; dataInfo.argument = 0; dataInfo.numValues = numSamples; dataInfo.limitData = 1; t1 = getTime(); if(err = tmsProcess.getData(dataInfo, data)){ return err.set(1, BString("Error: Getting Data: ") + err.getString()); } t2 = getTime(); if(timeStart == 0.0) timeStart = t2; if(!quiet) printf("CycleNum: %d Channel: %d Read: %d Time: %f\n", cn, dataInfo.channel, data.numValues, t2 - t1); if(check){ if(err = dataCheck(data)) return err; } } numSamples = data.numValues; timeEnd = t2; r = (sizeof(DataValue) * numSamples * (repeat - 1)) / (timeEnd - timeStart); if(!quiet) printf("Time to fetch data: %f DataRate: %fMBytes/sec\n", timeEnd - timeStart, r / (1024*1024)); return err; } // Function to read some data BError tmsTestAllManual(TmsControl& tmsControl, TmsProcess& tmsProcess, int check){ BError err; DataInfo dataInfo; UInt32 cn = 0; BString ct; UInt32 numChans = 40; UInt32 n; Data data[numChans]; Data dataAll; double timeStart = 0; double t1 = 0; double t2 = 0; double timeEnd = 0; int i; int repeat = 4; int numSamples = 20000; double r; ConfigInfo configInfo; // Get configuration if(err = tmsControl.getConfiguration(configInfo)){ return err.set(1, BString("Error: Getting Configuration: ") + err.getString()); } numChans = configInfo.puReferences.size(); // Find out the current cycle number and type if(err = tmsProcess.getCycleInfo(cn, ct)){ return err.set(1, BString("Error: Getting Cycle Number: ") + err.getString()); } if(!quiet) printf("Getting data from all pick-ups for cycle: %u\n", cn); for(i = 0; i < repeat; i++){ for(n = 0; n < numChans; n += 1){ dataInfo.cycleNumber = cn; dataInfo.channel = 1 + n; dataInfo.cyclePeriod = CyclePeriodEvent0; dataInfo.startTime = 0; dataInfo.orbitNumber = 0; dataInfo.bunchNumber = 0; dataInfo.function = DataFunctionRaw; dataInfo.argument = 0; dataInfo.numValues = numSamples; dataInfo.limitData = 1; t1 = getTime(); if(err = tmsProcess.getData(dataInfo, data[n])){ return err.set(1, BString("Error: Getting Data: ") + err.getString()); } t2 = getTime(); if(timeStart == 0.0) timeStart = t2; if(!quiet) printf("CycleNum: %d Channel: %d Time: %f\n", cn, 1 + n, t2 - t1); if(check){ #ifndef ZAP if(err = dataCheck(data[n])) return err; #else dataCheck(data[n]); #endif } // usleep(100000); } } numSamples = data[0].numValues; timeEnd = getTime(); r = (sizeof(DataValue) * numSamples * numChans * (repeat - 1)) / (timeEnd - timeStart); if(!quiet) printf("Time to fetch data: %f DataRate: %fMBytes/sec\n", timeEnd - timeStart, r / (1024*1024)); return err; } // Function to reads some data BError tmsTestAll(TmsControl& tmsControl, TmsProcess& tmsProcess, int numSamples, int check){ BError err; DataInfo dataInfo; UInt32 cn = 0; BString ct; UInt32 numChans = 40; UInt32 n; Data data; double timeStart = 0; double t1 = 0; double t2 = 0; double timeEnd = 0; int i; int repeat = 4; double r; ConfigInfo configInfo; if(numSamples == 0) numSamples = 300000; // Get configuration if(err = tmsControl.getConfiguration(configInfo)){ return err.set(1, BString("Error: Getting Configuration: ") + err.getString()); } numChans = configInfo.puReferences.size(); // Find out the current cycle number and type if(err = tmsProcess.getCycleInfo(cn, ct)){ return err.set(1, BString("Error: Getting Cycle Number: ") + err.getString()); } if(!quiet) printf("Getting data from %d pick-ups for cycle: %u\n", configInfo.puReferences.size(), cn); for(i = 0; i < repeat; i++){ dataInfo.cycleNumber = cn; dataInfo.channel = 0; dataInfo.cyclePeriod = CyclePeriodEvent0; dataInfo.startTime = 0; dataInfo.orbitNumber = 0; dataInfo.bunchNumber = 0; dataInfo.function = DataFunctionRaw; dataInfo.argument = 0; dataInfo.numValues = numSamples; dataInfo.limitData = 1; t1 = getTime(); if(err = tmsProcess.getData(dataInfo, data)){ return err.set(1, BString("Error: Getting Data: ") + err.getString()); } t2 = getTime(); if(timeStart == 0.0) timeStart = t2; if(!quiet) printf("CycleNum: %d Time: %fs NumValues: %d\n", cn, t2 - t1, data.numValues); if(check){ #ifdef ZAP #ifndef ZAP if(err = dataCheck(data)) return err; #else dataCheck(data); #endif #else if(err = dataCheck(data)){ printf("Error: Retry\n"); if(err = tmsProcess.getData(dataInfo, data)){ return err.set(1, BString("Error: Getting Data: ") + err.getString()); } if(err = dataCheck(data)){ printf("Double Error\n"); return err; } } #endif } // cn++; // usleep(100000); } numSamples = data.numValues; timeEnd = t2; r = (sizeof(DataValue) * numSamples * (repeat - 1)) / (timeEnd - timeStart); if(!quiet) printf("Time to fetch data: %f DataRate: %fMBytes/sec\n", timeEnd - timeStart, r / (1024*1024)); return err; } void usage(void) { cerr << "Usage:\ttmsTestData [options] hostname\n"; cerr << " -help - Help on command line parameters\n"; cerr << " -simdata - Set the system to use simulated timing signals and test data\n"; cerr << " -simdataall - Sets all PUPE boards in the system to use simulated timing signals and test data\n"; cerr << " -info - Prints information on the processing cycle\n"; cerr << " -numSamples <n> - The number of samples to read\n"; cerr << " -test <testName> - The Test to be performed: single - single channel all bunches, all - all bunches all channels\n"; cerr << " -check - Check the data for validity\n"; cerr << " -cont - Continuous\n"; cerr << " -quiet - Only print errors\n"; cerr << " -channel <n> - Channel number\n"; } static struct option options[] = { { "?", 0, NULL, 0 }, { "h", 0, NULL, 0 }, { "help", 0, NULL, 0 }, { "simdata", 0, NULL, 0 }, { "simdataall", 0, NULL, 0 }, { "info", 0, NULL, 0 }, { "check", 0, NULL, 0 }, { "cont", 0, NULL, 0 }, { "quiet", 0, NULL, 0 }, { "numSamples", 1, NULL, 0 }, { "test", 1, NULL, 0 }, { "channel", 1, NULL, 0 }, { 0,0,0,0 } }; int main(int argc, char** argv){ BError err; BString hostName = "localhost"; TmsProcess tmsProcess; TmsControl tmsControl; int optIndex = 0; int c; BString s; int simData = 0; int simDataAll = 0; int info = 0; int check = 0; int cont = 0; BString test; int numSamples = 0; int channel = 1; while((c = getopt_long_only(argc, argv, "", options, &optIndex)) == 0){ s = options[optIndex].name; if(s == "help" || s == "h" || s == "?"){ usage(); return 1; } else if(s == "simdata"){ simData = 1; } else if(s == "simdataall"){ simDataAll = 1; } else if(s == "info"){ info = 1; } else if(s == "check"){ check = 1; } else if(s == "cont"){ cont = 1; } else if(s == "quiet"){ quiet = 1; } else if(s == "test"){ test = optarg; } else if(s == "numSamples"){ numSamples = strtol(optarg, 0, 0); } else if(s == "channel"){ channel = strtol(optarg, 0, 0); } else { usage(); return 1; } } if(optind == argc){ usage(); return 1; } hostName = argv[optind++]; // Connect to the Control service if(err = tmsControl.connectService(BString("//") + hostName + "/tmsControl")){ cerr << "Error: " << err.getString() << "\n"; return 1; } // Connect to the Process service if(err = tmsProcess.connectService(BString("//") + hostName + "/tmsProcess")){ cerr << "Error: " << err.getString() << "\n"; return 1; } if(simData || simDataAll){ if(err = tmsSimData(tmsControl, tmsProcess, simDataAll)){ cerr << "Error: " << err.getString() << "\n"; return 1; } if(test != "") sleep(3); } if(info){ if(err = tmsInformation(tmsControl, tmsProcess)){ cerr << "Error: " << err.getString() << "\n"; return 1; } } if(test == "single"){ // Run a normal data gathering cycle as a normal client would. do { if(err = tmsTestSingle(tmsControl, tmsProcess, numSamples, check, channel)){ cerr << "Error: " << err.getString() << "\n"; return 1; } } while(cont); } else if(test == "all"){ do { if(err = tmsTestAll(tmsControl, tmsProcess, numSamples, check)){ cerr << "Error: " << err.getString() << "\n"; return 1; } } while(cont); } else if(test == "allManual"){ do { if(err = tmsTestAllManual(tmsControl, tmsProcess, check)){ cerr << "Error: " << err.getString() << "\n"; return 1; } } while(cont); } return 0; }