def get_selected_antennas(list_of_selected_antennas): """Given a list of antenna codenames, it returns a Stations object containing all given antennas. """ selected_antennas = stations.Stations('Observation', []) for ant in list_of_selected_antennas: selected_antennas.add(all_stations[ant]) return selected_antennas
def get_networks_from_file(filename='data/station_location.txt'): """Retrieves all the stations given in the filename and creates different arrays. Returns a dict with all arrays. The file must contain the information for each antenna on each row, with the following header (written at the beginning of the file): - station : full name of the station - code : code name of the station - network : name of the network the station belongs to. - x : x coordinates of the station, in meters. - y : y coordinates of the station, in meters. - z : z coordinates of the station, in meters. - SEFD-XX : SEFD of the station at XX cm (-1 if this band cannot be observed) """ datafile = ascii.read(filename) # Creates a `Stations` object for each network, for now with no stations network_labels = set(datafile['network']) networks = {} for network in network_labels: networks[network] = stations.Stations(network, []) sefd_names = datafile.colnames[6:] for a_line in datafile: # Create each station and add it to the correct noetwork sefds = {} for sefd_name in sefd_names: if a_line[sefd_name] > 0.0: sefds[f"{sefd_name.replace('SEFD-','').strip()}cm"] = a_line[sefd_name] a_loc = coord.EarthLocation(a_line['x']*u.m, a_line['y']*u.m, a_line['z']*u.m) # For now this is hard-coded if a_line['station'] is 'Arecibo': min_elev = 80*u.deg else: min_elev = 10*u.deg new_station = stations.SelectedStation(a_line['station'], a_line['code'], location=a_loc, freqs_sefds=sefds, min_elevation=min_elev, selected=False) networks[a_line['network']].add(new_station) return networks
def get_stations_from_configfile(filename='data/stations_catalog.inp'): """Retrieves the information concerning all stations available in the 'filename' file. Creates a Stations object containing the stations and the information on it. The file must have a format readable by the Python ConfigParser. Each section will be named with the name of the station, and then it must have the following keys: station - full name of the station. code - codename for the station (typically two letters). network - main network to which it belongs to. possible_networks - all networks the station can participate in (including 'network') country - country where the station is located. diameter - string with the diameter of the station. position = x, y, z (in meters). Geoposition of the station. min_elevation (in degrees) - minimum elevation the station can observe. SEFD_** - SEFD of the station at the **cm band. If a given band is not present, it is assumed that the station cannot observe it. [optional] img - a path to an image of the station. link - a url linking to the station page/related information. """ config = configparser.ConfigParser() config.read(filename) networks = stations.Stations('network', []) for stationname in config.sections(): temp = [float(i.strip()) for i in config[stationname]['position'].split(',')] a_loc = coord.EarthLocation(temp[0]*u.m, temp[1]*u.m, temp[2]*u.m) # Getting the SEFD values for the bands min_elev = float(config[stationname]['min_elevation'])*u.deg sefds = {} for akey in config[stationname].keys(): if 'SEFD_' in akey.upper(): sefds[f"{akey.upper().replace('SEFD_', '').strip()}cm"] = \ float(config[stationname][akey]) new_station = stations.SelectedStation(stationname, config[stationname]['code'], config[stationname]['network'], a_loc, sefds, min_elev, config[stationname]['station'], config[stationname]['possible_networks'], config[stationname]['country'], config[stationname]['diameter']) networks.add(new_station) return networks
def stations_with_band(networks, band, output_network_name=None): """For a given collection of networks or Stations, returns a Stations object including all stations that can observe at the given band. - networks : dict [name_network]: Stations or Stations - band : str """ if output_network_name is None: output_network_name = f"Stations@{band}" antennas = stations.Stations(output_network_name, []) if isinstance(networks, dict): for network in networks: for station in networks[network]: if band in station.bands: antennas.add(station) elif isinstance(networks, stations.Stations): for station in networks: if band in station.bands: antennas.add(station) else: raise ValueError(f"{networks} expected to be either dict of Stations type.") return antennas
def compute_observation(n_clicks, band, starttime, starthour, endtime, endhour, source, onsourcetime, datarate, subbands, channels, pols, inttime, *ants): """Computes all products to be shown concerning the set observation. """ if n_clicks is None: return '', dash.no_update, dash.no_update, dash.no_update, \ dash.no_update, dash.no_update try: target_source = observation.Source(convert_colon_coord(source), 'Source') except ValueError as e: return alert_message(["Incorrect format for source coordinates.", html.Br(), f"{'Empty value' if source=='' else source} found but 'hh:mm:ss dd:mm:ss' expected."]),\ "First, set correctly an observation in the previous tab.", \ dash.no_update, dash.no_update, dash.no_update, dash.no_update try: time0 = Time(dt.strptime(f"{starttime} {starthour}", '%Y-%m-%d %H:%M'), format='datetime', scale='utc') except ValueError as e: return alert_message("Incorrect format for starttime."), \ "First, set correctly an observation in the previous tab.", \ dash.no_update, dash.no_update, dash.no_update, dash.no_update try: time1 = Time(dt.strptime(f"{endtime} {endhour}", '%Y-%m-%d %H:%M'), format='datetime', scale='utc') except ValueError as e: return alert_message("Incorrect format for endtime."), \ "First, set correctly an observation in the previous tab.", \ dash.no_update, dash.no_update, dash.no_update, dash.no_update if time0 >= time1: return alert_message("The start time must be earlier than the end time"), \ "First, set correctly an observation in the previous tab.", \ dash.no_update, dash.no_update, dash.no_update, dash.no_update if (time1 - time0) > 5*u.d: return alert_message("Please, set an observation that last for less than 5 days."), \ "First, set correctly an observation in the previous tab.", \ dash.no_update, dash.no_update, dash.no_update, dash.no_update # try: # TODO: this should not be hardcoded... obs_times = time0 + np.linspace(0, (time1-time0).to(u.min).value, 50)*u.min # all_selected_antennas = list(itertools.chain.from_iterable(ants)) try: obs = observation.Observation(target=target_source, times=obs_times, band=band, datarate=datarate, subbands=subbands, channels=channels, polarizations=pols, inttime=inttime, ontarget=onsourcetime/100.0, stations=stations.Stations('Observation', itertools.compress(all_antennas, ants))) # stations=get_selected_antennas(all_selected_antennas)) sensitivity_results = update_sensitivity(obs) except observation.SourceNotVisible: return alert_message([ html.P(["Your source cannot be observed within the arranged observation.", html.Br(), "There are no antennas that can simultaneously observe your source " "during the given observing time."]), html.P("Modify the observing time or change the selected antennas" " to observe this source.")], title="Warning!"), \ dash.no_update, dash.no_update, dash.no_update, dash.no_update, dash.no_update # return update_sensitivity(obs), dash.no_update, dash.no_update # TODO: parallelize all these functions return [html.Br(), dbc.Alert("You can check now the results in the different tabs", color='info', \ dismissable=True)], sensitivity_results, \ get_fig_ant_elev(obs), get_fig_ant_up(obs), get_fig_uvplane(obs), dash.no_update