def do_snap_waterfall(ant_str,freq, source, fpga_file, waterfalllen, do_park = False): logger = logger_defaults.getModuleLogger(__name__) ant_list = snap_array_helpers.string_to_array(ant_str); full_ant_str = snap_array_helpers.array_to_string(ant_list) if waterfalllen < 2: logger.error('waterfall len too short') raise RuntimeError('waterfall len too short') try: ant_groups = ata_control.get_snap_dictionary(ant_list) except: logstr = "unable to match antennas with snaps" logger.exception(logstr) raise if len(ant_list) != 1: logger.error('only 1 antenna allowed') raise RuntimeError('only 1 antenna allowed') if len(ant_groups) != 1: logger.error('only 1 antenna allowed') raise RuntimeError('only 1 antenna allowed') ant_dict = {} for csnap in ant_groups: if len(ant_groups[csnap]) != 1: logger.error('only one antenna per snap allowed, got {}: {}'.format(csnap,",".join(ant_groups[csnap]))) raise RuntimeError("only 1 antenna per snap allowed") snaphost = csnap currAnt = ant_groups[csnap][0] logger.info("Reserving antennas %s in bfa antgroup" % full_ant_str) try: ata_control.reserve_antennas(ant_list) except: logstr = "unable to reserve the antennas" logger.exception(logstr) raise logger.info("starting plotting") try: ata_control.try_on_lna(currAnt) source_status = ata_positions.ATAPositions.getFirstInListThatIsUp([source]) if not source_status: errormsg = 'source {} is not up (or too close to sun/moon)... terminating observation set {}'.format(source,obs_set_id) logger.error(errormsg) raise RuntimeError(errormsg) if source_status['status'] != 'up': if source_status['status'] == 'next_up': errormsg = 'source {} is not up (or too close to sun/moon). Will be up in {} minutes. Terminating observation set {}'.format(source,source_status['minutes'],obs_set_id) else: errormsg = 'source {} is not up (or too close to sun/moon)... terminating observation set {}'.format(source,obs_set_id) logger.error(errormsg) raise RuntimeError(errormsg) logger.info("pointing the antennas") ata_control.make_and_track_ephems(source, currAnt ); logger.info("autotuning") ata_control.autotune(currAnt) ata_control.rf_switch_thread([currAnt]) logger.info("changing to frequency {}".format(freq)) ata_control.set_freq(freq, currAnt) snap_recorder.setSnapRMS(snaphost,currAnt,fpga_file,default_rms) snap_plot.plotWaterfall(snaphost, waterfalllen, freq,fpga_file) except KeyboardInterrupt: logger.info("Keyboard interuption") except Exception as e: logger.exception("something went wrong") errmsg = "Finishing recording - failed: {}".format(e) raise finally: logger.info("shutting down") ata_control.release_antennas(ant_list, do_park)
def start(self): ant_list = [] ant_pol_list = [] db_list = [] if self.ant1 != 'none': ant_list.append(self.ant1) ant1x = self.ant1 + 'x' ant1y = self.ant1 + 'y' ant_pol_list.append([ant1x, ant1y]) if (self.db1 >= 0) and (self.db1 <= 31.5): db_list.append([self.db1, self.db1]) else: raise Exception( "Error: Gain for Switch 1 must be between 0 and 31.5 dB") if self.ant2 != 'none': ant_list.append(self.ant2) ant2x = self.ant2 + 'x' ant2y = self.ant2 + 'y' ant_pol_list.append([ant2x, ant2y]) if (self.db2 >= 0) and (self.db2 <= 31.5): db_list.append([self.db2, self.db2]) else: raise Exception( "Error: Gain for Switch 2 must be between 0 and 31.5 dB") if self.ant3 != 'none': ant_list.append(self.ant3) ant3x = self.ant3 + 'x' ant3y = self.ant3 + 'y' ant_pol_list.append([ant3x, ant3y]) if (self.db3 >= 0) and (self.db3 <= 31.5): db_list.append([self.db3, self.db3]) else: raise Exception( "Error: Gain for Switch 3 must be between 0 and 31.5 dB") if not (self.ant1 or self.ant2 or self.ant3): print( "No antennas specified. Please select one or more antennas and try again." ) try_ping = subprocess.Popen(['ping', '-c', '1', 'if-switch'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT) stdout, stderr = try_ping.communicate() ping_output = stdout.decode('utf-8') ping_success = "1 packets transmitted, 1 received" if ping_success in ping_output: ac.rf_switch_thread(ant_list) print("IF Switch has been set.") ac.set_atten_thread(ant_pol_list, db_list) print("IF Switch attenuation has been set.") return super().start() print("Can't connect to if-switch machine. Try again.") return super().start()
def main(): logging.basicConfig(format='%(asctime)s %(message)s', level=logging.INFO) options = pol.argument_parser().parse_args() if gr.enable_realtime_scheduling() != gr.RT_OK: logging.warning("Error: failed to enable real-time scheduling.") tb = pol.flowgraph(directory=options.directory, gaindB=options.gaindB, samp_rate=options.samp_rate, src_name=obs_source, lo_freq = obs_freqs[0]) def sig_handler(sig=None, frame=None): tb.stop() tb.wait() park_antennas() logging.shutdown() sys.exit(0) signal.signal(signal.SIGINT, sig_handler) signal.signal(signal.SIGTERM, sig_handler) logging.info('Setting up feeds and IF switch') if do_observation: ac.try_on_lnas(antennas) ac.set_freq(obs_freqs[0], antennas, lo) ac.rf_switch_thread(antennas) ac.set_atten_thread([[f'{ant}x',f'{ant}y'] for ant in antennas], [[if_switch_att,if_switch_att] for _ in antennas]) else: time.sleep(1) logging.info('Feeds and IF set') logging.info(f'Slewing to source {obs_source}') if do_observation: ac.make_and_track_source(obs_source, antennas) else: time.sleep(1) logging.info(f'On source {obs_source}') logging.info('Running autotune') if do_observation: ac.autotune(antennas) logging.info(f'Detectors: {ac.get_dets(antennas)}') logging.info(f'PAMs: {ac.get_pams(antennas)}') else: time.sleep(1) logging.info('Autotune done') first_period = True while True: for freq in obs_freqs: if not first_period: logging.info(f'Setting LO {lo} to {freq} MHz') if do_observation: ac.set_freq(freq, antennas, lo) else: time.sleep(1) logging.info('LO set') else: logging.info(f'Starting first observation at {freq} MHz') logging.info('Starting recording') if first_period: first_period = False tb.make_sinks(freq) tb.start() else: tb.reload_sinks(freq) tb.unlock() time.sleep(obs_period) tb.lock() logging.info('Stopping recording')
def doOnOffObservations(ant_str,freq_str, pointings_str,az_offset,el_offset,repetitions,ncaptures,obs_set_id,fpga_file): logger = logger_defaults.getModuleLogger(__name__) ant_list = snap_array_helpers.string_to_array(ant_str); pointings = snap_array_helpers.string_to_array(pointings_str); freq_list = snap_array_helpers.string_to_numeric_array(freq_str); ant_list = remove_dups(ant_list) full_ant_str = snap_array_helpers.array_to_string(ant_list) info_string = ("OnOff Started\nDataset ID {7}\n\nAnts: {0!s}\nFreq: {1!s}\n" "Pointings: {2!s}\nOff positions: Az={3:3.2f} El={4:3.2f}\n" "Repetitions {5:d}\nCaptures {6:d}").format(full_ant_str, freq_str, pointings_str,az_offset,el_offset,repetitions,ncaptures,obs_set_id) logger.info(info_string) logger.warning("Communication disabled, edit code") ATAComm.sendMail("SNAP Obs started",info_string) ATAComm.postSlackMsg(info_string) try: ant_groups = ata_control.get_snap_dictionary(ant_list) except: logstr = "unable to match antennas with snaps" logger.exception(logstr) ATAComm.sendMail("SNAP Obs exception",logstr) raise #getting the antennas. From now on we can modify any antenna parameters # Reserve the antennas logger.info("Reserving antennas %s in bfa antgroup" % full_ant_str) try: ata_control.reserve_antennas(ant_list) except: logstr = "unable to reserve the antennas" logger.exception(logstr) ATAComm.sendMail("SNAP Obs exception",logstr) raise # For each SNAP. set the minicircuits attenuators to 12.0 # To do this, get a list of the first antenna in each snap group try: default_atten_db = 12 # Suggested by jack antpols_list_list = [] atten_list_list = [] for a in ant_groups.keys(): antpols_list_list.append(["%sx"%ant_groups[a][0],"%sy"%ant_groups[a][0]]) atten_list_list.append([default_atten_db, default_atten_db]) ata_control.set_atten_thread(antpols_list_list,atten_list_list) except: logstr = "unable to set attenuators" logger.exception(logstr) ATAComm.sendMail("SNAP Obs exception",logstr) ata_control.release_antennas(ant_list, True) raise current_source = None new_antennas = True logger.info("starting observations") try: ata_control.try_on_lnas(ant_list) while(1): new_antennas = True #gets a antenna dictionary and curr_ant_dict,curr_freq_list = onoff_db.get_obs_params(obs_set_id,pointings,ant_groups,freq_list) #if None, it meast that all was measured if not curr_ant_dict: logger.info("all seems to be measured") break for curr_freq in curr_freq_list: current_source,was_changed = ata_positions.ATAPositions.getPreferedSourceUp(current_source,pointings) if not current_source: errormsg = 'no source is up ({}). terminating observation set {}'.format(','.join(pointings),obs_set_id) logger.error(errormsg) raise RuntimeError(errormsg) #we either changed antennas or changed source. #need to generate the ephemeris and autotune PAMs if was_changed: #if we only switched the antennas, we don't need to regenerate # the ephemeris logger.info("source changed to {}".format(current_source)) ata_control.create_ephems(current_source, az_offset, el_offset); if( was_changed or new_antennas): logger.info("need to (re)run autotune") curr_ant_list = snap_array_helpers.dict_to_list(curr_ant_dict) curr_ant_string = snap_array_helpers.array_to_string(curr_ant_list) logger.info("pointing the antennas") ata_control.point_ants("on", curr_ant_string ); logger.info("autotuning") ata_control.autotune(curr_ant_string) ata_control.rf_switch_thread(curr_ant_list) new_antennas = False logger.info("changing to frequency {}".format(curr_freq)) ata_control.set_freq(curr_freq, curr_ant_string) onoff_observations(curr_ant_dict,obs_set_id,curr_freq,fpga_file,current_source,repetitions,ncaptures,az_offset,el_offset) #snap_control.do_onoff_obs(args.hosts, \ # "/home/sonata/dev/ata_snap/snap_adc5g_spec/outputs/snap_adc5g_spec_2018-06-23_1048.fpg", \ # source, args.ncaptures, args.repetitions, ants_to_observe, freq, obsid, 0.0, 10.0) #now, we believe we have measured all frequencies for curr_ant_dict, so we may #remove the content of it from our original ant_groups. Note that this function #alters the ant_groups! onoff_db.remove_antennas_from_dict(ant_groups,curr_ant_dict); ATAComm.sendMail("SNAP Obs End","Finishing measurements - success") ATAComm.postSlackMsg("Finishing measurements - success") except KeyboardInterrupt: logger.info("Keyboard interuption") ATAComm.sendMail("SNAP Obs End","Finishing measurements - keyboard interrupt, obsid {}".format(obs_set_id)) ATAComm.postSlackMsg("Finishing measurements - keyboard interrupt") except Exception as e: logger.exception("something went wrong") errmsg = "Finishing measurements - failed, obsid {}: {}".format(obs_set_id,e) ATAComm.sendMail("SNAP Obs End",errmsg) ATAComm.postSlackMsg(errmsg) raise finally: logger.info("shutting down") ata_control.release_antennas(ant_list, True)
def do_snap_rec(ant_str, freq, source, ncaptures, obs_set_id, fpga_file, obsuser, obstype, obsdesc, do_park=False): logger = logger_defaults.getModuleLogger(__name__) ant_list = snap_array_helpers.string_to_array(ant_str) full_ant_str = snap_array_helpers.array_to_string(ant_list) try: ant_groups = ata_control.get_snap_dictionary(ant_list) except: logstr = "unable to match antennas with snaps" logger.exception(logstr) raise ant_dict = {} for csnap in ant_groups: if len(ant_groups[csnap]) != 1: logger.error( 'only one antenna per snap allowed, got {}: {}'.format( csnap, ",".join(ant_groups[csnap]))) raise RuntimeError("only 1 antenna per snap allowed") ant_dict[csnap] = ant_groups[csnap][0] if obs_set_id: info_string = ( "Starting observation:\nDataset ID {4:d}\n\nAnts: {0!s}\nFreq: {1:0.2f}\n" "Source: {2:s}\nCaptures {3:d}\n" "Type: {5:s} by {6:s} [{7:s}]").format(full_ant_str, freq, source, ncaptures, obs_set_id, obstype, obsuser, obsdesc) else: info_string = ( "Starting observation:\nNO Dataset ID!\n\nAnts: {0!s}\nFreq: {1:0.2f}\n" "Source: {2:s}\nCaptures {3:d}\n" "Type: {5:s} by {6:s} [{7:s}]").format(full_ant_str, freq, source, ncaptures, obs_set_id, obstype, obsuser, obsdesc) logger.info(info_string) ATAComm.sendMail("SNAP Obs started", info_string) ATAComm.postSlackMsg(info_string) logger.info("Reserving antennas %s in bfa antgroup" % full_ant_str) try: ata_control.reserve_antennas(ant_list) except: logstr = "unable to reserve the antennas" logger.exception(logstr) ATAComm.sendMail("SNAP Obs exception", logstr) raise logger.info("starting observations") try: ata_control.try_on_lnas(ant_list) source_status = ata_positions.ATAPositions.getFirstInListThatIsUp( [source]) if not source_status: errormsg = 'source {} is not up (or too close to sun/moon)... terminating observation set {}'.format( source, obs_set_id) logger.error(errormsg) raise RuntimeError(errormsg) if source_status['status'] != 'up': if source_status['status'] == 'next_up': errormsg = 'source {} is not up (or too close to sun/moon). Will be up in {} minutes. Terminating observation set {}'.format( source, source_status['minutes'], obs_set_id) else: errormsg = 'source {} is not up (or too close to sun/moon)... terminating observation set {}'.format( source, obs_set_id) logger.error(errormsg) raise RuntimeError(errormsg) logger.info("pointing the antennas") ata_control.make_and_track_ephems(source, full_ant_str) logger.info("autotuning") ata_control.autotune(full_ant_str) ata_control.rf_switch_thread(ant_list) logger.info("changing to frequency {}".format(freq)) ata_control.set_freq(freq, full_ant_str) single_snap_recording(ant_dict, obs_set_id, obstype, obsuser, obsdesc, freq, fpga_file, source, ncaptures) ATAComm.sendMail("SNAP recording ended", "Finishing measurements - success") ATAComm.postSlackMsg("Finishing recording - success") except KeyboardInterrupt: logger.info("Keyboard interuption") ATAComm.sendMail( "SNAP recording ended", "Finishing measurements - keyboard interrupt, obsid {}".format( obs_set_id)) ATAComm.postSlackMsg("Finishing recording - keyboard interrupt") except Exception as e: logger.exception("something went wrong") errmsg = "Finishing recording - failed, obsid {}: {}".format( obs_set_id, e) ATAComm.sendMail("SNAP recording ended", errmsg) ATAComm.postSlackMsg(errmsg) raise finally: logger.info("shutting down") ata_control.release_antennas(ant_list, do_park)