/*******************************************************************************
* 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());
testsAll.append(new TestMulti());
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::addCycleNone(int numRepeat, int next){
int numSamples = onumSamples;
BSignal sig(osigList.number(), numSamples, numRepeat, next);
osigList.append(sig);
return 0;
}
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::addCycleStartMulti(int numRepeat, int next){
int numSamples = onumSamples;
BSignal sig(osigList.number(), numSamples, numRepeat, next);
SigGenPulse sig0;
SigGenPulse sig1;
SigGenPulse sig2;
SigGenPulse sig3;
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);
sig0.config(osampleRate, ofref, 1.0, 1e-6, cycleStartTime); // START_CYCLE
sig1.config(osampleRate, ofref, 1.0, 1e-6, cycleStartTime); // START_CYCLE
sig2.config(osampleRate, ofref, 1.0, 1e-6, cycleStartTime); // START_CYCLE
sig3.config(osampleRate, ofref, 1.0, 1e-6, cycleStartTime); // START_CYCLE
sig0.generate(sig.data[4], numSamples);
sig1.generate(sig.data[5], numSamples);
sig2.generate(sig.data[6], numSamples);
sig3.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;
}
TestMulti::TestMulti() : TestBeam("Multi") {
oinfo = "Outputs a repetitive TMS CYCLE_START timing pulse on the first four channels.";
ofref = 437000;
}
BError TestMulti::run(){
BError err;
int n = 1;
printf("SampleRate: %f\n", osampleRate);
printf("SysClock: %f\n", osysClock);
printf("Fref: %f\n", ofref);
addCycleStartMulti(0, n++);
addCycleNone(numLoops(ofref, 1200), n++);
if(err = output(osigList))
printf("Output Error: %s\n", err.getString().retStr());
pthread_testcancel();
return err;
}