From 584b9e6036463d1a6eea8b54a056e667165a4344 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Fri, 4 Sep 2015 15:54:12 +0200 Subject: [PATCH] added gain and offsets to the shared memory, that are sent along with sls_detector_module, only for eiger --- .../commonFiles/sls_detector_defs.h | 1 + .../eigerDetectorServer/FebControl.c | 34 +- .../eigerDetectorServer/FebControl.h | 2 - .../bin/eigerDetectorServer | Bin 252650 -> 251288 bytes .../slsDetectorFunctionList.c | 96 +++-- .../slsDetectorServer_defs.h | 3 + .../slsDetector/slsDetector.cpp | 407 ++++++++++++------ slsDetectorSoftware/slsDetector/slsDetector.h | 19 +- .../slsDetectorAnalysis/energyConversion.cpp | 88 ++-- .../slsDetectorAnalysis/energyConversion.h | 4 +- .../slsDetectorFunctionList.h | 14 +- .../slsDetectorServer_funcs.c | 76 +++- 12 files changed, 501 insertions(+), 243 deletions(-) diff --git a/slsDetectorSoftware/commonFiles/sls_detector_defs.h b/slsDetectorSoftware/commonFiles/sls_detector_defs.h index 29c624b8d..1c911c9d5 100755 --- a/slsDetectorSoftware/commonFiles/sls_detector_defs.h +++ b/slsDetectorSoftware/commonFiles/sls_detector_defs.h @@ -140,6 +140,7 @@ typedef struct { double offset; /**< is the module offset (V) */ } sls_detector_module; + /** @short structure for a region of interest diff --git a/slsDetectorSoftware/eigerDetectorServer/FebControl.c b/slsDetectorSoftware/eigerDetectorServer/FebControl.c index bd318d60a..b24cc374a 100644 --- a/slsDetectorSoftware/eigerDetectorServer/FebControl.c +++ b/slsDetectorSoftware/eigerDetectorServer/FebControl.c @@ -43,8 +43,6 @@ unsigned int Feb_Control_triggerMode; //internal timer, external start, unsigned int Feb_Control_externalEnableMode; //external enabling engaged and it's polarity unsigned int Feb_Control_subFrameMode; -unsigned int Feb_Control_photon_energy_eV; - unsigned int Feb_Control_nimages; double Feb_Control_exposure_time_in_sec; int Feb_Control_subframe_exposure_time_in_10nsec; @@ -450,7 +448,7 @@ int Feb_Control_AddModule1(unsigned int module_number, int top_enable, unsigned return parameters_ok; } - +/* not called anywhere**/ int Feb_Control_ReadSetUpFile(unsigned int module_num, char* file_name){ printf("Reading Setup file for module number:%d\n",module_num); char line[100]; @@ -486,14 +484,14 @@ int Feb_Control_ReadSetUpFile(unsigned int module_num, char* file_name){ } Feb_Control_SetHighVoltage(f0); } - +/* else if(!strcmp("photon_energy",str)){ if(sscanf (line,"%s %f", str,&f0) < 2){ printf("Error reading photon_energy\n"); exit(0); } Feb_Control_SetPhotonEnergy(f0); - } + }*/ else if(!strcmp("dynamic_range",str)){ if(sscanf (line,"%s %d", str,&i0) < 2){ @@ -591,32 +589,6 @@ unsigned int Feb_Control_GetNHalfModules(){ return n_half_modules; } -int Feb_Control_SetPhotonEnergy(unsigned int full_energy_eV){ - /** - - setDAC(VCMP_LL,val,imod,mV,retval); - setDAC(VCMP_LR,val,imod,mV,retval); - setDAC(VCMP_RL,val,imod,mV,retval); - ind = VCMP_RR; - */ - Feb_Control_photon_energy_eV = full_energy_eV; - printf("Setting photon energy to: %d eV\n",Feb_Control_photon_energy_eV); - - return 1; -} - -unsigned int Feb_Control_GetPhotonEnergy(){ - - /** - - setDAC(VCMP_LL,val,imod,mV,retval); - setDAC(VCMP_LR,val,imod,mV,retval); - setDAC(VCMP_RL,val,imod,mV,retval); - ind = VCMP_RR; - */ -return Feb_Control_photon_energy_eV; - -} int Feb_Control_SetIDelays(unsigned int module_num, unsigned int ndelay_units){ return Feb_Control_SetIDelays1(module_num,0,ndelay_units)&&Feb_Control_SetIDelays1(module_num,1,ndelay_units)&&Feb_Control_SetIDelays1(module_num,2,ndelay_units)&&Feb_Control_SetIDelays1(module_num,3,ndelay_units); diff --git a/slsDetectorSoftware/eigerDetectorServer/FebControl.h b/slsDetectorSoftware/eigerDetectorServer/FebControl.h index b72103e1c..3c0e62760 100644 --- a/slsDetectorSoftware/eigerDetectorServer/FebControl.h +++ b/slsDetectorSoftware/eigerDetectorServer/FebControl.h @@ -121,8 +121,6 @@ int Feb_Control_GetModuleNumber(); int Feb_Control_SetHighVoltage(float value); int Feb_Control_SetHighVoltage1(unsigned int module_num,float value); - int Feb_Control_SetPhotonEnergy(unsigned int full_energy_eV); - unsigned int Feb_Control_GetPhotonEnergy(); int Feb_Control_SetIDelays(unsigned int module_num, unsigned int ndelay_units); int Feb_Control_SetIDelays1(unsigned int module_num, unsigned int chip_pos, unsigned int ndelay_units); diff --git a/slsDetectorSoftware/eigerDetectorServer/bin/eigerDetectorServer b/slsDetectorSoftware/eigerDetectorServer/bin/eigerDetectorServer index 1a2700d2b560004430a9ec4d8e46d2a00f8f4bb0..45564168e1afacbbcec8b5ec7db322f1d95e2901 100755 GIT binary patch delta 64043 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 E04Ynbv;Y7A diff --git a/slsDetectorSoftware/eigerDetectorServer/slsDetectorFunctionList.c b/slsDetectorSoftware/eigerDetectorServer/slsDetectorFunctionList.c index 17f1889f0..edffb9be0 100644 --- a/slsDetectorSoftware/eigerDetectorServer/slsDetectorFunctionList.c +++ b/slsDetectorSoftware/eigerDetectorServer/slsDetectorFunctionList.c @@ -26,7 +26,8 @@ int *detectorChips=NULL; int *detectorChans=NULL; dacs_t *detectorDacs=NULL; dacs_t *detectorAdcs=NULL; - +int* detectorGain = NULL; +int* detectorOffset = NULL; int eiger_highvoltage = 0; int eiger_iodelay = 0; @@ -53,6 +54,8 @@ int dst_requested[32] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //char Module_dac_names[16][10]= {"SvP","Vtr","Vrf","Vrs","SvN","Vtgstv","Vcmp_ll","Vcmp_lr","cal","Vcmp_rl","rxb_rb","rxb_lb","Vcmp_rr","Vcp","Vcn","Vis"};; int default_dac_values[16] = {0,2480,3300,1400,4000,2556,1000,1000,4000,1000,1000,1000,1000,200,2000,1550}; +int default_gain_values[3] = {-314800,-314800,-314800}; +int default_offset_values[3] = {3714000,3714000,3714000}; enum masterFlags masterMode=IS_SLAVE; @@ -80,12 +83,16 @@ int initDetector(){ detectorChans=malloc(n*NCHIP*NCHAN*sizeof(int)); detectorDacs=malloc(n*NDAC*sizeof(dacs_t)); detectorAdcs=malloc(n*NADC*sizeof(dacs_t)); + detectorGain=malloc(n*NGAIN*sizeof(int)); + detectorOffset=malloc(n*NOFFSET*sizeof(int)); #ifdef VERBOSE printf("modules from 0x%x to 0x%x\n",detectorModules, detectorModules+n); printf("chips from 0x%x to 0x%x\n",detectorChips, detectorChips+n*NCHIP); printf("chans from 0x%x to 0x%x\n",detectorChans, detectorChans+n*NCHIP*NCHAN); printf("dacs from 0x%x to 0x%x\n",detectorDacs, detectorDacs+n*NDAC); printf("adcs from 0x%x to 0x%x\n",detectorAdcs, detectorAdcs+n*NADC); + printf("gains from 0x%x to 0x%x\n",detectorGain, detectorGain+n*NGAIN); + printf("offsets from 0x%x to 0x%x\n",detectorOffset, detectorOffset+n*NOFFSET); #endif for (imod=0; imoddacs=detectorDacs+imod*NDAC; @@ -102,6 +109,10 @@ int initDetector(){ (detectorModules+imod)->reg=0; /* initialize registers, dacs, retrieve sn, adc values etc */ } + for(i=0;indac;i++) setDAC((enum detDacIndex)i,default_dac_values[i],(detectorModules)->module,0,retval); - //setting default measurement parameters setTimer(FRAME_NUMBER,1); setTimer(ACQUISITION_TIME,1E9); setTimer(SUBFRAME_ACQUISITION_TIME,DEFAULT_SUBFRAME_EXPOSURE_VAL); setTimer(FRAME_PERIOD,1E9); setDynamicRange(16); - setThresholdEnergy(8000,0); + eiger_photonenergy = -1; setReadOutFlags(NONPARALLEL); setSpeed(0,1);//clk_devider,half speed setHighVolage(0,0); @@ -376,23 +386,30 @@ int enableTenGigabitEthernet(int val){ } -int setModule(sls_detector_module myMod){ +int setModule(sls_detector_module myMod, int* gain, int* offset){ int retval[2]; + int i; + //#ifdef VERBOSE printf("Setting module with settings %d\n",myMod.reg); //#endif - int i; - for(i=0;i= 0){ + eiger_photonenergy = ev; + //calculate thrvalues for dacs + for(i=0;inChip[Y]=1; thisDetector->nDacs=6; thisDetector->nAdcs=0; + thisDetector->nGain=0; + thisDetector->nOffset=0; thisDetector->nModMax[X]=24; thisDetector->nModMax[Y]=1; thisDetector->dynamicRange=24; @@ -544,6 +566,8 @@ int slsDetector::initializeDetectorSize(detectorType type) { thisDetector->nChip[Y]=1; thisDetector->nDacs=6; thisDetector->nAdcs=0; + thisDetector->nGain=0; + thisDetector->nOffset=0; thisDetector->nModMax[X]=6; thisDetector->nModMax[Y]=1; thisDetector->dynamicRange=24; @@ -555,6 +579,8 @@ int slsDetector::initializeDetectorSize(detectorType type) { thisDetector->nChip[Y]=1; thisDetector->nDacs=8; thisDetector->nAdcs=5; + thisDetector->nGain=0; + thisDetector->nOffset=0; thisDetector->nModMax[X]=1; thisDetector->nModMax[Y]=1; thisDetector->dynamicRange=16; @@ -566,6 +592,8 @@ int slsDetector::initializeDetectorSize(detectorType type) { thisDetector->nChip[Y]=1; thisDetector->nDacs=8; thisDetector->nAdcs=5; + thisDetector->nGain=0; + thisDetector->nOffset=0; thisDetector->nModMax[X]=1; thisDetector->nModMax[Y]=1; thisDetector->dynamicRange=16; @@ -577,6 +605,8 @@ int slsDetector::initializeDetectorSize(detectorType type) { thisDetector->nChip[Y]=1; thisDetector->nDacs=8; thisDetector->nAdcs=1; + thisDetector->nGain=0; + thisDetector->nOffset=0; thisDetector->nModMax[X]=1; thisDetector->nModMax[Y]=1; thisDetector->dynamicRange=16; @@ -588,6 +618,8 @@ int slsDetector::initializeDetectorSize(detectorType type) { thisDetector->nChip[Y]=1; thisDetector->nDacs=16; thisDetector->nAdcs=1; + thisDetector->nGain=0; + thisDetector->nOffset=0; thisDetector->nModMax[X]=1; thisDetector->nModMax[Y]=1; thisDetector->dynamicRange=16; @@ -599,6 +631,8 @@ int slsDetector::initializeDetectorSize(detectorType type) { thisDetector->nChip[Y]=1; thisDetector->nDacs=16; thisDetector->nAdcs=0; + thisDetector->nGain=4; + thisDetector->nOffset=4; thisDetector->nModMax[X]=1; thisDetector->nModMax[Y]=1; thisDetector->dynamicRange=16; @@ -610,6 +644,8 @@ int slsDetector::initializeDetectorSize(detectorType type) { thisDetector->nChip[Y]=0; thisDetector->nDacs=0; thisDetector->nAdcs=0; + thisDetector->nGain=0; + thisDetector->nOffset=0; thisDetector->nModMax[X]=0; thisDetector->nModMax[Y]=0; thisDetector->dynamicRange=32; @@ -725,7 +761,8 @@ int slsDetector::initializeDetectorSize(detectorType type) { thisDetector->adcoff=thisDetector->dacoff+sizeof(dacs_t)*thisDetector->nDacs*thisDetector->nModsMax; thisDetector->chipoff=thisDetector->adcoff+sizeof(dacs_t)*thisDetector->nAdcs*thisDetector->nModsMax; thisDetector->chanoff=thisDetector->chipoff+sizeof(int)*thisDetector->nChips*thisDetector->nModsMax; - + thisDetector->gainoff=thisDetector->chanoff+sizeof(int)*thisDetector->nGain*thisDetector->nModsMax; + thisDetector->offsetoff=thisDetector->gainoff+sizeof(int)*thisDetector->nOffset*thisDetector->nModsMax; //update?!?!?!? @@ -745,6 +782,8 @@ int slsDetector::initializeDetectorSize(detectorType type) { adcs=(dacs_t*)(goff+thisDetector->adcoff); chipregs=(int*)(goff+thisDetector->chipoff); chanregs=(int*)(goff+thisDetector->chanoff); + gain=(int*)(goff+thisDetector->gainoff); + offset=(int*)(goff+thisDetector->offsetoff); if (thisDetector->alreadyExisting==0) { /** if thisDetector is new, initialize its structures \sa initializeDetectorStructure(); */ initializeDetectorStructure(); @@ -864,6 +903,18 @@ int slsDetector::initializeDetectorStructure() { for (int ichan=0; ichannChans*thisDetector->nChips; ichan++) { *(chanregs+ichan+thisDetector->nChips*thisDetector->nChans*imod)=-1; } + + /** initializes the gain values to 0 */ + for (int igain=0; igainnGain; igain++) { + *(gain+igain+thisDetector->nGain*imod)=0; + } + + + /** initializes the offset values to 0 */ + for (int ioffset=0; ioffsetnOffset; ioffset++) { + *(offset+ioffset+thisDetector->nOffset*imod)=0; + } + /** initialize gain and offset to -1 */ thisMod->gain=-1.; thisMod->offset=-1.; @@ -910,7 +961,7 @@ slsDetectorDefs::sls_detector_module* slsDetector::createModule(detectorType t) nm=1; //modules/detector nc=4*1; //chips nd=16; //dacs - na=0; //use for gain???? + na=0; break; case MOENCH: nch=160*160; @@ -2554,6 +2605,8 @@ slsDetectorDefs::sls_detector_chip slsDetector::getChip(int ichip, int imod){ int slsDetector::setModule(int reg, int imod){ sls_detector_module myModule; + int* g=0; + int* o=0; #ifdef VERBOSE std::cout << "slsDetector set module " << std::endl; @@ -2622,16 +2675,14 @@ int slsDetector::setModule(int reg, int imod){ ads[i]=-1; myModule.adcs=ads; } - ret=setModule(myModule); + ret=setModule(myModule,g,o); } return ret; }; - - -int slsDetector::setModule(sls_detector_module module){ +int slsDetector::setModule(sls_detector_module module, int* gainval, int* offsetval){ int fnum=F_SET_MODULE; int retval; @@ -2649,6 +2700,13 @@ int slsDetector::setModule(sls_detector_module module){ if (connectControl() == OK){ controlSocket->SendDataOnly(&fnum,sizeof(fnum)); sendModule(&module); + + //extra gain and offset - eiger + if((thisDetector->nGain) && (gainval)) + controlSocket->SendDataOnly(gainval,sizeof(int)*thisDetector->nGain); + if((thisDetector->nOffset) && (offsetval)) + controlSocket->SendDataOnly(offsetval,sizeof(int)*thisDetector->nOffset); + controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); if (ret!=FAIL) { controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); @@ -2700,6 +2758,16 @@ int slsDetector::setModule(sls_detector_module module){ (detectorModules+imod)->reg=module.reg; } } + + if ((thisDetector->nGain) && (gainval) && (gain)) { + for (int i=0; inGain; i++) + gain[i+imod*thisDetector->nGain]=gainval[i]; + } + + if ((thisDetector->nOffset) && (offsetval) && (offset)) { + for (int i=0; inOffset; i++) + offset[i+imod*thisDetector->nOffset]=offsetval[i]; + } } #ifdef VERBOSE @@ -2709,106 +2777,131 @@ int slsDetector::setModule(sls_detector_module module){ return retval; }; + + + + slsDetectorDefs::sls_detector_module *slsDetector::getModule(int imod){ #ifdef VERBOSE - std::cout << "slsDetector get module " << std::endl; + std::cout << "slsDetector get module " << std::endl; #endif - int fnum=F_GET_MODULE; - sls_detector_module *myMod=createModule(); + int fnum=F_GET_MODULE; + sls_detector_module *myMod=createModule(); + int* gainval=0, *offsetval=0; + if(thisDetector->nGain) + gainval=new int[thisDetector->nGain]; + if(thisDetector->nOffset) + offsetval=new int[thisDetector->nOffset]; - //char *ptr, *goff=(char*)thisDetector; + //char *ptr, *goff=(char*)thisDetector; - // int chanreg[thisDetector->nChans*thisDetector->nChips]; - //int chipreg[thisDetector->nChips]; - //double dac[thisDetector->nDacs], adc[thisDetector->nAdcs]; + // int chanreg[thisDetector->nChans*thisDetector->nChips]; + //int chipreg[thisDetector->nChips]; + //double dac[thisDetector->nDacs], adc[thisDetector->nAdcs]; - int ret=FAIL; - char mess[100]; - // int n; + int ret=FAIL; + char mess[100]; + // int n; #ifdef VERBOSE - std::cout<< "getting module " << imod << std::endl; + std::cout<< "getting module " << imod << std::endl; #endif - myMod->module=imod; - // myMod.nchan=thisDetector->nChans*thisDetector->nChips; - //myMod.chanregs=chanreg; - //myMod.nchip=thisDetector->nChips; - //myMod.chipregs=chipreg; - //myMod.ndac=thisDetector->nDacs; - //myMod.dacs=dac; - //myMod.ndac=thisDetector->nAdcs; - //myMod.dacs=adc; + myMod->module=imod; + // myMod.nchan=thisDetector->nChans*thisDetector->nChips; + //myMod.chanregs=chanreg; + //myMod.nchip=thisDetector->nChips; + //myMod.chipregs=chipreg; + //myMod.ndac=thisDetector->nDacs; + //myMod.dacs=dac; + //myMod.ndac=thisDetector->nAdcs; + //myMod.dacs=adc; + if (thisDetector->onlineFlag==ONLINE_FLAG) { + if (connectControl() == OK){ + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + controlSocket->SendDataOnly(&imod,sizeof(imod)); + controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret!=FAIL) { + receiveModule(myMod); - - - if (thisDetector->onlineFlag==ONLINE_FLAG) { - if (connectControl() == OK){ - controlSocket->SendDataOnly(&fnum,sizeof(fnum)); - controlSocket->SendDataOnly(&imod,sizeof(imod)); - - controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); - if (ret!=FAIL) { - receiveModule(myMod); - } else { - controlSocket->ReceiveDataOnly(mess,sizeof(mess)); - std::cout<< "Detector returned error: " << mess << std::endl; - } - controlSocket->Disconnect(); - if (ret==FORCE_UPDATE) - updateDetector(); - } - } - - - if (ret!=FAIL) { - if (detectorModules) { - if (imod>=0 && imodnMod[X]*thisDetector->nMod[Y]) { - (detectorModules+imod)->nchan=myMod->nchan; - (detectorModules+imod)->nchip=myMod->nchip; - (detectorModules+imod)->ndac=myMod->ndac; - (detectorModules+imod)->nadc=myMod->nadc; - thisDetector->nChips=myMod->nchip; - thisDetector->nChans=myMod->nchan/myMod->nchip; - thisDetector->nDacs=myMod->ndac; - thisDetector->nAdcs=myMod->nadc; - - for (int ichip=0; ichipnChips; ichip++) { - if (chipregs) - chipregs[ichip+thisDetector->nChips*imod]=myMod->chipregs[ichip]; - - if (chanregs) { - for (int i=0; inChans; i++) { - chanregs[i+ichip*thisDetector->nChans+thisDetector->nChips*thisDetector->nChans*imod]=myMod->chanregs[ichip*thisDetector->nChans+i]; - } - } - } - if (dacs) { - for (int i=0; inDacs; i++) - dacs[i+imod*thisDetector->nDacs]=myMod->dacs[i]; - } - if (adcs) { - for (int i=0; inAdcs; i++) - adcs[i+imod*thisDetector->nAdcs]=myMod->adcs[i]; + //extra gain and offset - eiger + if(thisDetector->nGain) + controlSocket->ReceiveDataOnly(gainval,sizeof(int)*thisDetector->nGain); + if(thisDetector->nOffset) + controlSocket->ReceiveDataOnly(offsetval,sizeof(int)*thisDetector->nOffset); + } else { + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + } + controlSocket->Disconnect(); + if (ret==FORCE_UPDATE) + updateDetector(); + } } - (detectorModules+imod)->gain=myMod->gain; - (detectorModules+imod)->offset=myMod->offset; - (detectorModules+imod)->serialnumber=myMod->serialnumber; - (detectorModules+imod)->reg=myMod->reg; - } - } - } else { - deleteModule(myMod); - myMod=NULL; - } - return myMod; + + if (ret!=FAIL) { + if (detectorModules) { + if (imod>=0 && imodnMod[X]*thisDetector->nMod[Y]) { + (detectorModules+imod)->nchan=myMod->nchan; + (detectorModules+imod)->nchip=myMod->nchip; + (detectorModules+imod)->ndac=myMod->ndac; + (detectorModules+imod)->nadc=myMod->nadc; + thisDetector->nChips=myMod->nchip; + thisDetector->nChans=myMod->nchan/myMod->nchip; + thisDetector->nDacs=myMod->ndac; + thisDetector->nAdcs=myMod->nadc; + + for (int ichip=0; ichipnChips; ichip++) { + if (chipregs) + chipregs[ichip+thisDetector->nChips*imod]=myMod->chipregs[ichip]; + + if (chanregs) { + for (int i=0; inChans; i++) { + chanregs[i+ichip*thisDetector->nChans+thisDetector->nChips*thisDetector->nChans*imod]=myMod->chanregs[ichip*thisDetector->nChans+i]; + } + } + } + if (dacs) { + for (int i=0; inDacs; i++) + dacs[i+imod*thisDetector->nDacs]=myMod->dacs[i]; + } + if (adcs) { + for (int i=0; inAdcs; i++) + adcs[i+imod*thisDetector->nAdcs]=myMod->adcs[i]; + } + + (detectorModules+imod)->gain=myMod->gain; + (detectorModules+imod)->offset=myMod->offset; + (detectorModules+imod)->serialnumber=myMod->serialnumber; + (detectorModules+imod)->reg=myMod->reg; + } + } + + if ((thisDetector->nGain) && (gainval) && (gain)) { + for (int i=0; inGain; i++) + gain[i+imod*thisDetector->nGain]=gainval[i]; + } + + if ((thisDetector->nOffset) && (offsetval) && (offset)) { + for (int i=0; inOffset; i++) + offset[i+imod*thisDetector->nOffset]=offsetval[i]; + } + + if(gainval) delete[]gainval; + if(offsetval) delete[]offsetval; + + } else { + deleteModule(myMod); + myMod=NULL; + } + return myMod; } @@ -2958,6 +3051,19 @@ slsDetectorDefs::detectorSettings slsDetector::setSettings( detectorSettings ise string settingsfname, calfname; string ssettings; + int* gainval=0, *offsetval=0; + if(thisDetector->nGain) + gainval=new int[thisDetector->nGain]; + if(thisDetector->nOffset) + offsetval=new int[thisDetector->nOffset]; + + int ret=0; + + if(thisDetector->nGain) + gainval = new int[thisDetector->nGain]; + if(thisDetector->nOffset) + offsetval = new int[thisDetector->nOffset]; + switch (isettings) { case STANDARD: if ( (thisDetector->myDetectorType == MYTHEN) || @@ -3068,61 +3174,86 @@ slsDetectorDefs::detectorSettings slsDetector::setSettings( detectorSettings ise oscfn << thisDetector->calDir << ssettings << "/calibration.sn" << setfill('0') << setw(3) << hex << getId(MODULE_SERIAL_NUMBER, im) << setbase(10); } + + //settings file**** settingsfname=ostfn.str(); #ifdef VERBOSE cout << "the settings file name is "<myDetectorType, myMod)) { - calfname=oscfn.str(); -#ifdef VERBOSE - cout << calfname << endl; -#endif - - //reads calibration files here! - - - readCalibrationFile(calfname,myMod->gain, myMod->offset); - setModule(*myMod); - - - - } else { - ostringstream ostfn,oscfn; + if (!readSettingsFile(settingsfname,thisDetector->myDetectorType, myMod)) { + //if it didnt open, try default settings file + ostringstream ostfn_default; switch(thisDetector->myDetectorType){ case MOENCH: case GOTTHARD: case PROPIX: case JUNGFRAUCTB: - ostfn << thisDetector->settingsDir << ssettings << ssettings << ".settings"; + ostfn_default << thisDetector->settingsDir << ssettings << ssettings << ".settings"; break; case EIGER: default: - ostfn << thisDetector->settingsDir << ssettings << ssettings << ".trim"; + ostfn_default << thisDetector->settingsDir << ssettings << ssettings << ".trim"; break; } - oscfn << thisDetector->calDir << ssettings << ssettings << ".cal"; - calfname=oscfn.str(); - settingsfname=ostfn.str(); + settingsfname=ostfn_default.str(); #ifdef VERBOSE cout << settingsfname << endl; - cout << calfname << endl; #endif - if (readSettingsFile(settingsfname,thisDetector->myDetectorType, myMod)) { - calfname=oscfn.str(); - readCalibrationFile(calfname,myMod->gain, myMod->offset); - setModule(*myMod); - }else{ + if (!readSettingsFile(settingsfname,thisDetector->myDetectorType, myMod)) { + //if default doesnt work, return error std::cout << "Could not open settings file" << endl; setErrorMask((getErrorMask())|(SETTINGS_FILE_NOT_OPEN)); return thisDetector->currentSettings; } } + + + + //calibration file**** + calfname=oscfn.str(); +#ifdef VERBOSE + cout << "Specific file:"<< calfname << endl; +#endif + //extra gain and offset + if(thisDetector->nGain) + ret = readCalibrationFile(calfname,gainval, offsetval,thisDetector->myDetectorType ); + //normal gain and offset inside sls_detector_module + else + ret = readCalibrationFile(calfname,myMod->gain, myMod->offset); + + //if it didnt open, try default + if(ret != OK){ + ostringstream oscfn_default; + oscfn_default << thisDetector->calDir << ssettings << ssettings << ".cal"; + calfname=oscfn_default.str(); +#ifdef VERBOSE + cout << "Default file:" << calfname << endl; +#endif + //extra gain and offset + if(thisDetector->nGain) + ret = readCalibrationFile(calfname,gainval, offsetval,thisDetector->myDetectorType ); + //normal gain and offset inside sls_detector_module + else + ret = readCalibrationFile(calfname,myMod->gain, myMod->offset); + } + //if default doesnt work, return error + if(ret != OK){ + std::cout << "Could not open calibration file" << calfname << endl; + setErrorMask((getErrorMask())|(SETTINGS_FILE_NOT_OPEN)); + return thisDetector->currentSettings; + } + + //if everything worked, set module**** + setModule(*myMod,gainval,offsetval); } } deleteModule(myMod); + if(gainval) delete [] gainval; + if(offsetval) delete [] offsetval; + switch(thisDetector->myDetectorType==MYTHEN){ if (thisDetector->correctionMask&(1<myDetectorType!=MYTHEN) myMod->reg=thisDetector->currentSettings; - setModule(*myMod); + setModule(*myMod,g,o); deleteModule(myMod); } else return FAIL; @@ -5955,7 +6087,21 @@ int slsDetector::loadCalibrationFile(string fname, int imod) { sls_detector_module *myMod=NULL; string fn=fname; + + int* gainval=0, *offsetval=0; + if(thisDetector->nGain) + gainval=new int[thisDetector->nGain]; + if(thisDetector->nOffset) + offsetval=new int[thisDetector->nOffset]; + fn=fname; + + if(thisDetector->nGain) + gainval = new int[thisDetector->nGain]; + if(thisDetector->nOffset) + offsetval = new int[thisDetector->nOffset]; + + int mmin=0, mmax=setNumberOfModules(); if (imod>=0) { mmin=imod; @@ -5973,10 +6119,21 @@ int slsDetector::loadCalibrationFile(string fname, int imod) { } fn=ostfn.str(); if((myMod=getModule(im))){ - if(readCalibrationFile(fn, myMod->gain, myMod->offset)==FAIL) - return FAIL; - setModule(*myMod); + + //extra gain and offset + if(thisDetector->nGain){ + if(readCalibrationFile(fn,gainval, offsetval,thisDetector->myDetectorType)==FAIL) + return FAIL; + } //normal gain and offset inside sls_detector_module + else{ + if(readCalibrationFile(fn,myMod->gain, myMod->offset)==FAIL) + return FAIL; + } + setModule(*myMod,gainval,offsetval); + deleteModule(myMod); + if(gainval) delete[]gainval; + if(offsetval) delete offsetval; } else return FAIL; } @@ -6002,7 +6159,13 @@ int slsDetector::saveCalibrationFile(string fname, int imod) { else ostfn << fname << ".sn" << setfill('0') << setw(3) << hex << getId(MODULE_SERIAL_NUMBER,im); if ((myMod=getModule(im))) { - ret=writeCalibrationFile(ostfn.str(), myMod->gain, myMod->offset); + //extra gain and offset + if(thisDetector->nGain) + ret=writeCalibrationFile(ostfn.str(),gain, offset,thisDetector->myDetectorType); + //normal gain and offset inside sls_detector_module + else + ret=writeCalibrationFile(ostfn.str(),myMod->gain, myMod->offset); + deleteModule(myMod); }else return FAIL; diff --git a/slsDetectorSoftware/slsDetector/slsDetector.h b/slsDetectorSoftware/slsDetector/slsDetector.h index 3ad0841ad..85112f551 100644 --- a/slsDetectorSoftware/slsDetector/slsDetector.h +++ b/slsDetectorSoftware/slsDetector/slsDetector.h @@ -126,11 +126,17 @@ class slsDetector : public slsDetectorUtils, public energyConversion { int nDacs; /** number of adcs per module */ int nAdcs; + /** number of extra gain values*/ + int nGain; + /** number of extra offset values */ + int nOffset; /** dynamic range of the detector data */ int dynamicRange; /** size of the data that are transfered from the detector */ int dataBytes; + + /** corrections to be applied to the data \see ::correctionFlags */ int correctionMask; /** threaded processing flag (i.e. if data are processed and written to file in a separate thread) */ @@ -230,7 +236,10 @@ class slsDetector : public slsDetectorUtils, public energyConversion { int chipoff; /** memory offsets for the channel register arrays -trimbits*/ int chanoff; - + /** memory offsets for the gain register arrays */ + int gainoff; + /** memory offsets for the offset register arrays -trimbits*/ + int offsetoff; /* receiver*/ @@ -894,10 +903,12 @@ class slsDetector : public slsDetectorUtils, public energyConversion { /** configure chip \param module module to be set - must contain correct module number and also channel and chip registers + \param gainval pointer to extra gain values + \param offsetval pointer to extra offset values \returns current register value \sa ::sls_detector_module */ - int setModule(sls_detector_module module); + int setModule(sls_detector_module module, int* gainval, int* offsetval); //virtual int setModule(sls_detector_module module); /** @@ -1770,6 +1781,10 @@ class slsDetector : public slsDetectorUtils, public energyConversion { int *chipregs; /** pointer to channal registers */ int *chanregs; + /** pointer to gain values */ + int *gain; + /** pointer to offset values */ + int *offset; receiverInterface *thisReceiver; diff --git a/slsDetectorSoftware/slsDetectorAnalysis/energyConversion.cpp b/slsDetectorSoftware/slsDetectorAnalysis/energyConversion.cpp index 9999c5a30..818ab8399 100644 --- a/slsDetectorSoftware/slsDetectorAnalysis/energyConversion.cpp +++ b/slsDetectorSoftware/slsDetectorAnalysis/energyConversion.cpp @@ -47,7 +47,6 @@ int energyConversion::readCalibrationFile(string fname, double &gain, double &of int energyConversion::writeCalibrationFile(string fname, double gain, double offset){ //std::cout<< "Function not yet implemented " << std::endl; ofstream outfile; - outfile.open (fname.c_str()); // >> i/o operations here << @@ -70,66 +69,62 @@ int energyConversion::writeCalibrationFile(string fname, double gain, double off }; -int energyConversion::readCalibrationFile(string fname, double *gain, double *offset, detectorType myDetectorType){ +int energyConversion::readCalibrationFile(string fname, int *gain, int *offset, detectorType myDetectorType){ - string str; - ifstream infile; - double o,g; - int ig=0; - switch (myDetectorType) { - case EIGER: + string str; + ifstream infile; + double o,g; + int ig=0; + switch (myDetectorType) { + case EIGER: #ifdef VERBOSE - std::cout<< "Opening file "<< fname << std::endl; + std::cout<< "Opening file "<< fname << std::endl; #endif - infile.open(fname.c_str(), ios_base::in); - if (infile.is_open()) { - - for (ig=0; ig<4; ig++) { - //while ( (getline(infile,str)) > -1) { - getline(infile,str); + infile.open(fname.c_str(), ios_base::in); + if (infile.is_open()) { + for (ig=0; ig<4; ig++) { + //while ( (getline(infile,str)) > -1) { + getline(infile,str); #ifdef VERBOSE - std::cout<< str << std::endl; + std::cout<< str << std::endl; #endif - istringstream ssstr(str); - ssstr >> o >> g; - offset[ig]=o; - gain[ig]=g; - // ig++; - if (ig>=4) - break; - } - infile.close(); - cout << "Calibration file loaded: " << fname << endl; - } else { - std::cout<< "Could not open calibration file "<< fname << std::endl; - gain[0]=0.; - offset[0]=0.; + istringstream ssstr(str); + ssstr >> o >> g; + offset[ig]=(int)(o*1000); + gain[ig]=(int)(g*1000); + // ig++; + if (ig>=4) + break; + } + infile.close(); + cout << "Calibration file loaded: " << fname << endl; + } else { + cout << "Could not open calibration file: "<< fname << std::endl; + gain[0]=0; + offset[0]=0; #ifndef MYROOT - return FAIL; + return FAIL; #endif - return -1; - } + return -1; + } #ifndef MYROOT - return OK; + return OK; #endif - return 0; - break; - - - - - default: - return readCalibrationFile(fname, *gain, *offset); - } + return 0; + break; + default: + std::cout<< "Writing Calibration Files for this detector not defined\n" << std::endl; + return FAIL; + } }; -int energyConversion::writeCalibrationFile(string fname, double *gain, double *offset, detectorType myDetectorType){ +int energyConversion::writeCalibrationFile(string fname, int *gain, int *offset, detectorType myDetectorType){ //std::cout<< "Function not yet implemented " << std::endl; ofstream outfile; switch (myDetectorType) { @@ -140,7 +135,7 @@ int energyConversion::writeCalibrationFile(string fname, double *gain, double *o // >> i/o operations here << if (outfile.is_open()) { for (int ig=0; ig<4; ig++) - outfile << offset[ig] << " " << gain[ig] << std::endl; + outfile << ((double)offset[ig]/1000) << " " << ((double)gain[ig]/1000) << std::endl; } else { std::cout<< "Could not open calibration file "<< fname << " for writing" << std::endl; #ifndef MYROOT @@ -156,7 +151,8 @@ int energyConversion::writeCalibrationFile(string fname, double *gain, double *o return 0; break; default: - return writeCalibrationFile(fname, *gain, *offset); + std::cout<< "Writing Calibration Files for this detector not defined\n" << std::endl; + return FAIL; } }; diff --git a/slsDetectorSoftware/slsDetectorAnalysis/energyConversion.h b/slsDetectorSoftware/slsDetectorAnalysis/energyConversion.h index 6242601b5..2768632ba 100644 --- a/slsDetectorSoftware/slsDetectorAnalysis/energyConversion.h +++ b/slsDetectorSoftware/slsDetectorAnalysis/energyConversion.h @@ -54,7 +54,7 @@ class energyConversion \param gain reference to the gain variable \offset reference to the offset variable */ - static int readCalibrationFile(string fname, double *gain, double *offset, detectorType myDetectorType); + static int readCalibrationFile(string fname, int *gain, int *offset, detectorType myDetectorType); /** writes a calibration file @@ -62,7 +62,7 @@ class energyConversion \param gain \param offset */ - static int writeCalibrationFile(string fname, double *gain, double *offset, detectorType myDetectorType); + static int writeCalibrationFile(string fname, int *gain, int *offset, detectorType myDetectorType); diff --git a/slsDetectorSoftware/slsDetectorServer/slsDetectorFunctionList.h b/slsDetectorSoftware/slsDetectorServer/slsDetectorFunctionList.h index 14a0dc2ea..e15b673dd 100644 --- a/slsDetectorSoftware/slsDetectorServer/slsDetectorFunctionList.h +++ b/slsDetectorSoftware/slsDetectorServer/slsDetectorFunctionList.h @@ -60,14 +60,21 @@ int setChip(sls_detector_chip myChip); int getChip(sls_detector_chip *myChip); #endif + +#ifdef EIGERD +int setModule(sls_detector_module myMod, int* gain, int* offset); +int getModule(sls_detector_module *myMod, int* gain, int* offset); +#else int setModule(sls_detector_module myMod); int getModule(sls_detector_module *myMod); +#endif + enum detectorSettings setSettings(enum detectorSettings sett, int imod); #if defined(MYTHEND) || defined(EIGERD) int getThresholdEnergy(int imod); -int setThresholdEnergy(int thr, int imod); +int setThresholdEnergy(int ev, int imod); #endif int startStateMachine(); @@ -118,7 +125,10 @@ int getNumberOfChannelsPerModule(); int getNumberOfChipsPerModule(); int getNumberOfDACsPerModule(); int getNumberOfADCsPerModule(); - +#ifdef EIGERD +int getNumberOfGainsPerModule(); +int getNumberOfOffsetsPerModule(); +#endif enum externalSignalFlag getExtSignal(int signalindex); enum externalSignalFlag setExtSignal(int signalindex, enum externalSignalFlag flag); diff --git a/slsDetectorSoftware/slsDetectorServer/slsDetectorServer_funcs.c b/slsDetectorSoftware/slsDetectorServer/slsDetectorServer_funcs.c index 17b11eece..870bd9d3d 100755 --- a/slsDetectorSoftware/slsDetectorServer/slsDetectorServer_funcs.c +++ b/slsDetectorSoftware/slsDetectorServer/slsDetectorServer_funcs.c @@ -1788,11 +1788,15 @@ int get_chip(int file_des) { } int set_module(int file_des) { - int retval, n; + int retval, n,i; int ret=OK,ret1=OK; #ifdef SLS_DETECTOR_FUNCTION_LIST sls_detector_module myModule; +#ifdef EIGERD + int *myGain = (int*)malloc(getNumberOfGainsPerModule()*sizeof(int)); + int *myOffset = (int*)malloc(getNumberOfOffsetsPerModule()*sizeof(int)); +#endif int *myChip=(int*)malloc(getNumberOfChipsPerModule()*sizeof(int)); int *myChan=(int*)malloc(getNumberOfChannelsPerModule()*sizeof(int)); int *myDac=(int*)malloc(getNumberOfDACsPerModule()*sizeof(int)); @@ -1823,7 +1827,16 @@ int set_module(int file_des) { sprintf(mess,"could not allocate chans\n"); ret=FAIL; } - +#ifdef EIGERD + if (!myGain){ + sprintf(mess,"could not allocate gains\n"); + ret=FAIL; + } + if (!myOffset){ + sprintf(mess,"could not allocate offsets\n"); + ret=FAIL; + } +#endif myModule.nchip=getNumberOfChipsPerModule(); myModule.nchan=getNumberOfChannelsPerModule(); myModule.ndac=getNumberOfDACsPerModule(); @@ -1834,17 +1847,25 @@ int set_module(int file_des) { printf("Setting module\n"); #endif ret=receiveModule(file_des, &myModule); - - +#ifdef EIGERD + n = receiveData(file_des,myGain,sizeof(int)*getNumberOfGainsPerModule(),INT32); + n = receiveData(file_des,myOffset,sizeof(int)*getNumberOfOffsetsPerModule(),INT32); +#endif if (ret>=0) ret=OK; else ret=FAIL; -#ifdef VERBOSE +//#ifdef VERBOSE printf("module number is %d,register is %d, nchan %d, nchip %d, ndac %d, nadc %d, gain %f, offset %f\n",myModule.module, myModule.reg, myModule.nchan, myModule.nchip, myModule.ndac, myModule.nadc, myModule.gain,myModule.offset); +#ifdef EIGERD + for(i=0;i=0) { ret=OK; myModule.module=imod; +#ifdef EIGERD + getModule(&myModule, myGain, myOffset); +#ifdef VERBOSE + for(i=0;i