From ab27ab1c5def8cc64cef9e77362eb00d37084183 Mon Sep 17 00:00:00 2001 From: bergamaschi Date: Thu, 13 Oct 2011 11:26:28 +0000 Subject: [PATCH] Gotthard class implemented git-svn-id: file:///afs/psi.ch/project/sls_det_software/svn/slsDetectorSoftware@34 951219d9-93cf-4727-9268-0efd64621fa3 --- slsDetectorSoftware/Makefile | 30 +- slsDetectorSoftware/MySocketTCP/MySocketTCP.h | 6 +- .../commonFiles/sls_detector_defs.h | 27 +- .../gotthardDetector/gotthardDetector.cpp | 3345 +++++++++++++++ .../gotthardDetector/gotthardDetector.h | 352 ++ .../gotthardDetectorServer/.target-makefrag | 1 + .../gotthardDetectorServer/Makefile | 59 + .../communication_funcs.c | 540 +++ .../communication_funcs.h | 32 + .../gotthardDetectorServer/firmware_funcs.c | 1361 +++++++ .../gotthardDetectorServer/firmware_funcs.h | 138 + .../gotthardDetectorServer/mcb_funcs.c | 2581 ++++++++++++ .../gotthardDetectorServer/mcb_funcs.h | 175 + .../gotthardDetectorServer/registers_g.h | 181 + .../gotthardDetectorServer/server.c | 80 + .../gotthardDetectorServer/server_defs.h | 42 + .../gotthardDetectorServer/server_funcs.c | 2488 +++++++++++ .../gotthardDetectorServer/server_funcs.h | 71 + .../gotthardDetectorServer/server_funcs_old.c | 180 + .../gotthardDetectorServer/server_funcs_old.h | 24 + .../gotthardDetectorServer/sharedmemory.c | 39 + .../gotthardDetectorServer/sharedmemory.h | 47 + .../gotthardDetectorServer/stop_server.c | 41 + .../gotthardDetectorServer/trimming_funcs.c | 755 ++++ .../gotthardDetectorServer/trimming_funcs.h | 17 + .../multiSlsDetector/multiSlsDetector.cpp | 3624 +++++++++++++++++ .../multiSlsDetector/multiSlsDetector.h | 1277 ++++++ .../mythenDetector/mythenDetector.cpp | 68 +- .../mythenDetector/mythenDetector.h | 17 +- .../mythenDetectorServer/firmware_funcs.c | 2 +- .../mythenDetectorServer/server_funcs.c | 10 +- .../mythenDetectorServer/trimming_funcs.c | 39 +- .../slsDetector/slsDetector.cpp | 160 +- slsDetectorSoftware/slsDetector/slsDetector.h | 57 +- .../usersFunctions/usersFunctions.c | 136 + .../usersFunctions/usersFunctions.h | 16 + 36 files changed, 17857 insertions(+), 161 deletions(-) create mode 100644 slsDetectorSoftware/gotthardDetector/gotthardDetector.cpp create mode 100644 slsDetectorSoftware/gotthardDetector/gotthardDetector.h create mode 100755 slsDetectorSoftware/gotthardDetectorServer/.target-makefrag create mode 100755 slsDetectorSoftware/gotthardDetectorServer/Makefile create mode 100755 slsDetectorSoftware/gotthardDetectorServer/communication_funcs.c create mode 100755 slsDetectorSoftware/gotthardDetectorServer/communication_funcs.h create mode 100755 slsDetectorSoftware/gotthardDetectorServer/firmware_funcs.c create mode 100755 slsDetectorSoftware/gotthardDetectorServer/firmware_funcs.h create mode 100755 slsDetectorSoftware/gotthardDetectorServer/mcb_funcs.c create mode 100755 slsDetectorSoftware/gotthardDetectorServer/mcb_funcs.h create mode 100755 slsDetectorSoftware/gotthardDetectorServer/registers_g.h create mode 100755 slsDetectorSoftware/gotthardDetectorServer/server.c create mode 100755 slsDetectorSoftware/gotthardDetectorServer/server_defs.h create mode 100755 slsDetectorSoftware/gotthardDetectorServer/server_funcs.c create mode 100755 slsDetectorSoftware/gotthardDetectorServer/server_funcs.h create mode 100755 slsDetectorSoftware/gotthardDetectorServer/server_funcs_old.c create mode 100755 slsDetectorSoftware/gotthardDetectorServer/server_funcs_old.h create mode 100755 slsDetectorSoftware/gotthardDetectorServer/sharedmemory.c create mode 100755 slsDetectorSoftware/gotthardDetectorServer/sharedmemory.h create mode 100755 slsDetectorSoftware/gotthardDetectorServer/stop_server.c create mode 100755 slsDetectorSoftware/gotthardDetectorServer/trimming_funcs.c create mode 100755 slsDetectorSoftware/gotthardDetectorServer/trimming_funcs.h create mode 100644 slsDetectorSoftware/multiSlsDetector/multiSlsDetector.cpp create mode 100644 slsDetectorSoftware/multiSlsDetector/multiSlsDetector.h diff --git a/slsDetectorSoftware/Makefile b/slsDetectorSoftware/Makefile index 035550446..da435dd8a 100644 --- a/slsDetectorSoftware/Makefile +++ b/slsDetectorSoftware/Makefile @@ -1,14 +1,12 @@ CFLAGS= -DC_ONLY -FLAGS=-DVERBOSE -INCLUDES= -I commonFiles -I slsDetector -I MySocketTCP -I eigerDetector -ImythenDetector -I usersFunctions +FLAGS= +#-DVERBOSE +INCLUDES= -I commonFiles -I slsDetector -I MySocketTCP -I eigerDetector -ImythenDetector -IgotthardDetector -I usersFunctions + +#EPICSFLAGS=-D EPICS -I/usr/local/epics/base/include/ -I /usr/local/epics/base/include/os/Linux/ -L /usr/local/epics/base/lib/SL5-x86/ -Wl,-R/usr/local/epics/base/lib/SL5-x86 -lca -lCom -#SRC_H= slsDetector/slsDetector.h mythenDetector/mythenDetector.h eigerDetector/eigerDetector.h MySocketTCP/MySocketTCP.h usersFunctions/usersFunctions.h commonFiles/sls_detector_defs.h - -#mythenDetectorServer/communication_funcs.h mythenDetectorServer/firmware_funcs.h mythenDetectorServer/mcb_funcs.h mythenDetectorServer/registers.h mythenDetectorServer/server_defs.h mythenDetectorServer/server_funcs.h mythenDetectorServer/trimming_funcs.h - - -SRC_CLNT= slsDetector/slsDetector.cpp MySocketTCP/MySocketTCP.cxx usersFunctions/usersFunctions.c mythenDetector/mythenDetector.cpp eigerDetector/eigerDetector.cpp +SRC_CLNT= slsDetector/slsDetector.cpp MySocketTCP/MySocketTCP.cxx usersFunctions/usersFunctions.c mythenDetector/mythenDetector.cpp eigerDetector/eigerDetector.cpp gotthardDetector/gotthardDetector.cpp SRC_MYTHEN_SVC = mythenDetectorServer/server.c mythenDetectorServer/server_funcs.c mythenDetectorServer/communication_funcs.c mythenDetectorServer/firmware_funcs.c mythenDetectorServer/mcb_funcs.c mythenDetectorServer/trimming_funcs.c #mythenDetectorServer/sharedmemory.c @@ -20,17 +18,13 @@ doc: $(SRC_H) $(SRC_CLNT) - - - - mythenServer: $(SRC_MYTHEN_SVC) - $(CC) $(SRC_MYTHEN_SVC) $(CFLAGS) $(FLAGS) $(INCLUDES) -ImythenDetectorServer -D VIRTUAL -lm -D MCB_FUNCS -D C_ONLY + $(CC) $(SRC_MYTHEN_SVC) $(CFLAGS) $(FLAGS) $(INCLUDES) -ImythenDetectorServer -DVIRTUAL -lm -D MCB_FUNCS -DC_ONLY mv a.out mythenServer picassoServer: $(SRC_MYTHEN_SVC) - $(CXX) $(SRC_MYTHEN_SVC) $(CFLAGS) $(FLAGS) $(INCLUDES) -ImythenDetectorServer -D VIRTUAL -lm -D MCB_FUNCS -DPICASSOD + $(CC) $(SRC_MYTHEN_SVC) $(CFLAGS) $(FLAGS) $(INCLUDES) -ImythenDetectorServer -D VIRTUAL -lm -DMCB_FUNCS -DPICASSOD -DC_ONLY mv a.out picassoServer @@ -39,11 +33,12 @@ package: $(SRC_CLNT) $(CXX) -fPIC -g -o objs/slsDetector.o -c -Wall slsDetector/slsDetector.cpp $(INCLUDES) $(FLAGS) # $(CXX) -fPIC -g -o objs/eigerDetector.o -c -Wall eigerDetector/eigerDetector.cpp $(INCLUDES) $(FLAGS) $(CXX) -fPIC -g -o objs/mythenDetector.o -c -Wall mythenDetector/mythenDetector.cpp $(INCLUDES) $(FLAGS) - $(CXX) -fPIC -g -o objs/usersFunctions.o -c -Wall usersFunctions/usersFunctions.c $(INCLUDES) $(FLAGS) + $(CXX) -fPIC -g -o objs/gotthardDetector.o -c -Wall gotthardDetector/gotthardDetector.cpp $(INCLUDES) $(FLAGS) + $(CXX) -fPIC -g -o objs/usersFunctions.o -c -Wall usersFunctions/usersFunctions.c $(INCLUDES) $(FLAGS) $(EPICSFLAGS) $(CXX) -fPIC -g -o objs/MySocketTCP.o -c -Wall MySocketTCP/MySocketTCP.cxx $(INCLUDES) $(FLAGS) - $(CXX) -shared -Wl,-soname,libSlsDetector.so.1 -o libSlsDetector.so.1.0.1 objs/slsDetector.o objs/mythenDetector.o objs/usersFunctions.o objs/MySocketTCP.o -lc $(INCLUDES) $(FLAGS) + $(CXX) -shared -Wl,-soname,libSlsDetector.so.1 -o libSlsDetector.so.1.0.1 objs/slsDetector.o objs/mythenDetector.o objs/gotthardDetector.o objs/usersFunctions.o objs/MySocketTCP.o -lc $(INCLUDES) $(FLAGS) $(EPICSFLAGS) ln -sf libSlsDetector.so.1.0.1 libSlsDetector.so - ar rcs libSlsDetector.a objs/slsDetector.o objs/mythenDetector.o objs/usersFunctions.o objs/MySocketTCP.o + ar rcs libSlsDetector.a objs/slsDetector.o objs/mythenDetector.o objs/gotthardDetector.o objs/usersFunctions.o objs/MySocketTCP.o clean: rm -rf libSlsDetector.so.1.0.1 libSlsDetector.so core objs/* docs/* @@ -62,6 +57,7 @@ install_inc: cp -P ../slsDetectorSoftware/MySocketTCP/MySocketTCP.h $(DESTDIR) cp -P ../slsDetectorSoftware/eigerDetector/eigerDetector.h $(DESTDIR) cp -P ../slsDetectorSoftware/mythenDetector/mythenDetector.h $(DESTDIR) + cp -P ../slsDetectorSoftware/gotthardDetector/gotthardDetector.h $(DESTDIR) cp -P ../slsDetectorSoftware/slsDetector/slsDetector.h $(DESTDIR) cp -P ../slsDetectorSoftware/commonFiles/sls_detector_defs.h $(DESTDIR) cp -P ../slsDetectorSoftware/usersFunctions/usersFunctions.h $(DESTDIR) diff --git a/slsDetectorSoftware/MySocketTCP/MySocketTCP.h b/slsDetectorSoftware/MySocketTCP/MySocketTCP.h index 7c2ee3527..8e411b31c 100644 --- a/slsDetectorSoftware/MySocketTCP/MySocketTCP.h +++ b/slsDetectorSoftware/MySocketTCP/MySocketTCP.h @@ -4,9 +4,13 @@ #define SEND_REC_MAX_SIZE 4096 #define DEFAULT_PORTNO 1952 - +#define DEFAULT_PORTNO_GOTTHARD 1955 using namespace std; + + + + /** * * @libdoc The MySocketTCP class provides a simple interface for creating and sending/receiving data over a TCP socket. diff --git a/slsDetectorSoftware/commonFiles/sls_detector_defs.h b/slsDetectorSoftware/commonFiles/sls_detector_defs.h index 088ec4583..90dce201a 100755 --- a/slsDetectorSoftware/commonFiles/sls_detector_defs.h +++ b/slsDetectorSoftware/commonFiles/sls_detector_defs.h @@ -253,8 +253,15 @@ enum dacIndex { VDD_POT, /**< chiptest board power supply vdd */ VSH_POT, /**< chiptest board power supply vsh */ VIO_POT, /**< chiptest board power supply va */ - HV_POT /**< chiptest board high voltage */ - + HV_POT, /**< chiptest board high voltage */ + G_VREF_DS, /**< gotthard */ + G_VCASCN_PB, /**< gotthard */ + G_VCASCP_PB, /**< gotthard */ + G_VOUT_CM, /**< gotthard */ + G_VCASC_OUT, /**< gotthard */ + G_VIN_CM, /**< gotthard */ + G_VREF_COMP, /**< gotthard */ + G_IB_TESTC /**< gotthard */ }; /** @@ -265,6 +272,10 @@ enum detectorSettings{ STANDARD, /**< standard settings */ FAST, /**< fast settings */ HIGHGAIN, /**< highgain settings */ + DYNAMICGAIN, /**< dynamic gain settings */ + GAIN1, /**< gain 1 settings */ + GAIN2, /**< gain 2 settings */ + GAIN3, /**< gain 3 settings */ UNDEFINED, /**< undefined or custom settings */ UNINITIALIZED /**< uninitialiazed (status at startup) */ }; @@ -448,10 +459,18 @@ enum { //Trimming F_EXECUTE_TRIMMING, /**< execute trimming */ - + F_EXIT_SERVER, /**< turnoff detector server */ + + F_GET_TEMPERATURE, + F_SET_GOTTHARD, + F_GET_GOTTHARD, + + F_GET_ACTUAL_TIME, /**< Gets the actual time of the detector's internal timer */ + F_GET_MEASUREMENT_TIME /**< Gets the time of the measurement from the detector (fifo) */ - F_EXIT_SERVER /**< turnoff detector server */ + /* Always append functions hereafter!!! */ + }; diff --git a/slsDetectorSoftware/gotthardDetector/gotthardDetector.cpp b/slsDetectorSoftware/gotthardDetector/gotthardDetector.cpp new file mode 100644 index 000000000..e07489328 --- /dev/null +++ b/slsDetectorSoftware/gotthardDetector/gotthardDetector.cpp @@ -0,0 +1,3345 @@ +#include "gotthardDetector.h" +#include + +#include + +//using namespace std; + + +char* gotthardDetector::gotthardStringname(string name) { + + char retval[100]; + int fnum, set=0; + char val[100]; + + + if (name.length()==0){ + fnum=F_GET_GOTTHARD; + } + else + { + fnum=F_SET_GOTTHARD; + set=1; + strcpy(val,name.c_str()); + } + int ret=FAIL; + + + char mess[100]; + // int arg[1]; + // arg[0]=name; + + + //#ifdef VERBOSE + std::cout<< std::endl; + if(set) + std::cout<< "Setting Stringname" << std::endl; + else + std::cout<< "Retreiving stringname" << std::endl; + //#endif + + + if (controlSocket) { + std::cout<< "controlsocket worked\n"; + if (controlSocket->Connect()>=0) { + std::cout<< "connectsocket worked\n"; + std::cout<<"fnum:"<SendDataOnly(&fnum,sizeof(fnum)); + //controlSocket->SendDataOnly(arg,sizeof(arg)); + if(set) + controlSocket->SendDataOnly(val,sizeof(val)); + controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret==OK) { + controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); + } else { + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + } + controlSocket->Disconnect(); + } + + } + + //#ifdef VERBOSE + std::cout<< "Stringname set to "<< retval << std::endl; + //#endif + if (ret==FAIL) { + std::cout<< "Setting/Getting stringname failed " << std::endl; + } + return retval; + +} + + + +string gotthardDetector::executeLine(int narg, char *args[], int action) { + + +#ifdef VERBOSE + for (int ia=0; ia1) + sval=string(args[1]); + else + sval="none"; + float corr[24*1280], ecorr[24*1280]; + if (getFlatFieldCorrection(corr,ecorr)) { + if (sval!="none") { + writeDataFile(sval,corr,ecorr,NULL,'i'); + return sval; + } + return string(getFlatFieldCorrectionFile()); + } else { + return string("none"); + } + } + } else if (var=="ffdir") { + if (action==PUT_ACTION) { + sval=string(args[1]); + if (sval=="none") + sval=""; + setFlatFieldCorrectionDir(sval); + } + return string(getFlatFieldCorrectionDir()); + } else if (var=="ratecorr") { + if (action==PUT_ACTION) { + sscanf(args[1],"%f",&fval); + setRateCorrection(fval); + } + float t; + if (getRateCorrection(t)) { + sprintf(answer,"%f",t); + } else { + sprintf(answer,"%f",0.); + } + return string(answer); + } else if (var=="badchannels") { + if (action==PUT_ACTION) { + sval=string(args[1]); + if (sval=="none") + sval=""; + setBadChannelCorrection(sval); + } else if (action==GET_ACTION) { + if (narg>1) + sval=string(args[1]); + else + sval="none"; + int bch[24*1280], nbch; + if ((nbch=getBadChannelCorrection(bch))) { + if (sval!="none") { + ofstream outfile; + outfile.open (sval.c_str(),ios_base::out); + if (outfile.is_open()) { + for (int ich=0; ich1) + sval=string(args[1]); + else + sval="none"; + int dir; + if (getAngularConversion(dir)) { + if (sval!="none") { + writeAngularConversion(sval.c_str()); + return sval; + } + return string(getAngularConversion()); + } else { + return string("none"); + } + } + } else if (var=="globaloff") { + if (action==PUT_ACTION) { + sscanf(args[1],"%f",&fval); + setGlobalOffset(fval); + } + sprintf(answer,"%f",getGlobalOffset()); + return string(answer); + } else if (var=="fineoff") { + if (action==PUT_ACTION) { + sscanf(args[1],"%f",&fval); + setFineOffset(fval); + } + sprintf(answer,"%f",getFineOffset()); + return string(answer); + } else if (var=="binsize") { + if (action==PUT_ACTION) { + sscanf(args[1],"%f",&fval); + setBinSize(fval); + } + sprintf(answer,"%f",getBinSize()); + return string(answer); + } else if (var=="positions") { + if (action==PUT_ACTION) { + sscanf(args[1],"%d",&ival); + float pos[ival]; + for (int ip=0; ipnarg-2) + ival=narg-2; + int ene[ival]; + for (int ie=0; ienarg-2) + ival=narg-2; + float ene[ival]; + for (int ie=0; ienarg-2) + ival=narg-2; + float ene[ival]; + for (int ie=0; ie> ival; + if (vvstr.fail()) + return string("syntax is extsig:i where signal is signal number"); + externalSignalFlag flag=GET_EXTERNAL_SIGNAL_FLAG, ret; + if (action==PUT_ACTION) { + sval=string(args[1]); +#ifdef VERBOSE + std::cout<< "sig " << ival << " flag " << sval; +#endif + if (sval=="off") flag=SIGNAL_OFF; + else if (sval=="gate_in_active_high") flag=GATE_IN_ACTIVE_HIGH; + else if (sval=="gate_in_active_low") flag=GATE_IN_ACTIVE_LOW; + else if (sval=="trigger_in_rising_edge") flag=TRIGGER_IN_RISING_EDGE; + else if (sval=="trigger_in_falling_edge") flag=TRIGGER_IN_FALLING_EDGE; + else if (sval=="ro_trigger_in_rising_edge") flag=RO_TRIGGER_IN_RISING_EDGE; + else if (sval=="ro_trigger_in_falling_edge") flag=RO_TRIGGER_IN_FALLING_EDGE; + else if (sval=="gate_out_active_high") flag=GATE_OUT_ACTIVE_HIGH; + else if (sval=="gate_out_active_low") flag=GATE_OUT_ACTIVE_LOW; + else if (sval=="trigger_out_rising_edge") flag=TRIGGER_OUT_RISING_EDGE; + else if (sval=="trigger_out_falling_edge") flag=TRIGGER_OUT_FALLING_EDGE; + else if (sval=="ro_trigger_out_rising_edge") flag=RO_TRIGGER_OUT_RISING_EDGE; + else if (sval=="ro_trigger_out_falling_edge") flag=RO_TRIGGER_OUT_FALLING_EDGE; + + + } + ret= setExternalSignalFlags(flag,ival); + switch (ret) { + case SIGNAL_OFF: + return string( "off"); + case GATE_IN_ACTIVE_HIGH: + return string( "gate_in_active_high"); + case GATE_IN_ACTIVE_LOW: + return string( "gate_in_active_low"); + case TRIGGER_IN_RISING_EDGE: + return string( "trigger_in_rising_edge"); + case TRIGGER_IN_FALLING_EDGE: + return string( "trigger_in_falling_edge"); + case RO_TRIGGER_IN_RISING_EDGE: + return string( "ro_trigger_in_rising_edge"); + case RO_TRIGGER_IN_FALLING_EDGE: + return string( "ro_trigger_in_falling_edge"); + case GATE_OUT_ACTIVE_HIGH: + return string( "gate_out_active_high"); + case GATE_OUT_ACTIVE_LOW: + return string( "gate_out_active_low"); + case TRIGGER_OUT_RISING_EDGE: + return string( "trigger_out_rising_edge"); + case TRIGGER_OUT_FALLING_EDGE: + return string( "trigger_out_falling_edge"); + case RO_TRIGGER_OUT_RISING_EDGE: + return string( "ro_trigger_out_rising_edge"); + case RO_TRIGGER_OUT_FALLING_EDGE: + return string( "ro_trigger_out_falling_edge"); + default: + return string( "unknown"); + } + } else if (var.find("modulenumber")==0) {//else if (var=="modulenumber") { + cout << "modulenumber" << endl; + if (action==PUT_ACTION) { + return string("cannot set"); + } + if (var.size()<=13) + return string("syntax is modulenumber:i where is is module number"); + istringstream vvstr(var.substr(13)); + vvstr >> ival; + if (vvstr.fail()) + return string("syntax is modulenumber:i where is is module number"); + //cout << var.substr(13) << endl; + sprintf(answer,"%llx",getId(MODULE_SERIAL_NUMBER,ival)); + return string(answer); + } else if (var=="moduleversion") { + if (action==PUT_ACTION) { + return string("cannot set" ); + } + sprintf(answer,"%llx",getId(MODULE_FIRMWARE_VERSION)); + return string(answer); + } else if (var=="detectornumber") { + if (action==PUT_ACTION) { + return string("cannot set "); + } + sprintf(answer,"%llx",getId(DETECTOR_SERIAL_NUMBER)); + return string(answer); + } else if (var=="detectorversion") { + if (action==PUT_ACTION) { + return string("cannot set "); + } + sprintf(answer,"%llx",getId(DETECTOR_FIRMWARE_VERSION)); + return string(answer); + } else if (var=="softwareversion") { + if (action==PUT_ACTION) { + return string("cannot set "); + } + sprintf(answer,"%llx",getId(DETECTOR_SOFTWARE_VERSION)); + return string(answer); + } else if (var=="thisversion") { + if (action==PUT_ACTION) { + return string("cannot set "); + } + sprintf(answer,"%llx",getId(THIS_SOFTWARE_VERSION)); + return string(answer); + } + + else if (var.find("digitest")==0) {//else if (var=="digitest") { + cout << "digitest" << endl; + if (action==PUT_ACTION) { + return string("cannot set "); + } + if (var.size()<=9) + return string("syntax is digitest:i where i is the module number"); + + + istringstream vvstr(var.substr(9)); + vvstr >> ival; + if (vvstr.fail()) + return string("syntax is digitest:i where i is the module number"); + sprintf(answer,"%x",digitalTest(CHIP_TEST, ival)); + return string(answer); + } else if (var=="bustest") { + if (action==PUT_ACTION) { + return string("cannot set "); + } + sprintf(answer,"%x",digitalTest(DETECTOR_BUS_TEST)); + return string(answer); + } else if (var=="settings") { + detectorSettings sett=GET_SETTINGS; + if (action==PUT_ACTION) { + sval=string(args[1]); + if (sval=="highgain") + sett=HIGHGAIN; + else if (sval=="dynamicgain") + sett=DYNAMICGAIN; + else if (sval=="gain1") + sett=GAIN1; + else if (sval=="gain2") + sett=GAIN2; + else if (sval=="gain3") + sett=GAIN3; + else { + sprintf(answer,"%s not defined for this detector",sval.c_str()); + return string(answer); + } + } + switch (setSettings(sett)) { + case STANDARD: + return string("standard"); + case FAST: + return string("fast"); + case HIGHGAIN: + return string("highgain"); + case DYNAMICGAIN: + return string("dynamicgain"); + case GAIN1: + return string("gain1"); + case GAIN2: + return string("gain2"); + case GAIN3: + return string("gain3"); + default: + return string("undefined"); + } + } else if (var=="threshold") { + if (action==PUT_ACTION) { + sscanf(args[1],"%d",&ival); + setThresholdEnergy(ival); + } + sprintf(answer,"%d",getThresholdEnergy()); + return string(answer); + } else if (var=="vref_ds") { + if (action==PUT_ACTION) { + sscanf(args[1],"%f",&fval); + setDAC(fval,G_VREF_DS ); + } + sprintf(answer,"%f",setDAC(-1,G_VREF_DS)); + return string(answer); + } else if (var=="vcascn_pb") { + if (action==PUT_ACTION) { + sscanf(args[1],"%f",&fval); + setDAC(fval,G_VCASCN_PB ); + } + sprintf(answer,"%f",setDAC(-1,G_VCASCN_PB)); + return string(answer); + } else if (var=="vcascp_pb") { + if (action==PUT_ACTION) { + sscanf(args[1],"%f",&fval); + setDAC(fval, G_VCASCP_PB); + } + sprintf(answer,"%f",setDAC(-1,G_VCASCP_PB)); + return string(answer); + } else if (var=="vout_cm") { + if (action==PUT_ACTION) { + sscanf(args[1],"%f",&fval); + setDAC(fval,G_VOUT_CM ); + } + sprintf(answer,"%f",setDAC(-1,G_VOUT_CM)); + return string(answer); + } else if (var=="vcasc_out") { + if (action==PUT_ACTION) { + sscanf(args[1],"%f",&fval); + setDAC(fval,G_VCASC_OUT ); + } + sprintf(answer,"%f",setDAC(-1,G_VCASC_OUT)); + return string(answer); + } else if (var=="vin_cm") { + if (action==PUT_ACTION) { + sscanf(args[1],"%f",&fval); + setDAC(fval,G_VIN_CM ); + } + sprintf(answer,"%f",setDAC(-1,G_VIN_CM)); + return string(answer); + } else if (var=="vref_comp") { + if (action==PUT_ACTION) { + sscanf(args[1],"%f",&fval); + setDAC(fval,G_VREF_COMP); + } + sprintf(answer,"%f",setDAC(-1,G_VREF_COMP)); + return string(answer); + } else if (var=="ib_test_c") { + if (action==PUT_ACTION) { + sscanf(args[1],"%f",&fval); + setDAC(fval,G_IB_TESTC ); + } + sprintf(answer,"%f",setDAC(-1,G_IB_TESTC)); + return string(answer); + } + + else if (var=="temp") { + if (action==PUT_ACTION) { + return string("cannot set"); + } + sprintf(answer,"%f",getTemperature()); + return string(answer); + } + + //timers + + else if (var=="exptime") { + if (action==PUT_ACTION) { + sscanf(args[1],"%f",&fval);// in seconds! + setTimer(ACQUISITION_TIME,(int64_t)(fval*1E+9)); + } + sprintf(answer,"%f",(float)setTimer(ACQUISITION_TIME)*1E-9); + return string(answer); + } else if (var=="period") { + if (action==PUT_ACTION) { + sscanf(args[1],"%f",&fval);// in seconds! + setTimer(FRAME_PERIOD,(int64_t)(fval*1E+9)); + } + sprintf(answer,"%f",(float)setTimer(FRAME_PERIOD)*1E-9); + return string(answer); + } else if (var=="delay") { + if (action==PUT_ACTION) { + sscanf(args[1],"%f",&fval);// in seconds! + setTimer(DELAY_AFTER_TRIGGER,(int64_t)(fval*1E+9)); + } + sprintf(answer,"%f",(float)setTimer(DELAY_AFTER_TRIGGER)*1E-9); + return string(answer); + } else if (var=="gates") { + if (action==PUT_ACTION) { + sscanf(args[1],"%d",&ival); + setTimer( GATES_NUMBER,ival); + } + + sprintf(answer,"%lld",setTimer(GATES_NUMBER)); + return string(answer); + } else if (var=="frames") { + if (action==PUT_ACTION) { + sscanf(args[1],"%d",&ival); + setTimer(FRAME_NUMBER,ival); + } + sprintf(answer,"%lld",setTimer(FRAME_NUMBER)); + return string(answer); + } else if (var=="cycles") { + if (action==PUT_ACTION) { + sscanf(args[1],"%d",&ival); + setTimer(CYCLES_NUMBER,ival); + } + sprintf(answer,"%lld",setTimer(CYCLES_NUMBER)); + return string(answer); + } else if (var=="probes") { + if (action==PUT_ACTION) { + sscanf(args[1],"%d",&ival); + setTimer(PROBES_NUMBER,ival); + } + sprintf(answer,"%lld",setTimer(PROBES_NUMBER)); + return string(answer); + } + + else if (var=="exptimel") { + if (action==PUT_ACTION) { + sprintf(answer,"Cannot set\n"); + } else + sprintf(answer,"%f",(float)getTimeLeft(ACQUISITION_TIME)*1E-9); + return string(answer); + } else if (var=="periodl") { + if (action==PUT_ACTION) { + sprintf(answer,"Cannot set\n"); + } else + sprintf(answer,"%f",(float)getTimeLeft(FRAME_PERIOD)*1E-9); + return string(answer); + } else if (var=="delayl") { + if (action==PUT_ACTION) { + sprintf(answer,"Cannot set\n"); + } else + sprintf(answer,"%f",(float)getTimeLeft(DELAY_AFTER_TRIGGER)*1E-9); + return string(answer); + } else if (var=="gatesl") { + if (action==PUT_ACTION) { + sprintf(answer,"Cannot set\n"); + } else + sprintf(answer,"%f",(float)getTimeLeft(GATES_NUMBER)); + return string(answer); + } else if (var=="framesl") { + if (action==PUT_ACTION) { + sprintf(answer,"Cannot set\n"); + } else + sprintf(answer,"%f",(float)getTimeLeft(FRAME_NUMBER)+2); + return string(answer); + } else if (var=="cyclesl") { + if (action==PUT_ACTION) { + sprintf(answer,"Cannot set\n"); + } else + sprintf(answer,"%f",(float)getTimeLeft(CYCLES_NUMBER)+2); + return string(answer); + } else if (var=="progress") { + if (action==PUT_ACTION) { + setTotalProgress(); + sprintf(answer,"Cannot set\n"); + } else + sprintf(answer,"%f",getCurrentProgress()); + return string(answer); + } + + + else if (var=="dr") { + if (action==PUT_ACTION) { + sscanf(args[1],"%d",&ival); + setDynamicRange(ival); + } + sprintf(answer,"%d",setDynamicRange()); + return string(answer); + } else if (var=="flags") { + if (action==PUT_ACTION) { + sval=string(args[1]); + readOutFlags flag=GET_READOUT_FLAGS; + if (sval=="none") + flag=NORMAL_READOUT; + //else if (sval=="pumpprobe") + // flag=PUMP_PROBE_MODE; + else if (sval=="storeinram") + flag=STORE_IN_RAM; + else if (sval=="tot") + flag=TOT_MODE; + else if (sval=="continous") + flag=CONTINOUS_RO; + setReadOutFlags(flag); + + } + + switch (setReadOutFlags(GET_READOUT_FLAGS)) { + case NORMAL_READOUT: + return string("none"); + case STORE_IN_RAM: + return string("storeinram"); + case TOT_MODE: + return string("tot"); + case CONTINOUS_RO: + return string("continous"); + default: + return string("unknown"); + } + } + /*else if (var=="settingsbits") { + if (narg>=2) { + int nm=setNumberOfModules(GET_FLAG,X)*setNumberOfModules(GET_FLAG,Y); + sls_detector_module *myMod=NULL; + sval=string(args[1]); + std::cout<< " settingsfile " << sval << std::endl; + + for (int im=0; immodule=im; + setModule(*myMod); + deleteModule(myMod); + } //else cout << "myMod NULL" << endl; + } + } + } + std::cout<< "Returning settingsfile " << std::endl; + return string(getSettingsFile()); + } else if (var.find("trim")==0) { + if (action==GET_ACTION) { + trimMode mode=NOISE_TRIMMING; + int par1=0, par2=0; + if (var.size()<=5) + return string("trim:mode fname"); + + if (var.substr(5)=="noise") { + // par1 is countlim; par2 is nsigma + mode=NOISE_TRIMMING; + par1=500; + par2=4; + } else if (var.substr(5)=="beam") { + // par1 is countlim; par2 is nsigma + mode=BEAM_TRIMMING; + par1=1000; + par2=4; + } else if (var.substr(5)=="improve") { + // par1 is maxit; if par2!=0 vthresh will be optimized + mode=IMPROVE_TRIMMING; + par1=5; + par2=0; + } else if (var.substr(5)=="fix") { + // par1 is countlim; if par2<0 then trimwithlevel else trim with median + mode=FIXEDSETTINGS_TRIMMING; + par1=1000; + par2=1; + } else if (var.substr(5)=="offline") { + mode=OFFLINE_TRIMMING; + } else { + return string("Unknown trim mode ")+var.substr(5); + } + executeTrimming(mode, par1, par2); + sval=string(args[1]); + sls_detector_module *myMod=NULL; + int nm=setNumberOfModules(GET_FLAG,X)*setNumberOfModules(GET_FLAG,Y); + for (int im=0; im> sargname; + //if (ssstr.good()) { +#ifdef VERBOSE + std::cout<< iargval << " " << sargname << std::endl; +#endif + strcpy(args[iargval],sargname.c_str()); + iargval++; + //} + } + ans=executeLine(iargval,args,PUT_ACTION); +#ifdef VERBOSE + std::cout<< ans << std::endl; +#endif + } + iline++; + } + infile.close(); + } else { + std::cout<< "Error opening configuration file " << fname << " for reading" << std::endl; + return FAIL; + } +#ifdef VERBOSE + std::cout<< "Read configuration file of " << iline << " lines" << std::endl; +#endif + return iline; +}; + + +int gotthardDetector::writeConfigurationFile(string const fname){ + + string names[]={\ + "hostname",\ + "caldir",\ + "settingsdir",\ + "trimen",\ + "outdir",\ + "ffdir",\ + "headerbefore",\ + "headerafter",\ + "headerbeforepar",\ + "headerafterpar",\ + "nmod",\ + "badchannels",\ + "angconv",\ + "globaloff",\ + "binsize",\ + "threaded",\ + "waitstates",\ + "setlength",\ + "clkdivider"}; + int nvar=19; + ofstream outfile; + int iv=0; + char *args[100]; + for (int ia=0; ia<100; ia++) { + args[ia]=new char[1000]; + } + + + outfile.open(fname.c_str(),ios_base::out); + if (outfile.is_open()) { + for (iv=0; iv> sargname; + // if (ssstr.good()) { + strcpy(args[iargval],sargname.c_str()); +#ifdef VERBOSE + std::cout<< args[iargval] << std::endl; +#endif + iargval++; + // } + } + if (level==2) { + executeLine(iargval,args,PUT_ACTION); + } else { + if (string(args[0])==string("flatfield")) + ; + else if (string(args[0])==string("badchannels")) + ; + else if (string(args[0])==string("angconv")) + ; + else if (string(args[0])==string("trimbits")) + ; + else + executeLine(iargval,args,PUT_ACTION); + } + } + iline++; + } + infile.close(); + } else { + std::cout<< "Error opening " << fname << " for reading" << std::endl; + return FAIL; + } +#ifdef VERBOSE + std::cout<< "Read " << iline << " lines" << std::endl; +#endif + return iline; + +}; + + + + /* I/O */ + + + sls_detector_module* gotthardDetector::readSettingsFile(string fname, sls_detector_module *myMod){ + + int nflag=0; + + if (myMod==NULL) { + myMod=createModule(); + nflag=1; + } + string myfname; + string str; + ifstream infile; + ostringstream oss; + int iline=0; + // string names[]={"Vref", "VcascN","VcascP", "Vout", "Vcasc", "Vin", "Vref_comp", "Vib_test", "config", "HV"}; + string sargname; + int ival; + int ichan=0, ichip=0, idac=0; + + + +#ifdef VERBOSE + std::cout<< "reading settings file for module number "<< myMod->module << std::endl; +#endif + myfname=fname; +#ifdef VERBOSE + std::cout<< "settings file name is "<< myfname << std::endl; +#endif + infile.open(myfname.c_str(), ios_base::in); + if (infile.is_open()) { + for (int iarg=0; iargnDacs; iarg++) { + getline(infile,str); + iline++; +#ifdef VERBOSE + std::cout<< str << std::endl; +#endif + istringstream ssstr(str); + ssstr >> sargname >> ival; +#ifdef VERBOSE + std::cout<< sargname << " dac nr. " << idac << " is " << ival << std::endl; +#endif + myMod->dacs[idac]=ival; + idac++; + } + + getline(infile,str); + iline++; +#ifdef VERBOSE + std::cout<< str << std::endl; +#endif + istringstream ssstr(str); + ssstr >> sargname >> ival; +#ifdef VERBOSE + std::cout<< sargname << " (config) is " << ival << std::endl; +#endif + int configval = ival;//myMod->dacs[idac]=ival; + + + getline(infile,str); + iline++; +#ifdef VERBOSE + std::cout<< str << std::endl; +#endif + istringstream sstr(str); + sstr >> sargname >> ival; +#ifdef VERBOSE + std::cout<< sargname << " (HV) is " << ival << std::endl; +#endif + int HVval = ival;//myMod->dacs[idac]=ival; + + + infile.close(); + strcpy(thisDetector->settingsFile,fname.c_str()); + return myMod; + } else { + std::cout<< "could not open settings file " << myfname << std::endl; + if (nflag) + deleteModule(myMod); + return NULL; + } + +}; + + +int gotthardDetector::writeSettingsFile(string fname, sls_detector_module mod){ + + ofstream outfile; + string names[]={"Vref", "VcascN","VcascP", "Vout", "Vcasc", "Vin", "Vref_comp", "Vib_test", "config", "HV"}; + int iv, ichan, ichip; + int iv1, idac; + int nb; + outfile.open(fname.c_str(), ios_base::out); + + if (outfile.is_open()) { + for (idac=0; idacnChans; ichan++) { + iv=mod.chanregs[ichip*thisDetector->nChans+ichan]; + iv1= (iv&0x3f); + outfile <>nb); + outfile << iv1 << " "; + nb=8; + iv1=((iv&(1<>nb); + outfile << iv1 << " "; + nb=7; + iv1=((iv&(1<>nb); + outfile <>nb); + outfile << iv1 << " "; + nb=11; + iv1= ((iv&0xfffff800)>>nb); + outfile << iv1 << std::endl; + } + } + outfile.close(); + return OK; + } else { + std::cout<< "could not open trim file " << fname << std::endl; + return FAIL; + } +}; + + + + +int gotthardDetector::writeSettingsFile(string fname, int imod){ + + return writeSettingsFile(fname,detectorModules[imod]); + +}; + + +int gotthardDetector::writeDataFile(string fname, float *data, float *err, float *ang, char dataformat, int nch){ + + if (nch==-1) + nch=thisDetector->nChans*thisDetector->nChips*thisDetector->nMods; + + + ofstream outfile; + int idata; + if (data==NULL) + return FAIL; + + // args|=0x10; // one line per channel! + + outfile.open (fname.c_str(),ios_base::out); + if (outfile.is_open()) + { +#ifdef VERBOSE + std::cout<< "writeDataFile Writing to file " << fname << std::endl; +#endif + for (int ichan=0; ichannChans*thisDetector->nChips*thisDetector->nMods; ichan++) + outfile << ichan << " " << *(data+ichan) << std::endl; + outfile.close(); + return OK; + } else { + std::cout<< "Could not open file " << fname << "for writing"<< std::endl; + return FAIL; + } +}; + + + + + +int gotthardDetector::readDataFile(string fname, float *data, float *err, float *ang, char dataformat, int nch){ + + + ifstream infile; + int ichan, iline=0; + int interrupt=0; + float fdata, ferr, fang; + int maxchans; + int ich; + string str; + + if (nch==0) + maxchans=thisDetector->nChans*thisDetector->nChips*thisDetector->nMods; + else if (nch<0) + maxchans=0xfffffff; + else + maxchans=nch; + +#ifdef VERBOSE + std::cout<< "Opening file "<< fname << std::endl; +#endif + infile.open(fname.c_str(), ios_base::in); + if (infile.is_open()) { + while (infile.good() and interrupt==0) { + getline(infile,str); +#ifdef VERBOSE + std::cout<< str << std::endl; +#endif + istringstream ssstr(str); + if (ang==NULL) { + ssstr >> ichan >> fdata; + ich=ichan; + if (!ssstr.good()) { + interrupt=1; + break; + } + if (ich!=iline) + std::cout<< "Channel number " << ichan << " does not match with line number " << iline << " " << dataformat << std::endl; + } else { + ssstr >> fang >> fdata; + ich=iline; + } + if (!ssstr.good()) { + interrupt=1; + break; + } + if (err) + ssstr >> ferr; + if (!ssstr.good()) { + interrupt=1; + break; + } + if (ich> ichan >> idata; + if (!ssstr.good()) { + interrupt=1; + break; + } + if (ichan!=iline) { + std::cout<< " Expected channel "<< iline <<" but read channel "<< ichan << std::endl; + interrupt=1; + break; + } else { + if (ilinenChans*thisDetector->nChips*thisDetector->nMods) { + data[iline]=idata; + iline++; + } else { + interrupt=1; + break; + } + } + } + } else { + std::cout<< "Could not read file " << fname << std::endl; + return -1; + } + return iline; +}; + + + + +int gotthardDetector::readCalibrationFile(string fname, float &gain, float &offset){ + + string str; + ifstream infile; +#ifdef VERBOSE + std::cout<< "Opening file "<< fname << std::endl; +#endif + infile.open(fname.c_str(), ios_base::in); + if (infile.is_open()) { + getline(infile,str); +#ifdef VERBOSE + std::cout<< str << std::endl; +#endif + istringstream ssstr(str); + ssstr >> offset >> gain; + } else { + std::cout<< "Could not open calibration file "<< fname << std::endl; + gain=0.; + offset=0.; + return -1; + } + return 0; + +}; + +int gotthardDetector::writeCalibrationFile(string fname, float gain, float offset){ + + //std::cout<< "Function not yet implemented " << std::endl; + ofstream outfile; + + outfile.open (fname.c_str()); + + // >> i/o operations here << + if (outfile.is_open()) { + outfile << offset << " " << gain << std::endl; + } else { + std::cout<< "Could not open calibration file "<< fname << " for writing" << std::endl; + return -1; + } + + outfile.close(); + + return 0; + +}; + + + /* Communication to server */ + + + + // calibration functions +/* + really needed? + +int gotthardDetector::setCalibration(int imod, detectorSettings isettings, float gain, float offset){ + std::cout<< "function not yet implemented " << std::endl; + + + + return OK; + +} +int gotthardDetector::getCalibration(int imod, detectorSettings isettings, float &gain, float &offset){ + + std::cout<< "function not yet implemented " << std::endl; + + + +} +*/ + +/* + +int gotthardDetector::setROI(int nroi, int *xmin, int *xmax, int *ymin, int *ymax){ + + +}; +*/ + +//Corrections + +int gotthardDetector::setAngularConversion(string fname) { + + if (fname=="") { + thisDetector->correctionMask&=~(1<< ANGULAR_CONVERSION); + //strcpy(thisDetector->angConvFile,"none"); + //#ifdef VERBOSE + std::cout << "Unsetting angular conversion" << std::endl; + //#endif + } else { + if (fname=="default") { + fname=string(thisDetector->angConvFile); + } + + //#ifdef VERBOSE + std::cout << "Setting angular conversion to" << fname << std:: endl; + //#endif + if (readAngularConversion(fname)>=0) { + thisDetector->correctionMask|=(1<< ANGULAR_CONVERSION); + strcpy(thisDetector->angConvFile,fname.c_str()); + } + } + return thisDetector->correctionMask&(1<< ANGULAR_CONVERSION); + +} + + + + + + + +int gotthardDetector::getAngularConversion(int &direction, angleConversionConstant *angconv) { + + direction=thisDetector->angDirection; + if (angconv) { + for (int imod=0; imodnMods; imod++) { + (angconv+imod)->center=thisDetector->angOff[imod].center; + (angconv+imod)->r_conversion=thisDetector->angOff[imod].r_conversion; + (angconv+imod)->offset=thisDetector->angOff[imod].offset; + (angconv+imod)->ecenter=thisDetector->angOff[imod].ecenter; + (angconv+imod)->er_conversion=thisDetector->angOff[imod].er_conversion; + (angconv+imod)->eoffset=thisDetector->angOff[imod].eoffset; + } + } + if (thisDetector->correctionMask&(1<< ANGULAR_CONVERSION)) { + return 1; + } else { + return 0; + } +} + + + +int gotthardDetector::readAngularConversion(string fname) { + string str; + ifstream infile; + int mod; + float center, ecenter; + float r_conv, er_conv; + float off, eoff; + string ss; + int interrupt=0; + + //" module %i center %E +- %E conversion %E +- %E offset %f +- %f \n" +#ifdef VERBOSE + std::cout<< "Opening file "<< fname << std::endl; +#endif + infile.open(fname.c_str(), ios_base::in); + if (infile.is_open()) { + while (infile.good() and interrupt==0) { + getline(infile,str); +#ifdef VERBOSE + std::cout<< str << std::endl; +#endif + istringstream ssstr(str); + ssstr >> ss >> mod; + ssstr >> ss >> center; + ssstr >> ss >> ecenter; + ssstr >> ss >> r_conv; + ssstr >> ss >> er_conv; + ssstr >> ss >> off; + ssstr >> ss >> eoff; + if (modnModsMax && mod>=0) { + thisDetector->angOff[mod].center=center; + thisDetector->angOff[mod].r_conversion=r_conv; + thisDetector->angOff[mod].offset=off; + thisDetector->angOff[mod].ecenter=ecenter; + thisDetector->angOff[mod].er_conversion=er_conv; + thisDetector->angOff[mod].eoffset=eoff; + } + } + } else { + std::cout<< "Could not open calibration file "<< fname << std::endl; + return -1; + } + return 0; +} + + +int gotthardDetector:: writeAngularConversion(string fname) { + + ofstream outfile; + outfile.open (fname.c_str(),ios_base::out); + if (outfile.is_open()) + { + for (int imod=0; imodnMods; imod++) { + outfile << " module " << imod << " center "<< thisDetector->angOff[imod].center<<" +- "<< thisDetector->angOff[imod].ecenter<<" conversion "<< thisDetector->angOff[imod].r_conversion << " +- "<< thisDetector->angOff[imod].er_conversion << " offset "<< thisDetector->angOff[imod].offset << " +- "<< thisDetector->angOff[imod].eoffset << std::endl; + } + outfile.close(); + } else { + std::cout<< "Could not open file " << fname << "for writing"<< std::endl; + return -1; + } + //" module %i center %E +- %E conversion %E +- %E offset %f +- %f \n" +} + +int gotthardDetector::resetMerging(float *mp, float *mv, float *me, int *mm) { + float binsize; + if (thisDetector->binSize>0) + binsize=thisDetector->binSize; + else + return FAIL; + + for (int ibin=0; ibin<(360./binsize); ibin++) { + mp[ibin]=0; + mv[ibin]=0; + me[ibin]=0; + mm[ibin]=0; + } + return OK; +} + + +int gotthardDetector::finalizeMerging(float *mp, float *mv, float *me, int *mm) { + float binsize; + int np=0; + + if (thisDetector->binSize>0) + binsize=thisDetector->binSize; + else + return FAIL; + + for (int ibin=0; ibin<(360./binsize); ibin++) { + if (mm[ibin]>0) { + mp[np]=mp[ibin]/mm[ibin]; + mv[np]=mv[ibin]/mm[ibin]; + me[np]=me[ibin]/mm[ibin]; + me[np]=sqrt(me[ibin]); + mm[np]=mm[ibin]; + np++; + } + } + return OK; +} + +int gotthardDetector::addToMerging(float *p1, float *v1, float *e1, float *mp, float *mv,float *me, int *mm) { + float binsize; + float binmi=-180., binma; + int ibin=0; + int imod; + float ang=0; + if (thisDetector->binSize>0) + binsize=thisDetector->binSize; + else + return FAIL; + binmi=-180.; + binma=binmi+binsize; + + + if (thisDetector->angDirection>0) { + for (int ip=0; ipnChans*thisDetector->nChips*thisDetector->nMods; ip++) { + if (thisDetector->correctionMask&DISCARD_BAD_CHANNELS) { + if (badChannelMask[ip]) + continue; + } + imod=ip/(thisDetector->nChans*thisDetector->nChips); + if (p1) + ang=p1[ip]; + else + ang=angle(ip,currentPosition,thisDetector->fineOffset+thisDetector->globalOffset,thisDetector->angOff[imod].r_conversion,thisDetector->angOff[imod].center, thisDetector->angOff[imod].offset,thisDetector->angOff[imod].tilt,thisDetector->angDirection); + + + + while (binmanChans*thisDetector->nChips*thisDetector->nMods-1; ip>=0; ip--) { + if (thisDetector->correctionMask&(1<< DISCARD_BAD_CHANNELS)) { + if (badChannelMask[ip]) + continue; + } + + while (binmafileIndex; + int lastindex=startindex; + char cmd[MAX_STR_LENGTH]; + //string sett; + + thisDetector->progressIndex=0; + thisDetector->stoppedFlag=0; + + + + resetFinalDataQueue(); + resetDataQueue(); + + + jointhread=0; + queuesize=0; + + + + + + if (thisDetector->threadedProcessing) { + startThread(delflag); + } + + int np=1; + if (thisDetector->numberOfPositions>0) + np=thisDetector->numberOfPositions; + + int ns0=1; + if (thisDetector->actionMask & (1 << MAX_ACTIONS)) { + ns0=thisDetector->nScanSteps[0]; + } + if (ns0<1) + ns0=1; + + + int ns1=1; + if (thisDetector->actionMask & (1 << (MAX_ACTIONS+1))) { + ns1=thisDetector->nScanSteps[1]; + } + if (ns1<1) + ns1=1; + + + + + //action at start + if (thisDetector->stoppedFlag==0) { + if (thisDetector->actionMask & (1 << startScript)) { + //"Custom start script. The arguments are passed as nrun=n par=p."); + sprintf(cmd,"%s nrun=%d par=%s",thisDetector->actionScript[startScript],thisDetector->fileIndex,thisDetector->actionParameter[startScript]); +#ifdef VERBOSE + cout << "Executing start script " << cmd << endl; +#endif + system(cmd); + } + } + + for (int is0=0; is0stoppedFlag==0) { + + currentScanVariable[0]=thisDetector->scanSteps[0][is0]; + currentScanIndex[0]=is0; + + switch(thisDetector->scanMode[0]) { + case 1: + setThresholdEnergy((int)currentScanVariable[0]); //energy scan + break; + case 2: + setDAC(currentScanVariable[0],THRESHOLD); // threshold scan + break; + case 3: + trimbit=(int)currentScanVariable[0]; + setChannel((trimbit<<((int)TRIMBIT_OFF))|((int)COMPARATOR_ENABLE)); // trimbit scan + break; + case 0: + currentScanVariable[0]=0; + break; + default: + //Custom scan script level 0. The arguments are passed as nrun=n fn=filename var=v par=p" + sprintf(cmd,"%s nrun=%d fn=%s var=%f par=%s",thisDetector->scanScript[0],thisDetector->fileIndex,createFileName().c_str(),currentScanVariable[0],thisDetector->scanParameter[0]); +#ifdef VERBOSE + cout << "Executing scan script 0 " << cmd << endl; +#endif + system(cmd); + + + } + } else + break; + + + for (int is1=0; is1stoppedFlag==0) { + + currentScanVariable[1]=thisDetector->scanSteps[1][is1]; + currentScanIndex[1]=is1; + + switch(thisDetector->scanMode[1]) { + case 1: + setThresholdEnergy((int)currentScanVariable[1]); //energy scan + break; + case 2: + setDAC(currentScanVariable[1],THRESHOLD); // threshold scan + break; + case 3: + trimbit=(int)currentScanVariable[1]; + setChannel((trimbit<<((int)TRIMBIT_OFF))|((int)COMPARATOR_ENABLE)); // trimbit scan + break; + case 0: + currentScanVariable[1]=0; + break; + default: + //Custom scan script level 1. The arguments are passed as nrun=n fn=filename var=v par=p" + sprintf(cmd,"%s nrun=%d fn=%s var=%f par=%s",thisDetector->scanScript[1],thisDetector->fileIndex,createFileName().c_str(),currentScanVariable[1],thisDetector->scanParameter[1]); +#ifdef VERBOSE + cout << "Executing scan script 1 " << cmd << endl; +#endif + system(cmd); + } + + } else + break; + + if (thisDetector->stoppedFlag==0) { + if (thisDetector->actionMask & (1 << scriptBefore)) { + //Custom script before each frame. The arguments are passed as nrun=n fn=filename par=p sv0=scanvar0 sv1=scanvar1 p0=par0 p1=par1" + sprintf(cmd,"%s nrun=%d fn=%s par=%s sv0=%f sv1=%f p0=%s p1=%s",thisDetector->actionScript[scriptBefore],thisDetector->fileIndex,createFileName().c_str(),thisDetector->actionParameter[scriptBefore],currentScanVariable[0],currentScanVariable[1],thisDetector->scanParameter[0],thisDetector->scanParameter[1]); +#ifdef VERBOSE + cout << "Executing script before " << cmd << endl; +#endif + system(cmd); + } + } else + break; + + currentPositionIndex=0; + + for (int ip=0; ipstoppedFlag==0) { + if (thisDetector->numberOfPositions>0) { + go_to_position (thisDetector->detPositions[ip]); + currentPositionIndex=ip+1; +#ifdef VERBOSE + std::cout<< "moving to position" << std::endl; +#endif + } + } else + break; + + //write header before? + //cmd=headerBeforeScript; + //Custom script to write the header. \n The arguments will be passed as nrun=n fn=filenam acqtime=t gainmode=g threshold=thr badfile=badf angfile=angf bloffset=blo fineoffset=fo fffile=fffn tau=deadtau par=p") + + if (thisDetector->stoppedFlag==0) { + if (thisDetector->correctionMask&(1<< I0_NORMALIZATION)) + currentI0=get_i0(); + if (thisDetector->actionMask & (1 << headerBefore)) { + //Custom script after each frame. The arguments are passed as nrun=n fn=filename par=p sv0=scanvar0 sv1=scanvar1 p0=par0 p1=par1" + sprintf(cmd,"%s nrun=%d fn=%s acqtime=%f gainmode=%d threshold=%d badfile=%s angfile=%s bloffset=%f fineoffset=%f fffile=%s/%s tau=%f par=%s",thisDetector->actionScript[headerBefore],thisDetector->fileIndex,createFileName().c_str(),((float)thisDetector->timerValue[ACQUISITION_TIME])*1E-9, thisDetector->currentSettings, thisDetector->currentThresholdEV, getBadChannelCorrectionFile().c_str(), getAngularConversion().c_str(), thisDetector->globalOffset, thisDetector->fineOffset,getFlatFieldCorrectionDir(),getFlatFieldCorrectionFile(), getRateCorrectionTau(), thisDetector->actionParameter[headerBefore]); +#ifdef VERBOSE + cout << "Executing header after " << cmd << endl; +#endif + system(cmd); + } + } else + break; + + + + if (thisDetector->stoppedFlag==0) { + startAndReadAll(); + + if (thisDetector->correctionMask&(1<< ANGULAR_CONVERSION)) + currentPosition=get_position(); + + if (thisDetector->correctionMask&(1<< I0_NORMALIZATION)) + currentI0=get_i0()-currentI0; + + + if (thisDetector->threadedProcessing==0) + processData(delflag); + + + } else + break; + + //while (!dataQueue.empty()){ + while (queuesize){ + usleep(1000); + } + + + if (thisDetector->fileIndex>lastindex) + lastindex=thisDetector->fileIndex; + + if (thisDetector->stoppedFlag==0) { + if (thisDetector->actionMask & (1 << headerAfter)) { + //Custom script after each frame. The arguments are passed as nrun=n fn=filename par=p sv0=scanvar0 sv1=scanvar1 p0=par0 p1=par1" + sprintf(cmd,"%s nrun=%d fn=%s acqtime=%f gainmode=%d threshold=%d badfile=%s angfile=%s bloffset=%f fineoffset=%f fffile=%s/%s tau=%f par=%s", \ + thisDetector->actionScript[headerAfter], \ + thisDetector->fileIndex,\ + createFileName().c_str(), \ + ((float)thisDetector->timerValue[ACQUISITION_TIME])*1E-9, \ + thisDetector->currentSettings, \ + thisDetector->currentThresholdEV, \ + getBadChannelCorrectionFile().c_str(), \ + getAngularConversion().c_str(), \ + thisDetector->globalOffset, \ + thisDetector->fineOffset, \ + getFlatFieldCorrectionDir(), \ + getFlatFieldCorrectionFile(), \ + getRateCorrectionTau(), \ + thisDetector->actionParameter[headerAfter]); +#ifdef VERBOSE + cout << "Executing header after " << cmd << endl; +#endif + system(cmd); + } + } else + break; + + + + if (thisDetector->stoppedFlag) { +#ifdef VERBOSE + std::cout<< "exiting since the detector has been stopped" << std::endl; +#endif + break; + } else if (ip<(np-1)) { + thisDetector->fileIndex=startindex; + } + } // loop on position finished + + //script after + if (thisDetector->stoppedFlag==0) { + if (thisDetector->actionMask & (1 << scriptAfter)) { + //Custom script after each frame. The arguments are passed as nrun=n fn=filename par=p sv0=scanvar0 sv1=scanvar1 p0=par0 p1=par1" + sprintf(cmd,"%s nrun=%d fn=%s par=%s sv0=%f sv1=%f p0=%s p1=%s",thisDetector->actionScript[scriptAfter],thisDetector->fileIndex,createFileName().c_str(),thisDetector->actionParameter[scriptAfter],currentScanVariable[0],currentScanVariable[1],thisDetector->scanParameter[0],thisDetector->scanParameter[1]); +#ifdef VERBOSE + cout << "Executing script after " << cmd << endl; +#endif + system(cmd); + } + } else + break; + + + if (thisDetector->stoppedFlag) { +#ifdef VERBOSE + std::cout<< "exiting since the detector has been stopped" << std::endl; +#endif + break; + } else if (is1<(ns1-1)) { + thisDetector->fileIndex=startindex; + } + + + } + + //end scan1 loop is1 + //currentScanVariable[MAX_SCAN_LEVELS]; + + + if (thisDetector->stoppedFlag) { +#ifdef VERBOSE + std::cout<< "exiting since the detector has been stopped" << std::endl; +#endif + break; + } else if (is0<(ns0-1)) { + thisDetector->fileIndex=startindex; + } + } //end scan0 loop is0 + + thisDetector->fileIndex=lastindex; + if (thisDetector->stoppedFlag==0) { + if (thisDetector->actionMask & (1 << stopScript)) { + //Custom stop script. The arguments are passed as nrun=n par=p. + sprintf(cmd,"%s nrun=%d par=%s",thisDetector->actionScript[stopScript],thisDetector->fileIndex,thisDetector->actionParameter[stopScript]); +#ifdef VERBOSE + cout << "Executing stop script " << cmd << endl; +#endif + system(cmd); + } + } + + + if (thisDetector->threadedProcessing) { +#ifdef VERBOSE + std::cout<< " ***********************waiting for data processing thread to finish " << queuesize << std::endl ; +#endif + jointhread=1; + pthread_join(dataProcessingThread, &status); + } +} + + +void* gotthardDetector::processData(int delflag) { + + + int *myData; + float *fdata; + float *rcdata=NULL, *rcerr=NULL; + float *ffcdata=NULL, *ffcerr=NULL; + float *ang=NULL; + float bs=0.004; + int imod; + int nb; + int np; + detectorData *thisData; + int dum=1; + string ext; + + +#ifdef ACQVERBOSE + std::cout<< " processing data - threaded mode " << thisDetector->threadedProcessing; +#endif + + if (thisDetector->correctionMask!=0) { + ext=".dat"; + } else { + ext=".raw"; + } + while(dum | thisDetector->threadedProcessing) { // ???????????????????????? + + + while( !dataQueue.empty() ) { + queuesize=dataQueue.size(); + + /** Pop data queue */ + myData=dataQueue.front(); // get the data from the queue + if (myData) { + + + + thisDetector->progressIndex++; +#ifdef VERBOSE + cout << "Progress is " << getCurrentProgress() << " \%" << endl; +#endif + + //process data + /** decode data */ + fdata=decodeData(myData); + + /** write raw data file */ + if (thisDetector->correctionMask==0 && delflag==1) { + + + writeDataFile (createFileName().append(".raw"), fdata, NULL, NULL, 'i'); + delete [] fdata; + } else { + writeDataFile (createFileName().append(".raw"), fdata, NULL, NULL, 'i'); + + /** rate correction */ + if (thisDetector->correctionMask&(1<nChans*thisDetector->nChips*thisDetector->nMods]; + rcerr=new float[thisDetector->nChans*thisDetector->nChips*thisDetector->nMods]; + rateCorrect(fdata,NULL,rcdata,rcerr); + delete [] fdata; + } else { + rcdata=fdata; + fdata=NULL; + } + + /** flat field correction */ + if (thisDetector->correctionMask&(1<nChans*thisDetector->nChips*thisDetector->nMods]; + ffcerr=new float[thisDetector->nChans*thisDetector->nChips*thisDetector->nMods]; + flatFieldCorrect(rcdata,rcerr,ffcdata,ffcerr); + delete [] rcdata; + delete [] rcerr; + } else { + ffcdata=rcdata; + ffcerr=rcerr; + rcdata=NULL; + rcerr=NULL; + } + + if (thisDetector->correctionMask&(1<< ANGULAR_CONVERSION)) { + + if (currentPositionIndex<=1) { + if (thisDetector->binSize>0) + bs=thisDetector->binSize; + else if (thisDetector->angOff[0].r_conversion>0) { + bs=180./PI*atan(thisDetector->angOff[0].r_conversion); + thisDetector->binSize=bs; + } else + thisDetector->binSize=bs; + + + nb=(int)(360./bs); + + mergingBins=new float[nb]; + mergingCounts=new float[nb]; + mergingErrors=new float[nb]; + mergingMultiplicity=new int[nb]; + + resetMerging(mergingBins, mergingCounts,mergingErrors, mergingMultiplicity); + } + /* it would be better to create an ang0 with 0 encoder position and add to merging/write to file simply specifying that offset so that when it cycles writing the data or adding to merging it also calculates the angular position */ + + ang=new float[thisDetector->nChans*thisDetector->nChips*thisDetector->nMods]; + for (int ip=0; ipnChans*thisDetector->nChips*thisDetector->nMods; ip++) { + imod=ip/(thisDetector->nChans*thisDetector->nChips); + ang[ip]=angle(ip%(thisDetector->nChans*thisDetector->nChips),currentPosition,thisDetector->fineOffset+thisDetector->globalOffset,thisDetector->angOff[imod].r_conversion,thisDetector->angOff[imod].center, thisDetector->angOff[imod].offset,thisDetector->angOff[imod].tilt,thisDetector->angDirection); + } + + if (thisDetector->correctionMask!=0) + writeDataFile (createFileName().append(".dat"), ffcdata, ffcerr,ang); + addToMerging(ang, ffcdata, ffcerr, mergingBins, mergingCounts,mergingErrors, mergingMultiplicity); + if ((currentPositionIndex==thisDetector->numberOfPositions) || (currentPositionIndex==0)) { + np=finalizeMerging(mergingBins, mergingCounts,mergingErrors, mergingMultiplicity); + /** file writing */ + currentPositionIndex++; + if (thisDetector->correctionMask!=0) + writeDataFile (createFileName().append(".dat"),mergingCounts, mergingErrors, mergingBins,'f',np); + if (delflag) { + delete [] mergingBins; + delete [] mergingCounts; + delete [] mergingErrors; + delete [] mergingMultiplicity; + } else { + thisData=new detectorData(mergingCounts,mergingErrors,mergingBins,getCurrentProgress(),(createFileName().append(ext)).c_str(),np);/* + if (thisDetector->correctionMask!=0) { + //thisData=new detectorData(mergingCounts,mergingErrors,mergingBins,thisDetector->progressIndex+1,(createFileName().append(".dat")).c_str(),np); + thisData=new detectorData(mergingCounts,mergingErrors,mergingBins,getCurrentProgress(),(createFileName().append(".dat")).c_str(),np); + } else { + thisData=new detectorData(mergingCounts,mergingErrors,mergingBins,getCurrentProgress(),(createFileName().append(".raw")).c_str(),np); + //thisData=new detectorData(mergingCounts,mergingErrors,mergingBins,thisDetector->progressIndex+1,(createFileName().append(".raw")).c_str(),np); + }*/ + finalDataQueue.push(thisData); + } + } + + if (ffcdata) + delete [] ffcdata; + if (ffcerr) + delete [] ffcerr; + if (ang) + delete [] ang; + } else { + if (thisDetector->correctionMask!=0) { + writeDataFile (createFileName().append(".dat"), ffcdata, ffcerr); + } + if (delflag) { + if (ffcdata) + delete [] ffcdata; + if (ffcerr) + delete [] ffcerr; + if (ang) + delete [] ang; + } else { + thisData=new detectorData(ffcdata,ffcerr,NULL,getCurrentProgress(),(createFileName().append(ext)).c_str(),thisDetector->nChans*thisDetector->nChips*thisDetector->nMods);/* + if (thisDetector->correctionMask!=0) { + thisData=new detectorData(ffcdata,ffcerr,NULL,getCurrentProgress(),(createFileName().append(".dat")).c_str(),thisDetector->nChans*thisDetector->nChips*thisDetector->nMods); + //thisData=new detectorData(ffcdata,ffcerr,NULL,thisDetector->progressIndex+1,(createFileName().append(".dat")).c_str(),thisDetector->nChans*thisDetector->nChips*thisDetector->nMods); + } else { + thisData=new detectorData(ffcdata,ffcerr,NULL,getCurrentProgress(),(createFileName().append(".raw")).c_str(),thisDetector->nChans*thisDetector->nChips*thisDetector->nMods); + //thisData=new detectorData(ffcdata,ffcerr,NULL,thisDetector->progressIndex+1,(createFileName().append(".raw")).c_str(),thisDetector->nChans*thisDetector->nChips*thisDetector->nMods); + }*/ + finalDataQueue.push(thisData); + } + } + } + thisDetector->fileIndex++; + + /* + thisDetector->progressIndex++; +#ifdef VERBOSE + cout << "Progress is " << getCurrentProgress() << " \%" << endl; +#endif + */ + + delete [] myData; + myData=NULL; + dataQueue.pop(); //remove the data from the queue + queuesize=dataQueue.size(); + } + } + if (jointhread) { + if (dataQueue.size()==0) + break; + } + dum=0; + } // ???????????????????????? + return 0; + +} + + + +void gotthardDetector::startThread(int delflag) { + pthread_attr_t tattr; + int ret; + sched_param param, mparam; + int policy= SCHED_OTHER; + + + // set the priority; others are unchanged + //newprio = 30; + mparam.sched_priority =1; + param.sched_priority =1; + + + /* Initialize and set thread detached attribute */ + pthread_attr_init(&tattr); + pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_JOINABLE); + + + + // param.sched_priority = 5; + // scheduling parameters of main thread + ret = pthread_setschedparam(pthread_self(), policy, &mparam); + //#ifdef VERBOSE + // printf("current priority is %d\n",param.sched_priority); + //#endif + if (delflag) + ret = pthread_create(&dataProcessingThread, &tattr,startProcessData, (void*)this); + else + ret = pthread_create(&dataProcessingThread, &tattr,startProcessDataNoDelete, (void*)this); + + pthread_attr_destroy(&tattr); + // scheduling parameters of target thread + ret = pthread_setschedparam(dataProcessingThread, policy, ¶m); + +} + + +void* startProcessData(void *n) { + + //void* processData(void *n) { + gotthardDetector *myDet=(gotthardDetector*)n; + myDet->processData(1); + pthread_exit(NULL); + +} + +void* startProcessDataNoDelete(void *n) { + + //void* processData(void *n) { + gotthardDetector *myDet=(gotthardDetector*)n; + myDet->processData(0); + pthread_exit(NULL); + +} + +runStatus gotthardDetector::getRunStatus(){ + + + int fnum=F_GET_RUN_STATUS; + int ret=FAIL; + char mess[100]; + runStatus retval=ERROR; +#ifdef VERBOSE + std::cout<< "GOTTHARD Getting status "<< std::endl; +#endif + if (thisDetector->onlineFlag==ONLINE_FLAG) { + if (stopSocket) { + if (stopSocket->Connect()>=0) { + stopSocket->SendDataOnly(&fnum,sizeof(fnum)); + stopSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret!=OK) { + stopSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + } else { + stopSocket->ReceiveDataOnly(&retval,sizeof(retval)); + } + stopSocket->Disconnect(); + } + } + } + return retval; + + +}; + +int64_t gotthardDetector::getTimeLeft(timerIndex index){ + + + int fnum=F_GET_TIME_LEFT; + int64_t retval; + char mess[100]; + int ret=OK; + +#ifdef VERBOSE + std::cout<< "GOTTHARD Getting timer "<< index << std::endl; +#endif + if (thisDetector->onlineFlag==ONLINE_FLAG) { + if (stopSocket) { + if (stopSocket->Connect()>=0) { + stopSocket->SendDataOnly(&fnum,sizeof(fnum)); + stopSocket->SendDataOnly(&index,sizeof(index)); + stopSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret!=OK) { + stopSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + } else { + stopSocket->ReceiveDataOnly(&retval,sizeof(retval)); + //thisDetector->timerValue[index]=retval; + } + stopSocket->Disconnect(); + } + } + } +#ifdef VERBOSE + std::cout<< "Time left is "<< retval << std::endl; +#endif + return retval; + +}; + + + + + + + + /* + set positions for the acquisition + \param nPos number of positions + \param pos array with the encoder positions + \returns number of positions + */ +int gotthardDetector::setPositions(int nPos, float *pos){ + + if (nPos>=0) + thisDetector->numberOfPositions=nPos; + for (int ip=0; ipdetPositions[ip]=pos[ip]; + + + setTotalProgress(); + + return thisDetector->numberOfPositions; + +} +/* + get positions for the acquisition + \param pos array which will contain the encoder positions + \returns number of positions +*/ +int gotthardDetector::getPositions(float *pos){ + + if (pos ) { + for (int ip=0; ipnumberOfPositions; ip++) + pos[ip]=thisDetector->detPositions[ip]; + } + setTotalProgress(); + + + return thisDetector->numberOfPositions; +}; + + + +float gotthardDetector::getTemperature(int imod){ + + float retval; + int fnum=F_GET_TEMPERATURE; + int ret=FAIL; + char mess[100]; + //int arg = imod; + + //#ifdef VERBOSE + std::cout<< "GOTTHARD Getting Temperature of module "<< imod << std::endl; + //#endif + if (thisDetector->onlineFlag==ONLINE_FLAG) { + + std::cout<< "onlineflag worked\n"; + if (controlSocket) { + std::cout<< "controlsocket worked\n"; + if (controlSocket->Connect()>=0) { + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + controlSocket->SendDataOnly(&imod,sizeof(imod)); + controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret==OK) { + controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); + } else { + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + } + controlSocket->Disconnect(); + } + } + } + //#ifdef VERBOSE + std::cout<< "Temperature is "<< retval << std::endl; + //#endif + if (ret==FAIL) { + std::cout<< "Getting temperature failed " << std::endl; + } + return retval; + +} diff --git a/slsDetectorSoftware/gotthardDetector/gotthardDetector.h b/slsDetectorSoftware/gotthardDetector/gotthardDetector.h new file mode 100644 index 000000000..7a17e8459 --- /dev/null +++ b/slsDetectorSoftware/gotthardDetector/gotthardDetector.h @@ -0,0 +1,352 @@ + + + +#ifndef GOTTHARD_DETECTOR_H +#define GOTTHARD_DETECTOR_H + +//#include +#include "slsDetector.h" +#include "usersFunctions.h" + +#define defaultTDead {170,90,750} + +//using namespace std; +/** + \mainpage C++ class with GOTTHARD specific functions + * + + + @author Anna Bergamaschi + +*/ + + + +class gotthardDetector : public slsDetector{ + + + + public: + /** + (default) constructor + */ + gotthardDetector(int id=0, detectorType t=GOTTHARD) : slsDetector(t, id){}; + //slsDetector(string const fname); + // ~slsDetector(){while(dataQueue.size()>0){}}; + /** destructor */ + virtual ~gotthardDetector(){}; + + + char* gotthardStringname(string name); + + + + /** + executes a set of string arguments according to a given format. It is used to read/write configuration file, dump and retrieve detector settings and for the command line interface command parsing + \param narg number of arguments + \param args array of string arguments + \param action can be PUT_ACTION or GET_ACTION (from text client even READOUT_ACTION for acquisition) + \returns answer string + */ + string executeLine(int narg, char *args[], int action=GET_ACTION); + + /** + returns the help for the executeLine command + \param os output stream to return the help to + \param action can be PUT_ACTION or GET_ACTION (from text client even READOUT_ACTION for acquisition) + */ + static string helpLine(int action=GET_ACTION); + + + /** + type of action performed + */ +enum {GET_ACTION, PUT_ACTION, READOUT_ACTION}; + + + /** + reads configuration file fname calling executeLine + \param fname file to be read + */ + int readConfigurationFile(string const fname); + /** + writes configuration file calling executeLine + \param fname file to write to + */ + int writeConfigurationFile(string const fname); + /** + dumps all the possible detector parameters calling executeLine + \param fname file to write to + \param level 0 dumps only main parameters and filenames for flat field correction etc.; 2 dumps really the complete configuration including flat field files, badchannels files, trimbits, angular conversion etc. + */ + int dumpDetectorSetup(string const fname, int level=0); + /** + retrieves all possible detector parameters from file calling executeLine + \param fname file to be read + */ + int retrieveDetectorSetup(string const fname, int level=0); + + /** + reads a trim/settings file + \param fname name of the file to be read + \param myMod pointer to the module structure which has to be set.
If it is NULL a new module structure will be created + \returns the pointer to myMod or NULL if reading the file failed + */ + + sls_detector_module* readSettingsFile(string fname, sls_detector_module* myMod=NULL); + + /** + writes a trim/settings file + \param fname name of the file to be written + \param mod module structure which has to be written to file + \returns OK or FAIL if the file could not be written + + \sa ::sls_detector_module + */ + int writeSettingsFile(string fname, sls_detector_module mod); + + /** + writes a trim/settings file for module number imod - the values will be read from the current detector structure + \param fname name of the file to be written + \param imod module number + \returns OK or FAIL if the file could not be written + \sa ::sls_detector_module sharedSlsDetector + */ + int writeSettingsFile(string fname, int imod); + + /** + writes a data file + \param name of the file to be written + \param data array of data values + \param err array of arrors on the data. If NULL no errors will be written + + \param ang array of angular values. If NULL data will be in the form chan-val(-err) otherwise ang-val(-err) + \param dataformat format of the data: can be 'i' integer or 'f' float (default) + \param nch number of channels to be written to file. if -1 defaults to the number of installed channels of the detector + \returns OK or FAIL if it could not write the file or data=NULL + + + */ + int writeDataFile(string fname, float *data, float *err=NULL, float *ang=NULL, char dataformat='f', int nch=-1); + + /** + writes a data file + \param name of the file to be written + \param data array of data values + \returns OK or FAIL if it could not write the file or data=NULL + */ + int writeDataFile(string fname, int *data); + + /** + reads a data file + \param name of the file to be read + \param data array of data values to be filled + \param err array of arrors on the data. If NULL no errors are expected on the file + + \param ang array of angular values. If NULL data are expected in the form chan-val(-err) otherwise ang-val(-err) + \param dataformat format of the data: can be 'i' integer or 'f' float (default) + \param nch number of channels to be written to file. if <=0 defaults to the number of installed channels of the detector + \returns OK or FAIL if it could not read the file or data=NULL + + + */ + int readDataFile(string fname, float *data, float *err=NULL, float *ang=NULL, char dataformat='f', int nch=0); + + /** + reads a data file + \param name of the file to be read + \param data array of data values + \returns OK or FAIL if it could not read the file or data=NULL + */ + int readDataFile(string fname, int *data); + + + /** + reads a calibration file + \param fname file to be read + \param gain reference to the gain variable + \offset reference to the offset variable + \sa sharedSlsDetector + */ + int readCalibrationFile(string fname, float &gain, float &offset); + /** + writes a clibration file + \param fname file to be written + \param gain + \param offset + \sa sharedSlsDetector + */ + int writeCalibrationFile(string fname, float gain, float offset); + + + /** + reads an angular conversion file + \param fname file to be read + \sa angleConversionConstant + */ + int readAngularConversion(string fname=""); + /** + writes an angular conversion file + \param fname file to be written + \sa angleConversionConstant + */ + int writeAngularConversion(string fname=""); + + + + + //Corrections + + + /** + set angular conversion + \param fname file with angular conversion constants ("" disable) + \returns 0 if angular conversion disabled, >0 otherwise + */ + int setAngularConversion(string fname=""); + + /** + get angular conversion + \param reference to diffractometer direction + \param angconv array that will be filled with the angular conversion constants + \returns 0 if angular conversion disabled, >0 otherwise + */ + int getAngularConversion(int &direction, angleConversionConstant *angconv=NULL); + + + /** returns the angular conversion file */ + string getAngularConversion() {if (thisDetector->correctionMask&(1<< ANGULAR_CONVERSION)) return string(thisDetector->angConvFile); else return string("none");}; + + /** + set detector global offset + */ + float setGlobalOffset(float f){thisDetector->globalOffset=f; return thisDetector->globalOffset;}; + + /** + set detector fine offset + */ + float setFineOffset(float f){thisDetector->fineOffset=f; return thisDetector->fineOffset;}; + /** + get detector fine offset + */ + float getFineOffset(){return thisDetector->fineOffset;}; + + /** + get detector global offset + */ + float getGlobalOffset(){return thisDetector->globalOffset;}; + + /** + set positions for the acquisition + \param nPos number of positions + \param pos array with the encoder positions + \returns number of positions + */ + int setPositions(int nPos, float *pos); + /** + get positions for the acquisition + \param pos array which will contain the encoder positions + \returns number of positions + */ + int getPositions(float *pos=NULL); + + + /** set detector bin size used for merging (approx angular resolution)*/ + float setBinSize(float bs) {thisDetector->binSize=bs; return thisDetector->binSize;} + /** return detector bin size used for merging (approx angular resolution)*/ + float getBinSize() {return thisDetector->binSize;} + + + + + /** sets the arrays of the merged data to 0. NB The array should be created with size >= 360./getBinSize(); + \param mp already merged postions + \param mv already merged data + \param me already merged errors (squared sum) + \param mm multiplicity of merged arrays + \returns OK or FAIL + */ + int resetMerging(float *mp, float *mv,float *me, int *mm); + /** merge dataset + \param p1 angular positions of dataset + \param v1 data + \param e1 errors + \param mp already merged postions + \param mv already merged data + \param me already merged errors (squared sum) + \param mm multiplicity of merged arrays + */ + int addToMerging(float *p1, float *v1, float *e1, float *mp, float *mv,float *me, int *mm); + + /** + calculates the "final" positions, data value and errors for the emrged data + \param mp already merged postions + \param mv already merged data + \param me already merged errors (squared sum) + \param mm multiplicity of merged arrays + \returns FAIL or the + */ + int finalizeMerging(float *mp, float *mv,float *me, int *mm); + + + /** + function for processing data + \param delflag if 1 the data are deleted, else left there for further processing (or plotting?) + */ + void* processData(int delflag=1); // thread function + + /** performs the complete acquisition and data processing + moves the detector to next position
+ starts and reads the detector
+ reads the IC (if required)
+ reads the encoder (iof required for angualr conversion)
+ processes the data (flat field, rate, angular conversion and merging ::processData()) + \param delflag if 1 the data are deleted, else left there for further processing (or plotting?) + */ + + void acquire(int delflag=1); + + /** + get current timer value on the stop socket + \param index timer index + \returns elapsed time value in ns or number of...(e.g. frames, gates, probes) + */ + + int64_t getTimeLeft(timerIndex index); + + /** + get run status on the stop socket + \returns status mask + */ + runStatus getRunStatus(); + + + /** + get current temperature + \returns current temperature + */ + + float getTemperature(int imod=0); + + private: + /** + start data processing thread + */ + void startThread(int delflag=1); // + /** the data processing thread */ + + pthread_t dataProcessingThread; + + /** sets when the acquisition is finished */ + int jointhread; + + /** data queue size */ + int queuesize; +}; + + + +static void* startProcessData(void *n); +static void* startProcessDataNoDelete(void *n); + +#endif diff --git a/slsDetectorSoftware/gotthardDetectorServer/.target-makefrag b/slsDetectorSoftware/gotthardDetectorServer/.target-makefrag new file mode 100755 index 000000000..ce093ecac --- /dev/null +++ b/slsDetectorSoftware/gotthardDetectorServer/.target-makefrag @@ -0,0 +1 @@ +AXIS_BUILDTYPE ?= cris-axis-linux-gnu diff --git a/slsDetectorSoftware/gotthardDetectorServer/Makefile b/slsDetectorSoftware/gotthardDetectorServer/Makefile new file mode 100755 index 000000000..5325f2879 --- /dev/null +++ b/slsDetectorSoftware/gotthardDetectorServer/Makefile @@ -0,0 +1,59 @@ +# $Id: Makefile,v 1.1.1.1 2006/02/04 03:35:01 freza Exp $ +# first compile +# make cris-axis-linux-gnu + + +CROSS = bfin-uclinux- +CC = $(CROSS)gcc + +CFLAGS += -Wall -DMCB_FUNCS -DVERBOSE -DVERY_VERBOSE #-DVIRTUAL + +#INCLUDES= /usr/src/kernels/2.6.18-238.12.1.el5-i686/include +#/home/l_maliakal_d/bfin/blackfin-linux-dist/linux-2.6.x/include +#/usr/include/asm/page.h + + +PROGS= gotthardDetectorServer + +INSTDIR= /tftpboot +INSTMODE= 0777 + + + +BINS = testlib_sharedlibc +SRCS = server.c server_funcs.c communication_funcs.c firmware_funcs.c mcb_funcs.c trimming_funcs.c sharedmemory.c +OBJS = $(SRCS:%.c=%.o) + + +#LDLIBS+= -lm + + + +all: clean $(PROGS) + +boot: $(OBJS) + +$(PROGS): $(OBJS) + echo $(OBJS) + $(CC) $(CFLAGS) -o $@ $^ $(LDLIBS_$@) $(LDFLAGS_$@) + + +install: $(PROGS) + $(INSTALL) -d $(INSTDIR) + $(INSTALL) -m $(INSTMODE) $(PROGS) $(INSTDIR) + + +#CFLAGS+= -Wall -DC_ONLY -DMCB_FUNCS +#-DVERBOSE +#-DVERYVERBOSE +#-Werror + + +clean: + rm -rf $(PROGS) *.o + + + + + + diff --git a/slsDetectorSoftware/gotthardDetectorServer/communication_funcs.c b/slsDetectorSoftware/gotthardDetectorServer/communication_funcs.c new file mode 100755 index 000000000..557630b74 --- /dev/null +++ b/slsDetectorSoftware/gotthardDetectorServer/communication_funcs.c @@ -0,0 +1,540 @@ + + +#include "communication_funcs.h" +#include +#include /* for TCP_NODELAY */ +#include +#include +#include +#include + + + +//int socketDescriptor, file_des; +int socketDescriptor, file_des; +const int send_rec_max_size=SEND_REC_MAX_SIZE; +extern int errno; + +//struct sockaddr_in address; +//#define VERBOSE + + +int bindSocket(unsigned short int port_number) { + int i; + + struct sockaddr_in addressS; + + + file_des= -1; + socketDescriptor = socket(AF_INET, SOCK_STREAM,0); //tcp + + //socketDescriptor = socket(PF_INET, SOCK_STREAM, 0); + + + + if (socketDescriptor < 0) { + printf("Cannot create socket..socketdescript less than 0\n"); + } else { + + i = 1; + setsockopt(socketDescriptor, SOL_SOCKET, SO_REUSEADDR, &i, sizeof(i)); + // setsockopt(socketDescriptor, IPPROTO_TCP, TCP_NODELAY, (char *) &i, sizeof(i)); + // TCP_CORK + + // Set some fields in the serverAddress structure. + addressS.sin_family = AF_INET; + addressS.sin_addr.s_addr = htonl(INADDR_ANY); + addressS.sin_port = htons(port_number); + + // memset(&address.sin_addr, 0, sizeof(address.sin_addr)); + + + if(bind(socketDescriptor,(struct sockaddr *) &addressS,sizeof(addressS))<0){ + + printf("Cannot create socket..did not bind\n"); + + socketDescriptor=-1; + } else { + listen(socketDescriptor, 5); + } + } + + + + + + + //int getrlimit(int resource, struct rlimit *rlim); + + + + + + + return socketDescriptor; + +} + + +/* +only client funcs +*/ +/* +#ifndef C_ONLY + +MySocketTCP::MySocketTCP(const char* const host_ip_or_name, unsigned short int const port_number): + last_keep_connection_open_action_was_a_send(0), file_des(-1), send_rec_max_size(SEND_REC_MAX_SIZE), is_a_server(0), portno(DEFAULT_PORTNO), socketDescriptor(-1) +{ // sender (client): where to? ip + //is_a_server = 0; + // SetupParameters(); + strcpy(hostname,host_ip_or_name); + portno=port_number; + struct hostent *hostInfo = gethostbyname(host_ip_or_name); + if (hostInfo == NULL){ + cerr << "Exiting: Problem interpreting host: " << host_ip_or_name << "\n"; + } else { + // Set some fields in the serverAddress structure. + serverAddress.sin_family = hostInfo->h_addrtype; + memcpy((char *) &serverAddress.sin_addr.s_addr, + hostInfo->h_addr_list[0], hostInfo->h_length); + serverAddress.sin_port = htons(port_number); + socketDescriptor=0; //You can use send and recv, //would it work????? + } +} + + +int MySocketTCP::getHostname(char *name) { + if (is_a_server==0) { + strcpy(name,hostname); + } + return is_a_server; +}; +#endif +*/ + + + + +int getServerError() +{ + if (socketDescriptor<0) return 1; + else return 0; +}; + + +int acceptConnection() { + struct sockaddr_in addressC; + //socklen_t address_length; + size_t address_length=sizeof(struct sockaddr_in); + + if(file_des>0) return file_des; + + + //#ifndef C_ONLY + // if(is_a_server){ //server; the server will wait for the clients connection + //#endif + + + if (socketDescriptor>0) { + //if ((file_des = accept(socketDescriptor,(struct sockaddr *) &addressC, &address_length)) < 0) { + if ((file_des = accept(socketDescriptor,(struct sockaddr *) &addressC, &address_length)) < 0) { + + + + printf("Error: with server accept, connection refused %d\n", errno); + + + switch(errno) { + case EWOULDBLOCK: + printf("ewouldblock eagain\n"); + break; + case EBADF: + printf("ebadf\n"); + break; + case ECONNABORTED: + printf("econnaborted\n"); + break; + case EFAULT: + printf("efault\n"); + break; + case EINTR: + printf("eintr\n"); + break; + case EINVAL: + printf("einval\n"); + break; + case EMFILE: + printf("emfile\n"); + break; + case ENFILE: + printf("enfile\n"); + break; + case ENOTSOCK: + printf("enotsock\n"); + break; + case EOPNOTSUPP: + printf("eOPNOTSUPP\n"); + break; + case ENOBUFS: + printf("ENOBUFS\n"); + break; + case ENOMEM: + printf("ENOMEM\n"); + break; + case ENOSR: + printf("ENOSR\n"); + break; + case EPROTO: + printf("EPROTO\n"); + break; + default: + printf("unknown error\n"); + } + + + socketDescriptor=-1; + } +#ifdef VERBOSE + printf("client connected %d\n", file_des); +#endif + } + + + return file_des; +} + + + + + + + +void closeConnection() { + //fflush(stdout); + //printf("Closing file_des %d\n", file_des); + //sleep(1); +#ifdef VERY_VERBOSE +#endif + if(file_des>=0) + close(file_des); + file_des=-1; +} + +void exitServer() { + if (socketDescriptor>=0) + close(socketDescriptor); +#ifdef VERY_VERBOSE + printf("Closing server\n"); +#endif + socketDescriptor=-1; +} + + + + +/* client close conenction */ +/* +#ifndef C_ONLY +void MySocketTCP::Disconnect(){ + + if(file_des>=0){ //then was open + if(is_a_server){ + close(file_des); + } + else { + close(socketDescriptor); + socketDescriptor=-1; + } + file_des=-1; + } + +} +#endif +*/ + + +int sendDataOnly(void* buf,int length) { + /* + int total_sent=0; + int nsending; + int nsent; + + +#ifdef VERY_VERBOSE + printf("want to send %d Bytes\n", length); +#endif + if (file_des<0) return -1; + + while(length>0){ + nsending = (length>send_rec_max_size) ? send_rec_max_size:length; + nsent = write(file_des,(char*)buf+total_sent,nsending); + if(!nsent) break; + length-=nsent; + total_sent+=nsent; + // cout<<"nsent: "<0){ + nreceiving = (length>send_rec_max_size) ? send_rec_max_size:length; + +#ifdef VERY_VERBOSE + printf("want to receive %d Bytes\n", nreceiving); +#endif + nreceived = read(file_des,(char*)buf+total_received,nreceiving); +#ifdef VERY_VERBOSE + printf("read %d \n", nreceived); +#endif + if(!nreceived) break; + // if(nreceived<0) break; + length-=nreceived; + total_received+=nreceived; + // cout<<"nrec: "<nchan; + ts+=sendDataOnly(myChip,sizeof(sls_detector_chip)); + ts+=sendDataOnly(myChip->chanregs,nChans*sizeof(int)); + return ts; +} + +int sendModule(sls_detector_module *myMod) { + int ts=0; + int idac; + int nChips=myMod->nchip; + int nChans=myMod->nchan; + int nAdcs=myMod->nadc; + int nDacs=myMod->ndac; + ts+= sendDataOnly(myMod,sizeof(sls_detector_module)); +#ifdef VERBOSE + printf("module %d of size %d sent\n",myMod->module, ts); +#endif + ts+= sendDataOnly(myMod->dacs,sizeof(float)*nDacs); +#ifdef VERBOSE + printf("dacs %d of size %d sent\n",myMod->module, ts); + for (idac=0; idac< nDacs; idac++) + printf("dac %d is %d\n",idac,myMod->dacs[idac]); +#endif + ts+= sendDataOnly(myMod->adcs,sizeof(float)*nAdcs); +#ifdef VERBOSE + printf("adcs %d of size %d sent\n",myMod->module, ts); +#endif + ts+=sendDataOnly(myMod->chipregs,sizeof(int)*nChips); +#ifdef VERBOSE + printf("chips %d of size %d sent\n",myMod->module, ts); +#endif + ts+=sendDataOnly(myMod->chanregs,sizeof(int)*nChans); +#ifdef VERBOSE + printf("chans %d of size %d sent - %d\n",myMod->module, ts, myMod->nchan); +#endif +#ifdef VERBOSE + printf("module %d of size %d sent register %x\n",myMod->module, ts, myMod->reg); +#endif + return ts; +} + +int receiveChannel(sls_detector_channel *myChan) { + return receiveDataOnly(myChan,sizeof(sls_detector_channel)); +} + +int receiveChip(sls_detector_chip* myChip) { + + int *ptr=myChip->chanregs; + int ts=0; + int nChans, nchanold=myChip->nchan, chdiff; + + ts+= receiveDataOnly(myChip,sizeof(sls_detector_chip)); + + + myChip->chanregs=ptr; + nChans=myChip->nchan; + chdiff=nChans-nchanold; + if (nchanold!=nChans) { + printf("wrong number of channels received!\n"); + } + + +#ifdef VERBOSE + printf("chip structure received\n"); + printf("now receiving %d channels\n", nChans); +#endif + + if (chdiff<=0) + ts+=receiveDataOnly(myChip->chanregs, sizeof(int)*nChans); + else { + ptr=malloc(chdiff*sizeof(int)); + myChip->nchan=nchanold; + ts+=receiveDataOnly(myChip->chanregs, sizeof(int)*nchanold); + ts+=receiveDataOnly(ptr, sizeof(int)*chdiff); + free(ptr); + return FAIL; + } + +#ifdef VERBOSE + printf("chip's channels received\n"); +#endif + return ts; +} + +int receiveModule(sls_detector_module* myMod) { + + + float *dacptr=myMod->dacs; + float *adcptr=myMod->adcs; + int *chipptr=myMod->chipregs, *chanptr=myMod->chanregs; + int ts=0; + int nChips, nchipold=myMod->nchip, nchipdiff; + int nChans, nchanold=myMod->nchan, nchandiff; + int nDacs, ndold=myMod->ndac, ndacdiff; + int nAdcs, naold=myMod->nadc, nadcdiff; + + + ts+= receiveDataOnly(myMod,sizeof(sls_detector_module)); + + myMod->dacs=dacptr; + myMod->adcs=adcptr; + myMod->chipregs=chipptr; + myMod->chanregs=chanptr; + + nChips=myMod->nchip; + nchipdiff=nChips-nchipold; + if (nchipold!=nChips) { + printf("received wrong number of chips\n"); + } +#ifdef VERBOSE + else + printf("received %d chips\n",nChips); +#endif + + nChans=myMod->nchan; + nchandiff=nChans-nchanold; + if (nchanold!=nChans) { + printf("received wrong number of channels\n"); + } +#ifdef VERBOSE + else + printf("received %d chans\n",nChans); +#endif + + + nDacs=myMod->ndac; + ndacdiff=nDacs-ndold; + if (ndold!=nDacs) { + printf("received wrong number of dacs\n"); + } +#ifdef VERBOSE + else + printf("received %d dacs\n",nDacs); +#endif + + nAdcs=myMod->nadc; + nadcdiff=nAdcs-naold; + if (naold!=nAdcs) { + printf("received wrong number of adcs\n"); + } +#ifdef VERBOSE + else + printf("received %d adcs\n",nAdcs); +#endif + if (ndacdiff<=0) { + ts+=receiveDataOnly(myMod->dacs, sizeof(float)*nDacs); +#ifdef VERBOSE + printf("dacs received\n"); +#endif + } else { + dacptr=malloc(ndacdiff*sizeof(float)); + myMod->ndac=ndold; + ts+=receiveDataOnly(myMod->dacs, sizeof(float)*ndold); + ts+=receiveDataOnly(dacptr, sizeof(float)*ndacdiff); + free(dacptr); + return FAIL; + } + + if (nadcdiff<=0) { + ts+=receiveDataOnly(myMod->adcs, sizeof(float)*nAdcs); +#ifdef VERBOSE + printf("adcs received\n"); +#endif + } else { + adcptr=malloc(nadcdiff*sizeof(float)); + myMod->nadc=naold; + ts+=receiveDataOnly(myMod->adcs, sizeof(float)*naold); + ts+=receiveDataOnly(adcptr, sizeof(float)*nadcdiff); + free(adcptr); + return FAIL; + } + + if (nchipdiff<=0) { + ts+=receiveDataOnly(myMod->chipregs, sizeof(int)*nChips); +#ifdef VERBOSE + printf("chips received\n"); +#endif + } else { + chipptr=malloc(nchipdiff*sizeof(int)); + myMod->nchip=nchipold; + ts+=receiveDataOnly(myMod->chipregs, sizeof(int)*nchipold); + ts+=receiveDataOnly(chipptr, sizeof(int)*nchipdiff); + free(chipptr); + return FAIL; + } + + if (nchandiff<=0) { + ts+=receiveDataOnly(myMod->chanregs, sizeof(int)*nChans); +#ifdef VERBOSE + printf("chans received\n"); +#endif + } else { + chanptr=malloc(nchandiff*sizeof(int)); + myMod->nchan=nchanold; + ts+=receiveDataOnly(myMod->chanregs, sizeof(int)*nchanold); + ts+=receiveDataOnly(chanptr, sizeof(int)*nchandiff); + free(chanptr); + return FAIL; + } +#ifdef VERBOSE + printf("received module %d of size %d register %x\n",myMod->module,ts,myMod->reg); +#endif + return ts; +} diff --git a/slsDetectorSoftware/gotthardDetectorServer/communication_funcs.h b/slsDetectorSoftware/gotthardDetectorServer/communication_funcs.h new file mode 100755 index 000000000..a1dee9b73 --- /dev/null +++ b/slsDetectorSoftware/gotthardDetectorServer/communication_funcs.h @@ -0,0 +1,32 @@ +#ifndef COMMUNICATION_FUNCS_H +#define COMMUNICATION_FUNCS_H + +#define SEND_REC_MAX_SIZE 4096 +#define DEFAULT_PORTNO 1955 +#include +#include + + +#include +#include +#include +#include + +#include "sls_detector_defs.h" + +int bindSocket(unsigned short int port_number); +int acceptConnection(); +void closeConnection(); +void exitServer(); +int sendDataOnly(void* buf,int length); +int receiveDataOnly(void* buf,int length); + +int getServerError(); +int sendChannel(sls_detector_channel *myChan); +int sendChip(sls_detector_chip *myChip); +int sendModule(sls_detector_module *myMod); +int receiveChannel(sls_detector_channel *myChan); +int receiveChip(sls_detector_chip* myChip); +int receiveModule(sls_detector_module* myMod); + +#endif diff --git a/slsDetectorSoftware/gotthardDetectorServer/firmware_funcs.c b/slsDetectorSoftware/gotthardDetectorServer/firmware_funcs.c new file mode 100755 index 000000000..13e97ae69 --- /dev/null +++ b/slsDetectorSoftware/gotthardDetectorServer/firmware_funcs.c @@ -0,0 +1,1361 @@ +#ifndef PICASSOD +#include "server_defs.h" +#else +#include "picasso_defs.h" +#endif + +#include "firmware_funcs.h" +#include "mcb_funcs.h" +#include "registers_g.h" + +#ifdef SHAREDMEMORY +#include "sharedmemory.h" +#endif + +#include +#include +#include + + +//for memory mapping +u_int32_t CSP0BASE; + +FILE *debugfp, *datafp; + +int fr; +int wait_time; +int *fifocntrl; +int *values; +int *statusreg; +const int nModY=1; +int nModBoard; +int nModX=NMAXMOD; +int dynamicRange=32; +int dataBytes=NMAXMOD*NCHIP*NCHAN*4; +int storeInRAM=0; +int *ram_values=NULL; +char *now_ptr=NULL; +int ram_size=0; + +int64_t totalTime=1; +u_int32_t progressMask=0; + + + +int ififostart, ififostop, ififostep, ififo; + + +#ifdef MCB_FUNCS +extern const int nChans; +extern const int nChips; +extern const int nDacs; +extern const int nAdcs; +#endif +#ifndef MCB_FUNCS + +const int nChans=NCHAN; +const int nChips=NCHIP; +const int nDacs=NDAC; +const int nAdcs=NADC; +#endif + +//int mybyte; +//int mysize=dataBytes/8; + +int dacVals[NDAC]; + + +int mapCSP0(void) { + printf("Mapping memory\n"); +#ifndef VIRTUAL + int fd; + fd = open("/dev/mem", O_RDWR | O_SYNC, 0); + if (fd == -1) { + printf("\nCan't find /dev/mem!\n"); + return FAIL; + } + printf("/dev/mem opened\n"); + + CSP0BASE = (u_int32_t)mmap(0, MEM_SIZE, PROT_READ|PROT_WRITE, MAP_FILE|MAP_SHARED, fd, CSP0); + if (CSP0BASE == (u_int32_t)MAP_FAILED) { + printf("\nCan't map memmory area!!\n"); + return FAIL; + } + printf("CSP0 mapped\n"); + +#endif +#ifdef VIRTUAL + CSP0BASE = (u_int32_t)malloc(MEM_SIZE); + printf("memory allocated\n"); +#endif +#ifdef SHAREDMEMORY + if ( (res=inism(SMSV))<0) { + printf("error attaching shared memory! %i",res); + return FAIL; + } +#endif + printf("CSPObase is 0x%x \n",CSP0BASE); + printf("CSPOBASE=from %08x to %x\n",CSP0BASE,CSP0BASE+MEM_SIZE); + + /* must b uncommented later//////////////////////////////////////////////////////// + values=(u_int32_t*)(CSP0BASE+FIFO_DATA_REG_OFF); + printf("values=%08x\n",values); + fifocntrl=(u_int32_t*)(CSP0BASE+FIFO_CNTRL_REG_OFF); + printf("fifcntrl=%08x\n",fifocntrl); + statusreg=(u_int32_t*)(CSP0BASE+STATUS_REG); + printf("statusreg=%08x\n",statusreg); + */ + return OK; +} + + +int setDummyRegister() { + int result = OK; + /* + //to check if the dac really works with aldos code + int dacnum,dacvalue=700; + u_int32_t offw,codata; + u_int16_t valw; + int iru,i,ddx,csdx,cdx; + offw=0x37; + for(dacnum=0;dacnum<8;dacnum++) + { + ddx=2; csdx=0; cdx=1; + codata=((((0x2)<<4)+((dacnum)&0xf))<<16)+((dacvalue<<4)&0xfff0); + + valw=0xffff; bus_w(offw,(valw)); // start point + valw=((valw&(~(0x1<>(24-i))&0x1)<>(24-i))&0x1)); + valw=((valw&(~(0x1<>2)&0x1,(data>>1)&0x1 ,(data>>0)&0x1); + + *ptr1=data; + return OK; +} + + +u_int32_t bus_w(u_int32_t offset, u_int32_t data) { + u_int32_t *ptr1; + + ptr1=(u_int32_t*)(CSP0BASE+offset*2); + *ptr1=data; + + return OK; +} + + +u_int32_t bus_r(u_int32_t offset) { + u_int32_t *ptr1; + + ptr1=(u_int32_t*)(CSP0BASE+offset*2); + return *ptr1; +} + +// direct pattern output +u_int32_t putout(char *s, int modnum) { + int i; + u_int32_t pat; + int addr; + + if (strlen(s)<16) { + fprintf(stdout," *** putout error: incorrect pattern length ***\n"); + fprintf(stdout," %s \n",s); + return FAIL; + } + + pat=0; + for (i=0;i<16;i++) { + if (s[i]=='1') pat=pat+(1<<(15-i)); + } + //addr=MCB_CNTRL_REG_OFF+(modnum<<4); + addr=MCB_CNTRL_REG_OFF;//+(modnum<>CLK_DIVIDER_OFFSET); +} + +u_int32_t getClockDivider() { + u_int32_t clk_div; + clk_div=((bus_r(SPEED_REG)&CLK_DIVIDER_MASK)>>CLK_DIVIDER_OFFSET); + return clk_div; +} + +u_int32_t setSetLength(int d) { + u_int32_t c; + c=bus_r(SPEED_REG); + bus_w(SPEED_REG,(d<>SET_LENGTH_OFFSET); +} + +u_int32_t getSetLength() { + u_int32_t clk_div; + clk_div=((bus_r(SPEED_REG)& SET_LENGTH_MASK)>>SET_LENGTH_OFFSET); + return clk_div; +} + + +u_int32_t setWaitStates(int d1) { + u_int32_t c; + int d=d1-2; + //int d=d1-3; + char cmd[100]; + if (d1<=0xf) { + sprintf(cmd,"bus -a 0xb0000000 -w 0x%x0008",d1); + c=bus_r(SPEED_REG); + bus_w(SPEED_REG,(d<>WAIT_STATES_OFFSET)+2; +} + +u_int32_t getWaitStates() { + u_int32_t clk_div; + clk_div=((bus_r(SPEED_REG)& WAIT_STATES_MASK)>>WAIT_STATES_OFFSET); + return clk_div+2; +} + + +u_int32_t setTotClockDivider(int d) { + u_int32_t c; + c=bus_r(SPEED_REG); + bus_w(SPEED_REG,(d<>TOTCLK_DIVIDER_OFFSET); +} + +u_int32_t getTotClockDivider() { + u_int32_t clk_div; + clk_div=((bus_r(SPEED_REG)&TOTCLK_DIVIDER_MASK)>>TOTCLK_DIVIDER_OFFSET); + return clk_div; +} + + +u_int32_t setTotDutyCycle(int d) { + u_int32_t c; + c=bus_r(SPEED_REG); + bus_w(SPEED_REG,(d<>TOTCLK_DUTYCYCLE_OFFSET); +} + +u_int32_t getTotDutyCycle() { + u_int32_t clk_div; + clk_div=((bus_r(SPEED_REG)&TOTCLK_DUTYCYCLE_MASK)>>TOTCLK_DUTYCYCLE_OFFSET); + return clk_div; +} + + +u_int32_t setExtSignal(int d, enum externalSignalFlag mode) { + + int modes[]={EXT_SIG_OFF, EXT_GATE_IN_ACTIVEHIGH, EXT_GATE_IN_ACTIVELOW,EXT_TRIG_IN_RISING,EXT_TRIG_IN_FALLING,EXT_RO_TRIG_IN_RISING, EXT_RO_TRIG_IN_FALLING,EXT_GATE_OUT_ACTIVEHIGH, EXT_GATE_OUT_ACTIVELOW, EXT_TRIG_OUT_RISING, EXT_TRIG_OUT_FALLING, EXT_RO_TRIG_OUT_RISING, EXT_RO_TRIG_OUT_FALLING}; + + u_int32_t c; + int off=d*SIGNAL_OFFSET; + c=bus_r(EXT_SIGNAL_REG); + if (mode<=RO_TRIGGER_OUT_FALLING_EDGE && mode>=0) + bus_w(EXT_SIGNAL_REG,((modes[mode])<>off); + + if (mode=0) { + bus_w(CONFIG_REG,d); + } +#ifdef VERBOSE + printf("configuration register is %x", bus_r(CONFIG_REG)); +#endif + return bus_r(CONFIG_REG); +} + +int setToT(int d) { + int ret=0; + int reg; +#ifdef VERBOSE + printf("Setting ToT to %d\n",d); +#endif + reg=bus_r(CONFIG_REG); +#ifdef VERBOSE + printf("Before: ToT is %x\n", reg); +#endif + if (d>0) { + bus_w(CONFIG_REG,reg|TOT_ENABLE_BIT); + } else if (d==0) { + bus_w(CONFIG_REG,reg&(~TOT_ENABLE_BIT)); + } + reg=bus_r(CONFIG_REG); +#ifdef VERBOSE + printf("ToT is %x\n", reg); +#endif + if (reg&TOT_ENABLE_BIT) + return 1; + else + return 0; +} + +int setContinousReadOut(int d) { + int ret=0; + int reg; +#ifdef VERBOSE + printf("Setting Continous readout to %d\n",d); +#endif + reg=bus_r(CONFIG_REG); +#ifdef VERBOSE + printf("Before: Continous readout is %x\n", reg); +#endif + if (d>0) { + bus_w(CONFIG_REG,reg|CONT_RO_ENABLE_BIT); + } else if (d==0) { + bus_w(CONFIG_REG,reg&(~CONT_RO_ENABLE_BIT)); + } + reg=bus_r(CONFIG_REG); +#ifdef VERBOSE + printf("Continous readout is %x\n", reg); +#endif + if (reg&CONT_RO_ENABLE_BIT) + return 1; + else + return 0; +} + + +u_int64_t getMcsNumber() { + + FILE *fp=NULL; + u_int64_t res; + char line[150]; + int a[6]; + + int n=0, i; + //u_int64_t a0,a1,a2,a3,a4,a5,n=0; + fp=fopen("/etc/conf.d/mac","r"); + if (fp==NULL) { + printf("could not ope MAC file\n");; + return -1; + } + while (fgets(line,150,fp)) { + //MAC="00:40:8C:CD:00:00" + printf(line); + if (strstr(line,"MAC=")) + n=sscanf(line,"MAC=\"%x:%x:%x:%x:%x:%x\"",a+5,a+4,a+3,a+2,a+1,a); + } + fclose(fp); + if (n!=6){ + printf("could not scan MAC address\n");; + return -1; + } + res=0; + for (i=0; i=(FPGA_VERSION_VAL&0x00ffffff)) { + printf("FPGA version ok!! %06x\n",val); + } else { + printf("FPGA version too old! %06x\n",val); + return FAIL; + } + //dummy register + val=0xF0F0F0F0; + bus_w(DUMMY_REG, val); + val=bus_r(DUMMY_REG); + if (val==0xF0F0F0F0) { + printf("FPGA dummy register ok!! %x\n",val); + } else { + printf("FPGA dummy register wrong!! %x instead of 0xF0F0F0F0 \n",val); + result=FAIL; + // return FAIL; + } + //dummy register + val=0x0F0F0F0F; + bus_w(DUMMY_REG, val); + val=bus_r(DUMMY_REG); + if (val==0x0F0F0F0F) { + printf("FPGA dummy register ok!! %x\n",val); + } else { + printf("FPGA dummy register wrong!! %x instead of 0x0F0F0F0F \n",val); + result=FAIL; + // return FAIL; + } + // } + + return result; +} + + +// for fpga test +u_int32_t testRAM(void) { + int result=OK; + int i=0; + allocateRAM(); + // while(i<100000) { + memcpy(ram_values, values, dataBytes); + printf ("%d: copied fifo %x to memory %x size %d\n",i++, values, ram_values, dataBytes); + // } + return result; +} + +int getNModBoard() { + int nmodboard; + u_int32_t val; + val=bus_r(FPGA_VERSION_REG)&0xff000000; + + printf("version register %08x\n",val); + nmodboard = 1;//val >> 24; + //#ifdef VERY_VERBOSE + printf("The board hosts %d modules\n",nmodboard); + nmodboard=1;//edited by dhanya + //#endif + nModBoard=nmodboard; + //getNModBoard()=nmodboard; + return nmodboard; +} + +int setNMod(int n) { + + int fifo; + // int ifsta, ifsto, ifste; + int imod; + int rval; + int reg; + int nf=0; + int shiftfifo=SHIFTFIFO; + int ntot=getNModBoard(); + if (getProbes()==0) { + switch (dynamicRange) { + case 16: + shiftfifo=SHIFTFIFO-1; + break; + case 8: + shiftfifo=SHIFTFIFO-2; + break; + case 4: + shiftfifo=SHIFTFIFO-3; + break; + case 1: + shiftfifo=SHIFTFIFO-5; + break; + default: + shiftfifo=SHIFTFIFO; + } + } else + shiftfifo=SHIFTFIFO; + + +#ifdef VERBOSE + printf("SetNMod called arg %d -- dr %d shiftfifo %d\n",n,dynamicRange,shiftfifo); +#endif + if (n>0 && n<=ntot) { + nModX=n; + + /*d isable the fifos relative to the unused modules */ + for (ififo=0; ififo>FIFO_NM_OFF, (reg&FIFO_NC_MASK)>>FIFO_NC_OFF, FIFO_COUNTR_REG_OFF+(ififo<>FIFO_NM_OFF, (reg&FIFO_NC_MASK)>>FIFO_NC_OFF, FIFO_COUNTR_REG_OFF+(ififo<> 32; + vMSB=v64&(0xffffffff); + bus_w(aMSB,vMSB); + } + return get64BitReg(aLSB, aMSB); + +} + +int64_t get64BitReg(int aLSB, int aMSB){ + int64_t v64; + u_int32_t vLSB,vMSB; + vLSB=bus_r(aLSB); + vMSB=bus_r(aMSB); + v64=vMSB; + v64=(v64<<32) | vLSB; + return v64; +} + +int64_t setFrames(int64_t value){ + return set64BitReg(value, SET_FRAMES_LSB_REG, SET_FRAMES_MSB_REG); +} + +int64_t getFrames(){ + return get64BitReg(GET_FRAMES_LSB_REG, GET_FRAMES_MSB_REG); +} + +int64_t setExposureTime(int64_t value){ + /* time is in ns */ + if (value!=-1) + value*=(1E-9*CLK_FREQ); + return set64BitReg(value,SET_EXPTIME_LSB_REG, SET_EXPTIME_MSB_REG)/(1E-9*CLK_FREQ); +} + +int64_t getExposureTime(){ + return get64BitReg(GET_EXPTIME_LSB_REG, GET_EXPTIME_MSB_REG)/(1E-9*CLK_FREQ); +} + +int64_t setGates(int64_t value){ + return set64BitReg(value, SET_GATES_LSB_REG, SET_GATES_MSB_REG); +} + +int64_t getGates(){ + return get64BitReg(GET_GATES_LSB_REG, GET_GATES_MSB_REG); +} + +int64_t setPeriod(int64_t value){ + /* time is in ns */ + if (value!=-1) { + value*=(1E-9*CLK_FREQ); + } + + + + return set64BitReg(value,SET_PERIOD_LSB_REG, SET_PERIOD_MSB_REG)/(1E-9*CLK_FREQ); +} + +int64_t getPeriod(){ + return get64BitReg(GET_PERIOD_LSB_REG, GET_PERIOD_MSB_REG)/(1E-9*CLK_FREQ); +} + +int64_t setDelay(int64_t value){ + /* time is in ns */ + if (value!=-1) { + value*=(1E-9*CLK_FREQ); + } + return set64BitReg(value,SET_DELAY_LSB_REG, SET_DELAY_MSB_REG)/(1E-9*CLK_FREQ); +} + +int64_t getDelay(){ + return get64BitReg(GET_DELAY_LSB_REG, GET_DELAY_MSB_REG)/(1E-9*CLK_FREQ); +} + +int64_t setTrains(int64_t value){ + return set64BitReg(value, SET_TRAINS_LSB_REG, SET_TRAINS_MSB_REG); +} + +int64_t getTrains(){ + return get64BitReg(GET_TRAINS_LSB_REG, GET_TRAINS_MSB_REG); +} + + +int64_t setProbes(int64_t value){ + int ow; + int nm=setNMod(-1); + switch (getDynamicRange()) { + case 32: + ow=1; + break; + case 16: + ow=2; + break; + case 8: + ow=3; + break; + case 4: + ow=4; + break; + case 1: + ow=5; + break; + default: + ow=1; + } + if (value>=0) { + setCSregister(ALLMOD); + initChipWithProbes(0, ow,value, ALLMOD); + putout("0000000000000000",ALLMOD); + setNMod(nm); + getDynamicRange(); // needed to change dataBytes + } + return getProbes(); +} + + +int64_t setProgress() { + + //????? eventually call after setting the registers + +} + + +int64_t getProgress() { + + + //should be done in firmware!!!! + + +} + + + +int64_t getProbes(){ + u_int32_t shiftin=bus_r(GET_SHIFT_IN_REG); + u_int32_t np=(shiftin >>PROBES_OFF) & PROBES_MASK; +#ifdef VERYVERBOSE + printf("%08x ",shiftin); + printf("probes==%01x\n",np); +#endif + + return np; + +} + + +int setDACRegister(int idac, int val, int imod) { + u_int32_t addr, reg, mask; + int off; +#ifdef VERBOSE + printf("\ninside setdacref.....\n"); + printf("val=%d\n",val); + printf("Settings dac %d module %d register to %d\n",idac,imod,val); +#endif + + // addr=DUMMY_REG; + //off=0; + switch(idac){ + case 0: + case 1: + case 2: + addr=MOD_DACS1_REG; + break; + case 3: + case 4: + case 5: + addr=MOD_DACS2_REG; + break; + case 6: + case 7: + addr=MOD_DACS3_REG; + break; + default: + printf("weird idac value %d\n",idac); + return -1; + break; + } + + off=(idac%3)*10; + mask=~((0x3ff)<=0 && val>off)&0x3ff; + //val=(bus_r(addr)>>off)&0x3ff; + + +#ifdef VERBOSE + printf("Dac %d module %d register is %d\n\n",idac,imod,val); +#endif + return val; +} + + + + +u_int32_t runBusy(void) { + return bus_r(STATUS_REG)&RUN_BUSY_BIT; +} + +u_int32_t dataPresent(void) { + return bus_r(LOOK_AT_ME_REG); +} + +u_int32_t runState(void) { + int s=bus_r(STATUS_REG); +#ifdef SHAREDMEMORY + if (s&RUN_BUSY_BIT) + write_status_sm("Running"); + else + write_status_sm("Stopped"); +#endif +#ifdef VERBOSE + printf("status %08x\n",s); +#endif + return s; +} + + +// State Machine + +u_int32_t startStateMachine(){ +#ifdef VERBOSE + printf("Starting State Machine\n"); +#endif + // fifoReset(); printf("Starting State Machine\n"); + now_ptr=(char*)ram_values; +#ifdef SHAREDMEMORY + write_stop_sm(0); + write_status_sm("Started"); +#endif +#ifdef MCB_FUNCS + // setCSregister(ALLMOD); + clearSSregister(ALLMOD); +#endif + putout("0000000000000000",ALLMOD); + bus_w(CONTROL_REG, START_ACQ_BIT | START_EXPOSURE_BIT); + return OK; +} + + + + +u_int32_t stopStateMachine(){ + +#ifdef VERBOSE + printf("Stopping State Machine\n"); +#endif +#ifdef SHAREDMEMORY + write_stop_sm(1); + write_status_sm("Stopped"); +#endif + bus_w(CONTROL_REG, STOP_ACQ_BIT); + usleep(500); + if (!runBusy()) + return OK; + else + return FAIL; +} + + +u_int32_t startReadOut(){ + u_int32_t status; +#ifdef VERBOSE + printf("Starting State Machine Readout\n"); +#endif + status=bus_r(STATUS_REG)&RUN_BUSY_BIT; +#ifdef DEBUG + printf("State machine status is %08x\n",bus_r(STATUS_REG)); +#endif + bus_w(CONTROL_REG, START_ACQ_BIT |START_READOUT_BIT); // start readout + return OK; +} + + +// fifo routines + +u_int32_t fifoReset(void) { +#ifdef DEBUG + printf("resetting fifo\n"); +#endif + bus_w(FIFO_CNTRL_REG_OFF+(ALLFIFO<128) + printf("chip %d ch %d %d\n",ichip/128, ichip%128, (fifoReadCounter(ichip/128)&FIFO_COUNTER_MASK)); +#endif + } + //#endif + */ + + + +#ifdef VERYVERBOSE + printf("Copying to ptr %x %d\n",now_ptr, dataBytes); +#endif +#ifdef VERYVERBOSE + printf("after readout %08x %08x\n", runState(), bus_r(LOOK_AT_ME_REG)); + for (ichip=0; ichip0) { + now_ptr+=dataBytes; + } + return ram_values; +} + + + +u_int32_t* decode_data(int *datain) +{ + u_int32_t *dataout; + const char one=1; + const int bytesize=8; + char *ptr=(char*)datain; + //int nbits=dynamicRange; + int ipos=0, ichan=0;; + //int nch, boff=0; + int ibyte, ibit; + char iptr; + +#ifdef VERBOSE + printf("Decoding data for DR %d\n",dynamicRange); +#endif + dataout=malloc(nChans*nChips*nModX*4); + ichan=0; + switch (dynamicRange) { + case 1: + for (ibyte=0; ibyte>(ipos))&0x1; + ichan++; + } + } + break; + case 4: + for (ibyte=0; ibyte>(ipos*4))&0xf; + ichan++; + } + } + break; + case 8: + for (ichan=0; ichan0) { + nm=setNMod(-1); + if (dr==1) { + dynamicRange=1; + ow=5; + } else if (dr<=4) { + dynamicRange=4; + ow=4; + } else if (dr<=8) { + dynamicRange=8; + ow=3; + } else if (dr<=16) { + dynamicRange=16; + ow=2; + } else { + dynamicRange=32; + ow=0; //or 1? + } + setCSregister(ALLMOD); + initChipWithProbes(0, ow,np, ALLMOD); + putout("0000000000000000",ALLMOD); + setNMod(nm); + } + + + return getDynamicRange(); +} + + + + + + +int getDynamicRange() { + int dr; + u_int32_t shiftin=bus_r(GET_SHIFT_IN_REG); + u_int32_t outmux=(shiftin >> OUTMUX_OFF) & OUTMUX_MASK; + u_int32_t probes=(shiftin >> PROBES_OFF) & PROBES_MASK; +#ifdef VERYVERBOSE + printf("%08x ",shiftin); + printf("outmux=%02x probes=%d\n",outmux,probes); +#endif + + switch (outmux) { + case 2: + dr=16; + break; + case 4: + dr=8; + break; + case 8: + dr=4; + break; + case 16: + dr=1; + break; + default: + dr=32; + } + dynamicRange=dr; + if (probes==0) { + dataBytes=nModX*nModY*NCHIP*NCHAN*dynamicRange/8; + } else { + dataBytes=nModX*nModY*NCHIP*NCHAN*4;/// + } +#ifdef VERBOSE + printf("Number of data bytes %d - probes %d dr %d\n", dataBytes, probes, dr); +#endif + if (allocateRAM()==OK) { + ; + } else + printf("ram not allocated\n"); + + return dynamicRange; + +} + +int testBus() { + u_int32_t j; + u_int64_t i, n, nt; + char cmd[100]; + u_int32_t val=0x0; + int ifail=OK; + // printf("%s\n",cmd); + // system(cmd); + i=0; + + n=1000000; + nt=n/100; + printf("testing bus %d times\n",n); + while (i0) + storeInRAM=1; + else + storeInRAM=0; + return allocateRAM(); +} + + +int allocateRAM() { + size_t size; + u_int32_t nt, nf; + nt=setTrains(-1); + nf=setFrames(-1); + if (nt==0) nt=1; + if (nf==0) nf=1; + // ret=clearRAM(); + if (storeInRAM) { + size=dataBytes*nf*nt; + if (size +#include +#include +#include +#include +#include +#include +//#include +#include +#include +#include +#include +#include +#include + + +int mapCSP0(void); +int setDummyRegister(); +u_int16_t bus_w16(u_int32_t offset, u_int16_t data);//aldos function +u_int32_t bus_w(u_int32_t offset, u_int32_t data); +u_int32_t bus_r(u_int32_t offset); + + +u_int32_t putout(char *s, int modnum); +u_int32_t readin(int modnum); +u_int32_t setClockDivider(int d); +u_int32_t getClockDivider(); +u_int32_t setSetLength(int d); +u_int32_t getSetLength(); +u_int32_t setWaitStates(int d); +u_int32_t getWaitStates(); +u_int32_t setTotClockDivider(int d); +u_int32_t getTotClockDivider(); +u_int32_t setTotClockDutyCycle(int d); +u_int32_t getTotClockDutyCycle(); + +u_int32_t setExtSignal(int d, enum externalSignalFlag mode); +int getExtSignal(int d); +int setConfigurationRegister(int d); +int setToT(int d); +int setContinousReadOut(int d); + +int setDACRegister(int idac, int val, int imod); + + +u_int64_t getMcsNumber(); +u_int32_t getMcsVersion(); +u_int32_t testFifos(void); +u_int32_t testFpga(void); +u_int32_t testRAM(void); +int testBus(void); +int64_t set64BitReg(int64_t value, int aLSB, int aMSB); +int64_t get64BitReg(int aLSB, int aMSB); + +int64_t setFrames(int64_t value); +int64_t getFrames(); + +int64_t setExposureTime(int64_t value); +int64_t getExposureTime(); + +int64_t setGates(int64_t value); +int64_t getGates(); + +int64_t setDelay(int64_t value); +int64_t getDelaye(); + +int64_t setPeriod(int64_t value); +int64_t getPeriod(); + +int64_t setTrains(int64_t value); +int64_t getTrains(); + +int64_t setProbes(int64_t value); +int64_t getProbes(); + +int64_t getProgress(); +int64_t setProgress(); + + + +u_int32_t runBusy(void); +u_int32_t runState(void); +u_int32_t dataPresent(void); + + +u_int32_t startStateMachine(); +u_int32_t stopStateMachine(); +u_int32_t startReadOut(); +u_int32_t fifoReset(void); +u_int32_t fifoReadCounter(int fifonum); +u_int32_t fifoReadStatus(); + + +u_int32_t fifo_full(void); + + + +u_int32_t* fifo_read_event(); +u_int32_t* decode_data(int* datain); +//u_int32_t move_data(u_int64_t* datain, u_int64_t* dataout); +int setDynamicRange(int dr); +int getDynamicRange(); +int getNModBoard(); +int setNMod(int n); +int setStoreInRAM(int b); +int allocateRAM(); +int clearRAM(); + +/* + +u_int32_t setNBits(u_int32_t); +u_int32_t getNBits(); +*/ + +/* +//move to mcb_funcs? + +int readOutChan(int *val); +u_int32_t getModuleNumber(int modnum); +int testShiftIn(int imod); +int testShiftOut(int imod); +int testShiftStSel(int imod); +int testDataInOut(int num, int imod); +int testExtPulse(int imod); +int testExtPulseMux(int imod, int ow); +int testDataInOutMux(int imod, int ow, int num); +int testOutMux(int imod); +int testFpgaMux(int imod); +int calibration_sensor(int num, int *values, int *dacs) ; +int calibration_chip(int num, int *values, int *dacs); +*/ + + +#endif diff --git a/slsDetectorSoftware/gotthardDetectorServer/mcb_funcs.c b/slsDetectorSoftware/gotthardDetectorServer/mcb_funcs.c new file mode 100755 index 000000000..e7f764f40 --- /dev/null +++ b/slsDetectorSoftware/gotthardDetectorServer/mcb_funcs.c @@ -0,0 +1,2581 @@ +#ifdef MCB_FUNCS + +#include +#include +#include +#include +#include +#include "registers_g.h" + +#ifndef PICASSOD +#include "server_defs.h" +#else +#include "picasso_defs.h" +#endif +#include "firmware_funcs.h" +#include "mcb_funcs.h" + +/* global variables */ +#undef DEBUG +#undef DEBUGOUT + +extern int nModX; +extern int dataBytes; +extern int dynamicRange; +const int nChans=NCHAN; +const int nChips=NCHIP; +const int nDacs=NDAC; +const int nAdcs=NADC; +const enum detectorType myDetectorType=GOTTHARD; +enum detectorSettings thisSettings; + +int sChan, sChip, sMod, sDac, sAdc; +const int allSelected=-2; +const int noneSelected=-1; + + +sls_detector_module *detectorModules=NULL; +int *detectorChips=NULL; +int *detectorChans=NULL; +float *detectorDacs=NULL; +float *detectorAdcs=NULL; +//int numberOfProbes; + + + +int initDetector() { + + int imod; + // sls_detector_module *myModule; + int n=getNModBoard(); + nModX=n; + +#ifdef VERBOSE + printf("Board is for %d modules\n",n); +#endif + detectorModules=malloc(n*sizeof(sls_detector_module)); + detectorChips=malloc(n*NCHIP*sizeof(int)); + detectorChans=malloc(n*NCHIP*NCHAN*sizeof(int)); + detectorDacs=malloc(n*NDAC*sizeof(float)); + detectorAdcs=malloc(n*NADC*sizeof(float)); +#ifdef VERBOSE + printf("modules from 0x%x to 0x%x\n",detectorModules, detectorModules+n); + printf("chips from 0x%x to 0x%x\n",detectorChips, detectorChips+n*NCHIP); + printf("chans from 0x%x to 0x%x\n",detectorChans, detectorChans+n*NCHIP*NCHAN); + printf("dacs from 0x%x to 0x%x\n",detectorDacs, detectorDacs+n*NDAC); + printf("adcs from 0x%x to 0x%x\n",detectorAdcs, detectorAdcs+n*NADC); +#endif + for (imod=0; imoddacs=detectorDacs+imod*NDAC; + (detectorModules+imod)->adcs=detectorAdcs+imod*NADC; + (detectorModules+imod)->chipregs=detectorChips+imod*NCHIP; + (detectorModules+imod)->chanregs=detectorChans+imod*NCHIP*NCHAN; + (detectorModules+imod)->ndac=NDAC; + (detectorModules+imod)->nadc=NADC; + (detectorModules+imod)->nchip=NCHIP; + (detectorModules+imod)->nchan=NCHIP*NCHAN; + (detectorModules+imod)->module=imod; + (detectorModules+imod)->gain=0; + (detectorModules+imod)->offset=0; + (detectorModules+imod)->reg=0; + /* initialize registers, dacs, retrieve sn, adc values etc */ + } + thisSettings=UNINITIALIZED; + sChan=noneSelected; + sChip=noneSelected; + sMod=noneSelected; + sDac=noneSelected; + sAdc=noneSelected; + + /* + setCSregister(ALLMOD); //commented out by dhanya + setSSregister(ALLMOD); + counterClear(ALLMOD); + clearSSregister(ALLMOD); + putout("0000000000000000",ALLMOD); + */ + + /* initialize dynamic range etc. */ + /* dynamicRange=getDynamicRange(); //commented out by dhanya + nModX=setNMod(-1);*/ + + //dataBytes=nModX*NCHIP*NCHAN*4; + // dynamicRange=32; + // initChip(0, 0,ALLMOD); + //nModX=n; + // + // allocateRAM(); + + + return OK; +} + + + + +int copyChannel(sls_detector_channel *destChan, sls_detector_channel *srcChan) { + destChan->chan=srcChan->chan; + destChan->chip=srcChan->chip; + destChan->module=srcChan->module; + destChan->reg=srcChan->reg; + return OK; +} + + +int copyChip(sls_detector_chip *destChip, sls_detector_chip *srcChip) { + + int ichan; + int ret=OK; + if ((srcChip->nchan)>(destChip->nchan)) { + printf("Number of channels of source is larger than number of channels of destination\n"); + return FAIL; + } + + destChip->nchan=srcChip->nchan; + destChip->reg=srcChip->reg; + destChip->chip=srcChip->chip; + destChip->module=srcChip->module; + for (ichan=0; ichan<(srcChip->nchan); ichan++) { + *((destChip->chanregs)+ichan)=*((srcChip->chanregs)+ichan); + } + return ret; +} + + +int copyModule(sls_detector_module *destMod, sls_detector_module *srcMod) { + + int ichip, idac, ichan, iadc; + + int ret=OK; + +#ifdef VERBOSE + printf("Copying module %x to module %x\n",srcMod,destMod); +#endif + + if (srcMod->module>=0) { +#ifdef VERBOSE + printf("Copying module number %d to module number %d\n",srcMod->module,destMod->module); +#endif + destMod->module=srcMod->module; + } + if (srcMod->serialnumber>=0){ +/* #ifdef VERBOSE */ +/* printf("Copying module serial number %x to module serial number %x\n",srcMod->serialnumber,destMod->serialnumber); */ +/* #endif */ + destMod->serialnumber=srcMod->serialnumber; + } + if ((srcMod->nchip)>(destMod->nchip)) { + printf("Number of chip of source is larger than number of chips of destination\n"); + return FAIL; + } + if ((srcMod->nchan)>(destMod->nchan)) { + printf("Number of channels of source is larger than number of channels of destination\n"); + return FAIL; + } + if ((srcMod->ndac)>(destMod->ndac)) { + printf("Number of dacs of source is larger than number of dacs of destination\n"); + return FAIL; + } + if ((srcMod->nadc)>(destMod->nadc)) { + printf("Number of dacs of source is larger than number of dacs of destination\n"); + return FAIL; + } + +#ifdef VERBOSE + printf("DACs: src %d, dest %d\n",srcMod->ndac,destMod->ndac); + printf("ADCs: src %d, dest %d\n",srcMod->nadc,destMod->nadc); + printf("Chips: src %d, dest %d\n",srcMod->nchip,destMod->nchip); + printf("Chans: src %d, dest %d\n",srcMod->nchan,destMod->nchan); + +#endif + + + + destMod->ndac=srcMod->ndac; + destMod->nadc=srcMod->nadc; + destMod->nchip=srcMod->nchip; + destMod->nchan=srcMod->nchan; + if (srcMod->reg>=0) + destMod->reg=srcMod->reg; +#ifdef VERBOSE + printf("Copying register %x (%x)\n",destMod->reg,srcMod->reg ); +#endif + if (srcMod->gain>=0) + destMod->gain=srcMod->gain; + if (srcMod->offset>=0) + destMod->offset=srcMod->offset; + + // printf("copying gain and offset %f %f to %f %f\n",srcMod->gain,srcMod->offset,destMod->gain,destMod->offset); + + for (ichip=0; ichip<(srcMod->nchip); ichip++) { + if (*((srcMod->chipregs)+ichip)>=0) + *((destMod->chipregs)+ichip)=*((srcMod->chipregs)+ichip); + } + for (ichan=0; ichan<(srcMod->nchan); ichan++) { + if (*((srcMod->chanregs)+ichan)>=0) + *((destMod->chanregs)+ichan)=*((srcMod->chanregs)+ichan); + } + for (idac=0; idac<(srcMod->ndac); idac++) { + if (*((srcMod->dacs)+idac)>=0) + *((destMod->dacs)+idac)=*((srcMod->dacs)+idac); + } + for (iadc=0; iadc<(srcMod->nadc); iadc++) { + if (*((srcMod->adcs)+iadc)>=0) + *((destMod->adcs)+iadc)=*((srcMod->adcs)+iadc); + } + return ret; +} + + + +/* Register commands */ + + +int clearDACSregister(int imod) { + + putout("1111111111111111",imod);//reset + putout("1111111111111110",imod);//cs down + + /* commented out by dhanya + putout("0000000001000000",imod); + putout("0000000101000000",imod); + putout("0000000101000000",imod); + putout("0000000001000000",imod); + */ +#ifdef DEBUG + fprintf(stdout, "Clearing DAC shiftregister\n"); +#endif + // sDac=0; + sMod=imod; + if (imod==ALLMOD) + sMod=allSelected; + return OK; +} + +int nextDAC(int imod) { + + putout("1111111111111011",imod);//cs up + putout("1111111111111001",imod);//clk down + putout("1111111111111111",imod);//reset + + /*commented out by dhanya + putout("0000000001000000",imod); + putout("0000000001001000",imod); + putout("0000000001000000",imod); + */ +#ifdef DEBUG + fprintf(stdout, "Next DAC\n"); +#endif + // sDac++; + sMod=imod; + if (imod==ALLMOD) + sMod=allSelected; + return OK; +} + + +int clearCSregister(int imod) { + + putout("0000000001000000",imod); + putout("0000100001000000",imod); + putout("0000100001000000",imod); + putout("0000000001000000",imod); +#ifdef DEBUG + fprintf(stdout, "Clearing CS shiftregister\n"); +#endif + /* + sChan=noneSelected; + sMod=noneSelected; + sDac=noneSelected; + sAdc=noneSelected; + */ + sChip=noneSelected; + sMod=imod; + if (imod==ALLMOD) + sMod=allSelected; + //putout("0000000000000000",imod); + return 0; +} + +int setCSregister(int imod){ + + putout("0000000001000000",imod); + putout("0001000001000000",imod); + putout("0001000001000000",imod); + putout("0000000001000000",imod); +#ifdef DEBUG + fprintf(stdout, "Setting CS shiftregister\n"); +#endif + putout("0000000000000000",imod); + sChip=allSelected; + sMod=imod; + if (imod==ALLMOD) + sMod=allSelected; + return 0; +} + +int nextChip(int imod){ + + putout("0000000001000000",imod); + putout("0010000001000000",imod); + putout("0000000001000000",imod); +#ifdef DEBUG + fprintf(stdout, "Next Chip\n"); +#endif + sChip++; + sMod=imod; + if (imod==ALLMOD) + sMod=allSelected; + return 0; +} + +int firstChip(int imod){ + + putout("0100000001000000",imod); + putout("0110000001000000",imod); + putout("0100000001000000",imod); +#ifdef DEBUG + fprintf(stdout, "First Chip\n"); +#endif + sChip=0; + sMod=imod; + if (imod==ALLMOD) + sMod=allSelected; + return 0; +} + +int clearSSregister(int imod){ + int i; + putout("0000011000000000",imod); + for (i=0; i<10; i++) + putout("0000111000000000",imod); + putout("0000011000000000",imod); +#ifdef DEBUG + fprintf(stdout,"Clearing SS shiftregister\n"); +#endif + putout("0000000000000000",imod); + sChan=noneSelected; + sMod=imod; + if (imod==ALLMOD) + sMod=allSelected; + return 0; +} + +int setSSregister(int imod){ + int i; + putout("0000011000000000",imod); + for (i=0; i<10; i++) + putout("0001011000000000",imod); + putout("0000011000000000",imod); +#ifdef DEBUG + fprintf(stdout,"Setting SS shiftregister\n"); +#endif + putout("0000000000000000",imod); + sChan=allSelected; + sMod=imod; + if (imod==ALLMOD) + sMod=allSelected; + return 0; +} + +int nextStrip(int imod){ + putout("0000011000000000",imod); + putout("0010011000000000",imod); + putout("0000011000000000",imod); +#ifdef DEBUG + fprintf(stdout,"|-"); +#endif + sChan++; + sMod=imod; + if (imod==ALLMOD) + sMod=allSelected; + return 0; +} + +int selChannel(const int strip,int imod) { + int istrip; + clearSSregister(imod); + nextStrip(imod); + for (istrip=0; istrip=0 && imod=0) + initDAC(ind,val, imod); + + if (imod>=0 && imodgain,(detectorModules+imod)->offset); +#endif + if ((detectorModules+imod)->gain>0) + myg=(detectorModules+imod)->gain; + else { + if (thisSettings>=0 && thisSettings<3) + myg=g[thisSettings]; + // else + //myg=-1; + } + + if ((detectorModules+imod)->offset>0) + myo=(detectorModules+imod)->offset; + else { + if (thisSettings>=0 && thisSettings<3) + myo=o[thisSettings]; + // else + //myo=-1; + } + + if (myg>0 && myo>0) { + //ethr=(myo-detectorDacs[VTHRESH+imod*NDAC])*1000/myg; + + ethr=(myo-setDACRegister(VREF_DS,-1,imod))*1000/myg;//edited by dhanya + // else + // ethr=-1; + + } +#ifdef VERBOSE + //printf("module=%d gain=%f, offset=%f, dacu=%f\n",imod, myg, myo, detectorDacs[VTHRESH+imod*NDAC]); + printf("module=%d gain=%f, offset=%f, dacu=%f\n",imod, myg, myo,setDACRegister(VREF_DS,-1,imod));//edited by dhanya + printf("Threshold energy of module %d is %d eV\n", imod, ethr); +#endif + + if (imod==0) + ret=ethr; + else { + if (ethr>(ret+100) || ethr<(ret-100)) + return FAIL; + } + } + } + return ret; +} + +int setThresholdEnergy(int ethr) { + float g[3]=DEFAULTGAIN; + float o[3]=DEFAULTOFFSET; + float myg=-1, myo=-1; + int dacu; + int imod; + int ret=ethr; + + setSettings(GET_SETTINGS); + if (thisSettings>=0 || thisSettings<3){ + myg=g[thisSettings]; + myo=o[thisSettings]; + } + for (imod=0; imodgain>0) + myg=(detectorModules+imod)->gain; + else + if (thisSettings>=0 && thisSettings<3) + myg=g[thisSettings]; + else + myg=-1; + if ((detectorModules+imod)->offset>0) + myo=(detectorModules+imod)->offset; + else + if (thisSettings>=0 && thisSettings<3) + myo=o[thisSettings]; + else + myo=-1; + } else { + if (thisSettings>=0 && thisSettings<3) + myo=o[thisSettings]; + else + myo=-1; + if (thisSettings>=0 && thisSettings<3) + myg=g[thisSettings]; + else + myg=-1; + } + if (myg>0 && myo>0) { + dacu=myo-myg*((float)ethr)/1000.; +#ifdef VERBOSE + printf("module %d (%x): gain %f, off %f, energy %d eV, dac %d\n",imod,(detectorModules+imod),(detectorModules+imod)->gain,(detectorModules+imod)->offset, ethr,dacu); +#endif + } else { + dacu=ethr; +#ifdef VERBOSE + printf("could not set threshold energy for module %d, settings %d (offset is %f; gain is %f)\n",imod,thisSettings,myo,myg); +#endif + } + initDACbyIndexDACU(VREF_DS, dacu, imod); ///needs to be fixed dhanya + } + return ret; +} + + + +float getDACbyIndexDACU(int ind, int imod) { + /* + if (detectorDacs) { + if (imodndac) + return (detectorDacs[ind+imod*NDAC]); + } + return FAIL; + */ + return setDACRegister(ind, -1, imod); +} + + +//changed arguments by dhanya +int initDAC(int dac_addr, int value, int imod) { + int i; +#ifdef VERBOSE + printf("Programming dac %d with value %d\n", dac_addr, value); +#endif + clearDACSregister(imod); + program_one_dac(dac_addr,value,imod); + nextDAC(imod); + clearDACSregister(imod); + + return 0; +} + + +void showbits(int h) +{ + if(h==1) + printf("%d",h); + else + { + showbits(h/2); + printf("%d",h%2); + } +} + + +int initDACs(int* v,int imod) +{ + printf("\n..inside initdacs\n"); + + int iaddr; + // sDac=0; + for (iaddr=0; iaddr<8; iaddr++) { + clearDACSregister(imod); + if (v[iaddr]>=0) { +#ifdef VERBOSE + fprintf(stdout, "voltage %d\n", *(v+iaddr)); +#endif + program_one_dac(iaddr, *(v+iaddr),imod); + } + nextDAC(imod); + } + + + clearDACSregister(imod); + + return 0; + +} + + + + +int setSettings(int i) +{ + printf("\ninside set settings wit settins=%d...\n",i); + int imod, isett, is; + int vrefds[] = VREFDS_VALS; + int vcascn[] = VCASCN_VALS; + int vcascp[] = VCASCP_VALS; + int voutcm[] = VOUTCM_VALS; + int vcascout[] =VCASCOUT_VALS; + int vincm[] = VINCM_VALS; + int vrefcomp[] = VREFCOMP_VALS ; + int ibtestc[] = IBTESTC_VALS; + + int ivrefds,ivcascn,ivcascp,ivoutcm,ivcascout,ivincm,ivrefcomp,iibtestc; + + int v[NDAC]; + int ind; + for (ind=0; ind=HIGHGAIN) && (i<= GAIN3))) + { + v[VREF_DS]=vrefds[i]; + v[VCASCN_PB]=vcascn[i]; + v[VCASCP_PB]=vcascp[i]; + v[VOUT_CM]=voutcm[i]; + v[VCASC_OUT]=vcascout[i]; + v[VIN_CM]=vincm[i]; + v[VREF_COMP]=vrefcomp[i]; + v[IB_TESTC]=ibtestc[i]; + + initDACs(v,ALLMOD); + thisSettings=i; + } + + //check settings for module 0 + imod=0; + isett=UNDEFINED; + ivrefds=setDACRegister(VREF_DS,-1,imod); + ivcascn=setDACRegister(VCASCN_PB,-1,imod); + ivcascp=setDACRegister(VCASCP_PB,-1,imod); + ivoutcm=setDACRegister(VOUT_CM,-1,imod); + ivcascout=setDACRegister(VCASC_OUT,-1,imod); + ivincm=setDACRegister(VIN_CM,-1,imod); + ivrefcomp=setDACRegister(VREF_COMP,-1,imod); + iibtestc=setDACRegister(IB_TESTC,-1,imod); + + for (is=HIGHGAIN; is>(NTRIMBITS))&1; + int ae=(reg>>(NTRIMBITS+1))&1; + int coe=(reg>>(NTRIMBITS+2))&1; + int ocoe=(reg>>(NTRIMBITS+3))&1; + int counts=(reg>>(NTRIMBITS+4)); +#ifdef VERBOSE + printf("Initializing channel %d chip %d module %d reg %x\n",myChan.chan,myChan.chip,myChan.module, reg); + printf("trim %d, cae %d, ae %d, coe %d, ocoe %d, counts %d\n",ft, cae, ae, coe, ocoe, counts); +#endif + + if (myChan.chip<0) + setCSregister(myChan.module); + else + selChip(myChan.chip,myChan.module); + + if (myChan.chan<0) + setSSregister(myChan.module); + else + selChannel(myChan.chan,myChan.module); + + initChannel(ft,cae,ae, coe, ocoe, counts,myChan.module); + + setDynamicRange(dynamicRange); + + setCSregister(ALLMOD); + clearSSregister(ALLMOD); + putout("0000000000000000",ALLMOD); + + return myChan.reg; + +} + +int getChannelbyNumber(sls_detector_channel* myChan) { + int imod, ichip, ichan; + imod=myChan->module; + ichip=myChan->chip; + ichan=myChan->chan; + + if (detectorChans) { + if (imod=0) { + if (ichip<(detectorModules+imod)->nchip && ichan<(detectorModules+imod)->nchan/(detectorModules+imod)->nchip) + myChan->reg=detectorChans[imod*NCHAN*NCHIP+ichip*NCHAN+ichan]; + return OK; + } + } + return FAIL; + +} + +int getTrimbit(int imod, int ichip, int ichan) { + if (detectorChans) { + if (imod=0) + if (ichip<(detectorModules+imod)->nchip && ichan<(detectorModules+imod)->nchan/(detectorModules+imod)->nchip) + return (detectorChans[imod*NCHAN*NCHIP+ichip*NCHAN+ichan] & TRIM_DR); + } else + return -1; +} + +int initChannel(int ft,int cae, int ae, int coe, int ocoe, int counts, int imod){ + + int ibit, bit, i, im, ichip, ichan; + int chanmi, chanma, chipmi, chipma, modmi, modma; + + + + sMod=imod; + // printf("initializing module %d\n",sMod); + if (imod==ALLMOD) { + sMod=allSelected; + + // printf("initializing all modules\n"); + } + + if (sChan==allSelected) { + // printf("initializing all channels ft=%d coe=%d\n",ft,coe); + chanmi=0; + chanma=NCHAN; + } else if (sChan==noneSelected || sChan>NCHAN || sChan<0) { + // printf("initializing no channels ft=%d coe=%d\n",ft,coe); + chanmi=0; + chanma=-1; + } else { + // printf("initializing channel %d ft=%d coe=%d\n",sChan, ft,coe); + chanmi=sChan; + chanma=sChan+1; + } + + if (sChip==allSelected) { + // printf("initializing all chips\n"); + chipmi=0; + chipma=NCHIP; + } else if (sChip==noneSelected || sChip>NCHIP || sChip<0) { + // printf("initializing no chips\n"); + chipmi=0; + chipma=-1; + } else { + // printf("initializing chip %d\n",sChip); + chipmi=sChip; + chipma=sChip+1; + } + + + if (sMod==allSelected) { + modmi=0; + modma=nModX;//getNModBoard(); + } else if (sMod==noneSelected || sMod>nModX || sMod<0) {//(sMod==noneSelected || sMod>getNModBoard() || sMod<0) { + modmi=0; + modma=-1; + return 1; + } else { + modmi=sMod; + modma=sMod+1; + } + + if (detectorChans) { + for (im=modmi; im63 || ft<0) { + fprintf(stdout,"Fine Threshold is %d while should be between 0 and 63!",ft); + return 1; + } + /*cal_enable*/ + if (cae) { + putout("0100000000000000",imod); + putout("0110000000000000",imod); + } else { + putout("0000000000000000",imod); + putout("0010000000000000",imod); + } + /*n_an_enable*/ + if (ae) { + putout("0000000000000000",imod); + putout("0010000000000000",imod); + putout("0000000000000000",imod); + } else { + putout("0100000000000000",imod); + putout("0110000000000000",imod); + putout("0100000000000000",imod); + } + /*trb5*/ + ibit=5; + bit=ft & (1<>1; + int nchan, ichan; + int ft, cae, ae, coe, ocoe, counts, chanreg; + + + + nchan=myChip.nchan; + if (ichip<0) + setCSregister(imod); + else + selChip(ichip,imod); + + clearSSregister(imod); + for (ichan=0; ichan>(NTRIMBITS+1))&1; + ae=(chanreg>>(NTRIMBITS+2))&1; + coe=((chanreg)>>(NTRIMBITS+3))&1; + ocoe=((chanreg)>>(NTRIMBITS+4))&1; + counts=((chanreg)>>(NTRIMBITS+5)); + nextStrip(imod); + initChannel(ft,cae,ae, coe, ocoe, counts,imod); + } + initChip(obe,ow,imod); + return myChip.reg; + +} + +int getChipbyNumber(sls_detector_chip* myChip){ + int imod, ichip; + imod=myChip->module; + ichip=myChip->chip; + + if (detectorChips) { + if (imodnchip) { + myChip->reg=detectorChips[ichip+imod*NCHIP]; + myChip->nchan=NCHAN; + myChip->chanregs=detectorChans+imod*NCHAN*NCHIP+ichip*NCHIP; + return OK; + } + } + return FAIL; + +} + + + +int initChip(int obe, int ow,int imod){ + int i; + int im, ichip; + int chipmi, chipma, modmi, modma; + /* switch (ow) { + case 0:; + case 1: + setDynamicRange(32); + break; + case 2: + setDynamicRange(16); + break; + case 3: + setDynamicRange(8); + break; + case 4: + setDynamicRange(4); + break; + case 5: + setDynamicRange(1); + break; + default: + setDynamicRange(32); + break; + } + */ + +#ifdef DEBUGOUT + printf("Initializing chip\n"); +#endif + putout("0000000000000000",imod); +#ifdef DEBUGOUT + printf("Output mode= %d\n", ow); +#endif + + /* clearing shift in register */ + for (i=0; i<10; i++) + putout("0000100000000000",imod); + putout("0000000000000000",imod); + + if (ow>0) { + putout("0100000000000000",imod); + putout("0110000000000000",imod); + putout("0100000000000000",imod); + for (i=0; i<(OUTMUX_OFFSET-1); i++) { + putout("0000000000000000",imod); + putout("0010000000000000",imod); + putout("0000000000000000",imod); + } + if (ow>1) { + putout("0000000000000000",imod); + putout("0010000000000000",imod); + putout("0000000000000000",imod); + } + if (ow>2) { + putout("0000000000000000",imod); + putout("0010000000000000",imod); + putout("0000000000000000",imod); + } + if (ow>3) { + putout("0000000000000000",imod); + putout("0010000000000000",imod); + putout("0000000000000000",imod); + } + if (ow>4) { + putout("0000000000000000",imod); + putout("0010000000000000",imod); + putout("0000000000000000",imod); + } + } +#ifdef DEBUGOUT + printf("Output buffer enable= %d\n", obe); +#endif + if (obe) { + putout("0100000000000000",imod); + putout("0110000000000000",imod); + putout("0100000000000000",imod); + } else { + putout("0000000000000000",imod); + putout("0010000000000000",imod); + putout("0000000000000000",imod); + } + /*}*/ + putout("0000000000000000",imod); + + + + + + sMod=imod; + if (imod==ALLMOD) + sMod=allSelected; + + + if (sChip==allSelected) { + chipmi=0; + chipma=NCHIP; + } else if (sChip==noneSelected || sChip>NCHIP || sChip<0) { + chipmi=0; + chipma=-1; + } else { + chipmi=sChip; + chipma=sChip+1; + } + + + if (sMod==allSelected) { + modmi=0; + modma=nModX;//getNModBoard(); + } else if (sMod==noneSelected || sMod>nModX || sMod<0) {//(sMod==noneSelected || sMod>getNModBoard() || sMod<0) { + modmi=0; + modma=-1; + } else { + modmi=sMod; + modma=sMod+1; + } + + if (detectorChips) { + for (im=modmi; imNCHIP || sChip<0) { + chipmi=0; + chipma=-1; + } else { + chipmi=sChip; + chipma=sChip+1; + } + + + if (sMod==allSelected) { + modmi=0; + modma=nModX;//getNModBoard(); + } else if (sMod==noneSelected || sMod>nModX || sMod<0) {//(sMod==noneSelected || sMod>getNModBoard() || sMod<0) { + modmi=0; + modma=-1; + } else { + modmi=sMod; + modma=sMod+1; + } + + if (detectorChips) { + for (im=modmi; imnModX || sMod<0) {//(sMod==noneSelected || sMod>getNModBoard() || sMod<0) { + modmi=0; + modma=-1; + } else { + modmi=sMod; + modma=sMod+1; + } + + if (detectorModules) { + for (im=modmi; imreg)=cm; +#ifdef VERBOSE + printf("imod=%d reg=%d (%x)\n",im,(detectorModules+im)->reg,(detectorModules+im)); +#endif + } + } + return 0; +} + +int initModulebyNumber(sls_detector_module myMod) { + + printf("\ninside initmoduleynumber..\n"); + + int ichip, nchip, ichan, nchan; + int im, modmi,modma; + int ft, cae, ae, coe, ocoe, counts, chanreg; + int imod; + int obe; + int ow; + int v[NDAC]; + + + nchip=myMod.nchip; + nchan=(myMod.nchan)/nchip; + + imod=myMod.module; + sMod=imod; + + if (sMod==ALLMOD) + sMod=allSelected; + + if (sMod==allSelected) { + modmi=0; + modma=nModX;//getNModBoard(); + } else if (sMod==noneSelected || sMod>nModX || sMod<0) {// (sMod==noneSelected || sMod>getNModBoard() || sMod<0) { + modmi=0; + modma=-1; + } else { + modmi=sMod; + modma=sMod+1; + } + + + /* + for (idac=0; idacmodule; +#ifdef VERBOSE + printf("Getting module %d\n",imod); +#endif + if (detectorModules) { + copyModule(myMod,detectorModules+imod); + ; + } else + return FAIL; + + return OK; +} + +/* To chips */ +int clearCounter(int imod){ + int i; +#ifdef DEBUG + printf("Clearing counter with contclear\n"); +#endif + putout("0000000000000000",imod); + for (i=0; i<10; i++) + putout("0000000000010000",imod); + putout("0000000000000000",imod); + + return 0; +} + +int clearOutReg(int imod){ + int i; +#ifdef DEBUG + printf("Clearing output register\n"); +#endif + putout("0000010000000000",imod); + for (i=0; i<10; i++) + putout("0000110000000000",imod); + putout("0000010000000000",imod); + return 0; +} +int setOutReg(int imod){ + int i; +#ifdef DEBUG + printf("Setting output register\n"); +#endif + putout("0000010000000000",imod); + for (i=0; i<10; i++) + putout("0001010000000000",imod); + putout("0000010000000000",imod); + return 0; +} + + +int extPulse(int ncal, int imod) { + int ical; +#ifdef DEBUG + printf("Giving a clock pulse to the counter\n"); +#endif + for (ical=0; ical0 && i%2==0) { + printf("Shift in: module %d chip %i bit %d read %d instead of %d \n",k,j,i,val & 1<< j, i%2); + result++; + } + if (i%2>0 && (val & 1<0 && (dum & (1<0) { + printf("Shift out: module %d chip %i bit %d read %d instead of %d \n",k,j,i,val & 1<< j, (dum &1<0 && i%2==0) { + printf("Shift stsel: module %d chip %i bit %d read %d instead of %d \n",k,j,i,val & 1<< j, i%2); + result++; + } + if (i%2>0 && (val & 1<> 1; + + + putout("0000000000000000",ALLMOD); + putout("0010000000000000",ALLMOD); //change mux setting + putout("0000000000000000",ALLMOD); + } + + printf("Test FpgaMux module %d : %d errors\n", imod,result); + if (result) + return 1; + else + return 0; +} + + + + + + + + + +int calibration_sensor(int num, int *v, int *dacs) { + int ich, ichip, imod; + int val[10]; + + + printf("calibrating sensor..."); + for (imod=0; imod + + +int sockfd; + + +void error(char *msg) +{ + perror(msg); +} + +int main(int argc, char *argv[]) +{ + int portno, b; + char cmd[100]; + int retval=OK; + + if (argc==1) { + portno = DEFAULT_PORTNO; + sprintf(cmd,"%s %d &",argv[0],DEFAULT_PORTNO+1); + printf("opening control server on port %d\n",portno ); + system(cmd); + b=1; + } else { + portno = DEFAULT_PORTNO+1; + if ( sscanf(argv[1],"%d",&portno) ==0) { + printf("could not open stop server: unknown port\n"); + return 1; + } + b=0; + printf("opening stop server on port %d\n",portno); + } + init_detector(b); + + + bindSocket(portno); + if (getServerError()) { + printf("server error!\n"); + return -1; + } + + /* assign function table */ + function_table(); +#ifdef VERBOSE + printf("function table assigned \n"); +#endif + + + /* waits for connection */ + while(retval!=GOODBYE) { +#ifdef VERBOSE + printf("\n"); +#endif +#ifdef VERY_VERBOSE + printf("Waiting for client call\n"); +#endif + acceptConnection(); +#ifdef VERY_VERBOSE + printf("Conenction accepted\n"); +#endif + retval=decode_function(); +#ifdef VERY_VERBOSE + printf("function executed\n"); +#endif + closeConnection(); +#ifdef VERY_VERBOSE + printf("connection closed\n"); +#endif + } + + exitServer(); + printf("Goodbye!\n"); + + return 0; +} + diff --git a/slsDetectorSoftware/gotthardDetectorServer/server_defs.h b/slsDetectorSoftware/gotthardDetectorServer/server_defs.h new file mode 100755 index 000000000..e89c52ea9 --- /dev/null +++ b/slsDetectorSoftware/gotthardDetectorServer/server_defs.h @@ -0,0 +1,42 @@ +#ifndef SERVER_DEFS_H +#define SERVER_DEFS_H + +#include "sls_detector_defs.h" + +#include + + +// Hardware definitions + +#define NCHAN 128 +#define NCHIP 10 +#define NMAXMODX 1 +#define NMAXMODY 1 +#define NMAXMOD NMAXMODX*NMAXMODY +#define NDAC 8 +#define NADC 5 + +#define NCHANS NCHAN*NCHIP*NMAXMOD +#define NDACS NDAC*NMAXMOD + +#define NTRIMBITS 6 +#define NCOUNTBITS 24 + +//#define TRIM_DR ((2**NTRIMBITS)-1) +//#define COUNT_DR ((2**NCOUNTBITS)-1) +#define TRIM_DR (((int)pow(2,NTRIMBITS))-1) +#define COUNT_DR (((int)pow(2,NCOUNTBITS))-1) + + +#define ALLMOD 0xffff +#define ALLFIFO 0xffff + +#ifdef VIRTUAL +#define DEBUGOUT +#endif + +#define CLK_FREQ 100E+6 + + +#define THIS_SOFTWARE_VERSION 0x20100429 +#endif diff --git a/slsDetectorSoftware/gotthardDetectorServer/server_funcs.c b/slsDetectorSoftware/gotthardDetectorServer/server_funcs.c new file mode 100755 index 000000000..6dcc5a583 --- /dev/null +++ b/slsDetectorSoftware/gotthardDetectorServer/server_funcs.c @@ -0,0 +1,2488 @@ +#include "sls_detector_defs.h" +#include "server_funcs.h" +#ifndef PICASSOD +#include "server_defs.h" +#else +#include "picasso_defs.h" +#endif +#include "firmware_funcs.h" +#include "mcb_funcs.h" +#include "trimming_funcs.h" + + +// Global variables + +int (*flist[256])(int); + + + +#ifdef MCB_FUNCS +extern const enum detectorType myDetectorType; +#endif +#ifndef MCB_FUNCS +const enum detectorType myDetectorType=GOTTHARD; +#endif + + +extern int nModX; +extern int nModY; +extern int dataBytes; +extern int dynamicRange; +extern int storeInRAM; + + +/* global variables for optimized readout */ +extern int *ram_values; +char *dataretval=NULL; +int nframes, iframes, dataret; +char mess[1000]; +char stringname[100]="whatever i want it to be"; +float default_temperature = 999.99; + + + + +int init_detector( int b) { +#ifndef PICASSOD + printf("This is a GOTTHARD detector with %d chips per module\n", NCHIP); +#else + printf("This is a PICASSO detector with %d chips per module\n", NCHIP); +#endif + int res =mapCSP0(); + /* +#ifndef VIRTUAL + system("bus -a 0xb0000000 -w 0xd0008"); +#ifdef VERBOSE + printf("setting wait states \n"); + system("bus -a 0xb0000000"); +#endif +#endif + testFpga(); shouldnt this be inside virtual as well?! + + */ + if (res<0) { printf("Could not map memory\n"); + exit(1); + } + + //testFpga(); +#ifdef MCB_FUNCS + if (b) { + initDetector(); + printf("\ninitdetector done! \n"); + setDummyRegister(); + setSettings(GET_SETTINGS); + + //testRAM(); + } + #endif + + + strcpy(mess,"dummy message"); + return OK; +} + + +int decode_function() { + int fnum,n; + int retval=FAIL; +#ifdef VERBOSE + printf( "receive data\n"); +#endif + n = receiveDataOnly(&fnum,sizeof(fnum)); + if (n <= 0) { + printf("ERROR reading from socket %d", n); + return FAIL; + } +#ifdef VERBOSE + else + printf("size of data received %d\n",n); +#endif +#ifdef VERBOSE + printf( "calling function fnum = %d %x\n",fnum,flist[fnum]); +#endif + if (fnum<0 || fnum>255) + fnum=255; + retval=(*flist[fnum])(fnum); + if (retval==FAIL) + printf( "Error executing the function = %d \n",fnum); + return retval; +} + + +int function_table() { + int i; + for (i=0;i<256;i++){ + flist[i]=&M_nofunc; + } + flist[F_EXIT_SERVER]=&exit_server; + flist[F_EXEC_COMMAND]=&exec_command; + flist[F_GET_DETECTOR_TYPE]=&get_detector_type; + flist[F_SET_NUMBER_OF_MODULES]=&set_number_of_modules; + flist[F_GET_MAX_NUMBER_OF_MODULES]=&get_max_number_of_modules; + flist[F_SET_EXTERNAL_SIGNAL_FLAG]=&set_external_signal_flag; + flist[F_SET_EXTERNAL_COMMUNICATION_MODE]=&set_external_communication_mode; + flist[F_GET_ID]=&get_id; + flist[F_DIGITAL_TEST]=&digital_test; + flist[F_WRITE_REGISTER]=&write_register; + flist[F_READ_REGISTER]=&read_register; + flist[F_SET_DAC]=&set_dac; + flist[F_GET_ADC]=&get_adc; + flist[F_SET_CHANNEL]=&set_channel; + flist[F_SET_CHIP]=&set_chip; + flist[F_SET_MODULE]=&set_module; + flist[F_GET_CHANNEL]=&get_channel; + flist[F_GET_CHIP]=&get_chip; + flist[F_GET_MODULE]=&get_module; + flist[F_GET_THRESHOLD_ENERGY]=&get_threshold_energy; + flist[F_SET_THRESHOLD_ENERGY]=&set_threshold_energy; + flist[F_SET_SETTINGS]=&set_settings; + flist[F_START_ACQUISITION]=&start_acquisition; + flist[F_STOP_ACQUISITION]=&stop_acquisition; + flist[F_START_READOUT]=&start_readout; + flist[F_GET_RUN_STATUS]=&get_run_status; + flist[F_READ_FRAME]=&read_frame; + flist[F_READ_ALL]=&read_all; + flist[F_START_AND_READ_ALL]=&start_and_read_all; + flist[F_SET_TIMER]=&set_timer; + flist[F_GET_TIME_LEFT]=&get_time_left; + flist[F_SET_DYNAMIC_RANGE]=&set_dynamic_range; + flist[F_SET_ROI]=&set_roi; + flist[F_SET_SPEED]=&set_speed; + flist[F_SET_READOUT_FLAGS]=&set_readout_flags; + flist[F_EXECUTE_TRIMMING]=&execute_trimming; + flist[F_GET_TEMPERATURE]=&get_temperature; + flist[F_GET_GOTTHARD]=&getGotthard; + flist[F_SET_GOTTHARD]=&setGotthard; +#ifdef VERBOSE + /* for (i=0;i<256;i++){ + printf("function %d located at %x\n",i,flist[i]); + }*/ +#endif + return OK; +} + + +int M_nofunc(int fnum){ + + int retval=FAIL; + sprintf(mess,"Unrecognized Function %d\n",fnum); + printf(mess); + sendDataOnly(&retval,sizeof(retval)); + sendDataOnly(mess,sizeof(mess)); + return GOODBYE; +} + + +int exit_server(int fnum) { + int retval=FAIL; + sendDataOnly(&retval,sizeof(retval)); + printf("closing server."); + sprintf(mess,"closing server"); + sendDataOnly(mess,sizeof(mess)); + return GOODBYE; +} + +int exec_command(int fnum) { + char cmd[MAX_STR_LENGTH]; + char answer[MAX_STR_LENGTH]; + int retval=OK; + int sysret=0; + int n=0; + + /* receive arguments */ + n = receiveDataOnly(cmd,MAX_STR_LENGTH); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + retval=FAIL; + } + + /* execute action if the arguments correctly arrived*/ + if (retval==OK) { +#ifdef VERBOSE + printf("executing command %s\n", cmd); +#endif + sysret=system(cmd); + //should be replaced by popen + if (sysret==0) + sprintf(answer,"Succeeded\n"); + else { + sprintf(answer,"Failed\n"); + retval=FAIL; + } + } else { + sprintf(answer,"Could not receive the command\n"); + } + + /* send answer */ + n = sendDataOnly(answer,MAX_STR_LENGTH); + if (n < 0) { + sprintf(mess,"Error writing to socket"); + retval=FAIL; + } + + + /*return ok/fail*/ + return retval; + +} + + + +int get_detector_type(int fnum) { + int n=0; + enum detectorType ret; + int retval=OK; + + sprintf(mess,"Can't return detector type\n"); + + + /* receive arguments */ + /* execute action */ + ret=myDetectorType; + +#ifdef VERBOSE + printf("Returning detector type %d\n",ret); +#endif + + /* send answer */ + /* send OK/failed */ + n += sendDataOnly(&retval,sizeof(retval)); + if (retval==OK) { + /* send return argument */ + n += sendDataOnly(&ret,sizeof(ret)); + } else { + n += sendDataOnly(mess,sizeof(mess)); + } + /*return ok/fail*/ + return retval; + + +} + + +int set_number_of_modules(int fnum) { + int n; + int arg[2], ret=0; + int retval=OK; + int dim, nm; + + sprintf(mess,"Can't set number of modules\n"); + + /* receive arguments */ + n = receiveDataOnly(&arg,sizeof(arg)); + if (n < 0) { + sprintf(mess,"Error reading from socket %d", n); + retval=GOODBYE; + } + if (retval==OK) { + dim=arg[0]; + nm=arg[1]; + + /* execute action */ +#ifdef VERBOSE + printf("Setting the number of modules in dimension %d to %d\n",dim,nm ); +#endif + + //if (nm!=GET_FLAG) { + if (dim!=X) { + retval=FAIL; + sprintf(mess,"Can't change module number in dimension %d\n",dim); + } else { + ret=setNMod(nm); + if (nModX==nm || nm==GET_FLAG) + retval=OK; + else + retval=FAIL; + } + } + /*} else { + if (dim==Y) { + ret=nModY; + } else if (dim==X) { + ret=setNMod(-1); + } + } + */ + + /* send answer */ + /* send OK/failed */ + n = sendDataOnly(&retval,sizeof(retval)); + if (retval==OK) { + /* send return argument */ + n += sendDataOnly(&ret,sizeof(ret)); + } else { + n += sendDataOnly(mess,sizeof(mess)); + } + /*return ok/fail*/ + return retval; + +} + + +int get_max_number_of_modules(int fnum) { + int n; + int ret; + int retval=OK; + enum dimension arg; + + sprintf(mess,"Can't get max number of modules\n"); + /* receive arguments */ + n = receiveDataOnly(&arg,sizeof(arg)); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + retval=FAIL; + } + /* execute action */ +#ifdef VERBOSE + printf("Getting the max number of modules in dimension %d \n",arg); +#endif + + + switch (arg) { + case X: + ret=getNModBoard(); + break; + case Y: + ret=NMAXMODY; + break; + default: + ret=FAIL; + retval=FAIL; + } +#ifdef VERBOSE + printf("Max number of module in dimension %d is %d\n",arg,ret ); +#endif + + + + + /* send answer */ + /* send OK/failed */ + n = sendDataOnly(&retval,sizeof(retval)); + if (retval==OK) { + /* send return argument */ + n += sendDataOnly(&ret,sizeof(ret)); + } else { + n += sendDataOnly(mess,sizeof(mess)); + } + + + + /*return ok/fail*/ + return retval; +} + + +//index 0 is in gate +//index 1 is in trigger +//index 2 is out gate +//index 3 is out trigger + +int set_external_signal_flag(int fnum) { + int n; + int arg[2]; + int ret=OK; + int signalindex; + enum externalSignalFlag flag, retval; + + sprintf(mess,"Can't set external signal flag\n"); + + /* receive arguments */ + n = receiveDataOnly(&arg,sizeof(arg)); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } + retval=SIGNAL_OFF; + if (ret==OK) { + signalindex=arg[0]; + flag=arg[1]; + /* execute action */ + switch (flag) { + case GET_EXTERNAL_SIGNAL_FLAG: + retval=getExtSignal(signalindex); + break; + + default: + retval=setExtSignal(signalindex,flag); + + } + +#ifdef VERBOSE + printf("Setting external signal %d to flag %d\n",signalindex,flag ); + printf("Set to flag %d\n",retval); +#endif + + } else { + ret=FAIL; + } + + + /* send answer */ + /* send OK/failed */ + n = sendDataOnly(&ret,sizeof(ret)); + if (ret==OK) { + /* send return argument */ + n += sendDataOnly(&retval,sizeof(retval)); + } else { + n += sendDataOnly(mess,sizeof(mess)); + } + + + /*return ok/fail*/ + return ret; + +} + + +int set_external_communication_mode(int fnum) { + int n; + enum externalCommunicationMode arg, ret; + int retval=OK; + + sprintf(mess,"Can't set external communication mode\n"); + + + /* receive arguments */ + n = receiveDataOnly(&arg,sizeof(arg)); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + retval=FAIL; + } + /* +enum externalCommunicationMode{ + GET_EXTERNAL_COMMUNICATION_MODE, + AUTO, + TRIGGER_EXPOSURE_SERIES, + TRIGGER_EXPOSURE_BURST, + TRIGGER_READOUT, + TRIGGER_COINCIDENCE_WITH_INTERNAL_ENABLE, + GATE_FIX_NUMBER, + GATE_FIX_DURATION, + GATE_WITH_START_TRIGGER, + GATE_COINCIDENCE_WITH_INTERNAL_ENABLE +}; + */ + ret=AUTO; + if (retval==OK) { + /* execute action */ + switch(arg) { + default: + sprintf(mess,"The meaning of single signals should be set\n"); + retval=FAIL; + } + + +#ifdef VERBOSE + printf("Setting external communication mode to %d\n", arg); +#endif + } else + ret=FAIL; + + /* send answer */ + /* send OK/failed */ + n = sendDataOnly(&retval,sizeof(retval)); + if (retval==OK) { + /* send return argument */ + n += sendDataOnly(&ret,sizeof(ret)); + } else { + n += sendDataOnly(mess,sizeof(mess)); + } + + /*return ok/fail*/ + return retval; + + +} + + + +int get_id(int fnum) { + // sends back 64 bits! + int64_t retval; + int ret=OK; + int imod=-1; + int n=0; + enum idMode arg; + + sprintf(mess,"Can't return id\n"); + + /* receive arguments */ + n = receiveDataOnly(&arg,sizeof(arg)); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } + +#ifdef VERBOSE + printf("Getting id %d\n", arg); +#endif + + switch (arg) { + case MODULE_SERIAL_NUMBER: + n = receiveDataOnly(&imod,sizeof(imod)); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + retval=FAIL; + } else { +#ifdef VERBOSE + printf("of module %d\n", imod); +#endif + if (imod>=0 && imod<=getNModBoard()) { +#ifdef MCB_FUNCS + retval=getModuleNumber(imod); +#endif + ; + } + else { + sprintf(mess,"Module number %d out of range\n",imod); + ret=FAIL; + } + } + break; + case MODULE_FIRMWARE_VERSION: + retval=0x1; + break; + case DETECTOR_SERIAL_NUMBER: + retval=getMcsNumber(); + break; + case DETECTOR_FIRMWARE_VERSION: + retval=getMcsVersion(); + break; + case DETECTOR_SOFTWARE_VERSION: + retval=THIS_SOFTWARE_VERSION; + break; + default: + printf("Required unknown id %d \n", arg); + ret=FAIL; + retval=FAIL; + } + +#ifdef VERBOSE + printf("Id is %llx\n", retval); +#endif + + /* send answer */ + /* send OK/failed */ + n = sendDataOnly(&ret,sizeof(ret)); + if (ret==OK) { + /* send return argument */ + n += sendDataOnly(&retval,sizeof(retval)); + } else { + n += sendDataOnly(mess,sizeof(mess)); + } + + /*return ok/fail*/ + return ret; + +} + +int digital_test(int fnum) { + + int retval; + int ret=OK; + int imod=-1; + int n=0; + int ibit=0; + int ow; + enum digitalTestMode arg; + + sprintf(mess,"Can't send digital test\n"); + + n = receiveDataOnly(&arg,sizeof(arg)); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } + +#ifdef VERBOSE + printf("Digital test mode %d\n",arg ); +#endif + + switch (arg) { + case CHIP_TEST: + n = receiveDataOnly(&imod,sizeof(imod)); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + retval=FAIL; + } +#ifdef VERBOSE + printf("of module %d\n", imod); +#endif + retval=0; +#ifdef MCB_FUNCS + if (testShiftIn(imod)) retval|=(1<<(ibit)); + ibit++; + if (testShiftOut(imod)) retval|=(1<<(ibit)); + ibit++; + if (testShiftStSel(imod)) retval|=(1<<(ibit)); + ibit++; + //if ( testDataInOut(0x123456, imod)) retval|=(1<<(ibit++)); + //if ( testExtPulse(imod)) retval|=(1<<(ibit++)); + // for (ow=0; ow<6; ow++) + // ow=1; + //#ifndef PICASSOD + for (ow=0; ow<5; ow++) { + //#endif + if (testDataInOutMux(imod, ow, 0x789abc)) retval|=(1<=getNModBoard()) + ret=FAIL; + if (imod<0) + imod=ALLMOD; + +#ifdef MCB_FUNCS + switch (ind) { + case G_VREF_DS : + idac=VREF_DS; + break; + case G_VCASCN_PB: + idac=VCASCN_PB; + break; + case G_VCASCP_PB: + idac=VCASCP_PB; + break; + case G_VOUT_CM: + idac=VOUT_CM; + break; + case G_VCASC_OUT: + idac=VCASC_OUT; + break; + case G_VIN_CM: + idac=VIN_CM; + break; + case G_VREF_COMP: + idac=VREF_COMP; + break; + case G_IB_TESTC: + idac=IB_TESTC; + break; + default: + printf("Unknown DAC index %d\n",ind); + sprintf(mess,"Unknown DAC index %d\n",ind); + ret=FAIL; + } + + if (ret==OK) { + retval=initDACbyIndexDACU(idac,val,imod); + } +#endif + +#ifdef VERBOSE + printf("DAC set to %f V\n", retval); +#endif + if (retval==val || val==-1) + ret=OK; + else { + ret=FAIL; + printf("Setting dac %d of module %d: wrote %f but read %f\n", ind, imod, val, retval); + } + + + /* send answer */ + /* send OK/failed */ + n = sendDataOnly(&ret,sizeof(ret)); + if (ret==OK) { + /* send return argument */ + n += sendDataOnly(&retval,sizeof(retval)); + } else { + n += sendDataOnly(mess,sizeof(mess)); + } + + /* Maybe this is done inside the initialization funcs */ + //detectorDacs[imod][ind]=val; + /*return ok/fail*/ + return ret; + +} + + + +int get_adc(int fnum) { + + float retval; + int ret=OK; + int arg[2]; + enum dacIndex ind; + int imod; + int n; + int idac=0; + + sprintf(mess,"Can't read ADC\n"); + + + n = receiveDataOnly(arg,sizeof(arg)); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } + ind=arg[0]; + imod=arg[1]; + + + if (imod>=getNModBoard() || imod<0) + ret=FAIL; + +#ifdef MCB_FUNCS + switch (ind) { + case G_VREF_DS : + idac=VREF_DS; + break; + case G_VCASCN_PB: + idac=VCASCN_PB; + break; + case G_VCASCP_PB: + idac=VCASCP_PB; + break; + case G_VOUT_CM: + idac=VOUT_CM; + break; + case G_VCASC_OUT: + idac=VCASC_OUT; + break; + case G_VIN_CM: + idac=VIN_CM; + break; + case G_VREF_COMP: + idac=VREF_COMP; + break; + case G_IB_TESTC: + idac=IB_TESTC; + break; + default: + printf("Unknown DAC index %d\n",ind); + ret=FAIL; + sprintf(mess,"Unknown DAC index %d\n",ind); + } + + if (ret==OK) { + retval=getDACbyIndexDACU(idac,imod); + } + #endif +#ifdef VERBOSE + printf("Getting ADC %d of module %d\n", ind, imod); +#endif + +#ifdef VERBOSE + printf("ADC is %f V\n", retval); +#endif + if (ret==FAIL) { + printf("Getting adc %d of module %d failed\n", ind, imod); + } + + + /* send answer */ + /* send OK/failed */ + n = sendDataOnly(&ret,sizeof(ret)); + if (ret==OK) { + /* send return argument */ + n += sendDataOnly(&retval,sizeof(retval)); + } else { + n += sendDataOnly(mess,sizeof(mess)); + } + + /*return ok/fail*/ + return ret; + +} + +int set_channel(int fnum) { + int ret=OK; + sls_detector_channel myChan; + int retval; + int n; + + + sprintf(mess,"Can't set channel\n"); + +#ifdef VERBOSE + printf("Setting channel\n"); +#endif + ret=receiveChannel(&myChan); + if (ret>=0) + ret=OK; + else + ret=FAIL; +#ifdef VERBOSE + printf("channel number is %d, chip number is %d, module number is %d, register is %lld\n", myChan.chan,myChan.chip, myChan.module, myChan.reg); +#endif + + if (ret==OK) { + if (myChan.module>=getNModBoard()) + ret=FAIL; + if (myChan.chip>=NCHIP) + ret=FAIL; + if (myChan.chan>=NCHAN) + ret=FAIL; + if (myChan.module<0) + myChan.module=ALLMOD; + } + + + if (ret==OK) { +#ifdef MCB_FUNCS + retval=initChannelbyNumber(myChan); +#endif + } + /* Maybe this is done inside the initialization funcs */ + //copyChannel(detectorChans[myChan.module][myChan.chip]+(myChan.chan), &myChan); + + + + /* send answer */ + /* send OK/failed */ + n = sendDataOnly(&ret,sizeof(ret)); + if (ret==OK) { + /* send return argument */ + n += sendDataOnly(&retval,sizeof(retval)); + } else { + n += sendDataOnly(mess,sizeof(mess)); + } + + + /*return ok/fail*/ + return ret; + +} + + + + +int get_channel(int fnum) { + + int ret=OK; + sls_detector_channel retval; + + int arg[3]; + int ichan, ichip, imod; + int n; + + sprintf(mess,"Can't get channel\n"); + + + + n = receiveDataOnly(arg,sizeof(arg)); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } + ichan=arg[0]; + ichip=arg[1]; + imod=arg[2]; + + if (ret==OK) { + ret=FAIL; + if (imod>=0 && imod=0 && ichip=0 && ichan=0) + ret=OK; + else + ret=FAIL; +#ifdef VERBOSE + printf("chip number is %d, module number is %d, register is %d, nchan %d\n",myChip.chip, myChip.module, myChip.reg, myChip.nchan); +#endif + + if (ret==OK) { + if (myChip.module>=getNModBoard()) + ret=FAIL; + if (myChip.module<0) + myChip.module=ALLMOD; + if (myChip.chip>=NCHIP) + ret=FAIL; + } +#ifdef MCB_FUNCS + retval=initChipbyNumber(myChip); +#endif + /* Maybe this is done inside the initialization funcs */ + //copyChip(detectorChips[myChip.module]+(myChip.chip), &myChip); + + /* send answer */ + /* send OK/failed */ + n = sendDataOnly(&ret,sizeof(ret)); + if (ret==OK) { + /* send return argument */ + n += sendDataOnly(&retval,sizeof(retval)); + } else { + n += sendDataOnly(mess,sizeof(mess)); + } + + + return ret; +} + +int get_chip(int fnum) { + + + int ret=OK; + sls_detector_chip retval; + int arg[2]; + int ichip, imod; + int n; + + + + n = receiveDataOnly(arg,sizeof(arg)); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } + ichip=arg[0]; + imod=arg[1]; + if (ret==OK) { + ret=FAIL; + if (imod>=0 && imod=0 && ichip=0) + ret=OK; + else + ret=FAIL; + + +#ifdef VERBOSE + printf("module number is %d,register is %d, nchan %d, nchip %d, ndac %d, nadc %d, gain %f, offset %f\n",myModule.module, myModule.reg, myModule.nchan, myModule.nchip, myModule.ndac, myModule.nadc, myModule.gain,myModule.offset); +#endif + + if (ret==OK) { + // if (myModule.module>=getNModBoard()) {//commented out by dhanya + if (myModule.module>=1) { + ret=FAIL; + printf("Module number is too large %d\n",myModule.module); + } + if (myModule.module<0) + myModule.module=ALLMOD; + } + + if (ret==OK) { +#ifdef MCB_FUNCS + retval=initModulebyNumber(myModule); +#endif + } + + /* Maybe this is done inside the initialization funcs */ + //copyChip(detectorChips[myChip.module]+(myChip.chip), &myChip); + + /* send answer */ + /* send OK/failed */ + n = sendDataOnly(&ret,sizeof(ret)); + if (ret==OK) { + /* send return argument */ + n += sendDataOnly(&retval,sizeof(retval)); + } else { + n += sendDataOnly(mess,sizeof(mess)); + } + free(myChip); + free(myChan); + free(myDac); + free(myAdc); + + // setDynamicRange(dr);commentedout by dhanya + + + return ret; +} + + + + +int get_module(int fnum) { + + + int ret=OK; + + + int arg; + int imod; + int n; + + + + sls_detector_module myModule; + int *myChip=malloc(NCHIP*sizeof(int)); + int *myChan=malloc(NCHIP*NCHAN*sizeof(int)); + float *myDac=malloc(NDAC*sizeof(int)); + float *myAdc=malloc(NADC*sizeof(int)); + + + if (myDac) + myModule.dacs=myDac; + else { + sprintf(mess,"could not allocate dacs\n"); + ret=FAIL; + } + if (myAdc) + myModule.adcs=myAdc; + else { + sprintf(mess,"could not allocate adcs\n"); + ret=FAIL; + } + if (myChip) + myModule.chipregs=myChip; + else { + sprintf(mess,"could not allocate chips\n"); + ret=FAIL; + } + if (myChan) + myModule.chanregs=myChan; + else { + sprintf(mess,"could not allocate chans\n"); + ret=FAIL; + } + + myModule.ndac=NDAC; + myModule.nchip=NCHIP; + myModule.nchan=NCHAN*NCHIP; + myModule.nadc=NADC; + + + + + + n = receiveDataOnly(&arg,sizeof(arg)); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } + imod=arg; + + if (ret==OK) { + ret=FAIL; + if (imod>=0 && imod-2) { + dataret=FAIL; + sprintf(mess,"no data and run stopped: %d frames left\n",getFrames()+2); + printf("%s\n",mess); + } else { + dataret=FINISHED; + sprintf(mess,"acquisition successfully finished\n"); + printf("%s\n",mess); + } +#ifdef VERYVERBOSE + printf("%d %d %x %s\n",sizeof(mess),strlen(mess), mess,mess); +#endif + sendDataOnly(&dataret,sizeof(dataret)); + sendDataOnly(mess,sizeof(mess));//sizeof(mess));//sizeof(mess)); +#ifdef VERYVERBOSE + printf("message sent\n",mess); +#endif + return dataret; + } + } else { + nframes=0; + while(fifo_read_event()) { + nframes++; + } + dataretval=(char*)ram_values; + dataret=OK; +#ifdef VERBOSE + printf("sending data of %d frames\n",nframes); +#endif + for (iframes=0; iframes-2) { + dataret=FAIL; + sprintf(mess,"no data and run stopped: %d frames left\n",getFrames()+2); + printf("%s\n",mess); + } else { + dataret=FINISHED; + sprintf(mess,"acquisition successfully finished\n"); + printf("%s\n",mess); + } +#ifdef VERBOSE + printf("Frames left %d\n",getFrames()); +#endif + sendDataOnly(&dataret,sizeof(dataret)); + sendDataOnly(mess,sizeof(mess)); + return dataret; + } + + return dataret; +} + + + + + + + + +int read_all(int fnum) { + + + while(read_frame(0)==OK) { +#ifdef VERBOSE + printf("frame read\n"); +#endif + ; + } + +#ifdef VERBOSE + printf("Frames finished\n"); +#endif + return OK; + + +} + +int start_and_read_all(int fnum) { + // int ret=OK; +#ifdef VERBOSE + printf("Starting and reading all frames\n"); +#endif + + startStateMachine(); + /* ret=startStateMachine(); + if (ret!=OK) { + sprintf(mess,"could not start state machine\n"); + sendDataOnly(&ret,sizeof(ret)); + sendDataOnly(mess,sizeof(mess)); + + #ifdef VERBOSE + printf("could not start state machine\n"); +#endif +} else {*/ + read_all(1); +#ifdef VERBOSE + printf("Frames finished\n"); +#endif + //} + + + return OK; + + +} + +int set_timer(int fnum) { + enum timerIndex ind; + int64_t tns; + int n; + int64_t retval; + int ret=OK; + + + sprintf(mess,"can't set timer\n"); + + n = receiveDataOnly(&ind,sizeof(ind)); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } + + n = receiveDataOnly(&tns,sizeof(tns)); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } + + if (ret!=OK) { + printf(mess); + } + +#ifdef VERBOSE + printf("setting timer %d to %lld ns\n",ind,tns); +#endif + if (ret==OK) { + switch(ind) { + case FRAME_NUMBER: + retval=setFrames(tns); + break; + case ACQUISITION_TIME: + retval=setExposureTime(tns); + break; + case FRAME_PERIOD: + retval=setPeriod(tns); + break; + case DELAY_AFTER_TRIGGER: + retval=setDelay(tns); + break; + case GATES_NUMBER: + retval=setGates(tns); + break; + case PROBES_NUMBER: + retval=setProbes(tns); + break; + case CYCLES_NUMBER: + retval=setTrains(tns); + break; + default: + ret=FAIL; + sprintf(mess,"timer index unknown %d\n",ind); + } + } + if (ret!=OK) { + printf(mess); + } + //if (tns>=0 && retval!=tns && (retval+1)!=tns) { + // printf("wrote %lld, read %lld\n",tns,retval); + // ret=FAIL; + // } + if (ret!=OK) { + printf(mess); + printf("set timer failed\n"); + sprintf(mess, "set timer %d failed\n", ind); + } else if (ind==FRAME_NUMBER) { + ret=allocateRAM(); + if (ret!=OK) + sprintf(mess, "could not allocate RAM for %lld frames\n", tns); + } + + n = sendDataOnly(&ret,sizeof(ret)); + if (ret!=OK) { +#ifdef VERBOSE + printf("returning error\n"); +#endif + + n = sendDataOnly(mess,sizeof(mess)); + } else { +#ifdef VERBOSE + printf("returning ok %d\n",sizeof(retval)); +#endif + + n = sendDataOnly(&retval,sizeof(retval)); + } + + return ret; + +} + + + + + + + + +int get_time_left(int fnum) { + + enum timerIndex ind; + int n; + int64_t retval; + int ret=OK; + + sprintf(mess,"can't get timer\n"); + n = receiveDataOnly(&ind,sizeof(ind)); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } + + +#ifdef VERBOSE + + printf("getting time left on timer %d \n",ind); +#endif + + if (ret==OK) { + switch(ind) { + case FRAME_NUMBER: + retval=getFrames(); + break; + case ACQUISITION_TIME: + retval=getExposureTime(); + break; + case FRAME_PERIOD: + retval=getPeriod(); + break; + case DELAY_AFTER_TRIGGER: + retval=getDelay(); + break; + case GATES_NUMBER: + retval=getGates(); + break; + case PROBES_NUMBER: + retval=getProbes(); + break; + case CYCLES_NUMBER: + retval=getTrains(); + break; + case PROGRESS: + retval=getProgress(); + break; + default: + ret=FAIL; + sprintf(mess,"timer index unknown %d\n",ind); + } + } + + + if (ret!=OK) { + printf("get time left failed\n"); + } + + n = sendDataOnly(&ret,sizeof(ret)); + if (ret!=OK) { + n += sendDataOnly(mess,sizeof(mess)); + } else { + n = sendDataOnly(&retval,sizeof(retval)); + } + + return ret; + + +} + +int set_dynamic_range(int fnum) { + + + + int dr, ow; + int n; + int retval; + int ret=OK; + + + sprintf(mess,"can't set dynamic range\n"); + + + n = receiveDataOnly(&dr,sizeof(dr)); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } + + if (dr>0) { + /* +#ifdef MCB_FUNCS + setCSregister(ALLMOD); + switch(dr) { + case 1: + ow=5; + break; + case 4: + ow=4; + break; + case 8: + ow=3; + break; + case 16: + ow=2; + break; + default: + // ow=0; + ow=1; + break; + } + + + initChip(0, ow,ALLMOD); +#endif + */ +#ifdef VERBOSE + printf("setting dynamic range to %d\n",dr); +#endif + } + retval=setDynamicRange(dr); + + + if (dr>=0 && retval!=dr) + ret=FAIL; + if (ret!=OK) { + sprintf(mess,"set dynamic range failed\n"); + } else { + ret=allocateRAM(); + if (ret!=OK) + sprintf(mess,"Could not allocate RAM for the dynamic range selected\n"); + } + + n = sendDataOnly(&ret,sizeof(ret)); + if (ret!=OK) { + n = sendDataOnly(mess,sizeof(mess)); + } else { + n = sendDataOnly(&retval,sizeof(retval)); + } + return ret; +} + +int set_roi(int fnum) { + + return FAIL; + +} + +int get_roi(int fnum) { + + + return FAIL; +} + +int set_speed(int fnum) { + + enum speedVariable arg; + int val, n; + int ret=OK; + int retval; + + sprintf(mess,"can't set speed variable\n"); + + + n = receiveDataOnly(&arg,sizeof(arg)); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } + n = receiveDataOnly(&val,sizeof(val)); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } + +#ifdef VERBOSE + printf("setting speed variable %d to %d\n",arg,val); +#endif + if (ret==OK) { + switch (arg) { + case CLOCK_DIVIDER: + if (val>=0) + retval=setClockDivider(val); + else + retval=getClockDivider(); + break; + case WAIT_STATES: + if (val>=0) + retval=setWaitStates(val); + else + retval=getWaitStates(); + break; + case SET_SIGNAL_LENGTH: + if (val>=0) + retval=setSetLength(val); + else + retval=getSetLength(); + break; + case TOT_CLOCK_DIVIDER: + if (val>=0) + retval=setTotClockDivider(val); + else + retval=getTotClockDivider(); + break; + case TOT_DUTY_CYCLE: + if (val>=0) + retval=setTotDutyCycle(val); + else + retval=getTotDutyCycle(); + break; + default: + ret=FAIL; + } + } + n = sendDataOnly(&ret,sizeof(ret)); + if (ret!=OK) { + n = sendDataOnly(mess,sizeof(mess)); + } else { + n = sendDataOnly(&retval,sizeof(retval)); + } + return ret; +} + + + +int set_readout_flags(int fnum) { + + enum readOutFlags retval; + enum readOutFlags arg; + int n; + int ret=OK; + int regret=OK; + + + sprintf(mess,"can't set readout flags\n"); + + + n = receiveDataOnly(&arg,sizeof(arg)); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } + + +#ifdef VERBOSE + printf("setting readout flags to %d\n",arg); +#endif + + //ret=setStoreInRAM(0); + // initChipWithProbes(0,0,0, ALLMOD); + switch(arg) { + case GET_READOUT_FLAGS: + break; + case STORE_IN_RAM: + if (setStoreInRAM(1)==OK) + ret=OK; + else + ret=FAIL; + break; + case TOT_MODE: + if(setToT(1)) + ret=OK; + else + ret=FAIL; + break; + case CONTINOUS_RO: + if (setContinousReadOut(1)) + ret=OK; + else + ret=FAIL; + break; + // case PUMP_PROBE_MODE: + //set number of probes + //initChipWithProbes(0,0,2, ALLMOD); + //break; + default: + ret=setStoreInRAM(0); + regret=setConfigurationRegister(0); + ret=OK; + } + retval=NORMAL_READOUT; + + if (storeInRAM) + retval=STORE_IN_RAM; + //else if (getProbes()) + // retval=PUMP_PROBE_MODE; + //else + if (setToT(-1)) + retval|=TOT_MODE; + if (setContinousReadOut(-1)) + retval|=CONTINOUS_RO; + if (ret!=OK) { + printf("set readout flags failed\n"); + sprintf(mess,"Could not allocate RAM\n"); + } + n = sendDataOnly(&ret,sizeof(ret)); + if (ret!=OK) { + n = sendDataOnly(mess,sizeof(mess)); + } else { + n = sendDataOnly(&retval,sizeof(retval)); + } + return ret; +} + + + + + +int execute_trimming(int fnum) { + + int arg[3]; + int n; + int ret=OK; + int imod, par1,par2; + enum trimMode mode; + + sprintf(mess,"can't set execute trimming\n"); + + n = receiveDataOnly(&mode,sizeof(mode)); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + printf("Error reading from socket (mode)\n"); + ret=FAIL; + } + + n = receiveDataOnly(arg,sizeof(arg)); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + printf("Error reading from socket (args)\n"); + ret=FAIL; + } + + imod=arg[0]; + + if (imod>=getNModBoard()) + ret=FAIL; + + if (imod<0) + imod=ALLMOD; + + par1=arg[1]; + par2=arg[2]; + +#ifdef VERBOSE + printf("trimming module %d mode %d, parameters %d %d \n",imod,mode, par1, par2); +#endif + if (ret==OK) { + switch(mode) { + case NOISE_TRIMMING: + // par1 is countlim; par2 is nsigma + ret=trim_with_noise(par1, par2, imod); + break; + case BEAM_TRIMMING: + // par1 is countlim; par2 is nsigma + ret=trim_with_beam(par1,par2,imod); + break; + case IMPROVE_TRIMMING: + // par1 is maxit; if par2!=0 vthresh will be optimized + ret=trim_improve(par1, par2,imod); + break; + case FIXEDSETTINGS_TRIMMING: + // par1 is countlim; if par2<0 then trimwithlevel else trim with median + ret=trim_fixed_settings(par1,par2,imod); + break; + // case OFFLINE_TRIMMING: + + //break; + default: + printf("Unknown trimming mode\n"); + sprintf(mess,"Unknown trimming mode\n"); + ret=FAIL; + } + } + + + if (ret!=OK) { + printf("trimming failed\n"); + } + n = sendDataOnly(&ret,sizeof(ret)); + if (ret!=OK) { + n = sendDataOnly(mess,sizeof(mess)); + } + + return ret; +} + + + + + + +float get_temperature(int fnum) { + + float retval; + int ret=OK; + int imod,n; + + n = receiveDataOnly(&imod,sizeof(imod)); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } + +#ifdef VERBOSE + printf("Getting Temperature of module %d \n", imod); +#endif + + /* + if (imod>=getNModBoard()) + ret=FAIL; + if (imod<0) + imod=ALLMOD; + */ + + /* execute action if the arguments correctly arrived*/ + if (ret==OK) { + retval = default_temperature; //getTemperature(imod); + } + +#ifdef VERBOSE + printf("Temperature of module %d is %f \n",imod,retval); +#endif + + //validate somehow if the temperature read makes sense, else ret=FAIL + ret=OK; + strcpy(mess,"Getting temperature ERROR\n"); + + /* send ret */ + n = sendDataOnly(&ret,sizeof(ret)); + if (n < 0) { + sprintf(mess,"Error writing to socket"); + retval=FAIL; + } + if (ret==OK) { + /* send return argument */ + n = sendDataOnly(&retval,sizeof(retval)); + if (n < 0) { + sprintf(mess,"Error writing to socket"); + ret=FAIL; + } + } else { + n = sendDataOnly(mess,sizeof(mess)); + } + + /*return ok/fail*/ + return ret; + +} + +int getGotthard(int fnum) { + + int retval=OK; + int ret=0; + // char val[100]; + int n=0; + printf("in getgotthard fn\n"); + /* receive arguments + n = receiveDataOnly(val,sizeof(val)); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + retval=FAIL; + } + */ + /* execute action if the arguments correctly arrived*/ + if (retval==OK) { + + printf("getting stringname %s\n", stringname); + + } + + /* send ret */ + n = sendDataOnly(&ret,sizeof(ret)); + if (n < 0) { + sprintf(mess,"Error writing to socket"); + retval=FAIL; + } + + /* send answer */ + n = sendDataOnly(stringname,sizeof(stringname)); + if (n < 0) { + sprintf(mess,"Error writing to socket"); + retval=FAIL; + } + + if(retval==FAIL) + sendDataOnly(mess,sizeof(mess)); + + + + /*return ok/fail*/ + return retval; + +} + +int setGotthard(int fnum) { + int retval=OK; + int ret=0; + char val[100]; + int n=0; + printf("in setgotthard fn\n"); + /* receive arguments */ + n = receiveDataOnly(val,sizeof(val)); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + retval=FAIL; + } + + /* execute action if the arguments correctly arrived*/ + if (retval==OK) { + + printf("setting stringname %s\n", val); + + } + + strcpy(stringname, val); + + /* send ret */ + n = sendDataOnly(&ret,sizeof(ret)); + if (n < 0) { + sprintf(mess,"Error writing to socket"); + retval=FAIL; + } + + /* send answer */ + n = sendDataOnly(stringname,sizeof(stringname)); + if (n < 0) { + sprintf(mess,"Error writing to socket"); + retval=FAIL; + } + + if(retval==FAIL) + sendDataOnly(mess,sizeof(mess)); + + /*return ok/fail*/ + return retval; + +} + + + + diff --git a/slsDetectorSoftware/gotthardDetectorServer/server_funcs.h b/slsDetectorSoftware/gotthardDetectorServer/server_funcs.h new file mode 100755 index 000000000..22c52e186 --- /dev/null +++ b/slsDetectorSoftware/gotthardDetectorServer/server_funcs.h @@ -0,0 +1,71 @@ +#ifndef SERVER_FUNCS_H +#define SERVER_FUNCS_H +#include +/* +#include +#include +#include +*/ +#include "communication_funcs.h" + + + + +#define GOODBYE -200 +int function_table(); + +int decode_function(); + +int init_detector(int); + +int M_nofunc(int); +int exit_server(int); + +// General purpose functions +int get_detector_type(int); +int set_number_of_modules(int); +int get_max_number_of_modules(int); + + +int exec_command(int); +int set_external_signal_flag(int); +int set_external_communication_mode(int); +int get_id(int); +int digital_test(int); +int write_register(int); +int read_register(int); +int set_dac(int); +int get_adc(int); +int set_channel(int); +int set_chip(int); +int set_module(int); +int get_channel(int); +int get_chip(int); +int get_module(int); + +int get_threshold_energy(int); +int set_threshold_energy(int); +int set_settings(int); +int start_acquisition(int); +int stop_acquisition(int); +int start_readout(int); +int get_run_status(int); +int read_frame(int); +int read_all(int); +int start_and_read_all(int); +int set_timer(int); +int get_time_left(int); +int set_dynamic_range(int); +int set_roi(int); +int get_roi(int); +int set_speed(int); +int set_readout_flags(int); +int execute_trimming(int); + +// to take out/not by dhanya.. +int getGotthard(int); +int setGotthard(int); +float get_temperature(int); + + +#endif diff --git a/slsDetectorSoftware/gotthardDetectorServer/server_funcs_old.c b/slsDetectorSoftware/gotthardDetectorServer/server_funcs_old.c new file mode 100755 index 000000000..9bd06c424 --- /dev/null +++ b/slsDetectorSoftware/gotthardDetectorServer/server_funcs_old.c @@ -0,0 +1,180 @@ +#include "sls_detector_defs.h" +#include "server_funcs.h" +//#include "server_defs.h" + +// Global variables + +int (*flist[256])(int); + + + + +const enum detectorType myDetectorType=GOTTHARD; +char mess[1000]; +char stringname[100]="what i want it to be"; + + +int init_detector(int b) { + printf("This is a GOTTHARD detector\n"); + sprintf(mess,"dummy message"); + return OK; +} + + +int decode_function() { + int fnum,n; + int retval=FAIL; +#ifdef VERBOSE + printf( "receive data\n"); +#endif + n = receiveDataOnly(&fnum,sizeof(fnum)); + if (n <= 0) { + printf("ERROR reading from socket %d", n); + return FAIL; + } +#ifdef VERBOSE + else + printf("size of data received %d\n",n); +#endif +#ifdef VERBOSE + printf( "calling function fnum = %d %x\n",fnum,flist[fnum]); +#endif + if (fnum<0 || fnum>255) + fnum=255; + retval=(*flist[fnum])(fnum); + if (retval==FAIL) + printf( "Error executing the function = %d \n",fnum); + return retval; +} + + + + + + +int function_table(int b) { + int i; + for (i=0;i<256;i++){ + flist[i]=&M_nofunc; + } + flist[F_EXIT_SERVER]=&exit_server; + flist[F_GET_GOTTHARD]=&getGotthard; + flist[F_SET_GOTTHARD]=&setGotthard; + return OK; +} + + +int M_nofunc(int fnum){ + + int retval=FAIL; + sprintf(mess,"Unrecognized Function %d\n",fnum); + printf(mess); + sendDataOnly(&retval,sizeof(retval)); + sendDataOnly(mess,sizeof(mess)); + return GOODBYE; +} + + + +int exit_server(int fnum) { + int retval=FAIL; + sendDataOnly(&retval,sizeof(retval)); + printf("closing server."); + sprintf(mess,"closing server"); + sendDataOnly(mess,sizeof(mess)); + return GOODBYE; +} + + + + + +int getGotthard(int fnum) { + + int retval=OK; + int ret=0; + char val[100]; + int n=0; + printf("in getgotthard fn\n"); + /* receive arguments + n = receiveDataOnly(val,sizeof(val)); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + retval=FAIL; + } + */ + /* execute action if the arguments correctly arrived*/ + if (retval==OK) { + + printf("getting stringname %s\n", stringname); + + } + + /* send ret */ + n = sendDataOnly(&ret,sizeof(ret)); + if (n < 0) { + sprintf(mess,"Error writing to socket"); + retval=FAIL; + } + + /* send answer */ + n = sendDataOnly(stringname,sizeof(stringname)); + if (n < 0) { + sprintf(mess,"Error writing to socket"); + retval=FAIL; + } + + if(retval==FAIL) + sendDataOnly(mess,sizeof(mess)); + + + + /*return ok/fail*/ + return retval; + +} + +int setGotthard(int fnum) { + int retval=OK; + int ret=0; + char val[100]; + int n=0; + printf("in setgotthard fn\n"); + /* receive arguments */ + n = receiveDataOnly(val,sizeof(val)); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + retval=FAIL; + } + + /* execute action if the arguments correctly arrived*/ + if (retval==OK) { + + printf("setting stringname %s\n", val); + + } + + strcpy(stringname, val); + + /* send ret */ + n = sendDataOnly(&ret,sizeof(ret)); + if (n < 0) { + sprintf(mess,"Error writing to socket"); + retval=FAIL; + } + + /* send answer */ + n = sendDataOnly(stringname,sizeof(stringname)); + if (n < 0) { + sprintf(mess,"Error writing to socket"); + retval=FAIL; + } + + if(retval==FAIL) + sendDataOnly(mess,sizeof(mess)); + + /*return ok/fail*/ + return retval; + +} + diff --git a/slsDetectorSoftware/gotthardDetectorServer/server_funcs_old.h b/slsDetectorSoftware/gotthardDetectorServer/server_funcs_old.h new file mode 100755 index 000000000..23b9b9b64 --- /dev/null +++ b/slsDetectorSoftware/gotthardDetectorServer/server_funcs_old.h @@ -0,0 +1,24 @@ +#ifndef SERVER_FUNCS_H +#define SERVER_FUNCS_H +#include +#include "communication_funcs.h" + + + + +#define GOODBYE -200 +int function_table(); + +int decode_function(); + +int init_detector(int); + +int M_nofunc(int); +int exit_server(int); + +int getGotthard(int); +int setGotthard(int); + + + +#endif diff --git a/slsDetectorSoftware/gotthardDetectorServer/sharedmemory.c b/slsDetectorSoftware/gotthardDetectorServer/sharedmemory.c new file mode 100755 index 000000000..4504cfe05 --- /dev/null +++ b/slsDetectorSoftware/gotthardDetectorServer/sharedmemory.c @@ -0,0 +1,39 @@ +#include "sharedmemory.h" + +struct statusdata *stdata; + +int inism(int clsv) { + +static int scansmid; + + if (clsv==SMSV) { + if ( (scansmid=shmget(SMKEY,1024,IPC_CREAT | 0666 ))==-1 ) { + return -1; + } + if ( (stdata=shmat(scansmid,NULL,0))==(void*)-1) { + return -2; + } + } + + if (clsv==SMCL) { + if ( (scansmid=shmget(SMKEY,0,0) )==-1 ) { + return -3; + } + if ( (stdata=shmat(scansmid,NULL,0))==(void*)-1) { + return -4; + } + } + return 1; +} + +void write_status_sm(char *status) { + strcpy(stdata->status,status); +} + +void write_stop_sm(int v) { + stdata->stop=v; +} + +void write_runnumber_sm(int v) { + stdata->runnumber=v; +} diff --git a/slsDetectorSoftware/gotthardDetectorServer/sharedmemory.h b/slsDetectorSoftware/gotthardDetectorServer/sharedmemory.h new file mode 100755 index 000000000..f55e751e3 --- /dev/null +++ b/slsDetectorSoftware/gotthardDetectorServer/sharedmemory.h @@ -0,0 +1,47 @@ +#ifndef SM +#define SM + + +#include +#include +#include +#include +#include +#include +#include +//#include +#include +#include +#include +#include +#include +#include + + +#include + +#include +#include + +/* key for shared memory */ +#define SMKEY 10001 + +#define SMSV 1 +#define SMCL 2 + + +struct statusdata { + int runnumber; + int stop; + char status[20]; +} ; + + +/* for shared memory */ + +int inism(int clsv); +void write_status_sm(char *status); +void write_stop_sm(int v); +void write_runnumber_sm(int v); + +#endif diff --git a/slsDetectorSoftware/gotthardDetectorServer/stop_server.c b/slsDetectorSoftware/gotthardDetectorServer/stop_server.c new file mode 100755 index 000000000..94dcfa2c6 --- /dev/null +++ b/slsDetectorSoftware/gotthardDetectorServer/stop_server.c @@ -0,0 +1,41 @@ +/* A simple server in the internet domain using TCP + The port number is passed as an argument */ +#include "communication_funcs.h" +//#include "firmware_funcs.h" + + +int sockfd; + +int main(int argc, char *argv[]) +{ + int portno; + int retval=0; + + portno = DEFAULT_PORTNO; + + + bindSocket(portno); + if (getServerError()) + return -1; + + + + /* waits for connection */ + while(retval!=GOODBYE) { +#ifdef VERBOSE + printf("\n"); +#endif +#ifdef VERY_VERBOSE + printf("Stop server: waiting for client call\n"); +#endif + acceptConnection(); + retval=stopStateMachine(); + closeConnection(); + } + + exitServer(); + printf("Goodbye!\n"); + + return 0; +} + diff --git a/slsDetectorSoftware/gotthardDetectorServer/trimming_funcs.c b/slsDetectorSoftware/gotthardDetectorServer/trimming_funcs.c new file mode 100755 index 000000000..90655ec16 --- /dev/null +++ b/slsDetectorSoftware/gotthardDetectorServer/trimming_funcs.c @@ -0,0 +1,755 @@ +#ifndef PICASSOD +#include "server_defs.h" +#else +#include "picasso_defs.h" +#endif +#include "trimming_funcs.h" +#include "mcb_funcs.h" +#include "firmware_funcs.h" +#include + + + +extern int nModX; +//extern int *values; + +extern const int nChans; +extern const int nChips; +extern const int nDacs; +extern const int nAdcs; + + +int trim_fixed_settings(int countlim, int par2, int im) +{ + + int retval=OK; +#ifdef VERBOSE + printf("Trimming with fixed settings\n"); +#endif +#ifdef VIRTUAL + return OK; +#endif + + if (par2<=0) + retval=trim_with_level(countlim, im); + else + retval=trim_with_median(countlim,im); + + + return retval; +} + + +int trim_with_noise(int countlim, int nsigma, int im) +{ + + + int retval=OK, retval1=OK, retval2=OK; +#ifdef VERBOSE + printf("Trimming using noise\n"); +#endif +#ifdef VIRTUAL + return OK; +#endif + + /* threshold scan */ + +#ifdef VERBOSE + printf("chosing vthresh and vtrim....."); +#endif + retval1=choose_vthresh_and_vtrim(countlim,nsigma, im); + +#ifdef VERBOSE + printf("trimming with noise.....\n"); +#endif + retval2=trim_with_level(countlim, im); + +#ifdef DEBUGOUT + printf("done\n"); +#endif + if (retval1==OK && retval2==OK) + retval=OK; + else + retval=FAIL; + + return retval; + +} + +int trim_with_beam(int countlim, int nsigma, int im) //rpc +{ + + + int retval=OK, retval1=OK, retval2=OK; + + printf("Trimming using beam\n"); + //return OK; +#ifdef VIRTUAL + printf("Trimming using beam\n"); + return OK; +#endif + /* threshold scan */ +#ifdef DEBUGOUT + printf("chosing vthresh and vtrim....."); +#endif + + retval1=choose_vthresh_and_vtrim(countlim,nsigma,im); + retval2=trim_with_median(TRIM_DR, im); + +#ifdef DEBUGOUT + printf("done\n"); +#endif + + if (retval1==OK && retval2==OK) + retval=OK; + else + retval=FAIL; + + return retval; + +} + + +int trim_improve(int maxit, int par2, int im) //rpc +{ + + int retval=OK, retval1=OK, retval2=OK; + + +#ifdef VERBOSE + printf("Improve the trimming\n"); +#endif +#ifdef VIRTUAL + return OK; +#endif + + + if (par2!=0 && im==ALLMOD) + retval1=choose_vthresh(); + + retval2=trim_with_median(2*maxit+1, im); +#ifdef DEBUGOUT + printf("done\n"); +#endif + if (retval1==OK && retval2==OK) + retval=OK; + else + retval=FAIL; + + return retval; + +} + +int calcthr_from_vcal(int vcal) { + int thrmin; + //thrmin=140+3*vcal/5; + thrmin=180+3*vcal/5; + return thrmin; +} + +int calccal_from_vthr(int vthr) { + int vcal; + vcal=5*(vthr-140)/3; + return vcal; +} + +int choose_vthresh_and_vtrim(int countlim, int nsigma, int im) { + int retval=OK; +#ifdef MCB_FUNCS + int modma, modmi, nm; + int thr, thrstep=5, nthr=31; + + int *fifodata; + + float vthreshmean, vthreshSTDev; + int *thrmi, *thrma; + float c; + float b=BVTRIM; + float a=AVTRIM; + int *trim; + int ich, imod, ichan; + int nvalid=0; + u_int32_t *scan; + int ithr; + sls_detector_channel myChan; + + + + setFrames(1); + // setNMod(getNModBoard()); + + if (im==ALLMOD){ + modmi=0; + modma=nModX; + } else { + modmi=im; + modma=im+1; + } + nm=modma-modmi; + + trim=malloc(sizeof(int)*nChans*nChips*nModX); + thrmi=malloc(sizeof(int)*nModX); + thrma=malloc(sizeof(int)*nModX); + + + for (ich=0; ichcountlim && trim[ich]==-1) { + trim[ich]=getDACbyIndexDACU(VTHRESH,imod); +#ifdef VERBOSE + // printf("yes: %d %d %d\n",ich,ithr,scan[ich]); +#endif + } + */ +#ifdef VERBOSE + /* else { + printf("no: %d %d %d\n",ich,ithr,scan[ich]); + }*/ +#endif + } + } + free(scan); + } + + for (imod=modmi; imodthrmi[imod] && trim[ich]0) { + vthreshmean=vthreshmean/nvalid; + //vthreshSTDev=sqrt((vthreshSTDev/nvalid)-vthreshmean*vthreshmean); cuz is commented in firmware_funcs.c and in shared_memory.c + } else { + vthreshmean=thrmi[imod]; + vthreshSTDev=nthr*thrstep; + printf("No valid channel for module %d\n",imod); + retval=FAIL; + } + +#ifdef DEBUGOUT + printf("module= %d nvalid = %d mean=%f RMS=%f\n",imod, nvalid, vthreshmean,vthreshSTDev); +#endif + // *vthresh=round(vthreshmean-nsigma*vthreshSTDev); + thr=(int)(vthreshmean-nsigma*vthreshSTDev); + if (thr<0 || thr>(DAC_DR-1)) { + thr=thrmi[imod]/2; + printf("Can't find correct threshold for module %d\n",imod); + retval=FAIL; + } + //commented out by dhanya initDACbyIndexDACU(VTHRESH,thr,imod); +#ifdef VERBOSE + printf("vthresh=%d \n",thr); +#endif + c=CVTRIM-2.*nsigma*vthreshSTDev/63.; + // thr=(int)((-b-sqrt(b*b-4*a*c))/(2*a)); cuz is commented in firmware_funcs.c and in shared_memory.c + if (thr<500 || thr>(DAC_DR-1)) { + thr=750; + printf("Can't find correct trimbit size for module %d\n",imod); + retval=FAIL; + } + + //commented out by dhanya initDACbyIndexDACU(VTRIM,thr,imod); + +#ifdef VERBOSE + printf("vtrim=%d \n",thr); +#endif + + } + free(trim); + free(thrmi); + free(thrma); + +#endif + return retval; +} + + + + + +int trim_with_level(int countlim, int im) { + int ich, itrim, ichan, ichip, imod; + u_int32_t *scan; + int *inttrim; + int modma, modmi, nm; + int retval=OK; + int *fifodata; + sls_detector_channel myChan; + printf("trimming module number %d", im); + + +#ifdef MCB_FUNCS + setFrames(1); + // setNMod(getNModBoard()); + + if (im==ALLMOD){ + modmi=0; + modma=nModX; + } else { + modmi=im; + modma=im+1; + } + nm=modma-modmi; + + inttrim=malloc(sizeof(int)*nChips*nChans*nModX); + printf("countlim=%d\n",countlim); + for (ich=0; ichcountlim){ + inttrim[ich]=itrim; + if (scan[ich]>2*countlim && itrim>0) { + //if (scan[ich]>2*countlim || itrim==0) { + inttrim[ich]=itrim-1; + } +#ifdef VERBOSE + printf("Channel %d trimbit %d counted %d (%08x) countlim %d\n",ich,itrim,scan[ich],fifodata[ich],countlim); +#endif + } + } +#ifdef VERBOSE + /* else + printf("Channel %d trimbit %d counted %d countlim %d\n",ich,itrim,scan[ich],countlim);*/ +#endif + } + } + free(scan); + } + + for (imod=modmi; imod0) + direction[ichan]=1; + else + direction[ichan]=-1; + } + vthresh=getDACbyIndexDACU(VTHRESH,imod); + if ( direction[ichan]!=-3) { + if (abs(diff)>abs(olddiff[ichan])) { + vthresh=vthresh-direction[ichan]; + if (vthresh>(DAC_DR-1)) { + vthresh=(DAC_DR-1); + printf("can't equalize threshold for module %d\n", ichan); + retval=FAIL; + } + if (vthresh<0) { + vthresh=0; + printf("can't equalize threshold for module %d\n", ichan); + retval=FAIL; + } + direction[ichan]=-3; + } else { + vthresh=vthresh+direction[ichan]; + olddiff[ichan]=diff; + change_flag=1; + } + initDACbyIndex(VTHRESH,vthresh, ichan); + } + } + iteration++; + free(scan); + free(scan1); + } +#endif +*/ + return retval; +} + + + + + +int trim_with_median(int stop, int im) { + + + int retval=OK; + +#ifdef MCB_FUNCS + int ichan, imod, ichip, ich; + u_int32_t *scan, *scan1; + int *olddiff, *direction; + int med, diff; + int change_flag=1; + int iteration=0; + int me[nModX], me1[nModX]; + int modma, modmi, nm; + int trim; + int *fifodata; + + setFrames(1); + // setNMod(getNModBoard()); + + if (im==ALLMOD){ + modmi=0; + modma=nModX; + } else { + modmi=im; + modma=im+1; + } + nm=modma-modmi; + + olddiff=malloc(4*nModX*nChips*nChans); + direction=malloc(4*nModX*nChips*nChans); + for (imod=modmi; imod0) { + direction[ichan]=1; + } else { + direction[ichan]=-1; + } + } + if ( direction[ichan]!=-3) { + if (abs(diff)>abs(olddiff[ichan])) { + trim=getTrimbit(imod,ichip,ich)+direction[ichan]; + printf("%d old diff %d < new diff %d %d - trimbit %d\n",ichan, olddiff[ichan], diff, direction[ichan], trim); + direction[ichan]=-3; + } else { + trim=getTrimbit(imod,ichip,ich)-direction[ichan]; + olddiff[ichan]=diff; + change_flag=1; + } + if (trim>TRIM_DR) { + trim=63; + printf("can't trim channel %d chip %d module %d to trim %d\n",ich, ichip, imod, trim); + retval=FAIL; + } + if (trim<0) { + printf("can't trim channel %d chip %d module %d to trim %d\n",ich, ichip, imod, trim); + trim=0; + retval=FAIL; + } + initChannel(trim,0,0,1,0,0,imod); + } + } + } + } + iteration++; + free(scan); + free(scan1); + } + free(olddiff); + free(direction); +#endif + return retval; +} diff --git a/slsDetectorSoftware/gotthardDetectorServer/trimming_funcs.h b/slsDetectorSoftware/gotthardDetectorServer/trimming_funcs.h new file mode 100755 index 000000000..c41451008 --- /dev/null +++ b/slsDetectorSoftware/gotthardDetectorServer/trimming_funcs.h @@ -0,0 +1,17 @@ +#ifndef TRIMMING_FUNCS_H +#define TRIMMING_FUNCS_H +int trim_fixed_settings(int countlim, int par2, int imod); +int trim_with_noise(int countlim, int nsigma, int imod); +int trim_with_beam(int countlim, int nsigma, int imod); +int trim_improve(int maxit, int par2, int imod); +int calcthr_from_vcal(int vcal); +int calccal_from_vthr(int vthr); +int choose_vthresh_and_vtrim(int countlim, int nsigma, int imod); + +int choose_vthresh(); +int trim_with_level(int countlim, int imod); +int trim_with_median(int stop, int imod); +int calcthr_from_vcal(int vcal); +int calccal_from_vthr(int vthr); + +#endif diff --git a/slsDetectorSoftware/multiSlsDetector/multiSlsDetector.cpp b/slsDetectorSoftware/multiSlsDetector/multiSlsDetector.cpp new file mode 100644 index 000000000..3d4ea0ff8 --- /dev/null +++ b/slsDetectorSoftware/multiSlsDetector/multiSlsDetector.cpp @@ -0,0 +1,3624 @@ +#include "multiSlsDetector.h" +#include "usersFunctions.h" +#include +#include +#include + + + + +int multiSlsDetector::freeSharedMemory(int i) { + int nd=nDetectors; + for (int id=0; idfreeSharedMemory(); + delete detectors[id]; + detectors[id]=NULL; + nDetectors--; + } + return OK; +} + + +multiSlsDetector::multiSlsDetector(detectorType type, int ndet, int id): nDetectors(0) +{ + for (int i=0; i=0) { + imin=i; + imax=i; + } + for (int j=imin; j=0) { + imin=i; + imax=i; + } + + for (int j=imin; jsetOnline(off); + if (ret==GET_ONLINE_FLAG && err==0) + ret=ans; + if (ret!=ans) { + err=1; + ret=GET_ONLINE_FLAG; + } + } + } + return ret; +}; + + +int multiSlsDetector::exists(int id) { + + for (int i=0; igetId())==id) + return 1; + } + } + return 0; + +} + + + + + + + + + + + + + + + + + + + + /* + configure the socket communication and check that the server exists + enum communicationProtocol{ + TCP, + UDP + }{}; + + */ + +int multiSlsDetector::setTCPSocket(int i, string const name, int const control_port, int const stop_port, int const data_port){ + + if (i<0) + return FAIL; + if (detectors[i]) + return detectors[i]->setTCPSocket(name, control_port, stop_port, data_port); + else + return FAIL; +}; + + + + +char* multiSlsDetector::getHostname(int i) { + if (i<0) + return FAIL; + if (detectors[i]) + return detectors[i]->getHostname(); + else + return NULL; +} + +int multiSlsDetector::getControlPort(int i) { + + + int imin=0, imax=nDetectors; + int ret=-1, err=0; + if (i>=0) { + imin=i; + imax=i; + } + for (int j=imin; jgetControlPort(); + else if (detectors[j]->getControlPort()!=ret) { + ret=-1; + err=1; + } + } else { + ret=-1; + err=1; + } + } + return ret; +} + +int multiSlsDetector::getDataPort(int i) { + + + + + int imin=0, imax=nDetectors; + int ret=-1, err=0; + if (i>=0) { + imin=i; + imax=i; + } + for (int j=imin; jgetDataPort(); + else if (detectors[j]->getDataPort()!=ret) { + ret=-1; + err=1; + } + } else { + ret=-1; + err=1; + } + } + return ret; + + + + +} + + +int multiSlsDetector::getStopPort(int i) { + + int imin=0, imax=nDetectors; + int ret=-1, err=0; + if (i>=0) { + imin=i; + imax=i; + } + for (int j=imin; jgetStopPort(); + else if (detectors[j]->getStopPort()!=ret) { + ret=-1; + err=1; + } + } else { + ret=-1; + err=1; + } + } + return ret; + +} + + + /* I/O */ + +/* generates file name without extension*/ + +string multiSlsDetector::createFileName() { + + string ret=string("error"), ans; + int err=0; + + for (int i=0; icreateFileName(); + else { + ans=string("error"); + err=1; + } + if (ret==string("error") && err==0) + ret=ans; + else if (ans!=ret) { + ret=string("error"); + err=1; + } + } + return ret; + +} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + /* Communication to server */ + + // General purpose functions + + /* + executes a system command on the server + e.g. mount an nfs disk, reboot and returns answer etc. + */ +int multiSlsDetector::execCommand(string cmd, string answer){ + + char arg[MAX_STR_LENGTH], retval[MAX_STR_LENGTH]; + int fnum=F_EXEC_COMMAND; + + int ret=FAIL; + + strcpy(arg,cmd.c_str()); + +#ifdef VERBOSE + std::cout<< std::endl; + std::cout<< "Sending command " << arg << std::endl; +#endif + if (thisDetector->onlineFlag==ONLINE_FLAG) { + if (controlSocket) { + if (controlSocket->Connect()>=0) { + if (controlSocket->SendDataOnly(&fnum,sizeof(fnum))>=0) { + if (controlSocket->SendDataOnly(arg,MAX_STR_LENGTH)>=0) { + if (controlSocket->ReceiveDataOnly(retval,MAX_STR_LENGTH)>=0) { + ret=OK; + answer=retval; + } + } + } + controlSocket->Disconnect(); + } + } +#ifdef VERBOSE + std::cout<< "Detector answer is " << answer << std::endl; +#endif + } + return ret; +}; + +// Detector configuration functions + + /* + the detector knows what type of detector it is + + enum detectorType{ + GET_DETECTOR_TYPE, + GENERIC, + MYTHEN, + PILATUS, + EIGER, + GOTTHARD, + AGIPD + }; + + */ +int multiSlsDetector::setDetectorType(detectorType const type){ + + int arg, retval=FAIL; + int fnum=F_GET_DETECTOR_TYPE; + arg=int(type); + detectorType retType=type; + char mess[100]; + strcpy(mess,"dummy"); + + +#ifdef VERBOSE + std::cout<< std::endl; + std::cout<< "Setting detector type to " << arg << std::endl; +#endif + if (thisDetector->onlineFlag==ONLINE_FLAG) { + if (controlSocket) { + if (controlSocket->Connect()>=0) { + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); + if (retval==OK) + controlSocket->ReceiveDataOnly(&retType,sizeof(retType)); + else { + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + } + controlSocket->Disconnect(); + } + } + } else { + if (type==GET_DETECTOR_TYPE) + retType=thisDetector->myDetectorType; + else { + retType=type; + thisDetector->myDetectorType=type; + } + retval=OK; + } +#ifdef VERBOSE + std::cout<< "Detector type set to " << retType << std::endl; +#endif + if (retval==FAIL) { + std::cout<< "Set detector type failed " << std::endl; + retType=GENERIC; + } + else + thisDetector->myDetectorType=retType; + + + return retType; +}; + +int multiSlsDetector::setDetectorType(string const type){ + detectorType dtype=GENERIC; + if (type=="Mythen") + dtype=MYTHEN; + else if (type=="Pilatus") + dtype=PILATUS; + else if (type=="Eiger") + dtype=EIGER; + else if (type=="Gotthard") + dtype=GOTTHARD; + else if (type=="Agipd") + dtype=AGIPD; + return setDetectorType(dtype); +}; + +void multiSlsDetector::getDetectorType(char *type){ + + switch (thisDetector->myDetectorType) { + case MYTHEN: + strcpy(type,"Mythen"); + break; + case PILATUS: + strcpy(type,"Pilatus"); + break; + case EIGER: + strcpy(type,"Eiger"); + break; + case GOTTHARD: + strcpy(type,"Gotthard"); + break; + case AGIPD: + strcpy(type,"Agipd"); + break; + default: + strcpy(type,"Unknown"); + break; + } +}; + + + + + /* needed to set/get the size of the detector */ +// if n=GET_FLAG returns the number of installed modules, +int multiSlsDetector::setNumberOfModules(int n, dimension d){ + + int arg[2], retval; + int fnum=F_SET_NUMBER_OF_MODULES; + int ret=FAIL; + char mess[100]; + + + arg[0]=d; + arg[1]=n; + + + if (dY) { + std::cout<< "Set number of modules in wrong dimension " << d << std::endl; + return ret; + } + + +#ifdef VERBOSE + std::cout<< std::endl; + std::cout<< "Setting number of modules of dimension "<< d << " to " << n << std::endl; +#endif + if (thisDetector->onlineFlag==ONLINE_FLAG) { + if (controlSocket) { + if (controlSocket->Connect()>=0) { + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + controlSocket->SendDataOnly(&arg,sizeof(arg)); + controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret==OK) + controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); + else { + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Deterctor returned error: " << mess << std::endl; + } + controlSocket->Disconnect(); + } + } + } else { + ret=OK; + if (n==GET_FLAG) + ; + else { + if (n<=0 || n>thisDetector->nModMax[d]) { + ret=FAIL; + } else { + thisDetector->nMod[d]=n; + } + } + retval=thisDetector->nMod[d]; + } +#ifdef VERBOSE + std::cout<< "Number of modules in dimension "<< d <<" is " << retval << std::endl; +#endif + if (ret==FAIL) { + std::cout<< "Set number of modules failed " << std::endl; + } else { + thisDetector->nMod[d]=retval; + thisDetector->nMods=thisDetector->nMod[X]*thisDetector->nMod[Y]; + int dr=thisDetector->dynamicRange; + if (dr==24) + dr=32; + + if (thisDetector->timerValue[PROBES_NUMBER]==0) { + thisDetector->dataBytes=thisDetector->nMod[X]*thisDetector->nMod[Y]*thisDetector->nChips*thisDetector->nChans*dr/8; + } else { + thisDetector->dataBytes=thisDetector->nMod[X]*thisDetector->nMod[Y]*thisDetector->nChips*thisDetector->nChans*4; + } + +#ifdef VERBOSE + std::cout<< "Data size is " << thisDetector->dataBytes << std::endl; + std::cout<< "nModX " << thisDetector->nMod[X] << " nModY " << thisDetector->nMod[Y] << " nChips " << thisDetector->nChips << " nChans " << thisDetector->nChans<< " dr " << dr << std::endl; +#endif + } + return thisDetector->nMod[d]; +}; + + + + +int multiSlsDetector::getMaxNumberOfModules(dimension d){ + + int retval; + int fnum=F_GET_MAX_NUMBER_OF_MODULES; + int ret=FAIL; + char mess[100]; + + if (dY) { + std::cout<< "Get max number of modules in wrong dimension " << d << std::endl; + return ret; + } +#ifdef VERBOSE + std::cout<< std::endl; + std::cout<< "Getting max number of modules in dimension "<< d <onlineFlag==ONLINE_FLAG) { + if (controlSocket) { + if (controlSocket->Connect()>=0) { + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + controlSocket->SendDataOnly(&d,sizeof(d)); + controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret==OK) + controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); + else { + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Deterctor returned error: " << mess << std::endl; + } + controlSocket->Disconnect(); + } + } + } else { + ret=OK; + retval=thisDetector->nModMax[d]; + } +#ifdef VERBOSE + std::cout<< "Max number of modules in dimension "<< d <<" is " << retval << std::endl; +#endif + if (ret==FAIL) { + std::cout<< "Get max number of modules failed " << std::endl; + return retval; + } else { + thisDetector->nModMax[d]=retval; + thisDetector->nModsMax=thisDetector->nModMax[0]*thisDetector->nModMax[1]; + } + return thisDetector->nModMax[d]; +}; + + + + /* + This function is used to set the polarity and meaning of the digital I/O signals (signal index) + +enum externalSignalFlag { + GET_EXTERNAL_SIGNAL_FLAG, + SIGNAL_OFF, + GATE_ACTIVE_HIGH, + GATE_ACTIVE_LOW, + TRIGGER_RISING_EDGE, + TRIGGER_FALLING_EDGE +}{}; + */ + + externalSignalFlag multiSlsDetector::setExternalSignalFlags(externalSignalFlag pol, int signalindex){ + + + + + int arg[2]; + externalSignalFlag retval; + int ret=FAIL; + int fnum=F_SET_EXTERNAL_SIGNAL_FLAG; + char mess[100]; + + arg[0]=signalindex; + arg[1]=pol; + + retval=GET_EXTERNAL_SIGNAL_FLAG; + +#ifdef VERBOSE + std::cout<< std::endl; + std::cout<< "Setting signal "<< signalindex << " to flag" << pol << std::endl; +#endif + if (thisDetector->onlineFlag==ONLINE_FLAG) { + if (controlSocket) { + if (controlSocket->Connect()>=0) { + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + controlSocket->SendDataOnly(&arg,sizeof(arg)); + controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret==OK) + controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); + else { + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + } + controlSocket->Disconnect(); + } + } + } else { + retval=GET_EXTERNAL_SIGNAL_FLAG; + ret=FAIL; + } +#ifdef VERBOSE + std::cout<< "Signal "<< signalindex << " flag set to" << retval << std::endl; + if (ret==FAIL) { + std::cout<< "Set signal flag failed " << std::endl; + } +#endif + return retval; + + + + + + +}; + + /* + this function is used to select wether the detector is triggered or gated and in which mode + enum externalCommunicationMode{ + GET_EXTERNAL_COMMUNICATION_MODE, + AUTO, + TRIGGER_EXPOSURE, + TRIGGER_READOUT, + TRIGGER_COINCIDENCE_WITH_INTERNAL_ENABLE, + GATE_FIX_NUMBER, + GATE_FIX_DURATION, + GATE_WITH_START_TRIGGER, + GATE_COINCIDENCE_WITH_INTERNAL_ENABLE +}; + + */ + + externalCommunicationMode multiSlsDetector::setExternalCommunicationMode( externalCommunicationMode pol){ + + + + + int arg[1]; + externalCommunicationMode retval; + int fnum=F_SET_EXTERNAL_COMMUNICATION_MODE; + char mess[100]; + + arg[0]=pol; + + int ret=FAIL; + retval=GET_EXTERNAL_COMMUNICATION_MODE; + +#ifdef VERBOSE + std::cout<< std::endl; + std::cout<< "Setting communication to mode " << pol << std::endl; +#endif + if (thisDetector->onlineFlag==ONLINE_FLAG) { + if (controlSocket) { + if (controlSocket->Connect()>=0) { + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + controlSocket->SendDataOnly(&arg,sizeof(arg)); + controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret==OK) + controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); + else { + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + } + controlSocket->Disconnect(); + } + } + } else { + retval=GET_EXTERNAL_COMMUNICATION_MODE; + ret=FAIL; + } +#ifdef VERBOSE + std::cout<< "Communication mode "<< " set to" << retval << std::endl; +#endif + if (ret==FAIL) { + std::cout<< "Setting communication mode failed" << std::endl; + } + return retval; + +}; + + + // Tests and identification + /* + Gets versions + + enum idMode{ + MODULE_SERIAL_NUMBER, + MODULE_FIRMWARE_VERSION, + DETECTOR_SERIAL_NUMBER, + DETECTOR_FIRMWARE_VERSION, + DETECTOR_SOFTWARE_VERSION + }{}; + + */ + + + + + +int64_t multiSlsDetector::getId( idMode mode, int imod){ + + + int64_t retval=-1; + int fnum=F_GET_ID; + int ret=FAIL; + + char mess[100]; + +#ifdef VERBOSE + std::cout<< std::endl; + if (mode==MODULE_SERIAL_NUMBER) + std::cout<< "Getting id of "<< imod << std::endl; + else + std::cout<< "Getting id type "<< mode << std::endl; +#endif + if (mode==THIS_SOFTWARE_VERSION) { + ret=OK; + retval=thisSoftwareVersion; + } else { + if (thisDetector->onlineFlag==ONLINE_FLAG) { + if (controlSocket) { + if (controlSocket->Connect()>=0) { + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + controlSocket->SendDataOnly(&mode,sizeof(mode)); + if (mode==MODULE_SERIAL_NUMBER) + controlSocket->SendDataOnly(&imod,sizeof(imod)); + controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret==OK) + controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); + else { + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + } + controlSocket->Disconnect(); + } else + ret=FAIL; + } else { + ret=FAIL; + } + } + } + if (ret==FAIL) { + std::cout<< "Get id failed " << std::endl; + return ret; + } else { +#ifdef VERBOSE + if (mode==MODULE_SERIAL_NUMBER) + std::cout<< "Id of "<< imod <<" is " << hex <onlineFlag==ONLINE_FLAG) { + + + if (controlSocket) { + if (controlSocket->Connect()>=0) { + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + controlSocket->SendDataOnly(&mode,sizeof(mode)); + if (mode==CHIP_TEST) + controlSocket->SendDataOnly(&imod,sizeof(imod)); + controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret==OK) + controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); + else { + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + } + controlSocket->Disconnect(); + } + } + } else { + ret=FAIL; + } +#ifdef VERBOSE + std::cout<< "Id "<< mode <<" is " << retval << std::endl; +#endif + if (ret==FAIL) { + std::cout<< "Get id failed " << std::endl; + return ret; + } else + return retval; +}; + + + + /* + analog test of the modules + enum analogTestMode { + COUNT_CALIBRATION_PULSES, + I_DON_T_KNOW + }{}; + + */ +/* +int* multiSlsDetector::analogTest(analogTestMode mode){ + std::cout<< "function not yet implemented " << std::endl; +}; +*/ + /* + enable analog output of channel + */ +/* +int multiSlsDetector::enableAnalogOutput(int ichan){ + int imod=ichan/(nChans*nChips); + ichan-=imod*(nChans*nChips); + int ichip=ichan/nChans; + ichan-=ichip*(nChans); + enableAnalogOutput(imod,ichip,ichan); + +}; +int multiSlsDetector::enableAnalogOutput(int imod, int ichip, int ichan){ + std::cout<< "function not yet implemented " << std::endl; +}; +*/ + /* + give a train of calibration pulses + */ +/* +int multiSlsDetector::giveCalibrationPulse(float vcal, int npulses){ + std::cout<< "function not yet implemented " << std::endl; +}; +*/ + // Expert low level functions + + + + /* write or read register */ + +int multiSlsDetector::writeRegister(int addr, int val){ + + + int retval; + int fnum=F_WRITE_REGISTER; + int ret=FAIL; + + char mess[100]; + + int arg[2]; + arg[0]=addr; + arg[1]=val; + + +#ifdef VERBOSE + std::cout<< std::endl; + std::cout<< "Writing to register "<< addr << " data " << val << std::endl; +#endif + if (thisDetector->onlineFlag==ONLINE_FLAG) { + if (controlSocket) { + if (controlSocket->Connect()>=0) { + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + controlSocket->SendDataOnly(arg,sizeof(arg)); + controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret==OK) + controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); + else { + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + } + controlSocket->Disconnect(); + } + } + } +#ifdef VERBOSE + std::cout<< "Register returned "<< retval << std::endl; +#endif + if (ret==FAIL) { + std::cout<< "Write to register failed " << std::endl; + } + return retval; + +}; + + + + +int multiSlsDetector::readRegister(int addr){ + + + int retval; + int fnum=F_READ_REGISTER; + int ret=FAIL; + + char mess[100]; + + int arg; + arg=addr; + + +#ifdef VERBOSE + std::cout<< std::endl; + std::cout<< "Reding register "<< addr << std::endl; +#endif + if (thisDetector->onlineFlag==ONLINE_FLAG) { + if (controlSocket) { + if (controlSocket->Connect()>=0) { + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + controlSocket->SendDataOnly(&arg,sizeof(arg)); + controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret==OK) + controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); + else { + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + } + controlSocket->Disconnect(); + } + } + } +#ifdef VERBOSE + std::cout<< "Register returned "<< retval << std::endl; +#endif + if (ret==FAIL) { + std::cout<< "Read register failed " << std::endl; + } + return retval; + +}; + + + // Expert initialization functions + /* + set dacs or read ADC for the module + enum dacIndex { + TRIMBIT_SIZE, + THRESHOLD, + SHAPER1, + SHAPER2, + CALIBRATION_PULSE, + PREAMP, + TEMPERATURE, + HUMIDITY, + DETECTOR_BIAS +}{}; + */ + + +float multiSlsDetector::setDAC(float val, dacIndex index, int imod){ + + + float retval; + int fnum=F_SET_DAC; + int ret=FAIL; + char mess[100]; + int arg[2]; + arg[0]=index; + arg[1]=imod; + +#ifdef VERBOSE + std::cout<< std::endl; + std::cout<< "Setting DAC/POT "<< index << "of module " << imod << " to " << val << std::endl; +#endif + if (thisDetector->onlineFlag==ONLINE_FLAG) { + if (controlSocket) { + if (controlSocket->Connect()>=0) { + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + controlSocket->SendDataOnly(arg,sizeof(arg)); + controlSocket->SendDataOnly(&val,sizeof(val)); + controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret==OK) { + controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); + if (index < thisDetector->nDacs){ + + if (dacs) { + if (imod>=0) { + *(dacs+index+imod*thisDetector->nDacs)=retval; + } + else { + for (imod=0; imodnModsMax; imod++) + *(dacs+index+imod*thisDetector->nDacs)=retval; + } + } + } + } else { + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + } + controlSocket->Disconnect(); + } + + } + } +#ifdef VERBOSE + std::cout<< "Dac/Pot set to "<< retval << std::endl; +#endif + if (ret==FAIL) { + std::cout<< "Set dac/pot failed " << std::endl; + } + return retval; + + + +}; + + +float multiSlsDetector::getADC(dacIndex index, int imod){ + + float retval; + int fnum=F_GET_ADC; + int ret=FAIL; + char mess[100]; + + int arg[2]; + arg[0]=index; + arg[1]=imod; + + + +#ifdef VERBOSE + std::cout<< std::endl; + std::cout<< "Getting ADC "<< index << "of module " << imod << std::endl; +#endif + if (thisDetector->onlineFlag==ONLINE_FLAG) { + if (controlSocket) { + if (controlSocket->Connect()>=0) { + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + controlSocket->SendDataOnly(arg,sizeof(arg)); + controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret==OK) { + controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); + if (adcs) { + *(adcs+index+imod*thisDetector->nAdcs)=retval; + } + } else { + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + } + controlSocket->Disconnect(); + } + } + } +#ifdef VERBOSE + std::cout<< "ADC returned "<< retval << std::endl; +#endif + if (ret==FAIL) { + std::cout<< "Get ADC failed " << std::endl; + } + return retval; + + + +}; + + /* + configure single channel + enum channelRegisterBit { + COMPARATOR_ENABLE_OFF, + ANALOG_SIGNAL_ENABLE_OFF, + CALIBRATION_ENABLE_OFF, + TRIMBIT_OFF // should always be the last! + } + + */ + +int multiSlsDetector::setChannel(int64_t reg, int ichan, int ichip, int imod){ + sls_detector_channel myChan; +#ifdef VERBOSE + std::cout<< "Setting channel "<< ichan << " " << ichip << " " << imod << " to " << reg << std::endl; +#endif + //int mmin=imod, mmax=imod+1, chimin=ichip, chimax=ichip+1, chamin=ichan, chamax=ichan+1; + + int ret; + + /* if (imod==-1) { + mmin=0; + mmax=thisDetector->nModsMax; + } + + if (ichip==-1) { + chimin=0; + chimax=thisDetector->nChips; + } + + if (ichan==-1) { + chamin=0; + chamax=thisDetector->nChans; + }*/ + + // for (int im=mmin; imonlineFlag==ONLINE_FLAG) { + if (controlSocket) { + if (controlSocket->Connect()>=0) { + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + sendChannel(&chan); + + controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret==OK) { + controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); + } else { + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + } + controlSocket->Disconnect(); + } + } + } + + + if (ret==OK) { + if (chanregs) { + +int mmin=imod, mmax=imod+1, chimin=ichip, chimax=ichip+1, chamin=ichan, chamax=ichan+1; + + if (imod==-1) { + mmin=0; + mmax=thisDetector->nModsMax; + } + + if (ichip==-1) { + chimin=0; + chimax=thisDetector->nChips; + } + + if (ichan==-1) { + chamin=0; + chamax=thisDetector->nChans; + } + + + + + + + for (int im=mmin; imnChans*thisDetector->nChips+ichi*thisDetector->nChips+icha)=retval; + + } + } +} + + } + } +#ifdef VERBOSE + std::cout<< "Channel register returned "<< retval << std::endl; +#endif + return retval; + +} + + sls_detector_channel multiSlsDetector::getChannel(int ichan, int ichip, int imod){ + + + int fnum=F_GET_CHANNEL; + sls_detector_channel myChan; + int arg[3]; + int ret=FAIL; + char mess[100]; + arg[0]=ichan; + arg[1]=ichip; + arg[2]=imod; + if (thisDetector->onlineFlag==ONLINE_FLAG) { + if (controlSocket) { + if (controlSocket->Connect()>=0) { + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + controlSocket->SendDataOnly(arg,sizeof(arg)); + + controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret==OK) { + receiveChannel(&myChan); + } else { + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + } + controlSocket->Disconnect(); + } + } + } + + + if (ret==OK) { + if (chanregs) { + *(chanregs+imod*thisDetector->nChans*thisDetector->nChips+ichip*thisDetector->nChips+ichan)=myChan.reg; + } + } + +#ifdef VERBOSE + std::cout<< "Returned channel "<< ichan << " " << ichip << " " << imod << " " << myChan.reg << std::endl; +#endif + return myChan; +} + + /* + configure chip + enum chipRegisterBit { + ENABLE_ANALOG_OUTPUT, + OUTPUT_WIDTH // should always be the last + }{}; + */ +int multiSlsDetector::setChip(int reg, int ichip, int imod){ + sls_detector_chip myChip; + +#ifdef VERBOSE + std::cout<< "Setting chip "<< ichip << " " << imod << " to " << reg << std::endl; +#endif + + + int chregs[thisDetector->nChans]; + int mmin=imod, mmax=imod+1, chimin=ichip, chimax=ichip+1; + int ret=FAIL; + if (imod==-1) { + mmin=0; + mmax=thisDetector->nModsMax; + } + + if (ichip==-1) { + chimin=0; + chimax=thisDetector->nChips; + } + + myChip.nchan=thisDetector->nChans; + myChip.reg=reg; + for (int im=mmin; imnChans+im*thisDetector->nChans*thisDetector->nChips); + else { + for (int i=0; inChans; i++) + chregs[i]=-1; + myChip.chanregs=chregs; + } + ret=setChip(myChip); + } + } + return ret; +} + +int multiSlsDetector::setChip(sls_detector_chip chip){ + + int fnum=F_SET_CHIP; + int retval; + int ret=FAIL; + char mess[100]; + + int ichi=chip.chip; + int im=chip.module; + + + + + + if (thisDetector->onlineFlag==ONLINE_FLAG) { + if (controlSocket) { + if (controlSocket->Connect()>=0) { + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + sendChip(&chip); + controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret==OK) { + controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); + } else { + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + } + controlSocket->Disconnect(); + } + } + } + + + if (ret==OK) { + if (chipregs) + *(chipregs+ichi+im*thisDetector->nChips)=retval; + } + +#ifdef VERBOSE + std::cout<< "Chip register returned "<< retval << std::endl; +#endif + return retval; +}; + + + sls_detector_chip multiSlsDetector::getChip(int ichip, int imod){ + + int fnum=F_GET_CHIP; + sls_detector_chip myChip; + int chanreg[thisDetector->nChans]; + + int ret=FAIL; + char mess[100]; + + + myChip.chip=ichip; + myChip.module=imod; + myChip.nchan=thisDetector->nChans; + myChip.chanregs=chanreg; + + int arg[2]; + arg[0]=ichip; + arg[1]=imod; + + + + + if (thisDetector->onlineFlag==ONLINE_FLAG) { + if (controlSocket) { + if (controlSocket->Connect()>=0) { + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + controlSocket->SendDataOnly(arg,sizeof(arg)); + + controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret==OK) { + receiveChip(&myChip); + } else { + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + } + controlSocket->Disconnect(); + } + } + } + + + if (ret==OK) { + if (chipregs) + *(chipregs+ichip+imod*thisDetector->nChips)=myChip.reg; + if (chanregs) { + for (int ichan=0; ichannChans; ichan++) + *(chanregs+imod*thisDetector->nChans*thisDetector->nChips+ichip*thisDetector->nChans+ichan)=*((myChip.chanregs)+ichan); + } + } +#ifdef VERBOSE + std::cout<< "Returned chip "<< ichip << " " << imod << " " << myChip.reg << std::endl; +#endif + + return myChip; +}; + + /* + configure module + enum moduleRegisterBit { + I_DON_T_KNOW, + OUTPUT_WIDTH // should always be the last + }{}; + */ + +int multiSlsDetector::setModule(int reg, int imod){ + sls_detector_module myModule; + +#ifdef VERBOSE + std::cout << "slsDetector set module " << std::endl; +#endif + int charegs[thisDetector->nChans*thisDetector->nChips]; + int chiregs[thisDetector->nChips]; + float das[thisDetector->nDacs], ads[thisDetector->nAdcs]; + int mmin=imod, mmax=imod+1; + int ret=FAIL; + + if (imod==-1) { + mmin=0; + mmax=thisDetector->nModsMax; + } + + + + for (int im=mmin; imnChans; + myModule.nchip=thisDetector->nChips; + myModule.ndac=thisDetector->nDacs; + myModule.nadc=thisDetector->nAdcs; + + myModule.reg=reg; + if (detectorModules) { + myModule.gain=(detectorModules+im)->gain; + myModule.offset=(detectorModules+im)->offset; + myModule.serialnumber=(detectorModules+im)->serialnumber; + } else { + myModule.gain=-1; + myModule.offset=-1; + myModule.serialnumber=-1; + } + + + for (int i=0; inAdcs; i++) + ads[i]=-1; + + if (chanregs) + myModule.chanregs=chanregs+im*thisDetector->nChips*thisDetector->nChans; + else { + for (int i=0; inChans*thisDetector->nChips; i++) + charegs[i]=-1; + myModule.chanregs=charegs; + } + if (chipregs) + myModule.chipregs=chanregs+im*thisDetector->nChips; + else { + for (int ichip=0; ichipnChips; ichip++) + chiregs[ichip]=-1; + myModule.chipregs=chiregs; + } + if (dacs) + myModule.dacs=dacs+im*thisDetector->nDacs; + else { + for (int i=0; inDacs; i++) + das[i]=-1; + myModule.dacs=das; + } + if (adcs) + myModule.adcs=adcs+im*thisDetector->nAdcs; + else { + for (int i=0; inAdcs; i++) + ads[i]=-1; + myModule.adcs=ads; + } + ret=setModule(myModule); + } + return ret; + + +}; + + + +int multiSlsDetector::setModule(sls_detector_module module){ + + + int fnum=F_SET_MODULE; + int retval; + int ret=FAIL; + char mess[100]; + + int imod=module.module; + + + +#ifdef VERBOSE + std::cout << "slsDetector set module " << std::endl; +#endif + + + if (thisDetector->onlineFlag==ONLINE_FLAG) { + if (controlSocket) { + if (controlSocket->Connect()>=0) { + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + sendModule(&module); + controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret==OK) { + controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); + } else { + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + } + controlSocket->Disconnect(); + } + } + } + + + if (ret==OK) { + if (detectorModules) { + if (imod>=0 && imodnMod[X]*thisDetector->nMod[Y]) { + (detectorModules+imod)->nchan=module.nchan; + (detectorModules+imod)->nchip=module.nchip; + (detectorModules+imod)->ndac=module.ndac; + (detectorModules+imod)->nadc=module.nadc; + thisDetector->nChips=module.nchip; + thisDetector->nChans=module.nchan/module.nchip; + thisDetector->nDacs=module.ndac; + thisDetector->nAdcs=module.nadc; + + for (int ichip=0; ichipnChips; ichip++) { + if (chipregs) + chipregs[ichip+thisDetector->nChips*imod]=module.chipregs[ichip]; + + if (chanregs) { + for (int i=0; inChans; i++) { + chanregs[i+ichip*thisDetector->nChans+thisDetector->nChips*thisDetector->nChans*imod]=module.chanregs[ichip*thisDetector->nChans+i]; + } + } + } + if (dacs) { + for (int i=0; inDacs; i++) + dacs[i+imod*thisDetector->nDacs]=module.dacs[i]; + } + if (adcs) { + for (int i=0; inAdcs; i++) + adcs[i+imod*thisDetector->nAdcs]=module.adcs[i]; + } + + (detectorModules+imod)->gain=module.gain; + (detectorModules+imod)->offset=module.offset; + (detectorModules+imod)->serialnumber=module.serialnumber; + (detectorModules+imod)->reg=module.reg; + } + } + } + +#ifdef VERBOSE + std::cout<< "Module register returned "<< retval << std::endl; +#endif + + return retval; +}; + +sls_detector_module *multiSlsDetector::getModule(int imod){ + +#ifdef VERBOSE + std::cout << "slsDetector get module " << std::endl; +#endif + + int fnum=F_GET_MODULE; + sls_detector_module *myMod=createModule(); + + + //char *ptr, *goff=(char*)thisDetector; + + // int chanreg[thisDetector->nChans*thisDetector->nChips]; + //int chipreg[thisDetector->nChips]; + //float dac[thisDetector->nDacs], adc[thisDetector->nAdcs]; + + int ret=FAIL; + char mess[100]; + // int n; + +#ifdef VERBOSE + std::cout<< "getting module " << imod << std::endl; +#endif + + myMod->module=imod; + // myMod.nchan=thisDetector->nChans*thisDetector->nChips; + //myMod.chanregs=chanreg; + //myMod.nchip=thisDetector->nChips; + //myMod.chipregs=chipreg; + //myMod.ndac=thisDetector->nDacs; + //myMod.dacs=dac; + //myMod.ndac=thisDetector->nAdcs; + //myMod.dacs=adc; + + + + + + + if (thisDetector->onlineFlag==ONLINE_FLAG) { + if (controlSocket) { + if (controlSocket->Connect()>=0) { + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + controlSocket->SendDataOnly(&imod,sizeof(imod)); + + controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret==OK) { + receiveModule(myMod); + } else { + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + } + controlSocket->Disconnect(); + } + } + } + + + if (ret==OK) { + if (detectorModules) { + if (imod>=0 && imodnMod[X]*thisDetector->nMod[Y]) { + (detectorModules+imod)->nchan=myMod->nchan; + (detectorModules+imod)->nchip=myMod->nchip; + (detectorModules+imod)->ndac=myMod->ndac; + (detectorModules+imod)->nadc=myMod->nadc; + thisDetector->nChips=myMod->nchip; + thisDetector->nChans=myMod->nchan/myMod->nchip; + thisDetector->nDacs=myMod->ndac; + thisDetector->nAdcs=myMod->nadc; + + for (int ichip=0; ichipnChips; ichip++) { + if (chipregs) + chipregs[ichip+thisDetector->nChips*imod]=myMod->chipregs[ichip]; + + if (chanregs) { + for (int i=0; inChans; i++) { + chanregs[i+ichip*thisDetector->nChans+thisDetector->nChips*thisDetector->nChans*imod]=myMod->chanregs[ichip*thisDetector->nChans+i]; + } + } + } + if (dacs) { + for (int i=0; inDacs; i++) + dacs[i+imod*thisDetector->nDacs]=myMod->dacs[i]; + } + if (adcs) { + for (int i=0; inAdcs; i++) + adcs[i+imod*thisDetector->nAdcs]=myMod->adcs[i]; + } + + (detectorModules+imod)->gain=myMod->gain; + (detectorModules+imod)->offset=myMod->offset; + (detectorModules+imod)->serialnumber=myMod->serialnumber; + (detectorModules+imod)->reg=myMod->reg; + } + } + } else { + deleteModule(myMod); + myMod=NULL; + } + + return myMod; +} + + + + + // calibration functions +/* + really needed? + +int multiSlsDetector::setCalibration(int imod, detectorSettings isettings, float gain, float offset){ + std::cout<< "function not yet implemented " << std::endl; + + + + return OK; + +} +int multiSlsDetector::getCalibration(int imod, detectorSettings isettings, float &gain, float &offset){ + + std::cout<< "function not yet implemented " << std::endl; + + + +} +*/ + + /* + calibrated setup of the threshold + */ + +int multiSlsDetector::getThresholdEnergy(int imod){ + + int fnum= F_GET_THRESHOLD_ENERGY; + int retval; + int ret=FAIL; + char mess[100]; +#ifdef VERBOSE + std::cout<< "Getting threshold energy "<< std::endl; +#endif + + if (thisDetector->onlineFlag==ONLINE_FLAG) { + if (controlSocket) { + if (controlSocket->Connect()>=0) { + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + controlSocket->SendDataOnly(&imod,sizeof(imod)); + controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret!=OK) { + std::cout<< "Detector returned error: "<< std::endl; + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< mess << std::endl; + } else { + controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); + thisDetector->currentThresholdEV=retval; + } + controlSocket->Disconnect(); + } + } + } + return thisDetector->currentThresholdEV; +}; + +int multiSlsDetector::setThresholdEnergy(int e_eV, int imod, detectorSettings isettings){ + + int fnum= F_SET_THRESHOLD_ENERGY; + int retval; + int ret=FAIL; + char mess[100]; +#ifdef VERBOSE + std::cout<< "Getting threshold energy "<< std::endl; +#endif + if (thisDetector->onlineFlag==ONLINE_FLAG) { + if (controlSocket) { + if (controlSocket->Connect()>=0) { + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + controlSocket->SendDataOnly(&e_eV,sizeof(e_eV)); + controlSocket->SendDataOnly(&imod,sizeof(imod)); + controlSocket->SendDataOnly(&isettings,sizeof(isettings)); + controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret!=OK) { + std::cout<< "Detector returned error: "<< std::endl; + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< mess << std::endl; + } else { +#ifdef VERBOSE + std::cout<< "Detector returned OK "<< std::endl; +#endif + controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); + thisDetector->currentThresholdEV=retval; + } + controlSocket->Disconnect(); + } + } + } else { + thisDetector->currentThresholdEV=e_eV; + } + return thisDetector->currentThresholdEV; +}; + + /* + select detector settings + */ + detectorSettings multiSlsDetector::getSettings(int imod){ + + + int fnum=F_SET_SETTINGS; + int ret=FAIL; + char mess[100]; + int retval; + int arg[2]; + arg[0]=GET_SETTINGS; + arg[1]=imod; +#ifdef VERBOSE + std::cout<< "Getting settings "<< std::endl; +#endif + if (thisDetector->onlineFlag==ONLINE_FLAG) { + if (controlSocket) { + if (controlSocket->Connect()>=0) { + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + controlSocket->SendDataOnly(arg,sizeof(arg)); + controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret!=OK) { + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + } else{ + controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); + thisDetector->currentSettings=(detectorSettings)retval; +#ifdef VERBOSE + std::cout<< "Settings are "<< retval << std::endl; +#endif + } + controlSocket->Disconnect(); + } + } + } + return thisDetector->currentSettings; + +}; + + detectorSettings multiSlsDetector::setSettings( detectorSettings isettings, int imod){ +#ifdef VERBOSE + std::cout<< "slsDetector setSettings "<< std::endl; +#endif + sls_detector_module *myMod=createModule(); + int modmi=imod, modma=imod+1, im=imod; + string trimfname, calfname; + string ssettings; + + if (isettings>=STANDARD && isettings<=HIGHGAIN) { + switch (isettings) { + case STANDARD: + ssettings="/standard"; + thisDetector->currentSettings=STANDARD; + break; + case FAST: + ssettings="/fast"; + thisDetector->currentSettings=FAST; + break; + case HIGHGAIN: + ssettings="/highgain"; + thisDetector->currentSettings=HIGHGAIN; + break; + default: + std::cout<< "Unknown settings!" << std::endl; + } + + if (imod<0) { + modmi=0; + // modma=thisDetector->nModMax[X]*thisDetector->nModMax[Y]; + modma=thisDetector->nMod[X]*thisDetector->nMod[Y]; + } + + for (im=modmi; immodule=im; + //create file names + ostfn << thisDetector->trimDir << ssettings <<"/noise.sn" << setfill('0') << setw(3) << hex << getId(MODULE_SERIAL_NUMBER, im) << setbase(10); + oscfn << thisDetector->calDir << ssettings << "/calibration.sn" << setfill('0') << setw(3) << hex << getId(MODULE_SERIAL_NUMBER, im) << setbase(10); + // + trimfname=ostfn.str(); +#ifdef VERBOSE + cout << trimfname << endl; +#endif + if (readTrimFile(trimfname,myMod)) { + calfname=oscfn.str(); +#ifdef VERBOSE + cout << calfname << endl; +#endif + readCalibrationFile(calfname,myMod->gain, myMod->offset); + setModule(*myMod); + } else { + ostringstream ostfn,oscfn; + ostfn << thisDetector->trimDir << ssettings << ssettings << ".trim"; + oscfn << thisDetector->calDir << ssettings << ssettings << ".cal"; + calfname=oscfn.str(); + trimfname=ostfn.str(); +#ifdef VERBOSE + cout << trimfname << endl; + cout << calfname << endl; +#endif + if (readTrimFile(trimfname,myMod)) { + calfname=oscfn.str(); + readCalibrationFile(calfname,myMod->gain, myMod->offset); + setModule(*myMod); + } + } + } + } + deleteModule(myMod); + if (thisDetector->correctionMask&(1<-1 && isett<3) { + thisDetector->tDead=t[isett]; + } + } + + + return getSettings(imod); +}; + +// Acquisition functions +/* change these funcs accepting also ok/fail */ + +int multiSlsDetector::startAcquisition(){ + + + int fnum=F_START_ACQUISITION; + int ret=FAIL; + char mess[100]; + +#ifdef VERBOSE + std::cout<< "Starting acquisition "<< std::endl; +#endif + thisDetector->stoppedFlag=0; + if (thisDetector->onlineFlag==ONLINE_FLAG) { + if (controlSocket) { + if (controlSocket->Connect()>=0) { + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret!=OK) { + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + } + controlSocket->Disconnect(); + } + } + } + return ret; + + + +}; +int multiSlsDetector::stopAcquisition(){ + + + int fnum=F_STOP_ACQUISITION; + int ret=FAIL; + char mess[100]; + +#ifdef VERBOSE + std::cout<< "Stopping acquisition "<< std::endl; +#endif + if (thisDetector->onlineFlag==ONLINE_FLAG) { + if (stopSocket) { + if (stopSocket->Connect()>=0) { + stopSocket->SendDataOnly(&fnum,sizeof(fnum)); + stopSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret!=OK) { + stopSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + } + stopSocket->Disconnect(); + } + } + } + thisDetector->stoppedFlag=1; + return ret; + + +}; + +int multiSlsDetector::startReadOut(){ + + int fnum=F_START_READOUT; + int ret=FAIL; + char mess[100]; + +#ifdef VERBOSE + std::cout<< "Starting readout "<< std::endl; +#endif + if (thisDetector->onlineFlag==ONLINE_FLAG) { + if (controlSocket) { + if (controlSocket->Connect()>=0) { + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret!=OK) { + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + } + controlSocket->Disconnect(); + } + } + } + return ret; +}; + + + +/*int multiSlsDetector::getRunStatus(){ + int fnum=F_GET_RUN_STATUS; + int retval; + int ret=FAIL; + char mess[100]; +#ifdef VERBOSE + std::cout<< "Getting status "<< std::endl; +#endif + if (thisDetector->onlineFlag==ONLINE_FLAG) { + if (controlSocket) { + if (controlSocket->Connect()>=0) { + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret!=OK) { + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + } else + controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); + controlSocket->Disconnect(); + } + } + } + return retval; + + +}; +*/ + +int* multiSlsDetector::readFrame(){ + + int fnum=F_READ_FRAME; + int* retval=NULL; + +#ifdef VERBOSE + std::cout<< "slsDetector: Reading frame "<< std::endl; +#endif + if (thisDetector->onlineFlag==ONLINE_FLAG) { + if (controlSocket) { + if (controlSocket->Connect()>=0) { + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + retval=getDataFromDetector(); + if (retval) { + dataQueue.push(retval); + controlSocket->Disconnect(); + } + } + } + } + return retval; +}; + +int* multiSlsDetector::getDataFromDetector(){ + + int nel=thisDetector->dataBytes/sizeof(int); + int n; + int* retval=new int[nel]; + int ret=FAIL; + char mess[100]="Nothing"; +#ifdef VERY_VERBOSE + int i; +#endif + +#ifdef VERBOSE + // std::cout<< "getting data "<< std::endl; +#endif + controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret!=OK) { + n= controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + if (ret==FAIL) { + thisDetector->stoppedFlag=1; + std::cout<< "Detector returned: " << mess << " " << n << std::endl; + } else { + ; +#ifdef VERBOSE + std::cout<< "Detector successfully returned: " << mess << " " << n << std::endl; +#endif + } + delete [] retval; + retval=NULL; + } else { + n=controlSocket->ReceiveDataOnly(retval,thisDetector->dataBytes); + + //#ifdef VERBOSE + std::cout<< "Received "<< n << " data bytes" << std::endl; + //#endif + if (n!=thisDetector->dataBytes) { + std::cout<< "wrong data size received: received " << n << " but expected " << thisDetector->dataBytes << std::endl; + thisDetector->stoppedFlag=1; + ret=FAIL; + delete [] retval; + retval=NULL; + } + } + + return retval; +}; + + + +int* multiSlsDetector::readAll(){ + + int fnum=F_READ_ALL; + int* retval; // check what we return! + + int i=0; +#ifdef VERBOSE + std::cout<< "Reading all frames "<< std::endl; +#endif + if (thisDetector->onlineFlag==ONLINE_FLAG) { + if (controlSocket) { + if (controlSocket->Connect()>=0) { + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + while ((retval=getDataFromDetector())){ + i++; +#ifdef VERBOSE + // std::cout<< i << std::endl; +#endif + dataQueue.push(retval); + } + controlSocket->Disconnect(); + } + } + } +#ifdef VERBOSE + std::cout<< "received "<< i<< " frames" << std::endl; +#endif + return dataQueue.front(); // check what we return! + +}; + +int* multiSlsDetector::startAndReadAll(){ + + + int* retval; + int i=0; + startAndReadAllNoWait(); + while ((retval=getDataFromDetector())){ + i++; + //#ifdef VERBOSE + std::cout<< i << std::endl; + //#endif + dataQueue.push(retval); + } + controlSocket->Disconnect(); + + //#ifdef VERBOSE + std::cout<< "recieved "<< i<< " frames" << std::endl; + //#endif + return dataQueue.front(); // check what we return! +/* while ((retval=getDataFromDetectorNoWait())) + i++; + #ifdef VERBOSE + std::cout<< "Received " << i << " frames"<< std::endl; +#endif + return dataQueue.front(); // check what we return! + */ + +}; + + + +int multiSlsDetector::startAndReadAllNoWait(){ + + int fnum= F_START_AND_READ_ALL; + +#ifdef VERBOSE + std::cout<< "Starting and reading all frames "<< std::endl; +#endif + thisDetector->stoppedFlag=0; + if (thisDetector->onlineFlag==ONLINE_FLAG) { + if (controlSocket) { + if (controlSocket->Connect()>=0) { + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + return OK; + } + } + } + return FAIL; +}; + +int* multiSlsDetector::getDataFromDetectorNoWait() { + int *retval=getDataFromDetector(); + if (thisDetector->onlineFlag==ONLINE_FLAG) { + if (controlSocket) { + if (retval==NULL){ + controlSocket->Disconnect(); + +#ifdef VERBOSE + std::cout<< "Run finished "<< std::endl; +#endif + } else { +#ifdef VERBOSE + std::cout<< "Frame received "<< std::endl; +#endif + } + } + } + return retval; // check what we return! +}; + + + + + +int* multiSlsDetector::popDataQueue() { + int *retval=NULL; + if( !dataQueue.empty() ) { + retval=dataQueue.front(); + dataQueue.pop(); + } + return retval; +} + +detectorData* multiSlsDetector::popFinalDataQueue() { + detectorData *retval=NULL; + if( !finalDataQueue.empty() ) { + retval=finalDataQueue.front(); + finalDataQueue.pop(); + } + return retval; +} + +void multiSlsDetector::resetDataQueue() { + int *retval=NULL; + while( !dataQueue.empty() ) { + retval=dataQueue.front(); + dataQueue.pop(); + delete [] retval; + } + +} + +void multiSlsDetector::resetFinalDataQueue() { + detectorData *retval=NULL; + while( !finalDataQueue.empty() ) { + retval=finalDataQueue.front(); + finalDataQueue.pop(); + delete retval; + } + +} + + /* + set or read the acquisition timers + enum timerIndex { + FRAME_NUMBER, + ACQUISITION_TIME, + FRAME_PERIOD, + DELAY_AFTER_TRIGGER, + GATES_NUMBER, + PROBES_NUMBER + CYCLES_NUMBER, + GATE_INTEGRATED_TIME + } + */ +int64_t multiSlsDetector::setTimer(timerIndex index, int64_t t){ + + + int fnum=F_SET_TIMER; + int64_t retval; + uint64_t ut; + char mess[100]; + int ret=OK; + int n=0; + + + +#ifdef VERBOSE + std::cout<< "Setting timer "<< index << " to " << t << "ns" << std::endl; +#endif + ut=t; + if (thisDetector->onlineFlag==ONLINE_FLAG) { + if (controlSocket) { + if (controlSocket->Connect()>=0) { + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + controlSocket->SendDataOnly(&index,sizeof(index)); + n=controlSocket->SendDataOnly(&t,sizeof(t)); + controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret!=OK) { + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + } else { + controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); + thisDetector->timerValue[index]=retval; + } + controlSocket->Disconnect(); + } + } + } else { + //std::cout<< "offline " << std::endl; + if (t>=0) + thisDetector->timerValue[index]=t; + +} +#ifdef VERBOSE + std::cout<< "Timer " << index << " set to "<< thisDetector->timerValue[index] << "ns" << std::endl; +#endif + if (index==PROBES_NUMBER) { + setDynamicRange(); + //cout << "Changing probes: data size = " << thisDetector->dataBytes <timerValue[index]; + +}; + + + + + + +int multiSlsDetector::setTotalProgress() { + + int nf=1, npos=1, nscan[MAX_SCAN_LEVELS]={1,1}, nc=1; + + if (thisDetector->timerValue[FRAME_NUMBER]) + nf=thisDetector->timerValue[FRAME_NUMBER]; + + if (thisDetector->timerValue[CYCLES_NUMBER]>0) + nc=thisDetector->timerValue[CYCLES_NUMBER]; + + if (thisDetector->numberOfPositions>0) + npos=thisDetector->numberOfPositions; + + if ((thisDetector->nScanSteps[0]>0) && (thisDetector->actionMask & (1 << MAX_ACTIONS))) + nscan[0]=thisDetector->nScanSteps[0]; + + if ((thisDetector->nScanSteps[1]>0) && (thisDetector->actionMask & (1 << (MAX_ACTIONS+1)))) + nscan[1]=thisDetector->nScanSteps[1]; + + thisDetector->totalProgress=nf*nc*npos*nscan[0]*nscan[1]; + +#ifdef VERBOSE + cout << "nc " << nc << endl; + cout << "nf " << nf << endl; + cout << "npos " << npos << endl; + cout << "nscan[0] " << nscan[0] << endl; + cout << "nscan[1] " << nscan[1] << endl; + + cout << "Set total progress " << thisDetector->totalProgress << endl; +#endif + return thisDetector->totalProgress; +} + + +float multiSlsDetector::getCurrentProgress() { + + return 100.*((float)thisDetector->progressIndex)/((float)thisDetector->totalProgress); +} + + + + + + + + + + + + + + + +/* + important speed parameters + +enum speedVariable { + CLOCK_DIVIDER, + WAIT_STATES, + SET_SIGNAL_LENGTH +}; +*/ + +int multiSlsDetector::setSpeed(speedVariable sp, int value) { + + + int fnum=F_SET_SPEED; + int retval=-1; + char mess[100]; + int ret=OK; + int n=0; +#ifdef VERBOSE + std::cout<< "Setting speed variable"<< sp << " to " << value << std::endl; +#endif + if (thisDetector->onlineFlag==ONLINE_FLAG) { + if (controlSocket) { + if (controlSocket->Connect()>=0) { + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + controlSocket->SendDataOnly(&sp,sizeof(sp)); + n=controlSocket->SendDataOnly(&value,sizeof(value)); +#ifdef VERBOSE + std::cout<< "Sent "<< n << " bytes " << std::endl; +#endif + controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret!=OK) { + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + } else { + controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); + } + controlSocket->Disconnect(); + } + } + } +#ifdef VERBOSE + std::cout<< "Speed set to "<< retval << std::endl; +#endif + return retval; + +} + + + + + + + + + + + + + + + + +int64_t multiSlsDetector::getTimeLeft(timerIndex index){ + + + int fnum=F_GET_TIME_LEFT; + int64_t retval; + char mess[100]; + int ret=OK; + +#ifdef VERBOSE + std::cout<< "Getting timer "<< index << std::endl; +#endif + if (thisDetector->onlineFlag==ONLINE_FLAG) { +// if (controlSocket) { +// if (controlSocket->Connect()>=0) { +// controlSocket->SendDataOnly(&fnum,sizeof(fnum)); +// controlSocket->SendDataOnly(&index,sizeof(index)); +// controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); +// if (ret!=OK) { +// controlSocket->ReceiveDataOnly(mess,sizeof(mess)); +// std::cout<< "Detector returned error: " << mess << std::endl; +// } else { +// controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); +// // thisDetector->timerValue[index]=retval; +// } +// controlSocket->Disconnect(); +// } +// } + if (stopSocket) { + if (stopSocket->Connect()>=0) { + stopSocket->SendDataOnly(&fnum,sizeof(fnum)); + stopSocket->SendDataOnly(&index,sizeof(index)); + stopSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret!=OK) { + stopSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + } else { + stopSocket->ReceiveDataOnly(&retval,sizeof(retval)); + // thisDetector->timerValue[index]=retval; + } + stopSocket->Disconnect(); + } + } + } +#ifdef VERBOSE + std::cout<< "Time left is "<< retval << std::endl; +#endif + return retval; + +}; + + + // Flags +int multiSlsDetector::setDynamicRange(int n){ + + int fnum=F_SET_DYNAMIC_RANGE; + int retval=-1; + char mess[100]; + int ret=OK; + +#ifdef VERBOSE + std::cout<< "Setting dynamic range to "<< n << std::endl; +#endif + if (n==24) + n=32; + if (thisDetector->onlineFlag==ONLINE_FLAG) { + if (controlSocket) { + if (controlSocket->Connect()>=0) { + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + controlSocket->SendDataOnly(&n,sizeof(n)); + controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret!=OK) { + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + } else { + controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); + } + controlSocket->Disconnect(); + } + } + } else { + if (n>0) + thisDetector->dynamicRange=n; + retval=thisDetector->dynamicRange; + } + + if (ret==OK && retval>0) { + /* checking the number of probes to chose the data size */ + if (thisDetector->timerValue[PROBES_NUMBER]==0) { + thisDetector->dataBytes=thisDetector->nMod[X]*thisDetector->nMod[Y]*thisDetector->nChips*thisDetector->nChans*retval/8; + } else { + thisDetector->dataBytes=thisDetector->nMod[X]*thisDetector->nMod[Y]*thisDetector->nChips*thisDetector->nChans*4; + } + + if (retval==32) + thisDetector->dynamicRange=24; + else + thisDetector->dynamicRange=retval; + + +#ifdef VERBOSE + std::cout<< "Dynamic range set to "<< thisDetector->dynamicRange << std::endl; + std::cout<< "Data bytes "<< thisDetector->dataBytes << std::endl; +#endif + + } + return thisDetector->dynamicRange; +}; + +/* + +int multiSlsDetector::setROI(int nroi, int *xmin, int *xmax, int *ymin, int *ymax){ + + +}; +*/ + + /* + +enum readOutFlags { + NORMAL_READOUT, + setReadOutFlags(STORE_IN_RAM, + READ_HITS, + ZERO_COMPRESSION, + BACKGROUND_CORRECTION +}{}; + + */ + +int multiSlsDetector::setReadOutFlags(readOutFlags flag){ + + + int fnum=F_SET_READOUT_FLAGS; + readOutFlags retval; + char mess[100]; + int ret=OK; + +#ifdef VERBOSE + std::cout<< "Setting readout flags to "<< flag << std::endl; +#endif + + if (thisDetector->onlineFlag==ONLINE_FLAG) { + if (controlSocket) { + if (controlSocket->Connect()>=0) { + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + controlSocket->SendDataOnly(&flag,sizeof(flag)); + controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret!=OK) { + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + } else { + controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); + thisDetector->roFlags=retval; + } + controlSocket->Disconnect(); + } + } + } else { + if (flag!=GET_READOUT_FLAGS) + thisDetector->roFlags=flag; + } + +#ifdef VERBOSE + std::cout<< "Readout flag set to "<< retval << std::endl; +#endif + return thisDetector->roFlags; +}; + + //Trimming + /* +enum trimMode { + NOISE_TRIMMING, + BEAM_TRIMMING, + IMPROVE_TRIMMING, + FIXEDSETTINGS_TRIMMING, + OFFLINE_TRIMMING +}{}; + */ +int multiSlsDetector::executeTrimming(trimMode mode, int par1, int par2, int imod){ + + int fnum= F_EXECUTE_TRIMMING; + int retval=FAIL; + char mess[100]; + int ret=OK; + int arg[3]; + arg[0]=imod; + arg[1]=par1; + arg[2]=par2; + + +#ifdef VERBOSE + std::cout<< "Trimming module " << imod << " with mode "<< mode << " parameters " << par1 << " " << par2 << std::endl; +#endif + + if (thisDetector->onlineFlag==ONLINE_FLAG) { + if (controlSocket) { + if (controlSocket->Connect()>=0) { + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + std::cout<< "sending mode bytes= "<< controlSocket->SendDataOnly(&mode,sizeof(mode)) << std::endl; + controlSocket->SendDataOnly(arg,sizeof(arg)); + controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret!=OK) { + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + } else { +#ifdef VERBOSE + std::cout<< "Detector trimmed "<< ret << std::endl; +#endif + /* + controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); + thisDetector->roFlags=retval; + */ + retval=ret; + } + controlSocket->Disconnect(); + } + } + } + return retval; + +}; + +float* multiSlsDetector::decodeData(int *datain) { + float *dataout=new float[thisDetector->nChans*thisDetector->nChips*thisDetector->nMods]; + const int bytesize=8; + + int ival=0; + char *ptr=(char*)datain; + char iptr; + + int nbits=thisDetector->dynamicRange; + int ipos=0, ichan=0, ibyte; + if (thisDetector->timerValue[PROBES_NUMBER]==0) { + switch (nbits) { + case 1: + for (ibyte=0; ibytedataBytes; ibyte++) { + iptr=ptr[ibyte]&0x1; + for (ipos=0; ipos<8; ipos++) { + // dataout[ibyte*2+ichan]=((iptr&((0xf)<>ichan)&0xf; + ival=(iptr>>(ipos))&0x1; + dataout[ichan]=ival; + ichan++; + } + } + break; + case 4: + for (ibyte=0; ibytedataBytes; ibyte++) { + iptr=ptr[ibyte]&0xff; + for (ipos=0; ipos<2; ipos++) { + // dataout[ibyte*2+ichan]=((iptr&((0xf)<>ichan)&0xf; + ival=(iptr>>(ipos*4))&0xf; + dataout[ichan]=ival; + ichan++; + } + } + break; + case 8: + for (ichan=0; ichandataBytes; ichan++) { + ival=ptr[ichan]&0xff; + dataout[ichan]=ival; + } + break; + case 16: + for (ichan=0; ichannChans*thisDetector->nChips*thisDetector->nMods; ichan++) { + // dataout[ichan]=0; + ival=0; + for (ibyte=0; ibyte<2; ibyte++) { + iptr=ptr[ichan*2+ibyte]; + ival|=((iptr<<(ibyte*bytesize))&(0xff<<(ibyte*bytesize))); + } + dataout[ichan]=ival; + } + break; + default: + for (ichan=0; ichannChans*thisDetector->nChips*thisDetector->nMods; ichan++) { + ival=datain[ichan]&0xffffff; + dataout[ichan]=ival; + } + } + } else { + for (ichan=0; ichannChans*thisDetector->nChips*thisDetector->nMods; ichan++) { + dataout[ichan]=datain[ichan]; + } + } + + /* + + if (nbits==32) { + for (ichan=0; ichannChans*thisDetector->nChips*thisDetector->nMods; ichan++) + dataout[ichan]=(datain[ichan]&0xffffff); + } else { + for (int ibyte=0; ibytedataBytes; ibyte++) { + for (int ibit=0; ibit>ibit)<dynamicRange) { + ipos=0; + dataout[ichan]=ival; + ichan++; + ival=0; + if (ichan>thisDetector->nChans*thisDetector->nChips*thisDetector->nMods){ + std::cout<< "error: decoding too many channels!" << ichan; + break; + } + } + } + } + } + */ +#ifdef VERBOSE + std::cout<< "decoded "<< ichan << " channels" << std::endl; +#endif + + + return dataout; +} + +//Correction + /* + enum correctionFlags { + DISCARD_BAD_CHANNELS, + AVERAGE_NEIGHBOURS_FOR_BAD_CHANNELS, + FLAT_FIELD_CORRECTION, + RATE_CORRECTION, + ANGULAR_CONVERSION + } + */ + +int multiSlsDetector::setFlatFieldCorrection(string fname){ + float data[thisDetector->nModMax[X]*thisDetector->nModMax[Y]*thisDetector->nChans*thisDetector->nChips]; + //float err[thisDetector->nModMax[X]*thisDetector->nModMax[Y]*thisDetector->nChans*thisDetector->nChips]; + float xmed[thisDetector->nModMax[X]*thisDetector->nModMax[Y]*thisDetector->nChans*thisDetector->nChips]; + int nmed=0; + int im=0; + int nch; + thisDetector->nBadFF=0; + + char ffffname[MAX_STR_LENGTH*2]; + + if (fname=="") { +#ifdef VERBOSE + std::cout<< "disabling flat field correction" << std::endl; +#endif + thisDetector->correctionMask&=~(1<flatFieldFile,"none"); + } else { +#ifdef VERBOSE + std::cout<< "Setting flat field correction from file " << fname << std::endl; +#endif + sprintf(ffffname,"%s/%s",thisDetector->flatFieldDir,fname.c_str()); + nch=readDataFile(string(ffffname),data); + if (nch>0) { + strcpy(thisDetector->flatFieldFile,fname.c_str()); + for (int ichan=0; ichan0) { + /* add to median */ + im=0; + while ((imim; i--) + xmed[i]=xmed[i-1]; + xmed[im]=data[ichan]; + nmed++; + } else { + //add the channel to the ff bad channel list + if (thisDetector->nBadFFbadFFList[thisDetector->nBadFF]=ichan; + (thisDetector->nBadFF)++; +#ifdef VERBOSE + std::cout<< "Channel " << ichan << " added to the bad channel list" << std::endl; +#endif + } else + std::cout<< "Too many bad channels " << std::endl; + + } + } + + if (nmed>1 && xmed[nmed/2]>0) { +#ifdef VERBOSE + std::cout<< "Flat field median is " << xmed[nmed/2] << " calculated using "<< nmed << " points" << std::endl; +#endif + + thisDetector->correctionMask|=(1<0) { + ffcoefficients[ichan]=xmed[nmed/2]/data[ichan]; + fferrors[ichan]=ffcoefficients[ichan]*sqrt(data[ichan])/data[ichan]; + } else { + ffcoefficients[ichan]=0.; + fferrors[ichan]=1.; + } + } + for (int ichan=nch; ichannMod[X]*thisDetector->nMod[Y]*thisDetector->nChans*thisDetector->nChips; ichan++) { + ffcoefficients[ichan]=1.; + fferrors[ichan]=0.; + } + + fillBadChannelMask(); + + } else { + std::cout<< "Flat field data from file " << fname << " are not valid (" << nmed << "///" << xmed[nmed/2] << std::endl; + return -1; + } + } else { + std::cout<< "Flat field from file " << fname << " is not valid " << nch << std::endl; + return -1; + } + } + return thisDetector->correctionMask&(1<correctionMask&(1<nMod[X]*thisDetector->nMod[Y]*thisDetector->nChans*thisDetector->nChips; ichan++) { + corr[ichan]=(ffcoefficients[ichan]*ffcoefficients[ichan])/(fferrors[ichan]*fferrors[ichan]); + if (ecorr) { + ecorr[ichan]=ffcoefficients[ichan]/fferrors[ichan]; + } + } + } + return 1; + } else { +#ifdef VERBOSE + std::cout<< "Flat field correction is disabled" << std::endl; +#endif + if (corr) + for (int ichan=0; ichannMod[X]*thisDetector->nMod[Y]*thisDetector->nChans*thisDetector->nChips; ichan++) { + corr[ichan]=1; + if (ecorr) + ecorr[ichan]=0; + } + return 0; + } + +} + + +int multiSlsDetector::flatFieldCorrect(float datain, float errin, float &dataout, float &errout, float ffcoefficient, float fferr){ + float e; + + dataout=datain*ffcoefficient; + + if (errin==0 && datain>=0) + e=sqrt(datain); + else + e=errin; + + if (dataout>0) + errout=sqrt(e*ffcoefficient*e*ffcoefficient+datain*fferr*datain*fferr); + else + errout=1.; + + return 0; +}; + +int multiSlsDetector::flatFieldCorrect(float* datain, float *errin, float* dataout, float *errout){ +#ifdef VERBOSE + std::cout<< "Flat field correcting data" << std::endl; +#endif + float e, eo; + if (thisDetector->correctionMask&(1<nMod[X]*thisDetector->nMod[Y]*thisDetector->nChans*thisDetector->nChips; ichan++) { + if (errin==NULL) + e=0; + else + e=errin[ichan]; + + flatFieldCorrect(datain[ichan],e,dataout[ichan],eo,ffcoefficients[ichan],fferrors[ichan]); + if (errout) + errout[ichan]=eo; + } + } + return 0; + +}; + +int multiSlsDetector::setRateCorrection(float t){ + float tdead[]=defaultTDead; + + if (t==0) { +#ifdef VERBOSE + std::cout<< "unsetting rate correction" << std::endl; +#endif + thisDetector->correctionMask&=~(1<correctionMask|=(1<0) + thisDetector->tDead=t; + else { + if (thisDetector->currentSettings<3 && thisDetector->currentSettings>-1) + thisDetector->tDead=tdead[thisDetector->currentSettings]; + else + thisDetector->tDead=0; + } +#ifdef VERBOSE + std::cout<< "Setting rate correction with dead time "<< thisDetector->tDead << std::endl; +#endif + } + return thisDetector->correctionMask&(1<correctionMask&(1<tDead << std::endl; +#endif + t=thisDetector->tDead; + return 1; + } else + t=0; +#ifdef VERBOSE + std::cout<< "Rate correction is disabled " << std::endl; +#endif + return 0; +}; + +float multiSlsDetector::getRateCorrectionTau(){ + + if (thisDetector->correctionMask&(1<tDead << std::endl; +#endif + return thisDetector->tDead; + //return 1; + } else +#ifdef VERBOSE + std::cout<< "Rate correction is disabled " << std::endl; +#endif + return 0; +}; + + + + + + + +int multiSlsDetector::getRateCorrection(){ + + if (thisDetector->correctionMask&(1<=0) + e=sqrt(datain); + else + e=errin; + + if (dataout>0) + errout=e*dataout*sqrt((1/(datain*datain)+tau*tau/(t*t))); + else + errout=1.; + return 0; + +}; + + +int multiSlsDetector::rateCorrect(float* datain, float *errin, float* dataout, float *errout){ + float tau=thisDetector->tDead; + float t=thisDetector->timerValue[ACQUISITION_TIME]; + // float data; + float e; + if (thisDetector->correctionMask&(1<nMod[X]*thisDetector->nMod[Y]*thisDetector->nChans*thisDetector->nChips; ichan++) { + + if (errin==NULL) { + e=sqrt(datain[ichan]); + } else + e=errin[ichan]; + + rateCorrect(datain[ichan], e, dataout[ichan], errout[ichan], tau, t); + } + } + + return 0; +}; + + +int multiSlsDetector::setBadChannelCorrection(string fname){ + ifstream infile; + string str; + int interrupt=0; + int ich; + int chmin,chmax; +#ifdef VERBOSE + std::cout << "Setting bad channel correction to " << fname << std::endl; +#endif + + if (fname=="") { + thisDetector->correctionMask&=~(1<< DISCARD_BAD_CHANNELS); + thisDetector->nBadChans=0; + } else { + if (fname=="default") + fname=string(thisDetector->badChanFile); + infile.open(fname.c_str(), ios_base::in); + if (infile.is_open()==0) { + std::cout << "could not open file " << fname <nBadChans=0; + while (infile.good() and interrupt==0) { + getline(infile,str); +#ifdef VERBOSE + std::cout << str << std::endl; +#endif + istringstream ssstr; + ssstr.str(str); + if (!ssstr.good() || infile.eof()) { + interrupt=1; + break; + } + if (str.find('-')!=string::npos) { + ssstr >> chmin ; + ssstr.str(str.substr(str.find('-')+1,str.size())); + ssstr >> chmax; +#ifdef VERBOSE + std::cout << "channels between"<< chmin << " and " << chmax << std::endl; +#endif + for (ich=chmin; ich<=chmax; ich++) { + if (thisDetector->nBadChansbadChansList[thisDetector->nBadChans]=ich; + thisDetector->nBadChans++; +#ifdef VERBOSE + std::cout<< thisDetector->nBadChans << " Found bad channel "<< ich << std::endl; +#endif + } else + interrupt=1; + } + } else { + ssstr >> ich; +#ifdef VERBOSE + std::cout << "channel "<< ich << std::endl; +#endif + if (thisDetector->nBadChansbadChansList[thisDetector->nBadChans]=ich; + thisDetector->nBadChans++; +#ifdef VERBOSE + std::cout << thisDetector->nBadChans << " Found bad channel "<< ich << std::endl; +#endif + } else + interrupt=1; + } + + + } + if (thisDetector->nBadChans>0 && thisDetector->nBadChanscorrectionMask|=(1<< DISCARD_BAD_CHANNELS); + strcpy(thisDetector->badChanFile,fname.c_str()); + } + } + infile.close(); +#ifdef VERBOSE + std::cout << "found " << thisDetector->nBadChans << " badchannels "<< std::endl; +#endif + fillBadChannelMask(); +#ifdef VERBOSE + std::cout << " badchannels mask filled"<< std::endl; +#endif + return thisDetector->nBadChans; +} + +int multiSlsDetector::getBadChannelCorrection(int *bad) { + int ichan; + if (thisDetector->correctionMask&(1<< DISCARD_BAD_CHANNELS)) { + if (bad) { + for (ichan=0; ichannBadChans; ichan++) + bad[ichan]=thisDetector->badChansList[ichan]; + for (int ich=0; ichnBadFF; ich++) + bad[ichan+ich]=thisDetector->badFFList[ich]; + } + return thisDetector->nBadChans+thisDetector->nBadFF; + } else + return 0; +} + + +int multiSlsDetector::fillBadChannelMask() { + + if (thisDetector->correctionMask&(1<< DISCARD_BAD_CHANNELS)) { + if (badChannelMask) + delete [] badChannelMask; + badChannelMask=new int[thisDetector->nChans*thisDetector->nChips*thisDetector->nMods]; + for (int ichan=0; ichannChans*thisDetector->nChips*thisDetector->nMods; ichan++) + badChannelMask[ichan]=0; + for (int ichan=0; ichannBadChans; ichan++) { + if (thisDetector->badChansList[ichan]nChans*thisDetector->nChips*thisDetector->nMods) { + badChannelMask[thisDetector->badChansList[ichan]]=1; +#ifdef VERBOSE + std::cout << ichan << " badchannel "<< ichan << std::endl; +#endif + } + } + for (int ichan=0; ichannBadFF; ichan++) { + if (thisDetector->badFFList[ichan]nChans*thisDetector->nChips*thisDetector->nMods) { + badChannelMask[thisDetector->badFFList[ichan]]=1; +#ifdef VERBOSE + std::cout << ichan << "ff badchannel "<< thisDetector->badFFList[ichan] << std::endl; +#endif + } + } + + } else { + if (badChannelMask) { + delete [] badChannelMask; + badChannelMask=NULL; + } + } + return thisDetector->nBadFF; + +} + +int multiSlsDetector::exitServer(){ + + int retval; + int fnum=F_EXIT_SERVER; + + + if (thisDetector->onlineFlag==ONLINE_FLAG) { + if (controlSocket) { + controlSocket->Connect(); + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); + controlSocket->Disconnect(); + } + } + if (retval==OK) { + std::cout<< std::endl; + std::cout<< "Shutting down the server" << std::endl; + std::cout<< std::endl; + } + return retval; +}; + + + + + + + + + + + /** + set action + \param iaction can be enum {startScript, scriptBefore, headerBefore, headerAfter,scriptAfter, stopScript, MAX_ACTIONS} + \param fname for script ("" disable but leaves script unchanged, "none" disables and overwrites) + \returns 0 if action disabled, >0 otherwise + */ +int multiSlsDetector::setAction(int iaction, string fname, string par) { + + if (iaction>=0 && iactionactionMode[iaction]=0; + } else if (fname=="none") { + thisDetector->actionMode[iaction]=0; + strcpy(thisDetector->actionScript[iaction],fname.c_str()); + } else { + strcpy(thisDetector->actionScript[iaction],fname.c_str()); + thisDetector->actionMode[iaction]=1; + } + + if (par!="") { + strcpy(thisDetector->actionParameter[iaction],par.c_str()); + } + + if (thisDetector->actionMode[iaction]) { + +#ifdef VERBOSE + cout << iaction << " " << hex << (1 << iaction) << " " << thisDetector->actionMask << dec; +#endif + + thisDetector->actionMask |= (1 << iaction); + +#ifdef VERBOSE + cout << " set " << hex << thisDetector->actionMask << dec << endl; +#endif + + } else { +#ifdef VERBOSE + cout << iaction << " " << hex << thisDetector->actionMask << dec; +#endif + + thisDetector->actionMask &= ~(1 << iaction); + +#ifdef VERBOSE + cout << " unset " << hex << thisDetector->actionMask << dec << endl; +#endif + } +#ifdef VERBOSE + cout << iaction << " Action mask set to " << hex << thisDetector->actionMask << dec << endl; +#endif + + return thisDetector->actionMode[iaction]; + } else + return -1; +} + + +int multiSlsDetector::setActionScript(int iaction, string fname) { +#ifdef VERBOSE + +#endif + return setAction(iaction,fname,""); +} + + + +int multiSlsDetector::setActionParameter(int iaction, string par) { + if (iaction>=0 && iactionactionParameter[iaction],par.c_str()); + } + + if (thisDetector->actionMode[iaction]) { + thisDetector->actionMask |= (1 << iaction); + } else { + thisDetector->actionMask &= ~(1 << iaction); + } + + return thisDetector->actionMode[iaction]; + } else + return -1; +} + + /** + returns action script + \param iaction can be enum {startScript, scriptBefore, headerBefore, headerAfter,scriptAfter, stopScript} + \returns action script + */ +string multiSlsDetector::getActionScript(int iaction){ + if (iaction>=0 && iactionactionScript[iaction]); + else + return string("wrong index"); +}; + + /** + returns action parameter + \param iaction can be enum {startScript, scriptBefore, headerBefore, headerAfter,scriptAfter, stopScript} + \returns action parameter + */ +string multiSlsDetector::getActionParameter(int iaction){ + if (iaction>=0 && iactionactionParameter[iaction]); + else + return string("wrong index"); +} + + /** + returns action mode + \param iaction can be enum {startScript, scriptBefore, headerBefore, headerAfter,scriptAfter, stopScript} + \returns action mode + */ +int multiSlsDetector::getActionMode(int iaction){ + if (iaction>=0 && iactionactionMode[iaction] << endl; +#endif + return thisDetector->actionMode[iaction]; + } else { +#ifdef VERBOSE + cout << "slsDetetctor : wrong action index " << iaction << endl; +#endif + return -1; + } +} + + + /** + set scan + \param index of the scan (0,1) + \param fname for script ("" disable) + \returns 0 if scan disabled, >0 otherwise + */ +int multiSlsDetector::setScan(int iscan, string script, int nvalues, float *values, string par, int precision) { + if (iscan>=0 && iscanscanMode[iscan]=0; + } else { + strcpy(thisDetector->scanScript[iscan],script.c_str()); + if (script=="none") { + thisDetector->scanMode[iscan]=0; + } else if (script=="energy") { + thisDetector->scanMode[iscan]=1; + } else if (script=="threshold") { + thisDetector->scanMode[iscan]=2; + } else if (script=="trimbits") { + thisDetector->scanMode[iscan]=3; + } else { + thisDetector->scanMode[iscan]=4; + } + } + + + + + + + if (par!="") + strcpy(thisDetector->scanParameter[iscan],par.c_str()); + + if (nvalues>=0) { + if (nvalues==0) + thisDetector->scanMode[iscan]=0; + else { + thisDetector->nScanSteps[iscan]=nvalues; + if (nvalues>MAX_SCAN_STEPS) + thisDetector->nScanSteps[iscan]=MAX_SCAN_STEPS; + } + } + + if (values && thisDetector->scanMode[iscan]>0 ) { + for (int iv=0; ivnScanSteps[iscan]; iv++) { + thisDetector->scanSteps[iscan][iv]=values[iv]; + } + } + + if (precision>=0) + thisDetector->scanPrecision[iscan]=precision; + + if (thisDetector->scanMode[iscan]>0){ + thisDetector->actionMask |= 1<< (iscan+MAX_ACTIONS); + } else { + thisDetector->actionMask &= ~(1 << (iscan+MAX_ACTIONS)); + } + + + + setTotalProgress(); + + + + + + + + + + + return thisDetector->scanMode[iscan]; + } else + return -1; + +} + +int multiSlsDetector::setScanScript(int iscan, string script) { + if (iscan>=0 && iscanscanMode[iscan]=0; + } else { + strcpy(thisDetector->scanScript[iscan],script.c_str()); + if (script=="none") { + thisDetector->scanMode[iscan]=0; + } else if (script=="energy") { + thisDetector->scanMode[iscan]=1; + } else if (script=="threshold") { + thisDetector->scanMode[iscan]=2; + } else if (script=="trimbits") { + thisDetector->scanMode[iscan]=3; + } else { + thisDetector->scanMode[iscan]=4; + } + } + + if (thisDetector->scanMode[iscan]>0){ + thisDetector->actionMask |= (1 << (iscan+MAX_ACTIONS)); + } else { + thisDetector->actionMask &= ~(1 << (iscan+MAX_ACTIONS)); + } + + setTotalProgress(); + + + + + + + + + + + + + + + + + + +#ifdef VERBOSE + cout << "Action mask is " << hex << thisDetector->actionMask << dec << endl; +#endif + return thisDetector->scanMode[iscan]; + + + } else + return -1; + +} + + + +int multiSlsDetector::setScanParameter(int iscan, string par) { + + + if (iscan>=0 && iscanscanParameter[iscan],par.c_str()); + return thisDetector->scanMode[iscan]; + } else + return -1; + +} + + +int multiSlsDetector::setScanPrecision(int iscan, int precision) { + if (iscan>=0 && iscan=0) + thisDetector->scanPrecision[iscan]=precision; + return thisDetector->scanMode[iscan]; + } else + return -1; + +} + +int multiSlsDetector::setScanSteps(int iscan, int nvalues, float *values) { + + if (iscan>=0 && iscan=0) { + if (nvalues==0) + thisDetector->scanMode[iscan]=0; + else { + thisDetector->nScanSteps[iscan]=nvalues; + if (nvalues>MAX_SCAN_STEPS) + thisDetector->nScanSteps[iscan]=MAX_SCAN_STEPS; + } + } + + if (values) { + for (int iv=0; ivnScanSteps[iscan]; iv++) { + thisDetector->scanSteps[iscan][iv]=values[iv]; + } + } + + if (thisDetector->scanMode[iscan]>0){ + thisDetector->actionMask |= (1 << (iscan+MAX_ACTIONS)); + } else { + thisDetector->actionMask &= ~(1 << (iscan+MAX_ACTIONS)); + } + +#ifdef VERBOSE + cout << "Action mask is " << hex << thisDetector->actionMask << dec << endl; +#endif + setTotalProgress(); + + + + + return thisDetector->scanMode[iscan]; + + + } else + return -1; + + + + +} + + + + /** + returns scan script + \param iscan can be (0,1) + \returns scan script + */ +string multiSlsDetector::getScanScript(int iscan){ + if (iscan>=0 && iscanscanMode[iscan]) + return string(thisDetector->scanScript[iscan]); + else + return string("none"); + } else + return string("wrong index"); + +}; + + /** + returns scan parameter + \param iscan can be (0,1) + \returns scan parameter + */ +string multiSlsDetector::getScanParameter(int iscan){ + if (iscan>=0 && iscanscanMode[iscan]) + return string(thisDetector->scanParameter[iscan]); + else + return string("none"); + } else + return string("wrong index"); +} + + + /** + returns scan mode + \param iscan can be (0,1) + \returns scan mode + */ +int multiSlsDetector::getScanMode(int iscan){ + if (iscan>=0 && iscanscanMode[iscan]; + else + return -1; +} + + + /** + returns scan steps + \param iscan can be (0,1) + \param v is the pointer to the scan steps + \returns scan steps + */ +int multiSlsDetector::getScanSteps(int iscan, float *v) { + + if (iscan>=0 && iscannScanSteps[iscan]; iv++) { + v[iv]=thisDetector->scanSteps[iscan][iv]; + } + } + + + setTotalProgress(); + + + + + + + + + + + + + + + + if (thisDetector->scanMode[iscan]) + return thisDetector->nScanSteps[iscan]; + else + return 0; + } else + return -1; +} + + +int multiSlsDetector::getScanPrecision(int iscan){ + if (iscan>=0 && iscanscanPrecision[iscan]; + } else + return -1; +} + + + + + + + + + + + + + + + + + + + diff --git a/slsDetectorSoftware/multiSlsDetector/multiSlsDetector.h b/slsDetectorSoftware/multiSlsDetector/multiSlsDetector.h new file mode 100644 index 000000000..e913891b2 --- /dev/null +++ b/slsDetectorSoftware/multiSlsDetector/multiSlsDetector.h @@ -0,0 +1,1277 @@ + + + +#ifndef MULTI_SLS_DETECTOR_H +#define MULTI_SLS_DETECTOR_H + +#include "slsDetector.h" + +#define MAXDET 100 + + +//using namespace std; +/** + \mainpage Common C++ library for SLS detectors data acquisition + * + * \section intro_sec Introduction + + * \subsection mot_sec Motivation + Although the SLS detectors group delvelops several types of detectors (1/2D, counting/integrating etc.) it is common interest of the group to use a common platfor for data acquisition + \subsection arch_sec System Architecture + The architecture of the acquisitions system is intended as follows: + \li A socket server running on the detector (or more than one in some special cases) + \li C++ classes common to all detectors for client-server communication. These can be supplied to users as libraries and embedded also in acquisition systems which are not developed by the SLS \sa MySocketTCP slsDetector + \li the possibility of using a Qt-based graphical user interface (with eventually root analisys capabilities) + \li the possibility of runnin alla commands from command line. In order to ensure a fast operation of this so called "text client" the detector parameters should not be re-initialized everytime. For this reason a shared memory block is allocated where the main detector flags and parameters are stored \sa slsDetector::sharedSlsDetector + \section howto_sec How to use it + The best way to operate the slsDetectors is to use the software (text client or GUI) developed by the sls detectors group. +In case you need to embed the detector control in a previously existing software, compile these classes using
+make package +
+and link the shared library created to your software bin/libSlsDetector.so.1.0.1 +Then in your software you should use the class related to the detector you want to control (mythenDetector or eigerDetector). + + @author Anna Bergamaschi + +*/ + + + +/** + * + * +@libdoc The slsDetector class is expected to become the interface class for all SLS Detectors acquisition (and analysis) software. + * + * @short This is the base class for all SLS detector functionalities + * @author Anna Bergamaschi + * @version 0.1alpha + + + */ + +class multiSlsDetector : public slsDetector { + + + + public: + + + /** + @short Structure allocated in shared memory to store detector settings and be accessed in parallel by several applications (take care of possible conflicts!) + + */ + + +/** (default) constructor + \param type is needed to define the size of the detector shared memory 9defaults to GENERIC i.e. the largest shared memory needed by any slsDetector is allocated + \param id is the detector index which is needed to define the shared memory id. Different physical detectors should have different IDs in order to work independently + + +*/ + multiSlsDetector(detectorType type=GENERIC, int ndet=1, int id=0); + //slsDetector(string const fname); + /** destructor */ + virtual ~multiSlsDetector(); + + + + + int addSlsDetector(detectorType type=GENERIC, int id=0); + int removeSlsDetector(int i=-1); + + + int getDetectorId(int i) {if (detectors[i]) return detectors[i]->getDetectorId();}; + + + /** sets the onlineFlag + \param off can be:
GET_ONLINE_FLAG, returns wether the detector is in online or offline state;
OFFLINE_FLAG, detector in offline state (i.e. no communication to the detector - using only local structure - no data acquisition possible!);
ONLINE_FLAG detector in online state (i.e. communication to the detector updating the local structure) */ + int setOnline(int const online=GET_ONLINE_FLAG, int i=-1); + /** sets the onlineFlag + \returns 1 if the detector structure has already be initlialized with the given idand belongs to this multiDetector instance, 0 otherwise */ + int exists(int id) ; + + /** + Purely virtual function + Should be implemented in the specific detector class + /sa mythenDetector::readConfigurationFile + */ + + virtual int readConfigurationFile(string const fname)=0; + /** + Purely virtual function + Should be implemented in the specific detector class + /sa mythenDetector::writeConfigurationFile + */ + virtual int writeConfigurationFile(string const fname)=0; + + + /* + It should be possible to dump all the settings of the detector (including trimbits, threshold energy, gating/triggering, acquisition time etc. + in a file and retrieve it for repeating the measurement with identicals ettings, if necessary + */ + /** + + Purely virtual function + Should be implemented in the specific detector class + /sa mythenDetector::dumpDetectorSetup + */ + virtual int dumpDetectorSetup(string const fname, int level)=0; + /** + Purely virtual function + Should be implemented in the specific detector class + /sa mythenDetector::retrieveDetectorSetup + */ + virtual int retrieveDetectorSetup(string const fname, int level)=0; + + /** + configure the socket communication and initializes the socket instances + + \param name hostname - if "" the current hostname is used + \param control_port port for control commands - if -1 the current is used + \param stop_port port for stop command - if -1 the current is used + \param data_port port for receiving data - if -1 the current is used + + \returns OK is connection succeded, FAIL otherwise + \sa sharedSlsDetector + */ + int setTCPSocket(int i, string const name="", int const control_port=-1, int const stop_port=-1, int const data_port=-1); + + /** returns the detector hostname \sa sharedSlsDetector */ + char* getHostname(int i) ; + /** returns the detector control port \sa sharedSlsDetector */ + int getControlPort(int i=-1); + /** returns the detector stop port \sa sharedSlsDetector */ + int getStopPort(int i=-1); + /** returns the detector data port \sa sharedSlsDetector */ + int getDataPort(int i=-1); + + /** generates file name without extension + + always appends to file path and file name the run index. + + in case also appends the position index + + Filenames will be of the form: filepath/filename(_px)_i + where x is the position index and i is the run index + + */ + string createFileName(); + + + + + + + + + + + + + + + /* I/O */ + /** returns the detector trimbit directory \sa sharedSlsDetector */ + char* getTrimDir(int i=-1); + /** sets the detector trimbit directory \sa sharedSlsDetector */ + char* setTrimDir(string s, int i=-1); + /** returns the number of trim energies and their value \sa sharedSlsDetector + \param point to the array that will contain the trim energies (in ev) + \returns number of trim energies + + unused! + + \sa sharedSlsDetector + */ + int getTrimEn(int *en=NULL, int i=-1); + /** sets the number of trim energies and their value \sa sharedSlsDetector + \param nen number of energies + \param en array of energies + \returns number of trim energies + + unused! + + \sa sharedSlsDetector + */ + int setTrimEn(int nen, int *en=NULL, int i=-1); + + /** + Pure virtual function + reads a trim file + \param fname name of the file to be read + \param myMod pointer to the module structure which has to be set.
If it is NULL a new module structure will be created + \returns the pointer to myMod or NULL if reading the file failed + \sa mythenDetector::readTrimFile + */ + + virtual sls_detector_module* readTrimFile(string fname, sls_detector_module* myMod=NULL)=0; + + /** + Pure virtual function + writes a trim file + \param fname name of the file to be written + \param mod module structure which has to be written to file + \returns OK or FAIL if the file could not be written + + \sa ::sls_detector_module mythenDetector::writeTrimFile(string, sls_detector_module) + */ + virtual int writeTrimFile(string fname, sls_detector_module mod)=0; + + /** + returns currently the loaded trimfile name + */ + + const char *getTrimFile(int i=-1); + + /** + Pure virtual function + writes a trim file for module number imod - the values will be read from the current detector structure + \param fname name of the file to be written + \param imod module number + \returns OK or FAIL if the file could not be written + \sa ::sls_detector_module sharedSlsDetector mythenDetector::writeTrimFile(string, int) + */ + virtual int writeTrimFile(string fname, int imod, int i)=0; + + /** + sets the default output files path + \sa sharedSlsDetector + */ + char* setFilePath(string s, int i=-1); + + /** + sets the default output files root name + \sa sharedSlsDetector + */ + char* setFileName(string s, int i=-1); + + /** + sets the default output file index + \sa sharedSlsDetector + */ + int setFileIndex(int i, int id=-1); + + /** + returns the default output files path + \sa sharedSlsDetector + */ + char* getFilePath(int id=-1); + + /** + returns the default output files root name + \sa sharedSlsDetector + */ + char* getFileName(int id=-1) ; + + /** + returns the default output file index + \sa sharedSlsDetector + */ + int getFileIndex(int id=-1) ; + + + + /** + Pure virtual function + writes a data file + \param name of the file to be written + \param data array of data values + \param err array of arrors on the data. If NULL no errors will be written + + \param ang array of angular values. If NULL data will be in the form chan-val(-err) otherwise ang-val(-err) + \param dataformat format of the data: can be 'i' integer or 'f' float (default) + \param nch number of channels to be written to file. if -1 defaults to the number of installed channels of the detector + \returns OK or FAIL if it could not write the file or data=NULL + \sa mythenDetector::writeDataFile + + */ + virtual int writeDataFile(string fname, float *data, float *err=NULL, float *ang=NULL, char dataformat='f', int nch=-1)=0; + + /** + Pure virtual function + writes a data file + \param name of the file to be written + \param data array of data values + \returns OK or FAIL if it could not write the file or data=NULL + \sa mythenDetector::writeDataFile + */ + virtual int writeDataFile(string fname, int *data)=0; + + /** + Pure virtual function + reads a data file + \param name of the file to be read + \param data array of data values to be filled + \param err array of arrors on the data. If NULL no errors are expected on the file + + \param ang array of angular values. If NULL data are expected in the form chan-val(-err) otherwise ang-val(-err) + \param dataformat format of the data: can be 'i' integer or 'f' float (default) + \param nch number of channels to be written to file. if <=0 defaults to the number of installed channels of the detector + \returns OK or FAIL if it could not read the file or data=NULL + + \sa mythenDetector::readDataFile + */ + virtual int readDataFile(string fname, float *data, float *err=NULL, float *ang=NULL, char dataformat='f', int nch=0)=0; + + /** + Pure virtual function + reads a data file + \param name of the file to be read + \param data array of data values + \returns OK or FAIL if it could not read the file or data=NULL + \sa mythenDetector::readDataFile + */ + virtual int readDataFile(string fname, int *data)=0; + + /** + returns the location of the calibration files + \sa sharedSlsDetector + */ + char* getCalDir(int id=-1); + + + /** + sets the location of the calibration files + \sa sharedSlsDetector + */ + char* setCalDir(string s, int id=-1) + /** + Pure virtual function + reads a calibration file + \param fname file to be read + \param gain reference to the gain variable + \offset reference to the offset variable + \sa sharedSlsDetector mythenDetector::readCalibrationFile + */ + virtual int readCalibrationFile(string fname, float &gain, float &offset)=0; + /** + Pure virtual function + writes a calibration file + \param fname file to be written + \param gain + \param offset + \sa sharedSlsDetector mythenDetector::writeCalibrationFile + */ + virtual int writeCalibrationFile(string fname, float gain, float offset)=0; + + + /** + Pure virtual function + reads an angular conversion file + \param fname file to be read + \sa angleConversionConstant mythenDetector::readAngularConversion + */ + virtual int readAngularConversion(string fname="", int id=-1)=0; + /** + Pure virtual function + writes an angular conversion file + \param fname file to be written + \sa angleConversionConstant mythenDetector::writeAngularConversion + */ + virtual int writeAngularConversion(string fname="", int id=-1)=0; + + /** Returns the number of channels per chip */ + int getNChans(int id=-1); // + + /** Returns the number of chips per module */ + int getNChips(int id=-1); // + + + /* Communication to server */ + + + /** + executes a system command on the server + e.g. mount an nfs disk, reboot and returns answer etc. + \param cmd is the command to be executed + \param answer is the answer from the detector + \returns OK or FAIL depending on the command outcome + */ + int execCommand(string cmd, string answer, int id=-1); + + /** + sets/gets detector type + normally the detector knows what type of detector it is + \param type is the detector type (defaults to GET_DETECTOR_TYPE) + \returns returns detector type index (1 GENERIC, 2 MYTHEN, 3 PILATUS, 4 XFS, 5 GOTTHARD, 6 AGIPD, -1 command failed) + */ + int setDetectorType(detectorType type=GET_DETECTOR_TYPE, int id=-1); + + /** + sets/gets detector type + normally the detector knows what type of detector it is + \param type is the detector type ("Mythen", "Pilatus", "XFS", "Gotthard", Agipd") + \returns returns detector type index (1 GENERIC, 2 MYTHEN, 3 PILATUS, 4 XFS, 5 GOTTHARD, 6 AGIPD, -1 command failed) + */ + int setDetectorType(string type, int id=-1); + + /** + gets detector type + normally the detector knows what type of detector it is + \param type is the string where the detector type will be written ("Mythen", "Pilatus", "XFS", "Gotthard", Agipd") + */ + void getDetectorType(char *type, int id=-1); + + + // Detector configuration functions + /** + set/get the size of the detector + \param n number of modules + \param d dimension + \returns current number of modules in direction d + */ + + // Detector configuration functions + /** + set/get the size of the detector + \param n number of modules + \param d dimension + \returns current number of modules in direction d + */ + int setNumberOfModules(int n=GET_FLAG, dimension d=X, int id=-1); // if n=GET_FLAG returns the number of installed modules + + /* + returns the instrinsic size of the detector (maxmodx, maxmody, nchans, nchips, ndacs + enum numberOf { + MAXMODX, + MAXMODY, + CHANNELS, + CHIPS, + DACS + } + */ + + + /** + get the maximum size of the detector + \param d dimension + \returns maximum number of modules that can be installed in direction d + */ + int getMaxNumberOfModules(dimension d=X, int id=-1); // + + + /** + set/get the use of an external signal + \param pol meaning of the signal \sa externalSignalFlag + \param signalIndex index of the signal + \returns current meaning of signal signalIndex + */ + externalSignalFlag setExternalSignalFlags(externalSignalFlag pol=GET_EXTERNAL_SIGNAL_FLAG , int signalindex=0, int id=-1); + + + /** + set/get the external communication mode + + obsolete \sa setExternalSignalFlags + \param pol value to be set \sa externalCommunicationMode + \returns current external communication mode + */ + externalCommunicationMode setExternalCommunicationMode(externalCommunicationMode pol=GET_EXTERNAL_COMMUNICATION_MODE, int id=-1); + + + // Tests and identification + + /** + get detector ids/versions for module + \param mode which id/version has to be read + \param imod module number for module serial number + \returns id + */ + int64_t getId(idMode mode, int imod=0, int id=0); + int64_t getId(idMode mode, int imod=0); + /** + Digital test of the modules + \param mode test mode + \param imod module number for chip test or module firmware test + \returns OK or error mask + */ + int digitalTest(digitalTestMode mode, int imod=0); + int digitalTest(digitalTestMode mode, int imod=0, int id=0); + /** + analog test + \param modte test mode + \return pointer to acquired data + + not yet implemented + */ + + int* analogTest(analogTestMode mode); + + /** + enable analog output of channel ichan + + not yet implemented + */ + int enableAnalogOutput(int ichan); + + /** + enable analog output of channel ichan, chip ichip, module imod + + not yet implemented + */ + int enableAnalogOutput(int imod, int ichip, int ichan); + + /** + give a train of calibration pulses + \param vcal pulse amplitude + \param npulses number of pulses + + not yet implemented + + */ + int giveCalibrationPulse(float vcal, int npulses); + + // Expert Initialization functions + + + /** + write register + \param addr address + \val value + \returns current register value + + */ + int writeRegister(int addr, int val); + + /** + read register + \param addr address + \returns current register value + + */ + int readRegister(int addr); + + /** + set dacs value + \param val value (in V) + \param index DAC index + \param imod module number (if -1 alla modules) + \returns current DAC value + */ + float setDAC(float val, dacIndex index, int imod=-1); + + /** + set dacs value + \param index ADC index + \param imod module number + \returns current ADC value + */ + float getADC(dacIndex index, int imod=0); + + /** + configure channel + \param reg channel register + \param ichan channel number (-1 all) + \param ichip chip number (-1 all) + \param imod module number (-1 all) + \returns current register value + \sa ::sls_detector_channel + */ + int setChannel(int64_t reg, int ichan=-1, int ichip=-1, int imod=-1); + + /** + configure channel + \param chan channel to be set - must contain correct channel, module and chip number + \returns current register value + */ + int setChannel(sls_detector_channel chan); + + /** + get channel + \param ichan channel number + \param ichip chip number + \param imod module number + \returns current channel structure for channel + */ + sls_detector_channel getChannel(int ichan, int ichip, int imod); + + + + /** + configure chip + \param reg chip register + \param ichip chip number (-1 all) + \param imod module number (-1 all) + \returns current register value + \sa ::sls_detector_chip + */ + int setChip(int reg, int ichip=-1, int imod=-1); + + /** + configure chip + \param chip chip to be set - must contain correct module and chip number and also channel registers + \returns current register value + \sa ::sls_detector_chip + */ + int setChip(sls_detector_chip chip); + + /** + get chip + \param ichip chip number + \param imod module number + \returns current chip structure for channel + + \bug probably does not return corretly! + */ + sls_detector_chip getChip(int ichip, int imod); + + + /** + configure module + \param imod module number (-1 all) + \returns current register value + \sa ::sls_detector_module + */ + virtual int setModule(int reg, int imod=-1); + + /** + configure chip + \param module module to be set - must contain correct module number and also channel and chip registers + \returns current register value + \sa ::sls_detector_module + */ + virtual int setModule(sls_detector_module module); + + /** + get module + \param imod module number + \returns pointer to module structure (which has bee created and must then be deleted) + */ + virtual sls_detector_module *getModule(int imod); + + // calibration functions + // int setCalibration(int imod, detectorSettings isettings, float gain, float offset); + //int getCalibration(int imod, detectorSettings isettings, float &gain, float &offset); + + + /* + calibrated setup of the threshold + */ + /** + get threshold energy + \param imod module number (-1 all) + \returns current threshold value for imod in ev (-1 failed) + */ + int getThresholdEnergy(int imod=-1); + + /** + set threshold energy + \param e_eV threshold in eV + \param imod module number (-1 all) + \param isettings ev. change settings + \returns current threshold value for imod in ev (-1 failed) + */ + int setThresholdEnergy(int e_eV, int imod=-1, detectorSettings isettings=GET_SETTINGS); + + /** + get detector settings + \param imod module number (-1 all) + \returns current settings + */ + detectorSettings getSettings(int imod=-1); + + /** + set detector settings + \param isettings settings + \param imod module number (-1 all) + \returns current settings + + in this function trimbits and calibration files are searched in the trimDir and calDir directories and the detector is initialized + */ + virtual detectorSettings setSettings(detectorSettings isettings, int imod=-1); + + +// Acquisition functions + + + /** + start detector acquisition + \returns OK/FAIL + */ + int startAcquisition(); + + /** + stop detector acquisition + \returns OK/FAIL + */ + int stopAcquisition(); + + /** + start readout (without exposure or interrupting exposure) + \returns OK/FAIL + */ + int startReadOut(); + + /** + get run status + \returns status mask + */ + virtual runStatus getRunStatus()=0; + + /** + start detector acquisition and read all data putting them a data queue + \returns pointer to the front of the data queue + \sa startAndReadAllNoWait getDataFromDetector dataQueue + */ + int* startAndReadAll(); + + /** + start detector acquisition and read out, but does not read data from socket + + */ + int startAndReadAllNoWait(); + + /** + receives a data frame from the detector socket + \returns pointer to the data or NULL. If NULL disconnects the socket + \sa getDataFromDetector + */ + int* getDataFromDetectorNoWait(); + + /** + asks and receives a data frame from the detector and puts it in the data queue + \returns pointer to the data or NULL. + \sa getDataFromDetector + */ + int* readFrame(); + + /** + asks and receives all data from the detector and puts them in a data queue + \returns pointer to the front of the queue or NULL. + \sa getDataFromDetector dataQueue + */ + int* readAll(); + + + /** + pops the data from the data queue + \returns pointer to the popped data or NULL if the queue is empty. + \sa dataQueue + */ + int* popDataQueue(); + + /** + pops the data from thepostprocessed data queue + \returns pointer to the popped data or NULL if the queue is empty. + \sa finalDataQueue + */ + detectorData* popFinalDataQueue(); + + + + + /** + resets the raw data queue + \sa dataQueue + */ + void resetDataQueue(); + + /** + resets the postprocessed data queue + \sa finalDataQueue + */ + void resetFinalDataQueue(); + + + + + + + + + + /** + set/get timer value + \param index timer index + \param t time in ns or number of...(e.g. frames, gates, probes) + \returns timer set value in ns or number of...(e.g. frames, gates, probes) + */ + int64_t setTimer(timerIndex index, int64_t t=-1); + + /** + get current timer value + \param index timer index + \returns elapsed time value in ns or number of...(e.g. frames, gates, probes) + */ + int64_t getTimeLeft(timerIndex index); + + + + + /** sets/gets the value of important readout speed parameters + \param sp is the parameter to be set/get + \param value is the value to be set, if -1 get value + \returns current value for the specified parameter + \sa speedVariable + */ + int setSpeed(speedVariable sp, int value=-1); + + // Flags + /** + set/get dynamic range + \param n dynamic range (-1 get) + \returns current dynamic range + updates the size of the data expected from the detector + \sa sharedSlsDetector + */ + int setDynamicRange(int n=-1); + + /** + set roi + + not yet implemented + */ + int setROI(int nroi=-1, int *xmin=NULL, int *xmax=NULL, int *ymin=NULL, int *ymax=NULL); + + + /** + set/get readout flags + \param flag readout flag to be set + \returns current flag + */ + int setReadOutFlags(readOutFlags flag); + + /** + execute trimming + \param mode trim mode + \param par1 if noise, beam or fixed setting trimming it is count limit, if improve maximum number of iterations + \param par2 if noise or beam nsigma, if improve par2!=means vthreshold will be optimized, if fixed settings par2<0 trimwith median, par2>=0 trim with level + \param imod module number (-1 all) + \returns OK or FAIl (FAIL also if some channel are 0 or 63 + */ + int executeTrimming(trimMode mode, int par1, int par2, int imod=-1); + + + //Corrections + + /** + set/get if the data processing and file writing should be done by a separate thread +s + \param b 0 sequencial data acquisition and file writing, 1 separate thread, -1 get + \returns thread flag + */ + + int setThreadedProcessing(int b=-1) {if (b>=0) thisDetector->threadedProcessing=b; return thisDetector->threadedProcessing;} + + /** + set flat field corrections + \param fname name of the flat field file (or "" if disable) + \returns 0 if disable (or file could not be read), >0 otherwise + */ + int setFlatFieldCorrection(string fname=""); + + /** + get flat field corrections + \param corr if !=NULL will be filled with the correction coefficients + \param ecorr if !=NULL will be filled with the correction coefficients errors + \returns 0 if ff correction disabled, >0 otherwise + */ + int getFlatFieldCorrection(float *corr=NULL, float *ecorr=NULL); + + /** + get flat field corrections file directory + \returns flat field correction file directory + */ + char *getFlatFieldCorrectionDir(){return thisDetector->flatFieldDir;}; + /** + set flat field corrections file directory + \param flat field correction file directory + */ + void setFlatFieldCorrectionDir(string dir){strcpy(thisDetector->flatFieldDir,dir.c_str());}; + + /** + get flat field corrections file name + \returns flat field correction file name + */ + char *getFlatFieldCorrectionFile(){ if (thisDetector->correctionMask&(1<flatFieldFile; else return "none";}; + + /** + set rate correction + \param t dead time in ns - if 0 disable correction, if >0 set dead time to t, if <0 set deadtime to default dead time for current settings + \returns 0 if rate correction disabled, >0 otherwise + */ + int setRateCorrection(float t=0); + + + /** + get rate correction + \param t reference for dead time + \returns 0 if rate correction disabled, >0 otherwise + */ + int getRateCorrection(float &t); + + + /** + get rate correction tau + \returns 0 if rate correction disabled, otherwise the tau used for the correction + */ + float getRateCorrectionTau(); + /** + get rate correction + \returns 0 if rate correction disabled, >0 otherwise + */ + int getRateCorrection(); + + /** + set bad channels correction + \param fname file with bad channel list ("" disable) + \returns 0 if bad channel disabled, >0 otherwise + */ + int setBadChannelCorrection(string fname=""); + + /** + get bad channels correction + \param bad pointer to array that if bad!=NULL will be filled with the bad channel list + \returns 0 if bad channel disabled or no bad channels, >0 otherwise + */ + int getBadChannelCorrection(int *bad=NULL); + + /** returns the bad channel list file */ + string getBadChannelCorrectionFile() {if (thisDetector->correctionMask&(1<< DISCARD_BAD_CHANNELS)) return string(thisDetector->badChanFile); else return string("none");}; + + + /** + pure virtual function + set angular conversion + \param fname file with angular conversion constants ("" disable) + \returns 0 if angular conversion disabled, >0 otherwise + \sa mythenDetector::setAngularConversion + */ + virtual int setAngularConversion(string fname="")=0; + + /** + pure virtual function + get angular conversion + \param reference to diffractometer direction + \param angconv array that will be filled with the angular conversion constants + \returns 0 if angular conversion disabled, >0 otherwise + \sa mythenDetector::getAngularConversion + */ + virtual int getAngularConversion(int &direction, angleConversionConstant *angconv=NULL)=0; + + + /** + pure virtual function + returns the angular conversion file + \sa mythenDetector::getAngularConversion */ + virtual string getAngularConversion()=0; + + /** + pure virtual function + set detector global offset + \sa mythenDetector::setGlobalOffset + */ + virtual float setGlobalOffset(float f)=0; + + /** + pure virtual function + set detector fine offset + \sa mythenDetector::setFineOffset + */ + virtual float setFineOffset(float f)=0; + /** + pure virtual function + get detector fine offset + \sa mythenDetector::getFineOffset + */ + virtual float getFineOffset()=0; + + /** + pure virtual function + get detector global offset + \sa mythenDetector::getGlobalOffset + */ + virtual float getGlobalOffset()=0; + + /** + pure virtual function + set positions for the acquisition + \param nPos number of positions + \param pos array with the encoder positions + \returns number of positions + \sa mythenDetector::setPositions + */ + virtual int setPositions(int nPos, float *pos)=0; + /** + pure virtual function + get positions for the acquisition + \param pos array which will contain the encoder positions + \returns number of positions + \sa mythenDetector::getPositions + */ + virtual int getPositions(float *pos=NULL)=0; + + + /** pure virtual function + set detector bin size used for merging (approx angular resolution) + \param bs bin size in degrees + \returns current bin size + \sa mythenDetector::setBinSize +*/ + virtual float setBinSize(float bs)=0; + + /** pure virtual function + return detector bin size used for merging (approx angular resolution) + \sa mythenDetector::getBinSize + */ + virtual float getBinSize()=0; + + + + + + /** + set action + \param iaction can be enum {startScript, scriptBefore, headerBefore, headerAfter,scriptAfter, stopScript, MAX_ACTIONS} + \param fname for script ("" disable) + \param par for script + \returns 0 if action disabled, >0 otherwise + */ + int setAction(int iaction, string fname="", string par=""); + + /** + set action + \param iaction can be enum {startScript, scriptBefore, headerBefore, headerAfter,scriptAfter, stopScript, MAX_ACTIONS} + \param fname for script ("" disable) + \returns 0 if action disabled, >0 otherwise + */ + int setActionScript(int iaction, string fname=""); + /** + set action + \param iaction can be enum {startScript, scriptBefore, headerBefore, headerAfter,scriptAfter, stopScript, MAX_ACTIONS} + \param par for script ("" disable) + \returns 0 if action disabled, >0 otherwise + */ + int setActionParameter(int iaction, string par=""); + + /** + returns action script + \param iaction can be enum {startScript, scriptBefore, headerBefore, headerAfter,scriptAfter, stopScript} + \returns action script + */ + string getActionScript(int iaction); + + /** + returns action parameter + \param iaction can be enum {startScript, scriptBefore, headerBefore, headerAfter,scriptAfter, stopScript} + \returns action parameter + */ + string getActionParameter(int iaction); + + /** + returns action mode + \param iaction can be enum {startScript, scriptBefore, headerBefore, headerAfter,scriptAfter, stopScript} + \returns action mode + */ + int getActionMode(int iaction); + + + /** + set scan + \param index of the scan (0,1) + \param fname for script ("" disables, "none" disables and overwrites current) + \param nvalues number of steps (0 disables, -1 leaves current value) + \param values pointer to steps (if NULL leaves current values) + \param par parameter for the scan script ("" leaves unchanged) + \returns 0 is scan disabled, >0 otherwise + */ + int setScan(int index, string script="", int nvalues=-1, float *values=NULL, string par="", int precision=-1); + + int setScanScript(int index, string script=""); + int setScanParameter(int index, string par=""); + int setScanPrecision(int index, int precision=-1); + int setScanSteps(int index, int nvalues=-1, float *values=NULL); + /** + returns scan script + \param iscan can be (0,1) + \returns scan script + */ + string getScanScript(int iscan); + + /** + returns scan parameter + \param iscan can be (0,1) + \returns scan parameter + */ + string getScanParameter(int iscan); + + /** + returns scan mode + \param iscan can be (0,1) + \returns scan mode + */ + int getScanMode(int iscan); + + /** + returns scan steps + \param iscan can be (0,1) + \param v is the pointer to the scan steps + \returns scan steps + */ + int getScanSteps(int iscan, float *v=NULL); + + + /** + returns scan precision + \param iscan can be (0,1) + \returns scan precision + */ + int getScanPrecision(int iscan); + + + + + /** + decode data from the detector converting them to an array of floats, one for each channle + \param datain data from the detector + \returns pointer to a float array with a data per channel + */ + float* decodeData(int *datain); + + + + + /** + flat field correct data + \param datain data + \param errin error on data (if<=0 will default to sqrt(datain) + \param dataout corrected data + \param errout error on corrected data + \param ffcoefficient flat field correction coefficient + \param fferr erro on ffcoefficient + \returns 0 + */ + int flatFieldCorrect(float datain, float errin, float &dataout, float &errout, float ffcoefficient, float fferr); + + /** + flat field correct data + \param datain data array + \param errin error array on data (if NULL will default to sqrt(datain) + \param dataout array of corrected data + \param errout error on corrected data (if not NULL) + \returns 0 + */ + int flatFieldCorrect(float* datain, float *errin, float* dataout, float *errout); + + + + /** + rate correct data + \param datain data + \param errin error on data (if<=0 will default to sqrt(datain) + \param dataout corrected data + \param errout error on corrected data + \param tau dead time 9in ns) + \param t acquisition time (in ns) + \returns 0 + */ + int rateCorrect(float datain, float errin, float &dataout, float &errout, float tau, float t); + + /** + rate correct data + \param datain data array + \param errin error array on data (if NULL will default to sqrt(datain) + \param dataout array of corrected data + \param errout error on corrected data (if not NULL) + \returns 0 + */ + int rateCorrect(float* datain, float *errin, float* dataout, float *errout); + + + /** + pure virtual function + sets the arrays of the merged data to 0. NB The array should be created with size >= 360./getBinSize(); + \param mp already merged postions + \param mv already merged data + \param me already merged errors (squared sum) + \param mm multiplicity of merged arrays + \returns OK or FAIL + \sa mythenDetector::resetMerging + */ + virtual int resetMerging(float *mp, float *mv,float *me, int *mm)=0; + /** + pure virtual function + merge dataset + \param p1 angular positions of dataset + \param v1 data + \param e1 errors + \param mp already merged postions + \param mv already merged data + \param me already merged errors (squared sum) + \param mm multiplicity of merged arrays + \sa mythenDetector::addToMerging + */ + virtual int addToMerging(float *p1, float *v1, float *e1, float *mp, float *mv,float *me, int *mm)=0; + + /** pure virtual function + calculates the "final" positions, data value and errors for the emrged data + \param mp already merged postions + \param mv already merged data + \param me already merged errors (squared sum) + \param mm multiplicity of merged arrays + \returns FAIL or the number of non empty bins (i.e. points belonging to the pattern) + \sa mythenDetector::finalizeMerging + */ + int finalizeMerging(float *mp, float *mv,float *me, int *mm); + + /** + turns off server + */ + int exitServer(); + + /** pure virtual function + function for processing data + /param delflag if 1 the data are processed, written to file and then deleted. If 0 they are added to the finalDataQueue + \sa mythenDetector::processData + */ + virtual void* processData(int delflag=1)=0; // thread function + /** Allocates the memory for a sls_detector_module structure and initializes it + \returns myMod the pointer to the allocate dmemory location + + */ + sls_detector_module* createModule(); + /** frees the memory for a sls_detector_module structure + \param myMod the pointer to the memory to be freed + + */ + + void deleteModule(sls_detector_module *myMod); + + + /** pure virtual function + performs the complete acquisition and data processing + moves the detector to next position
+ starts and reads the detector
+ reads the IC (if required)
+ reads the encoder (iof required for angualr conversion)
+ processes the data (flat field, rate, angular conversion and merging ::processData()) + /param delflag if 1 the data are processed, written to file and then deleted. If 0 they are added to the finalDataQueue + \sa mythenDetector::acquire() + */ + + virtual void acquire(int delflag=1)=0; + + /** calcualtes the total number of steps of the acquisition. + called when number of frames, number of cycles, number of positions and scan steps change + */ + int setTotalProgress(); + + /** returns the current progress in % */ + float getCurrentProgress(); + + + protected: + + + + + int nDetectors; + + + slsDetector *detectors[MAXDET]; + + +}; + + +#endif diff --git a/slsDetectorSoftware/mythenDetector/mythenDetector.cpp b/slsDetectorSoftware/mythenDetector/mythenDetector.cpp index fa8ca32c7..b75bfc8cf 100644 --- a/slsDetectorSoftware/mythenDetector/mythenDetector.cpp +++ b/slsDetectorSoftware/mythenDetector/mythenDetector.cpp @@ -6,10 +6,6 @@ //using namespace std; - - - - string mythenDetector::executeLine(int narg, char *args[], int action) { @@ -99,8 +95,8 @@ string mythenDetector::executeLine(int narg, char *args[], int action) { std::cout<< helpLine(action); return string("more questions? Refere to software documentation!"); } - - if (var=="hostname") { + + if (var=="hostname") { if (action==PUT_ACTION) { setTCPSocket(args[1]); } @@ -270,9 +266,9 @@ string mythenDetector::executeLine(int narg, char *args[], int action) { if (var=="trimdir") { if (action==PUT_ACTION) { sval=string(args[1]); - setTrimDir(sval); + setSettingsDir(sval); } - return string(getTrimDir()); + return string(getSettingsDir()); } else if (var=="caldir") { if (action==PUT_ACTION) { sval=string(args[1]); @@ -730,9 +726,11 @@ string mythenDetector::executeLine(int narg, char *args[], int action) { sett=FAST; else if (sval=="highgain") sett=HIGHGAIN; - //setSettings(sett); + else { + sprintf(answer,"%s not defined for this detector",sval.c_str()); + return string(answer); + } } - //switch (setSettings( GET_SETTINGS)) { switch (setSettings(sett)) { case STANDARD: return string("standard"); @@ -740,6 +738,14 @@ string mythenDetector::executeLine(int narg, char *args[], int action) { return string("fast"); case HIGHGAIN: return string("highgain"); + case DYNAMICGAIN: + return string("dynamicgain"); + case GAIN1: + return string("gain1"); + case GAIN2: + return string("gain2"); + case GAIN3: + return string("gain3"); default: return string("undefined"); } @@ -981,14 +987,14 @@ string mythenDetector::executeLine(int narg, char *args[], int action) { if (action==GET_ACTION) { ostfn << sval << ".sn" << setfill('0') << setw(3) << hex << getId(MODULE_SERIAL_NUMBER, im); if ((myMod=getModule(im))) { - writeTrimFile(ostfn.str(),*myMod); + writeSettingsFile(ostfn.str(),*myMod); deleteModule(myMod); } } else if (action==PUT_ACTION) { ostfn << sval ; if (sval.find('.',sval.length()-7)module=im; setModule(*myMod); @@ -998,7 +1004,7 @@ string mythenDetector::executeLine(int narg, char *args[], int action) { } } std::cout<< "Returning trimfile " << std::endl; - return string(getTrimFile()); + return string(getSettingsFile()); } else if (var.find("trim")==0) { if (action==GET_ACTION) { trimMode mode=NOISE_TRIMMING; @@ -1040,7 +1046,7 @@ string mythenDetector::executeLine(int narg, char *args[], int action) { //create file names ostfn << sval << ".sn" << setfill('0') << setw(3) << hex << getId(MODULE_SERIAL_NUMBER, im); if ((myMod=getModule(im))) { - writeTrimFile(ostfn.str(),*myMod); + writeSettingsFile(ostfn.str(),*myMod); deleteModule(myMod); } } @@ -1549,29 +1555,6 @@ string mythenDetector::helpLine( int action) { - - - - - - - - - - - - - - - - - - - - - - - /* detector configuration (no communication to server) */ /* @@ -1921,11 +1904,10 @@ int mythenDetector::retrieveDetectorSetup(string fname1, int level){ - /* I/O */ - sls_detector_module* mythenDetector::readTrimFile(string fname, sls_detector_module *myMod){ + sls_detector_module* mythenDetector::readSettingsFile(string fname, sls_detector_module *myMod){ int nflag=0; @@ -2056,7 +2038,7 @@ int mythenDetector::retrieveDetectorSetup(string fname1, int level){ std::cout<< "read " << ichan*ichip << " channels" <trimFile,fname.c_str()); + strcpy(thisDetector->settingsFile,fname.c_str()); return myMod; } else { std::cout<< "could not open trim file " << myfname << std::endl; @@ -2068,7 +2050,7 @@ int mythenDetector::retrieveDetectorSetup(string fname1, int level){ }; -int mythenDetector::writeTrimFile(string fname, sls_detector_module mod){ +int mythenDetector::writeSettingsFile(string fname, sls_detector_module mod){ ofstream outfile; string names[]={"Vtrim", "Vthresh", "Rgsh1", "Rgsh2", "Rgpr", "Vcal", "outBuffEnable"}; @@ -2119,9 +2101,9 @@ int mythenDetector::writeTrimFile(string fname, sls_detector_module mod){ -int mythenDetector::writeTrimFile(string fname, int imod){ +int mythenDetector::writeSettingsFile(string fname, int imod){ - return writeTrimFile(fname,detectorModules[imod]); + return writeSettingsFile(fname,detectorModules[imod]); }; diff --git a/slsDetectorSoftware/mythenDetector/mythenDetector.h b/slsDetectorSoftware/mythenDetector/mythenDetector.h index a4895d564..cd68fe9a3 100644 --- a/slsDetectorSoftware/mythenDetector/mythenDetector.h +++ b/slsDetectorSoftware/mythenDetector/mythenDetector.h @@ -35,7 +35,8 @@ class mythenDetector : public slsDetector{ // ~slsDetector(){while(dataQueue.size()>0){}}; /** destructor */ virtual ~mythenDetector(){}; - + + /** executes a set of string arguments according to a given format. It is used to read/write configuration file, dump and retrieve detector settings and for the command line interface command parsing \param narg number of arguments @@ -81,35 +82,33 @@ enum {GET_ACTION, PUT_ACTION, READOUT_ACTION}; */ int retrieveDetectorSetup(string const fname, int level=0); - - /** - reads a trim file + reads a trim/settings file \param fname name of the file to be read \param myMod pointer to the module structure which has to be set.
If it is NULL a new module structure will be created \returns the pointer to myMod or NULL if reading the file failed */ - sls_detector_module* readTrimFile(string fname, sls_detector_module* myMod=NULL); + sls_detector_module* readSettingsFile(string fname, sls_detector_module* myMod=NULL); /** - writes a trim file + writes a trim/settings file \param fname name of the file to be written \param mod module structure which has to be written to file \returns OK or FAIL if the file could not be written \sa ::sls_detector_module */ - int writeTrimFile(string fname, sls_detector_module mod); + int writeSettingsFile(string fname, sls_detector_module mod); /** - writes a trim file for module number imod - the values will be read from the current detector structure + writes a trim/settings file for module number imod - the values will be read from the current detector structure \param fname name of the file to be written \param imod module number \returns OK or FAIL if the file could not be written \sa ::sls_detector_module sharedSlsDetector */ - int writeTrimFile(string fname, int imod); + int writeSettingsFile(string fname, int imod); /** writes a data file diff --git a/slsDetectorSoftware/mythenDetectorServer/firmware_funcs.c b/slsDetectorSoftware/mythenDetectorServer/firmware_funcs.c index 1d8c6a1d2..c9517e829 100755 --- a/slsDetectorSoftware/mythenDetectorServer/firmware_funcs.c +++ b/slsDetectorSoftware/mythenDetectorServer/firmware_funcs.c @@ -69,7 +69,7 @@ int mapCSP0(void) { fd = open("/dev/mem", O_RDWR | O_SYNC, 0); if (fd == -1) { printf("\nCan't find /dev/mem!\n"); - return FAIL; + return FAIL; } printf("/dev/mem opened\n"); CSP0BASE = (u_int32_t)mmap(0, MEM_SIZE, PROT_READ|PROT_WRITE, MAP_FILE|MAP_SHARED, fd, CSP0); diff --git a/slsDetectorSoftware/mythenDetectorServer/server_funcs.c b/slsDetectorSoftware/mythenDetectorServer/server_funcs.c index dbb543246..a89be5ffc 100755 --- a/slsDetectorSoftware/mythenDetectorServer/server_funcs.c +++ b/slsDetectorSoftware/mythenDetectorServer/server_funcs.c @@ -150,7 +150,7 @@ int M_nofunc(int fnum){ printf(mess); sendDataOnly(&retval,sizeof(retval)); sendDataOnly(mess,sizeof(mess)); - return -1; + return GOODBYE; } @@ -825,6 +825,14 @@ int set_dac(int fnum) { case PREAMP: idac=RGPR; break; + /*************************************************************** +add possible potentiometers like in chiptest board!!!!!!!!!!!!!!! + + ****************************************************************/ + + + + default: printf("Unknown DAC index %d\n",ind); sprintf(mess,"Unknown DAC index %d\n",ind); diff --git a/slsDetectorSoftware/mythenDetectorServer/trimming_funcs.c b/slsDetectorSoftware/mythenDetectorServer/trimming_funcs.c index 1495deb70..97131d023 100755 --- a/slsDetectorSoftware/mythenDetectorServer/trimming_funcs.c +++ b/slsDetectorSoftware/mythenDetectorServer/trimming_funcs.c @@ -476,9 +476,9 @@ int choose_vthresh() { int retval=OK; #ifdef MCB_FUNCS int imod, ichan; - u_int32_t *scan; + u_int32_t *scan, *scan1; int olddiff[nModX], direction[nModX]; - int med[nModX], diff, media; + int med[nModX], med1[nModX], diff, media; int change_flag=1; int iteration=0; int maxiterations=10; @@ -517,10 +517,14 @@ int choose_vthresh() { fifodata=fifo_read_event(); scan=decode_data(fifodata); + // + scan1=decode_data(fifodata); for (imod=modmi; imod0) @@ -586,6 +597,7 @@ int choose_vthresh() { } iteration++; free(scan); + free(scan1); } #endif return retval; @@ -602,12 +614,12 @@ int trim_with_median(int stop, int im) { #ifdef MCB_FUNCS int ichan, imod, ichip, ich; - u_int32_t *scan; + u_int32_t *scan, *scan1; int *olddiff, *direction; int med, diff; int change_flag=1; int iteration=0; - int me[nModX]; + int me[nModX], me1[nModX]; int modma, modmi, nm; int trim; int *fifodata; @@ -631,7 +643,7 @@ int trim_with_median(int stop, int im) { for (ich=0; ich0) { direction[ichan]=1; @@ -726,6 +740,7 @@ int trim_with_median(int stop, int im) { } iteration++; free(scan); + free(scan1); } free(olddiff); free(direction); diff --git a/slsDetectorSoftware/slsDetector/slsDetector.cpp b/slsDetectorSoftware/slsDetector/slsDetector.cpp index 270dacdaf..36968a5dc 100644 --- a/slsDetectorSoftware/slsDetector/slsDetector.cpp +++ b/slsDetectorSoftware/slsDetector/slsDetector.cpp @@ -5,10 +5,6 @@ #include - -//using namespace std; - - int slsDetector::initSharedMemory(detectorType type, int id) { @@ -34,6 +30,12 @@ int slsDetector::initSharedMemory(detectorType type, int id) { nc=12; nd=6; // dacs+adcs break; + case GOTTHARD: + nch=128; + nm=1; + nc=10; + nd=13; // dacs+adcs + break; default: nch=65535; // one EIGER module nm=1; //modules/detector @@ -115,22 +117,25 @@ slsDetector::slsDetector(detectorType type, int id): chanregs(NULL), badChannelMask(NULL) { - while (shmId<0) { - /**Initlializes shared memory \sa initSharedMemory + while (shmId<0) { + /**Initlializes shared memory \sa initSharedMemory - if it fails the detector id is incremented until it succeeds - */ - shmId=initSharedMemory(type,id); - id++; - } - id--; + if it fails the detector id is incremented until it succeeds + */ + shmId=initSharedMemory(type,id); + id++; + } + id--; #ifdef VERBOSE - std::cout<< "Detector id is " << id << std::endl; + std::cout<< "Detector id is " << id << std::endl; #endif - detId=id; - /**Initializes the detector stucture \sa initializeDetectorSize - */ - initializeDetectorSize(type); + detId=id; + + + /**Initializes the detector stucture \sa initializeDetectorSize + */ + initializeDetectorSize(type); + } @@ -146,10 +151,17 @@ int slsDetector::initializeDetectorSize(detectorType type) { /** sets onlineFlag to OFFLINE_FLAG */ thisDetector->onlineFlag=OFFLINE_FLAG; /** set ports to defaults */ + switch(type){ + case GOTTHARD: + thisDetector->controlPort=DEFAULT_PORTNO_GOTTHARD; + thisDetector->stopPort=DEFAULT_PORTNO_GOTTHARD+1; + thisDetector->dataPort=DEFAULT_PORTNO_GOTTHARD+2; + break; + default: thisDetector->controlPort=DEFAULT_PORTNO; thisDetector->stopPort=DEFAULT_PORTNO+1; thisDetector->dataPort=DEFAULT_PORTNO+2; - + } /** set thisDetector->myDetectorType to type and according to this set nChans, nChips, nDacs, nAdcs, nModMax, dynamicRange, nMod*/ thisDetector->myDetectorType=type; switch(thisDetector->myDetectorType) { @@ -171,6 +183,15 @@ int slsDetector::initializeDetectorSize(detectorType type) { thisDetector->nModMax[Y]=1; thisDetector->dynamicRange=24; break; + case GOTTHARD: + thisDetector->nChans=128; + thisDetector->nChips=10; + thisDetector->nDacs=8; + thisDetector->nAdcs=5; + thisDetector->nModMax[X]=1; + thisDetector->nModMax[Y]=1; + thisDetector->dynamicRange=1; + break; default: thisDetector->nChans=65536; thisDetector->nChips=8; @@ -196,11 +217,11 @@ int slsDetector::initializeDetectorSize(detectorType type) { else thisDetector->dataBytes=thisDetector->nMod[X]*thisDetector->nMod[Y]*thisDetector->nChips*thisDetector->nChans*thisDetector->dynamicRange/8; /** set trimDsdir, calDir and filePath to default to home directory*/ - strcpy(thisDetector->trimDir,getenv("HOME")); + strcpy(thisDetector->settingsDir,getenv("HOME")); strcpy(thisDetector->calDir,getenv("HOME")); strcpy(thisDetector->filePath,getenv("HOME")); /** sets trimbit file */ - strcpy(thisDetector->trimFile,"none"); + strcpy(thisDetector->settingsFile,"none"); /** set fileName to default to run*/ strcpy(thisDetector->fileName,"run"); /** set fileIndex to default to 0*/ @@ -2324,7 +2345,7 @@ int slsDetector::setThresholdEnergy(int e_eV, int imod, detectorSettings isetti */ detectorSettings slsDetector::getSettings(int imod){ - + int fnum=F_SET_SETTINGS; int ret=FAIL; char mess[100]; @@ -2359,16 +2380,29 @@ int slsDetector::setThresholdEnergy(int e_eV, int imod, detectorSettings isetti }; + + detectorSettings slsDetector::setSettings( detectorSettings isettings, int imod){ -#ifdef VERBOSE + //#ifdef VERBOSE std::cout<< "slsDetector setSettings "<< std::endl; -#endif + //#endif sls_detector_module *myMod=createModule(); int modmi=imod, modma=imod+1, im=imod; - string trimfname, calfname; + string settingsfname, calfname; string ssettings; + detectorSettings minsettings, maxsettings; - if (isettings>=STANDARD && isettings<=HIGHGAIN) { + switch(thisDetector->myDetectorType){ + case GOTTHARD: + minsettings = HIGHGAIN; + maxsettings = GAIN3; + break; + default: + minsettings = STANDARD; + maxsettings = HIGHGAIN; + } + + if (isettings>=minsettings && isettings<=maxsettings) { switch (isettings) { case STANDARD: ssettings="/standard"; @@ -2382,10 +2416,26 @@ int slsDetector::setThresholdEnergy(int e_eV, int imod, detectorSettings isetti ssettings="/highgain"; thisDetector->currentSettings=HIGHGAIN; break; + case DYNAMICGAIN: + ssettings="/dynamicgain"; + thisDetector->currentSettings=DYNAMICGAIN; + break; + case GAIN1: + ssettings="/gain1"; + thisDetector->currentSettings=GAIN1; + break; + case GAIN2: + ssettings="/gain2"; + thisDetector->currentSettings=GAIN2; + break; + case GAIN3: + ssettings="/gain3"; + thisDetector->currentSettings=GAIN3; + break; default: std::cout<< "Unknown settings!" << std::endl; } - + if (imod<0) { modmi=0; // modma=thisDetector->nModMax[X]*thisDetector->nModMax[Y]; @@ -2396,31 +2446,46 @@ int slsDetector::setThresholdEnergy(int e_eV, int imod, detectorSettings isetti ostringstream ostfn, oscfn; myMod->module=im; //create file names - ostfn << thisDetector->trimDir << ssettings <<"/noise.sn" << setfill('0') << setw(3) << hex << getId(MODULE_SERIAL_NUMBER, im) << setbase(10); - oscfn << thisDetector->calDir << ssettings << "/calibration.sn" << setfill('0') << setw(3) << hex << getId(MODULE_SERIAL_NUMBER, im) << setbase(10); - // - trimfname=ostfn.str(); -#ifdef VERBOSE - cout << trimfname << endl; -#endif - if (readTrimFile(trimfname,myMod)) { + switch(thisDetector->myDetectorType){ + case GOTTHARD: + ostfn << thisDetector->settingsDir << ssettings <<"/settings.sn";// << setfill('0') << setw(3) << hex << getId(MODULE_SERIAL_NUMBER, im) << setbase(10); + oscfn << thisDetector->calDir << ssettings << "/calibration.sn";// << setfill('0') << setw(3) << hex << getId(MODULE_SERIAL_NUMBER, im) << setbase(10); + std::cout<< thisDetector->settingsDir<calDir <settingsDir << ssettings <<"/noise.sn" << setfill('0') << setw(3) << hex << getId(MODULE_SERIAL_NUMBER, im) << setbase(10); + oscfn << thisDetector->calDir << ssettings << "/calibration.sn" << setfill('0') << setw(3) << hex << getId(MODULE_SERIAL_NUMBER, im) << setbase(10); + } + //oscfn << thisDetector->calDir << ssettings << "/calibration.sn" << setfill('0') << setw(3) << hex << getId(MODULE_SERIAL_NUMBER, im) << setbase(10); + + settingsfname=ostfn.str(); + //#ifdef VERBOSE + cout << "the settings name is "<gain, myMod->offset); setModule(*myMod); } else { ostringstream ostfn,oscfn; - ostfn << thisDetector->trimDir << ssettings << ssettings << ".trim"; + switch(thisDetector->myDetectorType){ + case GOTTHARD: + ostfn << thisDetector->settingsDir << ssettings << ssettings << ".settings"; + break; + default: + ostfn << thisDetector->settingsDir << ssettings << ssettings << ".trim"; + } oscfn << thisDetector->calDir << ssettings << ssettings << ".cal"; calfname=oscfn.str(); - trimfname=ostfn.str(); + settingsfname=ostfn.str(); #ifdef VERBOSE - cout << trimfname << endl; - cout << calfname << endl; + cout << settingsfname << endl; + cout << calfname << endl; #endif - if (readTrimFile(trimfname,myMod)) { + if (readSettingsFile(settingsfname,myMod)) { calfname=oscfn.str(); readCalibrationFile(calfname,myMod->gain, myMod->offset); setModule(*myMod); @@ -2429,18 +2494,23 @@ int slsDetector::setThresholdEnergy(int e_eV, int imod, detectorSettings isetti } } deleteModule(myMod); + /* if (thisDetector->correctionMask&(1<-1 && isett<3) { thisDetector->tDead=t[isett]; - } + } } - + */ return getSettings(imod); }; + + + + // Acquisition functions /* change these funcs accepting also ok/fail */ @@ -3698,8 +3768,7 @@ int slsDetector::exitServer(){ int retval; int fnum=F_EXIT_SERVER; - - + if (thisDetector->onlineFlag==ONLINE_FLAG) { if (controlSocket) { controlSocket->Connect(); @@ -3708,12 +3777,13 @@ int slsDetector::exitServer(){ controlSocket->Disconnect(); } } - if (retval==OK) { + if (retval!=OK) { std::cout<< std::endl; std::cout<< "Shutting down the server" << std::endl; std::cout<< std::endl; } return retval; + }; diff --git a/slsDetectorSoftware/slsDetector/slsDetector.h b/slsDetectorSoftware/slsDetector/slsDetector.h index 323d03ff6..7f5e46f7a 100644 --- a/slsDetectorSoftware/slsDetector/slsDetector.h +++ b/slsDetectorSoftware/slsDetector/slsDetector.h @@ -160,8 +160,8 @@ typedef struct sharedSlsDetector { detectorType myDetectorType; - /** path of the trimbits files */ - char trimDir[MAX_STR_LENGTH]; + /** path of the trimbits/settings files */ + char settingsDir[MAX_STR_LENGTH]; /** path of the calibration files */ char calDir[MAX_STR_LENGTH]; /** number of energies at which the detector has been trimmed (unused) */ @@ -253,7 +253,7 @@ typedef struct sharedSlsDetector { /* detector setup - not needed */ /** name root of the output files */ - char trimFile[MAX_STR_LENGTH]; + char settingsFile[MAX_STR_LENGTH]; /** detector settings (standard, fast, etc.) */ detectorSettings currentSettings; /** detector threshold (eV) */ @@ -322,6 +322,7 @@ typedef struct sharedSlsDetector { \returns 1 if the detector structure has already be initlialized, 0 otherwise */ int exists() {return thisDetector->alreadyExisting;}; + /** Purely virtual function Should be implemented in the specific detector class @@ -378,10 +379,10 @@ typedef struct sharedSlsDetector { /* I/O */ - /** returns the detector trimbit directory \sa sharedSlsDetector */ - char* getTrimDir() {return thisDetector->trimDir;}; - /** sets the detector trimbit directory \sa sharedSlsDetector */ - char* setTrimDir(string s) {sprintf(thisDetector->trimDir, s.c_str()); return thisDetector->trimDir;}; + /** returns the detector trimbit/settings directory \sa sharedSlsDetector */ + char* getSettingsDir() {return thisDetector->settingsDir;}; + /** sets the detector trimbit/settings directory \sa sharedSlsDetector */ + char* setSettingsDir(string s) {sprintf(thisDetector->settingsDir, s.c_str()); return thisDetector->settingsDir;}; /** returns the number of trim energies and their value \sa sharedSlsDetector \param point to the array that will contain the trim energies (in ev) \returns number of trim energies @@ -404,49 +405,49 @@ typedef struct sharedSlsDetector { /** Pure virtual function - reads a trim file + reads a trim/settings file \param fname name of the file to be read \param myMod pointer to the module structure which has to be set.
If it is NULL a new module structure will be created \returns the pointer to myMod or NULL if reading the file failed - \sa mythenDetector::readTrimFile + \sa mythenDetector::readSettingsFile */ - virtual sls_detector_module* readTrimFile(string fname, sls_detector_module* myMod=NULL)=0; + virtual sls_detector_module* readSettingsFile(string fname, sls_detector_module* myMod=NULL)=0; /** Pure virtual function - writes a trim file + writes a trim/settings file \param fname name of the file to be written \param mod module structure which has to be written to file \returns OK or FAIL if the file could not be written - \sa ::sls_detector_module mythenDetector::writeTrimFile(string, sls_detector_module) + \sa ::sls_detector_module mythenDetector::writeSettingsFile(string, sls_detector_module) */ - virtual int writeTrimFile(string fname, sls_detector_module mod)=0; + virtual int writeSettingsFile(string fname, sls_detector_module mod)=0; /** - returns currently the loaded trimfile name + Pure virtual function + writes a trim/settings file for module number imod - the values will be read from the current detector structure + \param fname name of the file to be written + \param imod module number + \returns OK or FAIL if the file could not be written + \sa ::sls_detector_module sharedSlsDetector mythenDetector::writeSettingsFile(string, int) */ + virtual int writeSettingsFile(string fname, int imod)=0; - const char *getTrimFile(){\ - string s(thisDetector->trimFile); \ + + /** + returns currently the loaded trimfile/settingsfile name + */ + const char *getSettingsFile(){\ + string s(thisDetector->settingsFile); \ if (s.length()>6) {\ if (s.substr(s.length()-6,3)==string(".sn") && s.substr(s.length()-3)!=string("xxx") ) \ return s.substr(0,s.length()-6).c_str(); \ } \ - return thisDetector->trimFile;\ + return thisDetector->settingsFile;\ }; - /** - Pure virtual function - writes a trim file for module number imod - the values will be read from the current detector structure - \param fname name of the file to be written - \param imod module number - \returns OK or FAIL if the file could not be written - \sa ::sls_detector_module sharedSlsDetector mythenDetector::writeTrimFile(string, int) - */ - virtual int writeTrimFile(string fname, int imod)=0; - /** sets the default output files path \sa sharedSlsDetector @@ -899,7 +900,7 @@ typedef struct sharedSlsDetector { \param imod module number (-1 all) \returns current settings - in this function trimbits and calibration files are searched in the trimDir and calDir directories and the detector is initialized + in this function trimbits/settings and calibration files are searched in the settingsDir and calDir directories and the detector is initialized */ virtual detectorSettings setSettings(detectorSettings isettings, int imod=-1); diff --git a/slsDetectorSoftware/usersFunctions/usersFunctions.c b/slsDetectorSoftware/usersFunctions/usersFunctions.c index f0cdbec12..c7d7d4ac4 100644 --- a/slsDetectorSoftware/usersFunctions/usersFunctions.c +++ b/slsDetectorSoftware/usersFunctions/usersFunctions.c @@ -2,6 +2,142 @@ #include #include + +#ifdef EPICS + +#include +#include + +static double timeout = 3.0; + +/* connect to a PV */ +int connect_channel(const char *name, chid *ch_id) { + int status = ECA_NORMAL; + status = ca_create_channel(name, NULL, NULL, CA_PRIORITY_DEFAULT, ch_id); + if (status != ECA_NORMAL) + return status; + + status = ca_pend_io(timeout); + return status; +} + +/* disconnect to a PV */ +int disconnect_channel(chid ch_id) +{ + ca_clear_channel(ch_id); + ca_flush_io(); +} + +int caget(chid ch_id, double *value) { + + int status = ECA_NORMAL; + + status = ca_get(DBR_DOUBLE, ch_id, value); + if (status != ECA_NORMAL) { + return status; + } + + status = ca_pend_io(timeout); + if (status != ECA_NORMAL) { + return status; + } + + return status; +} + +int caputq(chid ch_id, double value) { + // does not wait! + int status = ECA_NORMAL; + + status = ca_put(DBR_DOUBLE, ch_id, &value); + if (status != ECA_NORMAL) + return status; + + status = ca_pend_io(timeout); + if (status != ECA_NORMAL) { + return status; + } + + return status; +} + +void put_callback(struct event_handler_args args) +{ + epicsEventId eid = (epicsEventId)args.usr; + epicsEventSignal(eid); +} + +int caput(chid ch_id, double value) { + + // waits! + int status = ECA_NORMAL; + epicsEventId eid = epicsEventCreate(epicsEventEmpty); + + status = ca_put_callback(DBR_DOUBLE, + ch_id, + &value, + put_callback, + eid); + status = ca_pend_io(timeout); + if (status != ECA_NORMAL) + return status; + + if (epicsEventWait(eid) != epicsEventWaitOK) + status = ECA_TIMEOUT; + + return status; +} + +/* int main(int argc, char *argv[]) { */ +/* double value = 256; */ +/* /\* channel name *\/ */ +/* const char *name = "ARIDI-PCT:CURRENT"; */ +/* /\* channel id *\/ */ +/* chid ch_id; */ +/* /\* status code *\/ */ +/* int status; */ + +/* /\* init channel access context before any caget/put *\/ */ +/* ca_context_create(ca_enable_preemptive_callback); */ + +/* /\* open the channel by name and return ch_id *\/ */ +/* status = connect_channel(name, &ch_id); */ +/* if (status == ECA_NORMAL) */ +/* printf("channel connected %s\n", name); */ +/* else { */ +/* printf(ca_message(status)); */ +/* return -1; */ +/* } */ +/* /\* caput and wait until done *\/ */ +/* if ((status = caput(ch_id, value)) == ECA_NORMAL) */ +/* printf("caput: success\n"); */ +/* else */ +/* printf(ca_message(status)); */ + +/* /\* caget *\/ */ +/* if (caget(ch_id, &value) == ECA_NORMAL) */ +/* printf("caget: %f\n", value); */ +/* else */ +/* printf(ca_message(status)); */ + +/* /\* close channel connect *\/ */ +/* disconnect_channel(ch_id); */ + +/* /\* delete channel access context before program exits *\/ */ +/* ca_context_destroy(); */ +/* } */ + + + +#endif + + + + + + + + float pos; float i0=0; diff --git a/slsDetectorSoftware/usersFunctions/usersFunctions.h b/slsDetectorSoftware/usersFunctions/usersFunctions.h index ee0bcd98c..67b5ac935 100644 --- a/slsDetectorSoftware/usersFunctions/usersFunctions.h +++ b/slsDetectorSoftware/usersFunctions/usersFunctions.h @@ -9,11 +9,27 @@ Functions depending on the experimental setup should be defined here #define PI 3.14159265358979323846 +#ifdef EPICS +#include +#include +#endif + #ifdef __cplusplus extern "C" { #endif +#ifdef EPICS + int connect_channel(const char *name, chid *ch_id); + int disconnect_channel(chid ch_id); + int caget(chid ch_id, double *value); + int caputq(chid ch_id, double value); + void put_callback(struct event_handler_args args); + int caput(chid ch_id, double value); + +#endif + + float angle(int ichan, float encoder, float totalOffset, float conv_r, float center, float offset, float tilt, int direction); float get_position(); int go_to_position(float p);