def process_spectrometer_command(self): self.data = self.recv(1024) if not self.data: return False else: msg = self.data.strip().split() if not msg[0] in allowed_commands: #print "Request has to be one of 'open', 'config', 'start', 'stop', 'close'" logger.error("Request has to be one of %s" % allowed_commands) return False if msg[0] == 'open': self.open(msg[1], msg[2], msg[3], msg[4], msg[5]) elif msg[0] == 'config': self.config(msg[1], msg[2]) elif msg[0] == 'start': self.start() elif msg[0] == 'stop': self.stop() elif msg[0] == 'close': self.spec_close() elif msg[0] == 'snapshot': self.spec_snapshot() elif msg[0] == 'snapsend': snaps = self.spec_snapsend() #print self.data logger.info("Received Data: %s" % self.data) if msg[0] == 'snapsend': self.send("%s DONE; %.2f %.2f %.2f %.2f\n" % (self.data.strip(), snaps[0], snaps[1], snaps[2], snaps[3])) else: self.send("%s DONE\n" % self.data.strip()) return True
def program_device(self): bitcode = self.mode.bitcode self.roach.progdev(bitcode) #print 'Programming bitcode %s' %(bitcode) logger.info('Programming bitcode %s' % (bitcode))
def integrate(self, inputs): #logging.debug('Starting ') #print "Starting" logger.info("Integration Starting") #throw away the current sample to guarantee timing acc_n = self.spec.get_acc_n() while True: acc_nn = self.spec.get_acc_n() if acc_nn != acc_n: break time.sleep(0.0001) acc_n = acc_nn #now collect data while self.integration_active: for inp in inputs: self.spec.integrate(inp, write_nc=False) while True: acc_nn = self.spec.get_acc_n() if acc_nn != acc_n: break time.sleep(0.0001) acc_n = acc_nn #print "Integration halted" logger.info("Integrration halted") self.spec.queue.put(None) # to mark end of data
def reset(self): #print 'Resetting counters...', logger.info('Resetting counters...') self.roach.write_int('cnt_rst', 1) self.roach.write_int('cnt_rst', 0) #print 'done' logger.info('done')
def calADC(self): #print '------------------------' logger.info('------------------------') #print 'Loading default OGP/INL corrections to ADCs' logger.info('Loading default OGP/INL corrections to ADCs') self.adc_cal_tools.update_ogp(fname=self.default_ogp_file) self.adc_cal_tools.update_inl(fname=self.default_inl_file)
def __init__(self, roach_id='172.30.51.101', katcp_port=7147, mode=800, scale=1024, default_ogp_file='ogp_data/ogp_chans01.npz', default_inl_file='ogp_data/inl_chans01.npz', gain=None, basefile='spectrometer'): self.default_ogp_file = default_ogp_file self.default_inl_file = default_inl_file self.roach_id = roach_id self.katcp_port = katcp_port self.roach = katcp_wrapper.FpgaClient(roach_id) self.roach.wait_connected() #self.roach = roach self.sync_scale = scale self.sync_period = None self.sync_time = None self.acc_len = None self.inputs = {} # a dictionary of spectral classes self.spec_dumps = [] # a list of all spectrometer dumps self.gain = gain # if (mode==800): # if gain is not None: # self.mode = mode_800(gain=gain) # else: # self.mode = mode_800() # if (mode==400): # if gain is not None: # self.mode = mode_400(gain=gain) # else: # self.mode = mode_400() # if (mode==200): # if gain is not None: # self.mode = mode_200(gain=gain) # else: # self.mode = mode_200() #self.adc_cal_tools = ADC5g_Load(self.roach, program=False) # self.set_sync_period() # self.set_acc_len() # self.program_device() # self.configure() #self.calADC() self.mode_setup(mode=mode) self.nc = None self.basefile = basefile logger.info("Spectrometer class inititated with roach_id: %s" % self.roach_id)
def start(self): self.integration_active = True # needs to be a threaded integrate below self.integrate_thread = threading.Thread(name="integrate daemon", target=self.integrate, args=([0, 1, 2, 3], )) self.integrate_thread.setDaemon(True) self.integrate_thread.start() self.consumer_thread = ConsumerWriterThread(args=(self.spec, )) self.consumer_thread.start() #print "Started integrate thread and consumer writer thread" logger.info("Started integrate thread and consumer writer thread")
def printlog(self, *arguments): # if len(arguments) == 1: # type=syslog.LOG_INFO # msg = arguments[0] # else: # type=arguments[0] # msg=arguments[1] # if self.log == LOG_STDOUT: # print msgtype[type], msg # else: # syslog.syslog(type, msg) #print arguments logger.info(arguments)
def snapshot_file_all(self, roach_num=0, obsnum=None): basedir = os.path.join("/data_lmt/spectrometer/snapshots", "roach%d" % roach_num) basefile = "roach%d_%d" % (roach_num, obsnum) for inp in range(4): filename = "%s_inp%d_%s.txt" % ( basefile, inp, datetime.datetime.now().strftime('%Y-%m-%d_%H%M%S')) fullpath = os.path.join(basedir, filename) self.snap_file(inp, fullpath) logger.info("Wrote snapshot file %s" % fullpath) time.sleep(0.010) logger.info("Done with Snapshots")
def integrate(self, inp, write_nc=True, queue_enable=True): t1 = time.time() acc_n = self.get_acc_n() # test code here # while len(self.spec_dumps) > 0 and acc_n - self.spec_dumps[-1].acc_n == 0: # time.sleep(0.001) # acc_n = self.get_acc_n() # test code finish sync_n = self.get_sync_cnt() interleave = np.empty((self.mode.numchannels, ), dtype=float) for bramNo in range(self.mode.nbram): interleave[bramNo::self.mode.nbram] = self.read_bram(inp, bramNo) write_time = time.time() read_time = write_time - t1 #print 'Done with integration' #print 'acc_n = %i, sync_n = %i' %(acc_n, sync_n) logger.info('Done with integration') logger.info('acc_n = %i, sync_n = %i' % (acc_n, sync_n)) #if plt: # plot(10.*np.log10(interleave[10:])) # xlabel('FFT Channel') # ylabel('dB') self.inputs[inp] = SpectrometerIntegration(inp, self.mode.numchannels, acc_n, sync_n, read_time, write_time, interleave) if not queue_enable: self.spec_dumps.append(self.inputs[inp]) if queue_enable and self.queue: self.queue.put(self.inputs[inp]) self.numscans += 1 if write_nc: if self.nc is None: self.open_nc_file() #filename ="%s_%s.nc" % (self.basefile, datetime.datetime.now().strftime('%Y-%m-%d_%H%M%S')) #self.nc = WaresNetCDFFile(filename, 'w') #self.nc.setup_scan(self, inp) self.nc.save_scan(self, inp) #nc.close_scan() return acc_n, sync_n, interleave, read_time
def config(self, mode=800, dump_time=0.05): #get usb port for the right valon valonSN = ['A502NJ6F', 'A5Z7ZF81', 'A5Z7ZC6N', 'A51G8YDP'] device = None com = serial.tools.list_ports.comports() for c in com: if c.vid == 0x0403 and c.pid == 0x6001 and valonSN[ self.roach_id] == c.serial_number: device = c.device break logger.info('valonSN[%d] = %s, device = %s' % (self.roach_id, valonSN[self.roach_id], device)) if device == None: return valon = ValonSynthesizer(device) #valon = ValonSynthesizer('/dev/ttyUSB%d' % self.roach_id) #print "Current Frequency: %s MHz" % valon.get_frequency(SYNTH_A) logger.info("Current Frequency: %s MHz" % valon.get_frequency(SYNTH_A)) valon.set_frequency(SYNTH_A, synth_freq[mode]) #print "Setting Frequency to: %s MHz" % valon.get_frequency(SYNTH_A) logger.info("Setting Frequency to: %s MHz" % valon.get_frequency(SYNTH_A)) mode_fn = getattr(spec_modes, 'mode_%d' % mode) mode_obj = mode_fn() if dump_time < 0.040: logger.info( "Dump time %s specified. Cannot be smaller than 0.04 seconds. Resetting to 0.04 seconds" % dump_time) dump_time = 0.04 scale = self.calc_scale(dump_time, mode_obj) self.spec.sync_scale = scale self.spec.mode_setup(mode=mode)
def integrate_par(self, inp, write_nc=True): t1 = time.time() acc_n = self.get_acc_n() sync_n = self.get_sync_cnt() self.interleave = np.empty((self.mode.numchannels, ), dtype=float) ncpu = multiprocessing.cpu_count() #self.pstop = ProcessStopper() self.process = {} for bramNo in range(self.mode.nbram): self.process[bramNo] = multiprocessing.Process( target=self.read_bram_par, args=(inp, bramNo)) self.process[bramNo].start() #self.pstop.add_process(process) time.sleep(0.001) #interleave[bramNo::self.mode.nbram] = self.read_bram(inp, bramNo) read_time = time.time() - t1 #print 'Done with integration' #print 'acc_n = %i, sync_n = %i' %(acc_n, sync_n) logger.info('Done with integration') logger.info('acc_n = %i, sync_n = %i' % (acc_n, sync_n)) #if plt: # plot(10.*np.log10(self.interleave[10:])) # xlabel('FFT Channel') # ylabel('dB') self.inputs[inp] = SpectrometerIntegration(inp, self.mode.numchannels, acc_n, sync_n, read_time, self.interleave) if write_nc: if self.nc is None: self.open_nc_file() self.nc.save_scan(self, inp) #nc.close_scan() # while self.pstop.keep_running: # try: # time.sleep(1) # except KeyboardInterrupt: # self.pstop.terminate() # break return acc_n, sync_n, self.interleave, read_time
def open_nc_file(self, roach_num=0, obs_num=None, subobs_num=None, scan_num=None, source_name=None, obspgm=None): basedir = os.path.join("/data_lmt/spectrometer", "roach%d" % roach_num) self.ObsNum, self.SubObsNum, self.ScanNum, self.source_name, self.obspgm = obs_num, subobs_num, scan_num, source_name, obspgm self.roach_num = roach_num # roach_num is integer; roach_id is IP address if self.ObsNum is not None and self.SubObsNum is not None and self.ScanNum is not None and self.source_name is not None: self.basefile = "roach%d_%d_%d_%d_%s" % ( self.roach_num, self.ObsNum, self.SubObsNum, self.ScanNum, self.source_name) filename = "%s_%s.nc" % ( self.basefile, datetime.datetime.now().strftime('%Y-%m-%d_%H%M%S')) fullpath = os.path.join(basedir, filename) #print "Opening filename: %s" % fullpath logger.info("Opening filename: %s" % fullpath) self.nc = WaresNetCDFFile(fullpath, 'w') self.nc.setup_scan(self)
def configure(self): #print 'Configuring accumulation period to %d...' %self.acc_len, logger.info('Configuring accumulation period to %d...' % self.acc_len) self.roach.write_int('acc_len', self.acc_len) #print 'done' logger.info('done') #print 'Setting digital gain of all channels to %i...' %self.mode.gain, logger.info('Setting digital gain of all channels to %i...' % self.mode.gain) self.roach.write_int('gain', self.mode.gain) #print 'done' logger.info('done') #print 'Setting fft shift schedule to %i...' %self.mode.shift, logger.info('Setting fft shift schedule to %i...' % self.mode.shift) self.roach.write_int('fftshift', self.mode.shift) #print 'done' logger.info('done') #print 'Setting sync period to %i...' %self.sync_period, logger.info('Setting sync period to %i...' % self.sync_period) self.roach.write_int('sync_constant', self.sync_period) #print 'done' logger.info('done') self.reset() time.sleep(0.1)
def process_ifproc_map(self, remove_offset=False, numoff=20, scigrid=False, **kwargs): """ processes Map Obspgm that has been made in IFProc continuum mode. Uses a regridding algorithm and uses some kwargs arguments to derive output grid size and sampling """ if self.telnc.hdu.header.ObsPgm not in ('Map', 'Lissajous'): logger.error("Not a Map datafile") return else: maptype = self.telnc.hdu.header.ObsPgm logger.info("Processing MSIP 1mm Continuum Map data and regridding for Observation with ObsNum %d" % int(self.telnc.hdu.header.ObsNum)) self.numpixels = self.telnc.hdu.data.BasebandLevel.shape[1] xlength = numpy.degrees(self.telnc.hdu.header.get('%s.XLength' % maptype))*3600.0 ylength = numpy.degrees(self.telnc.hdu.header.get('%s.YLength' % maptype))*3600.0 if maptype == 'Lissajous': xlength = xlength/numpy.cos(numpy.radians(45)) xlength = ylength/numpy.cos(numpy.radians(45)) ind = numpy.where(self.telnc.hdu.data.BufPos == 0) xpos = numpy.degrees(self.telnc.hdu.data.TelAzMap[ind])*3600. ypos = numpy.degrees(self.telnc.hdu.data.TelElMap[ind])*3600. rows = self.telnc.hdu.header.get('Map.RowsPerScan') z = {} self.off_source = {} for chan in range(self.numpixels): z[chan] = self.telnc.hdu.data.BasebandLevel[ind, chan].flatten() self.off_source[chan] = numpy.histogram(self.telnc.hdu.data.BasebandLevel[ind, chan].flatten())[1][:4].mean() if remove_offset: z[chan] = z[chan] - self.off_source[chan] print z[chan].shape ramp = kwargs.get('ramp', 5.) numpoints = kwargs.get('numpoints', 100) numypoints = kwargs.get('numypoints', 100) xlength = xlength * (1.-ramp/100.) ylength = ylength * (1.-ramp/100.) ind = numpy.logical_and(xpos > -xlength/2., xpos < xlength/2.) xpos, ypos = xpos[ind], ypos[ind] # add a tiny random number to stop griddata from crashing when two pixels are same xpos = xpos + numpy.random.random(xpos.size)*1e-6 ypos = ypos + numpy.random.random(ypos.size)*1e-6 for chan in range(self.numpixels): z[chan] = z[chan][ind] ind = numpy.logical_and(ypos > -ylength/2., ypos < ylength/2.) xpos, ypos = xpos[ind], ypos[ind] for chan in range(self.numpixels): z[chan] = z[chan][ind] self.xi = numpy.linspace(-xlength/2, xlength/2, numpoints) self.yi = numpy.linspace(-ylength/2, ylength/2, numypoints) print "Making %d x %d map" % (numpoints, numypoints) #self.z = z #self.xpos = xpos #self.ypos = ypos self.BeamMap = numpy.zeros((self.yi.size, self.xi.size, self.numpixels)) for chan in range(self.numpixels): #self.BeamMap[chan] = numpy.zeros((self.yi.size, self.xi.size), # dtype='float') if scigrid: self.BeamMap[:, :, chan] = scipy.interpolate.griddata(xpos, ypos, z[chan], (self.xi, self.yi), method='cubic') else: self.BeamMap[:, :, chan] = griddata(xpos, ypos, z[chan], self.xi, self.yi)
def close(self): #self.spec.save_all_scans() if self.spec.nc is not None: self.spec.close_scan() else: logger.info("No NC file to close")