""" generate image header """ import numpy as np from astropy.io import fits import astropy.wcs as pywcs from collections import OrderedDict 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]) # print(arr[0],arr[1]) 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 = 9216, ylen = 9232, 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+']' e_header_fn = os.path.split(os.path.realpath(__file__))[0] + '/extension_header.param' name, value, description = read_header_parameter(e_header_fn) f = open(os.path.split(os.path.realpath(__file__))[0] + '/filter.lst') s = f.readline() s = s.strip("\n") filters = s.split(' ') s = f.readline() s = s.strip("\n") filterID = s.split() s = f.readline() s = s.strip("\n") CCDID = s.split() k = (row_num-1)*6+col_num h_iter = 0 for n1,v1,d1 in zip(name, value, description): if n1=='EXTNAME': value[h_iter] = 'RAW,'+CCDID[k-1].rjust(2,'0') if n1=='CCDNAME': value[h_iter] = 'ccd' + CCDID[k-1].rjust(2,'0') if n1=='AMPNAME': value[h_iter] = 'ccd' + CCDID[k-1].rjust(2,'0') + ':A' if n1=='GAIN': value[h_iter] = gain if n1=='RDNOISE': value[h_iter] = readout if n1=='SATURATE': value[h_iter] = saturation if n1=='CCDCHIP': value[h_iter] = 'ccd' + CCDID[k-1].rjust(2,'0') if n1=='CCDLABEL': value[h_iter] = filters[k-1] + '-' + filterID[k-1] if n1=='DATASEC': value[h_iter] = data_sec h_iter = h_iter + 1 return name, value, description ##9232 9216 898 534 1309 60 -40 -23.4333 def WCS_def(xlen = 9216, ylen = 9232, gapy = 898.0, gapx1 = 534, gapx2 = 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 = 6 y_num = 5 detector_num = x_num*y_num detector_size_x = xlen detector_size_y = ylen gap_y = gapy gap_x = [gapx1,gapx2] ra_ref = ra dec_ref = dec pa_aper = pa pixel_size = psize gap_x1_num = 3 gap_x2_num = 2 y_center = (detector_size_y*y_num+gap_y*(y_num-1))/2 x_center = (detector_size_x*x_num+gap_x[0]*gap_x1_num+gap_x[1]*gap_x2_num)/2 gap_x_map = np.array([[0,0,0,0,0],[gap_x[0],gap_x[1],gap_x[1],gap_x[1],gap_x[1]],[gap_x[1],gap_x[0],gap_x[0],gap_x[0],gap_x[0]],[gap_x[0],gap_x[0],gap_x[0],gap_x[0],gap_x[0]],[gap_x[0],gap_x[0],gap_x[0],gap_x[0],gap_x[1]],[gap_x[1],gap_x[1],gap_x[1],gap_x[1],gap_x[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*i + sum(gap_x_map[0:i,j-1]) - detector_size_x/2. , (detector_size_y+gap_y)*j-gap_y-detector_size_y/2 # print(i,j,x_ref,y_ref,ra_ref,dec_ref) r_dat = OrderedDict() # 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") r_dat['EQUINOX'] = 2000.0 r_dat['WCSDIM'] = 2.0 r_dat['CTYPE1'] = 'RA---TAN' r_dat['CTYPE2'] = 'DEC--TAN' r_dat['CRVAL1'] = ra_ref r_dat['CRVAL2'] = dec_ref r_dat['CRPIX1'] = flag_ext_x[k]*((x_ref+flag_ext_x[k]*detector_size_x/2)-x_center) r_dat['CRPIX2'] = flag_ext_y[k]*((y_ref+flag_ext_y[k]*detector_size_y/2)-y_center) r_dat['CD1_1'] = cd_rot[0,0] r_dat['CD1_2'] = cd_rot[0,1] r_dat['CD2_1'] = cd_rot[1,0] r_dat['CD2_2'] = cd_rot[1,1] return r_dat # 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 = 9216, ylen = 9232, pointNum = '1', ra = 60, dec = -40, psize = 0.074, row_num = 1, col_num = 1, date='200930', time_obs='120000'): # array_size1, array_size2, flux, sigma = int(argv[1]), int(argv[2]), 1000.0, 5.0 k = (row_num-1)*6+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) f = open(os.path.split(os.path.realpath(__file__))[0] + '/filter.lst') s = f.readline() s = s.strip("\n") filters = s.split(' ') s = f.readline() s = s.strip("\n") filterID = s.split() s = f.readline() s = s.strip("\n") CCDID = s.split() h_prim = fits.Header() for i in range(len(name)): if(name[i]=='FILENAME'): # value[i] = 'CSST_' + date + '_' +time_obs + '_' + pointNum.rjust(6,'0') + '_' +ccdnum.rjust(2,'0')+'_raw' # value[i] = 'CSST_' + date + '_' +time_obs + '_' + pointNum.rjust(6,'0') + '_' +CCDID[k-1].rjust(2,'0')+'_raw' value[i] = 'MSC_' + date + time_obs + '_' + pointNum.rjust(7,'0') + '_' +CCDID[k-1].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='DETETEMP') h_prim.add_comment('Other information') h_prim.add_comment('==================================================================') return h_prim def generateExtensionHeader(xlen = 9216, ylen = 9232,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)): # print(name[j],value[j],description[j]) h_ext[name[j]] = (value[j],description[j]) header_wcs = WCS_def(xlen = xlen, ylen = ylen, gapy = 898.0, gapx1 = 534, gapx2 = 1309, ra = ra, dec = dec, pa = pa ,psize = psize, row_num = row_num, col_num = col_num) for k,v in header_wcs.items(): h_ext.set(k,v) # 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='TRIMSEC') h_ext.add_comment('WCS information') h_ext.add_comment('==================================================================') h_ext.add_comment('==================================================================',after='CD2_2') h_ext.add_comment('Other 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)