""" generate image header """ import numpy as np from astropy.io import fits import astropy.wcs as pywcs from scipy import math import random import os import sys def chara2digit(char): """ Function to judge and convert characters to digitals Parameters ---------- """ try: float(char) # for int, long and float except ValueError: pass return char else: data = float(char) return data def read_header_parameter(filename='global_header.param'): """ Function to read the header parameters Parameters ---------- """ name = [] value = [] description = [] for line in open(filename): line = line.strip("\n") arr = line.split('|') # csvReader = csv.reader(csvDataFile) # for arr in csvReader: name.append(arr[0]) value.append(chara2digit(arr[1])) description.append(arr[2]) # print(value) return name, value, description def rotate_CD_matrix(cd, pa_aper): """Rotate CD matrix Parameters ---------- cd: (2,2) array CD matrix pa_aper: float Position angle, in degrees E from N, of y axis of the detector Returns ------- cd_rot: (2,2) array Rotated CD matrix Comments -------- `astropy.wcs.WCS.rotateCD` doesn't work for non-square pixels in that it doesn't preserve the pixel scale! The bug seems to come from the fact that `rotateCD` assumes a transposed version of its own CD matrix. """ rad = np.deg2rad(-pa_aper) mat = np.zeros((2,2)) mat[0,:] = np.array([np.cos(rad),-np.sin(rad)]) mat[1,:] = np.array([np.sin(rad),np.cos(rad)]) cd_rot = np.dot(mat, cd) return cd_rot def Header_extention(xlen = 9232, ylen = 9216, gain = 1.0, readout = 5.0, dark = 0.02,saturation=90000, row_num = 1, col_num = 1): """ Creat an image frame for CCST with multiple extensions Parameters ---------- """ flag_ltm_x = [0,1,-1,1,-1] flag_ltm_y = [0,1,1,-1,-1] flag_ltv_x = [0,0,1,0,1] flag_ltv_y = [0,0,0,1,1] detector_size_x = int(xlen) detector_size_y = int(ylen) data_x = str(int(detector_size_x)) data_y = str(int(detector_size_y)) data_sec = '[1:'+data_x+',1:'+data_y+']' name = [] value = [] description = [] for k in range(1,2): # f = open("extension"+str(k)+"_image.param","w") j = row_num i = col_num ccdnum = str((j-1)*5+i) name = ['EXTNAME', 'BSCALE', 'BZERO', 'OBSID', 'CCDNAME', 'AMPNAME', 'GAIN', 'RDNOISE', 'DARK', 'SATURATE', 'RSPEED', 'CHIPTEMP', 'CCDCHIP', 'DATASEC', 'CCDSUM', 'NSUM', 'LTM1_1', 'LTM2_2', 'LTV1', 'LTV2', 'ATM1_1', 'ATM2_2', 'ATV1', 'ATV2', 'DTV1', 'DTV2', 'DTM1_1', 'DTM2_2'] value = ['IM'+str(k), 1.0, 0.0, 'CSST.20200101T000000', 'ccd' + ccdnum.rjust(2,'0'), 'ccd' + ccdnum.rjust(2,'0') + ':'+str(k), gain, readout, dark, saturation, 10.0, -100.0, 'ccd' + ccdnum.rjust(2,'0'), data_sec, '1 1', '1 1', flag_ltm_x[k], flag_ltm_y[k], flag_ltv_x[k]*(detector_size_x-20*2+1), flag_ltv_y[k]*(detector_size_y+1), flag_ltm_x[k], flag_ltm_y[k], flag_ltv_x[k]*(detector_size_x-20*2+1), flag_ltv_y[k]*(detector_size_y+1), 0, 0, 1, 1] description = ['Extension name', ' ', ' ', 'Observation ID', 'CCD name', 'Amplifier name', 'Gain (e-/ADU)', 'Readout noise (e-/pixel)', 'Dark noise (e-/pixel/s)', 'Saturation (e-)', 'Read speed', 'Chip temperature', 'CCD chip ID', 'Data section', 'CCD pixel summing', 'CCD pixel summing', 'CCD to image transformation', 'CCD to image transformation', 'CCD to image transformation', 'CCD to image transformation', 'CCD to amplifier transformation', 'CCD to amplifier transformation', 'CCD to amplifier transformation', 'CCD to amplifier transformation', 'CCD to detector transformatio', 'CCD to detector transformatio', 'CCD to detector transformatio', 'CCD to detector transformatio'] return name, value, description ##9232 9216 898 534 1309 60 -40 -23.4333 def WCS_def(xlen = 9232, ylen = 9216, gapx = 898.0, gapy1 = 534, gapy2 = 1309, ra = 60, dec = -40, pa = -23.433,psize = 0.074, row_num = 1, col_num = 1): """ Creat a wcs frame for CCST with multiple extensions Parameters ---------- """ flag_x = [0, 1, -1, 1, -1] flag_y = [0, 1, 1, -1, -1] flag_ext_x = [0,-1,1,-1,1] flag_ext_y = [0,-1,-1,1,1] x_num = 5 y_num = 6 detector_num = x_num*y_num detector_size_x = xlen detector_size_y = ylen gap_x = gapx gap_y = [gapy1,gapy2] ra_ref = ra dec_ref = dec pa_aper = pa pixel_size = psize gap_y1_num = 3 gap_y2_num = 2 x_center = (detector_size_x*x_num+gap_x*(x_num-1))/2 y_center = (detector_size_y*y_num+gap_y[0]*gap_y1_num+gap_y[1]*gap_y2_num)/2 gap_y_map = np.array([[0,0,0,0,0],[gap_y[0],gap_y[1],gap_y[1],gap_y[1],gap_y[1]],[gap_y[1],gap_y[0],gap_y[0],gap_y[0],gap_y[0]],[gap_y[0],gap_y[0],gap_y[0],gap_y[0],gap_y[0]],[gap_y[0],gap_y[0],gap_y[0],gap_y[0],gap_y[1]],[gap_y[1],gap_y[1],gap_y[1],gap_y[1],gap_y[0]]]) frame_array = np.empty((5,6),dtype=np.float64) # print(x_center,y_center) j = row_num i = col_num ccdnum = str((j-1)*5+i) x_ref, y_ref = (detector_size_x+gap_x)*i-gap_x-detector_size_x/2, detector_size_y*j + sum(gap_y_map[0:j,i-1]) - detector_size_y/2 # print(i,j,x_ref,y_ref,ra_ref,dec_ref) name = [] value = [] description = [] for k in range(1,2): cd = np.array([[ pixel_size, 0], [0, pixel_size]])/3600.*flag_x[k] cd_rot = rotate_CD_matrix(cd, pa_aper) # f = open("CCD"+ccdnum.rjust(2,'0')+"_extension"+str(k)+"_wcs.param","w") name = ['EQUINOX', 'WCSDIM', 'CTYPE1', 'CTYPE2', 'CRVAL1', 'CRVAL2', 'CRPIX1', 'CRPIX2', 'CD1_1', 'CD1_2', 'CD2_1', 'CD2_2'] value = [2000.0, 2.0, 'RA---TAN', 'DEC--TAN', ra_ref, dec_ref, flag_ext_x[k]*((x_ref+flag_ext_x[k]*detector_size_x/2)-x_center), flag_ext_y[k]*((y_ref+flag_ext_y[k]*detector_size_y/2)-y_center), cd_rot[0,0], cd_rot[0,1], cd_rot[1,0], cd_rot[1,1]] description = ['Equinox of WCS', 'WCS Dimensionality', 'Coordinate type', 'Coordinate typ', 'Coordinate reference value', 'Coordinate reference value', 'Coordinate reference pixel', 'Coordinate reference pixel', 'Coordinate matrix', 'Coordinate matrix', 'Coordinate matrix', 'Coordinate matrix'] return name, value, description def generatePrimaryHeader(xlen = 9232, ylen = 9216,pointNum = '1', ra = 60, dec = -40, psize = 0.074, row_num = 1, col_num = 1): # array_size1, array_size2, flux, sigma = int(argv[1]), int(argv[2]), 1000.0, 5.0 filerParm_fn = os.path.split(os.path.realpath(__file__))[0] + '/filter.lst' f = open(filerParm_fn) s = f.readline() s = s.strip("\n") filter = s.split(' ') k = (row_num-1)*5+col_num ccdnum = str(k) g_header_fn = os.path.split(os.path.realpath(__file__))[0] + '/global_header.param' name, value, description = read_header_parameter(g_header_fn) h_prim = fits.Header() date = '200930' time_obs = '120000' for i in range(len(name)): if(name[i]=='FILTER'): value[i] = filter[k-1] if(name[i]=='FILENAME'): value[i] = 'CSST_' + date + '_' +time_obs + '_' + pointNum.rjust(6,'0') + '_' +ccdnum.rjust(2,'0')+'_raw' if(name[i]=='DETSIZE'): value[i] = '[1:' + str(int(xlen)) + ',1:'+ str(int(ylen)) + ']' if(name[i]=='PIXSCAL1'): value[i] = str(psize) if(name[i]=='PIXSCAL2'): value[i] = str(psize) h_prim[name[i]] = (value[i],description[i]) h_prim.add_comment('==================================================================',after='FILETYPE') h_prim.add_comment('Target information') h_prim.add_comment('==================================================================') h_prim.add_comment('==================================================================',after='EQUINOX') h_prim.add_comment('Exposure information') h_prim.add_comment('==================================================================') h_prim.add_comment('==================================================================',after='MJDEND') h_prim.add_comment('Telescope information') h_prim.add_comment('==================================================================') h_prim.add_comment('==================================================================',after='REFFRAME') h_prim.add_comment('Detector information') h_prim.add_comment('==================================================================') h_prim.add_comment('==================================================================',after='FILTER') h_prim.add_comment('Other information') h_prim.add_comment('==================================================================') return h_prim def generateExtensionHeader(xlen = 9232, ylen = 9216,ra = 60, dec = -40, pa = -23.433, gain = 1.0, readout = 5.0, dark = 0.02, saturation=90000, psize = 0.074, row_num = 1, col_num = 1): h_ext = fits.Header() for i in range(1,2): # NAXIS1:Number of pixels per row; NAXIS2:Number of rows h_ext['NAXIS1'] = xlen h_ext['NAXIS2'] = ylen name, value, description = Header_extention(xlen = xlen, ylen = ylen, gain = gain, readout = readout, dark = dark, saturation=saturation, row_num = row_num, col_num = col_num) for j in range(len(name)): h_ext[name[j]] = (value[j],description[j]) name, value, description = WCS_def(xlen = xlen, ylen = ylen, gapx = 898.0, gapy1 = 534, gapy2 = 1309, ra = ra, dec = dec, pa = pa ,psize = psize, row_num = row_num, col_num = col_num) for j in range(len(name)): h_ext[name[j]] = (value[j],description[j]) h_ext.add_comment('==================================================================',after='OBSID') h_ext.add_comment('Readout information') h_ext.add_comment('==================================================================') h_ext.add_comment('==================================================================',after='CHIPTEMP') h_ext.add_comment('Chip information') h_ext.add_comment('==================================================================') h_ext.add_comment('==================================================================',after='DTM2_2') h_ext.add_comment('WCS information') h_ext.add_comment('==================================================================') return h_ext def main(argv): xlen = int(argv[1]) ylen = int(argv[2]) pointingNum = argv[3] ra = float(argv[4]) dec = float(argv[5]) pSize = float(argv[6]) ccd_row_num = int(argv[7]) ccd_col_num = int(argv[8]) pa_aper = float(argv[9]) gain = float(argv[10]) readout = float(argv[11]) dark = float(argv[12]) fw = float(argv[13]) h_prim = generatePrimaryHeader(xlen = xlen, ylen = ylen,ra = ra, dec = dec, psize = pSize, row_num = ccd_row_num, col_num = ccd_col_num, pointNum = pointingNum) h_ext = generateExtensionHeader(xlen = xlen, ylen = ylen,ra = ra, dec = dec, pa = pa_aper, gain = gain, readout = readout, dark = dark, saturation=fw, psize = pSize, row_num = ccd_row_num, col_num = ccd_col_num) hdu1 = fits.PrimaryHDU(header=h_prim) hdu2 = fits.ImageHDU(np.zeros([ylen,xlen]),header = h_ext) hdul = fits.HDUList([hdu1,hdu2]) hdul.writeto(h_prim['FILENAME']+'.fits',output_verify='ignore') # if __name__ == "__main__": # main(sys.argv)