From c097dfc8b3e5a519357b669139c7eb2eebc4a20c Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Fri, 20 Nov 2015 16:28:48 +0100 Subject: [PATCH] two acquires at the same tiem should not be possile. using shared memory to set flag, made all connect use the standard connectControl etc --- slsDetectorSoftware/commonFiles/error_defs.h | 4 +- .../commonFiles/sls_detector_funcs.h | 3 +- .../eigerDetectorServer/FebControl.c | 198 ++++++++------- .../eigerDetectorServer/FebControl.h | 1 + .../bin/eigerDetectorServer | Bin 259491 -> 260004 bytes .../slsDetectorFunctionList.c | 7 +- .../multiSlsDetector/multiSlsDetector.cpp | 27 ++- .../multiSlsDetector/multiSlsDetector.h | 22 +- .../slsDetector/slsDetector.cpp | 226 ++++++++++++------ slsDetectorSoftware/slsDetector/slsDetector.h | 22 ++ .../slsDetector/slsDetectorBase.h | 4 +- .../slsDetector/slsDetectorCommand.cpp | 65 +++-- .../slsDetector/slsDetectorUtils.cpp | 17 +- .../slsDetector/slsDetectorUtils.h | 20 +- .../slsDetectorFunctionList.h | 1 + .../slsDetectorServer_funcs.c | 51 +++- .../slsDetectorServer_funcs.h | 2 + .../receiverInterface.cpp | 9 - 18 files changed, 474 insertions(+), 205 deletions(-) diff --git a/slsDetectorSoftware/commonFiles/error_defs.h b/slsDetectorSoftware/commonFiles/error_defs.h index 8d1b04d3f..c3509a44a 100644 --- a/slsDetectorSoftware/commonFiles/error_defs.h +++ b/slsDetectorSoftware/commonFiles/error_defs.h @@ -55,7 +55,7 @@ using namespace std; #define COULD_NOT_SET_COUNTER_BIT 0x0000000000020000ULL #define COULD_NOT_PULSE_PIXEL 0x0000000000040000ULL #define COULD_NOT_PULSE_PIXEL_NMOVE 0x0000000000080000ULL - +#define COULD_NOT_PULSE_CHIP 0x0000000000100000ULL // 0x00000000FFFFFFFFULL /** @short class returning all error messages for error mask */ @@ -174,6 +174,8 @@ public: if(slsErrorMask&COULD_NOT_PULSE_PIXEL_NMOVE) retval.append("Could not pulse pixel and move\n"); + if(slsErrorMask&COULD_NOT_PULSE_CHIP) + retval.append("Could not pulse chip\n"); return retval; diff --git a/slsDetectorSoftware/commonFiles/sls_detector_funcs.h b/slsDetectorSoftware/commonFiles/sls_detector_funcs.h index 6950b80dd..e61b5cf9c 100644 --- a/slsDetectorSoftware/commonFiles/sls_detector_funcs.h +++ b/slsDetectorSoftware/commonFiles/sls_detector_funcs.h @@ -97,7 +97,8 @@ enum { F_SET_COUNTER_BIT, /** < set/reset counter bit in detector for eiger */ F_PULSE_PIXEL, /** < pulse pixel n number of times in eiger at (x,y) */ - F_PULSE_PIXEL_AND_MOVE /** < pulse pixel n number of times and move relatively by x and y */ + F_PULSE_PIXEL_AND_MOVE, /** < pulse pixel n number of times and move relatively by x and y */ + F_PULSE_CHIP /** < pulse chip n number of times */ /* Always append functions hereafter!!! */ diff --git a/slsDetectorSoftware/eigerDetectorServer/FebControl.c b/slsDetectorSoftware/eigerDetectorServer/FebControl.c index 90ed811ba..27e00df46 100644 --- a/slsDetectorSoftware/eigerDetectorServer/FebControl.c +++ b/slsDetectorSoftware/eigerDetectorServer/FebControl.c @@ -296,25 +296,25 @@ int Feb_Control_ReadSetUpFileToAddModules(char* file_name){ if(!strcmp(str,"add_module")){ if( sscanf (line,"%s %d %d %d", str,&i0,&i1,&i2) < 4){ - printf("Error adding module from %s.\n",file_name); + cprintf(RED,"Error adding module from %s.\n",file_name); exit(0); } printf ("str:%s len:%d i0:%d i1:%d i2:%d\n", str, strlen(str),i0,i1,i2); if(!Feb_Control_AddModule1(i0,1,i1,i2,0)){ - printf("Error adding module, parameter was assigned twice in setup file: %s.\n",file_name); + cprintf(RED,"Error adding module, parameter was assigned twice in setup file: %s.\n",file_name); exit(0); } } else if(!strcmp(str,"add_half_module")){ if( sscanf (line,"%s %d %d %d", str,&i0,&i1,&i2) < 4){ - printf("Error adding half module from %s.\n",file_name); + cprintf(RED,"Error adding half module from %s.\n",file_name); exit(0); } printf ("str:%s len:%d i0:%d i1:%d i2:%d\n", str, strlen(str),i0,i1,i2); if(!Feb_Control_AddModule1(i0,i1,i2,i2,1)){ - printf("Error adding module, parameter was assigned twice in setup file: %s.\n",file_name); + cprintf(RED,"Error adding module, parameter was assigned twice in setup file: %s.\n",file_name); exit(0); } @@ -322,7 +322,7 @@ int Feb_Control_ReadSetUpFileToAddModules(char* file_name){ Feb_Control_PrintModuleList(); /* if(!Feb_Control_AddModule1(i0,i1)){ - printf("Error adding module, parameter was assigned twice in setup file: %s.\n",file_name); + cprintf(RED,"Error adding module, parameter was assigned twice in setup file: %s.\n",file_name); exit(0); }*/ } @@ -391,12 +391,12 @@ int Feb_Control_CheckModuleAddresses(struct Module* m){ (Module_BottomAddressIsValid(m) && Module_GetBottomBaseAddress(&modules[i]) && Module_GetBottomBaseAddress(m)==Module_GetBottomBaseAddress(&modules[i]))) found_b=1; } - if(found_t) printf("\tWarning: top address %d already used.\n",Module_GetTopBaseAddress(m)); - if(found_b) printf("\tWarning: bottom address %d already used.\n",Module_GetBottomBaseAddress(m)); + if(found_t) cprintf(RED,"\tWarning: top address %d already used.\n",Module_GetTopBaseAddress(m)); + if(found_b) cprintf(RED,"\tWarning: bottom address %d already used.\n",Module_GetBottomBaseAddress(m)); int top_bottom_same = Module_TopAddressIsValid(m)&&Module_BottomAddressIsValid(m)&&Module_GetTopBaseAddress(m)==Module_GetBottomBaseAddress(m); - if(top_bottom_same) printf("\tWarning: top and bottom address are the same %d.\n",Module_GetTopBaseAddress(m)); + if(top_bottom_same) cprintf(RED,"\tWarning: top and bottom address are the same %d.\n",Module_GetTopBaseAddress(m)); return !(top_bottom_same||found_t||found_b); } @@ -473,7 +473,7 @@ int Feb_Control_ReadSetUpFile(unsigned int module_num, char* file_name){ if(!strcmp("iodelay",str)){ if(sscanf (line,"%s %d", str,&i0) < 2){ - printf("Error reading io_delay\n"); + cprintf(RED,"Error reading io_delay\n"); exit(0); } Feb_Control_SetIDelays(module_num,i0); @@ -481,7 +481,7 @@ int Feb_Control_ReadSetUpFile(unsigned int module_num, char* file_name){ else if(!strcmp("high_voltage",str)){ if(sscanf (line,"%s %f", str,&f0) < 2){ - printf("Error reading high_voltage\n"); + cprintf(RED,"Error reading high_voltage\n"); exit(0); } Feb_Control_SetHighVoltage(f0); @@ -489,7 +489,7 @@ int Feb_Control_ReadSetUpFile(unsigned int module_num, char* file_name){ /* else if(!strcmp("photon_energy",str)){ if(sscanf (line,"%s %f", str,&f0) < 2){ - printf("Error reading photon_energy\n"); + cprintf(RED,"Error reading photon_energy\n"); exit(0); } Feb_Control_SetPhotonEnergy(f0); @@ -497,7 +497,7 @@ int Feb_Control_ReadSetUpFile(unsigned int module_num, char* file_name){ else if(!strcmp("dynamic_range",str)){ if(sscanf (line,"%s %d", str,&i0) < 2){ - printf("Error reading dynamic_range\n"); + cprintf(RED,"Error reading dynamic_range\n"); exit(0); } Feb_Control_SetDynamicRange(i0); @@ -505,7 +505,7 @@ int Feb_Control_ReadSetUpFile(unsigned int module_num, char* file_name){ else if(!strcmp("readout_speed",str)){ if(sscanf (line,"%s %d", str,&i0) < 2){ - printf("Error reading readout_speed\n"); + cprintf(RED,"Error reading readout_speed\n"); exit(0); } Feb_Control_SetReadoutSpeed(i0); @@ -513,7 +513,7 @@ int Feb_Control_ReadSetUpFile(unsigned int module_num, char* file_name){ else if(!strcmp("readout_mode",str)){ if(sscanf (line,"%s %d", str,&i0) < 2){ - printf("Error reading readout_mode\n"); + cprintf(RED,"Error reading readout_mode\n"); exit(0); } Feb_Control_SetReadoutMode(i0); @@ -521,14 +521,14 @@ int Feb_Control_ReadSetUpFile(unsigned int module_num, char* file_name){ else { if( sscanf (line,"%s %f", str,&f0) < 2){ - printf("Error reading dac\n"); + cprintf(RED,"Error reading dac\n"); exit(0); } if(module_num>0) sprintf(str,"%s",str); /*sprintf(str,"mod%d::%s",module_num,str);*/ if(!Feb_Control_SetDAC(str,f0,1)) - printf("error in string: %s",str); + cprintf(RED,"Error in string: %s",str); } } @@ -548,25 +548,25 @@ int Feb_Control_CheckSetup(){ for(j=0;j<4;j++){ if(Module_GetTopIDelay(&modules[i],j)<0){ - printf("Warning: module %d's idelay top number %d not set.\n",Module_GetModuleNumber(&modules[i]),j); + cprintf(RED,"Warning: module %d's idelay top number %d not set.\n",Module_GetModuleNumber(&modules[i]),j); ok=0; } if(Module_GetBottomIDelay(&modules[i],j)<0){ - printf("Warning: module %d's idelay bottom number %d not set.\n",Module_GetModuleNumber(&modules[i]),j); + cprintf(RED,"Warning: module %d's idelay bottom number %d not set.\n",Module_GetModuleNumber(&modules[i]),j); ok=0; } } if(Module_GetHighVoltage(&modules[i])<0){ - printf("Warning: module %d's high voltage not set.\n",Module_GetModuleNumber(&modules[i])); + cprintf(RED,"Warning: module %d's high voltage not set.\n",Module_GetModuleNumber(&modules[i])); ok=0; } for(j=0;j3){ - printf("Error SetIDelay chip_pos %d doesn't exist.\n",chip_pos);; + cprintf(RED,"Error SetIDelay chip_pos %d doesn't exist.\n",chip_pos);; return 0; } unsigned int module_index=0; if(!Feb_Control_GetModuleIndex(module_num,&module_index)){ - printf("Error could not set i delay module number %d invalid.\n",module_num); + cprintf(RED,"Error could not set i delay module number %d invalid.\n",module_num); return 0; } @@ -620,7 +620,7 @@ int Feb_Control_SetIDelays1(unsigned int module_num, unsigned int chip_pos, unsi for(i=0;i4095){ - printf("Warning: SetDac bad value, %d. The range is 0 to 4095.\n",v); + cprintf(RED,"Warning: SetDac bad value, %d. The range is 0 to 4095.\n",v); return 0; } @@ -882,7 +882,7 @@ int Feb_Control_GetDAC(char* s, int* ret_value, int voltage_mv){ int Feb_Control_GetDACName(unsigned int dac_num, char* s){ if(dac_num>=Module_ndacs){ - printf("Warning: GetDACName index out of range, %d invalid.\n",dac_num); + cprintf(RED,"Warning: GetDACName index out of range, %d invalid.\n",dac_num); return 0; } strcpy(s,Module_dac_names[dac_num]); @@ -909,7 +909,7 @@ int Feb_Control_SendDACValue(unsigned int dst_num, unsigned int ch, unsigned int //static float vmax = 2; if(ch<0||ch>15){ - printf("Warning invalid ch for SetDAC.\n"); + cprintf(RED,"Warning invalid ch for SetDAC.\n"); return 0; } @@ -922,7 +922,7 @@ int Feb_Control_SendDACValue(unsigned int dst_num, unsigned int ch, unsigned int if(!Feb_Interface_WriteRegister(dst_num,0,r,1,0)){ - printf("Warning: trouble setting dac %d voltage.\n",ch); + cprintf(RED,"Warning: trouble setting dac %d voltage.\n",ch); return 0; } @@ -953,11 +953,11 @@ int Feb_Control_SetTrimbits(unsigned int module_num, unsigned int *trimbits){ unsigned int module_index=0; if(!Feb_Control_GetModuleIndex(module_num,&module_index)){ - printf("Warning could not set trimbits, bad module number.\n"); + cprintf(RED,"Warning could not set trimbits, bad module number.\n"); return 0; } - if(!Feb_Control_Reset()) printf("Warning could not reset DAQ.\n"); + if(!Feb_Control_Reset()) cprintf(RED,"Warning could not reset DAQ.\n"); int l_r; //printf("222\n"); for(l_r=0;l_r<2;l_r++){ // l_r loop //printf("\nl_r:%d\t\t",l_r); @@ -971,12 +971,12 @@ int Feb_Control_SetTrimbits(unsigned int module_num, unsigned int *trimbits){ //printf("row_set:%d\t\t",row_set); if(row_set==0){ if(!Feb_Control_SetCommandRegister(DAQ_RESET_COMPLETELY|DAQ_SEND_A_TOKEN_IN|DAQ_LOAD_16ROWS_OF_TRIMBITS)){ - printf("Warning: Could not Feb_Control_SetCommandRegister for loading trim bits.\n"); + cprintf(RED,"Warning: Could not Feb_Control_SetCommandRegister for loading trim bits.\n"); return 0; } }else{ if(!Feb_Control_SetCommandRegister(DAQ_LOAD_16ROWS_OF_TRIMBITS)){ - printf("Warning: Could not Feb_Control_SetCommandRegister for loading trim bits.\n"); + cprintf(RED,"Warning: Could not Feb_Control_SetCommandRegister for loading trim bits.\n"); return 0; } } @@ -1084,7 +1084,7 @@ int Feb_Control_SetCommandRegister(unsigned int cmd){ int Feb_Control_GetDAQStatusRegister(unsigned int dst_address, unsigned int* ret_status){ if(!Feb_Interface_ReadRegister(dst_address,DAQ_REG_STATUS,ret_status)){ - printf("Error: reading status register.\n"); + cprintf(RED,"Error: reading status register.\n"); return 0; } @@ -1095,7 +1095,7 @@ int Feb_Control_GetDAQStatusRegister(unsigned int dst_address, unsigned int* ret int Feb_Control_StartDAQOnlyNWaitForFinish(int sleep_time_us){ if(!Feb_Interface_WriteRegister(Feb_Control_AddressToAll(),DAQ_REG_CTRL,0,0,0)||!Feb_Interface_WriteRegister(Feb_Control_AddressToAll(),DAQ_REG_CTRL,DAQ_CTRL_START,0,0)){ - printf("Warning: could not start.\n"); + cprintf(RED,"Warning: could not start.\n"); return 0; } @@ -1110,15 +1110,15 @@ int Feb_Control_AcquisitionInProgress(){ if(Module_BottomAddressIsValid(&modules[ind])){ if(!(Feb_Control_GetDAQStatusRegister(Module_GetBottomRightAddress(&modules[ind]),&status_reg_r))) - {printf("ERROR: Trouble reading Status register. bottom right address\n");return 0;} + {cprintf(RED,"Error: Trouble reading Status register. bottom right address\n");return 0;} if(!(Feb_Control_GetDAQStatusRegister(Module_GetBottomLeftAddress(&modules[ind]),&status_reg_l))) - {printf("ERROR: Trouble reading Status register. bottom left address\n");return 0;} + {cprintf(RED,"Error: Trouble reading Status register. bottom left address\n");return 0;} }else{ if(!(Feb_Control_GetDAQStatusRegister(Module_GetTopRightAddress(&modules[ind]),&status_reg_r))) - {printf("ERROR: Trouble reading Status register. top right address\n");return 0;} + {cprintf(RED,"Error: Trouble reading Status register. top right address\n");return 0;} if(!(Feb_Control_GetDAQStatusRegister(Module_GetTopLeftAddress(&modules[ind]),&status_reg_l))) - {printf("ERROR: Trouble reading Status register. top left address\n");return 0;} + {cprintf(RED,"Error: Trouble reading Status register. top left address\n");return 0;} } //running @@ -1137,15 +1137,15 @@ int Feb_Control_AcquisitionStartedBit(){ if(Module_BottomAddressIsValid(&modules[ind])){ if(!(Feb_Control_GetDAQStatusRegister(Module_GetBottomRightAddress(&modules[ind]),&status_reg_r))) - {printf("ERROR: Trouble reading Status register. bottom right address\n");return -1;} + {cprintf(RED,"Error: Trouble reading Status register. bottom right address\n");return -1;} if(!(Feb_Control_GetDAQStatusRegister(Module_GetBottomLeftAddress(&modules[ind]),&status_reg_l))) - {printf("ERROR: Trouble reading Status register. bottom left address\n");return -1;} + {cprintf(RED,"Error: Trouble reading Status register. bottom left address\n");return -1;} }else{ if(!(Feb_Control_GetDAQStatusRegister(Module_GetTopRightAddress(&modules[ind]),&status_reg_r))) - {printf("ERROR: Trouble reading Status register. top right address\n"); return -1;} + {cprintf(RED,"Error: Trouble reading Status register. top right address\n"); return -1;} if(!(Feb_Control_GetDAQStatusRegister(Module_GetTopLeftAddress(&modules[ind]),&status_reg_l))) - {printf("ERROR: Trouble reading Status register. top left address\n");return -1;} + {cprintf(RED,"Error: Trouble reading Status register. top left address\n");return -1;} } //doesnt mean it started, just the bit @@ -1189,7 +1189,7 @@ int Feb_Control_WaitForStartedFlag(int sleep_time_us, int prev_flag){ int Feb_Control_Reset(){ if(!Feb_Interface_WriteRegister(Feb_Control_AddressToAll(),DAQ_REG_CTRL,0,0,0) || !Feb_Interface_WriteRegister(Feb_Control_AddressToAll(),DAQ_REG_CTRL,DAQ_CTRL_RESET,0,0) || !Feb_Interface_WriteRegister(Feb_Control_AddressToAll(),DAQ_REG_CTRL,0,0,0)){ - printf("Warning: Could not reset daq, no response.\n"); + cprintf(RED,"Warning: Could not reset daq, no response.\n"); return 0; } @@ -1202,7 +1202,7 @@ int Feb_Control_Reset(){ int Feb_Control_SetStaticBits(){ //program=1,m4=2,m8=4,test=8,rotest=16,cs_bar_left=32,cs_bar_right=64 if(!Feb_Interface_WriteRegister(Feb_Control_AddressToAll(),DAQ_REG_STATIC_BITS,Feb_Control_staticBits,0,0) || !Feb_Control_SetCommandRegister(DAQ_SET_STATIC_BIT) || !Feb_Control_StartDAQOnlyNWaitForFinish(5000)){ - printf("Warning: Could not set static bits\n"); + cprintf(RED,"Warning: Could not set static bits\n"); return 0; } @@ -1213,7 +1213,7 @@ int Feb_Control_SetStaticBits1(unsigned int the_static_bits){ return Feb_Control_SetStaticBits(); } -int Feb_Control_SetTestModeVariable(int on){ +int Feb_Control_SetInTestModeVariable(int on){ if(on) Feb_Control_staticBits |= DAQ_STATIC_BIT_CHIP_TEST; //setting test bit to high else Feb_Control_staticBits &= (~DAQ_STATIC_BIT_CHIP_TEST); //setting test bit to low return 1; @@ -1238,7 +1238,7 @@ int Feb_Control_SetDynamicRange(unsigned int four_eight_sixteen_or_thirtytwo){ Feb_Control_staticBits = DAQ_STATIC_BIT_M12 | (Feb_Control_staticBits&everything_but_bit_mode); Feb_Control_subFrameMode |= DAQ_NEXPOSURERS_ACTIVATE_AUTO_SUBIMAGING; }else{ - printf("Warning: dynamic range (%d) not valid, not setting bit mode.\n",four_eight_sixteen_or_thirtytwo); + cprintf(RED,"Warning: dynamic range (%d) not valid, not setting bit mode.\n",four_eight_sixteen_or_thirtytwo); printf("Set dynamic range int must equal 4,8 16, or 32.\n"); return 0; } @@ -1268,7 +1268,7 @@ int Feb_Control_SetReadoutSpeed(unsigned int readout_speed){ //0->full,1->half,2 printf("Everything at super slow speed, ie. reading with ~0.200 MHz main clk (super slow speed) ....\n"); }else{ if(readout_speed){ - printf("Warning readout speed %d unknown, defaulting to full speed.\n",readout_speed); + cprintf(RED,"Warning readout speed %d unknown, defaulting to full speed.\n",readout_speed); printf("Everything at full speed, ie. reading with 100 MHz main clk (full speed) ....\n"); return 0; } @@ -1289,7 +1289,7 @@ int Feb_Control_SetReadoutMode(unsigned int readout_mode){ //0->parallel,1->non- }else{ Feb_Control_acquireNReadoutMode |= DAQ_NEXPOSURERS_PARALLEL_MODE; if(readout_mode){ - printf("Warning readout mode %d) unknown, defaulting to full speed.\n",readout_mode); + cprintf(RED,"Warning readout mode %d) unknown, defaulting to full speed.\n",readout_mode); printf("Readout mode set to parrallel acquire/read mode .... \n");; return 0; } @@ -1317,7 +1317,7 @@ int Feb_Control_SetTriggerMode(unsigned int trigger_mode,int polarity){ printf("Trigger mode: externally controlled, external image window (start and stop).\n");; }else{ Feb_Control_triggerMode = DAQ_NEXPOSURERS_INTERNAL_ACQUISITION; - if(trigger_mode) printf("Warning trigger %d) unknown, defaulting to internal triggering.\n",trigger_mode);; + if(trigger_mode) cprintf(RED,"Warning trigger %d) unknown, defaulting to internal triggering.\n",trigger_mode);; printf("Trigger mode: acquisition internally controlled exposure length and period.\n");; return trigger_mode==0; @@ -1347,7 +1347,7 @@ int Feb_Control_SetExternalEnableMode(int use_external_enable, int polarity){ printf(", polarity set to negative.\n");; } }else{ - Feb_Control_externalEnableMode &= (~DAQ_NEXPOSURERS_EXTERNAL_ENABLING); + Feb_Control_externalEnableMode = 0; /* changed by Dhanya according to old code &= (~DAQ_NEXPOSURERS_EXTERNAL_ENABLING);*/ printf("External enabling disabled.\n");; } @@ -1356,7 +1356,7 @@ int Feb_Control_SetExternalEnableMode(int use_external_enable, int polarity){ int Feb_Control_SetNExposures(unsigned int n_images){ if(!n_images){ - printf("Warning nimages must be greater than zero.%d\n",n_images); + cprintf(RED,"Warning nimages must be greater than zero.%d\n",n_images); return 0; } @@ -1393,7 +1393,7 @@ unsigned int Feb_Control_ConvertTimeToRegister(float time_in_sec){ unsigned int decoded_time; if(n_clk_cycles>(pow(2,29)-1)*pow(10,7)){ float max_time = 10e-9*(pow(2,28)-1)*pow(10,7); - printf("Warning: time exceeds (%f) maximum exposure time of %f sec.\n",time_in_sec,max_time); + cprintf(RED,"Warning: time exceeds (%f) maximum exposure time of %f sec.\n",time_in_sec,max_time); printf("\t Setting to maximum %f us.\n",max_time); decoded_time = 0xffffffff; }else{ @@ -1407,7 +1407,7 @@ unsigned int Feb_Control_ConvertTimeToRegister(float time_in_sec){ int Feb_Control_ResetChipCompletely(){ if(!Feb_Control_SetCommandRegister(DAQ_RESET_COMPLETELY) || !Feb_Control_StartDAQOnlyNWaitForFinish(5000)){ - printf("Warning: could not ResetChipCompletely() with 0x%x.\n",DAQ_RESET_COMPLETELY); + cprintf(RED,"Warning: could not ResetChipCompletely() with 0x%x.\n",DAQ_RESET_COMPLETELY); return 0; } printf("Chip reset completely\n"); @@ -1418,13 +1418,13 @@ int Feb_Control_ResetChipCompletely(){ int Feb_Control_ResetChipPartially(){ if(!Feb_Control_SetCommandRegister(DAQ_RESET_PERIPHERY) || !Feb_Control_StartDAQOnlyNWaitForFinish(5000)){ - printf("Warning: could not ResetChipPartially with periphery\n"); + cprintf(RED,"Warning: could not ResetChipPartially with periphery\n"); return 0; } printf("Chip reset periphery 0x%x\n",DAQ_RESET_PERIPHERY); if(!Feb_Control_SetCommandRegister(DAQ_RESET_COLUMN_SELECT) || !Feb_Control_StartDAQOnlyNWaitForFinish(5000)){ - printf("Warning: could not ResetChipPartially with column select\n"); + cprintf(RED,"Warning: could not ResetChipPartially with column select\n"); return 0; } printf("Chip reset column select 0x%x\n",DAQ_RESET_COLUMN_SELECT); @@ -1463,7 +1463,7 @@ int Feb_Control_SendBitModeToBebServer(){ if(!Beb_SetUpTransferParameters(bit_mode)){ - printf("Error: sending bit mode ...\n"); + cprintf(RED,"Error: sending bit mode ...\n"); return 0; } @@ -1472,7 +1472,7 @@ int Feb_Control_SendBitModeToBebServer(){ sprintf(buffer,"setbitmode %d",bit_mode); if(Feb_Control_WriteNRead(buffer,strlen(buffer),1024)<1||strncmp(buffer,"0",1)){ - printf("Error: sending bit mode ...\n"); + cprintf(RED,"Error: sending bit mode ...\n"); return 0; } */ @@ -1511,10 +1511,10 @@ int Feb_Control_WriteNRead(char* message, int length, int max_length){ } int n = write(sockfd,message,length); - if(n<0) printf("ERROR writing to socket"); + if(n<0) cprintf(RED,"Error writing to socket"); length = read(sockfd,message,max_length); - if(length<0) printf("ERROR reading to socket"); + if(length<0) cprintf(RED,"Error reading to socket"); close(sockfd); @@ -1613,7 +1613,7 @@ int Feb_Control_StartAcquisition(){ reg_vals[14]=ACQ_CTRL_START; if(!Feb_Interface_WriteRegisters(Feb_Control_AddressToAll(),15,reg_nums,reg_vals,0,0)){ - printf("Trouble starting acquisition....\n");; + cprintf(RED,"Trouble starting acquisition....\n");; return 0; } @@ -1667,7 +1667,7 @@ int Feb_Control_Pulse_Pixel(int npulses, int x, int y){ printf("Pulsing pixel %d in all super columns below number %d.\n",x%8,x/8); } if(x<0||x>255||y<0||y>255){ - printf("Warning: Pixel out of range.\n"); + cprintf(RED,"Warning: Pixel out of range.\n"); return 0; } @@ -1676,14 +1676,14 @@ int Feb_Control_Pulse_Pixel(int npulses, int x, int y){ nrowclocks += (Feb_Control_staticBits&DAQ_STATIC_BIT_M4) ? 0 : 2*y; nrowclocks += (Feb_Control_staticBits&DAQ_STATIC_BIT_M8) ? 0 : y; - Feb_Control_SetTestModeVariable(1); //on + Feb_Control_SetInTestModeVariable(1); //on Feb_Control_SetStaticBits(); Feb_Control_SetCommandRegister(DAQ_RESET_PERIPHERY|DAQ_RESET_COLUMN_SELECT); Feb_Control_StartDAQOnlyNWaitForFinish(5000); unsigned int serial_in = 8<<(4*(7-x%8)); if(!Feb_Control_Shift32InSerialIn(serial_in)){ - printf("Warning ChipController::PulsePixel: could shift in the initail 32.\n"); + cprintf(RED,"Warning ChipController::PulsePixel: could shift in the initail 32.\n"); return 0; } @@ -1696,6 +1696,7 @@ int Feb_Control_Pulse_Pixel(int npulses, int x, int y){ Feb_Control_ClockRowClock(nrowclocks); Feb_Control_PulsePixelNMove(npulses,0,0); + return 1; } @@ -1708,7 +1709,7 @@ int Feb_Control_PulsePixelNMove(int npulses, int inc_x_pos, int inc_y_pos){ if(!Feb_Interface_WriteRegister(Feb_Control_AddressToAll(),DAQ_REG_SEND_N_TESTPULSES,npulses,0,0) || !Feb_Control_SetCommandRegister(c) || !Feb_Control_StartDAQOnlyNWaitForFinish(5000)){ - printf("Warning: could not PulsePixelNMove(...).\n"); + cprintf(RED,"Warning: could not PulsePixelNMove(...).\n"); return 0; } @@ -1720,7 +1721,7 @@ int Feb_Control_Shift32InSerialIn(unsigned int value_to_shift_in){ if(!Feb_Control_SetCommandRegister(DAQ_SERIALIN_SHIFT_IN_32) || !Feb_Interface_WriteRegister(Feb_Control_AddressToAll(),DAQ_REG_SHIFT_IN_32,value_to_shift_in,0,0) || !Feb_Control_StartDAQOnlyNWaitForFinish(5000)){ - printf("Warning: could not shift in 32.\n"); + cprintf(RED,"Warning: could not shift in 32.\n"); return 0; } return 1; @@ -1729,7 +1730,7 @@ int Feb_Control_Shift32InSerialIn(unsigned int value_to_shift_in){ int Feb_Control_SendTokenIn(){ if(!Feb_Control_SetCommandRegister(DAQ_SEND_A_TOKEN_IN) || !Feb_Control_StartDAQOnlyNWaitForFinish(5000)){ - printf("Warning: could not SendTokenIn().\n"); + cprintf(RED,"Warning: could not SendTokenIn().\n"); return 0; } return 1; @@ -1737,15 +1738,14 @@ int Feb_Control_SendTokenIn(){ int Feb_Control_ClockRowClock(unsigned int ntimes){ if(ntimes>1023){ - printf("Warning: Clock row clock ntimes (%d) exceeds the maximum value of 1023.\n",ntimes); - printf("\t Setting ntimes to 1023.\n"); + cprintf(RED,"Warning: Clock row clock ntimes (%d) exceeds the maximum value of 1023.\n\t Setting ntimes to 1023.\n",ntimes); ntimes=1023; } if(!Feb_Control_SetCommandRegister(DAQ_CLK_ROW_CLK_NTIMES) || !Feb_Interface_WriteRegister(Feb_Control_AddressToAll(),DAQ_REG_CLK_ROW_CLK_NTIMES,ntimes,0,0) || !Feb_Control_StartDAQOnlyNWaitForFinish(5000)){ - printf("Warning: could not clock row clock.\n"); + cprintf(RED,"Warning: could not clock row clock.\n"); return 0; } @@ -1753,6 +1753,41 @@ int Feb_Control_ClockRowClock(unsigned int ntimes){ } +int Feb_Control_PulseChip(int npulses){ + int i; + int on = 1; + + if(npulses == -1){ + on = 0; + printf("\nResetting to normal mode\n"); + }else{ + printf("\n\nPulsing Chip.\n");//really just toggles the enable + printf("Vcmp should be set to 2.0 and Vtrim should be 2.\n"); + } + + + Feb_Control_SetInTestModeVariable(on); + Feb_Control_SetStaticBits(); //toggle the enable 2x times + Feb_Control_ResetChipCompletely(); + + for(i=0;i;o0D&{0V}% zP7oqG0N$UMi%{MPF)cZI=2vqNr1!16ip8=w)_ql>FNWCu-gu&{4i69J7 z@5=-sNWHHF{=w>lRS-hd`x-$Qs@~TL!Z7u|Q4qq^`!#|PuHJ8eZcy(x2||>5-zo^v z>isT3Fsk=^1tA9S?V$E0`voCZEjS_w!`1uaf)Jb+;3jIa6jD?@MF>HO$`I0 z#M!f{X+VfiaIWMv`!p>X5T7*rZ8KPWd$bU0wg>`%cQ;zX8(N};h_+}Up-k}3Z}jqN zfJPjptpmcsX8U0=HUk(&_oMBGRB>qw?J`Wk zOY)#hyjTat+skeN>i{4hpmYJ*iftRy5xh(CDogB1yDU#nyX*$XKO%WOc8B4!{(;fq z;$QX&lzpM4WfGisM>z!BcNqfjSOZ9?gp98 zf&ROc=MZmrJ^|02{5b%g55RK=e~y6X-SFJbpX1Z}vxPrHUzAOR=TiP$3D0BUxsX3w;dul+oA`4LJO{(Gkw4eL zb3X$B3>?r1nz}{fhQvlKMf)&FUNhEX=QIkbwT%MVln3^cRSl+X9g@y1Jj|NWTp$G4 z9TJWp-zKACWi5Wz47vR+5+YhN=;a~vLuPCSLcTo+FGhzc3=x*C!OZ zcEWbr7&k|pFpQp$dsZADDYrdCV&8vegvHAzRFb^%$I{CQnLeRal2_gxYD|P%7(aPO zX(it7h1+JjHF1%cdyC#pd{)f4Lmf%;#oR%(D+!*0sddzRF(-u{AN8!5okpePnPT>I z+LrvRm{m^WQu4*Dey9s-Pbr8EJq3yk#qq8**?bLLA^{iZ3(XMIjG^7MDYaIbf-wcO@_L0i+7bxvfwgmf*p4 zEM1eDKE+z(0OwNd?Aol7;W`E~!$2?Q@n*s41Tt&D(Uc=8fL8!K5n#Efcg4F{i(VN$ zDa2ZY@)kR6y5;O;68V~ zO;3%E^3OcYi`UYdqvPYltXSLZ5FV1eGB+~fLRgnVF|*lh0TI12@6bZil(5$6AepZu zyfzlm(v0EWa0SQvgn{ldWu}KSV=)QUUCq^kus%`nMlZYZaWEcVuZC?20-|FzoNb_5 zbvF%21FJR5r6yvgHED~)<+o{PTKeGdIMArU-H#c&Y4`WZv@m^e$nx7bR>}lJHu|nS zqd~|@9CwnMz6-ZI3%5H@Dx{a+R!Yo!6}x4g2w1A{tOgDj^!T~09KK%<&p*%MhxG7* z8V)~_E7-A3DuYLoc|nK1!Xq0v{FEL(xs$^?_3#pv4qC8={!~@a02kcObWs||3881x zRG5C7!+9sEf|f^cc&HwKRuPBu&QkGbui0 za63~G6g+3-1-1GLYrQ$VP7i-x)lh>TzFyT(qaOa#L!6F72e&7_*uo3e=n4{FRvEAJ zfOm8J4SM)S)fij!@K@A^ZPLTHbRZr3#!0j(=GX|7a_RckAINt~QQiak6kzUvM&mSGcW*|9%&T z-=(Hc!{zAbNF?nX=i?t;A&T~fD2Wt1FHJ=_ ztKxXVU~coe3UDugkEMlKv2xUNB#Q1g4~_W(P$0StuTjXQoWN(83b<(lx9jFffm#Y( z)j(kdnMd2RLj1$Ig#un@)-w~VW^KsQ=mSBxk2RMC(mRA8kTOVNGiswQ$lf6!8DzVM zwq)l|VPptQ?o7!zSvmSMG6?JB67SC{@Vcu`MF8_MwN-aXUdb3g`=H7LKBZh848Y~ZW>^7182eBAdRTnz zU|}m*XT-(c>BO-`t6Hw1GZFB8TWI~fVd7s>Xyb&i5UnftOFvXTD58X#3PaLAy~6s! zE+iB?&!A*p7+*Sk)e!m2F@&LHjY{UBh;~eWgyuXP9;mg8Pbbp0hllnPB%x(CbvztR z{NOoEY>A|8MbYFmJOn||{4QV>MMtt29!UCP)X5hVYJ46*J01=PN7eRlhz|zzyDreG zqGxbrxXYSD2DLNN7XnI4hillrpe zC|sk5LSHNXS@>`w4VYX2OiNqCbk4tXEbT0g5<7!wckxKNVsFjM2e?P$ zjKy^BlpwPG|46d%3wp_p3}GCi=2kkuD# z#K4}x1Reg0uBd5xIQ`MVf#RtHw0(LI^_?0G9oso`C@q-UU)TOq<{b+L0_Lb z)IU;E*-*!aE9lEJ`ltSZO)sEIC3V#*BmjzN5+bYejOeWuPwe;&rZPf5p;gmTLtN9H zw!?Di-f2H%l$cvT3Jgf%Ry1Z^}*!aHjltHYVkXUn~j)&Ls%Xga!- zl1Fn$3|;qVy!go-+Wu&iu8E(Vrj8}y^bgZ>Q-ZkY>rnKpMDS;$U=0q61m-dNHF-!3 zwUiDen?1X|GwX@SP&Vlc&$4WoOaCk@2ErJp=a8wiWnR2^as=pHFU-dv-}EK^k$XWB z)xds4>U(mjqsfoOPuf?GgAQ24SzrKxYR+Rl45%PM%Hj|;ouWE<9-CCc6lG9UxG#%t zeJnmb5>pm&T1Sq3=J*PR2uo28!8NxsUnud3nRY)G64qCT4H-m@WvQtA(z4Mckvhso z64Il&$In4?r_iYKi1;Y)UX(skuk=Bn^zvSnzKZ(KjC(XH8SPNp1|@-FxQ6P1GMwgd zddNULrI+5>$5n`(uT>o>q{n`dD1Jofo|z*F3^tFh`t92w`>bK1=(?Z>Sm={xjIz3V zuJDxt`qr!<=xh(C)ivwc)Ti$?z5qE9FxZU+f??wVG-d$<9hkME8bG`V_pB5+h_+P3 zs}UiSs^b_~P_&;fL>6MPvtwHi={lA%&A#+VF#Y-Lq5e^uTw>L3n?(yA51`R=e90A0 z(RBW_M|99oC+|2q$G<>m%f-=X$Ny`eSiNJ-u#C zviDFeG*IjZ$_N7g&>#FmGV312wPMTygVMMO$~A+MVA>xS*I=O0rD%xEoq7>%ybWc> zJ$d?WgoTY4*+#e8lCqy-`!wJ@B7nBK1Y!K3UI(Wc0Dc(c6ZT>ARM!q(HJXMmF_0#j zyksOPhgoeXeY93TdA|>CcgcKz<7KSLY*ZQhLA?#fC+Js?hwF!9n0S97HCC~xyr?QR zHU?d2sMfverU>!=n{-`OG`RUaRlPaPcIGf4fb#XrbxG9GkwGnQ52f!`2a(C11GsBe z4J}c5kLmfyHBKhND}z(6xJz9)SpW&H8})Uf;A(-u|hNzjQ-ri zSocD_Rx{r}W}OF<(a?t;F0$plr#$)H#>~3g2pr3^#b4f_N0vv&jD@8LWW@U#Bfmu5 zhtr`e3c@y}s4)X*F^(m$ann%zS2e9&5goY<2|d97h6VofFcU(FFLPlnJ)FKg)0a9| z7(lUx+L2_XYK`&Q#nYSWkT&okZGhn%Ac?oG(3T~`>8rIP!(KVcMPtt0E!wR+vXz1oqorXGB=0Ip3uqrz1oJK*t^vf^U22?Z5#d_(!zsIC|e${CE#y3$qw^TO= zsnSZqMixc5%f7#*DjCZ9>Fa%eftMw~if_9|nW_QsKrL)V<)Rrae!r7fG(jN?E?tG< z_iJg{lkxsBtuDJNe0nbZ>d9#Tm_s_y;yM7Gb%6}^3+UhL!u?~qHK67Gu{a4SJ_9lS zyMCa5Y=R1U<*E7h7uiA-TvwSSyqL%3DusJh#tOJU%;A-g36r3=*I`no*!j+B=!*y_ zXN|=+U>UeiBZg~AKJWFZfMf0jCywFtXGy=;6Y1rrlEl~|YWPup$hXtMY%vrIg>ldV z!ir;H?%nCn>6=U~PLqn#xWxIkq zR>2*n$NlLIy0szR?pkvyF_Pi{aFvT$6%!vm+>`eaB8&e>!5JjWF0^D72olsO)J41E zjd`H97Vg%J;A-O}!G?*%2*(hZGN7T%jq=So2((w{K<;$I>iE=Gne~A&o4GNABAI7U zypC@6d=*yrt3#5mS3@5pOXBr~a5ceoHe55{IvuV?xK4&^99+j!my&G7G^ zP{Y$6W8ug8aj<|6Zv>;)j)S@M^+p&P+Ho+Kj%*sD9}9Eos|eDJg}I5~ch}zI;z)3R zn%@_}eLcS~L>yZ9Of-3$TAtCxh>mC83tX)DRCT&4wC4~=KiQ-0nC=7mYqUcJBaHy} zP}z13aKJWt;21PGNC$A36*RDcth0h`yHQTCm^f}Rm#I*`!1JSVVe!1a8(*2oy7B4fgK)w3{Cxl6jo2<0Di=OoMoZTDyH`9) z^OP(a%au>)%dvmC8JY)dR>N&jWEG)V(29Y?)4tFY0A% zfgpZ8NVeZqr=vrnrWbtTho6$fi@1NKrkz#ORU}p7vjNn73}{&QUM1Tzi3%2VTsH7IkI z(RCh5LSaopU*`8094_jffJEEPVW}^mm+nQ77qsgMn7VK<&Vj|`%hO`5$VH{1TGk;3 zQ``^iWVM8(GPDN>^XUZ*877QoA1+*X3jzPH(xm7F4-CiVvc5YnaA6Ls7BtQnE@Ri5NYEP%_*!={Jra_R4^q6Ej zvuX>ufimaCCJph=pQy%LxPzS4v{&s-MbGMfiT9?=DSesLpTB^dkp;*ZAommqxu*no z-f2WAh79O|-C4g8p>)lr3I1_w@{CF%opx>t6VGg>*EdCp71wCM=2(xVtZhAp%k z@G6>V-R9V^xDI5fb@$4|c&3@QZw{HnPXvgaXHeZRF0V`C8QkUt)sMhTMQ>Gc-$y@g zF*7iHODN6`Tf)+{{r=oU9L-n(;&8MLv$A;(%VU;xeQpGn!}9PE`ll`Z{YR9cirL)J zwdJwiI%yUCot*2@?xla64IBzlTxF`Ca|WK(6@)KuPF3&C`QvE|tazY|1u||IHNqi@ ze{Alhsi~p^_WwMB83!aqwvK|W4BX-xT|LTw1am?>Ve|w^^E5YIlDHIG?TXOW{4BPw zM4)(TCGGfGRC;_bSz->;9`+SR?9Wq;$MEwo@ek!R`RDQCtShwa=lT94uDX=%o%ARWgHMK?)*xU5j*=tIp4Nx%1)#~^SE|QogE8ZRip}NOF)3u!Sx2xr_ z-PmW#PhO+aj`@?yxAWNs92HAsf~Cgqf$j_HY2+v8fi$8?h(C*F!6ZWmCw_c@7XD%= z^?J2HjPIgFug1^$cr0ITD#l_NX=pBhs0i)95c0=MVHe8^r%6Y^P8N%NKStNr3+3P4 za2X7bgdxc|6jD1w#nlITsBiU)Y-4owGSFWJP%eFaWMZ1fG!Ba)pDNZm-8B9bY}CI# z5`ycKua72BbJtKha90pn%kFaE4yw3Uk%L|cB==VqMPF`jn65u5rbTSUSn2y13_|6?R>`}N`}fAbyK z*@Wzocbn~kYETh*pgeOG7*x??4NW#Ms(3Ie7JC0?ZJ)-o@+caQ?i|I+&8la`a}?rA zI2ePw>rcc{`<{Uz3AvK^;WF&ZG-CpWdd#W5@>Ds!vnM#U_8!zVV5!NH&?t#VFJS|) zD+?cdC@EnBAkU_I-i%H`$F7oS2WaAdN}@v&kL;wDU&e|RU*N)NLc--dFjvhc4J@3F ztOj!G((*dWuQ9k@Pu=wCIF3Zppts;;vMGD889lQ83^E^i%{NMxY&Yb=#G#*ZZ|+iERHv@%p6Th^@IQ5 z37C!J(kwzc$Eg6E3J;u}9LK7mQ{{ov#BsK0=vbN-&(WN`7Z1+nNGCOfYCQ;zS@Kh zQ^ZHUqr2Ws4@+cc8rh0k{FN@5Lc8B(Yohj%WFeK>^+yh>$I`m?7V-p;C$$NnzRt$g>^a1eW+dZ*+ChEi9FXyI&`|(OhrbN_= z!7X^bKPF#%mf*$)$N;-gOJHl|eZA~9@V)OpR2+SjT^ z4G~mNNnirZTx>%rG-$ca1w0p{gwMTbVKJO&^ALA&KM?m}JmVTloxd95pLkpq7`@xd zgCQ_?czAygdAkmT59^ubP!)$MgoTkk*1ncou+FTY0fz(q6T4K7FbkF0@qy=$)x~BJ zgJ}*6LHC#d1`$JFtAn>!su2iG0tPtu2k)eeJ_Z_7b065nz0JG>LK$H;_3ph#P3z;u z1x-D~Uw~(jxcGNbI-Z}Yq{a_?JfeWqx5jGBO5w>js?g~`2Wwcq1+VP^%lUpiSkAiy zEXUC3lPPSPNHZp3HHEQpMlP*8k^_7F5AG_{2jRo;kfS;i=q;;zLp1%v!vn>+w|d0m zb5BEdAe{c|r~%IB;qjQ49vMIvd^prU$?Ous@!^l)1VZ6)T_V|X{24KFI_)~1k8ay| zB2}Edla`*)=aXiyrlyXO1m0XaF^e5$OR8{D?dX^vQhfok)Fu8ylZg zn`iuA4pWJ{(rD>#!+a*f>TKdYTKn4x=}DVlfIT3H-G$j+MWdd<>dehOg4LPJSg<;C zsuE|+j#Jc$PF?9!$A?de<)?eoXXt9TK1X9f=b_HBG*D-}SO%fsiKqONuDVDXfA<({ zhkBSuXV$7%p#gFJe}@FGUZ52pM@5C8U(}8-y)w9YB~8BqXxfZaGP-Lfq%M@54#y=R zjU9c&@0H($_$RrCnd8I7^iL;)-~`wIeN(nqLsOz76aS-@JX-&swdB#MnDthC?5nu} z^yvaWK88m{xH?DK*bl{Ege7qJ!roiidz^O3bEBE{8wL~qYrplG6#jV(I!DkxWE2L^ zeqfU^;Cgh8FP_l!nTjbzcsuh@i0&NH)M4z<;#>K#@-icNi0=CRVEZTtaDO%knq(*w zOzA9}Aa1*W5d*q-COqs@ZcMP2C^*JUj&neV1Ct5l%}N!Vwh)f9QHP_@Dbw+?i`!Uu z;$o%{s(|@Gki>1%dm&KiAxMf2N2zb|!12@JD1umF{t@W@KMW3GZG*S+p#92Qd0x%c z)(U#@5AY@eHd|kmXsyH(+Zz+y(>|p4dg4`EOR4!(RPWTwXw9i8(ON<`oPzvw32j#{ zXO+us&LX^VO;q>{_0~KsI`*M0rh!xuz!1ge?;8}@_P4xEZ>=3K9m!e!M z{V{!swM`PldP(>mPUlZbQ@gl1!P=^^)vc}-f-vb0z+vGuYQH3I36_Mt${vqp)G2uG zhgyWyA*Q@6%?sFxMz1vEB6wHzkJ!Lh{*;Xp=l*H9eIZWr_zHV&N6ybIzxzELJ&l+O zus{VSB*1eXJc}MUi2#G-M~n@{%YrwF74=(da{*TpVrN6S0Iz^T01Pm+ z9pG^9pJldW<4yWKE^h>nJ}^xe!OT_2uwi9Mcmdj2$?^hYI!0ZF*IRefmRmsylDH`k z6)~nG*;^94x1mY7-c}bk#Xx0$Nu=xLQZosb-yTi|%h5h$$OOSA3Ej6Op(sXGFPKXo zsxHE8HCOefew^X}+S!?Hx3*#;8cCQ0>sHh_xCLJb+(GkiH8Ijk%(9ioEI|sXWFrWL z3vK4mOqS##c*fSLFOLe8sq*m`6?(lK)jLFy0MqP#`ww$9||Ld_4gR+c* zkX0xM8w&^=awWVWDT15f%WJ9OY>55k)66xBEhku!kP??wK-^~&#TIrh3EE=9QJe+Q zw}#nlwGQ?=`f_MTp5DbePq`bCk^oCagRUW7;>(eA&)NC*mu_*Z!Z;YZFU8~*^`(_K z1%VPIv@$S9C+t7MQu(FBitI1%<8su2e434mmzlc<*)h@rqf2Q}l>0LCWh$=yIDD>Q zG~4=pc_lJ|0!<@dj#P=e8~HM!`_IM3zVsrrO~T?dV~PW+7U|k1zIgim+vnaR{wZq| zXTISu-T#+VF{O=O{!6?FJ7WRoSlnQ4ANB$EI|nY%m7E z=w7(Q^g|4auLn5nrB0=77s3LqRmh1iS*qm1!Ndfw4Mxz?3nSA?6$PaRXedQWLUxuq zW1!`@gciz=DHLlo6l;)TGVS;*Dc0Ho?L~Xles!QlgWEz)H3YS}TJ zEaa8 zYN1^h(*sknJH7C=q2{FkGJX*o@{@C1AXtf|RwzCBlVh)38cJ7ukt15IP%oT*{Ke3~ z)LKnlt5VlbQ`e!?U3&}b=6v}OOl#b4umA~}!iyp$wDQZx$jbNIzkHlTvcw@G!9os^ zP=r>6%yU<0Mi;)Ku(u1Q2Mf);WTK&$V79ZuZMwK3lGa}Ox0^*AlTBH$mQcrEXADk- zq+0V%23EXYE$s-4rY{flrvtto5tw?BcPDsl#|2vWby%3SmXA?Lfsj)wL2$*OsLNqu z0<53lu$RF`+rJJG6E-VPDRN^j85T{3HLC~jn<^oTnN#cv$AJK73kk%qDgzJG%FAIP z{Rg-zz+k}Cr$k2D=!VPjfvI;Ha|j_|%C*pr%V5sX50@v1&wz46X!aFjdiROu0v3S> zvEv^*cy7xwIzxr)2kSF0(hXOl)9QJta%jX|%c{aXYUR<3P-_G)RgRRqYi&~D`dUpl zX!18v>EE8?#YPVikE?KxYVe(nZy?+d!CNw^xzja?8`i7Y?c|Lr)*T@gzxXgblH^=={`S-^dLy zl;cNnO4PHfOWtt zfty@mvGN?z^e|YTW@EnPA0`ZDPBw5^i3 zdTp`u9y=cg^e~BxDH^PQoY(K?!08|x#nmX@EJ$y`4Z~dJiYtQG49KTU1fhN5ZXk>a%hHUXzRK(Q*;cef#aSmQ)v$`=A*(`FU3`Hg@bxLh$13FpdiHv3U^O8VAKJ9G*lQFV_@rP73|?Ig*DE1JM3d%ajJO$upfQuS<3&4W`j)^1~kz?B3vaQ^%d?AR`@v<&WS+iU2C)gsN*%qz- zZjfkgpdJ5{zI@DGNnF{?S>h1lqGZGY91qv@!m{=|{!yZn3d@XAH_O^{0K@mHL;28b z#AhB9Hc-p=lSFGH-Sd5RUo{!2;c7cNmvHk9tIEu?khHf>?~ZAgsMc^auWhf zhlZ9z2{2ne_mj=YB(cpZkgg6g$84qn2AygERI@;__Q4@0gB^ zu43mG7hqUKr7y3B+XLz-fR&Ihtc3UkH#P&Ryopsz7FK;bP}@nnZiUQYk4*}-u{8i* zt({L{;c_SaFoP;%f1U0~~G! z_#q9P&HZV{%p!nCXy9u(eks7$XyD60_E?bHV5SFd2ghetx-H-d_+*vhjGLhx>a+Q< zx!Br5yKl!v{p6fx_@8n(ISLHVWt#h0y-tGvka!Q)yq)$qKD zK)WMG$^*Sg&Z5exj10)iKi;RtChIhCZ?%sgX4#1$WS^sGJWmS^pQ z!22C<6yo|I@)BMhLh=wLEHZW~OdA*6e-t7J)_wJXxdA~gtLSKXFx4k7S8lgn~# zDT$Gn1(9I8^}MFvT=&qQ7d3F#J;2Xu;I4asAJV{G_W}F0ar||43u_6)(o{hTV{jFJQ_?!4YpqPDC?3p1e0`e+BUf(n1tA; z?bO%>jH{`a03T+-ahJ0SG_MDX)6m%}_5)?^Ow2U=JdOd+%3!@T<2cNfMd*XhsW`(! zK<}gdn&@SKZ5S<=hmhc;ao71MgPDBlPA;(e5yUQh=5yR-c~c0<4z%tm6VxRB)Oz`1 z2#FO}-QF^kWWq%@4<-3{Z5T>Y@w$h@yExn!N;1=}dl*UZ128@c$8W#C0RlMuwnC^R z{BjW7L$Fdj584U&&|*k3zkNYo7fPlCj=Sx4)WwN%S11Vy8wV58l+)-OAg8KK+ZJ;K z)T@>a!^o5na|Y<7QLmFJM6Ml1qN2=ZsC!Qx*Kl4{FguknAx$tB$$N*9r2NU-c)1t6 zEX_j(vlvA)S+z7A!VupJW)*k+t;!_FY?+Xzz*T$5vz zXG;v3fX}=5^Z6L1JSbKvmtvuFk!~!BP0iYi1GU)sced(rH*)+u5Skqyf>lr)S8A8s z84EIvPm{04lBHqUK}y}fRqGX0`1Zk?;l!WhXRAF{C5Z(XFXLB-aH&)Q_W}44Wgbk| zS=Fml8>>fs}AFr2(*pyBsMA!!%cNt7U<~GBYR{^JVXT9ow6gI#E0Zz7~2<} zVGpEp7wO~#$PpufPVTwB>EzBE+sG`tSU#!)1E;di`P%c=vLD~Z`n3aji}!0J4M35ILHCQidfVJ~KX(gz#X zr0|98WlxV5-R5ivXM=}B*_m!hFy(e6sjt zmUYj~CmptK2(Hq259L-Ue6pBR47s6Ee+F7=nlX1TwoAp6 zMDskHRA3IqoS}hTk>I#a;-^(}UOJr)Ev^fv1#<(G$T34p-+-DEN_)?K&Qd3hholhXm2 zPOw9>0|kDsT<%H+hn{=8FPg>9t`w~2cJi4JRiu#ErEc1suWNV~wyGPCdANDntE|P& zuMYFqR1J|Zd11Rv!eXiMAu$MfsRukIF>|798cRZY@Vmk~jTw`hU)2NnW&LOT#-5OK zQz1gM#x)o4D7E!I2E(vm&)X%5V{ZVD0NJ<}7Hhv*467Su6}LxjPbFbEMV?9}(*oVv zfrLr9TsfLVg!a~Fpod{tnhG@!!i$6!VeY!f8qz&R$Rfc;qi|O4$RJ@My_OGi z1svY#B&m0t6D}N6CJ777&v46~*2MZ&C->*4-Ew=i_uZeLpOZV&`;hx0I0mnTzUBUW zn@grX<-R!4g>!KX3CqlHaLYYfJqiMGiCEURj2EWM$)G!(HC#A~`c9Ic$sh^6D(th# z@{tS@)q7d6ODIK|Y*K*^10zUyKz=iMh0u*?=wUY9t zT#-pWOe!crm?S1&!jXa_6v9D1;TBlj_{qoQ!f_-dq=2oNltv`;q+P*Qxn>+m5|gXt zt$2OKPd+{l))^bG$XD6*m>gh+Xl&zl)mq#;#RVr7{-X}a-80EpxyejY#5dNWs|%Hn zo5^5t_cHmsnWWD72nN9K>}EPyvbIDE`KNNyyU_GUk1M;;bhc>eTfKnJ z4rHC&L%-Ph=go3M4lE{D-EK-0gP?;W)VZ+Oc`i%t1pMC1`Z2><_aJ{%+1xe)i7yd^PyyVV}={{Ra^+XPvAnZebgDD^36Q*tZ40$8}i8{owon9TRxRf<_|7(IeT!-5JQFf%N z_Z~RCOl~WLl_V^Jt{0MUvQzdQ59<^4(dKdrmE%38p;KR|+5#u=AP&LEAx!>sJTbZG zuGh1f>SEI{fxI!nWr6{26Z{h!(J*TzL*sR8d2X&++-tJsVOaL=PLy{&OlD5e&iHD+ zXZ$X%SWtTOCEl?(RA4uDv4lJ#1i>F8H1Hq+N|+nHPi~(J(ZRdXBzc%SvH={okwkwY z?=6BQHe^Mw7Lmn+xO*Ib8BruLYNuQ=k-QZ9oJ)J)-ngwzFmN&uA4Gm9`%WSw%eTSW zjoI}W$Alv6cIZYIXZxFMpt3K$KlcYndt-J*__$p4P4?%$X5of?_um^FUkRc1kG}^I zBJ1(zOoHWYlSr0*0s@+``7O~#lNtUTb|ZT|x!8Grr`p4A7d&Bu(vFB5ipubG*_#9pg|H2V3Y80K;szJ zGvRkQ5eblinBPz{z65rre!_kQucHDss~;g4yR}QzeDB8k zL5fNpB-x9-)d!vpS7fl9*7)T6EV|(uR~y`=NM=~b4AU-Nt)O=F@^GqXquNTh4vT6Pq5}_eqCGOo>RP_odAPn8 zLGyZ{$wCWB9BAV-q08E*}kPZb7p-R^W94L1Fa7#Wplf?QI-Il}wX}AcP;}ehqCNobi zodqNIZ8l;DuRN-11iGlQ*m=8I?wSRG+e(*ZDI@uIIm1s~X;bmtf=x6jY#(ak)&Z|W z4p|4If1+GkK{A*B>l|v0c{9b4cjB-BkKo0>)g~w&q4t7G8+fw0737(xfidS??7ZWe zxHK~G6rKMka(4xp=40(Fb~;ngYsAscGjOPBps(CGn*^p?J1u_7dkFj-O(*CMqZ)Pg z>n!u@|CA~$?$FBJ8(~LPlV<6Zug@lv@|C??B~V{{waF-$fwHKrsiAtl%uo2OrtG|2 zI|s6az0&a3;B`KT21w342DmB%sG>xz2WJeFdQ9CQTO!-iQO_v2X%6wT_7p5)ZcoAb zA^`QRenvrM4C*=$Lg6d~?rq{$vKPV%O@`1S| zO|+huug=B84V|)YrE*QEB-18Y50&|O;VbNFiw@!F0xjU-N)v-C)8-+oAN$=i7oH-- zBv_&JpC=!w#D*e{ua*|aX#|`R&=@vyfwosKv;%sn*C~lUa3W2>5Lk^Mxk4Uc14U7Y zPc`EcZg~X4TA!m_BT7iBz}}Q==aC6hu(6`6JMk#N0~%Y{Q=msq0{s{eXsg^&3A_HR z!HU6yc_2Nd!4fPl`@tRn`))|=&x z^T|}vdRFe54@oI@UILPu(s?KxB>OIaElm|R8IFm0Ujc#G1jc&+cl6-AM5uaJ;;h1O zG6YQChXJ^(xMKP3R_E1$5CcP}6#rdZEf{k#Pv#@z&G zG^GL%(|{3nsj8*3WqxE`FSu&}x1ZcHpXAD=7F7L3s~^!4y~wx=Q`%7?N%Tqs^{UA# ztsO%>v1dKY6iDHFVeY>~Bg{n*=Jy(56dsl-SEb>=0FaGXs8JC|D2D#`8iY1yrlug@ zQZRSKgmGMKbSq4p%`Mf8RGJImER|wKR}nYOSX_Z{#VJ~^s^O0$iZQqzg$Vbm+&vrK zHfamhe^(5oxB?^gh=_1%_1_1D!CcbHtjaCwy{c@AKN=5q0 z%MkZnXB%BGI6H!K6^l#lI3>U7CpTJ2ytrk$yvs^b!-{cJ56+nEc~d=^tgM3fY=fVM zj2uGlAI3I~=_rZd@MsGi;E6+%rP9*hpCROA~tvbg!q7!X7rEx&`{h8F{}A z5}2DK<@0!bcAI?HM&?dF({qmf`)(EHwu6#fv;&y810`}#jnIQoW|O6)5nyZOwk0IT z?uuPt8s}5?-+Kx6OExj9CwJ9AwU&_*O3rdNqD1a)hb1;_I9*NMC4OR zNq3`HEDR-bSB+G8!PE>+)ECMo!@CP9a%3`jNZ$K6@weZ_ubC+8W%2`iZ%yflsby^W zLGH3R)|F-@Kj2n4bkx+^V(0fPuGf^YPE0dS-2gc1Ksf6%O!C7vUUwG+GAzilhpUGu z$PerUjY*i=k*Am@8ww$Ve<;UF0Kd-R%w$8vA5!F&D$L+?%BQOEki~g9v>GzfiJ$aT z%`}#tlgPips_RIy?5Kui6#R(XKZpi5l<~1lD+0V~Wu%MB2va81&N88YBWkkP`K_y) zLH%mI8mO1X>p?Vm|8Os~HvkS_@W_LglAtha0yuYc(C~Y$cL@(?;e_$s)pFrdJg0U@ zB6s)nP$B$4LNhi#jOP4uVAETsBBk*V_>cd!)q`q zBBx?NDtHgVA5!ljD{{6ek)2>rZSA7R^Lh1|)3?K%ubd6$t@Ysya3rfU+FncrDPp^X z3WEJx7LD_fNy1v$13wguX&$dE|z8`EwB zbTe8Ex+$2QN|748Wzs5dt$~oQ>N=bm9%UZ@zb?C1k*BIv)AMEygK<%+_PiPPrzffk z25&Wx;j~q?vTH}xb+??AuGNp*g*?h;JBj>LS?R-X?t;uob#NlozKjGBf+u9@%fAnn zPc6e^PW$D{%gB3S*8S`ZS*!CnOyT%B81_nTvGXs-P1o=5$VXO?(J9+=EzVS(vQ$e(1>Y!k z{`Ysl)V~;h@K{-VU8FWr$l0@L>wRGMsrrgUhFsuX$j~gWyEFnQ-AxHMbwVw6A z?4|EZD-~(G%W)N12yu|N-0~#pZ|9Lv={hWD0X+E@P9=Id(P}~Q4&dQRSb#>LJs0bd zC*t>PPx;!O@_g}~3Uk|H=}ko*@!R!EgWxMl5%vHGyWkg?oK8I6jmX?U&}+bunjR;S zZ<}B!DP3ThUI@?2cv&gjj43QT=_lq+k zF>Fw6dJI)||3 zB4m_(HP~Z$Sp`yqvKmdpEHupe^<-wf?Pg}Zt!HNK#N-+82M66$Zth98sI zB2!7R|&H_GNK*KWh~_K(RV{~6q4{`W$;3y6e0W`qhX zXfz3rnYsT70N4mQ;%V}l|6?VJkN9S_eDZ0M zp50=>E)2&u{8ou1MDm6`2E*#gQ5N(HQSeioK|Jqun3RB zx+W4Ef4Lr8!^iD)&^A$@A-QlJ?qPgBc2n+bB0mw`Yo1(bCs96STcKW->;OEmtWDl(C;91@j&VQe<3564#+2%K zRkQ%_$vEA^l?^3RTiIFJ*Fm!LFX3s#i;TA*p5Zhw%;o;BtQ*U*JxGUr=9ygjgwq-? zI~>q?8ePXVLtx*99o46x>bd6Ve74EpV2|Cjtk*+4WwVBL7{dYH$DF1RMgQ=rD zR}Os^R)PS}eU?OJy5Z)oX+}xtx6e&WfVlxzJ>`;Tf5|P+Ldy87%{|~po(1m+c60Sv zvIKdQJ_iO}UaR&!O!A=;`SK{%gHe>rw$`J1j2hmj<*k5wN$z-#Oq$?{qb@+o+X1IZ zu?0c#0`C*BY=BTfo8FYv8qlpmK02aQxC64g}+xWzT`h{B|{$)%Fik`_}MwR=6TTf zg==!l^CWCq`ArUg5$AIVCJfC5?86C0{G1aW7eM*Iqnzy9OMRB6^zmoaI7VV=VCh5h zh;<|j6>eFlbnY5{-LnqfeyabYY+g^I!e)l@j(|=$kMCSFziV>T|5dJK5?nIAgvpd5x4Z!Dvl-<5FMwmR8L*R~(?sg{ zcbr`KQ!>;3=}t5TjMAVExcix>vI^WAEfV?k46HZtWdBy+4_@_C=I&uVD#Ad;_P}gC zvlASK!R>fHE$0SS*9>(yPB-A_KS4vzt#!!jUnDVsGf&~DW(PCKrxWF(4PY zyy=$f?3sgyUW8+5VYVR9VgzV_eeM=D%_cEF(DLP%VF?4*fEMMN(L$cW=e;dtX_O7l zrLnIVsOvC6S2trL`LzfW9c-q|@SnvjPa=Q1C6~NH-tn203->#>P&iElC~Xu+m9Kn= zV(0qG7b#ifKdTIlK_aK`9F#VZ_r$Kmc-WA2ng>1&0uHK7Lp_ z0~?!WtmtGN$>Q=VHVgnCKZF*_zO7D<=W(lB12l%o<{czH>7!w&JSHdk=vE&}ybk!) z^12=5k7C7577#;s{PxVj+E>XOuk`ARC;V$GAVX;GOr7U zb7ZS+0gzt_L%;P}Mz|P~cq0@j>$OUyuni zY{}ewa76Hk$;Ns?B8PEAXuhRjGlSMc-D`?pkL{(=$+Gbn`lV#Kb`N6-fo$&zEZm!nRQh%w0A4LLwrN1QcGi1o~*ap*^zmv9*Sw686L!Q%BWx#4XR zHD&*sjGlrgK`+9=Gxjo_IufvF5q4hTKSvpHT)nI=^W`>4?gDy&Hs(l`^&7wf-a(i$ zvJ{yMWpghu>pLVV`~7`jA&3jzIH!WqR`@6;!RzbSTJJYOY9BtuoNvZofwJ3J6JTjo zs#bUS+gK9-#*7b0x2k1eAqr__(CB|XlDu~fdmZKm1H)GaqS6$Ok7wA~K*y7?ST3)B zm&DlTuyq-*GR31i`1z6(sWBC%kNpM;V04@4d~-CU}%Vfb*W~ zceP+{Rq0g%e6?d7V@BA-3p1WtSO0)DQqq~Osr%~-@T&g6@~``{XLBF3gx!<;5>gN%&hO?EBDd}L@i zK=OSmq08Q$DwiEVoQ#8x10;-aY9aD_zakNy)C`}%o&-=aeFBjNUJt@6&Tu{X2}Z)O z=J-8M5pijEU9YRH!W#bX9up?x?{K8=pigN8b3?8qt zOzu7cirF(=?mkSuL6Oe?nxuM4(|L-d``F@uL7Z&-7+x$fo>tg5en6HCuEbQJhVvU! z<<3LcP#tFwyHGxP1evxfOn0ZqK}X4sq{_2d5W}I5f#=HWIko5ka~(&M>Kd3Hq> zivLl}v_c%pwVgINQstkiArV8#M-k1(c8gI}iQW!N~% zR;np9$!j{ulo_^4KHx)Hnc}f4m7r{AFv6M()NeuAEZEcT_+{s^URqnpD4NqJWkT%ZOn9e{aUxl>pW^L_o$WJqgv#3C&;Iwtpc4L_yQdb?&oT`pQ}Yb z7c1v~OmanAiQM=xx~tNI?H`j^aBvm!*^@mfD88+h`!={T-&V_gTP^o(wFkksZ6V?o zKe_u4kW2z%j#H3Tt-Qq4B zpFAXbT|HQGfeh&9MebibSotOSY>4=G?}O(5ApQ= z-ak)j9{4N5R3+|%Ys2jX*7sKE*r$4tp_^{VmYzj z`{BCt-rWuQzaNe$&p+&iYbC$GsK@D1=Pr~-z+b?F@$~iV|6h>*4{&QdXxKekez(yB z!L$57c}{)+ja+?Mm|h*udq14w2qg#i4iW$A6P8=*yq}lg@n?bO26<1I_=dgkxbyz_ z7U%uKL&_EJ|D(Uo{}As1^a?wj1@{Xt0`sfzcM}LgE@6BC{Ds0_9Q>K!FBkqK_$z}y z5PWmVD86T}FLB7V^UyYv2$lg|4e zCOhwU7~Frq@pa#8;p+X-T?cDY#fpCM;d95NEt|M%)rwWdg;s0z^2d$KR#@w6Y{n(4 zRxC4)crw*Le6DGk{MRvJd_RUO`(}s}!x1P5P-8*W!kQ%ulsbZfV95|;y;-g2GQ_oN zt+C?B0ZJ`_coq3RI<3sUV74tv5XD!o^ClrUli@jZfCCf_}&b<*WKCTCrUI z%{VcU>+KHgUq7RQ@mA0W-)EJQXMMWj1O1Y7C(W#`Mu zgXJ@3F-9Yt48WA3bt`HY)Yz8PC30S>4xuo|LmWr&wPlD!)#!punKkO=c(pF3Bkrm=Qf|!`2N;w> zeZ4VU%5U<;Y%Zm-Kuq#fTuFf#>j|qZ5c8Dr{!W27gDADPj2Cki4d;y)zv2`lCaAy{ z$BRP`)=m%&99?!iEEXz6jy)_6RiWpL#1w^!&qVPVPG!wRmCCV+;&2XJH%W}xGD!?o zu!l_&!`%g=2@Q>ehoeo z#Gx1Az10A1Psn#Aae}9c3MY#RdaRnsVzkFN*)Um*c}UYYa{FXalJ8Cyhv}f9Q^ese zFXlf3?XeDRv~C3$=&EH4YtZwfOY`?Hh3N*19)<}gRhYSWS*`KODrT>XY(}(WsFR** zGA>+hHO>TYwMufu-tvn{Q^bet&z^TW zo3A^a&z8b6lUC*Lc@sRF`JV(=^%?IGj?Z^B zf9srfXKR(y`Ln%F=g*<==XLyg)%}cRtQ=ub-kPELD|9+{Cp(?HPAPwH>~cEa073s> zS62g8Rh6~(-Ulv-2%BH|6R-TJQ&ePRWSTfJWivF9F=Y-a=%r{vBcr0iE)_Lom^4|3 zz9_LMvB9K?zDtge!%X(&I8>z6Foi{m#w40kj6)N4zjvLp4v_nKPG`S+t-bbIYp?x# zE@nMwbPQ9T%0X{V8-HF&^2$WxGPt7yPptpUjw-yn{ri0c@84L4H&VSIUq92M;MH#Fc4L$`pg zD*gVZO9zpu^ZQ>Uh91Ddw=;|z)Hww(r8&pbc zYqP*VhK+|3y)*p&iY_zjMm00Gav1;Qd=ttjW#cLJ`yZ$=%WqWk&UvsJcnA+AjR(p< zv=ndXW2H>|7lu5XY4+Tx<}7(+1hU$h27Vds_dgC}@b4hoiOOc9j2x6Rp$uN%Nb*Oy z3_8kul#Q56mn!`2LXla$R9$(_^LZ#wnozID?|-3SLK$?EgK%6CemSX@spc*-?Ghr)<2Qs`mSLGy!)`DBJA!zXtgNon=p7Sm78I$us-()SD^d?#er~2#=Vsx_#)CuRxjA@p@#Ntt zz*C5)2u~@Vay*rIs`1p|srBU*E0z$()6Kp!%- z7O?+g(Su%b=m$M0cAP>S7Jc%0T`lLqo$M(%WK~{-Gn_DClG1 zI7UxtaOlTtP*_9+PFDT23&!XJ=;j=Uh_^*gAGGNBMUy;{hC;H!NfyJbO^$$*Zu}Ub z&LQG$(a(9pp`UIQA}IT8`uW`s{mj6G*d{ise&$z1_hLj!KQdzjVvOOUP!^z2K?HUY zfs-ZRk`#v?2=@jzJ4C!K`n*{VJ&cquJDYx4FX(7rXca~yqw{Qr1=}3~;T@puKAXPq zc89JjKqDDWvJ_a<<d}yc9y)%)myj-nv*(9^KT;1V1*sU>8eAnKgdIK4l=iQ^0tDaD^?jB{jdJ44c z8S(w368~obSFc;kL!IV__o_FYeBFKO>t&zN>>IdKW@!13I%ETOS=mY|eU-9(<&@n@ z+1^oN=(nOMsR#Em-%6>9HyiZ!CyUma8S8s(J>eP~kW4K}VZ&NRt^VX|y*P*>s zXkNQseUo}<2#R4Ql!GJ&-*n*ZX8h3OhzQs6vrs(Irsn~bnff{W`*}XRcNrL6>xogl zEJXYqV*ETGPpRp9Kwa(XPlELMrpv45hxCtXNuymKG#5UoUN_Hp)nu1l=nJb>v!v^b zK^pGnWe=)O&in8W1%YrF{yo}lp8qfihkLC2@Wbkx<%c2i2!cR(Dd!ap+jh{|vs zg)YZy%r726?{U8IQT4U=%N9tod+%5owP^L;v87aM_1;(6l(l;A%TQvldhb{#Wv$*j zW_7yNdxP!7YxUl-t_Vzkm_O9zkyfve9i-|m5e3zH@$`dehSaJC*YO%CH(<8Zs=qn; zdmmE|2OV!kd3&_kx>Y5cGd8F=*YN?G+02C-h||vN$JJUjge&#ORif+oh?Yab-1@k> zF62a-mNd&H44dv})k1UQ1{GvhKCEstchsQ|ZL+ziPTi7vqJflzLh>Pf*SeKL;@9wE z5&p*?l~DEs!sf($bMZ!Xo$Dk9!Rc0W%SQDf=Y4lSfs@LzQ!S8S`|(sJ3A6loDws+w zKMvPY*7D=m6~tiq@#GL?EkB+l3HB)XrjU3oKb{;hzucr=cb$eS&J36@)T80kZIt)j z^`uIauG5IV(<8oTey6IX>-zvLzi%{?Hmg0ZGjNYznEjhk!_NDBPpbto#E+?oCf~FJ z6wwRK1*Uq!Wf%HBG*vGCIWm!?Rp6kR^sMRza1-!-`>aYJQW0vGo6*myJ-CF%PdSZH z^y7CFYKi8^bL#RSWkjPi$z0H=z77c-#6(<&&jZg>C;TNsUn5g#|6WWoiR7E~f{K^R zf;S^xEdMFjUSuu*DOV$vlK)g_8D+_TDyWwj$bTv*pR(jX6%+r#`kBk7n+tcSTU=57xRq}-TX(1nT=osU`Na-(g)2G(!<2Am> zqbfqG;{(3*Vmxb%j(X-M)7QRaAgF-RApbNW~foVf)S3szNHi@Rj~ct(N$s zVz=-8Z&ZPz7)$%NnifDoam9BeF>J(l!+%wwM3?y5zgO2u^nowvjPgkG^_m~l&keZN zd`lWX;IoDKmNFK>ZgW%_^I*1_Z5VT5wOLMY@U<8y2j2i;eBww7Fe108Nfr1xoRRE` z2^Q9-_$4DHBxW}9Sj88gGOLNUB2K6kab`1Ut`$AV_n2LjFK!kJ8|q;z-->*znbb_> z?Z~&AxmLad`3|$p%6B8*ZEmLgsurPEwV1mpzj{ch)kEe0a^qZz%8-p`x!@pf&`6=G(aS-K7FeSqb4R-0MB&G^_0KOtdni*Zl8 z9P*Qer`Q<2vT+#W9>(Do#sP#e)(X@&idz|D%v!jeG3G!E(>9ITi?Z-)qqv(3qOAf0 zjzj`OjE&(;8^_uh4z=-A#+i&QMYRFP+VpsvUaHN-+l}{AY(+6yk)kskMS)4t3xM0r z>{pHC$WqcnqC5fbVr`VhnWe89zx-*jr5D$4*Q&S)bh^ACNBo8AGbTgdr=d$2=cLJa z4FC_BBd;1Oyi2J40Mvtn<=t8>q4peH4NP`8c!M@p4>E>7KOECUw)YebF35@A@ z48IM1sa=QuAu##R!JiBBqu(1B(vLlZTaEYSoYljik`?f-kpe5M?nDu^G%h*|UkQwV zn&dTOx*RoUzh)#a@tgu{06Yk#jTba`p4;j?W4ksy6b%mjV=ZsZ1g?RH;1uIDt$S!Z zDNwmuvF{WI;|E%R#3HEYh;N2bfk^$O*VXi>_X*5VZIbUah6C z3-qOoF_#NB==GAQzxlBv0@rC- zQ4Vl9zf93&pt_R2DPJr6$^Zq#8To0KGo9tWRlGl{-ecBHDs8L zUD#(7QrP7&o{n&B0A>YT7ig(T9BqZ*5Z9Gj>_&mgVSE#g$a?PthC8)OHH<$+NDNPq=RJ&qoCyUd zfFW?K!T)OcTmb}dmj)T2kBrlUVzjt5cif_&R1BmO*vEvuy=}uF&G< zec-RMu{Q{P{Hr!JaEci!w2Ul51={<;WkI!C22=pEML{pZBl*DWksx@WCl1(Y;9V__ zHeryobNx@Wd^j5ojxs(41JEAV_ljUx@MJd%@@C9#i-v@>X(N{|!E4BSB*qX;K6%u11DEHVNl}LQ;t2dEw$o zS88eGqkvsJsZh&;a^QMffl2Ejpk;!9TI8(+I?|+<>^-IEw1?@Wom$>a25`(wdKVro z0Cp5OLbWJGT2~Ze(g+$LmoP)f6jWF`0cT(~#>6J7?Vt*or^SDuP~eEIV8~Tkz5ue| zE(*!la$_YtR?2itY|A!--plwdE&dnnDG>?(!vi6YY3b&jeh|4Ge1WIOIvELCn|}&BplGHhr?SC!qRX6d+A@TQB^F zF;);yJ0N>xa-NnE2da3#~;Y${Eg(Dy7E^<)VEAM$ zu7*O27pL&)Kejl0mX`NIo-@&eFMx|PC)CgR@eV3{F^$t<%<1K}M&V1qY$aRc@Kw0e zgB3=$?b2{`;PE0T%o9_1C4y=*D)2B2M+{tDjw!i=4R}Ednr&49;}$JW51^o)vG;WV zD{+I^2z%TpAdAt*;qPk^+7AKcT;U&de}_@h&I%pY(rki)yxfNW8#5uHdmjS}{#SIb|MxdFWexN-u19hf|3)A5O*0|oQP3WWYEcGGFVJdE@|wDB82XB_J<(WiwI_H&m$2FiAc%zK*Y6L>~Drgvxpz#KVq4dwM$`P5ev8(4HSW&Er>wW z|BeK5&_&c?xo!aFQ4q0B%iq+aejL~TE7poy(76jDjyYHGc9%tbirQ65u;_H!6VJLeN^&6JTduo@1b&spKfIa>7YhDE$qL|&?;s}=G%2qS-i zQPBv@21I&bARu+Im-;vob9V_%EXwZl$Oo`Rq9EdVAo39{gVBH!<&m4wAobyFR&cA9 zUW_7V{f~T0i`BglcZ%tM*7)B&!b7!;5!Ba>z<@Mf|06N(U(JGmL7O28=W%P_&s`9O z%joiI(8*=+SX4G9q5+0p#dj|tuG#cPM=4u0G+zfkyoZ=4iu2HY5gaG*yaAz z4UHUu&rxMcpd&@?p!+yvcH4az^+zq9%?E!C*ME=h5#iBhrei~*$wM3iQD1BMQXLxP zc_3<3OZwU%y>44TbOcL$VR~Z| z@DR(x#8y%|L0&ELRstO<`hT=I1dn(HYZQ%{DI6Aw`7FQ(0n{bzvgmiTz&Te01~VNO z`S#aMRsa*z{gvQf%=EA5MiaP<>BBIPFw2XKG_cUw<;FBr$(WWL&vy(unP5g)WqPdS4#58 zVjRU{aI`BaXB>x%i$LV5eJ99br)u%eAOx~Pu{g_l906DhV(|gs`U0@;wH1iH#;QDC zAItR{MNqJb>1$A*`kh@KyZ$WxC$#W>3>P~ySM2jzTu2S{vw$61c5j{_5NErM^}rQO zN0d(~gTk8`AJw7>F%ZBLP3#H86uK;+j_C-XXjm>-!Kq=|Yk0cHHJq9b7tNo5FVW&s z2*gBTb-~nJEq>bz1$bhaiW`&^H~1Y~f`bXg1jo!&95nLNz~965H)-*!Bq+?IXzET3 z6Ax8j7ft<(7A@uD8c#h4I>;6sT`=`1aNz`gY{4#vLV`UI7l^64l`2Fi+SJBH+8;`t zQ4p7`WgR@|1Z|u*Q;P&Q3QBDa<7oLM7m-3}Fz#w#1f8Q`+^>+E6ajoXgZX#n(gR^TmSro;{4py5UkNe;TW zFKy}={XbZ)DaZ=!`tcH%Qq+a?83Z1PpQ`13-M~B(#%EwATnwCR@q0x)KI|PFLIDq( zcl)AR5R7b{aUT<%RjcJWLZ@T2^)f^HiM>>-@09ZZHAE zxFmGEe!|6Ce2XBoJVNV#!Xh+4F5w0euGaF>Y$!BrE09pECj1F`EAjb10k>3L)hMap22N=C+s(k-=ZUyx zwG-$_iS`RQ#yD84&H`kG6LHO!=>g_pnOJ~bFS@`PmWjXC^4(e}T*2#q;yMtm!~!3} zB@|iM0t^o&KC9(pWT722A`u6TC~ANwn#4{mQ}Te@nIHFtv8BLej8AL1gFMh_<0Pf! zrhdqaMma^Jk*HXo`Po5EIR`%Td`%U_hGoD=lNl z#XQWWt<@sE3d3k03&8f}F$i>~;%OVT++RNdql-MVQNNz~-`4W~FbZT9W9%178fpBM za={rb*JGH;-8N39<j2%<7O`ndSyULCF+}`v=T-kUBAz(2xEI^P@pYk}JeuI|H{lNK5zg5dQ z6~G+j)2lJDDR@2^h=y+YONK)Zd}y?dVc`x3EUl^!?bj>tR&L;(}wyTL~Cx z`iK^L^2Y_ZaiMUq8|~%W7P=#}@c;xmqr`1}=^|{`chk=oti%{yme286{{USPJ+{R}plfKH#fanpGhd8FAk!2KS!-9^A`kozoy+}L(M zFa!mHZT=Z?UTi8eP@#wmX5u$AJ+OGxws6J;S}sJ;IZ->~7ua;>j5jdjM!1|5U#UI;W+)m-5l9L1_Z zpKs$7EVm`mevX}%kuVUnV5%B;3zzx#WS5SsNSM` zMG7o>$Bha+v!zC8iCvhGowk6~1TCMb26i((9~%sc5#C^={uB!30<%J?SZwYq!d-6? z^REOwX##yMwrHn-t$Rm||I`Pyh~JF@c3J8MEmHxFLKg6QE#_pwg3XL~VHZn%x|i`g z_-d8|i!vD>(&9!aq;eP!;I20S{Op0$GwAXRU|L(eSX|Nqu>1~>xkRMR(DE`cNS@o% z=HUVY6OZJmPP-Ndm3q|Y>-aPTp@%SgAng|5z6tnIEm}um5PLKY$M^Y-Xb%c`X?abf zo65=w6>!;nA`N)Jwjd3Q&+n6<09%lT{Q_+&ov&JHLt5Mpi)A_U;}U91C+hP!Pshx+ z6G12KJ{Rd4K@5Yj+QR=(ARXU)Jo)1aq$5fnh0C2Qne@f@z|aqRuH8WT^~hTZ7%9C3 z^-Gaq52W9t<>T&gh0-@@kz4@}v~vBYG0(sNk2+ldvxOqoYr#vYg%f-M^Lahfe}W~%c`SXUQ4SsJCGoX(R zXgF433CkCD12a81`^`pK2J>Szn-7JZ#boBwT3kbYTFZ0C8iep^W!o z!vYU@4Ibw+KiBf*OfWPu!|}5ez}fA*Dl|X}q043&_)M`0`0zNc0fU6VN4~ zJ6$qsCNLR5U4;F{tT~9e#p2p=hDG=QQ2++kc-A$j&_6){MfJc0{2(xO1NZqX^y&U= zU)=jfmBfYQ-D_@Ld;Z09vo1xhxDvUGGtKQE7)h6AiFGBntXzB7nmf8zI3V)?Zt$q`$WG&Hdas9_U+i)ObTqvWhKn-ySpC G!u}ubnO>0q delta 54085 zcmb@v4O~>m)i8c%Km~%jDy+C5tcVDRx*!@rzBFJ~K}AKQi61MA3JFFum|~0FCBXy} zjOeJNDH=>P(MD5jG-{&>wwh?74fai1O*Fw)pPEEl(rO>`6tnL+bLZ~fT_8{2-~aFL zx8C_UbLPyMGv}N+GxxIR?|onUwr@i;-EG?xQ=B!gRiW@xlpYF!{}uS3+7yGI`co8I zrzjC8puCr?r%;~=_2Reb^thloxdy8K-u5St`cXp*v-wY>OH1Ew_RsQn6k8P~Fa$9h z{Fas~%HRQNx+DVn3YF;?=txT^DvF<$PEizpEu8^0YUx}>>8Yg)fHo~%q$mMedOq|U zsyIZ)B_)dTfL2kiD8X8~Qc-$q>1svkqor#VrLUH*2hz3l7Def&r5hEczn0#kCbQA}F;ilT&T>FY2JTKblvL~7|fiV~%z zI~2t%(@XpnWeBDn!1g7F#C0M&aTDnM461DVv=zpY^DN&SBTDn|OMr-LxMX_kWw&N^)-8nGQb#Js&Q6}ud!nt2t71F~> z{r5BH1IdwwW+-Zhwr$v!)hLE+r@;?!#MDJBEoZF{M8?_z#(!xG&TcdKIj*)B)?_cO zaC~X382_cqOSLJA)$ft})wb}ehA1VXDN2beQv9>3{rsw+Jd`!| zHklq-jMX>{=rAHfF;I&Qu|2Yzwe~h9%-Qd*-bE}>?N|MPUzPKL;yTe}mr{sj7NxY5 z8T!nj@JQ?z&o&GQ#AIV1)41ZgB(p+9!yvz^O$o(yn6AlI0ua%r5ykb8r%5)$6%D2a zVA!obri3|xg5p5`EK#L`+hEOyU=xdCXjexv`x>+KeKn}`CV~l4uJkq0qVL(gzL9f^ z>#_gTC?#g?(EO@Qv%xQQed*2ACPhhYQIzUl$cm!d4IsOkO0AfOYRoplJy9KZW#RkgoBznC=}M$yuntj#b5 zABp|O;iIHqtYg+x=sFnC2dh&+w&U2wwDe1~`pvBAjCc;AESrk{t2&b}S0t@Wl+tELyI*^9obkvMc6vSsyWLco!>(iY6W>IGA2dtVk z68PUH^YxG)4Ea`>-vasGkZ+OsJ<#uc$T!RU0m$Eme3Q%{hWu44sIdlFZ~_W00Dx2G zK@Ml0gnWg}pNITG$lGN866AM6zEI|`Lw*C~b7cM&uMpaZRWJ@NcFBNbDdEY*^)=Z_u)}G^ z6%?@6tV&r!U~xUP46uMHg2fjA9cW9Zo?RcX&{%jIt2-eUvQf$!LS`BZr~Vj(B{aG} zE-sf#Lk)|mjx~jZzwHPe--AxRu-TNuZL7!wtXFtAEuPO}!jtLb#cXc)oH?a)aU`i_ zrB+o$Cr?Hs7F%hmcsfh1R=>$dP-IXnLBWM#c^a%FxoWon({PnwnWB}kiVdkeXAJRw zJ11gXK+gd%-#K?#biy=@{H`nF@(BEOykTCIK=8`$-@aXkmLLvjW) z$B*k70&6NGl+DLviq&uYWwt%On2w*yI^v(9=`)x!VIfT~V{Hk~(6r^OWW++6wvL@1 z@eEB}&#Z}aXzG5}l=uvN@F0sBnMEI5fc#*Nk=fB9MZnB3)B);_yVr3WSna6fDaDOWP&oOnHnEy@EJifImvK8%6_*Rp)PnMvji{i!4a#ev zECboDYMkQ6&7&t7iyM*NeAkWT5)#CI9Pn`Tq=b-r>QKfm!KyLN&}J|SepcnxmDRh3 zR#mSJuY$ZkWE5=e4XUgSN8xZL? zb_UC_OfkLO1857dDz6BzB(o6}JE-HbQntr3F4@?qW=m6R$`oaNyyB0#chfSEo&dk9 z9dU|3VuxmXB%GB6C&kj@hRvIYvR|bRW|c{g(&dG$H7U8j@c?ku;F-(h`>f$#i7W?d zmKWlhDN+pSsM9jd1|=>2!DiO_&v1t;XQ%6|ihOyYT9dj(68*g5UNsNUMU-#_eM1Nm@IGgE-%pV2>s&0 zKUE_%*bVOxyeJHoh*0C{I-b!c%f+JhAe!wj%Y_2)ls}Rv%Okw;%qy4WsA6^a7lt@w zg~hwVuCXq~yL@T0girM@FVi{}%fLg>6I#bsZ}{bAiN{gkU9mz#RODS=(I^|t^)6qf zvDD^W{!^=jFVU5gw0LKUEH78f9b)dG;#ukW2&<;C2+C`3$p)3)h@RItROMa1UgJ=; zclnD=5|7iX+!4Q_N>^&5Uw=a^V(vQ;My`L!vwSgzMnYo=K^ zf2pb~G&~+gn&@_iMu_PHO(KR;%tdw@v4*d)0{K`>ehRRhcU(C8SL z(e?0SR>P<&!N-Ug?eud^*r}udJ76}$%vhFb1HL{{R_bvSWAebC3bOhQ9jxmfw!2}e zFgIb?#@n$Rx(>^V9+2DgeAma5+2IM%$fQdXq8(ucU3W8duOvg%Yr<^xi@p!t1cNjA zFUNYZR5B!7NjG>F=<9WOjsSc>16xu%sOO(>at+MTWb|6ae;UkAOpHppFP4QviOY9g zoC?VN(7kg8Xg=!2%UFg)Rjc8E#?8+@%w|0l-bX*_e+0ihH-t4j)RVq6j0NXLl0ULn zazg{a5e4UZ!`Dz0MQ#9$ksdfHG6z}fBoi%$C`4{JXc1@)!01B13VQ|sP7}bp1_@xo zF6Bnj*Eg`7yy4_HGv`4jPh?iIQpoJRFEa7088b&%D}Y^N_b{_uWOlHeNst*PGBa2m zWcFMYnLwl?T3x}QVBEHq57t^bh@5L!pTUWD|e3RD{wt@zq97RU5 z=Ef|xYhEaGP3{#GwnZHSC~m`)pO7Q}KT&0x>`m42^*~iN8PtiW3*P}zk@UhvplUc9 zT`(pn?68}nwl|AdOF>Zo;u6?n3v-2HU6oxhd<_pH!_PZ5h15|DG@z+A8p#x!W8kIPJq825rJ=2VO zR8^7A_c2^BFpW8L3(qdQTHyl=iWqLBIjgsl(QTnIH(vSMF!is_HtLeSG#((Yx zyEA=Z&>#bjCM_PuKEKdJLpHJ2QX@Tg(09I@3s;3Z&!ClYvs|xC*>@`!+? z)#z&x2~B59M_@i~t5xp2b%-_3iY*?5+x{56UdDNHeg%s`g#P-S0;a0!U-b?&KO;wD z`j1aezZ#ZWGz$6L`uITRC<-GJ*!H5~D91iSK7E^+-qVK~F{zsHuC;L35yTuZ;+p5q~ zAkPf(&7Ko>QcF>wAzhtAQ@x0D!aUau*W#R}dS-oWD7om{eRJV57QUcwkSWzYRfXk) zqWl7`L6m>4w`_RB4Dbus4>0Htn1xTOthvi7<_{(N|I?{&NsfaMC$A5ii9V@aA zCkt4^I|DWr)S(RVhX8ubO z9G#dBY*JPOSO^TX7YsDfsx;k@OCMJgxS$acQ14ll)P>B!eI}SH(DS@nc39xJ!yRyU-8DW*pgMm+BfMN&^%&l!y)fdoD>?b^2dV4F&T{;}L z2Za^h+W&3PkxLf_MU*2Jw6>d1IgmfEA|Pt?C}BKB!wrH0Sy7t zxQodEre2X8Gg#^Wl)*%peK>}C@`Zno1A`(u++@-1aWA(e*{R?ox)nqFMRD0QgsT)`1Fpsm!Y`ivFXYth7MoO0P=#-Cb7xRBX`T7$F1bqnj%iv41}m9yC}+ z(?rovg9gucLo}^k#QatRM3q<3^Q-#?4c?+FdNOEmvpd`N=3|q=c)ZwK(o$qqUJz$t zz=%R9A0*4?LOMyN=Y!B%K^*EZT9WU2>jumP;uy*ujJHpLh$^b`SIYt3Go4;nZs!00N8s@Bu?0 z8kxc3ssJ`qz^?gBz}{N#1G|JZSH(_pZyr^DN>vi*@Zzq-BA1F(VBMHpdTS?(SQBad z_5uvJLFza&=v{8Fblgv7?gr zuq!`vgvIAcESg>_0nxxYty0&*uB%WFdg&Qh3l3Az%LKtiw#^Z~7%L$sw7WWRFC(<$ zBoYn65+j8r1`vZ2bNvWB!4tWD5S|h6#PA^q$@QJ^1f6_+D?GvWUf;mxI~S1}UsHwS z`ea=In_kn4I(D$RHId^w`CQoCOEb%rqTkd1Xy}Fh1urv{0wp2nV_KDx&saxIR&pdB zQVQo-x}G8EdRpn9KZA1QA_lcphe7p%)o8{Wr2{F?WX@Xes0|MV3m(EQJu?s^)6cAc z7^sh3c0T(!UE71*dNwlKbPT)J`%7XwNw00ia$L_=W#MiqD8k%#o^#yYZ=KhPj;%?8 zjuW*;y0wSfhY4R7N51zZNag-O`ZEaX{xWiAC(gqJe}#?=c&CwdQpto!#||d_%kMe~ z<1V?0*8*Y?!|g60M!!meSwRm&h6?7dW80rgel+qtut50FFe{=rbymL2Q&)vruV)=l z6yp2}+yR&+pz7d{&Yq(vAkD|3Z(aw&?{zxrn zQU1sX5w9}TE%fZ5RQ;|-!bCiKVt4BNDxTVd#$0$A7pWWongjIBK@~&^F%&&Ct%g&O z^?gvk=d2%1%2>sEZ$WIBz-${921R9PL~VXyT5MF2m41O|Kw2PJi-M^%s=n8c)A&WG zO5=h<-O#ApM-(yhi-JVUi=)Y!P9(lGLnX0JBN2T4nZA6}(G=Ys-!7vJ0pI3NWexSl zpr|G{!shxpDvL(Z`rVxfs9&QJaLf(w%t>P3Z|FT`ex_V?7|B7-qd11RcmDKGL=!J? z{RE7~7In!=|Ac{5RavOQzl9aPG@8Kre93!yUX<(eB_n;Y2T);U5gUUZb^8R{ks`U+ zHJ_js%hJs5TR%8TSd-l`<&U^hw5usi%(*dqWF|;-7?xVR)cOm<1f;qxXo3NN@qOe1 zJG*h((qh3%dA~&y7Qrqb;`Shl|D3qbCi@U)a;%@wHFfK8Uw~6^OHZX|Dn6a3M+MYh z!o0<%l8z&_D)SDyBeF0`xSFN%SCy?Ma47-zQhmuXcD!hGp z85_%t5MT5$Hmx%&*cBEOBu|a$#WdE=jGi@CA_k!8>4+`kOx=mo#i^`(i^*ti5>Y0v zu${SyHEx-hU=GeSt1;`fBj9QlFc+NIG_Mmi+KL+PEUVaRqH`9rn61%1TU7eVPFB7( zlFt5~)o+b%e-C*Rq?PuDF$p}$Zu3ZqFsnSji;*vyqy`U#$q0^`jXoahP{ zp2&DDS+x1Etb~(ie$3JZ8L++R|J4IZ*hER z=jmyl{S^C(LufEHQ?ic1KK=3Y=YXUfBv5@4n0 zzw;fc43rO~HKdaZ;k>+g#|Ux|PI_hr4G|1dqeG9duXcox$-biIbs$!VW7p0DSmVpl z-OANR*Vv_(Bc~1NA{;Es^w(aMAsHH{bV8QmEoA4;u$-cBw&)iR(Af)E`7g49hEyOu zzJ@cbF|z-{8*a^@9)Xs!ru;~{c4eodueC7Z#wY^kkid^<L65Gno>|}) zBF!IeeS8#MbDIcK&4s1x^zLjp zBeT3ZkcGcGfL8T}wVKqHkrIWA?z4be9zim8%@qJ!=4dj zC;UH5zH zsYx;qy(y*z8P)dYY}Rjo=%|&U;8_~P%-Lf60dxiuE;eF~-Q3rSfj!E*=UB`BsF4eF zjZ>j?$N%2g3Sj+M)i0yzoY}YqGRBl=f^g~1k^%j1zGkhz)LBkpaoidXb~xRx=-+H$ ziEqXh7newfq7*2y$bD28>{=pV*8(2b!s`fWH3Vz#%&TAPi{6{4yN1(2Ased zx6y*YxI@GZf}M(XSgne%(pi`?tn?l5_E2TV-1Ju2M=k>*Rn~Xmee?7ixR8ONJzy6I zVVl(3tm0QwXkHmR@vCH0%pEC4AfHFPf+H-Tc{JJ0Qk#dvzRT9^ed1FFH%pqI#QQn6 z!%qhd3j)Z%jj32Hf}CR^U=@VK~f-Y)L4BfjlAhu2Mq&cF!0!zwC5 z_0S%}DocUBw}+!%e8-#cC7^xZ{<)iQi<|Ja!#{x=NIpdSbe?l8e9&FlHv#ufb@@Df zkD~UqZ2miu#$xo|eTHTSgWyAqeJ~L7kl6VT!zHV-5S7^aqeid|K9Z|6L~Nkjf%^2nAL3c>4ktr8b-w_F<=v%0!^93&xPFBvegdcN|NFeWf!F@J z7SWvbQ7k;SFP-1Jle_%b4G|X#cyA!yVten&pkXcUp|<_*Y5LemW_aJ{!2jnod@yT% zKMP|N?eCAqhArN1$2{2Uor$IMAi&eIFlbnth7#|y;>EOiJ$wh`<%j?0e&=gDnEAKS zLBsB4nx$V=@LN;#tGmHG!~r|-s9TxP2vIsnqt>x16XE5rhgP$?-%d=9ji|}~F<G!5!*asPs?_%Mq0 zyQ`;Z{6_|G(tK%}z67JjeDrt{%G%HOcMMmo^yMQk`-URLk}M>EzAR1}acv?a@owp+ zxZ*u3jCq`d5vMqA7*KE!e%YtOG#Mp~a97r@1Xy$RWI(F;axj{$fXkVfndajfKn=LD)-yb%KSm->s5LSu;d;7H-^Cg6tpc9UOC zS#dLq`#oG5?_3pMd{||W$MAH6VqZa7JZ|lXDIu~=%>UBu0kut&QM6%ae&3H4 z?_rmI4_7nxunzTM{zT+*)kmrNsQ)AZLFzvV@0YsCDqm-l!(-P!nPMzP76psLG&#z& z_{H@sw>8~Ze4>l0?QBbH^3vjaz^m0(rTwy1$wOCPNJmXv@f~d-@YZs>+qqRH?S*pK zf(?f)*fzLv^-Ci2IgsD4**j1owwgu4?)fE|7ZoB zw2Xh*_Q6MrRSEwd%KE5faI~p}e+_x+1M?Y_!I{vIen?-M+2xYbd^Q7Mtx9wcs8`e* z&oS$m;SW)8gUs@W@X&r(4(Gp%A^IGMG>>T+K9|}45I*dh%z>u#-+`j%eg~LtIRmYN ztaQsr*7S$0tiM6H=ONs~i-<2sMK?^!6*~ZxNn7@-DA*xh@i-aDGuM&_92TYc4$3K_ zf^<9j2;j>Ez!3^;EcRmrQnRG(LZ7>1*Tc5}HSxe-15yoL9E1EI9sC_1_%`@ zNSYbKkU5I7DVrEJEg~W62;(ZnQzb1Pw_dQ{5NB?ZG}t6HtOU~Fxv5ORDskJ>vWYk< z6z^)#P5p34zy%D<1f*r_UW23!_tiF8aobTu)CLXLumJ)iJ9Boq&g;h92m~0s$Gq_r zyYt6|ksIL+RN?WV@qyWi+vA~qV<@ZmlQDhc0+rN;*^<rM7cE8ot&^lK6n zcTd&t8y0N-d=!ljVV2Kh>4qL`E<6?oGw0_~nRqP@kEj4sycHM|=OMX%HQgLyH#7v!z~UC(7D6nn`cee5T^ZFs-s!>d!YQkg z2Jb#x8AxW!mZy>+-MSbaDeTIZllsSRcSh=NbJDuCEaj^ywD=fvewExO{)9jbE`QDAP}K5O zwDEcLzErVS;?Jv7^89hu^p}CGZ`*iUd;%JVvt?}q`@~<@H9ny>2KV3HSnM~g^ts!j z@fU627wwUXAwp{j_x-`-w9O)C-Y&cbuQBgL?yBN0KWU*P2o+$ZwO84vfBp$X(+d6q z3j7$m@)rv`_7|{HCm@+jpS;Zs*Z;@UMU3bIj1$<7Jc31h_O7_O(`N%K{4XPo zJ&C#WKC`P|fcLXum+yG(+bYNDe~KvS+DWsjtYqMRt#0jn2$hY`S6w01f&vE-=VXDi z_chk>UnXOZvF-*S$rxX=l3@@b`fF^T1mTaO;Q>Q=jM@GQVheNg*NN1D3^%gR|7uSD zZct4&Xmt>I`N9Hn1>RvwK(|4Zd#^>uI+l1dD(Rf84fAPrNh|khHI`LFt2MGV!n@Uo z0Il4+)z5FR^EV@t+v8=m*{4~mR_@bmD~tI0@jk`(bQ5_Gmc$Ug^KtlKLd(}d2_s73 z9+8NJc&zB!i*Rox6Gv~cjcBscpAWGrTYGQb9Lh7JNq_!I5*d_gRhAD!-7cX{Sm|0Y zwzVg9J$))=Gfcw3Del_6to)m(vEn+Jx8#oKP?yizKoBGM2Ma7pVy;?V4LAJ1$;wJB zmD&APWnF0X&%?n9*snSPElR3fG4R$2>M3y|3;XfJdf8?*TJ%sB_{|7u$d^{K+HYgW z6{{)(!~@>ox}|qgAz!ujArL=Z06(=2k?+6F+P+PAy!ck88MIH?(n`F5k3M3W4Gbc@ z`;Xsa5zGLI1;_lBNXss;O-+1pkU{KvKN>IY^}9d`wr7QeJ|Ybyz1b+;aY z07%=d$e_f-R{Asi3_}lI@ft~GIk$T{p7>6u5u{p5JfRN$r&ECdWX4UI$NAN?shBB< z+z88Kv5f@F{L{7huKO1xKD;TBsJ0)OsaIdPM@}-sM0flxE4>(96F+=+3ckK0nyCg*V%4@=P!C`5 zaqAoCwVYM{J-W}x?O@l;VB_E>*EM+0r9G1N7{m>wB(yL6$!EH{{a9!6|E!ZjQYzP2 zmCCzVJ+4ph&ed(bwGUQ+m)`&!HVctEzgZ1XI7QUl*$_D z;09}LPv|qU)k9L-dO@z=5lQaT=zz(gwB-qM{Z_iMY5G&CTnyN*Vzn{YqmSLyU+!ne zzKe8>yyc!GbrOAoxvP)6>(xmt_e|o-Gn&kT{B3c=sZ$`-b{8{?!F+UpVXv~Z(&-na z1aJQPK(^u^Q8VSNs${6LqRpzhw$xcwZCXWjq+eCF@d>2)WIyg!6!2-JJFuf|WwyJ?PmZpz(p4a!qDx#sl9bWgp&TTkt1ef5 zt#+xLm0h0pbh%P&yQSQr*a$Fa3Gpc;e3*{`*m5@l9!8Zaw=x33&D^ z5}fb)a>3?%k^L=ZD_wCLsU6c|DT30G%yKU>dBtK#25L(Hwlo2-r3n^;vRU>)lif0n z&9?&VUFN)Jd{kgtEwQyhvCx^CErpF(hm}5g7s~Nkdxwf539kLFn4m*97RAS=Tw4b` z7hNVPNhPfP-jtvf;;dL?bHASw^yDGY%9&KbwtxR}(38F0*^K{r*|A*irji=u902di z&mc&WIjISp`9hD6Uw%-QAAs^>x^j6KmUIlt#Wg{7gH^s(!k>onS{?inpgkJsHl(uI z{|=2!YW2*2c^Zxj>H=z@9@?wh@ciPNtl{6$k+t`AOaHvnB|%_q)&v4b>%YgDHst9* zaOr|ak_0>CC%$9m4r8RgvnQ5!)d{UlV^tmS(w@MVP`_G-FHz!a2Yf@2x-^{)*?iwb z!D_Vp)4~ew2SxvgwUBy+Row@9zR6nd|Ep&*tkJUB?8FbFdL|b@atLe3WTTaq-exf_ znLN(sx_(3deSd2e8NPKq8BhPc<46^m(jzkYy5u43r559dxdJe+#z-DpEq6m#1V2?p zc7+G@Bv1Aq_u`1t7xCt!W7OOHKaFh2p~PN@%8|cPB#zX7C$nS|2>GL@DYLJ z**?Wi&#m-@BYA5d66sw=ct; zA$+D;@n0O@Q#x99R8^`v9}{R-Bbm6@r-f-K18zTB$df$)fjukCu56o6!uj6^k`evw z89sHXJTZ(U)9IVIEsPi)(|73P0@l;C%K#7NZOq)XY{l%+Mbqbjj#cFc>O8TP=@YOV zZ((4&B=Z;yf_ZG;6hfZ)_pQnS!sEipls;q1JxnPW!kyv7 zXc_~?J^u_U1qhp}#@aTf0opI-&Ctd;W*;!6+I#;v<$G?3Ad!({4nSLR5}+DYqNKW1 z=O9TLbBq^6kc6x$o8-dxgU^LX-(-yD4BUhEgK$FNxd|s>Ov{+-*dOxLN~hf5ha+IZ zr<~(ABS=<4icokkPG~n}t=ewNT@7ALzB8o|>Mrxb!Nf>a8b)Ml+FeINiZ*S4YVv)F zO4@5Z36sz9*1<3plMii+BomE#3MMaBn@zsV=SGs)bn9_V#pUd}p9r&Huu>~r-XV99 zyJ+ro(x8)q$w~ZJq$&khBGuUriBe~~C`y%r+9oXyhjRxby9$#XSmz)>V4=R zB=TY8E=a+oQmGrYu1CiYCJh4Ll*fSE)Vr)=?aFyn} zz8&N}#)-3mW^o+_#)11^7{^!(uNVd-O^oMt!^q>NvG|<_X!}i>ciRbjj|Rt*Ad)p! z^YcorGzWcTd|MOuMspz@jPKB8nlU)Bvalvw2_75|VQUCb;033&Ctv{Z{f20oGl*4O z6l`c14)bS+xP|^xn=p}g&ZN5&bm(I3?`og&c31FDud5*?X^E~T(3&Ib^W zKK=pfJ|3+9I0HAwlUQRGdaB)_5hq3J#=J8c-YD=C@Dqq9^Fnuch7QI>-YqpeHGxcX zjH{Cpf741c2LqFCK^rtII{le(7mSB+QdHgN*C1eQs82J*@d13i@+{~kb%R1PPU39A zXBkM&PQUUrhjy7n=vVLP#xj~g>Y|j2BBf^*ARjtmmtQU*sz9PdCr(tn89F!FFUGqb zm0-qI>=22A_WoF(X*ST*vT=u1&pqQLw~Yj`8h3&_6N$+&UWgMeeNfcu61R;z4S43M zYA$0XNYAGrdN)OTr6-(T(s~`uPQ6=?&s!F zWZ$)Ii zd<(c~AW*5WLaa*jR=#~SDCP%mc83qXS1Wd%9)tAYHGUJ?I6Syjnyzb7fR{4oB3s6^ zq=s~l_p6KYLZe|Y7;AvXGdS1>(GcuQyYgqH56+g31fDv0#_Rys-+RzEYTWbUAt2YQ zk*-a?>#G_683E%y(-DB1JrR)S4eyX1QRLHzUkQMkYw~M#WCvm(viA4ADj0(ae%XwQ8iS;V`DhbOXxFwnN2g7*^9-kwPN7u1j(|7AI0jLf0@?-7qZ=5>s;O9TZTN z$m9(=-g_qBYaYM2!EIxGi2mZXO7ySCc0=@)uX+2}ZixQkkei@xiN3Nxz$Ex?N?gZ4 zP0N5|n#D7aq~83*I3FS}m+|0K-?Gn;@R?mQ>hs0CF|`|-KOgC)SuioJ+|&1HylRQA zxc3V3V&dhrE@)Y)GI3#QH%$CI^G65@^dhKF+CC3KqmFY!8hLL{+D$C8(vjc6Di!a% zga0S}@3amN{75*06Ys2RKB8)nJy zC*tT3F= z>pxScN3i{qbsD=n9lO)GHK}a(A3}IpHklDQ1p_lwJujP*qotieQ*zPQU^$}n?M%!A1{1oTpsEbs9~S+`JaGjfATsR%yT9} z)a(tg{}V}a`gqNJBwA^V*tmlhE5~7saQ207sH>Z@B=h+5SmtqaV$N~@hkT6Ig~7Zq z*GH>eSkLD_1pCRAh1>E-I62ANa$)}?b2V;75ti#?kIsMJ1+FB-W#XH2iA6)P*9&2p z8(~Twy!qr7u3(MueAg!x~HAilMzupka=S?PQOEbV>jg)u9 z%$C$BGkm(hEIx0L@49qKC(qgtS^>UH^?3pbR<>a2Z?|nMR#;vE01pY09huv$G~}FaN`!+Bq-YMh7@oz3(|GcvMk-1owvpwZp^4Gu z?;@O|1viSSCQ#u{eC-1lSk1qiMHbMfH}JwDGR5@N_gV)!UL3R10UP+SB4Q^Kc*JaC znzMSp1_pFk@?AfKVjgt>Y~@HsQ;zuCM(TB()xz3KeW3~KB`fWJPMvn~5i?k9e%E-z zY>52WQ!!49eD2zuzPm)%x6p3g!0p5x73_p{n)ZhYT3g-lAjZ*8YE2U1badbGV2RM+ zQQh~y(;++t696)ul>!Ly#bexEp^fThAiqiLOyK?94jn?ttt^OV^_wjbR(Fr^`0*|X z)JID+d=R?o*F)kL#HtoT-REVso~8o*kRlnZSRa>Shx9u9gVVo9kv) zk6!Lf;J@{XT{j7Rhe>>K-jmRSKQ@mP3>t~yO^_ip6=HK?rG0wjyE;O7%RCa@GYdka zeQMMV!ry-mUXdL;i zR^UijaYM&rIfQJ8-1Sb zJp4RBX`puu}53}uY{MLLjDN8+CRpZ^oxogczD&VF1 zb~>E!onPg*x;i*ASO78IE^+8i^JTqiy*l9lx<5r(1NCVD9u#Q!;V2n*Ju-+6w8g96 z=0IAtBViHK84zgigp@}t>`Yj92%vpQpjpv61LWX53EKl(u58Vzhe%@JdVm4-m)#8M zt5PcD{yDo%`iBU&80tthKeCV{QM-lTTnOGba6Dj<`ixsdrcJUNiUR%cZDuh-=+q#& zAU+f*%2kdTN&>|nZgRs(B08)z;0Qml2nUKV0eW02Ob$p=z*-oLP^rLSKj5&%2e%sj zRJkg>#GEE*mj~@~B~9o{pfLu9Ob}Zv@LXY_y-ta;aNC3&XaLI19c}|Ii88_~Y-HjT z94u`W9m|e>WU%NL`V4kL19XO$!?yF5MQ|uD2CRy^7vU4m1Kb3Fvk4p?2C8}QzIB6| z7~z?{p1Z}MY!l~OY0tafV-jW8Qu(IEWGb~M^0vjW^AcAWV89c>&FNXj1B&6u(Om|n zw{cwLN43*nR+8g!O4=?M|sZQ8x>!Vp1M*dI;_zZbw;c z55YM~kBb79?=2?7rq~lp0{s=i33cSMqg(?3u7{2=uPKbgqCisD1uQt-Jr?kW#Uz6l z+L84sC4oebRD|R$N^U7q1b>?ozl*5_m-Mm*?P%wAw%l51g9pBIb;P6qF(2uOQTwpv zHd#kQ2R@VoFb(bk_yizcz+3i^4Cb`>hXLcw00knPd&$E*zrEa6LX6S&9IQ(+=ed^= zxac{W8)T(^%X#xc^l5W=YY7>bWe=;#hO1?ZV7DoF3-_+`)xWQ1QS#z4%`k!S05e(f zuZdTq68H@k@pb{Fr+C9sIKQ=r@v0?o`@xRN68p}Dr&M@$e_me#yJC1^f3bG+kMvh6 z`!n-Iz(?(7#5gjs`*?&02TtD%(cA(LzHh$M z%79c=4cI0PsRM+AB#qJ(O%hio0AT|Nsj+@$)l8(W= zeKkbp9OWd$0siLS0=s~N5YN9)shp)-fEZ0t!r%ApRgIj?cm2I9{O!~#(#mbJ}(kq5r!yW5*&T`PY)(mJN4J^5d)L4{dThh$1 zdZqf2W!Irh+7hQ6{|Z$e*2}-7rq)Tk{t_?BiJ!%x*u^z!yuMijdd{ON zUKOlU*>Uf_<_znQst8nKdq|{0TU!*n2#$5ex%&uChs3!baXNe`l?Vg}s6>jsix?%0 z%$)`$p13yNuS%;7E^)}zVJwgEH-PkmE60Ha)KHT%w8d)g!c~a z@a-$Wmt2+$cZ5ecdc$AcJfIS@^o~v@QYC@8ndU-GCQ{)vd$q=1AhNGY0NFAe55E6A@+cJ=aD zqw6&I2Kez2@!~8*F?;aCD`A&YT$=_jgz$&gLzv$msYmAQxON>lG`xyGA946i7ye;81XWoPnSaBA!A^8^;TuA|pcKF8p8d z9$pZfvtLlRbJzCshNsBrL5I2+Y=@QH+0Cy&HG#9kN;14RUWgXKWC+;j@tjKX206%Y zR+7kxbNXor&{syS3P;}hZK*U1@Rkh-H?DTi)KAW_l7Ein1*^%!^Ui72fF>7Cdxg=G z66J>n3uqwKxYKO66nU(~SIf2bI`rjM@{g@3SrbQnIZ~_lwE6PBR;FuH4{e6wCNzgx zLi`;g;7_r^!9=3qyE3^MDH59i^4$`3E+zxFzB`_(__6vB&O^csm z<>ocSMB$kspL5rcZ%lvBL^!xCwhO1#W5NDDjL-imNihBGds$!ZUH`XhN1J|1ULtf# z0k>2WW6WWE9s03iV$ucF=JJz9MgEOsG zUHv&(e?YcP*VV}r*(oi~aJAE2y2?$m;iucyf(v$QCA`z0xa}R%%OMqmy&M2w)8Q}G zsl5pEaupR}Y}kFro!k z-PyOFp$PbNCiI{ruF$75E8S)-e z+=TR6UJkIdvVhn9oJ1$sb44G(P4)7ts|9t3m3%W+4oFzZLnG`qZWse^0|Yq8q@esb zly3k^;&UC~gya`Mx(phC*OOl&*G;gMe0`U1agbMo;1hfT{_Dv+$4L@`@|$Enlvg^* z%R%|V9kr61D|uKAc(XTq@QfN_>RAA8+szGpehnOE*>m~!8nQ6R4yqn^9+d^#o*~h( zf6YTWRWY*X0-uPMhj>G-Ajwu>=GJG(PjSqrp$)t;B1r`F|FspxY_M5=d{?O~@SKBu zkKfJ!Ufj3_Csxrs{aIq}Q=k*&|LP~Meme>(0Op9QqG^Ndvk`F502NvUUa6{1$qk|S z)T@is0`>saI4r4x7J#YpI%FU>dc(~{2<2)w7ij>(Al(ALv*0w~7mms30YcG|TdD7> z2rVrI=eePlWF=o0E-xrz_!Cyz&ago6+W88#0nzH6adJZ}9ZSx%12iZ(IkrRR4m)*6oDwD*$8si`$UE4eu>r zNWfYA%Tyln9GQueRQeo=44R6olUiD)mhy(@Kv4A)b0<_R7+?mNcbsqvw0q#MJV#7f zQ!Bfl*nghF_MWZ4pO^T;@|5S{k_O0}?Rl~kX*&BniS9qOQ4<`nQlO%*ZQvcx1D`rA zA}It@!NIZVX(IGxC0Fo3Ccx^f&G_28OpJjYW1(jcf6xe1$QR#)-W z1w64HT(wHrn}cczx=Pd;y_&`=>Q(Mts)tn#TX{HCb4$@&PWUk$iX?P2{yZhi^di>(S+YBSX1m%?LYy_wGy_1k6p7^v?7 z^>MO3i#Le+W3oQZNa0{#Z7M!lJ$vDkFW2+d0nL$RP6Qq;9&|o4QNuC3SfB1Vh(;Ko$OF0ig6!Z(g#AOq=$nlSnZrG(XRUj_G(6 zS4Z)m4s}6sPG^e$cx~Hekn-tf550fdeH7^JPfd1oPT)`Finl4m>`TK~%I9x^pbc=m zRz44GAx~pIW-Gjf2G54AVC>*|U@Q3zwc9p-8o`^ANI$-H8yOZfT}Yml{NW5gy^Xxp zb9yPHSMn-OcA4z9YNb~SdIT^-=!=VG)f5PZ(6Sw8+s2Ewlj5N1PLvKSX+3weWjpyb z?K6Fk6c-TZ-v@H%FW?5#^cGLqg{%C)FUY9m={GaYu>8KB-hm&^fSq=loPM1jSP0C% za6>W>_6Lpd7TeH9vZ!aF1u7Qvx<*pmX)S+zl6N$M^(-u~lJggM#7?00;~Ji`6J)ut z1j@944~ER)CK<)8m$+2|b@AM}le{|4S3i7&9}*7$Jpdabw;n*Qpj;~|2R;UGU>EfD zQ68_}MUwky`r)IC*alvejN>QP69d1q3)u7#;f5Zt7Yc475l7ozAwMTQ3!PSSb{#L- z4Tm;`xF+yCS*!_Kk5*7$MsKQH7e@eJ7 zs*SJ}wu9Y(Skwnoaa2;i@se?hx}pj@#C!|ibZIHtKeRKTDZ|7UrpbrB<&@M~$(gTt z^Q&;9_6+`cSM@76>&^OC6}gv zOk<2*gqhOJn)g_mq8=#{p~>{+yz&j$>y@VPeQ&_)8Ko)cw87f53VOwU5bCbK0kZ(l zfPG+V1+E`}YdCi4?LuA7K3F%UDMw4;N$C5Bc*A~>(-}EZPJyNGgA=fyjEjDMtLg>4 zhhL;nqux7R^~flTZAKBmea1t6NhU?lm@C_Y8h(EWGDz;|D-kxyJfn(N{}Kp$?`z)l zOR!n*O+dy&qzT{6=nG~gMBr3r$OZM@A$|$qgWUOb;%(KaH%XMkjs{kLeo*U^Z&LGa zSHBALQfX9qd*APk#dU{u0!GA|?2S73Mj!9HI>X`J`F5YqoVvzN@6JvN7tp7(Ejsuu zKAj<>HNxwV!5Ple{dmR!GI6F|3#f$&7$L3pT6Ha+!1aKCAX|PKz}^7N4)g49PWI?x z(6zkv06Gb^y!i}718(mjeYx!*>d!`AeGtUMUZ?A+k?%W*E=VK4bP%k(eGAWd3y+0V z81;hD7P)r((Ra*u{p&c0QizrO<|N`tGs7KLmEGHQ;?gYofaw4iMvu!W{{*Y}z6iKL zTl5ZdzU#lg7bD_V-y;2H+QpQ}`QDC;Od2Sy@phlru(rbj$$*YQt;`TCR5$*=nUQMq zy9opnp7Sd-G~0RUuSiz<3{^hFy-9nMXAgQ@T!)czUyk^aY%>ms0Rcm5671Ey?N@k0 zTD`5A#4bI)7?%J_i1ZRPzqtu!4mV`*;ZhfhHZGqN0*%_`c3qbuROQoUtFFs>*=0R; znSAU>H(hS`?Gje^bt^drCmOKtQ;n|pc&NP^zo#z$_N~UxdOr6MnK)+#@aouPL9jAY zC@=LxiFkaUaP^VLoAnI?tgJtmfO#p?a(3ZSRl}e&rmPE_(xSd22cMX6AaXStHNq8!Mt;T1>0cH0}|g3Ez5j!rKG8V*h62ab~W zsJ)7pA0wlD3EOuJ_oUT4=VLOnryaew2=2THFA+3UU&X*LA&l_3y|khrLCbH(|y+Zk+uXii|FQ*e8Ep&AYvqX3R^i z+3f95>=nUqABRFU6%JLPPxyEgLWSr$-{aF+tFE(FpUy}ZUW01h)V>br`!YZTZl4ZW z9q%|zrp&Y-mTO+`wj5U7me+0|e2vF#Ifk?9aa;C?(*~c>9+qy)VRT!zQTvH5w8aTt z{s9W%3EudD$B|Jr$q9Z|)~T_S^J386u@o_b@|y5@8B00Atsg>E(SATUKHl2t0B?tQ z%cR|DDs$bA&K}gu(pWcYyzy~#T74Xy1H9lYiOsT$iIP$vK3?hL)9mr_Y4(8PiBtWT zrcJyVa8Uame(5Zk7;8U~Y2GNEFKKJRHiC^%$En)M6Flb}Y6~Havfr~(JD!!=@vvSy z9^3X2`6IPA^GhG$()DhqDzCFrdEsSFkMf!rWZxsa9SB)Vowe_1+<6iWI;)u%Tr zUVg+(e>;G-9^lsp&`I>)yLn;=eU94v`QZ>+9R2UXP6CnQ0KeB$hbV?=P6hPrpXVEt zk<|v;x7|NApYJzB}L6EF|Hq!Pi4Bu8>Um6N`T!0zuF&%^KR$( ze*ymg4y#=E!Qt>7`5hkspL%cVyM|TvbX|^ZmBZe3CSQa~t_q-><}1T!*wKtI`cY3) zPP6NW33Wcd7RX=X<|z8QBQM7FLtZ=l!sHXv|G{sPR_78a(fXE8JBKXqm~i$rC#YLVc_o_cKy%- zGjpoL^J}@|N$bnC^!p7*?7wN;N>-OIQ8-DX(L~|H)95;WD2)z>^o=x{Kox}#N~g(0IXXR^jwSQ+R;^mG z%DigH;*zo_mzm2}EGk)2zIctIl$I?kUG(&d^2)`_mH>Wb*i+_Vu&YwM;k}_s);zg* zd6|9Ds>M%=M*RMG8lI^j@)fHq7d=(6WJyUU6yCL34u&DR<;ydu3C^dzyDeF42Rusz z>19uvpQ>C1#HRya_{SM^B)^|QN5FW;X3|kO-sPDzDIDN)S3J4I{7~r<`x7|SSxYL- zt1F;b;iobM{P&r39Kx^7q9glOuBcd4zGP`-Jg^#Jpm03kbl0r{{>Vx!OyQZ?Gyni5 zXHy4XTu4LtpR=h63IcQJc%Gj_%lPpe7611+G{RpX9WsHYV~_Am>Xl+i8;kS0e*#TW ztG}K=Be6PkB8>-36DQIseA7gljAa)m(ufE|^3aOalm(O#WUj9m;#>(vUzzWb9|H`H5*yjLl&7%XcL}Z+Kv@d3M=Fv~8I;a51o=`wj zpnOdM4aal@KT<%$%s7sRVEiD^Pr>|FELl}nQMzQ+8ndNpSQSj98?-MsPo=$)u;i)q z8$M(jpm}H-y~+!w(^S5Gx;8_HrqhWCMG9%0Iw`=y5I(t(J^;PLJP+}MF8PK+Y89Oa zqFhy?d_7rNwtUG`=E@c3Buny`Q3wT12k_t-)Nr)#O!~kBj^|Qbu60)U9dNm7@2Jn` zw(Ig(2R|&s`sZRizjaq!t`~z{uJ!lS-wX9F*9%+ZZx1}RJf^W6@-NQy{9d^3a=2bO z?Q-o3fFD%uYE_@F5DslQ)BtYbeADt^$ZI}d3r!~7dg z&u@Q~gM|By2fiGGpV4*yNFh9-lQkjmyzX+X1zkacU9M+AV2K$cZez3nKz}a?IswI1A77F4v|wc(%D*n@iydTw{QT!XSQe2c8y}>ousSRW8?_v|LEQ z$oC>ZlgsrcAf_EI*W0a%;uqs`!3Ik4OND0#JPTZ|BS5I1&EXsTwesZupa*bJPC2RUV_0WHY|XDSO&AOF$bRT6aTO*1DH|{IiO$s z0~$#oFsO(p+Gs4@ae^1w=%j?EeNY}DVX)n&F4yj6UD;en-*mZNJ;6`g=%aLB95*kf zv2&XDKpVu5|DYXpx?IiJR|^)vKP&^$`@iK~k6)EV)}NW@azVJj02lco>g9*%+qz}N z7WuM8Nt@g2w%Af(tHlpf+R(_Tti>)B6(zM;tmAH2RG6fc*h^h2tGlgjw3*UIt(F-k zyP&aUF56PM^?uLuoJVi{3-5eB*O~8}GiT16bLQv0>Q=}X+wB^suIt-xpD6_%kEq)Y zyBDCJL33M`I>oeBslflEKOWR-g6XVO6DM9$qSYl$`0UW?QjfMOaCNP~KW_$uE8S|w zE3t=E513h1>h`nqJGIL1!lxUb9(;Q7*@jOTpFVv0@fpBpA3j6)jN&tf&p1BELPx5U zSE`DcX1rQ0Q*UiIOBZ9m*|pf*ZRewABjvlx&FhrE(`AM!-#gbtUxj>MlbKHWhjr!x z%J-L>rIa5iH+NG$>@yqfyw}L zZ*A9d*W%FGHOgx-Fc)5XVTCVPj-8HJ^ZbX07 zYsAr~%qusjICJU>b-vdjnT8eWy4c<2TE2rIk6Gieg}~;syiT=wd!<^WcDI>XH!I`a zy-&;j#?V_gtH)&QJ6&4RKkFCwmZ{u;Ev(~7b(fjcpc1_f1;3F~pI!cLGv-m$7CBSP zcl{`OUa*TayP`Hx@vq}le3XgwTIf8MH&=I*VBt_`#hkgOhg66P-EfBHd@2tpe^?IxyC&GNnv zbHBgGoZYC>yzlQp`H1;tqxz}$gHA0!*kLv`sv_^cCM^*+qm3%e<fI0N`&;k> zA84>2z3%TePobRq5eE9vV)*-q7=m{d4MAZD*{9JEK3a@VgBiX{{oFg)s^#E1bK82A zW`1$Eni+cly$}0@NL>(Nq8~KFL=MFiH^Wf}XOV4fM;#a=E7^`ZFi5qwqy84AqV1@U z+law-)W>tFXglg-+rPG>hKh*ScGSmZ=AL_0miIsf##m!E-=iM#4*Q@{t(kYPdebdW zUajtk9xgzAk>8X)uBMpRR;%>b;aV+6x`oJi$dulzUeX60o1xaBnBEq(Ja>3B2};z# zzio*(thiE0oVmq3Ax_?v48}%$n$7w5srj)Z-C7<(tY?lLcf=~MQ)#O1S4-8QfO+$N zHOV`II2hSsM(;r{p^TXD?0d~{Z_Yr9Xjq3GD|lUAy= zZFfXd(YD>;W5i(F?r=R7ZQC6t2~LpzV~BWd+Z}E+tJkQlu}5K-FKdMe{KD2C$@kmi zp>wp5NTG}e)gqKMAp0q`hl*rBrP`=Sv8ST?iI?oB)Q|~0s-BIF^+SV3 z9C2PWt&gj>O!s5Zz^ODZJ*M99#x`nNnOh!L``q&KPIbr|SB&~&X3+*%h06s`s6(-F z$23-MoOK##NLeAQeeu$icBxpeLkd-N!9rdi_N#<}P~(&8%;VstO=^PlCSYevtO@Ph ztdcAS=HSz6sW-6(?^=1Lbc;I0>%4K9JGZDg-o#!s7&E)JsMEYUKs+IDkD3y|))&g} zSN#fmUugU<>dz>QhIYJ5h27<$);(&0#P%2ZWUnf))ZTfa><`spNgLpGgKBo@f{)Y; ziES_hbg@+X7aGtDL;pFTR!Z!Kp_>k>A6wWCL(lzPB}p}08+v1yB#v~4@(!sv5<6n( z>cc9HVeV&>tP3sLC>L4QH+cUui#*o3 zwDWg(tl6~l@AFt^VDQEtg&chIqEHXMX2N(Y3`beXkK}vkkmn{37w$k#i?J7mZ58%e zrPIneS@)pagUe!@+W@)SW(~JdIO~)Me9YVpR*v^FEX% zw;~1=F;oGfMp>H?yX;5VZ}byXKNIDdrjW{&9-%5drh>{~<{uic2^k{Y{u#zrfj$fb6^#jK?Ks?SUZEjz!?NL8taE|3`S)c*;7JeoNK;l(kEqR#gfrjRMxSaxe;l zlrS3W^zY%H0M9htTdb*a$n4x=O}V(5oa2E7VSMXh*LeY)Xn>#8R<$RB{+^agXz)$2 z5R77d;cT5UD_Pn28!h$~nW7$RO0c^VrYmvyJOwa9Bg=u)J?CoKKta&O^h>q)a| zQO4C;{%;xR<&1H{{JIPDKBphgD(74(Mj77;z0sfOz&N0{XRS_=&+b759Ri@J2d9j? zn#?E^OTHWfk~_KnuoiXgCTpv8cJNx*OU!iYql%m@-5pp|321f#9Vx2py91BH8S}cu z#F)gF~z^q5qRuLq*NZi3|T2|Eo7IK3FS}Z_Vd)Q)8 zpK7^)rpr8s?wx?}3;=r=XJ{E;0Zd097{H4I=!@g}f{DC^OW< z^_{>R8s7V~oHGF2%JfbxKHmm`>>_Wk7IAH$=P~_7EfwTR4i)cfkT)+v-cE$Xx(FQn zD=K;-Du%RNyAJ}`h2DQaKxqX1TP?1hd16G-@!F~>1YIKrF!7@^we*Yv&u|oq#?gKW z)9Kwt%9>a}>EEL_L*`?NTx4E$ljh`*S%S`3o{eaz6M zMPC+1;5K+k%h^PCG!`*X&Pf3~iy3Ap7=I0y5)a4Fgaj=GDZmz;kf-JR4&WB_7ler> zoDT~CA8$bZwi6hTCS2njHAUE&_Y-c?@_G*ltl)&-pnW&6+u>$vMTy&oLC1)X)87Rq zg}@)A1#rR`R^NJ5G&(^PtF-tRd=@qCSR@wL!QUaO1qV%Rx|a6yb!o18TKcJ+qCpopn|7i>^jWrR$vm~1N~twZ`=kr zmj(1_vAP3Myod42TF$DYqZZ@$s4XR6q}UNV!yk;{qH4$$o*+gH3&i=cFi;1x9075& z;KLSTVEP#-+sP3ScY(I*1E@I3u~^*2;2#He`LEP+eIFEzVR;D3w-BUQ`t2ktQ$SHid_w5-;kvkBw=ti`eb1o)W$dn1m+HLCIm_!}L% z4=*0W=+KQBA8xU9dkea2y)RRXfqry2j~mPYvz>sEd}m>VH7L*sv6=biXtAOR^Lq#L zUqs)d6DPDJ`T}fDWa47*V{`IB`z!p2scz;+48*t6`p+i!HDR+@i3Tf~;kP7=5-YG# z%Y}$yS;TZ48EWQ&%qyR-U(1K~0GBX*KYZK(%r5bb0+R(9$NR9*_0ayq^D=P(+h zwT^)JQ$e$nqd@#cT24n4d)PwpH4xYc23O!JZCwouStCwN#NQ4&EOeZXX<9`w;POAL z@ozaUMu(l;;bt%Z+YB&a{0my_od>**>3#G_1U%vdQ9MSxhB|0s`lyyk0bpJi5)|b1 z0dt25sW@MBqraIBf5LPvgRhjsq@`SO9!x?}%oa(&-f$C{*ri{m<)T*b2bjMFG&=z! zC9K!hb*1QluFKer5;kbr(g=Ru%o4U>`yK!zyF6jH4q8=5P~mF$jut=N1_8VoB@BOe z#0j5ic>@Frp7)7SFmdyV_K7jyJs~A(OjB4erp{3)k&ec8auiNH3Hv{p*eY~Pns~Yv zBVlOFD_df*mhD++!P77iG4PWfte9Pn1rnENF<1eG%NW;bF;)WpR>t_^*h$>sYPiG= zO1L;Nh|R}02my86;8EvUFRGUn+N9-!GoT=EuZh@8IGA$5FvipM-}` zx~s@^7H}8#h7r&?YLgzP2N>Ws$3;m!h>PX?|4 zR*sL8{~PPb5HQdCWK44}2X&CP-{kq|a4r~Ta0i(8zosZ1WPGC*)nUjx!uVD#pKO7J zni=DqKYtJdU<)R9YPn%M+K({(B`8FgU68z2%Vi|LkoW)Of8p3%f{GHSK?<#072E(( zn=%1qJAsarG70n@D6qhk|I!lwRF_6-&Z$T-V;UyJ)kK_6v|Y1>W;6fi!f#Rc`)|J~biYP1%AnE?h4n$%Qi z+gQUP2GOC|;b=4wzsGQrBVb~dmQRmB!49UM1ObEKV3SXr&FrKw z(!~GK;vI?^UbrS+uEnWkAPjPQ9713}9EmkAd4F@R$~7L7ux#q)8o=3l@WccfYi3E$$9O zAzo2F)NlIU~ww)AF&h6ETtTh?c)3 z1)Es@i%_5$*j51ZKjRNto=hX;d76RUseUf-K5lS`zAguD<_^Drf`mEBGh?(k(g4gB z$@HUxjtDxY@fnR!h=Vw@K+76(X+PxC{Xg?E?0#9O;Hb^S0c2S(8n6j7u~t72gZ_A$ zWwzkw$|c}0bQH{d0A)J?BV}Uy?E}C2444_liHPL0i!;gmc1m{M-!lJpqJm19|JJgi z018l$K*32FTFjym^9UwQ$28QyJPjwEtmPkp-F0Nr_co_VmuRU;fi9L;tL2@=;4k6* ze^LV&c7TBwnn_rQrjm&`Y9~FdWlA4#Eem)<%dVZkVaD%jxw-}ddF7ilh$kEH%WFc#PJcI849CTB#yETo%qyxpv<;Xyk8FHJlb8 z0}n7>i=f*E?6!X#k5a9`Y@zI}TE@(SLTr)jAinX48U#ZT3&3_;T^k|bpceGALW^fb z_NSoP3H(Ue*nY2v1zZJkuvFvZecXaMd3cWZ0dtJy{1^&(fJ>bIf;o7}tgb@^Yn-zX zOKk;kjl+<019rzD;604jXqn!PS-=YCgtS=Og%Pzf9RmsjyXXF#AuV582a|`Hj(Y%Y zW-?&opvaXtV6>nCA24$1+}{q&3gu$6xn(ZicC#D-xu=0nBX;TMqWwHzerU`s(;{O# zFk38lk(Pl9Sa2b?zg3IV3NU~M!kGWL_(H%>KHI?z>$JQUQLAP!#$)qkGl7d4hw!#b z3bO@r`{DCuV4gL(f5rCOaKa+FV_Fu%!jhNvym&3|F9oKcru{!J2RD@wwC9^j9-Z?E z^9b{1W5m$-I9{MdH(cU;gMs!-wJ2&rhpbQ@R=(=~2>u7K(t+;Yl=9lOe4-NyfZx9V z=i$I`MGq>PoDt^X1>;(bSk^J_L(sqlZWQNX<=gBBoqe8n5DyAvz~jvSIR?-bp#XyP zHn_xnl9@IMhuRv@-Ti+W{wlhYAOLAvAq0d`U<*vcDfli3bQPMmNQ)`;ut2xd;j|ho zG~{z$YNz4q_NEW~n(4T_#vKEF+*t>v;p^vRaDhkA`+p`nd=W%Du>x2s=g|n+0@FUk zeosEnV}W>*q2G`RURd(+ygr%uD;#=0d@Ke|@aIpnh2sxLe*T%b`;`L*d4JExZgy55 zDtcHzjTS#6pEff_)Mhq=UdDJe4xLay`WQc?WuAsbc%J7!gUtp(?Vg(RUq)LyfgdUV zZJZ$yq(S$#oBy7cTVYb{cJ`Sse;D6v!bG;lxR~bC7m+1^?2`O1;UXw#V;nf9(^G86 z3Ho%u7Ju&rW`(B*Krf7-Q&1O)smBFQFGEFf1Ot5fS~xVi+iH-hXNVh@UA_F|ADvNf zCQ6knsZ?lIy=`TkbsGLU&C)BE->~fZlYdnBqtk74V`Z(43cf=t{0{A`&|luRF0w*r zylZ`Ig=X)yCd7m;I$#}+n);Kgs;-=K?eh8+*VbN%zr0X()%Ep1!{5HSv~tDOl~uJ@ Rh0YwddS&QeBi5FL{{t)^VN?JB diff --git a/slsDetectorSoftware/eigerDetectorServer/slsDetectorFunctionList.c b/slsDetectorSoftware/eigerDetectorServer/slsDetectorFunctionList.c index 4e884acd2..96cadc708 100644 --- a/slsDetectorSoftware/eigerDetectorServer/slsDetectorFunctionList.c +++ b/slsDetectorSoftware/eigerDetectorServer/slsDetectorFunctionList.c @@ -151,7 +151,7 @@ int initDetector(){ //SetRateCorrection(0); //deactivate rate correction int enable[2] = {0,1}; setExternalGating(enable);//disable external gating - Feb_Control_SetTestModeVariable(0); + Feb_Control_SetInTestModeVariable(0); Feb_Control_CheckSetup(); //print detector mac and ip @@ -465,6 +465,11 @@ int pulsePixelNMove(int n, int x, int y){ return OK; } +int pulseChip(int n){ + if(!Feb_Control_PulseChip(n)) + return FAIL; + return OK; +} diff --git a/slsDetectorSoftware/multiSlsDetector/multiSlsDetector.cpp b/slsDetectorSoftware/multiSlsDetector/multiSlsDetector.cpp index 9405d3f38..f7ac43fb1 100644 --- a/slsDetectorSoftware/multiSlsDetector/multiSlsDetector.cpp +++ b/slsDetectorSoftware/multiSlsDetector/multiSlsDetector.cpp @@ -199,7 +199,7 @@ multiSlsDetector::multiSlsDetector(int id) : slsDetectorUtils(), shmId(-1) } thisMultiDetector->receiver_read_freq = 0; - + thisMultiDetector->acquiringFlag = false; thisMultiDetector->alreadyExisting=1; } @@ -5145,4 +5145,27 @@ int multiSlsDetector::pulsePixelNMove(int n,int x,int y) { return ret; } - + +int multiSlsDetector::pulseChip(int n) { + int ret=-100,ret1; + for (int idet=0; idetnumberOfDetectors; idet++) + if (detectors[idet]){ + ret1=detectors[idet]->pulsePixelNMove(n); + if(detectors[idet]->getErrorMask()) + setErrorMask(getErrorMask()|(1<acquiringFlag = b; +} + +bool multiSlsDetector::getAcquiringFlag(){ + return thisMultiDetector->acquiringFlag; +} diff --git a/slsDetectorSoftware/multiSlsDetector/multiSlsDetector.h b/slsDetectorSoftware/multiSlsDetector/multiSlsDetector.h index 85eb894bb..311810396 100644 --- a/slsDetectorSoftware/multiSlsDetector/multiSlsDetector.h +++ b/slsDetectorSoftware/multiSlsDetector/multiSlsDetector.h @@ -194,6 +194,9 @@ class multiSlsDetector : public slsDetectorUtils { /* Receiver read frequency */ int receiver_read_freq; + /** flag for acquiring */ + bool acquiringFlag; + }; @@ -1321,9 +1324,24 @@ class multiSlsDetector : public slsDetectorUtils { */ int pulsePixelNMove(int n=0,int x=0,int y=0); + /** + Pulse Chip + \param n is number of times to pulse + \returns OK or FAIL + */ + int pulseChip(int n=0); + + /** + Set acquiring flag in shared memory + \param b acquiring flag + */ + void setAcquiringFlag(bool b=false); - - + /** + Get acquiring flag from shared memory + \returns acquiring flag + */ + bool getAcquiringFlag(); diff --git a/slsDetectorSoftware/slsDetector/slsDetector.cpp b/slsDetectorSoftware/slsDetector/slsDetector.cpp index 6f94fbaa8..8b0581c8b 100644 --- a/slsDetectorSoftware/slsDetector/slsDetector.cpp +++ b/slsDetectorSoftware/slsDetector/slsDetector.cpp @@ -347,6 +347,7 @@ slsDetectorDefs::detectorType slsDetector::getDetectorType(const char *name, int #endif if (connectData() == OK) retval=thisReceiver->sendInt(fnum2,k,(int)t); + disconnectData(); if(retval==FAIL){ cout << "ERROR: Could not send detector type to receiver" << endl; setErrorMask((getErrorMask())|(RECEIVER_DET_HOSTTYPE_NOT_SET)); @@ -732,6 +733,7 @@ int slsDetector::initializeDetectorSize(detectorType type) { thisDetector->actionMask=0; thisDetector->tenGigaEnable=0; + thisDetector->acquiringFlag = false; for (int ia=0; iaactionScript[ia],"none"); @@ -1190,7 +1192,7 @@ string slsDetector::checkOnline() { } //still cannot connect to socket, controlSocket=0 if(controlSocket){ - if (controlSocket->Connect()<0) { + if (connectControl() == FAIL) { controlSocket->SetTimeOut(5); thisDetector->onlineFlag=OFFLINE_FLAG; delete controlSocket; @@ -1202,7 +1204,7 @@ string slsDetector::checkOnline() { } else { thisDetector->onlineFlag=ONLINE_FLAG; controlSocket->SetTimeOut(100); - controlSocket->Disconnect(); + disconnectControl(); #ifdef VERBOSE std::cout<< "online!" << std::endl; #endif @@ -1344,8 +1346,7 @@ int slsDetector::connectData() { else{ std::cout << "cannot connect to receiver" << endl; setErrorMask((getErrorMask())|(CANNOT_CONNECT_TO_RECEIVER)); - return FAIL; - } + return FAIL;} } return UNDEFINED; }; @@ -1359,9 +1360,15 @@ int slsDetector::disconnectData(){ /** connect to the stop port */ int slsDetector::connectStop() { - if (stopSocket) - return stopSocket->Connect(); - return FAIL; + if (stopSocket){ + if (stopSocket->Connect() >= 0) + return OK; + else{ + std::cout << "cannot connect to stop server" << endl; + return FAIL; + } + } + return UNDEFINED; }; /** disconnect from the stop port */ int slsDetector::disconnectStop(){ @@ -1418,7 +1425,7 @@ int slsDetector::execCommand(string cmd, string answer){ } } } - controlSocket->Disconnect(); + disconnectControl(); } #ifdef VERBOSE std::cout<< "Detector answer is " << answer << std::endl; @@ -1468,7 +1475,7 @@ int slsDetector::setDetectorType(detectorType const type){ controlSocket->ReceiveDataOnly(mess,sizeof(mess)); std::cout<< "Detector returned error: " << mess << std::endl; } - controlSocket->Disconnect(); + disconnectControl(); if (retval==FORCE_UPDATE) updateDetector(); } @@ -1501,6 +1508,7 @@ int slsDetector::setDetectorType(detectorType const type){ #endif if (connectData() == OK) retval=thisReceiver->sendInt(fnum2,arg,(int)thisDetector->myDetectorType); + disconnectData(); if(retval==FAIL){ cout << "ERROR: Could not send detector type to receiver" << endl; setErrorMask((getErrorMask())|(RECEIVER_DET_HOSTTYPE_NOT_SET)); @@ -1563,7 +1571,7 @@ int slsDetector::setNumberOfModules(int n, dimension d){ controlSocket->ReceiveDataOnly(mess,sizeof(mess)); std::cout<< "Detector returned error: " << mess << std::endl; } - controlSocket->Disconnect(); + disconnectControl(); if (ret==FORCE_UPDATE) updateDetector(); } @@ -1661,7 +1669,7 @@ int slsDetector::getMaxNumberOfModules(dimension d){ controlSocket->ReceiveDataOnly(mess,sizeof(mess)); std::cout<< "Detector returned error: " << mess << std::endl; } - controlSocket->Disconnect(); + disconnectControl(); if (ret==FORCE_UPDATE) updateDetector(); } @@ -1731,7 +1739,7 @@ slsDetectorDefs::externalSignalFlag slsDetector::setExternalSignalFlags(external controlSocket->ReceiveDataOnly(mess,sizeof(mess)); std::cout<< "Detector returned error: " << mess << std::endl; } - controlSocket->Disconnect(); + disconnectControl(); if (ret==FORCE_UPDATE) updateDetector(); } @@ -1800,7 +1808,7 @@ slsDetectorDefs::externalCommunicationMode slsDetector::setExternalCommunication controlSocket->ReceiveDataOnly(mess,sizeof(mess)); std::cout<< "Detector returned error: " << mess << std::endl; } - controlSocket->Disconnect(); + disconnectControl(); if (ret==FORCE_UPDATE) updateDetector(); } @@ -1860,6 +1868,7 @@ int64_t slsDetector::getId( idMode mode, int imod){ if (setReceiverOnline(ONLINE_FLAG)==ONLINE_FLAG) { if (connectData() == OK) ret=thisReceiver->getInt(fnum2,retval); + disconnectData(); if(ret==FORCE_UPDATE) ret=updateReceiver(); } @@ -1879,7 +1888,7 @@ int64_t slsDetector::getId( idMode mode, int imod){ controlSocket->ReceiveDataOnly(mess,sizeof(mess)); std::cout<< "Detector returned error: " << mess << std::endl; } - controlSocket->Disconnect(); + disconnectControl(); if (ret==FORCE_UPDATE) updateDetector(); } @@ -1941,7 +1950,7 @@ int slsDetector::digitalTest( digitalTestMode mode, int imod){ controlSocket->ReceiveDataOnly(mess,sizeof(mess)); std::cout<< "Detector returned error: " << mess << std::endl; } - controlSocket->Disconnect(); + disconnectControl(); if (ret==FORCE_UPDATE) updateDetector(); } @@ -2032,7 +2041,7 @@ int slsDetector::writeRegister(int addr, int val){ controlSocket->ReceiveDataOnly(mess,sizeof(mess)); std::cout<< "Detector returned error: " << mess << std::endl; } - controlSocket->Disconnect(); + disconnectControl(); if (ret==FORCE_UPDATE) updateDetector(); } @@ -2077,7 +2086,7 @@ int slsDetector::writeAdcRegister(int addr, int val){ controlSocket->ReceiveDataOnly(mess,sizeof(mess)); std::cout<< "Detector returned error: " << mess << std::endl; } - controlSocket->Disconnect(); + disconnectControl(); if (ret==FORCE_UPDATE) updateDetector(); } @@ -2115,7 +2124,7 @@ int slsDetector::readRegister(int addr){ if (thisDetector->onlineFlag==ONLINE_FLAG) { // if (connectControl() == OK){ if (stopSocket) { - if (stopSocket->Connect()>=0) { + if (connectStop() == OK) { stopSocket->SendDataOnly(&fnum,sizeof(fnum)); stopSocket->SendDataOnly(&arg,sizeof(arg)); stopSocket->ReceiveDataOnly(&ret,sizeof(ret)); @@ -2125,7 +2134,7 @@ int slsDetector::readRegister(int addr){ stopSocket->ReceiveDataOnly(mess,sizeof(mess)); std::cout<< "Detector returned error: " << mess << std::endl; } - stopSocket->Disconnect(); + disconnectStop(); // if (ret==FORCE_UPDATE) // updateDetector(); } @@ -2200,7 +2209,7 @@ dacs_t slsDetector::setDAC(dacs_t val, dacIndex index, int mV, int imod){ controlSocket->ReceiveDataOnly(mess,sizeof(mess)); std::cout<< "Detector returned error: " << mess << std::endl; } - controlSocket->Disconnect(); + disconnectControl(); if (ret==FORCE_UPDATE) updateDetector(); @@ -2250,7 +2259,7 @@ dacs_t slsDetector::getADC(dacIndex index, int imod){ controlSocket->ReceiveDataOnly(mess,sizeof(mess)); std::cout<< "Detector returned error: " << mess << std::endl; } - controlSocket->Disconnect(); + disconnectControl(); if (ret==FORCE_UPDATE) updateDetector(); } @@ -2340,7 +2349,7 @@ int slsDetector::setChannel(sls_detector_channel chan){ controlSocket->ReceiveDataOnly(mess,sizeof(mess)); std::cout<< "Detector returned error: " << mess << std::endl; } - controlSocket->Disconnect(); + disconnectControl(); if (ret==FORCE_UPDATE) updateDetector(); } @@ -2431,7 +2440,7 @@ slsDetectorDefs::sls_detector_channel slsDetector::getChannel(int ichan, int ic controlSocket->ReceiveDataOnly(mess,sizeof(mess)); std::cout<< "Detector returned error: " << mess << std::endl; } - controlSocket->Disconnect(); + disconnectControl(); if (ret==FORCE_UPDATE) updateDetector(); } @@ -2522,7 +2531,7 @@ int slsDetector::setChip(sls_detector_chip chip){ controlSocket->ReceiveDataOnly(mess,sizeof(mess)); std::cout<< "Detector returned error: " << mess << std::endl; } - controlSocket->Disconnect(); + disconnectControl(); if (ret==FORCE_UPDATE) updateDetector(); } @@ -2575,7 +2584,7 @@ slsDetectorDefs::sls_detector_chip slsDetector::getChip(int ichip, int imod){ controlSocket->ReceiveDataOnly(mess,sizeof(mess)); std::cout<< "Detector returned error: " << mess << std::endl; } - controlSocket->Disconnect(); + disconnectControl(); if (ret==FORCE_UPDATE) updateDetector(); } @@ -2716,7 +2725,7 @@ int slsDetector::setModule(sls_detector_module module, int* gainval, int* offset controlSocket->ReceiveDataOnly(mess,sizeof(mess)); std::cout<< "Detector returned error: " << mess << std::endl; } - controlSocket->Disconnect(); + disconnectControl(); if (ret==FORCE_UPDATE) updateDetector(); } @@ -2841,7 +2850,7 @@ slsDetectorDefs::sls_detector_module *slsDetector::getModule(int imod){ controlSocket->ReceiveDataOnly(mess,sizeof(mess)); std::cout<< "Detector returned error: " << mess << std::endl; } - controlSocket->Disconnect(); + disconnectControl(); if (ret==FORCE_UPDATE) updateDetector(); } @@ -2957,7 +2966,7 @@ int slsDetector::getThresholdEnergy(int imod){ controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); thisDetector->currentThresholdEV=retval; } - controlSocket->Disconnect(); + disconnectControl(); if (ret==FORCE_UPDATE) updateDetector(); } @@ -2992,7 +3001,7 @@ int slsDetector::setThresholdEnergy(int e_eV, int imod, detectorSettings isetti controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); thisDetector->currentThresholdEV=retval; } - controlSocket->Disconnect(); + disconnectControl(); if (ret==FORCE_UPDATE) updateDetector(); } @@ -3033,7 +3042,7 @@ slsDetectorDefs::detectorSettings slsDetector::getSettings(int imod){ std::cout<< "Settings are "<< retval << std::endl; #endif } - controlSocket->Disconnect(); + disconnectControl(); if (ret==FORCE_UPDATE) updateDetector(); } @@ -3392,7 +3401,7 @@ int slsDetector::updateDetector() { std::cout<< "Detector returned error: " << mess << std::endl; } else updateDetectorNoWait(); - controlSocket->Disconnect(); + disconnectControl(); } } return ret; @@ -3422,7 +3431,7 @@ int slsDetector::startAcquisition(){ controlSocket->ReceiveDataOnly(mess,sizeof(mess)); std::cout<< "Detector returned error: " << mess << std::endl; } - controlSocket->Disconnect(); + disconnectControl(); if (ret==FORCE_UPDATE) updateDetector(); } @@ -3444,14 +3453,14 @@ int slsDetector::stopAcquisition(){ #endif if (thisDetector->onlineFlag==ONLINE_FLAG) { if (stopSocket) { - if (stopSocket->Connect()>=0) { + if (connectStop() == OK) { stopSocket->SendDataOnly(&fnum,sizeof(fnum)); stopSocket->ReceiveDataOnly(&ret,sizeof(ret)); if (ret==FAIL) { stopSocket->ReceiveDataOnly(mess,sizeof(mess)); std::cout<< "Detector returned error: " << mess << std::endl; } - stopSocket->Disconnect(); + disconnectStop(); } } } @@ -3478,7 +3487,7 @@ int slsDetector::startReadOut(){ controlSocket->ReceiveDataOnly(mess,sizeof(mess)); std::cout<< "Detector returned error: " << mess << std::endl; } - controlSocket->Disconnect(); + disconnectControl(); if (ret==FORCE_UPDATE) updateDetector(); } @@ -3498,7 +3507,7 @@ slsDetectorDefs::runStatus slsDetector::getRunStatus(){ //#endif if (thisDetector->onlineFlag==ONLINE_FLAG) { if (stopSocket) { - if (stopSocket->Connect()>=0) { + if (connectStop() == OK) { stopSocket->SendDataOnly(&fnum,sizeof(fnum)); stopSocket->ReceiveDataOnly(&ret,sizeof(ret)); @@ -3511,7 +3520,7 @@ slsDetectorDefs::runStatus slsDetector::getRunStatus(){ stopSocket->ReceiveDataOnly(&retval,sizeof(retval)); //cout << "____________________" << retval << endl; } - stopSocket->Disconnect(); + disconnectStop(); } } } @@ -3535,7 +3544,7 @@ int* slsDetector::readFrame(){ retval=getDataFromDetector(); if (retval) { dataQueue.push(retval); - controlSocket->Disconnect(); + disconnectControl(); } } } @@ -3633,7 +3642,7 @@ int* slsDetector::readAll(){ dataQueue.push(retval); std::cout<< "pushed" << std::endl; } - controlSocket->Disconnect(); + disconnectControl(); } } #ifdef VERBOSE @@ -3693,7 +3702,7 @@ int* slsDetector::startAndReadAll(){ #endif dataQueue.push(retval); } - controlSocket->Disconnect(); + disconnectControl(); #ifdef VERBOSE std::cout<< "received "<< i<< " frames" << std::endl; @@ -3736,7 +3745,7 @@ int slsDetector::startAndReadAllNoWait(){ // if (thisDetector->onlineFlag==ONLINE_FLAG) { // if (controlSocket) { // if (retval==NULL){ -// controlSocket->Disconnect(); +// disconnectControl(); // #ifdef VERBOSE // std::cout<< "Run finished "<< std::endl; @@ -3797,7 +3806,7 @@ int64_t slsDetector::setTimer(timerIndex index, int64_t t){ controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); thisDetector->timerValue[index]=retval; } - controlSocket->Disconnect(); + disconnectControl(); if (ret==FORCE_UPDATE) { updateDetector(); #ifdef VERBOSE @@ -3865,6 +3874,7 @@ int64_t slsDetector::setTimer(timerIndex index, int64_t t){ if (connectData() == OK) ret=thisReceiver->sendIntArray(fnum2,ut,args); + disconnectData(); if((ut != retval)|| (ret==FAIL)){ ret = FAIL; if(index==FRAME_PERIOD){ @@ -3905,7 +3915,7 @@ int slsDetector::lockServer(int lock) { } else { controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); } - controlSocket->Disconnect(); + disconnectControl(); if (ret==FORCE_UPDATE) updateDetector(); } @@ -3934,7 +3944,7 @@ string slsDetector::getLastClientIP() { } else { controlSocket->ReceiveDataOnly(clientName,sizeof(clientName)); } - controlSocket->Disconnect(); + disconnectControl(); if (ret==FORCE_UPDATE) updateDetector(); } @@ -4261,7 +4271,7 @@ int slsDetector::setSpeed(speedVariable sp, int value) { } else { controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); } - controlSocket->Disconnect(); + disconnectControl(); if (ret==FORCE_UPDATE) updateDetector(); } @@ -4289,7 +4299,7 @@ int64_t slsDetector::getTimeLeft(timerIndex index){ #endif if (thisDetector->onlineFlag==ONLINE_FLAG) { if (stopSocket) { - if (stopSocket->Connect()>=0) { + if (connectStop() == OK) { stopSocket->SendDataOnly(&fnum,sizeof(fnum)); stopSocket->SendDataOnly(&index,sizeof(index)); stopSocket->ReceiveDataOnly(&ret,sizeof(ret)); @@ -4299,7 +4309,7 @@ int64_t slsDetector::getTimeLeft(timerIndex index){ } else { stopSocket->ReceiveDataOnly(&retval,sizeof(retval)); } - stopSocket->Disconnect(); + disconnectStop(); } } } @@ -4339,7 +4349,7 @@ int slsDetector::setDynamicRange(int n){ } else { controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); } - controlSocket->Disconnect(); + disconnectControl(); if (ret==FORCE_UPDATE) updateDetector(); } @@ -4388,6 +4398,7 @@ int slsDetector::setDynamicRange(int n){ #endif if (connectData() == OK) ret=thisReceiver->sendInt(fnum2,retval1,n); + disconnectData(); if ((ret==FAIL) || (retval1 != retval)){ ret = FAIL; cout << "ERROR:Dynamic range in receiver set incorrectly to " << retval1 << " instead of " << retval << endl; @@ -4471,7 +4482,7 @@ int slsDetector::sendROI(int n,ROI roiLimits[]){ controlSocket->ReceiveDataOnly(mess,sizeof(mess)); std::cout<< "Detector returned error: " << mess << std::endl; } - controlSocket->Disconnect(); + disconnectControl(); if (ret==FORCE_UPDATE) updateDetector(); } @@ -4531,7 +4542,7 @@ int slsDetector::setReadOutFlags(readOutFlags flag){ controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); thisDetector->roFlags=retval; } - controlSocket->Disconnect(); + disconnectControl(); if (ret==FORCE_UPDATE) updateDetector(); } @@ -4595,7 +4606,7 @@ int slsDetector::executeTrimming(trimMode mode, int par1, int par2, int imod){ */ retval=ret; } - controlSocket->Disconnect(); + disconnectControl(); if (ret==FORCE_UPDATE) updateDetector(); } @@ -5086,7 +5097,7 @@ int slsDetector::exitServer(){ controlSocket->Connect(); controlSocket->SendDataOnly(&fnum,sizeof(fnum)); controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); - controlSocket->Disconnect(); + disconnectControl(); } } if (retval!=OK) { @@ -5355,6 +5366,7 @@ int slsDetector::setUDPConnection(){ #endif if (connectData() == OK) ret=thisReceiver->sendUDPDetails(fnum,retval,args); + disconnectData(); if(ret!=FAIL){ strcpy(thisDetector->receiverUDPMAC,retval); @@ -5492,7 +5504,7 @@ int slsDetector::configureMAC(){ } else controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); - controlSocket->Disconnect(); + disconnectControl(); if (ret==FORCE_UPDATE) updateDetector(); } @@ -5517,6 +5529,7 @@ int slsDetector::configureMAC(){ #endif if (connectData() == OK) ret=thisReceiver->sendInt(fnum2,retval,retval); + disconnectData(); if(ret==FAIL) setErrorMask((getErrorMask())|(COULD_NOT_CONFIGURE_MAC)); } @@ -5633,7 +5646,7 @@ int slsDetector::sendImageToDetector(imageType index,short int imageVals[]){ controlSocket->ReceiveDataOnly(mess,sizeof(mess)); std::cout<< "Detector returned error: " << mess << std::endl; } - controlSocket->Disconnect(); + disconnectControl(); if (ret==FORCE_UPDATE) updateDetector(); } @@ -5658,7 +5671,7 @@ int slsDetector::getCounterBlock(short int arg[],int startACQ){ controlSocket->ReceiveDataOnly(mess,sizeof(mess)); std::cout<< "Detector returned error: " << mess << std::endl; } - controlSocket->Disconnect(); + disconnectControl(); if (ret==FORCE_UPDATE) updateDetector(); } @@ -5710,7 +5723,7 @@ int slsDetector::resetCounterBlock(int startACQ){ controlSocket->ReceiveDataOnly(mess,sizeof(mess)); std::cout<< "Detector returned error: " << mess << std::endl; } - controlSocket->Disconnect(); + disconnectControl(); if (ret==FORCE_UPDATE) updateDetector(); } @@ -5747,7 +5760,7 @@ int slsDetector::setCounterBit(int i){ setErrorMask((getErrorMask())|(COULD_NOT_SET_COUNTER_BIT)); } controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); - controlSocket->Disconnect(); + disconnectControl(); if (ret==FORCE_UPDATE) updateDetector(); @@ -6114,7 +6127,7 @@ int slsDetector::setAllTrimbits(int val, int imod){ } else { controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); } - controlSocket->Disconnect(); + disconnectControl(); if (ret==FORCE_UPDATE) updateDetector(); } @@ -6250,7 +6263,7 @@ slsDetectorDefs::masterFlags slsDetector::setMaster(masterFlags flag) { } else { controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); } - controlSocket->Disconnect(); + disconnectControl(); if (ret==FORCE_UPDATE) updateDetector(); } @@ -6294,7 +6307,7 @@ slsDetectorDefs::synchronizationMode slsDetector::setSynchronization(synchroniza } else { controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); } - controlSocket->Disconnect(); + disconnectControl(); if (ret==FORCE_UPDATE) updateDetector(); } @@ -6349,7 +6362,7 @@ string slsDetector::checkReceiverOnline() { } //still cannot connect to socket, dataSocket=0 if(dataSocket){ - if (dataSocket->Connect()<0) { + if (connectData() == FAIL) { dataSocket->SetTimeOut(5); thisDetector->receiverOnlineFlag=OFFLINE_FLAG; delete dataSocket; @@ -6361,7 +6374,7 @@ string slsDetector::checkReceiverOnline() { } else { thisDetector->receiverOnlineFlag=ONLINE_FLAG; dataSocket->SetTimeOut(100); - dataSocket->Disconnect(); + disconnectData(); #ifdef VERBOSE std::cout<< "receiver online!" << std::endl; #endif @@ -6467,6 +6480,7 @@ string slsDetector::setFilePath(string s) { #endif if (connectData() == OK) ret=thisReceiver->sendString(fnum,retval,arg); + disconnectData(); if(ret!=FAIL) fileIO::setFilePath(string(retval)); else if(!s.empty()){ @@ -6502,6 +6516,7 @@ string slsDetector::setFileName(string s) { #endif if (connectData() == OK) ret=thisReceiver->sendString(fnum,retval,arg); + disconnectData(); if(ret!=FAIL){ #ifdef VERBOSE std::cout << "Complete file prefix from receiver: " << retval << std::endl; @@ -6538,6 +6553,7 @@ int slsDetector::setFileIndex(int i) { #endif if (connectData() == OK) ret=thisReceiver->sendInt(fnum,retval,arg); + disconnectData(); if(ret!=FAIL) fileIO::setFileIndex(retval); if(ret==FORCE_UPDATE) @@ -6561,6 +6577,7 @@ int slsDetector::startReceiver(){ #endif if (connectData() == OK) ret=thisReceiver->executeFunction(fnum,mess); + disconnectData(); if(ret==FORCE_UPDATE) ret=updateReceiver(); else if (ret == FAIL){ @@ -6595,6 +6612,7 @@ int slsDetector::stopReceiver(){ #endif if (connectData() == OK) ret=thisReceiver->executeFunction(fnum,mess); + disconnectData(); if(ret==FORCE_UPDATE) ret=updateReceiver(); else if (ret == FAIL) @@ -6619,6 +6637,7 @@ slsDetectorDefs::runStatus slsDetector::startReceiverReadout(){ #endif if (connectData() == OK) ret=thisReceiver->getInt(fnum,retval); + disconnectData(); if(retval!=-1) s=(runStatus)retval; if(ret==FORCE_UPDATE) @@ -6647,7 +6666,7 @@ int slsDetector::detectorSendToReceiver(bool set){ controlSocket->ReceiveDataOnly(mess,sizeof(mess)); std::cout<< "Detector returned error: " << mess << std::endl; } - controlSocket->Disconnect(); + disconnectControl(); if (ret==FORCE_UPDATE) updateDetector(); } @@ -6675,6 +6694,7 @@ slsDetectorDefs::runStatus slsDetector::getReceiverStatus(){ #endif if (connectData() == OK) ret=thisReceiver->getInt(fnum,retval); + disconnectData(); if(retval!=-1) s=(runStatus)retval; if(ret==FORCE_UPDATE) @@ -6698,6 +6718,7 @@ int slsDetector::getFramesCaughtByReceiver(){ #endif if (connectData() == OK) ret=thisReceiver->getInt(fnum,retval); + disconnectData(); if(ret==FORCE_UPDATE) ret=updateReceiver(); } @@ -6718,6 +6739,7 @@ int slsDetector::getReceiverCurrentFrameIndex(){ #endif if (connectData() == OK) ret=thisReceiver->getInt(fnum,retval); + disconnectData(); if(ret==FORCE_UPDATE) ret=updateReceiver(); } @@ -6739,6 +6761,7 @@ int slsDetector::resetFramesCaught(){ #endif if (connectData() == OK) ret=thisReceiver->executeFunction(fnum,mess); + disconnectData(); if(ret==FORCE_UPDATE) ret=updateReceiver(); } @@ -6771,7 +6794,7 @@ int* slsDetector::readFrameFromReceiver(char* fName, int &acquisitionIndex, int n= dataSocket->ReceiveDataOnly(mess,sizeof(mess)); std::cout<< "Detector returned: " << mess << " " << n << std::endl; delete [] retval; - dataSocket->Disconnect(); + disconnectData(); return NULL; } else { n=dataSocket->ReceiveDataOnly(fName,MAX_STR_LENGTH); @@ -6788,11 +6811,11 @@ int* slsDetector::readFrameFromReceiver(char* fName, int &acquisitionIndex, int std::cout<dataBytes << std::endl; ret=FAIL; delete [] retval; - dataSocket->Disconnect(); + disconnectData(); return NULL; } } - dataSocket->Disconnect(); + disconnectData(); } } return retval; @@ -6816,6 +6839,7 @@ int slsDetector::lockReceiver(int lock){ #endif if (connectData() == OK) ret=thisReceiver->sendInt(fnum,retval,arg); + disconnectData(); if(ret==FORCE_UPDATE) updateReceiver(); } @@ -6839,6 +6863,7 @@ string slsDetector::getReceiverLastClientIP(){ #endif if (connectData() == OK) ret=thisReceiver->getLastClientIP(fnum,retval); + disconnectData(); if(ret==FORCE_UPDATE) updateReceiver(); } @@ -6889,7 +6914,7 @@ int slsDetector::updateReceiver() { dataSocket->ReceiveDataOnly(mess,sizeof(mess)); std::cout<< "Receiver returned error: " << mess << std::endl; } - dataSocket->Disconnect(); + disconnectData(); } } @@ -6911,7 +6936,7 @@ int slsDetector::exitReceiver(){ dataSocket->Connect(); dataSocket->SendDataOnly(&fnum,sizeof(fnum)); dataSocket->ReceiveDataOnly(&retval,sizeof(retval)); - dataSocket->Disconnect(); + disconnectData(); } } if (retval!=OK) { @@ -6945,6 +6970,7 @@ int slsDetector::enableWriteToFile(int enable){ #endif if (connectData() == OK) ret=thisReceiver->sendInt(fnum,retval,arg); + disconnectData(); if(ret!=FAIL) parentDet->enableWriteToFileMask(retval); if(ret==FORCE_UPDATE) @@ -6975,6 +7001,7 @@ int slsDetector::overwriteFile(int enable){ #endif if (connectData() == OK) ret=thisReceiver->sendInt(fnum,retval,arg); + disconnectData(); if(ret!=FAIL) parentDet->enableOverwriteMask(retval); if(ret==FORCE_UPDATE) @@ -7003,6 +7030,7 @@ int slsDetector::setFrameIndex(int index){ #endif if (connectData() == OK) ret=thisReceiver->sendInt(fnum,retval,arg); + disconnectData(); if(ret!=FAIL) fileIO::setFrameIndex(retval); if(ret==FORCE_UPDATE) @@ -7034,7 +7062,7 @@ int slsDetector::calibratePedestal(int frames){ controlSocket->ReceiveDataOnly(mess,sizeof(mess)); std::cout<< "Detector returned error: " << mess << std::endl; } - controlSocket->Disconnect(); + disconnectControl(); if (ret==FORCE_UPDATE) updateDetector(); } @@ -7071,6 +7099,7 @@ int slsDetector::setReadReceiverFrequency(int getFromReceiver,int i){ #endif if (connectData() == OK) ret=thisReceiver->sendInt(fnum,retval,arg); + disconnectData(); if(ret==FAIL) retval = -1; if(ret==FORCE_UPDATE) @@ -7097,6 +7126,7 @@ int slsDetector::enableReceiverCompression(int i){ #endif if (connectData() == OK) ret=thisReceiver->sendInt(fnum,retval,i); + disconnectData(); if(ret==FAIL) setErrorMask((getErrorMask())|(COULDNOT_ENABLE_COMPRESSION)); } @@ -7117,6 +7147,7 @@ void slsDetector::setDetectorHostname(){ #endif if (connectData() == OK) ret=thisReceiver->sendString(fnum,retval,thisDetector->hostname); + disconnectData(); if((ret==FAIL) || (strcmp(retval,thisDetector->hostname))) setErrorMask((getErrorMask())|(RECEIVER_DET_HOSTNAME_NOT_SET)); } @@ -7145,7 +7176,7 @@ int slsDetector::enableTenGigabitEthernet(int i){ setErrorMask((getErrorMask())|(DETECTOR_TEN_GIGA)); } controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); - controlSocket->Disconnect(); + disconnectControl(); if (ret==FORCE_UPDATE) updateDetector(); } @@ -7164,6 +7195,7 @@ int slsDetector::enableTenGigabitEthernet(int i){ #endif if (connectData() == OK) ret=thisReceiver->sendInt(fnum2,retval,i); + disconnectData(); if(ret==FAIL) setErrorMask((getErrorMask())|(RECEIVER_TEN_GIGA)); } @@ -7193,6 +7225,7 @@ int slsDetector::setReceiverFifoDepth(int i){ #endif if (connectData() == OK) ret=thisReceiver->sendInt(fnum,retval,i); + disconnectData(); if(ret==FAIL) setErrorMask((getErrorMask())|(COULD_NOT_SET_FIFO_DEPTH)); } @@ -7288,7 +7321,7 @@ uint64_t slsDetector::setCTBWord(int addr,uint64_t word) { controlSocket->ReceiveDataOnly(mess,sizeof(mess)); std::cout<< "Detector returned error: " << mess << std::endl; } - controlSocket->Disconnect(); + disconnectControl(); if (ret==FORCE_UPDATE) updateDetector(); } @@ -7342,7 +7375,7 @@ int slsDetector::setCTBPatLoops(int level,int &start, int &stop, int &n) { controlSocket->ReceiveDataOnly(mess,sizeof(mess)); std::cout<< "Detector returned error: " << mess << std::endl; } - controlSocket->Disconnect(); + disconnectControl(); if (ret==FORCE_UPDATE) updateDetector(); } @@ -7390,7 +7423,7 @@ int slsDetector::setCTBPatWaitAddr(int level, int addr) { controlSocket->ReceiveDataOnly(mess,sizeof(mess)); std::cout<< "Detector returned error: " << mess << std::endl; } - controlSocket->Disconnect(); + disconnectControl(); if (ret==FORCE_UPDATE) updateDetector(); } @@ -7440,7 +7473,7 @@ int slsDetector::setCTBPatWaitTime(int level, uint64_t t) { controlSocket->ReceiveDataOnly(mess,sizeof(mess)); std::cout<< "Detector returned error: " << mess << std::endl; } - controlSocket->Disconnect(); + disconnectControl(); if (ret==FORCE_UPDATE) updateDetector(); } @@ -7472,7 +7505,7 @@ int slsDetector::pulsePixel(int n,int x,int y) { std::cout<< "Detector returned error: " << mess << std::endl; setErrorMask((getErrorMask())|(COULD_NOT_PULSE_PIXEL)); } - controlSocket->Disconnect(); + disconnectControl(); if (ret==FORCE_UPDATE) updateDetector(); } @@ -7503,7 +7536,7 @@ int slsDetector::pulsePixelNMove(int n,int x,int y) { std::cout<< "Detector returned error: " << mess << std::endl; setErrorMask((getErrorMask())|(COULD_NOT_PULSE_PIXEL_NMOVE)); } - controlSocket->Disconnect(); + disconnectControl(); if (ret==FORCE_UPDATE) updateDetector(); } @@ -7512,4 +7545,43 @@ int slsDetector::pulsePixelNMove(int n,int x,int y) { return ret; } - + + +int slsDetector::pulseChip(int n) { + int ret=FAIL; + int fnum=F_PULSE_CHIP; + char mess[100]; + + +#ifdef VERBOSE + std::cout<< std::endl<< "Pulsing Pixel " << n << " number of times" << endl << endl; +#endif + + if (thisDetector->onlineFlag==ONLINE_FLAG) { + if (connectControl() == OK){ + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + controlSocket->SendDataOnly(&n,sizeof(n)); + controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret==FAIL){ + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + setErrorMask((getErrorMask())|(COULD_NOT_PULSE_CHIP)); + } + disconnectControl(); + if (ret==FORCE_UPDATE) + updateDetector(); + } + } + + return ret; +} + + + +void slsDetector::setAcquiringFlag(bool b){ + thisDetector->acquiringFlag = b; +} + +bool slsDetector::getAcquiringFlag(){ + return thisDetector->acquiringFlag; +} diff --git a/slsDetectorSoftware/slsDetector/slsDetector.h b/slsDetectorSoftware/slsDetector/slsDetector.h index f80c3e80f..66c08783e 100644 --- a/slsDetectorSoftware/slsDetector/slsDetector.h +++ b/slsDetectorSoftware/slsDetector/slsDetector.h @@ -265,6 +265,9 @@ class slsDetector : public slsDetectorUtils, public energyConversion { /** 10 Gbe enable*/ int tenGigaEnable; + /** flag for acquiring */ + bool acquiringFlag; + } sharedSlsDetector; @@ -1752,6 +1755,25 @@ class slsDetector : public slsDetectorUtils, public energyConversion { */ int pulsePixelNMove(int n=0,int x=0,int y=0); + /** + Pulse Chip + \param n is number of times to pulse + \returns OK or FAIL + */ + int pulseChip(int n=0); + + /** + Set acquiring flag in shared memory + \param b acquiring flag + */ + void setAcquiringFlag(bool b=false); + + /** + Get acquiring flag from shared memory + \returns acquiring flag + */ + bool getAcquiringFlag(); + protected: diff --git a/slsDetectorSoftware/slsDetector/slsDetectorBase.h b/slsDetectorSoftware/slsDetector/slsDetectorBase.h index 22d1ee691..7377036db 100644 --- a/slsDetectorSoftware/slsDetector/slsDetectorBase.h +++ b/slsDetectorSoftware/slsDetector/slsDetectorBase.h @@ -321,9 +321,9 @@ class slsDetectorBase : public virtual slsDetectorDefs, public virtual errorDef reads the encoder (iof required for angualr conversion)
processes the data (flat field, rate, angular conversion and merging ::processData()) \param delflag 0 leaves the data in the final data queue (default is 1) - \returns nothing + \returns OK or FAIL depending on if it already started */ - virtual void acquire(int delflag=1)=0; + virtual int acquire(int delflag=1)=0; int startMeasurement(){acquire(0); return OK;}; diff --git a/slsDetectorSoftware/slsDetector/slsDetectorCommand.cpp b/slsDetectorSoftware/slsDetector/slsDetectorCommand.cpp index 326511759..411d87de9 100644 --- a/slsDetectorSoftware/slsDetector/slsDetectorCommand.cpp +++ b/slsDetectorSoftware/slsDetector/slsDetectorCommand.cpp @@ -1019,7 +1019,7 @@ slsDetectorCommand::slsDetectorCommand(slsDetectorUtils *det) { i++; - /* pulse pixel */ + /* pulse */ descrToFuncMap[i].m_pFuncName="pulse"; // descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdPulse; @@ -1029,7 +1029,10 @@ slsDetectorCommand::slsDetectorCommand(slsDetectorUtils *det) { descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdPulse; i++; - + descrToFuncMap[i].m_pFuncName="pulsechip"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdPulse; + i++; + numberOfCommands=i; @@ -1132,7 +1135,9 @@ string slsDetectorCommand::cmdAcquire(int narg, char *args[], int action) { myDet->setOnline(ONLINE_FLAG); - myDet->acquire(); + + if(myDet->acquire() == FAIL) + return string("acquire unsuccessful"); if(myDet->setReceiverOnline()==ONLINE_FLAG){ char answer[100]; sprintf(answer,"\n%d",myDet->getFramesCaughtByReceiver()); @@ -4934,10 +4939,12 @@ string slsDetectorCommand::helpPulse(int narg, char *args[], int action) { if (action==PUT_ACTION || action==HELP_ACTION) { os << "pulse [n] [x] [y] \t pulses pixel at coordinates (x,y) n number of times" << std::endl; os << "pulsenmove [n] [x] [y]\t pulses pixel n number of times and moves relatively by x value (x axis) and y value(y axis)" << std::endl; + os << "pulsechip [n] \t pulses chip n number of times, while n=-1 will reset it to normal mode" << std::endl; } if (action==GET_ACTION || action==HELP_ACTION){ os << "pulse \t cannot get" << std::endl; os << "pulsenmove \t cannot get" << std::endl; + os << "pulsechip \t cannot get" << std::endl; } return os.str(); @@ -4945,6 +4952,7 @@ string slsDetectorCommand::helpPulse(int narg, char *args[], int action) { string slsDetectorCommand::cmdPulse(int narg, char *args[], int action) { + int retval = FAIL; if (action==HELP_ACTION) return helpPulse(narg, args, action); @@ -4953,32 +4961,43 @@ string slsDetectorCommand::cmdPulse(int narg, char *args[], int action) { myDet->setOnline(ONLINE_FLAG); - if(narg<4) - return string("insufficient arguments:\n" + helpPulse(narg, args, action)); - int ival1=1,ival2=-2,ival3=-1; + int ival1=-1; if (!sscanf(args[1],"%d",&ival1)) return string("Could not scan 1st argument ")+string(args[1]); - if (!sscanf(args[2],"%d",&ival2)) - return string("Could not scan 2nd argument ")+string(args[2]); - if (!sscanf(args[3],"%d",&ival3)) - return string("Could not scan 3rd argument ")+string(args[3]); - if (string(args[0])==string("pulse")){ - if(myDet->pulsePixel(ival1,ival2,ival3) == OK) - return string("Pulse pixel successful"); - else - return string("Pulse pixel failed"); + if (string(args[0])==string("pulsechip")) + retval = myDet->pulseChip(ival1); + + + else{ + //next commands requires 3 addnl. arguments + int ival2=-1,ival3=-1; + if(narg<4) + return string("insufficient arguments:\n" + helpPulse(narg, args, action)); + if (!sscanf(args[2],"%d",&ival2)) + return string("Could not scan 2nd argument ")+string(args[2]); + if (!sscanf(args[3],"%d",&ival3)) + return string("Could not scan 3rd argument ")+string(args[3]); + + + if (string(args[0])==string("pulse")) + retval = myDet->pulsePixel(ival1,ival2,ival3); + + else if (string(args[0])==string("pulsenmove")) + retval = myDet->pulsePixelNMove(ival1,ival2,ival3); + + else return string("could not decode command")+cmd; + } - else if (string(args[0])==string("pulsenmove")){ - if(myDet->pulsePixelNMove(ival1,ival2,ival3) == OK) - return string("Pulse pixel and move successful"); - else - return string("Pulse pixel and move failed"); - } - - return string("could not decode command")+cmd; + return string(""); +/* + if(retval == OK) + return string(" successful"); + else + return string(" failed"); + */ } diff --git a/slsDetectorSoftware/slsDetector/slsDetectorUtils.cpp b/slsDetectorSoftware/slsDetector/slsDetectorUtils.cpp index 970f3c5f4..3b546efb1 100644 --- a/slsDetectorSoftware/slsDetector/slsDetectorUtils.cpp +++ b/slsDetectorSoftware/slsDetector/slsDetectorUtils.cpp @@ -41,7 +41,18 @@ slsDetectorUtils::slsDetectorUtils() { -void slsDetectorUtils::acquire(int delflag){ +int slsDetectorUtils::acquire(int delflag){ + + //ensure acquire isnt started multiple times by same client + pthread_mutex_lock(&mp); + if(getAcquiringFlag() == false) + setAcquiringFlag(true); + else{ + std::cout << "Error: Acquire has already been started." << std::endl; + return FAIL; + } + pthread_mutex_unlock(&mp); + bool receiver = (setReceiverOnline()==ONLINE_FLAG); if(!receiver){ @@ -526,6 +537,10 @@ void slsDetectorUtils::acquire(int delflag){ #ifdef VERBOSE cout << "acquisition finished callback done " << endl; #endif + + setAcquiringFlag(false); + return OK; + } diff --git a/slsDetectorSoftware/slsDetector/slsDetectorUtils.h b/slsDetectorSoftware/slsDetector/slsDetectorUtils.h index 4d5f15dd5..4225efa08 100644 --- a/slsDetectorSoftware/slsDetector/slsDetectorUtils.h +++ b/slsDetectorSoftware/slsDetector/slsDetectorUtils.h @@ -405,10 +405,10 @@ class slsDetectorUtils : public slsDetectorActions, public postProcessing { reads the encoder (iof required for angualr conversion)
processes the data (flat field, rate, angular conversion and merging ::processData()) \param delflag 0 leaves the data in the final data queue - \returns nothing + \returns OK or FAIL depending on if it already started */ - void acquire(int delflag=1); + int acquire(int delflag=1); // double* convertAngles(){return convertAngles(currentPosition);}; @@ -778,8 +778,24 @@ virtual int setReceiverFifoDepth(int i = -1)=0; */ virtual int pulsePixelNMove(int n=0,int x=0,int y=0)=0; + /** + Pulse Chip + \param n is number of times to pulse + \returns OK or FAIL + */ + virtual int pulseChip(int n=0)=0; + /** + Set acquiring flag in shared memory + \param b acquiring flag + */ + virtual void setAcquiringFlag(bool b=false)=0; + /** + Get acquiring flag from shared memory + \returns acquiring flag + */ + virtual bool getAcquiringFlag() = 0; diff --git a/slsDetectorSoftware/slsDetectorServer/slsDetectorFunctionList.h b/slsDetectorSoftware/slsDetectorServer/slsDetectorFunctionList.h index 85e25581f..b352a293c 100644 --- a/slsDetectorSoftware/slsDetectorServer/slsDetectorFunctionList.h +++ b/slsDetectorSoftware/slsDetectorServer/slsDetectorFunctionList.h @@ -50,6 +50,7 @@ int enableTenGigabitEthernet(int val); int setCounterBit(int val); int pulsePixel(int n, int x, int y); int pulsePixelNMove(int n, int x, int y); +int pulseChip(int n); #endif #if defined(MYTHEND) || defined(GOTTHARDD) diff --git a/slsDetectorSoftware/slsDetectorServer/slsDetectorServer_funcs.c b/slsDetectorSoftware/slsDetectorServer/slsDetectorServer_funcs.c index 8f10944e4..e2c5dd2b5 100755 --- a/slsDetectorSoftware/slsDetectorServer/slsDetectorServer_funcs.c +++ b/slsDetectorSoftware/slsDetectorServer/slsDetectorServer_funcs.c @@ -178,7 +178,7 @@ int function_table() { flist[F_SET_COUNTER_BIT]=&set_counter_bit; flist[F_PULSE_PIXEL]=&pulse_pixel; flist[F_PULSE_PIXEL_AND_MOVE]=&pulse_pixel_and_move; - + flist[F_PULSE_CHIP]=&pulse_chip; #ifdef VERBOSE @@ -3766,3 +3766,52 @@ int pulse_pixel_and_move(int file_des) { } + + + +int pulse_chip(int file_des) { + + int ret=OK,ret1=OK; + int n; + int arg = -1; + + + sprintf(mess,"pulse chip failed\n"); + + n = receiveData(file_des,arg,sizeof(arg),INT32); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } +#ifndef EIGERD + ret = FAIL; + strcpy(mess,"Not applicable/implemented for this detector\n"); +#else +#ifdef SLS_DETECTOR_FUNCTION_LIST + if (ret==OK) { + if (differentClients==1 && lockStatus==1) { + ret=FAIL; + sprintf(mess,"Detector locked by %s\n",lastClientIP); + } else + ret=pulseChip(arg); + } +#endif +#endif + if(ret==OK){ + if (differentClients) + ret=FORCE_UPDATE; + } + + /* send answer */ + /* send OK/failed */ + //ret could be swapped during sendData + ret1 = ret; + n = sendData(file_des,&ret1,sizeof(ret),INT32); + if (ret==FAIL) + n += sendData(file_des,mess,sizeof(mess),OTHER); + + /*return ok/fail*/ + return ret; + +} + diff --git a/slsDetectorSoftware/slsDetectorServer/slsDetectorServer_funcs.h b/slsDetectorSoftware/slsDetectorServer/slsDetectorServer_funcs.h index 3cf4122d0..c45da8b56 100755 --- a/slsDetectorSoftware/slsDetectorServer/slsDetectorServer_funcs.h +++ b/slsDetectorSoftware/slsDetectorServer/slsDetectorServer_funcs.h @@ -86,5 +86,7 @@ int set_all_trimbits(int); int set_counter_bit(int); int pulse_pixel(int); int pulse_pixel_and_move(int); +int pulse_chip(int); + #endif diff --git a/slsDetectorSoftware/slsReceiverInterface/receiverInterface.cpp b/slsDetectorSoftware/slsReceiverInterface/receiverInterface.cpp index 11f17fceb..e5a5011a0 100644 --- a/slsDetectorSoftware/slsReceiverInterface/receiverInterface.cpp +++ b/slsDetectorSoftware/slsReceiverInterface/receiverInterface.cpp @@ -33,7 +33,6 @@ int receiverInterface::sendString(int fnum, char retval[], char arg[]){ std::cout<< "Receiver returned error: " << mess << std::endl; } dataSocket->ReceiveDataOnly(retval,MAX_STR_LENGTH); - dataSocket->Disconnect(); return ret; } @@ -54,7 +53,6 @@ int receiverInterface::sendUDPDetails(int fnum, char retval[], char arg[3][MAX_S } else dataSocket->ReceiveDataOnly(retval,MAX_STR_LENGTH); - dataSocket->Disconnect(); return ret; } @@ -72,7 +70,6 @@ int receiverInterface::sendInt(int fnum, int &retval, int arg){ std::cout<< "Receiver returned error: " << mess << std::endl; } dataSocket->ReceiveDataOnly(&retval,sizeof(retval)); - dataSocket->Disconnect(); return ret; } @@ -90,7 +87,6 @@ int receiverInterface::getInt(int fnum, int &retval){ std::cout<< "Receiver returned error: " << mess << std::endl; } dataSocket->ReceiveDataOnly(&retval,sizeof(retval)); - dataSocket->Disconnect(); return ret; } @@ -109,7 +105,6 @@ int receiverInterface::sendInt(int fnum, int64_t &retval, int64_t arg){ std::cout<< "Receiver returned error: " << mess << std::endl; } dataSocket->ReceiveDataOnly(&retval,sizeof(retval)); - dataSocket->Disconnect(); return ret; } @@ -128,7 +123,6 @@ int receiverInterface::sendIntArray(int fnum, int64_t &retval, int64_t arg[2]){ std::cout<< "Receiver returned error: " << mess << std::endl; } dataSocket->ReceiveDataOnly(&retval,sizeof(retval)); - dataSocket->Disconnect(); return ret; } @@ -141,7 +135,6 @@ int receiverInterface::getInt(int fnum, int64_t &retval){ dataSocket->SendDataOnly(&fnum,sizeof(fnum)); dataSocket->ReceiveDataOnly(&ret,sizeof(ret)); dataSocket->ReceiveDataOnly(&retval,sizeof(retval)); - dataSocket->Disconnect(); return ret; } @@ -153,7 +146,6 @@ int receiverInterface::getLastClientIP(int fnum, char retval[]){ dataSocket->SendDataOnly(&fnum,sizeof(fnum)); dataSocket->ReceiveDataOnly(&ret,sizeof(ret)); dataSocket->ReceiveDataOnly(retval,sizeof(retval)); - dataSocket->Disconnect(); return ret; } @@ -169,7 +161,6 @@ int receiverInterface::executeFunction(int fnum,char mess[]){ dataSocket->ReceiveDataOnly(mess,MAX_STR_LENGTH); std::cout<< "Receiver returned error: " << mess << std::endl; } - dataSocket->Disconnect(); return ret; }