def _transfer_coos(self): """Transfer coordinates from the IOL to the GOL""" # compose the WCS-term for the direct and grism images dir_term = getDATA("{0:s} [{1:d}]".format( self.dirname, self.dirname_extinfo['fits_ext'])) gri_term = getDATA("{0:s} [{1:d}]".format( self.grisim, self.grism_extinfo['fits_ext'])) # generate the WCS objects dir_wcs = wcsutil.WCSObject(dir_term) gri_wcs = wcsutil.WCSObject(gri_term) # go over each row in the catalog for row in self.gol: # make a position tuple try: xy_direct = (row['X_IMAGE'], row['Y_IMAGE']) except KeyError: # self._treat_NULL_table raise aXeError("No coordinate columns in catalog, empty?") # convert to RADEC using the direct image radec_pos = dir_wcs.xy2rd(xy_direct) # convert to XY on grism image xy_grism = gri_wcs.rd2xy(radec_pos) # store projected vals in the GOL row['X_IMAGE'] = float(xy_grism[0]) row['Y_IMAGE'] = float(xy_grism[1])
def _check_global_backsub(self): """Check for global background subtraction""" # go over all inputs for one_input in self.axe_inputs: # load the config file and get the extension information conf = configfile.ConfigFile( config_util.getCONF(one_input['config'])) ext_info = config_util.get_ext_info( config_util.getDATA(one_input['grisim']), conf) # open the fits image gri_fits = fits.open(config_util.getDATA(one_input['grisim']), 'readonly') # go to the correct header act_header = gri_fits[ext_info['fits_ext']].header # make sure a sky background value is set if 'SKY_CPS' in act_header and act_header['SKY_CPS'] >= 0.0: # close the fits gri_fits.close() else: # close fits, complain and out gri_fits.close() err_msg = ( "{0:s}: The grism image: \n{1:s}\nhas no keyword " "SKY_CPS>=0.0 in the extension {2:d}. This means " "it had NO global\nsky subtraction, which is " "required for the CRR version of aXedrizzle!".format( self.taskname, config_util.getDATA(one_input['grisim']), ext_info['fits_ext'])) raise aXeError(err_msg)
def prepare_extraction(self): """Prepares the aXe extraction The module does some preparatory stuff before the extraction can start. This includes copying the simulated dispersed image to AXE_IMAGE_PATH and subtracting the background on this copy. """ # give brief feedback _log.info('Dummy extraction on the dispersed image:') sys.stdout.flush() # get a random filenames tmpfile1 = config_util.get_random_filename('t', '.fits') # copy the grism image to AXE_IMAGE_PATH shutil.copy(config_util.getOUTSIM(self.simul_grisim), config_util.getDATA(tmpfile1)) # subtract the background from # the grism image # expression = "(a - b)" # iraf.imexpr(expr=expression, output=tmpfile2, # a=config_util.getDATA(tmpfile1)+'[SCI]', b=self.bck_flux, Stdout=1) in_image = fits.open(config_util.getDATA(tmpfile1)) in_image['sci'].data -= self.bck_flux in_image.close() # store the name of the background # subtracted grism image - this was tmpfile self.dispersed_image = tmpfile1
def _check_files(self): """Checks the existence of the input files""" # check the direct image if not os.path.isfile(config_util.getDATA(self.direct_image)): err_msg = ("\nThe direct image is not available: {0:s}" .format(config_util.getDATA(self.direct_image))) raise aXeSIMError(err_msg) # check the configuration file if not os.path.isfile(config_util.getCONF(self.configfile)): err_msg = ("\nThe configuration file is not available: {0:s}" .format(config_util.getCONF(self.configfile))) raise aXeSIMError(err_msg) # check the simulated grism image if not os.path.isfile(config_util.getOUTSIM(self.simul_grisim)): err_msg = ("\nThe grism image is not available: {0:s}" .format(config_util.getOUTSIM(self.simul_grisim))) raise aXeSIMError(err_msg) # check the IOL if not os.path.isfile(self.iolname): err_msg = ("\nThe Input Object List is not available: {0:s}" .format(self.iolname)) raise aXeSIMError(err_msg) try: float(self.bck_flux) except ValueError: # check the background image if not os.path.isfile(config_util.getCONF(self.bck_flux)): err_msg = ("\nThe background imagage is not available: {0:s}" .format(config_util.getCONF(self.bck_flux))) raise aXeSIMError(err_msg)
def _make_objPET(self): """Generate the object PET.""" # set the use_direct flag # NOTE: the flag is only usefull # for the C-version, the python # version does not need it! use_direct = False if self.dirim is not None: use_direct = True # run SEX2GOL axetasks.sex2gol(grism=self.grisim, config=config_util.getCONF(self.config), in_sex=config_util.getDATA(self.objcat), use_direct=use_direct, direct=config_util.getDATA(self.dirim), dir_hdu=None, spec_hdu=None, out_sex=None) # run GOL2AF axetasks.gol2af(grism=self.grisim, config=self.config, mfwhm=self.params['extrfwhm'], back=False, orient=self.params['orient'], slitless_geom=self.params['slitless_geom'], exclude=self.params['exclude'], lambda_mark=self.params['lambda_mark'], dmag=self.dmag, out_af=None, in_gol=None) # run AF2PET axetasks.af2pet(grism=self.grisim, config=self.config, back=False, out_pet=None) # run PETCONT axetasks.petcont(grism=self.grisim, config=self.config, cont_model=self.params['cont_model'], model_scale=self.params['model_scale'], spec_models=None, object_models=None, inter_type=self.params['inter_type'], lambda_psf=self.params['lambda_psf'], cont_map=True, in_af="") # run PETFF axetasks.petff(grism=self.grisim, config=self.config, back=False, ffname=None)
def mopup(self): """Deleting tmp-files, copying SPC's, STP's""" # get the root name of the dispersed image root_name = self.dispersed_image.split('.fits')[0] # get the root name of the simulated image result_root = self.simul_grisim.split('.fits')[0] # move and rename the SPC-file out_spc = config_util.getOUTPUT(root_name + '_2.SPC.fits') result_spc = config_util.getOUTSIM(result_root + '_2.SPC.fits') shutil.move(out_spc, result_spc) # move and rename the STP-file out_stp = config_util.getOUTPUT(root_name + '_2.STP.fits') result_stp = config_util.getOUTSIM(result_root + '_2.STP.fits') shutil.move(out_stp, result_stp) # delete the background subtracted # grism image os.unlink(config_util.getDATA(self.dispersed_image)) # delete the GOL, the OAF and the PET result_cat = config_util.getOUTPUT(root_name + '_2.cat') if os.path.isfile(result_cat): os.unlink(result_cat) result_oaf = config_util.getOUTPUT(root_name + '_2.OAF') if os.path.isfile(result_oaf): os.unlink(result_oaf) result_pet = config_util.getOUTPUT(root_name + '_2.PET.fits') if os.path.isfile(result_pet): os.unlink(result_pet)
def _get_grism_ext_info(self, grisim='', config='', spec_hdu=None): """Determine the extension information on the grism image. Parameters ---------- grisim : str The name of the grism images config : str The name of the configuration file spec_hdu : int, None The extention number of the spectra data Returns ------- ext_info : dict A dictionary that contains the header extension and the data extension """ if spec_hdu is None: conf = configfile.ConfigFile(getCONF(config)) ext_info = get_ext_info(getDATA(grisim), conf) else: # make by hand the extension information ext_info = {'axe_ext': spec_hdu, 'fits_ext': spec_hdu - 1} # return the extension info return ext_info
def _check_dpps(self, back=False): # go over all inputs for one_input in self.axe_inputs: # load the config file and get the extension information conf = configfile.ConfigFile( config_util.getCONF(one_input['config'])) ext_info = config_util.get_ext_info( config_util.getDATA(one_input['grisim']), conf) # derive the aXe names axe_names = config_util.get_axe_names(one_input['grisim'], ext_info) # check the DPP file if not os.path.isfile(config_util.getOUTPUT(axe_names['DPP'])): # error and out err_msg = ("{0s:}: The DPP file: {1:s} does not exist!".format( self.taskname, config_util.getOUTPUT(axe_names['DPP']))) raise aXeError(err_msg) # check for the background DPP file if back and not os.path.isfile( config_util.getOUTPUT(axe_names['BCK_DPP'])): # error and out err_msg = ("{0:s}: The background DPP file: {1:s} does not " "exist!".format( self.taskname, config_util.getOUTPUT(axe_names['BCK_DPP']))) raise aXeError(err_msg)
def _is_prism_data(self): # define the default is_prism = False # make sure there are grism images for row in self.axe_inputs: one_grisim = config_util.getDATA(row['grisim']) # open the fits one_fits = fits.open(one_grisim, 'readonly') # read the keyword 'FILTER1' try: filter1 = one_fits[0].header['FILTER1'] except KeyError: filter1 = None # read the keyword 'FILTER2' try: filter2 = one_fits[0].header['FILTER2'] except KeyError: filter2 = None # check whether it is prism data if ((filter1 and filter1.find('PR')) or (filter2 and filter2.find('PR'))): # switch to IS_PRISM is_prism = True # close the fits one_fits.close() # return the index return is_prism
def _get_dpp_list(self, inima, confterm, back): """Determine the name of all DPP files""" DPP_list = [] # generate the input list for aXe axe_inputs = axeinputs.aXeInput(inima, confterm) # go over the list of all inputs for an_input in axe_inputs: # load the configuration file conf = configfile.ConfigFile(config_util.getCONF(an_input['config'])) # get the image extensions ext_info = config_util.get_ext_info(config_util.getDATA(an_input['grisim']), conf) # get the name of all axe files axe_names = config_util.get_axe_names(an_input['grisim'], ext_info) # if requested, # append the background DPP file if back: DPP_list.append(axe_names['BCK_DPP']) else: # append the 'normal' DPP name to the list DPP_list.append(axe_names['DPP']) # return the DPP list return DPP_list
def run(self): # load the configuration files; # get the extension info conf = configfile.ConfigFile(config_util.getCONF(self.config)) ext_info = config_util.get_ext_info(config_util.getDATA(self.grisim), conf) del conf # Does this harm data that was astrodrizzled? if (('drzfwhm' in self.params) and (self.params['drzfwhm']) or (('cont_model' in self.params) and (config_util.is_quant_contam(self.params['cont_model'])))): # generate the non-linear distortions from the IDCTAB; # and store them in the fits-file header _log.info( "Generating and storing nonlinear distortions in {0}".format( config_util.getDATA(self.grisim))) nlins = nlincoeffs.NonLinCoeffs(config_util.getDATA(self.grisim), ext_info) nlins.make() nlins.store_coeffs() del nlins # make the object PET's self._make_objPET() # make a background PET if necessary if 'back' in self.params and self.params['back']: _log.info("\nMaking backpet\n") self._make_bckPET() # extract the spectra if 'spectr' in self.params and self.params['spectr']: _log.info("\nMaking spectra\n") self._make_spectra() # make the proper non-quantitative contamination if ('drzfwhm' in self.params and self.params['drzfwhm']) and \ ('cont_model' in self.params and not config_util.is_quant_contam(self.params['cont_model'])): _log.info("\nmaking non quant contam\n") self._make_drzgeocont(ext_info)
def _check_subarray(self): """ check for and reject subarray images """ # go over all rows in the list for row in self._inimlist: # check the existence of the Input Image List image = config_utils.getDATA(row['grisim']) subarray = fits.getval(image, "SUBARRAY", ext=0) if subarray: err_msg = ("Grism image: {0:s} is a subarray" " which is not supported".format(image)) raise aXeError(err_msg) if 'dirim' in self._inimlist.colnames: image = config_utils.getDATA(row['dirim']) subarray = fits.getval(image, "SUBARRAY", ext=0) if subarray: err_msg = ("Direct image: {0:s} is a subarray" " which is not supported".format(image)) raise aXeError(err_msg)
def _validate_columns(self): """Identify columns according to the Input Image List format""" columns = self._inimlist.colnames # check for number of columns if len(columns) < 2: err_msg = ("Expected at least 2 columns in {0:s}!".format( self._inimlist)) raise aXeError(err_msg) columns.reverse() name = columns.pop() if ((np.issubsctype(self._inimlist[name], np.str)) and ('fits' in self._inimlist[name][0])): self._inimlist.rename_column(name, 'grisim') else: err_msg = ("Column 1 should be the names of the grism" " fits files: {0}".format(self._inimlist)) raise aXeError(err_msg) # check whether second column has type string name = columns.pop() if np.issubsctype(self._inimlist[name], np.str): self._inimlist.rename_column(name, 'objcat') else: err_msg = ("Column 2 should be the names of the object catalogs" "{0}".format(self._inimlist)) raise aXeError(err_msg) # do a check on the first object catalog to make sure it's a format # that we can read try: __ = Table.read(config_utils.getDATA(self._inimlist[0]['objcat']), format='ascii.sextractor') except IORegistryError: raise aXeError( "Catalog format not recognized , checked for: {0:s}".format( self._inimlist[name][0])) # go over all remaining rows to find DMAG and DIRIM while columns: name = columns.pop() # assume if it's a number it's DMAG if np.issubsctype(self._inimlist[name], np.float): self._inimlist.rename_column(name, 'dmag') # assume if it's a string its the direct image elif np.issubsctype(self._inimlist.columns[0], np.str): if '.fits' in self._inimlist.columns[0][0]: self._inimlist.rename_column(name, 'dirim') else: err_msg = ("Problem identifying last columns in: {0}".format( self._inimlist)) raise aXeError(err_msg)
def _check_fluxcubes(self): # go over all inputs for one_input in self.axe_inputs: # load the config file and get the extension information conf = configfile.ConfigFile( config_util.getCONF(one_input['config'])) ext_info = config_util.get_ext_info( config_util.getDATA(one_input['grisim']), conf) # derive the aXe names axe_names = config_util.get_axe_names(one_input['grisim'], ext_info) # check the fluxcube if not os.path.isfile(config_util.getDATA(axe_names['FLX'])): # error and out err_msg = ( "{0:s}: The fluxcube file: {1:s} does not exist!".format( self.taskname, config_util.getDATA(axe_names['FLX']))) raise aXeError(err_msg)
def _force_dirim(self): # go over all inputs for one_input in self.axe_inputs: # check whether there is a direct image if one_input['DIRIM'] is None: # error and out err_msg = ("{0:s}: The grism image: {1:s} does NOT have an " "associated direct image!".format( self.taskname, config_util.getDATA(one_input['grisim']))) raise aXeError(err_msg)
def __init__(self, grisim="", objcat="", dirim="", config="", dmag=None, **params): if grisim: self.grisim = config_util.getDATA(grisim) else: raise ValueError("No grisim image specified for axeprep") self.objcat = config_util.getDATA(objcat) _log.info("\n**Using object catalog: {0}\n".format(self.objcat)) self.dirim = config_util.getDATA(dirim) self.config = config self.dmag = dmag self.params = params # store the master background if 'master_bck' in params: self.master_bck = config_util.getCONF(params['master_bck'])
def _get_dirname_information(self, dirname=None, config="", grisim="", grism_extinfo=None, dir_hdu=None): """Determine the direct image information. Parameters ---------- dirname : str Diretory name config : str The name of the config file grisim : str The name of the grisim image grism_extinfo : dict Dictionary of header information dir_hdu : fits.HDU FITS header data unit Returns ------- A tuple of the direct image name and a dictionary of extension information """ # check whether ANY direct image information exists if ((dirname is None) and (dir_hdu is None)): # set the grism image as direct image dirname = grisim dirname_extinfo = grism_extinfo elif ((dirname is not None) and (dir_hdu is None)): # load the configuration file; # determine the extension information conf = configfile.ConfigFile(getCONF(config)) dirname_extinfo = get_ext_info(getDATA(grisim), conf) del conf elif ((dirname is not None) and (dir_hdu is not None)): # make by hand the extension information dirname_extinfo = {'axe_ext': dir_hdu, 'fits_ext': dir_hdu - 1} else: # error and out err_msg = ("Specifying NO direct image but a direct image HDU: " "{0:d} makrs NO sense!".format(dir_hdu)) raise aXeError(err_msg) # return the name and the extension info return dirname, dirname_extinfo
def check_simdirim_input(self, incat, config, tpass_direct, model_spectra, model_images, nx, ny, exptime, bck_flux): """Does basic checks on the parameters The method checks whether all input values are reasonable, e.g. the exposure time and background flux >= 0.0 and similar. Input files are checked for existence. Also the input type is checked for the numbers. Parameters ---------- incat: str name of model object table config: str aXe configuration file name tpass_direct: str total passband file model_spectra: str name of model spectra model_images: str name of model images nx: int number of pixels in x ny: int number of pixels in y exptime: float exposure time bck_flux: float flux in background """ # do the setup config_util.axe_setup(axesim=True) # check the existence of the # model object table if not os.path.isfile(config_util.getDATA(incat)): error_message = ( "The Model Object Table does not exist: {0}".format( config_util.getDATA(incat))) raise aXeSIMError(error_message) # check the existence of the # axe configuration file if not os.path.isfile(config_util.getCONF(config)): error_message = ( "The aXe configuration file does not exist: {0}".format( config_util.getCONF(config))) raise aXeSIMError(error_message) else: # load the aXe configuration file conf = configfile.ConfigFile(config_util.getCONF(config)) # make the internal checks n_sens = conf.check_files(check_glob=False) # make sure there is # at least one sens. file if n_sens < 1: error_message = ("There must be at least one sensitivity " "file in: {0}".format( config_util.getCONF(config))) raise aXeSIMError(error_message) # check the existence of the # total passband file if not os.path.isfile(config_util.getSIMDATA(tpass_direct)): error_message = ( "The total passband file does not exist: {0}".format( config_util.getSIMDATA(tpass_direct))) raise aXeSIMError(error_message) if model_spectra is not None: # check the existence of the # model spectra file if not os.path.isfile(config_util.getDATA(model_spectra)): error_message = ( "The model spectra file does not exist: {0}".format( config_util.getDATA(config))) raise aXeSIMError(error_message) if model_images is not None: # check the existence of the # model images file if not os.path.isfile(config_util.getDATA(model_images)): error_message = ( "The model images file does not exist: {0}".format( config_util.getDATA(config))) raise aXeSIMError(error_message) # check the nx-value if ((nx is not None) and (nx <= 0.0)): error_message = ("Value for 'nx' or 'nx_dir' must be positive: " "{0:s}".format(str(nx))) raise aXeSIMError(error_message) # check the ny-value if ((ny is not None) and (ny <= 0)): error_message = ("Value for 'ny' or 'ny_dir' must be positive: " "{0:s}".format(str(ny))) raise aXeSIMError(error_message) # check the exptime-value if ((exptime is not None) and (exptime < 0)): error_message = ("Value for 'exptime' or 'exptime_dir' must be " "positive: {0:s}".format(str(exptime))) raise aXeSIMError(error_message) if bck_flux is not None: # check the bck_flux-value try: # convert to float bck = float(bck_flux) # check for positive value if bck < 0: error_message = ("Value for 'bck_flux' or 'bck_flux_dir'" " must be positive: {0:s}".format( str(bck_flux))) raise aXeSIMError(error_message) # catch a string except ValueError: # check for existence of file if not os.path.isfile(config_util.getCONF(bck_flux)): error_message = ( "The background file does not exist: {0}".format( config_util.getCONF(bck_flux))) raise aXeSIMError(error_message)
def check_simdispim_input(self, incat, config, lambda_psf, model_spectra, model_images, nx, ny, exptime, bck_flux, extraction, extrfwhm, orient, slitless_geom, adj_sens): """Does basic checks on the parameters The method checks whether all input values are reasonable, e.g. the exposure time and background flux >= 0.0 and similar. Input files are checked for existence. Also the input type is checked for the numbers. Parameters ---------- incat: str name of model object table config: str aXe configuration file name lambda_psf: float wavelength the object shapes were determined at model_spectra: str name of model spectra model_images: str name of model images nx: int number of pixels in x ny: int number of pixels in y exptime: float exposure time bck_flux: float flux in background extraction: bool flag for default extraction extrfwhm: float multiplier for extraction width orient: bool flag for tilted extraction slitless_geom: bool flag for slitless optimized extraction adj_sens: bool flag for adjusted flux conversion """ # do the setup config_util.axe_setup(axesim=True) # check the existence of the # model object table if not os.path.isfile(config_util.getDATA(incat)): msg = ("The Model Object Table does not exist: {}".format( config_util.getDATA(incat))) raise aXeSIMError(msg) # check the existence of the # axe configuration file if not os.path.isfile(config_util.getCONF(config)): msg = ("The aXe configuration file does not exist: {}".format( config_util.getCONF(config))) raise aXeSIMError(msg) else: # load the aXe configuration file conf = configfile.ConfigFile(config_util.getCONF(config)) # make the internal checks n_sens = conf.check_files(check_glob=False) # make sure there is # at least one sens. file if n_sens < 1: msg = ("There must be at least one sensitivity file in: {}". format(config_util.getCONF(config))) raise aXeSIMError(msg) # check whether the configuration files # allows the requested extraction if extraction and (slitless_geom or adj_sens): extr_ready = conf.confirm_extrkeys() # error and out if not extr_ready: msg = ("It is not possible to perform the requested" "extraction. The likely cause is that the configuration" "file does NOT contain the keywords 'POBJSIZE' or " "'SMFACTOR' or their values are NOT reasonable " "(e.g. <0.0)!") raise aXeSIMError(msg) # check the lambda_psf-value if ((lambda_psf is not None) and (lambda_psf <= 0.0)): msg = ("Value for 'lambda_psf' must be positive: {0:s}".format( str(lambda_psf))) raise aXeSIMError(msg) if (model_spectra is not None): # check the existence of the # model spectra file if not os.path.isfile(config_util.getDATA(model_spectra)): msg = ("The model spectra file does not exist: {}".format( config_util.getDATA(model_spectra))) raise aXeSIMError(msg) if model_images is not None: # check the existence of the # model images file if not os.path.isfile(config_util.getDATA(model_images)): msg = ("The model images file does not exist: ".format( config_util.getDATA(model_images))) raise aXeSIMError(msg) # check the nx-value if ((nx is not None) and (nx <= 0.0)): msg = ("Value for 'nx' or 'nx_disp' must be positive: {0:g}". format(nx)) raise aXeSIMError(msg) # check the ny-value if ((ny is not None) and (ny <= 0)): error_message = ("Value for 'ny' or 'ny_disp' must be " "positive: {0:g}".format(ny)) raise aXeSIMError(error_message) # check the exptime-value if ((exptime is not None) and (exptime < 0)): error_message = ("Value for 'exptime' or 'exptime_disp' must be " "positive: {0:g}".format(exptime)) raise aXeSIMError(error_message) # the extraction width must be set! if not extrfwhm: error_message = ("Value for 'extrfwhm' must not be 0.0 to create" "PETs, but extrfwhm={0:0.1f}!".format(extrfwhm)) raise aXeSIMError(error_message) # negative extraction width is significant ONLY # if orient="NO" if orient and extrfwhm < 0.0: error_message = ( "Negative width extrfwhm={0:0.1f} together with " "extraction orient=yes does NOT make sense!".format(extrfwhm)) raise aXeSIMError(error_message) try: # convert to float bck = float(bck_flux) # check for positive value if bck < 0: error_message = ("Value for 'bck_flux' or 'bck_flux_disp'" " most be positive: {0:g}".format(bck_flux)) raise aXeSIMError(error_message) # catch a string except ValueError: # check for existence of file if not os.path.isfile(config_util.getCONF(bck_flux)): error_message = ( "The background file does not exist: {0}".format( config_util.getCONF(bck_flux))) raise aXeSIMError(error_message)
def tofits(self, fitsname, indata_copy=0): """ Converts and stores the spectra in a fits file Converts all images stored in the class instance to a multi-extension fits image with a name gvien as input. A flagg indicates whether, besides the normal output to AXE_OUTSIM_PATH, a copy to AXE_IMAGE_PATH is desired. Parameters ---------- fitsname: str name for the MEX fits file indata_copy: int flag to save also a copy """ # create a HDU list hdulist = fits.HDUList() # create an empty primary HDU phdu = fits.PrimaryHDU() # put the primary to the list hdulist.append(phdu) # give a linefeed print() # check whther the fitsname # ends with '.fits' if ('.fits' not in fitsname[-5:]): fitsname += '.fits' # initialize an index index = 0 # go over all spectra for ima in self._imalist: # enhance the counter index += 1 # append the the image HDU # to the output fits hdulist.append(ima.imgHDU) # print what you do on the screen print("Adding: {0:s} to {1:s}, ext: {2:s}" .format(os.path.basename(ima.filename), fitsname, str(index))) # delete older versions # of the fits name if os.path.isfile(getOUTSIM(fitsname)): os.unlink(getOUTSIM(fitsname)) print("\nWriting images to file: {0:s} ..." .format(getOUTSIM(fitsname))) # write it to fits hdulist.writeto(getOUTSIM(fitsname)) # give an end notice print('Done') # check whether a copy # is needed at AXE_IMAGE_PATH directory if indata_copy: # delete older versions # of the fits name if os.path.isfile(getDATA(fitsname)): os.unlink(getDATA(fitsname)) print("Writing images to file: {0:s} ..." .format(getDATA(fitsname))) # write it to fits hdulist.writeto(getDATA(fitsname)) # give an end notice print('Done') # add an extra linefeed print('')