def DCM_master_attn_cal(roach_list,ant_list='ant1-15'): ''' Perform a sequence of FEM settings, using ADC levels to deduce optimum DCM attenuation settings for all 34 bands and return the master table DCM attenuation lines. TAKES ABOUT 5 MINUTES TO COMPLETE roach_list a set of ROACH objects created with roach.py ant_list a list of antennas in the form of a string, e.g. "ant1-5 ant7" on which to adjust FEMs Default is all antennas, and an empty string means all antennas in current subarray. Returns DCM_lines list of strings, one for each band ''' accini = stf.rd_ACCfile() acc = {'host': accini['host'], 'scdport':accini['scdport']} n = len(roach_list) adc_ndon = np.zeros((34,n,4),dtype='float') # Set DCM state to standard values send_cmds(['DCMAUTO-OFF '+ant_list,'DCMATTN 12 12 '+ant_list],acc) # Set FEM attenuations to nominal send_cmds(['FEMATTN 0 '+ant_list],acc) # Cycle through bands to get "nd-on" ADC levels send_cmds(['ND-ON '+ant_list],acc) for band in range(34): acc_tune(band+1,acc) time.sleep(3) r.adc_levels(roach_list) for i,ro in enumerate(roach_list): adc_ndon[band,i] = ro.adc_levels send_cmds(['ND-OFF '+ant_list],acc) DCM_lines = make_DCM_table(roach_list,adc_ndon,dcm_base=12,adc_nom=30) return DCM_lines
def set_dcm_attn(roach_list,fem_level=5,nd_state='on',adc_nom=25,ant_list='ant1-13',do_plot=False): ''' Set the FEM attenuation to the given value, switch ND state to the given state and cycle through the IF bands, and find the optimum DCM attenuation needed to attain the given ADC level. Returns the corresponding DCM table ''' import copy accini = stf.rd_ACCfile() acc = {'host': accini['host'], 'scdport':accini['scdport']} # Switch noise diode to requested state if nd_state == 'on': send_cmds(['ND-ON '+ant_list],acc) else: send_cmds(['ND-OFF '+ant_list],acc) # Set FEM power level to requested level if set_fem_attn(fem_level,ant_list) == 'Failure': return time.sleep(5) dcm_table = np.zeros((34,32), dtype='int') # Set DCM state to standard values send_cmds(['DCMAUTO-OFF '+ant_list],acc) time.sleep(1) send_cmds(['DCMATTN 12 12 '+ant_list],acc) time.sleep(1) # Cycle through bands to get ADC levels for band in range(34): # Start with nominal DCM attenuation #send_cmds(['DCMATTN 12 12 '+ant_list],acc) #time.sleep(1) print 'Band:',band+1 acc_tune(band+1,acc) time.sleep(5) errstr = chk_lo1a(accini,band) if errstr != 'No error': print errstr return None # Go through ROACH list for i,ro in enumerate(roach_list): # Get ADC levels at nominal setting dcm_base = np.array([12,12,12,12],dtype='int') r.adc_levels([ro]) # Calculate new attenuation to achieve nominal level ch_atn = np.clip(((20*np.log10(ro.adc_levels/adc_nom)+dcm_base + 1)/2).astype('int')*2,0,30) # Set new attenuation levels (twice, for good measure, and check result # send_cmds(['DCMATTN '+str(ch_atn[0])+' '+str(ch_atn[1])+' ant'+str(ro.ants[0])],acc) # time.sleep(1) # send_cmds(['DCMATTN '+str(ch_atn[0])+' '+str(ch_atn[1])+' ant'+str(ro.ants[0])],acc) # time.sleep(1) # send_cmds(['DCMATTN '+str(ch_atn[2])+' '+str(ch_atn[3])+' ant'+str(ro.ants[1])],acc) # time.sleep(1) # send_cmds(['DCMATTN '+str(ch_atn[2])+' '+str(ch_atn[3])+' ant'+str(ro.ants[1])],acc) # time.sleep(1) # r.adc_levels([ro]) # ch_atn2 = np.clip(((20*np.log10(ro.adc_levels/adc_nom)+ch_atn + 1)/2).astype('int')*2,0,30) # print ' ',ro.roach_ip[:6],'Attn:',ch_atn,'Check:',ch_atn2 print ' ',ro.roach_ip[:6],'Attn:',ch_atn dcm_table[band,np.array(((ro.ants[0]-1)*2,(ro.ants[0]-1)*2+1,(ro.ants[1]-1)*2,(ro.ants[1]-1)*2+1))] = copy.copy(ch_atn) return dcm_table
def adc_cal(roach_list,ant_list='ant1-15',do_plot=False): ''' Perform a sequence of FEM settings, using ADC levels to deduce optimum DCM attenuation settings for all 34 bands. This can also reveal problems in FEM or DCM hardware. TAKES ABOUT 17 MINUTES TO COMPLETE roach_list a set of ROACH objects created with roach.py ant_list a list of antennas in the form of a string, e.g. "ant1-5 ant7" on which to adjust FEMs Default is all antennas, and an empty string means all antennas in current subarray. do_plot if True, makes a summary plot of results Returns numpy arrays : adc_nosig[34, nroach, 4] (no-signal ADC levels) adc_ndoff[34, nroach, 4] (ADC levels for ND-OFF) adc_ndon [34, nroach, 4] (ADC levels for ND-ON) ''' accini = stf.rd_ACCfile() acc = {'host': accini['host'], 'scdport':accini['scdport']} n = len(roach_list) adc_nosig = np.zeros((34,n,4),dtype='float') adc_ndoff = np.zeros((34,n,4),dtype='float') adc_ndon = np.zeros((34,n,4),dtype='float') # Set DCM state to standard values send_cmds(['DCMAUTO-OFF '+ant_list,'DCMATTN 12 12 '+ant_list],acc) # Set FEM attenuations to maximum send_cmds(['FEMATTN 15 '+ant_list],acc) # Cycle through bands to get "zero-input" ADC levels for band in range(34): acc_tune(band+1,acc) time.sleep(3) # Go through roaches and find optimum ADC levels for i,ro in enumerate(roach_list): r.adc_levels([ro]) adc_nosig[band,i] = ro.adc_levels # Set FEM attenuations to nominal send_cmds(['FEMATTN 0 '+ant_list],acc) # Cycle through bands to get "nd-on" ADC levels send_cmds(['ND-ON '+ant_list],acc) for band in range(34): acc_tune(band+1,acc) time.sleep(3) r.adc_levels(roach_list) for i,ro in enumerate(roach_list): adc_ndon[band,i] = ro.adc_levels # Cycle through bands to get "nd-off" ADC levels send_cmds(['ND-OFF '+ant_list],acc) for band in range(34): acc_tune(band+1,acc) time.sleep(3) r.adc_levels(roach_list) for i,ro in enumerate(roach_list): adc_ndoff[band,i] = ro.adc_levels if do_plot: plot_adc_cal(roach_list, adc_nosig, adc_ndoff, adc_ndon) return adc_nosig, adc_ndoff, adc_ndon