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 SUBTRACT(): path = input("\n-> Enter path to exposure time directory: ") method = input("\n-> Choose subtraction method: hotpants or AIS: ") if method == 'hotpants': # align_skimage.skimage_template(location) subtract_hotpants.hotpants(path) # MR(path) elif method == 'AIS': # align_chi2.chi2(location) subtract_ais.isis_sub(path) # MR(path) else: print("\n-> Error: Unknown method")
def PIPELINE(): get_check = input("-> Get data or analyze existing data? (get/analyze): ") if get_check == 'get': get.GET() elif get_check == 'analyze': location = input("-> Enter path to data directory: ") sat = check_saturation.check_saturate(location) if sat == 0: ref_image(location) align_astroalign.align2(location) else: check = input( "-> Saturated images found, continue image alignment? (y/n): ") if check == 'y': move = input( "-> Move saturated images to SDI archives before continuing? (y/n): " ) if move == 'y': check_saturation.move_arch(sat) ref_image(location) align_astroalign.align2(location) else: ref_image(location) align_astroalign.align2(location) method = input( "-> Choose combination method-- numpy (default) or swarp: ") if method == "swarp": combine_swarp.swarp(location) elif method == "numpy" or method == "": combine_numpy.combine_median(location) else: print("-> Error: unknown method entered") path = location[:-5] sub_method = input( "\n-> Choose subtraction method-- ais (default) or hotpants: ") if sub_method == '' or sub_method == 'ais': subtract_ais.isis_sub(path) elif sub_method == 'hotpants': subtract_hotpants.hotpants(path) else: print("\n-> Error: Unknown method") ask = input("-> Run sextractor on residual images? (y/n): ") if ask == 'y': extract.SEXTRACTOR(path) elif ask != 'y' and ask != 'n': print("-> Error: unknown input")
def SUBTRACT(path, method='ois', use_config_file=True): '''Performs difference imaging on the science images. The template image is convolved to match the science image's PSF, then the template is subtracted from the science image. This process is repeated for a number of different parameter configurations until an optimal residual is found. The actual convolution and subtraction is done with either the ``ISIS`` package (Alard) or ``hotpants`` (Becker). 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 method: Method of difference imaging. :param bool use_config_file: If ``True`` all input parameters are fetched from the local *OASIS.config* file. * *ois* (default): Optimal Image Subtraction. Christohpe Alard's ``ISIS`` package. * *hotpants*: Andrew Becker's ``hotpants`` program. Very similar to Alard's OIS, but differs in input parameters. May be useful to try if OIS is returning inadequate results. :returns: All science images are differenced and the corresponding residuals are placed in the **residuals** directory with the *_residual_* suffix. ''' paths = (path.replace(' ', '')).split(',') del path for path in paths: if use_config_file == True: method = get_config_value('sub_method') images = glob.glob(path + '/data/*.fits') psf_data = glob.glob(path + '/psf/*') if len(psf_data) != 2 * (len(images) + 1): psf.PSF(path) else: print("\n-> PSFs already exist...") if method == '' or method == 'ois': subtract_ais.isis_sub(path) optimize.perform_optimization(path) MR.MR_swarp(path) elif sub_method == 'hotpants': subtract_hotpants.hotpants(path) optimize.perform_optimization(path) MR.MR_swarp(path) else: print("\n-> Error: Unknown method") sys.exit()
"-> Move saturated images to SDI archives before continuing? (y/n): " ) if move == 'y': check_saturation.move_arch(sat) ref_image(location) align_astroalign.align2(location) else: ref_image(location) align_astroalign.align2(location) method = input( "-> Choose combination method-- numpy (default) or swarp: ") if method == "swarp": combine_swarp.swarp(location) elif method == "numpy" or method == "": combine_numpy.combine_median(location) else: print("-> Error: unknown method entered") path = location[:-5] sub_method = input( "\n-> Choose subtraction method-- ais (default) or hotpants: ") if sub_method == '' or sub_method == 'ais': subtract_ais.isis_sub(path) elif sub_method == 'hotpants': subtract_hotpants.hotpants(path) else: print("\n-> Error: Unknown method") ask = input("-> Run sextractor on residual images? (y/n): ") if ask == 'y': extract.SEXTRACTOR(path) elif ask != 'y' and ask != 'n': print("-> Error: unknown input")
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]))