/******************************************************************************* * Tests.cpp Signal Generator classes * T.Barnaby, BEAM Ltd, 2006-09-12 ******************************************************************************* */ #include <Tests.h> #include <math.h> #include <pthread.h> BList<Test*> testsAll; BList<Test*>& testsInit(){ testsAll.append(new TestSine()); testsAll.append(new TestSquare()); testsAll.append(new TestBeam()); testsAll.append(new TestBeam1()); testsAll.append(new TestBeam2()); testsAll.append(new TestBeam3()); testsAll.append(new TestBeam4()); return testsAll; } TestParam::TestParam(BString name, BString value){ this->name = name; this->value = value; } BString TestParams::getValue(BString name){ BIter i; for(start(i); !isEnd(i); next(i)){ if(get(i).name == name){ return get(i).value; } } return ""; } void TestParams::setValue(BString name, BString value){ BIter i; for(start(i); !isEnd(i); next(i)){ if(get(i).name == name){ get(i).value = value; return; } } BList<TestParam>::append(TestParam(name, value)); } Test::Test(BString name){ oname = name; osampleRate = 150000000; oamplitude = 1.0; ox = 0; } Test::~Test(){ } BError Test::init(TestParams& params){ BError err; BString s; oparams = params; if((s = params.getValue("sampleRate")) != "") osampleRate = atof(s); if((s = params.getValue("amplitude")) != "") oamplitude = atof(s); if((s = params.getValue("fileName")) != "") ofileName = s; if((s = params.getValue("fileType")) != "") ofileType = s; if(ofileName == "") return owgen.config(osampleRate, 8); else return ofile.open(ofileName, "w"); } void Test::close(){ if(ofileName == ""){ owgen.close(); } else { ofile.close(); } } BString Test::name(){ return oname; } BString Test::info(){ return oinfo; } BError Test::run(){ BError err; return err; } BError Test::output(BSignalList& sigs){ BError err; BString str; int s; int c = -1; BIter i; int in = 0; int p = -1; if(ofileName == ""){ return owgen.output(sigs); } else { if((str = oparams.getValue("channel")) != "") c = atoi(str); if((str = oparams.getValue("integer")) != "") in = atoi(str); if((str = oparams.getValue("period")) != "") p = atoi(str); if(ofileType == "txt"){ if(c >= 0){ for(sigs.start(i); !sigs.isEnd(i); sigs.next(i)){ if((p >= 0) && (sigs[i].id != p)) continue; for(s = 0; s < sigs[i].numSamples; s++){ if(in){ int16_t d; d = int16_t(sigs[i].data[c][s] * 8191); ofile.printf("%d\n", d); } else { ofile.printf("%f\n", sigs[i].data[c][s]); } } } } else { for(sigs.start(i); !sigs.isEnd(i); sigs.next(i)){ if((p >= 0) && (sigs[i].id != p)) continue; for(s = 0; s < sigs[i].numSamples; s++){ for(c = 0; c < 8; c++){ if(in){ int16_t d; d = int16_t(sigs[i].data[c][s] * 8191); ofile.printf("%d ", d); } else { ofile.printf("%f ", sigs[i].data[c][s]); } } ofile.printf("\n"); } } } } else { for(sigs.start(i); !sigs.isEnd(i); sigs.next(i)){ if((p >= 0) && (sigs[i].id != p)) continue; for(s = 0; s < sigs[i].numSamples; s++){ uint32_t v; uint16_t ds; uint16_t dx; uint16_t dy; // Get 14bit value ds = int16_t(sigs[i].data[0][s] * 8191); dx = int16_t(sigs[i].data[1][s] * 8191); dy = int16_t(sigs[i].data[2][s] * 8191); v = (dy >> 4) << 22; v |= (dx >> 4) << 12; v |= (ds >> 3) << 1; if(sigs[i].data[4][s] > 0.5) v |= 0x01; ofile.write(&v, sizeof(v)); #ifdef ZAP int16_t t; t = (v >> 1) & 0x07FF; t |= (t & 0x400) ? 0xFE00 : 0; printf("%d\n", t); #endif } } } return err; } } TestSine::TestSine() : Test("Sine") { oinfo = "Outputs a sine wave on channel 0"; ofreq = 10e6; } TestSine::~TestSine(){ } BError TestSine::run(){ BError err; int numSamples = int(64 * osampleRate / ofreq); BSignal sig(0, numSamples, 0, 0); SigGenSine sig1; sig1.config(osampleRate, ofreq, oamplitude); sig1.generate(sig.data[0], numSamples); osigList.append(sig); if(err = output(osigList)) printf("Output Error: %s\n", err.getString().retStr()); pthread_testcancel(); return err; } TestSquare::TestSquare() : Test("Square") { oinfo = "Outputs a square wave, 0 to 1v, at 10MHz on channel 0"; ofreq = 10e6; } TestSquare::~TestSquare(){ } BError TestSquare::run(){ BError err; int numSamples = int(64 * osampleRate / ofreq); BSignal sig(0, numSamples, 0, 0); SigGenSquare sig1; sig1.config(osampleRate, ofreq, oamplitude/2, oamplitude/2); sig1.generate(sig.data[0], numSamples); osigList.append(sig); if(err = output(osigList)) printf("Output Error: %s\n", err.getString().retStr()); pthread_testcancel(); return err; } TestBeam::TestBeam(BString name) : Test(name) { if(name == ""){ oname = "Beam"; oinfo = "Outputs a repetitive TMS Cycle with a beam with short timings"; oinfo += " Has 4 particle bunches at harmonic 8."; ofref = 437000; } } TestBeam::~TestBeam(){ } BError TestBeam::init(TestParams& params){ BError err; int ns = 0; BString s; if(err = Test::init(params)) return err; if((s = params.getValue("fref")) != "") ofref = atof(s); if(ofileName == ""){ // Set ns to be a multiple of 15 for sysclock and 8 samples for the AWG ns = 8 * 15 * int(round((osampleRate / (8 * 15)) / ofref)); ofref = osampleRate / ns; osysClock = osampleRate / int(osampleRate / 10e6); onumSamples = ns; } else { ns = int(round(osampleRate / ofref)); // Round ns to 2 for PUPE TestData if(ns & 1) ns++; ofref = osampleRate / ns; osysClock = ns * int(10e6 / ns); onumSamples = ns; } #ifdef ZAP // Set ns to be a multiple of 15 for sysclock and 8 samples for the AWG ns = 8 * 15 * int(round((osampleRate / (8 * 15)) / ofref)); ofref = osampleRate / ns; osysClock = osampleRate / int(osampleRate / 10e6); onumSamples = ns; #endif #ifdef ZAP printf("Samplerate: %f\n", osampleRate); printf("NumSamplesPerLoop: %d\n", ns); printf("SysClock: %f Ratio: %f\n", osysClock, osampleRate/osysClock); printf("Fref: %f Ratio: %f\n", ofref, osampleRate/ofref); #endif return err; } uint32_t TestBeam::numLoops(double fref, int ms){ return uint32_t(ms * osampleRate / (onumSamples* 1000)); } int TestBeam::addCycleBlank(int numRepeat, int next){ int numSamples = onumSamples; BSignal sig(osigList.number(), numSamples, numRepeat, next); SigGenSquare sig3; sig3.config(osampleRate, osysClock, 0.5, 0.5); // SYSTEM_CLOCK sig3.generate(sig.data[3], numSamples); osigList.append(sig); return 0; } int TestBeam::addCycleStart(int numRepeat, int next){ int numSamples = onumSamples; BSignal sig(osigList.number(), numSamples, numRepeat, next); SigGenSquare sig3; SigGenPulse sig7; BString s; int cycleStartPhase = 0; double cycleStartTime; if((s = oparams.getValue("cycleStartPhase")) != "") cycleStartPhase = s.retInt(); cycleStartTime = cycleStartPhase / (ofref * 360); // printf("CycleStartPhase: %d %g\n", cycleStartPhase, cycleStartTime); sig3.config(osampleRate, osysClock, 0.5, 0.5); // SYSTEM_CLOCK sig7.config(osampleRate, ofref, 1.0, 1e-6, cycleStartTime); // START_CYCLE sig3.generate(sig.data[3], numSamples); sig7.generate(sig.data[7], numSamples); osigList.append(sig); return 0; } int TestBeam::addCyclePreInjection(int numRepeat, int next){ int numSamples = onumSamples; BSignal sig(osigList.number(), numSamples, numRepeat, next); SigGenSquare sig3; SigGenSquare sig4; sig3.config(osampleRate, osysClock, 0.5, 0.5); // SYSTEM_CLOCK sig4.config(osampleRate, ofref, 0.5, 0.5); // FREF sig3.generate(sig.data[3], numSamples); sig4.generate(sig.data[4], numSamples); osigList.append(sig); return 0; } int TestBeam::addCycleInjection(int numRepeat, int next){ int numSamples = onumSamples; BSignal sig(osigList.number(), numSamples, numRepeat, next); SigGenSquare sig3; SigGenSquare sig4; SigGenPulse sig5; sig3.config(osampleRate, osysClock, 0.5, 0.5); // SYSTEM_CLOCK sig4.config(osampleRate, ofref, 0.5, 0.5); // FREF sig5.config(osampleRate, ofref, 1.0, 1e-6); // INJECTION sig3.generate(sig.data[3], numSamples); sig4.generate(sig.data[4], numSamples); sig5.generate(sig.data[5], numSamples); osigList.append(sig); return 0; } int TestBeam::addCycleBeam(int numRepeat, int next, int harmonic, int numBunches, int hchange, double reduce){ int numSamples = onumSamples; BSignal sig(osigList.number(), numSamples, numRepeat, next); SigGenBeam sig0; SigGenBeam sig1; SigGenBeam sig2; SigGenSquare sig3; SigGenSquare sig4; SigGenPulse sig6; int bunchSet = 0; int i; for(i = 0; i < numBunches; i++){ bunchSet |= (1 << (harmonic/2 - numBunches/2 + i)); } // sig0.config(osampleRate, ofref, harmonic, bunchSet, reduce, 1, oamplitude); sig0.config(osampleRate, ofref, harmonic, bunchSet, reduce, 0, oamplitude); sig1.config(osampleRate, ofref, harmonic, bunchSet, reduce, 0, 0.5 * oamplitude); // DeltaX sig2.config(osampleRate, ofref, harmonic, bunchSet, reduce, 0, -0.25 * oamplitude); // DeltaY sig3.config(osampleRate, osysClock, 0.5, 0.5); // SYSTEM_CLOCK sig4.config(osampleRate, ofref, 0.5, 0.5); // FREF sig6.config(osampleRate, ofref, 1.0, 1e-6); // HCHANGE sig0.generate(sig.data[0], numSamples); sig1.generate(sig.data[1], numSamples); sig2.generate(sig.data[2], numSamples); sig3.generate(sig.data[3], numSamples); sig4.generate(sig.data[4], numSamples); if(hchange) sig6.generate(sig.data[6], numSamples); osigList.append(sig); return 0; } int TestBeam::addCycleStop(int numRepeat, int next){ int numSamples = onumSamples; BSignal sig(osigList.number(), numSamples, numRepeat, next); SigGenSquare sig3; SigGenPulse sig8; sig3.config(osampleRate, osysClock, 0.5, 0.5); // SYSTEM_CLOCK sig8.config(osampleRate, ofref, 1.0, 1e-6); // STOP_CYCLE sig3.generate(sig.data[3], numSamples); sig8.generate(sig.data[8], numSamples); osigList.append(sig); return 0; } BError TestBeam::run(){ BError err; int n = 1; printf("SampleRate: %f\n", osampleRate); printf("SysClock: %f\n", osysClock); printf("Fref: %f\n", ofref); printf("NumSamples: %u\n", onumSamples); addCycleBlank(0, n++); addCycleStart(0, n++); addCyclePreInjection(2, n++); addCycleInjection(0, n++); addCycleBeam(4, n++, 8, 4, 0, 0.0); addCycleStop(0, 0); if(err = output(osigList)) printf("Output Error: %s\n", err.getString().retStr()); pthread_testcancel(); return err; } TestBeam1::TestBeam1() : TestBeam("Beam1") { oinfo = "Outputs a repetitive TMS Cycle with a beam."; oinfo += " Has 4 particle bunches at harmonic 8."; ofref = 437000; } BError TestBeam1::run(){ BError err; int n = 1; printf("SampleRate: %f\n", osampleRate); printf("SysClock: %f\n", osysClock); printf("Fref: %f\n", ofref); addCycleBlank(0, n++); addCycleStart(0, n++); addCyclePreInjection(numLoops(ofref, 150), n++); addCycleInjection(0, n++); addCycleBeam(numLoops(ofref, 600), n++, 8, 4, 0, 0.0); addCycleStop(0, n++); addCycleBlank(numLoops(ofref, 400), n++); addCycleBlank(0, 0); if(err = output(osigList)) printf("Output Error: %s\n", err.getString().retStr()); pthread_testcancel(); return err; } TestBeam2::TestBeam2() : TestBeam("Beam2") { oinfo = "Outputs a repetitive TMS Cycle with a beam."; oinfo += " Has 4 particle bunches at harmonic 8 moving to 4 particle bunches at harmonic 16."; ofref = 437000; } BError TestBeam2::run(){ BError err; int n = 1; printf("SampleRate: %f\n", osampleRate); printf("SysClock: %f\n", osysClock); printf("Fref: %f\n", ofref); addCycleBlank(0, n++); addCycleStart(0, n++); addCyclePreInjection(numLoops(ofref, 150), n++); addCycleInjection(0, n++); addCycleBeam(numLoops(ofref, 100), n++, 8, 4, 0, 0.0); addCycleBeam(0, n++, 8, 4, 1, 0.0); addCycleBeam(numLoops(ofref, 100), n++, 16, 4, 0, 0.0); addCycleBeam(numLoops(ofref, 400), n++, 16, 4, 0, 0.0); addCycleStop(0, n++); addCycleBlank(numLoops(ofref, 400), n++); addCycleBlank(0, 0); if(err = output(osigList)) printf("Output Error: %s\n", err.getString().retStr()); pthread_testcancel(); return err; } TestBeam3::TestBeam3() : TestBeam("Beam3") { oinfo = "Outputs a repetitive TMS Cycle with a beam. With Fref = 437000"; oinfo += " Has 4 particle bunches at harmonic 8 moving to 8 particle bunches at harmonic 16."; oinfo += " The 4 bunches have amplitudes reducing from the first to last bunch within an orbit."; oinfo += " The DeltaX set is at 0.2 amplitude."; oinfo += " The DeltaY set is at -0.1 amplitude."; oinfo += " Period 4 is set at harmonic 8, Period 6 is set at harmonic 16."; ofref = 437000; } BError TestBeam3::run(){ BError err; int n = 1; double reduce = 0.1; printf("SampleRate: %f\n", osampleRate); printf("SysClock: %f\n", osysClock); printf("Fref: %f\n", ofref); addCycleBlank(0, n++); addCycleStart(0, n++); addCyclePreInjection(numLoops(ofref, 150), n++); addCycleInjection(0, n++); addCycleBeam(numLoops(ofref, 300), n++, 8, 4, 0, reduce); addCycleBeam(0, n++, 8, 4, 1, reduce); addCycleBeam(numLoops(ofref, 100), n++, 16, 8, 0, reduce); addCycleBeam(numLoops(ofref, 400), n++, 16, 8, 0, reduce); addCycleStop(0, n++); addCycleBlank(numLoops(ofref, 400), n++); addCycleBlank(0, 0); if(err = output(osigList)) printf("Output Error: %s\n", err.getString().retStr()); pthread_testcancel(); return err; } TestBeam4::TestBeam4() : TestBeam("Beam4") { oinfo = "Outputs a repetitive TMS Cycle with a beam. With Fref = 437000"; oinfo += " Has 4 particle bunches at harmonic 8 moving to 8 particle bunches at harmonic 16."; oinfo += " The 4 bunches have amplitudes reducing from the first to last bunch within an orbit."; oinfo += " The first set of bunches after injection are full size."; oinfo += " The DeltaX set is at 0.2 amplitude."; oinfo += " The DeltaY set is at -0.1 amplitude."; oinfo += " Period 4 is set at harmonic 8, Period 6 is set at harmonic 16."; ofref = 437000; } BError TestBeam4::run(){ BError err; int n = 1; double reduce = 0.1; printf("SampleRate: %f\n", osampleRate); printf("SysClock: %f\n", osysClock); printf("Fref: %f\n", ofref); addCycleBlank(0, n++); addCycleStart(0, n++); addCyclePreInjection(numLoops(ofref, 150), n++); addCycleInjection(0, n++); addCycleBeam(1, n++, 8, 4, 0, 0); addCycleBeam(numLoops(ofref, 300), n++, 8, 4, 0, reduce); addCycleBeam(0, n++, 8, 4, 1, reduce); addCycleBeam(numLoops(ofref, 100), n++, 16, 8, 0, reduce); addCycleBeam(numLoops(ofref, 400), n++, 16, 8, 0, reduce); addCycleStop(0, n++); addCycleBlank(numLoops(ofref, 400), n++); addCycleBlank(0, 0); if(err = output(osigList)) printf("Output Error: %s\n", err.getString().retStr()); pthread_testcancel(); return err; }