def pipeline_run_sim(path): startTime = time.time() if os.path.exists(path) == True: location = path + '/data' mask.MASK(path) ref_image(location) align_astroalign.align2(location) print("-> Combining images using swarp method...") psf.PSF(path) combine_swarp.swarp(location) psf.PSF(path) print("\n-> Subtracting images using AIS method...") subtract_ais.isis_sub(path) optimize.perform_optimization(path) print("-> Running SExtractor on residuals...") extract.EXTRACT(path, method='indiv') MR.MR_swarp(path) extract.EXTRACT(path, method='MR') endTime = time.time() print("-> Finished!\n-> Total runtime: %.2f seconds\n" % (endTime - startTime)) else: print( "\n-> Error: Unknown path entered\n-> Please enter the path to an existing exposure time directory\n-> Exiting...\n" ) sys.exit()
def PIPELINE(path): '''The **OASIS Pipeline**. Runs all **OASIS** functions in succession. :param str path: Path of data file tree (contains the **configs**, **data**, **psf**, **residuals**, **sources**, **templates** directories). Use a comma-separated list for mapping to multiple datasets. :returns: All-in-one difference imaging pipeline. Raw science images are placed in the **data** directory, and residual images and source catalogs are outputted into the **residuals** and **sources** directories, respectively. ''' paths = (path.replace(' ', '')).split(',') del path for path in paths: startTime = time.time() if os.path.exists(path) == True: initialize.create(path) location = path + '/data' mask.MASK(path) sat = check_saturation.check_saturate(location) if sat == 0: ref_image(location) align_astroalign.align2(location) else: check = input( "-> Saturated images found\n-> Move saturated images to OASIS archive? (y/n): " ) if check == 'y': check_saturation.move_arch(sat) ref_image(location) align_astroalign.align2(location) elif check == 'n': ref_image(location) align_astroalign.align2(location) else: print("-> Error: Unknown input") sys.exit() print("-> Combining images using swarp method...") psf.PSF(path) combine_swarp.swarp(location) psf.PSF(path) print("\n-> Subtracting images using AIS method...") subtract_ais.isis_sub(path) optimize.perform_optimization(path) print("-> Running SExtractor on residuals...") extract.EXTRACT(path, method='indiv') MR.MR(path) extract.EXTRACT(path, method='MR') endTime = time.time() print("-> Finished!\n-> Total runtime: %.2f seconds\n" % (endTime - startTime)) else: print( "\n-> Error: Unknown path entered\n-> Please enter the path to an existing exposure time directory\n-> Exiting...\n" ) sys.exit()
def pipeline_run_sim(path, sim_x=1, sim_y=1, sim_width=30, sim=True): import align_astroalign from ref_image import ref_image import combine_swarp import extract import subtract import mask import sys import psf import MR import os import time startTime = time.time() if os.path.exists(path) == True: location = path + '/data' ref_image(location) align_astroalign.align2(location) mask.MASK(path) print("-> Combining images using swarp method...") psf.PSF(path) combine_swarp.swarp(location) psf.PSF(path) print("\n-> Subtracting images...") subtract.SUBTRACT(path) # print("\n-> Subtracting images using AIS method...") # subtract_ais.isis_sub(path) # optimize.perform_optimization(path, s_x=sim_x, s_y=sim_y, s_width=sim_width, simulate=sim, qFloor=0.80, qValue=0.90, qInitial=0.95, use_config_file=False) print("-> Running SExtractor on residuals...") extract.EXTRACT(path, method='indiv') MR.MR(path) extract.EXTRACT(path, method='MR') endTime = time.time() print("-> Finished!\n-> Total runtime: %.2f seconds\n" % (endTime - startTime)) else: print( "\n-> Error: Unknown path entered\n-> Please enter the path to an existing exposure time directory\n-> Exiting...\n" ) sys.exit()
def ALIGN(path, align_method='standard'): '''Registers all science images to their reference image. If no reference image exists, one is chosen (see documentation for details). :param str path: Path of data file tree (contains the **configs**, **data**, **psf**, **residuals**, **sources**, **templates** directories). Use a comma-separated list for mapping to multiple datasets. :param str align_method: Method of alignment. Can be either *standard* or *fakes*. Default is *standard*. The *fakes* method should be used only for simulations, as it bypasses registration and only performs photometric alignment. :returns: Aligns all science images are aligned to the reference image to subpixel precision. A succesful alignment changes an image's suffix from *_U_* to *_A_*. ''' paths = (path.replace(' ', '')).split(',') del path for path in paths: if os.path.exists(path): location = path + '/data' mask.MASK(path) sat = check_saturation.check_saturate(location) if sat == 0: ref_image(location) align_astroalign.align2(location, method=align_method) else: check = input( "-> Saturated images found, continue image alignment? (y/n): " ) if check == 'y': print("-> Moving saturated images to OASIS archives...") check_saturation.move_arch(sat) ref_image(location) align_astroalign.align2(location, method=align_method) elif check == 'n': pass else: print("-> Unknown input: must be y or n") sys.exit() else: print( "\n-> Error: Unknown path entered\n-> Please enter the path to an existing exposure time directory\n-> Exiting...\n" ) sys.exit()
def TEST(): '''Tests the installation of **OasisPy** by downloading a set of images from an online public archive, adding fake sources to one of the images, and running the dataset through the **OASIS Pipeline**. If the fake sources are recovered, the test is a success. The images used are 118 second exposures of exoplanet HAT-P-37b taken with telescopes at the Las Cumbres Observatory. Results of the test are compared to control results located in **OasisPy**'s source code directory. :returns: Prints either 'TEST SUCCESSFUL!' or 'Test failure: Results do not match controls'. ''' frameNum = 30 q_initial = 1 q_value = 0.90 q_min = 0.80 startTime = time.time() #look for existing TEST folder and delete it og_test = loc + '/OASIS/targets/TEST' if os.path.exists(og_test) == True: shutil.rmtree(og_test) #get data from LCO public archive and put in target directory under 'TEST' folder print("\n-> Getting data from LCO...") object_name = 'HAT-P-37' response = requests.get('https://archive-api.lco.global/frames/?' + 'limit=%d&' % (frameNum) + 'RLEVEL=91&' + 'PROPID=' + 'LCOEPO2014B-007' + '&' + 'OBJECT=' + '%s&' % (object_name) + 'FILTER=' + 'w&' + 'start=' + '2019-05-29' + '&' 'end=' + '2019-05-31' + '&').json() frames = response['results'] # print(len(frames)) #take only the first 25 frames frames = frames[:frameNum] #download data temp_loc = loc + '/OASIS/temp/' os.mkdir(temp_loc + 'test_data') for frame in frames: with open(temp_loc + 'test_data/' + frame['filename'], 'wb') as f: f.write(requests.get(frame['url']).content) #funpack and move to 'TEST' folder obtain.process() obtain.movetar() old_data_location = obtain.rename() data_location = old_data_location.replace(object_name.replace(' ', '_'), 'TEST') os.rename("%s/OASIS/targets/%s" % (loc, object_name.replace(' ', '_')), "%s/OASIS/targets/TEST" % (loc)) #align and combine images test_loc = data_location[:-5] mask.MASK(test_loc) check_saturation.check_saturate(test_loc + '/data') ref_image.ref_image(test_loc + '/data') align_astroalign.align2(test_loc + '/data') psf.PSF(test_loc) combine_swarp.swarp(test_loc + '/data') #get PSFs of images so fake stars with same seeing can be added fake_im = '02:59:10.860_A_.fits' print('\n-> Image %s chosen as fake image\n' % (fake_im)) fake_residual = fake_im.replace('_A_', '_A_residual_') psf.PSF(test_loc) FWHM = psf.fwhm(test_loc + '/data/%s' % (fake_im)) #add three fake stars to reference image print("\n-> Adding fake stars to test image...") hdu = fits.open(test_loc + '/data/%s' % (fake_im)) hdu_data = hdu[0].data hdu_header = hdu[0].header hdu_mask = hdu[1].data h, w = np.shape(hdu_data) pos_x = [1500, 200, 1200] pos_y = [1600, 1400, 700] array = np.array([0.65343465, 0.50675629, 0.84946314]) fluxes = (200000.0 * array) + 300.0 print("\n-> Fake locations (in pixel coords):") print("\t X:", pos_x) print("\t Y:", pos_y) print("-> Fake fluxes (in ADUs):") print("\t ", fluxes) img = make_gaussian_im(h, w, fluxes=[fluxes[0], fluxes[1], fluxes[2]], x_pos=[pos_x[0], pos_x[1], pos_x[2]], y_pos=[pos_y[0], pos_y[1], pos_y[2]], std=[FWHM, FWHM, FWHM]) finalData = fits.PrimaryHDU(hdu_data + img, header=hdu_header) finalMask = fits.ImageHDU(hdu_mask) finalList = fits.HDUList([finalData, finalMask]) finalList.writeto(test_loc + '/data/%s' % (fake_im), overwrite=True) hdu.close() #subtract images using ISIS subtract_ais.isis_sub(test_loc) perform_optimization(test_loc, qInitial=q_initial, qValue=q_value, qFloor=q_min, use_config_file=False) MR.MR_swarp(test_loc) #perform SExtractor on residual images extract.EXTRACT(test_loc) #print TEST runtime endTime = time.time() print("\n-> Total test runtime: %.3fs\n" % (endTime - startTime)) residual = glob.glob(test_loc + '/residuals/%s' % (fake_residual)) fake1_check = False fake2_check = False fake3_check = False MR_sources, inds = filters.get_sources("%s/residuals/MR.fits" % (test_loc), filtered=True, MR=True) for src in MR_sources: if 1498 < src[1] < 1502 and 1598 < src[2] < 1602: fake1_check = True elif 198 < src[1] < 202 and 1398 < src[2] < 1402: fake2_check = True elif 1198 < src[1] < 1202 and 698 < src[2] < 702: fake3_check = True if fake1_check == True and fake2_check == True and fake3_check == True: print("\n-> Test SUCCESSFUL!") else: print("-> Test failure: Results do not match controls") #display final residual test image os.system('ds9 %s -scale zscale' % (residual[0]))
def RUN(): ''' Master run function. Allows user to call any of the main **OASIS** methods. See documentation for details. ''' print('\n\t ------------------------------------------------------') print('\t OASIS v.1.0 ') print('\n\t Difference Imaging Software for Optical SETI Purposes ') print('\t Developed for the SDI Program @ UCSB ') print('\t http://www.deepspace.ucsb.edu ') print('\n\t Contact [email protected] for bug reports ') print('\t ------------------------------------------------------') print("\n-> Methods:") print("\n\tinitialize get mask align") print("\tpsf combine subtract mr") print("\textract pipeline simulate test") method = str(input('\n-> Enter method: ')) if method == 'get': import get get.GET() elif method == 'mask': path = input("-> Enter path to exposure time directory: ") import mask mask.MASK(path) elif method == 'align': path = input("-> Enter path to exposure time directory: ") import align align.ALIGN(path) elif method == 'psf': path = input("-> Enter path to exposure time directory: ") import psf psf.PSF(path) elif method == 'combine': path = input("-> Enter path to exposure time directory: ") import combine combine.COMBINE(path) elif method == 'subtract': path = input("-> Enter path to exposure time directory: ") import subtract subtract.SUBTRACT(path) elif method == 'mr': path = input("-> Enter path to exposure time directory: ") import MR MR.MR(path) elif method == 'extract': import extract path = input("-> Enter path to exposure time directory: ") extract_method = input("\n-> Extract method (both/indiv/MR): ") extract.EXTRACT(path, method=extract_method) elif method == 'pipeline': import pipeline path = input("-> Enter path to exposure time directory: ") pipeline.PIPELINE(path) elif method == 'initialize': import initialize initialize.INITIALIZE() elif method == 'test': import test test.TEST() elif method == 'simulate': import simulation simulation.SIM() else: print("-> Error: Method not recognized")