def __init__(self, input, telescopeName, psfModel=1.0, inputType='fitscube', fluxType='intensity', saveConvCube=True, yamlfile='lvmdatasim.yaml'): """ Initialize for Simulator """ self.input = input self.inputType = inputType self.fluxType = fluxType self.telescopeName = telescopeName self.psfModel = psfModel self.saveConvCube = saveConvCube self.yamlfile = yamlfile self.data, self.hdr = self.readInput() self.telescope = Telescope(telescopeName) """ still need to define how user sets parameters of exposure and simulation" """ import lvmdatasimdefaults self.simparam = lvmdatasimdefaults.param self.convdata = None
def teleinput(): '''Page to input custom telescope and observability parameters''' form = CustomTelescopeForm() location_properties = ['longitude', 'latitude', 'elevation', 'min_altitude', 'max_altitude', 'start_date', 'end_date', 'resolution']#, 'fast_return'] if form.validate_on_submit(): # create new telescope instance custom_telescope = Telescope() flash = [] # array to keep messages to flash the user to confirm their choices for prop in Telescope.property_dict.keys(): if prop != 'name': val = getattr(form, prop).data setattr(custom_telescope, prop, val) # flash a message to the user confirming their choices if val is not None: flash.append('{} = {}'.format(prop, val)) # error checking already done by form.py custom_telescope._C_T_calculable = True # make a copy of the exoplanet array so as to not alter the master copy custom_exoplanet_array = copy.deepcopy(exoplanet_array) # calculate new metrics for planet in custom_exoplanet_array: planet.decision_metric_(custom_telescope) # sort and truncate custom_exoplanet_array functions.sort_and_truncate_by_property(custom_exoplanet_array, 'decision_metric') # copy print properties, since location may append it observable_properties = copy.deepcopy(print_properties) # if telescope location is given, see which planets are visible for property in location_properties: value = getattr(form, property).data if value is not None and property != 'start_date' and property != 'end_date': flash.append('{} = {}'.format(property, value)) longitude = form.longitude.data latitude = form.latitude.data elevation = form.elevation.data start_date = form.start_date.data end_date = form.end_date.data min_altitude = form.min_altitude.data max_altitude = form.max_altitude.data resolution = form.resolution.data if longitude is not None and latitude is not None: # create json for exoplanet array, celery demands json_exoplanet_array = functions.planet_array_to_json_array(custom_exoplanet_array, 'host.') # start task task = observability.apply_async(args=(json_exoplanet_array, longitude, latitude, elevation, start_date, end_date, min_altitude, max_altitude, resolution)) # render template, ajax calls to celery task will fill in the page return render_template('observability.html', home=False, custom=True, print_properties=print_properties, flash=flash, exoplanet_array=custom_exoplanet_array, task_id=task.id, _ra_dec_img_url=functions.ra_dec_img_url, _deg_to_ra_hms=functions.deg_to_ra_hms, _deg_to_dec_dms=functions.deg_to_dec_dms, _round_sig_figs=functions.round_sig_figs) # choose a random planet if len(custom_exoplanet_array) > 0: randomPlanet = functions.random_planet_selector(custom_exoplanet_array) else: randomPlanet = False # graph of decision metric vs rank tooltip_dict = { 'name' : [], 'mass' : [], 'radius' : [], 'orbital_period' : [], 'semi_major_axis' : [], 'temp_calculated' : [], 'detection_type' : [], 'decision_metric' : [], 'filter' : [], 't_exp' : [], } graph = functions.metric_rank_bar_graph(custom_exoplanet_array, tooltip_dict) # render new table return render_template('table.html', graph=graph, home=False, custom=True, flash=flash, print_properties=print_properties, exoplanet_array=custom_exoplanet_array, randomPlanet=randomPlanet, _ra_dec_img_url=functions.ra_dec_img_url, _deg_to_ra_hms=functions.deg_to_ra_hms, _deg_to_dec_dms=functions.deg_to_dec_dms, _round_sig_figs=functions.round_sig_figs) # render the input form for telescope data return render_template('teleinput.html', property_list=Telescope.property_dict.keys(), location_properties=location_properties, form=form)
class LVMSimulator(object): """ Manages the simulation of LVM data Parameters: ----------- input: str path to input data file telescopeName: str Telescope name. Syntax is LVM[160,1000]-[SCI,CAL,SKY]-[N,S]. So for example, the spectrophotometric calibration 0.16m telescope at LCO (i.e. South) would be "LVM160-CAL-S" psfModel: float or int or list or str or None If float or int generates a symmetric 2D Gaussian kernel of FWHM=psfModel If list=[FWHM_a,FWHM_b,theta] and len(list)==3 generates elliptical and rotated Gaussian kernel If str reads a fits file image as the kernel If None or False no psf convolution is performed inputType: str Can be one of the following: 'fitscube' = native input datacube in fits format 'lenscube' = lenslet convolved datacube in fits format 'psfcube' = psf+lenslet convolved datacube in fits format 'fitsrss' = RSS file with one spectrum per lenslet, first row is wavelength in A 'asciirss' = ascii file with one spectrum per lenslet, first column is wavelength in A, headers must be commented with "#" fluxType: str Can be one of the following: 'intensity' = input is assumed to be in units of erg/s/cm2/arcsec2 (for both cubes and RSS files) 'flux' = input is assumed to be in units of erg/s/cm2/pixel (for cubes) or erg/s/cm2 (for RSS files) """ def __init__(self, input, telescopeName, psfModel=1.0, inputType='fitscube', fluxType='intensity', saveConvCube=True, yamlfile='lvmdatasim.yaml'): """ Initialize for Simulator """ self.input = input self.inputType = inputType self.fluxType = fluxType self.telescopeName = telescopeName self.psfModel = psfModel self.saveConvCube = saveConvCube self.yamlfile = yamlfile self.data, self.hdr = self.readInput() self.telescope = Telescope(telescopeName) """ still need to define how user sets parameters of exposure and simulation" """ import lvmdatasimdefaults self.simparam = lvmdatasimdefaults.param self.convdata = None """ Lensed cube should store PA in header, and if imputType=lenscube or psfcube code should check that PA in header is consistent with PA of observation, otherwise raise error. """ def readInput(self): if self.inputType in ['fitscube', 'lenscube', 'psfcube']: """ - Read self.input as fits cube and return data and header - Add a PIXSCALE keyword to the header if not present before passing it on """ data = fits.open(self.input) if ('PIXSCALE' not in data[0].header.keys()) and ( 'CDELT1' not in data[0].header.keys()) and ( 'CD1_1' not in data[0].header.keys()): sys.exit('No WCS Information in input FITS header') elif 'PIXSCALE' not in data[0].header.keys(): mywcs = wcs.WCS(data[0].header) pixscale = wcs.utils.proj_plane_pixel_scales( mywcs).mean() * 3600. data[0].header.set( 'PIXSCALE', pixscale, 'Pixel scale calculated from WCS by LVMSimulator') if data[0].data.ndim == 3: return (data[0].data, data[0].header) elif data[0].data.ndim == 2: ny, nx = np.shape(data[0].data) return (data[0].data.reshape(1, ny, nx), data[0].header) elif self.inputType == 'fitsrss': """ - Read self.input as fits RSS file with spectra for each spaxel and return data """ data = fits.open(self.input) return (data.data, data.header) elif self.inputType == 'asciirss': """ - Read self.input as ascii file with one spectrum per each spaxel (1st column = wavelength, each following column is one spectrum), and return data """ data = np.genfromtxt(self.input, comments="#", unpack=True) return (data, '') else: sys.exit('Input Type \"' + self.inputType + '\" not recognized.') def makePsfKernel(self): try: pixscalecube = self.hdr['PIXSCALE'] except: sys.exit( "Something went wrong. You made it this far with no 'PIXSCALE' defined in the data header." ) if isinstance(self.psfModel, (float or int)): """ Make Symmetric Gaussian 2D PSF - Need to calculate the scaling between the plate scale and the PSF model """ return (Gaussian2DKernel(self.psfModel / 2.355 / pixscalecube, mode='oversample', factor=25)) elif isinstance(self.psfModel, list): """ Make rotated Gaussian 2D elliptical PSF """ if len(self.psfModel) == 3: #Extract PSF model parameters from the list (a_stddev, b_stddev) = self.psfModel[0:2] / 2.355 (a_stddev, b_stddev) = (a_stddev / pixscalecube, b_stddev / pixscalecube) theta = self.psfModel[2] return (Gaussian2DKernel(x_stddev=a_stddev, y_stddev=b_stddev, theta=theta, mode='oversample', factor=25)) else: sys.exit( "The provided PSF model is a list, but not of length three. It can not be interpreted as a_FWHM, b_FWHM, theta" ) elif isinstance(self.psfModel, str): """ Read 2D PSF from fits file - Right now rebining fits kernel with interpolation, it would be better to do an actual integration over a surface fit """ if self.psfModel.endswith() != ".fits": sys.exit( "psfModel is str but does not end in \".fits\" as expected" ) else: psf = fits.open(self.psfModel) pixscalepsf = psf.header['PIXSCALE'] wcs0 = wcs.WCS(naxis=2) wcs0.wcs.crpix = [0, 0] wcs0.wcs.crval = [0, 0] wcs0.wcs.cdelt = np.full(2, pixscalepsf) wcs1 = wcs.WCS(naxis=2) wcs1.wcs.crpix = [0, 0] wcs1.wcs.crval = [0, 0] wcs1.wcs.cdelt = np.full(2, pixscalecube) psf[0].header = wcs0.to_header() psfrebin = reproject_interp(psf, wcs1) return (psfrebin[0].data) elif self.psfModel is False: return self.psfModel def updateyaml(self): with open("lvmdatasimTemplate.yaml", 'r') as f: data = f.read() # produces single string for key in self.simparam.keys(): data = data.replace("%s__placeholder" % key, str(self.simparam[key])) with open(self.yamlfile, 'w') as f: f.writelines(data) def makeCircularLensKernel(self): """ Generate a 2D numpy array with the characteristic function of a circle of size 'radius' (center to corner) in units of pixels of the array. The image will have dimensions of imgsize x imgsize and the circle will be at the integer center. """ rlensmm = np.mean(self.telescope.ifu.lensr) rlensarcsec = rlensmm * self.telescope.platescale() rlenspix = rlensarcsec / self.hdr['PIXSCALE'] imgsize = 2 * rlenspix antialias = 5 imgsize = int(imgsize * antialias) img = Image.new('L', (imgsize, imgsize), 0) ImageDraw.Draw(img).ellipse((0, 0, imgsize, imgsize), outline=1, fill=1) kernel = np.array(img, dtype=float) kernel /= np.sum(kernel) kernel = int_rebin(kernel, (imgsize // antialias, imgsize // antialias)) return kernel def makeHexLensKernel(self): """ Generate a 2D numpy array with the characteristic function of a hexagon of size 'radius' (center to corner) in units of pixels of the array. The image will have dimensions of imgsize x imgsize and the hexagon will be at the integer center. """ rlensmm = np.mean(self.telescope.ifu.lensr) rlensarcsec = rlensmm * self.telescope.platescale() rlenspix = rlensarcsec / self.hdr['PIXSCALE'] imgsize = 2 * rlenspix antialias = 5 imgsize = int(imgsize * antialias) center = imgsize // 2 + 1 hexLayout = hexlib.Layout(hexlib.layout_pointy, rlenspix * antialias, hexlib.Point(center, center)) polygon = hexlib.polygon_corners(hexLayout, hexlib.Hex(0, 0, 0)) img = Image.new('L', (imgsize, imgsize), 0) ImageDraw.Draw(img).polygon(polygon, outline=1, fill=1) kernel = np.array(img, dtype=float) kernel /= np.sum(kernel) kernel = int_rebin(kernel, (imgsize // antialias, imgsize // antialias)) return kernel def convolveInput(self): """ results of call: 0,0 - no convolution 1,0 - psf convolution, no lens convolution 0,1 - no psf convolution. lens convolution 1,1 - psf and lens convolution """ if self.inputType == "psfcube": # if is a psfcube dont do anything (0,0) self.convdata = self.data else: # if not psfcube it needs some sort of convolution if self.psfModel is not (False or None): # if psfModel defined then make psf kernel self.psfKernel = self.makePsfKernel() if self.inputType == ('fitscube'): # if its fitscube kernel is convolution of psf+lenslet (1,1) self.telescope.ifu.lensKernel = self.makeCircularLensKernel( ) self.kernel = convolve_fft(self.telescope.ifu.lensKernel, self.psfKernel) elif self.inputType == ('lenscube'): # if its lenscube kernel is only the psf (1,0) self.kernel = self.psfKernel else: # if psfModel is not defined then kernel is lenslet only (0,1) self.telescope.ifu.lensKernel = self.makeCircularLensKernel() self.kernel = self.telescope.ifu.lensKernel self.convdata = np.zeros(np.shape(self.data)) for i in range(np.shape(self.data)[0]): self.convdata[i, :, :] = convolve_fft(self.data[i, :, :], self.kernel, normalize_kernel=True) def getDataFluxes(self): """ - Extract the spectral fluxes from data. - If working on cube sample convolved cube at lenslet positions and scale fluxes by lenslet area with respect to average lenslet area - This version does not correct for DAR!!!!! - If working on an RSS file simply pass on the fluxes for each spaxel - Return a 2D np array of dimensions (Nspax, Nwave) in the format needed by specsim (do in one step, check scipy.interpolate.interp1d) - Main Dependent Parameters ---------- 'self.data' = data, sampled data or convolved data 'self.telescope.ifu.lensx' = image pixel coordinate x where the FOV will be centered and fluxes will be extracted. Default to center 'self.telescope.ifu.lensy' = image pixel coordinate y where the FOV will be centered and fluxes will be extracted. Default to center 'self.telescope.ifu.lensr' = hexagon radius: This does not result in a convolution of the image with each indivdual PSF of each lens. That's too expensive. What is done is to scale the fluxes of an indivudal fiber by the area of the average lens size. potentially self.skycor and telescope model, otherwise use pixel """ waveout = self.simulator.simulated[ 'wavelength'].data # get this wavelength from the simspec config member nlens = len(self.telescope.ifu.lensID) lensrsky = np.array( self.telescope.ifu.lensr) * self.telescope.platescale( self.telescope.ifu.lensx, self.telescope.ifu.lensy) lensareasky = 3 * np.sqrt( 3) * lensrsky**2 / 2 # lenslet area in arcsec2 lensrpix = lensrsky / self.hdr['PIXSCALE'] lensareapix = 3 * np.sqrt( 3) * lensrpix**2 / 2 # lenslet area in number of pixels if self.inputType in ['fitsrss', 'asciirss']: wavein = self.convdata[0, :] fluxesin = self.convdata[1:, :] interp = interpolate.RectBivariateSpline(np.range(nlens), wavein, fluxesin) fluxesout = interp(np.range(nlens), waveout) if self.fluxType == 'intensity': """Multiply input spaxel area in arcsec2 """ fluxesout *= np.repeat(lensareasky[:, np.newaxis], np.shape(fluxesout)[1], axis=1) elif self.inputType in ['fitscube', 'lenscube', 'psfcube']: # compute lenslet coordinates, do mask, evaluate spectra # resample data to output wavelength sampling self.lensra, self.lensdec = self.telescope.ifu2sky( self.simparam['ra'], self.simparam['dec'], self.simparam['theta']) mywcs = wcs.WCS(self.hdr) lenscubex, lenscubey = np.array( mywcs.wcs_world2pix(self.lensra, self.lensdec, 1)).astype(int) # The above is a placeholder # We will improve this with a cube of references fluxesin = np.zeros((nlens, np.shape(self.data)[0])) for i in range(nlens): fluxesin[i, :] = self.convdata[:, lenscubey[i], lenscubex[i]] if np.shape(self.data)[0] > 1: wavein = None "need to read this from header" interp = interpolate.RectBivariateSpline( np.range(nlens), wavein, fluxesin) fluxesout = interp(np.range(nlens), waveout) elif np.shape(self.data)[0] == 1: fluxesout = np.repeat(fluxesin, len(waveout), axis=1) # Maybe we want the image to pupulate an emission line instead of a continuum source if self.fluxType == 'intensity': """Multiply input spaxel area in arcsec2 """ fluxesout *= np.repeat(lensareasky[:, np.newaxis], np.shape(fluxesout)[1], axis=1) elif self.fluxType == 'flux': """Multiply input by spaxel area in pixels """ fluxesout *= np.repeat(lensareapix[:, np.newaxis], np.shape(fluxesout)[1], axis=1) return fluxesout def simulate(self, forceConv=False): """ Measure fluxes for each spaxel, create the simspec Simulator object, update it with user defined parameters, and run simulation """ if (self.convdata is None) or forceConv: # If convdata does not exist or the user wants to reconvolve the input (i.e. forceConv=True) then convolve the input self.convolveInput() self.updateyaml() self.simulator = specsim.simulator.Simulator( self.yamlfile, num_fibers=len(self.telescope.ifu.lensID)) self.fluxes = self.getDataFluxes( ) #intentionally broken, x and y are not defined # TO DO: add right keywords to simultate so we pass on fluxes array self.simulator.simulate(source_fluxes=self.fluxes * 1e-17 * u.erg / (u.s * u.cm**2 * u.Angstrom))
import subprocess init_pigpio = ["sudo", "pigpiod", "-t0"] subprocess.Popen(init_pigpio, stdout=subprocess.PIPE, stderr=subprocess.DEVNULL) print("Initializing...") from Telescope import Telescope from basicTrack import basicTrack as angleFunc from Pointing_Angle import getRA from astropy.coordinates.name_resolve import NameResolveError # Server IP and port placeholders telescope = Telescope(1, 1) name = input('Input name of celestial body to be tracked: ') while True: try: getRA(name) print("Located!") break except NameResolveError: print("Input name could not be resolved") name = input("Please try again: ") trackParams = { 'bodyName': name, 'LAT': Telescope.getLAT, 'LON': Telescope.getLON, 'currentTimeDt': Telescope.getCurrentTime, 'currentAngle': Telescope.getAngles
from StarChart import StarChart from Telescope import Telescope if __name__ == "__main__": chart = StarChart() scope = Telescope(0.5, 0.5, 250, 250, (0, 0, 0), (1, 0, 0)) data = [(100, 0, 0), (100, -10, -10), (100, 10, 10)] chart.load_data(data) scope.calculate_view(chart.find_nearby_stars((0, 0, 0), (0, 0, 0))) scope.update_view()
import numpy as np from Telescope import Telescope import Pointing_Angle as pointer from Pointing_Angle import getRA from astropy.coordinates.name_resolve import NameResolveError print( "This script will attempt to calibrate the positioning of the telescope.") print( "You select a star to point at, and the telescope will try to point at that star." ) print( "Then you provide a list of fine adjustments until the star is centered in the telescope's field of view" ) t = Telescope(1, 2) name = input('Input name of celestial body to calibrate against: ') while True: try: getRA(name) print("Located!") angle = pointer.calcAngle(name, t.LAT, t.LON, Telescope.getCurrentTime(), Telescope.getAltAngle(), Telescope.getAzAngle()) check = t.checkConstraints(angle) if check: print("Star is within viewing constraints!") break else:
def read_planet_telescope_data_csv(planet_src, tele_src, path_to_static, onlyConfirmed, to_remove=[]): ''' Function to read in the planet and telescope data, determine if calculable, truncate and return arrays for both, and check if images are present in the static folder Parameters ---------- planet_src : str A url for the csv containing planet data tele_src : str A full file path to the csv containing telescope data path_to_static : str A file path to the static folder, for checking and saving images, saving pickle files as a backup and saving pickle files to check observability Returns ------- exoplanet_array : list of Exoplanet tele_array : list of Telescope plottingsource : dict A dictionary with Exoplanet properties as keys and a list as values, ready to be converted into a Bokeh plotting source ''' try: ################ # exoplanet read in start = time.perf_counter() print('Updated data ' + str(datetime.datetime.now())) # access database and read the data from the csv file if not onlyConfirmed: try: # submit form data to get unconfirmed planets too values = { 'Confirmed': 'on', 'Candidate': 'on', 'Other': 'on', 'query_f': '', 'search': '' } data = urllib.parse.urlencode(values).encode('utf-8') url = planet_src + '?status_1=on&status_2=on&status_4=on&query_f=&search=/' req = urllib.request.Request(url, data=data) planet_csv = urllib.request.urlopen(req) except: # didn't work, just get confirmed ones by default planet_csv = urllib.request.urlopen(planet_src) onlyConfirmed = True else: planet_csv = urllib.request.urlopen(planet_src) # convert the web file to string and split into rows (each row still a csv) planet_csv = str(planet_csv.read()) planet_rows = planet_csv.split('\\r\\n') # remove the first row containing the table headers and the last blank row and create an empty array of exoplanet objects planet_rows.pop(0) planet_rows.pop() exoplanet_array = [] host_star_array = [] # split each row by comma and fill the empty exoplanet array with all assigned properties # specific to the exoplanets.eu database, Exoplanet.property_dict has the same headers in the same order for row in planet_rows: # split by comma (except when inside quotes) columns = re.split(",(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)", row) planet_col = columns[:68] host_col = columns[68:] prop_units = list(Exoplanet.property_dict.items()) + [ ('host.' + prop, val) for prop, val in Star.property_dict.items() ] # planet object (and host object contained inside) planet = Exoplanet() # add info for val, (prop, unit) in zip(columns, prop_units): try: # attempt to float if not np.isnan(float(val)) and not np.isinf(float(val)): rsetattr(planet, prop, float(val)) # years will should be datetime timestamps, for plotting sake if unit == 'year': rsetattr( planet, prop, datetime.datetime.strptime( val, '%Y').timestamp() * 1000) else: # could float but the value is nan or inf, set a blank instead rsetattr(planet, prop, '') # could not float except ValueError: # dates should be datetime timestamps, for plotting sake if unit == 'date': rsetattr( planet, prop, datetime.datetime.strptime( val, '%Y-%m-%d').timestamp() * 1000) # yes/no strings converted to bool elif val == 'yes': rsetattr(planet, prop, True) elif val == 'no': rsetattr(planet, prop, False) # save as string instead else: rsetattr(planet, prop, val.replace('"', '')) # append to lists exoplanet_array.append(planet) host_star_array.append(planet.host) # manually remove erroneous members of the list for planet in exoplanet_array: if planet.name in to_remove: exoplanet_array.remove(planet) host_star_array.remove(planet.host) #################### # telescope read in # read in telescope data tele_csv = open(tele_src, 'r') tele_csv = tele_csv.read() tele_csv = tele_csv.replace('NaN', '') # replace NaN in csv with blank space tele_rows = tele_csv.split('\n') # remove the first row containing the table headers and last blank row and create an empty array of telescope objects tele_rows.pop(0) tele_rows.pop() tele_array = [] # split each row by comma and fill the empty telescope array with all assigned properties for row in tele_rows: # split by comma columns = re.split(',', row) # telescope object telescope = Telescope() # append each new telescope and fill with values according to the dictionary for prop, index in Telescope.property_dict.items(): val = columns[index] try: # spectral bins and half well are ints if prop == 'spectral_bins' or prop == 'Half_Well': setattr(telescope, prop, int(val)) # otherwise attempt to float else: setattr(telescope, prop, float(val)) # could not float, save as string instead except ValueError: setattr(telescope, prop, val) # append telescope tele_array.append(telescope) ################### # other jobs to do # determine if calculable for planet in exoplanet_array: planet._metric_calculable_() for telescope in tele_array: telescope._C_T_calculable_() # check images of each planet exist in the static folder, if not download it from the internet new_names = [] for planet in exoplanet_array: if not os.path.isfile( path_to_static + planet.name.replace(' ', '_').replace('/', '_') + '.gif'): url_pic = ra_dec_img_url(planet.host.ra, planet.host.dec) filename = path_to_static + planet.name.replace( ' ', '_').replace('/', '_') + '.gif' urllib.request.urlretrieve(url_pic, filename) new_names.append(planet.name) # make bokeh plotting source source_dict = plotting_source_dict(exoplanet_array) ################### # save progress # save in pickle just in case with open(path_to_static + 'exoplanet_array.pkl', 'wb') as f: pickle.dump(exoplanet_array, f) with open(path_to_static + 'tele_array.pkl', 'wb') as f: pickle.dump(tele_array, f) with open(path_to_static + 'source_dict.pkl', 'wb') as f: pickle.dump(source_dict, f) end = time.perf_counter() print('Data read-in took ' + str(round(end - start, 3)) + ' seconds for %i planets (reduced to %i) and %i telescopes' % (len(planet_rows), len(exoplanet_array), len(tele_array))) if new_names: print('New planets since last update:') for name in new_names: print(name) except: # maybe a timeout error occured, just reload from stored pickle arrays instead with open(path_to_static + 'exoplanet_array.pkl', 'rb') as f: exoplanet_array = pickle.load(f) with open(path_to_static + 'tele_array.pkl', 'rb') as f: tele_array = pickle.load(f) with open(path_to_static + 'source_dict.pkl', 'rb') as f: source_dict = pickle.load(f) print('Could not load new data, loading data from last update instead') print('%i planets and %i telescopes' % (len(exoplanet_array), len(tele_array))) return (exoplanet_array, tele_array, source_dict)
from Telescope import Telescope try: myTel = Telescope("LVM160-SCI-S") print("Telescope Import Successful") except: print("Telescope Import Failed")