From 848305f9ac567094329ce02e89b9222912fe691f Mon Sep 17 00:00:00 2001 From: bergamaschi Date: Thu, 3 Nov 2011 13:51:26 +0000 Subject: [PATCH] most methods moved to slsDetector (instead of mythen and gotthard) and connect/disconnect method added to users functions (to possibly comply with epics) - mutex added to the acquisition and data processing threads to avoid wrong indexes. git-svn-id: file:///afs/psi.ch/project/sls_det_software/svn/slsDetectorSoftware@38 951219d9-93cf-4727-9268-0efd64621fa3 --- .../mythenDetector/mythenDetector.cpp | 2466 --------------- .../mythenDetector/mythenDetector.h | 177 -- .../slsDetector/slsDetector.cpp | 2680 ++++++++++++++++- slsDetectorSoftware/slsDetector/slsDetector.h | 160 +- .../usersFunctions/usersFunctions.c | 2 + .../usersFunctions/usersFunctions.h | 3 + 6 files changed, 2757 insertions(+), 2731 deletions(-) diff --git a/slsDetectorSoftware/mythenDetector/mythenDetector.cpp b/slsDetectorSoftware/mythenDetector/mythenDetector.cpp index b75bfc8cf..49d22ec9c 100644 --- a/slsDetectorSoftware/mythenDetector/mythenDetector.cpp +++ b/slsDetectorSoftware/mythenDetector/mythenDetector.cpp @@ -6,1553 +6,6 @@ //using namespace std; -string mythenDetector::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=="standard") - sett=STANDARD; - else if (sval=="fast") - sett=FAST; - else if (sval=="highgain") - sett=HIGHGAIN; - 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=="vthreshold") { - if (action==PUT_ACTION) { - sscanf(args[1],"%f",&fval); - setDAC(fval, THRESHOLD); - } - sprintf(answer,"%f",setDAC(-1,THRESHOLD)); - return string(answer); - } else if (var=="vcalibration") { - if (action==PUT_ACTION) { - sscanf(args[1],"%f",&fval); - setDAC(fval, CALIBRATION_PULSE); - } - sprintf(answer,"%f",setDAC(-1,CALIBRATION_PULSE)); - return string(answer); - } else if (var=="vtrimbit") { - if (action==PUT_ACTION) { - sscanf(args[1],"%f",&fval); - setDAC(fval, TRIMBIT_SIZE); - } - sprintf(answer,"%f",setDAC(-1,TRIMBIT_SIZE)); - return string(answer); - } else if (var=="vpreamp") { - if (action==PUT_ACTION) { - sscanf(args[1],"%f",&fval); - setDAC(fval, PREAMP); - } - sprintf(answer,"%f",setDAC(-1,PREAMP)); - return string(answer); - } else if (var=="vshaper1") { - if (action==PUT_ACTION) { - sscanf(args[1],"%f",&fval); - setDAC(fval, SHAPER1); - } - sprintf(answer,"%f",setDAC(-1,SHAPER1)); - return string(answer); - } else if (var=="vshaper2") { - if (action==PUT_ACTION) { - sscanf(args[1],"%f",&fval); - setDAC(fval, SHAPER2); - } - sprintf(answer,"%f",setDAC(-1,SHAPER2)); - return string(answer); - } else if (var=="vhighvoltage") { - if (action==PUT_ACTION) { - sscanf(args[1],"%f",&fval); - setDAC(fval, HV_POT); - } - sprintf(answer,"%f",setDAC(-1,HV_POT)); - return string(answer); - } else if (var=="vapower") { - if (action==PUT_ACTION) { - sscanf(args[1],"%f",&fval); - setDAC(fval, VA_POT); - } - sprintf(answer,"%f",setDAC(-1,VA_POT)); - return string(answer); - } else if (var=="vddpower") { - if (action==PUT_ACTION) { - sscanf(args[1],"%f",&fval); - setDAC(fval, VDD_POT); - } - sprintf(answer,"%f",setDAC(-1,VDD_POT)); - return string(answer); - } else if (var=="vshpower") { - if (action==PUT_ACTION) { - sscanf(args[1],"%f",&fval); - setDAC(fval, VSH_POT); - } - sprintf(answer,"%f",setDAC(-1,VSH_POT)); - return string(answer); - } else if (var=="viopower") { - if (action==PUT_ACTION) { - sscanf(args[1],"%f",&fval); - setDAC(fval, VIO_POT); - } - sprintf(answer,"%f",setDAC(-1,VIO_POT)); - 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=="trimbits") { - if (narg>=2) { - int nm=setNumberOfModules(GET_FLAG,X)*setNumberOfModules(GET_FLAG,Y); - sls_detector_module *myMod=NULL; - sval=string(args[1]); - std::cout<< " trimfile " << sval << std::endl; - - for (int im=0; immodule=im; - setModule(*myMod); - deleteModule(myMod); - } //else cout << "myMod NULL" << endl; - } - } - } - std::cout<< "Returning trimfile " << 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; imcorrectionMask&=~(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 mythenDetector::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 mythenDetector::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 mythenDetector:: 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" - return 0; -} - -int mythenDetector::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 mythenDetector::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 mythenDetector::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* mythenDetector::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 mythenDetector::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) { - mythenDetector *myDet=(mythenDetector*)n; - myDet->processData(1); - pthread_exit(NULL); - -} - -void* startProcessDataNoDelete(void *n) { - //void* processData(void *n) { - mythenDetector *myDet=(mythenDetector*)n; - myDet->processData(0); - pthread_exit(NULL); - -} - -runStatus mythenDetector::getRunStatus(){ - int fnum=F_GET_RUN_STATUS; - int ret=FAIL; - char mess[100]; - runStatus retval=ERROR; -#ifdef VERBOSE - std::cout<< "MYTHEN 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 mythenDetector::getTimeLeft(timerIndex index){ - - - int fnum=F_GET_TIME_LEFT; - int64_t retval; - char mess[100]; - int ret=OK; - -#ifdef VERBOSE - std::cout<< "MYTHEN 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 mythenDetector::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 mythenDetector::getPositions(float *pos){ - if (pos ) { - for (int ip=0; ipnumberOfPositions; ip++) - pos[ip]=thisDetector->detPositions[ip]; - } - setTotalProgress(); - - - return thisDetector->numberOfPositions; -}; - - - diff --git a/slsDetectorSoftware/mythenDetector/mythenDetector.h b/slsDetectorSoftware/mythenDetector/mythenDetector.h index cd68fe9a3..fc6f1b7af 100644 --- a/slsDetectorSoftware/mythenDetector/mythenDetector.h +++ b/slsDetectorSoftware/mythenDetector/mythenDetector.h @@ -37,27 +37,6 @@ class mythenDetector : public slsDetector{ 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 - \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}; /** @@ -175,164 +154,8 @@ enum {GET_ACTION, PUT_ACTION, READOUT_ACTION}; 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(); - - 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/slsDetector/slsDetector.cpp b/slsDetectorSoftware/slsDetector/slsDetector.cpp index 36968a5dc..0ce879b8a 100644 --- a/slsDetectorSoftware/slsDetector/slsDetector.cpp +++ b/slsDetectorSoftware/slsDetector/slsDetector.cpp @@ -135,10 +135,20 @@ slsDetector::slsDetector(detectorType type, int id): /**Initializes the detector stucture \sa initializeDetectorSize */ initializeDetectorSize(type); - + + + + + pthread_mutex_t mp1 = PTHREAD_MUTEX_INITIALIZER; + + mp=mp1; + + pthread_mutex_init(&mp, NULL); + } +slsDetector::~slsDetector(){}; int slsDetector::initializeDetectorSize(detectorType type) { char *goff; @@ -2598,34 +2608,34 @@ int slsDetector::startReadOut(){ }; - -/*int slsDetector::getRunStatus(){ +runStatus slsDetector::getRunStatus(){ int fnum=F_GET_RUN_STATUS; - int retval; int ret=FAIL; char mess[100]; + runStatus retval=ERROR; #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 (stopSocket) { + if (stopSocket->Connect()>=0) { + stopSocket->SendDataOnly(&fnum,sizeof(fnum)); + stopSocket->ReceiveDataOnly(&ret,sizeof(ret)); if (ret!=OK) { - controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + stopSocket->ReceiveDataOnly(mess,sizeof(mess)); std::cout<< "Detector returned error: " << mess << std::endl; - } else - controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); - controlSocket->Disconnect(); + } else { + stopSocket->ReceiveDataOnly(&retval,sizeof(retval)); + } + stopSocket->Disconnect(); } } } return retval; - + }; -*/ + int* slsDetector::readFrame(){ @@ -2681,9 +2691,9 @@ int* slsDetector::getDataFromDetector(){ } else { n=controlSocket->ReceiveDataOnly(retval,thisDetector->dataBytes); - //#ifdef VERBOSE +#ifdef VERBOSE std::cout<< "Received "<< n << " data bytes" << std::endl; - //#endif +#endif if (n!=thisDetector->dataBytes) { std::cout<< "wrong data size received: received " << n << " but expected " << thisDetector->dataBytes << std::endl; thisDetector->stoppedFlag=1; @@ -2714,7 +2724,9 @@ int* slsDetector::readAll(){ while ((retval=getDataFromDetector())){ i++; #ifdef VERBOSE - // std::cout<< i << std::endl; + std::cout<< i << std::endl; +#else + std::cout << "-" ; #endif dataQueue.push(retval); } @@ -2724,6 +2736,8 @@ int* slsDetector::readAll(){ } #ifdef VERBOSE std::cout<< "received "<< i<< " frames" << std::endl; +#else + std::cout << std::endl; #endif return dataQueue.front(); // check what we return! @@ -2737,16 +2751,20 @@ int* slsDetector::startAndReadAll(){ startAndReadAllNoWait(); while ((retval=getDataFromDetector())){ i++; - //#ifdef VERBOSE +#ifdef VERBOSE std::cout<< i << std::endl; - //#endif +#else + std::cout<< "-" ; +#endif dataQueue.push(retval); } controlSocket->Disconnect(); - //#ifdef VERBOSE - std::cout<< "recieved "<< i<< " frames" << std::endl; - //#endif +#ifdef VERBOSE + std::cout<< "received "<< i<< " frames" << std::endl; +#else + std::cout << std::endl; +#endif return dataQueue.front(); // check what we return! /* while ((retval=getDataFromDetectorNoWait())) i++; @@ -3062,19 +3080,19 @@ int64_t slsDetector::getTimeLeft(timerIndex index){ // } // } 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(); - } + 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 @@ -4192,19 +4210,6 @@ int slsDetector::getScanSteps(int iscan, float *v) { setTotalProgress(); - - - - - - - - - - - - - if (thisDetector->scanMode[iscan]) return thisDetector->nScanSteps[iscan]; else @@ -4228,6 +4233,1513 @@ int slsDetector::getScanPrecision(int iscan){ +string slsDetector::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 i is module number"); + istringstream vvstr(var.substr(13)); + vvstr >> ival; + if (vvstr.fail()) + return string("syntax is modulenumber:i where i 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]); + switch(thisDetector->myDetectorType) { + + case MYTHEN: + case EIGER: + if (sval=="standard") + sett=STANDARD; + else if (sval=="fast") + sett=FAST; + else if (sval=="highgain") + sett=HIGHGAIN; + else { + sprintf(answer,"%s not defined for this detector",sval.c_str()); + return string(answer); + } + break; + + case GOTTHARD: + case AGIPD: + 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); + } + break; + + default: + 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); + } + + /* MYTHEN POTS */ + else if (var=="vthreshold") { + if (action==PUT_ACTION) { + sscanf(args[1],"%f",&fval); + setDAC(fval, THRESHOLD); + } + sprintf(answer,"%f",setDAC(-1,THRESHOLD)); + return string(answer); + } else if (var=="vcalibration") { + if (action==PUT_ACTION) { + sscanf(args[1],"%f",&fval); + setDAC(fval, CALIBRATION_PULSE); + } + sprintf(answer,"%f",setDAC(-1,CALIBRATION_PULSE)); + return string(answer); + } else if (var=="vtrimbit") { + if (action==PUT_ACTION) { + sscanf(args[1],"%f",&fval); + setDAC(fval, TRIMBIT_SIZE); + } + sprintf(answer,"%f",setDAC(-1,TRIMBIT_SIZE)); + return string(answer); + } else if (var=="vpreamp") { + if (action==PUT_ACTION) { + sscanf(args[1],"%f",&fval); + setDAC(fval, PREAMP); + } + sprintf(answer,"%f",setDAC(-1,PREAMP)); + return string(answer); + } else if (var=="vshaper1") { + if (action==PUT_ACTION) { + sscanf(args[1],"%f",&fval); + setDAC(fval, SHAPER1); + } + sprintf(answer,"%f",setDAC(-1,SHAPER1)); + return string(answer); + } else if (var=="vshaper2") { + if (action==PUT_ACTION) { + sscanf(args[1],"%f",&fval); + setDAC(fval, SHAPER2); + } + sprintf(answer,"%f",setDAC(-1,SHAPER2)); + return string(answer); + } else if (var=="vhighvoltage") { + if (action==PUT_ACTION) { + sscanf(args[1],"%f",&fval); + setDAC(fval, HV_POT); + } + sprintf(answer,"%f",setDAC(-1,HV_POT)); + return string(answer); + } else if (var=="vapower") { + if (action==PUT_ACTION) { + sscanf(args[1],"%f",&fval); + setDAC(fval, VA_POT); + } + sprintf(answer,"%f",setDAC(-1,VA_POT)); + return string(answer); + } else if (var=="vddpower") { + if (action==PUT_ACTION) { + sscanf(args[1],"%f",&fval); + setDAC(fval, VDD_POT); + } + sprintf(answer,"%f",setDAC(-1,VDD_POT)); + return string(answer); + } else if (var=="vshpower") { + if (action==PUT_ACTION) { + sscanf(args[1],"%f",&fval); + setDAC(fval, VSH_POT); + } + sprintf(answer,"%f",setDAC(-1,VSH_POT)); + return string(answer); + } else if (var=="viopower") { + if (action==PUT_ACTION) { + sscanf(args[1],"%f",&fval); + setDAC(fval, VIO_POT); + } + sprintf(answer,"%f",setDAC(-1,VIO_POT)); + return string(answer); + } + /* GOTTHARD POTS */ +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=="now") { + if (action==PUT_ACTION) { + sprintf(answer,"Cannot set\n"); + } else + sprintf(answer,"%0.9f",(float)getTimeLeft(ACTUAL_TIME)*1E-9); + //sprintf(answer,"%x",getTimeLeft(ACTUAL_TIME)); + return string(answer); + } else if (var=="timestamp") { + if (action==PUT_ACTION) { + sprintf(answer,"Cannot set\n"); + } else + sprintf(answer,"%0.9f",(float)getTimeLeft(MEASUREMENT_TIME)*1E-9); + //sprintf(answer,"%x",getTimeLeft(MEASUREMENT_TIME)); + 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=="trimbits") { + if (narg>=2) { + int nm=setNumberOfModules(GET_FLAG,X)*setNumberOfModules(GET_FLAG,Y); + sls_detector_module *myMod=NULL; + sval=string(args[1]); + std::cout<< " trimfile " << sval << std::endl; + + for (int im=0; immodule=im; + setModule(*myMod); + deleteModule(myMod); + } //else cout << "myMod NULL" << endl; + } + } + } + std::cout<< "Returning trimfile " << 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; imcorrectionMask&=~(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 slsDetector::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 slsDetector::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 slsDetector:: 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" + return 0; +} + +int slsDetector::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 slsDetector::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 slsDetector::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=thisDetector->fileIndex; + char cmd[MAX_STR_LENGTH]; + int nowindex=thisDetector->fileIndex; + string fn; + + + //string sett; + if ((thisDetector->correctionMask&(1<< ANGULAR_CONVERSION)) || (thisDetector->correctionMask&(1<< I0_NORMALIZATION))) + connect_channels(); + + + + + thisDetector->progressIndex=0; + thisDetector->stoppedFlag=0; + + + + resetFinalDataQueue(); + resetDataQueue(); + + + //cout << "main mutex lock line 6188" << endl; + pthread_mutex_lock(&mp); + jointhread=0; + queuesize=0; + pthread_mutex_unlock(&mp); + //cout << "main mutex unlock line 6188" << endl; + + + + + + 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") + + fn=createFileName(); + nowindex=thisDetector->fileIndex; + + 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],nowindex,fn.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 before " << 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()){ + //cout << "main mutex lock line 6372" << endl; + pthread_mutex_lock(&mp); + while (queuesize){ + pthread_mutex_unlock(&mp); + //cout << "main mutex unlock line 6375" << endl; + usleep(10000); + //cout << "main mutex lock line 6378" << endl; + pthread_mutex_lock(&mp); + } + pthread_mutex_unlock(&mp); + //cout << "main mutex unlock line 6381" << endl; + + 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], \ + nowindex, \ + fn.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); + + } + if (thisDetector->fileIndex>lastindex) + lastindex=thisDetector->fileIndex; + } else { + + + if (thisDetector->fileIndex>lastindex) + lastindex=thisDetector->fileIndex; + + 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 <<" " << thisDetector->fileIndex << std::endl ; + //#endif + //cout << "main mutex lock line 6488" << endl; + pthread_mutex_lock(&mp); + jointhread=1; + pthread_mutex_unlock(&mp); + //cout << "main mutex unlock line 6488" << endl; + pthread_join(dataProcessingThread, &status); + // std::cout<< " ***********************data processing finished " << queuesize <<" " << thisDetector->fileIndex << std::endl ; + } + + if ((thisDetector->correctionMask&(1<< ANGULAR_CONVERSION)) || (thisDetector->correctionMask&(1<< I0_NORMALIZATION))) + disconnect_channels(); +} + + +void* slsDetector::processData(int delflag) { + + + //cout << "thread mutex lock line 6505" << endl; + pthread_mutex_lock(&mp); + queuesize=dataQueue.size(); + pthread_mutex_unlock(&mp); + //cout << "thread mutex unlock line 6505" << endl; + + 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; + string fname; + + +#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() ) { + //cout << "thread mutex lock line 6539" << endl; + pthread_mutex_lock(&mp); + while((queuesize=dataQueue.size())>0) { + pthread_mutex_unlock(&mp); + //cout << "thread mutex unlock line 6543" << endl; + //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); + + fname=createFileName(); + + /** write raw data file */ + if (thisDetector->correctionMask==0 && delflag==1) { + + + writeDataFile (fname.append(".raw"), fdata, NULL, NULL, 'i'); + delete [] fdata; + } else { + writeDataFile (fname.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 (fname.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++; + fname=createFileName(); + if (thisDetector->correctionMask!=0) + writeDataFile (fname.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(),(fname.append(ext)).c_str(),np);/* + if (thisDetector->correctionMask!=0) { + //thisData=new detectorData(mergingCounts,mergingErrors,mergingBins,thisDetector->progressIndex+1,(fname().append(".dat")).c_str(),np); + thisData=new detectorData(mergingCounts,mergingErrors,mergingBins,getCurrentProgress(),(fname().append(".dat")).c_str(),np); + } else { + thisData=new detectorData(mergingCounts,mergingErrors,mergingBins,getCurrentProgress(),(fname().append(".raw")).c_str(),np); + //thisData=new detectorData(mergingCounts,mergingErrors,mergingBins,thisDetector->progressIndex+1,(fname().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 (fname.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(),(fname.append(ext)).c_str(),thisDetector->nChans*thisDetector->nChips*thisDetector->nMods);/* + if (thisDetector->correctionMask!=0) { + thisData=new detectorData(ffcdata,ffcerr,NULL,getCurrentProgress(),(fname().append(".dat")).c_str(),thisDetector->nChans*thisDetector->nChips*thisDetector->nMods); + //thisData=new detectorData(ffcdata,ffcerr,NULL,thisDetector->progressIndex+1,(fname().append(".dat")).c_str(),thisDetector->nChans*thisDetector->nChips*thisDetector->nMods); + } else { + thisData=new detectorData(ffcdata,ffcerr,NULL,getCurrentProgress(),(fname().append(".raw")).c_str(),thisDetector->nChans*thisDetector->nChips*thisDetector->nMods); + //thisData=new detectorData(ffcdata,ffcerr,NULL,thisDetector->progressIndex+1,(fname().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 + //cout << "thread mutex lock line 6697" << endl; + pthread_mutex_lock(&mp); + queuesize=dataQueue.size(); + pthread_mutex_unlock(&mp); + //cout << "thread mutex unlock line 6697" << endl; + usleep(1000); + //pthread_mutex_unlock(&mp); + } + pthread_mutex_unlock(&mp); + //cout << "thread mutex unlock line 6706" << endl; + usleep(1000); + // cout << "PPPPPPPPPPPPPPPPPPPP " << queuesize << " " << thisDetector->fileIndex << endl; + } + pthread_mutex_unlock(&mp); + //cout << "thread mutex unlock line 6711" << endl; + //cout << "thread mutex lock line 6711" << endl; + pthread_mutex_lock(&mp); + if (jointhread) { + pthread_mutex_unlock(&mp); + //cout << "thread mutex unlock line 6715" << endl; + if (dataQueue.size()==0) + break; + } else + pthread_mutex_unlock(&mp); + //cout << "thread mutex unlock line 6720" << endl; + + dum=0; + } // ???????????????????????? + return 0; +} + + + +void slsDetector::startThread(int delflag) { + pthread_attr_t tattr; int ret; - int newprio; sched_param param, mparam; - void *arg; int policy= SCHED_OTHER; - ret = pthread_attr_init(&tattr); // set the priority; others are unchanged //newprio = 30; - mparam.sched_priority = 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); - - - printf("current priority is %d\n",param.sched_priority); - ret = pthread_create(&dataProcessingThread, NULL,startProcessData, (void*)this); - - - param.sched_priority = 1; - // scheduling parameters of target thread + //#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) { - void *w; + slsDetector *myDet=(slsDetector*)n; + myDet->processData(1); + pthread_exit(NULL); + +} + +void* startProcessDataNoDelete(void *n) { + //void* processData(void *n) { slsDetector *myDet=(slsDetector*)n; myDet->processData(0); + pthread_exit(NULL); + } + + + + + + /* + set positions for the acquisition + \param nPos number of positions + \param pos array with the encoder positions + \returns number of positions + */ +int slsDetector::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 slsDetector::getPositions(float *pos){ + if (pos ) { + for (int ip=0; ipnumberOfPositions; ip++) + pos[ip]=thisDetector->detPositions[ip]; + } + setTotalProgress(); + + + return thisDetector->numberOfPositions; +} + + + + diff --git a/slsDetectorSoftware/slsDetector/slsDetector.h b/slsDetectorSoftware/slsDetector/slsDetector.h index 7f5e46f7a..68a068a4e 100644 --- a/slsDetectorSoftware/slsDetector/slsDetector.h +++ b/slsDetectorSoftware/slsDetector/slsDetector.h @@ -312,7 +312,7 @@ typedef struct sharedSlsDetector { //slsDetector(string const fname); // ~slsDetector(){while(dataQueue.size()>0){}}; /** destructor */ - virtual ~slsDetector(){}; + virtual ~slsDetector();//{ disconnect_channels();}; /** sets the onlineFlag @@ -348,13 +348,13 @@ typedef struct sharedSlsDetector { Should be implemented in the specific detector class /sa mythenDetector::dumpDetectorSetup */ - virtual int dumpDetectorSetup(string const fname, int level)=0; + virtual int dumpDetectorSetup(string const fname, int level=0)=0; /** Purely virtual function Should be implemented in the specific detector class /sa mythenDetector::retrieveDetectorSetup */ - virtual int retrieveDetectorSetup(string const fname, int level)=0; + virtual int retrieveDetectorSetup(string const fname, int level=0)=0; /** configure the socket communication and initializes the socket instances @@ -587,14 +587,14 @@ typedef struct sharedSlsDetector { \param fname file to be read \sa angleConversionConstant mythenDetector::readAngularConversion */ - virtual int readAngularConversion(string fname="")=0; + int readAngularConversion(string fname=""); /** Pure virtual function writes an angular conversion file \param fname file to be written \sa angleConversionConstant mythenDetector::writeAngularConversion */ - virtual int writeAngularConversion(string fname="")=0; + int writeAngularConversion(string fname=""); /** Returns the number of channels per chip */ int getNChans(){return thisDetector->nChans;}; // @@ -930,7 +930,8 @@ typedef struct sharedSlsDetector { get run status \returns status mask */ - virtual runStatus getRunStatus()=0; + //virtual runStatus getRunStatus()=0; + runStatus getRunStatus(); /** start detector acquisition and read all data putting them a data queue @@ -1161,7 +1162,7 @@ s \returns 0 if angular conversion disabled, >0 otherwise \sa mythenDetector::setAngularConversion */ - virtual int setAngularConversion(string fname="")=0; + int setAngularConversion(string fname=""); /** pure virtual function @@ -1171,41 +1172,41 @@ s \returns 0 if angular conversion disabled, >0 otherwise \sa mythenDetector::getAngularConversion */ - virtual int getAngularConversion(int &direction, angleConversionConstant *angconv=NULL)=0; + int getAngularConversion(int &direction, angleConversionConstant *angconv=NULL) ; /** pure virtual function returns the angular conversion file \sa mythenDetector::getAngularConversion */ - virtual string getAngularConversion()=0; + string getAngularConversion(){if (thisDetector->correctionMask&(1<< ANGULAR_CONVERSION)) return string(thisDetector->angConvFile); else return string("none");}; /** pure virtual function set detector global offset \sa mythenDetector::setGlobalOffset */ - virtual float setGlobalOffset(float f)=0; + float setGlobalOffset(float f){thisDetector->globalOffset=f; return thisDetector->globalOffset;}; /** pure virtual function set detector fine offset \sa mythenDetector::setFineOffset */ - virtual float setFineOffset(float f)=0; + float setFineOffset(float f){thisDetector->fineOffset=f; return thisDetector->fineOffset;}; /** pure virtual function get detector fine offset \sa mythenDetector::getFineOffset */ - virtual float getFineOffset()=0; + float getFineOffset(){return thisDetector->fineOffset;}; /** pure virtual function get detector global offset \sa mythenDetector::getGlobalOffset */ - virtual float getGlobalOffset()=0; + float getGlobalOffset(){return thisDetector->globalOffset;}; /** pure virtual function @@ -1215,7 +1216,7 @@ s \returns number of positions \sa mythenDetector::setPositions */ - virtual int setPositions(int nPos, float *pos)=0; + int setPositions(int nPos, float *pos); /** pure virtual function get positions for the acquisition @@ -1223,7 +1224,7 @@ s \returns number of positions \sa mythenDetector::getPositions */ - virtual int getPositions(float *pos=NULL)=0; + int getPositions(float *pos=NULL); /** pure virtual function @@ -1232,13 +1233,13 @@ s \returns current bin size \sa mythenDetector::setBinSize */ - virtual float setBinSize(float bs)=0; + float setBinSize(float bs){thisDetector->binSize=bs; return thisDetector->binSize;}; /** pure virtual function return detector bin size used for merging (approx angular resolution) \sa mythenDetector::getBinSize */ - virtual float getBinSize()=0; + float getBinSize() {return thisDetector->binSize;}; @@ -1412,7 +1413,7 @@ s \returns OK or FAIL \sa mythenDetector::resetMerging */ - virtual int resetMerging(float *mp, float *mv,float *me, int *mm)=0; + int resetMerging(float *mp, float *mv,float *me, int *mm); /** pure virtual function merge dataset @@ -1425,7 +1426,7 @@ s \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; + int addToMerging(float *p1, float *v1, float *e1, float *mp, float *mv,float *me, int *mm); /** pure virtual function calculates the "final" positions, data value and errors for the emrged data @@ -1448,7 +1449,7 @@ s /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 + void* processData(int delflag=1); // thread function /** Allocates the memory for a sls_detector_module structure and initializes it \returns myMod the pointer to the allocate dmemory location @@ -1473,7 +1474,7 @@ s \sa mythenDetector::acquire() */ - virtual void acquire(int delflag=1)=0; + void acquire(int delflag=1); /** calcualtes the total number of steps of the acquisition. called when number of frames, number of cycles, number of positions and scan steps change @@ -1483,6 +1484,90 @@ s /** returns the current progress in % */ float getCurrentProgress(); + + + + /** + type of action performed (for text client) + */ +enum {GET_ACTION, PUT_ACTION, READOUT_ACTION}; + + + /** + 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); + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + protected: @@ -1660,8 +1745,41 @@ s fill bad channel mask (0 if channel is good, 1 if bad) */ int fillBadChannelMask(); + + + /** + 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; + + + + + /** mutex to synchronize threads */ + pthread_mutex_t mp; + + + + + + + + + }; +static void* startProcessData(void *n); +static void* startProcessDataNoDelete(void *n); + //static void* startProcessData(void *n); #endif diff --git a/slsDetectorSoftware/usersFunctions/usersFunctions.c b/slsDetectorSoftware/usersFunctions/usersFunctions.c index c7d7d4ac4..1dbb33ef7 100644 --- a/slsDetectorSoftware/usersFunctions/usersFunctions.c +++ b/slsDetectorSoftware/usersFunctions/usersFunctions.c @@ -198,3 +198,5 @@ float get_i0() { return i0++; } +int disconnect_channels() { } +int connect_channels() {} diff --git a/slsDetectorSoftware/usersFunctions/usersFunctions.h b/slsDetectorSoftware/usersFunctions/usersFunctions.h index 67b5ac935..0026d30fa 100644 --- a/slsDetectorSoftware/usersFunctions/usersFunctions.h +++ b/slsDetectorSoftware/usersFunctions/usersFunctions.h @@ -35,6 +35,9 @@ extern "C" { int go_to_position(float p); int go_to_position_no_wait(float p); + int connect_channels(); + int disconnect_channels(); + float get_i0();