def _construct_CCD(hdulist, headers, filename): SEG_DATASIZE = headers['SEG_DATASIZE'] SEG_SIZE = headers['SEG_SIZE'] # Traverse the amplifier headers new_data = np.zeros(shape=(headers['DATASIZE']['y'], headers['DATASIZE']['x']), dtype=np.float32) for amps_row in headers['BOUNDARY']: for amp in amps_row: hdu = hdulist[amp['index']] data_sec = getCoord((hdu.header)['DATASEC']) det_sec = getCoord((hdu.header)['DETSEC']) data_slice_x = convert_slice(data_sec['start_X'], data_sec['end_X']) data_slice_y = convert_slice(data_sec['start_Y'], data_sec['end_Y']) slice_x = convert_slice(det_sec['start_X'], det_sec['end_X']) slice_y = convert_slice(det_sec['start_Y'], det_sec['end_Y']) new_data[slice_y, slice_x] = (hdu.data)[data_slice_y, data_slice_x] new_hdu = fits.PrimaryHDU(new_data) new_hdulist = fits.HDUList([new_hdu]) new_hdulist.writeto(filename+"_mosaicked_trimmed"+".fits", clobber=True) new_data = np.zeros(shape=(headers['DETSIZE']['y'], headers['DETSIZE']['x']), dtype=np.float32) for amps_row in headers['BOUNDARY_OVERSCAN']: for amp in amps_row: data_slice_x = slice(SEG_SIZE['x']-1, None, -1) if amp['reverse_slice']['x'] else slice(0, SEG_SIZE['x']) data_slice_y = slice(SEG_SIZE['y']-1, None, -1) if amp['reverse_slice']['y'] else slice(0, SEG_SIZE['y']) start_X = (amp['x']//SEG_SIZE['x'])*SEG_SIZE['x'] start_Y = (amp['y']//SEG_SIZE['y'])*SEG_SIZE['y'] slice_x = slice(start_X, start_X+SEG_SIZE['x']) slice_y = slice(start_Y, start_Y+SEG_SIZE['y']) new_data[slice_y, slice_x] = (hdulist[amp['index']].data)[data_slice_y, data_slice_x] new_hdu = fits.PrimaryHDU(new_data) new_hdulist = fits.HDUList([new_hdu]) new_hdulist.writeto(filename+"_mosaicked_untrimmed"+".fits", clobber=True) return ["Created single-extension FITS file."]
def _get_Header_Info(imgHDUs): if not imgHDUs: raise RuntimeError("The given file is not a multi-extension FITS image.") # Get info from the first amplifier header. first_seg = imgHDUs[0] seg_dimension = [first_seg["NAXIS1"], first_seg["NAXIS2"]] DETSIZE = getDim(getCoord(first_seg["DETSIZE"])) # Assume 'DETSIZE' is same for all segments/amplifiers. # Sanity Check if (DETSIZE[0] % seg_dimension[0] != 0) and (DETSIZE[1] % seg_dimension[1] != 0): raise ValueError("Incorrect segment/amplifier dimension.") num_X, num_Y = DETSIZE[0] // seg_dimension[0], DETSIZE[1] // seg_dimension[1] num_amps = num_X * num_Y boundary = [[{} for x in range(num_X)] for y in range(num_Y)] boundary_overscan = [[{} for x in range(num_X)] for y in range(num_Y)] # Traverse the list of headers for i in range(num_amps): header = imgHDUs[i] seg_dimension = [header["NAXIS1"], header["NAXIS2"]] seg_detsec = getCoord(header["DETSEC"]) seg_datasec = getCoord(header["DATASEC"]) seg_datadim = getDim(seg_datasec) seg_bias_Size = getDim(getCoord(header["BIASSEC"])) # Segment/amplifier coordinates in a CCD. # Format: amplifier[Y][X] (origin at top left corner). # +----+----+----+----+----+----+----+----+ # | 00 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | # +----+----+----+----+----+----+----+----+ # | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | # +----+----+----+----+----+----+----+----+ seg_X, seg_Y = (seg_detsec["start_X"]) // seg_datadim[0], (seg_detsec["start_Y"]) // seg_datadim[1] seg_Y_converted = num_Y - 1 - seg_Y boundary[seg_Y_converted][seg_X] = convert_to_Box(seg_detsec) # Condition about X & Y slicing in segment data. is_Slice_Reverse = check_Reverse_Slicing(seg_detsec, seg_datasec) # Add correct offset for each segment. boundary[seg_Y_converted][seg_X]["EXTNAME"] = header["EXTNAME"] boundary_overscan[seg_Y_converted][seg_X] = { # NOTE: DS9 box region start from top left corner "x": seg_X * seg_dimension[0], "y": seg_Y * seg_dimension[1] + seg_datadim[1] - 1, "width": seg_datadim[0], "height": seg_datadim[1], "EXTNAME": header["EXTNAME"], } boundary_overscan[seg_Y_converted][seg_X]["x"] += ( seg_bias_Size[0] if is_Slice_Reverse["x"] else (min(seg_datasec["start_X"], seg_datasec["end_X"])) ) boundary_overscan[seg_Y_converted][seg_X]["y"] += ( (seg_dimension[1] - seg_datadim[1]) if is_Slice_Reverse["y"] else 0 ) boundary[seg_Y_converted][seg_X]["index"] = boundary_overscan[seg_Y_converted][seg_X]["index"] = i boundary[seg_Y_converted][seg_X]["reverse_slice"] = boundary_overscan[seg_Y_converted][seg_X][ "reverse_slice" ] = is_Slice_Reverse return { "DETSIZE": {"x": DETSIZE[0], "y": DETSIZE[1]}, "DATASIZE": {"x": num_X * seg_datadim[0], "y": num_Y * seg_datadim[1]}, "NUM_AMPS": {"num": num_amps, "x": num_X, "y": num_Y}, "SEG_SIZE": {"x": seg_dimension[0], "y": seg_dimension[1]}, "SEG_DATASIZE": {"x": seg_datadim[0], "y": seg_datadim[1]}, "BOUNDARY": boundary, "BOUNDARY_OVERSCAN": boundary_overscan, }