def makeSACat(self, imgfile, extref=False): """ Makes a catalog of objects to be used for input to superalign from a external reference catalog. Catalog should be of form: ID RA(deg) Dec(deg) Mag Output appends _sa """ if extref: wcs = self.refwcs else: wcs = HSTWCS(imgfile) cat = imgfile.replace('.fits', '.cat') outcat = imgfile.replace('.fits', '_sa.cat') data = ascii.read(cat, names=['id', 'ra', 'dec', 'x', 'y', 'mag']) arcs = (wcs.all_world2pix(zip(data['ra'], data['dec']), 1) - [wcs.naxis1/2, wcs.naxis2/2])*wcs.pscale ascii.write([data['id'], arcs[:,0], arcs[:,1], data['mag']], outcat, format='no_header') return
def makeSACat(self, imgfile, extref=False): """ Makes a catalog of objects to be used for input to superalign from a external reference catalog. Catalog should be of form: ID RA(deg) Dec(deg) Mag Output appends _sa """ if extref: wcs = self.refwcs else: wcs = HSTWCS(imgfile) cat = imgfile.replace('.fits', '.cat') outcat = imgfile.replace('.fits', '_sa.cat') data = ascii.read(cat, names=['id', 'ra', 'dec', 'x', 'y', 'mag']) arcs = (wcs.all_world2pix(list(zip(data['ra'], data['dec'])), 1) - [wcs.naxis1 / 2, wcs.naxis2 / 2]) * wcs.pscale ascii.write([data['id'], arcs[:, 0], arcs[:, 1], data['mag']], outcat, format='no_header', overwrite=True) return
def refineShiftMCMC(drzfile): """ Refine shifts using MCMC """ dsn = drzfile[:9] wcs = HSTWCS(fits.open(drzfile)) wcsn = fits.getval(drzfile, 'wcsname') try: refcat = np.loadtxt('%s_drz_sci_sa_ref_match.cat' % dsn, usecols=(1, 2)) imgcat = np.loadtxt('%s_drz_sci_sa_match.cat' % dsn, usecols=(1, 2)) refcatw = wcs.all_world2pix(refcat, 1) imgcatw = wcs.all_world2pix(imgcat, 1) ox, oy = wcs.wcs.crpix.tolist() offset, err = mcmcShifts.findOffsetMCMC(imgcatw, refcatw, maxShift=(10, 10, 0.3), rotOrigin=(ox, oy), precision=0.01, visualize=False) print(drzfile, offset, err) dxp, dyp, dtp = offset updatehdr.updatewcs_with_shift(drzfile, drzfile, wcsname='DRZWCS', xsh=dxp, ysh=dyp, rot=dtp, scale=1.0, force=True) return offset except UserWarning: pass
class MakeCat(object): def __init__(self, refimg): super(MakeCat, self).__init__() self.refimg = str(refimg) self.refwcs = HSTWCS(self.refimg) def getInstDet(self, imgfile): """Get the instrument/detector of an HST image (e.g. acswfc)""" hdr = fits.getheader(imgfile) return '%s%s' % (hdr['instrume'].lower(), hdr['detector'].lower()) def findSources(self, inputfile, outputfile, instdet, weightfile=None, extref=False, **sconfig): """Finds objects in image""" # Set up SExtractor sex = sextractor.SExtractor() # Load the default configuration if instdet == 'acswfc' or instdet == 'wfc3uvis': for k, v in _sex_config_ACSWFC.items(): sex.config[k] = v if instdet == 'wfc3ir': for k, v in _sex_config_WFC3IR.items(): sex.config[k] = v if sconfig: # Load any runtime configuration for k, v in sconfig.items(): sex.config[k] = v if weightfile: sex.config['WEIGHT_IMAGE'] = weightfile sex.config['WEIGHT_TYPE'] = 'MAP_WEIGHT' sex.config['WEIGHT_GAIN'] = 'N' sex.config['CATALOG_NAME'] = outputfile # Load default parameters' sex.config['PARAMETERS_LIST'] = [] for p in _sex_parms: sex.config['PARAMETERS_LIST'].append(p) # Run SExtractor sex.run(inputfile) cfg = _sa_config[instdet] low_limit = cfg['low_limit'] hi_limit = cfg['hi_limit'] objectlist = [] for l in [i.split() for i in open(outputfile).readlines()]: if l[0] != '#': x = float(l[1]) y = float(l[2]) ra = float(l[3]) if l[4].startswith('+'): dec = float(l[4][1:]) else: dec = float(l[4]) aa = float(l[5]) ba = float(l[6]) r = ba / aa m = float(l[7]) f = float(l[8]) fwhm = float(l[9]) if min(2.3 * ba, fwhm) >= low_limit and max( 2.3 * aa, fwhm) < hi_limit and r > cfg['min_axis_ratio']: objectlist.append(Object(x, y, ra, dec, r, m, f)) return objectlist def removeCloseSources(self, objectlist): """Removes objects from catalog with multiple close detections""" for objecti in objectlist: for objectj in objectlist: dist = ((objecti.x - objectj.x)**2 + (objecti.y - objectj.y)**2)**0.5 if dist < 10 and dist > 0: if objecti.mag < objectj.mag: objectj.nextToBig = 1 else: objecti.nextToBig = 1 objectlist_keep = [] for objecti in objectlist: if not objecti.nextToBig: objectlist_keep.append(objecti) else: print('Excluding object at %i %i' % (objecti.x, objecti.y)) return objectlist_keep def makeCat(self, imgfile, instdet, weightfile=None, extref=False): """Makes a catalog of objects to be used for input to superalign and creates a DS9 region file of objects""" imgfile_cat = '%s_all.cat' % imgfile.replace('.fits', '') imgfile_reg = '%s_all.reg' % imgfile.replace('.fits', '') o_radec = [] ext = 0 objectlist = self.findSources('%s[%s]' % (imgfile, ext), imgfile_cat, instdet, weightfile, extref=extref) cleanobjectlist = self.removeCloseSources(objectlist) print('Found %s sources' % len(cleanobjectlist)) wcs = HSTWCS(str(imgfile)) for obj in cleanobjectlist: sky = wcs.all_pix2world(np.array([[obj.x, obj.y]]), 1) o_radec.append([obj.ra[0], obj.dec[0]]) obj.ra = sky[0][0] obj.dec = sky[0][1] # Write out a ds9 region file of object selected for alignment regout = open(imgfile_reg, 'w') regout.write( 'global color=green font="helvetica 8 normal" edit=1 move=1 delete=1 include=1 fixed=0\nfk5\n' ) for i, rd in enumerate(o_radec): oid = i + 1 regout.write('circle(%s,%s,%s") # color=%s text={%s}\n' % (rd[0], rd[1], 0.5, 'red', oid)) regout.close() # Now we need to write out the catalog in the reference image coords in arcseconds with respect to center of the image catout = open(imgfile_cat, 'w') for i, obj in enumerate(cleanobjectlist): oid = i + 1 catout.write('%i %.9f %.9f %.4f %.4f %.4f\n' % (oid, obj.ra, obj.dec, obj.x, obj.y, obj.mag)) catout.close() return def makeSACat(self, imgfile, extref=False): """ Makes a catalog of objects to be used for input to superalign from a external reference catalog. Catalog should be of form: ID RA(deg) Dec(deg) Mag Output appends _sa """ if extref: wcs = self.refwcs else: wcs = HSTWCS(imgfile) cat = imgfile.replace('.fits', '.cat') outcat = imgfile.replace('.fits', '_sa.cat') data = ascii.read(cat, names=['id', 'ra', 'dec', 'x', 'y', 'mag']) arcs = (wcs.all_world2pix(list(zip(data['ra'], data['dec'])), 1) - [wcs.naxis1 / 2, wcs.naxis2 / 2]) * wcs.pscale ascii.write([data['id'], arcs[:, 0], arcs[:, 1], data['mag']], outcat, format='no_header', overwrite=True) return def makeSACatExtRef(self, refcat, outcat): """ Makes a catalog of objects to be used for input to superalign from a external reference catalog. Catalog should be of form: ID RA(deg) Dec(deg) Mag """ data = ascii.read(refcat, names=['id', 'ra', 'dec', 'x', 'y', 'mag']) arcs = ( self.refwcs.all_world2pix(list(zip(data['ra'], data['dec'])), 1) - [self.refwcs.naxis1 / 2, self.refwcs.naxis2 / 2 ]) * self.refwcs.pscale ascii.write([data['id'], arcs[:, 0], arcs[:, 1], data['mag']], outcat, format='no_header', overwrite=True) return
def characterize_gaia_distribution(hap_obj, log_level=logutil.logging.NOTSET): """Statistically describe distribution of GAIA sources in footprint. Computes and writes the file to a json file: - Number of GAIA sources - X centroid location - Y centroid location - X offset of centroid from image center - Y offset of centroid from image center - X standard deviation - Y standard deviation - minimum closest neighbor distance - maximum closest neighbor distance - mean closest neighbor distance - standard deviation of closest neighbor distances Parameters ---------- hap_obj : drizzlepac.hlautils.Product.FilterProduct hap product object to process log_level : int, optional The desired level of verboseness in the log statements displayed on the screen and written to the .log file. Default value is 'NOTSET'. Returns ------- Nothing """ log.setLevel(log_level) # get table of GAIA sources in footprint gaia_table = generate_gaia_catalog( hap_obj, columns_to_remove=['mag', 'objID', 'GaiaID']) # if log_level is either 'DEBUG' or 'NOTSET', write out GAIA sources to DS9 region file if log_level <= logutil.logging.DEBUG: reg_file = "{}_gaia_sources.reg".format(hap_obj.drizzle_filename[:-9]) gaia_table.write(reg_file, format='ascii.csv') log.debug( "Wrote GAIA source RA and Dec positions to DS9 region file '{}'". format(reg_file)) # convert RA, Dec to image X, Y outwcs = HSTWCS(hap_obj.drizzle_filename + "[1]") x, y = outwcs.all_world2pix(gaia_table['RA'], gaia_table['DEC'], 1) # compute stats for the distribution centroid = [np.mean(x), np.mean(y)] centroid_offset = [] for idx in range(0, 2): centroid_offset.append(outwcs.wcs.crpix[idx] - centroid[idx]) std_dev = [np.std(x), np.std(y)] # Find straight-line distance to the closest neighbor for each GAIA source xys = np.array([x, y]) xys = xys.reshape(len(x), 2) tree = KDTree(xys) neighborhood = tree.query(xys, 2) min_seps = np.empty([0]) for sep_pair in neighborhood[0]: min_seps = np.append(min_seps, sep_pair[1]) # add statistics to out_dict out_dict = collections.OrderedDict() out_dict["units"] = "pixels" out_dict["Number of GAIA sources"] = len(gaia_table) axis_list = ["X", "Y"] title_list = [ "centroid", "offset of centroid from image center", "standard deviation" ] for item_value, item_title in zip([centroid, centroid_offset, std_dev], title_list): for axis_item in enumerate(axis_list): log.info("{} {} ({}): {}".format(axis_item[1], item_title, out_dict["units"], item_value[axis_item[0]])) out_dict["{} {}".format(axis_item[1], item_title)] = item_value[axis_item[0]] min_sep_stats = [ min_seps.min(), min_seps.max(), min_seps.mean(), min_seps.std() ] min_sep_title_list = [ "minimum closest neighbor distance", "maximum closest neighbor distance", "mean closest neighbor distance", "standard deviation of closest neighbor distances" ] for item_value, item_title in zip(min_sep_stats, min_sep_title_list): log.info("{} ({}): {}".format(item_title, out_dict["units"], item_value)) out_dict[item_title] = item_value # write catalog to HapDiagnostic-formatted .json file. diag_obj = du.HapDiagnostic(log_level=log_level) diag_obj.instantiate_from_hap_obj( hap_obj, data_source="{}.characterize_gaia_distribution".format(__taskname__), description= "A statistical characterization of the distribution of GAIA sources in image footprint" ) diag_obj.add_data_item(out_dict, "distribution characterization statistics") diag_obj.write_json_file(hap_obj.drizzle_filename[:-9] + "_svm_gaia_distribution_characterization.json", clobber=True)
def make_grismcat(self, drizzle_image="", catalog=None, hard_angle=False, hard_angle_value=90.): """Make the grism catalog. The method creates a new input object list. The positional information on objects in a drizzled image are projected back into the coordinate system of one input image. A selection is done on the basis of the projected coordinates, and the selected objects are stored to a new IOL file with an updated object angle that is in the projected coordinate system. Parameters ---------- drizzle_image : str The name of the drizzled mosaic image that the catalog was constructed from. catalog : astropy.table.Table A the master catalog which will be used to create the dither image catalog with updated angles hard_angle : bool This will always set the extraction angle to 90degrees. hard_angle_value : float If a specified angle for extraction is preferred then this is the value to use and will replace THETA_IMAGE in the output catalog. It's currently specified in degrees, and is converted appropriately for whatever units are used in the catalog itself. Returns ------- Nothing Notes ----- This method previous took the names of two text files that contained the displayed position and angles calculated from the catalog entry. That functionality has been moved to memory since awtran is no longer in use. The catalog is read directly. """ if not drizzle_image: raise aXeError("IOLPREP: No drizzle image specified.") if catalog is None: raise aXeError("IOLPREP: No input catalog provided.") if not isinstance(catalog, Table): raise aXeError( "IOLPREP: Expected input catalog to be an astropy table") _log.info("\n >>>> Working on Input Object List: {0:s} >>>>\n".format( self.iol_name)) # now translate ra dec to new image pixel points # this must go through the wcs of the mosaic image # and then through the wcs for the individual image _log.info( "Converting coordinates using wcs from grism image {0}\n".format( self.filename)) trad = catalog['THETA_IMAGE'] xcat = catalog['X_IMAGE'] ycat = catalog['Y_IMAGE'] # translate to degrees if necessary if catalog['THETA_IMAGE'].unit.name == 'deg': translate = True elif catalog['THETA_IMAGE'].unit.name == 'rad': translate = False hard_angle_value = math.radians(hard_angle_value) else: raise aXeError("Unknown unit on THETA_IMAGE in input catalog") # 10.0 is a made up scaling length to use to # get the angle precision shifted_x = [] shifted_y = [] for t, x, y in zip(trad, xcat, ycat): if translate: angle = math.radians(t) shifted_x.append(x + 10.0 * math.cos(angle)) shifted_y.append(y + 10.0 * math.sin(angle)) # translate the catalog (x, y) to (ra, dec) mosaic_image_wcs = HSTWCS(drizzle_image, ext=1) mosaic_image_ra, mosaic_image_dec = mosaic_image_wcs.wcs_pix2world( shifted_x, shifted_y, 1) # compute the location in the dithered image using the shifted coords dither_image_wcs = HSTWCS(self.filename) dither_image_x, dither_image_y = dither_image_wcs.all_world2pix( mosaic_image_ra, mosaic_image_dec, 1) trans_ra, trans_dec = mosaic_image_wcs.wcs_pix2world(xcat, ycat, 1) trans_x, trans_y = dither_image_wcs.all_world2pix( trans_ra, trans_dec, 1) output_catalog = deepcopy(catalog) for row in range(len(catalog) - 1, -1, -1): x = trans_x[row] y = trans_y[row] # check whether the object position is # in the range to be stored if ((self.dim_info[0] <= x <= self.dim_info[1]) and (self.dim_info[2] <= y <= self.dim_info[3])): # compute the new object angle dx = xcat[row] - x dy = ycat[row] - y angle = math.atan2(dy, dx) # compute local angle change # return to degrees for catalog if necessary if translate: angle = math.degrees(angle) # _log.info("dx {} dy {} angle {} x,y: ({},{})\n".format(dx, dy, angle, x, y)) # fill in the new position and angle output_catalog['X_IMAGE'][row] = trans_x[row] output_catalog['Y_IMAGE'][row] = trans_y[row] if hard_angle: output_catalog['THETA_IMAGE'][row] = hard_angle_value else: output_catalog['THETA_IMAGE'][row] = angle else: _log.info( f"{x}\t{y}\t{self.dim_info}\t{output_catalog['NUMBER'][row]}" ) output_catalog.remove_row(row) # save the new IOL, this is done especially for the C # code which is expecting Source Extractor style catalog # files. Decided to keep the output here consistent with # the C code so that it can continue to be used separately. # numbers start at 1 not zero. The output formatting allows # the astropy.sextractor formatter to read the catalog file. # There isn't currently an astropy writer for that format. if os.access(self.iol_name, os.F_OK): os.remove(self.iol_name) of = open(self.iol_name, 'w') for num, name in zip(range(len(output_catalog.colnames) + 1), output_catalog.colnames): of.write("# {0:d} {1:s}\t\t{2:s}\t\t[{3:s}]\n".format( num + 1, name, output_catalog[name].description, str(output_catalog[name].unit))) output_catalog.write(of, format='ascii.no_header', overwrite=False) of.close() _log.info( f"\n >>>> Catalog: {self.iol_name} written with {len(catalog)} entries.>>>> \n" )
class MakeCat(object): def __init__(self, refimg): super(MakeCat, self).__init__() self.refimg = str(refimg) self.refwcs = HSTWCS(self.refimg) def getInstDet(self, imgfile): """Get the instrument/detector of an HST image (e.g. acswfc)""" hdr = fits.getheader(imgfile) return '%s%s' % (hdr['instrume'].lower(), hdr['detector'].lower()) def findSources(self, inputfile, outputfile, instdet, weightfile=None, extref=False, **sconfig): """Finds objects in image""" # Set up SExtractor sex = sextractor.SExtractor() # Load the default configuration if instdet == 'acswfc' or instdet == 'wfc3uvis': for k,v in _sex_config_ACSWFC.iteritems(): sex.config[k] = v if instdet == 'wfc3ir': for k,v in _sex_config_WFC3IR.iteritems(): sex.config[k] = v if sconfig: # Load any runtime configuration for k,v in sconfig.iteritems(): sex.config[k] = v if weightfile: sex.config['WEIGHT_IMAGE'] = weightfile sex.config['WEIGHT_TYPE'] = 'MAP_WEIGHT' sex.config['WEIGHT_GAIN'] = 'N' sex.config['CATALOG_NAME'] = outputfile # Load default parameters' sex.config['PARAMETERS_LIST'] = [] for p in _sex_parms: sex.config['PARAMETERS_LIST'].append(p) # Run SExtractor sex.run(inputfile) cfg = _sa_config[instdet] low_limit = cfg['low_limit'] hi_limit = cfg['hi_limit'] objectlist = [] for l in [i.split() for i in open(outputfile).readlines()]: if l[0] != '#': x = float(l[1]) y = float(l[2]) ra = float(l[3]) if l[4].startswith('+'): dec = float(l[4][1:]) else: dec = float(l[4]) aa = float(l[5]) ba = float(l[6]) r = ba / aa m = float(l[7]) f = float(l[8]) fwhm = float(l[9]) if min(2.3 * ba, fwhm) >= low_limit and max(2.3 * aa, fwhm) < hi_limit and r > cfg['min_axis_ratio']: objectlist.append(Object(x, y, ra, dec, r, m, f)) return objectlist def removeCloseSources(self, objectlist): """Removes objects from catalog with multiple close detections""" for objecti in objectlist: for objectj in objectlist: dist = ((objecti.x - objectj.x) ** 2 + (objecti.y - objectj.y) ** 2) ** 0.5 if dist < 10 and dist > 0: if objecti.mag < objectj.mag: objectj.nextToBig = 1 else: objecti.nextToBig = 1 objectlist_keep = [] for objecti in objectlist: if not objecti.nextToBig: objectlist_keep.append(objecti) else: print 'Excluding object at %i %i' % (objecti.x, objecti.y) return objectlist_keep def makeCat(self, imgfile, instdet, weightfile=None, extref=False): """Makes a catalog of objects to be used for input to superalign and creates a DS9 region file of objects""" imgfile_cat = '%s.cat' % imgfile.replace('.fits', '') imgfile_reg = '%s.reg' % imgfile.replace('.fits', '') o_radec = [] ext = 0 objectlist = self.findSources('%s[%s]' % (imgfile, ext), imgfile_cat, instdet, weightfile, extref=extref) cleanobjectlist = self.removeCloseSources(objectlist) print 'Found %s sources' % len(cleanobjectlist) wcs = HSTWCS(str(imgfile)) for obj in cleanobjectlist: sky = wcs.all_pix2world(np.array([[obj.x, obj.y]]), 1) o_radec.append([obj.ra[0], obj.dec[0]]) obj.ra = sky[0][0] obj.dec = sky[0][1] # Write out a ds9 region file of object selected for alignment regout = open(imgfile_reg, 'w') regout.write('global color=green font="helvetica 8 normal" edit=1 move=1 delete=1 include=1 fixed=0\nfk5\n') for i,rd in enumerate(o_radec): oid = i+1 regout.write('circle(%s,%s,%s") # color=%s text={%s}\n' % (rd[0], rd[1], 0.5, 'red', oid)) regout.close() # Now we need to write out the catalog in the reference image coords in arcseconds with respect to center of the image catout = open(imgfile_cat, 'w') for i,obj in enumerate(cleanobjectlist): oid = i+1 catout.write('%i %.9f %.9f %.4f %.4f %.4f\n' % (oid, obj.ra, obj.dec, obj.x, obj.y, obj.mag)) catout.close() return def makeSACat(self, imgfile, extref=False): """ Makes a catalog of objects to be used for input to superalign from a external reference catalog. Catalog should be of form: ID RA(deg) Dec(deg) Mag Output appends _sa """ if extref: wcs = self.refwcs else: wcs = HSTWCS(imgfile) cat = imgfile.replace('.fits', '.cat') outcat = imgfile.replace('.fits', '_sa.cat') data = ascii.read(cat, names=['id', 'ra', 'dec', 'x', 'y', 'mag']) arcs = (wcs.all_world2pix(zip(data['ra'], data['dec']), 1) - [wcs.naxis1/2, wcs.naxis2/2])*wcs.pscale ascii.write([data['id'], arcs[:,0], arcs[:,1], data['mag']], outcat, format='no_header') return def makeSACatExtRef(self, refcat, outcat): """ Makes a catalog of objects to be used for input to superalign from a external reference catalog. Catalog should be of form: ID RA(deg) Dec(deg) Mag """ data = ascii.read(refcat, names=['id', 'ra', 'dec', 'x', 'y', 'mag']) arcs = (self.refwcs.all_world2pix(zip(data['ra'], data['dec']), 1) - [self.refwcs.naxis1/2, self.refwcs.naxis2/2])*self.refwcs.pscale ascii.write([data['id'], arcs[:,0], arcs[:,1], data['mag']], outcat, format='no_header') return
def make_grismcat(self, data_name, data_angle, grism_cat, mdrizzle_image, odd_signs=None): """ Input: data_name - filename of the position data data_angle - filename of the displaced positions grism_cat - refernece to the axecat object mdrizzle_image - name of the multidrizzled image Return: - Description: The method creates a new input object list. The positional information on objects in a multidrizzled image are projected back into the coordinate system of one nput image. A selection is done on the basis of the projected coordinates, and the selected objects are stored to a new IOL file """ import os import os.path import math from . import awtran print('') print(' >>>> Working on Input Object List: ', self.iol_name, '>>>>') print('') #------------------------------------------------------------------------ # newer faster version from aXe-1.7 on: # if (self.useMdriz): print("Using multidrizzle coeffs for coordinate transformation\n") dir_pts = awtran.b(mdrizzle_image + "[SCI]", self.header_name, List=data_name) ang_pts = awtran.b(mdrizzle_image + "[SCI]", self.header_name, List=data_angle) else: #use HSTWCS instead for the astrodrizzle image #read in the data_name file # awtran gives back this format: all_out.append("%10.3f %10.3f %10.3f %10.3f" % (xin,yin,xout,yout)) hstimage = HSTWCS(mdrizzle_image, ext=1) datanamefile = open(data_name, 'r') datapoints = datanamefile.readlines() data = [list(map(float, line.split())) for line in datapoints] skypoints = hstimage.all_pix2world( data, 1) #trans points are now in ra and dec from mdrizzle_image #now translate to new image pixel points newhstimage = HSTWCS(self.header_name) trans_pts = newhstimage.all_world2pix(skypoints[:, 0], skypoints[:, 1], 1) #pix2sky returns (2,len) array of points, reshape for what awtran returned dir_pts = list() for i in range(0, len(trans_pts[0])): dir_pts.append("%10.8g %10.8g %10.8g %10.8g" % (trans_pts[0][i], trans_pts[1][i], skypoints[i, 0], skypoints[i, 1])) #now the same for the ang file points angfile = open(data_angle, 'r') angpoints = angfile.readlines() data = [list(map(float, line.split())) for line in datapoints] ang_pts = list() for i in range(0, len(trans_pts[0])): ang_pts.append( "%10.8g %10.8g %10.8g %10.8g" % (data[i][0], data[i][1], trans_pts[0][i], trans_pts[1][i])) # delete the first element, # which contains a description only # but only for the multidrizzle version #------------------------------------------------------------------------- if self.useMdriz: del (dir_pts[0]) del (ang_pts[0]) # start the reverse index; # iterate over all objects r_index = len(dir_pts) - 1 for index in range(grism_cat.nrows): # extract the projected object positions x_ori = float(dir_pts[r_index].split()[0]) y_ori = float(dir_pts[r_index].split()[1]) # check whether the object position is # range to be stored if x_ori >= self.dim_info[0] and x_ori <= self.dim_info[1] and \ y_ori >= self.dim_info[2] and y_ori <= self.dim_info[3]: # extract the displaced projected position x_ang = float(ang_pts[r_index].split()[0]) y_ang = float(ang_pts[r_index].split()[1]) # compute the new object angle dx = x_ang - x_ori dy = y_ang - y_ori angle = math.atan2(dy, dx) / math.pi * 180.0 # Note: this correction is only necessary # as long as there are two different # flavors in pydrizzle and iraf.drizzle if (self.useMdriz): if odd_signs != None: if odd_signs[0]: x_ori -= 0.5 if odd_signs[1]: y_ori -= 0.5 # fill in the new position and angle grism_cat['X_IMAGE'][r_index] = x_ori grism_cat['Y_IMAGE'][r_index] = y_ori grism_cat['THETA_IMAGE'][r_index] = angle # delete outside entries else: grism_cat.delete(r_index) # decrease the reverse index r_index -= 1 # save the new IOL grism_cat.writeto(self.iol_name) print('') print(' >>>> Catalog: ', self.iol_name, 'written with ', grism_cat.nrows, 'entries.>>>>') print('')