Commit b0ca68fe authored by Xie Zhou's avatar Xie Zhou
Browse files

大致完成了仪器效应改正的代码, 修改了一些csstdata的小bug, deepcr部分还没添加

parent e121def7
...@@ -2,6 +2,7 @@ from collections import OrderedDict ...@@ -2,6 +2,7 @@ from collections import OrderedDict
import astropy.io.fits as fits import astropy.io.fits as fits
from astropy.io.fits import HDUList, PrimaryHDU from astropy.io.fits import HDUList, PrimaryHDU
import numpy as np
from csst.core.exception import CsstException from csst.core.exception import CsstException
...@@ -104,9 +105,13 @@ class CsstData: ...@@ -104,9 +105,13 @@ class CsstData:
print("save L1 image to a fits file with name " + filename) print("save L1 image to a fits file with name " + filename)
try: try:
self._l1hdr_global.set('TYPE', imgtype, 'Type of Level 1 data') self._l1hdr_global.set('TYPE', imgtype, 'Type of Level 1 data')
pri_hdu = PrimaryHDU(header=self._l1hdr_global) hdulist = fits.HDUList(
hdulist = HDUList([pri_hdu, self._l1data[imgtype]]) [
hdulist.writeto(filename) fits.PrimaryHDU(header=self._l1hdr_global),
fits.ImageHDU(header=self._l1data[imgtype].header, data=self._l1data[imgtype].data),
]
)
hdulist.writeto(filename, overwrite=True)
except Exception as e: except Exception as e:
print(e) print(e)
......
...@@ -3,6 +3,7 @@ import astropy.io.fits as fits ...@@ -3,6 +3,7 @@ import astropy.io.fits as fits
from astropy.io.fits import HDUList, PrimaryHDU, ImageHDU from astropy.io.fits import HDUList, PrimaryHDU, ImageHDU
from astropy.io.fits.header import Header from astropy.io.fits.header import Header
from ..core.data import CsstData, INSTRUMENT_LIST from ..core.data import CsstData, INSTRUMENT_LIST
import numpy as np
__all__ = ["CsstMscData", "CsstMscImgData"] __all__ = ["CsstMscData", "CsstMscImgData"]
...@@ -12,10 +13,8 @@ class CsstMscData(CsstData): ...@@ -12,10 +13,8 @@ class CsstMscData(CsstData):
_l1img_types = {'sci': True, 'weight': True, 'flag': True} _l1img_types = {'sci': True, 'weight': True, 'flag': True}
def __init__(self, priHDU, imgHDU, **kwargs): def __init__(self, priHDU, imgHDU, **kwargs):
super(CsstData, self).__init__(priHDU, imgHDU, **kwargs) super(CsstMscData, self).__init__(priHDU, imgHDU, **kwargs)
self._l1hdr_global = priHDU.header.copy() self._l1hdr_global = priHDU.header.copy()
# self._l1hdr_global['SIMPLE'] = 'T' #/ conforms to FITS standard
# self._l1hdr_global['NAXIS'] = 0kkjk
self._l1data['sci'] = ImageHDU() self._l1data['sci'] = ImageHDU()
self._l1data['weight'] = ImageHDU() self._l1data['weight'] = ImageHDU()
self._l1data['flag'] = ImageHDU() self._l1data['flag'] = ImageHDU()
...@@ -74,8 +73,18 @@ class CsstMscData(CsstData): ...@@ -74,8 +73,18 @@ class CsstMscData(CsstData):
def set_l1data(self, imgtype, img): def set_l1data(self, imgtype, img):
""" set L1 data """ """ set L1 data """
try: try:
if self._l1img_types[imgtype]: if imgtype == 'sci':
self._l1data[imgtype].data = img.copy() self._l1data[imgtype].header['EXTNAME'] = 'img'
self._l1data[imgtype].header['BUNIT'] = 'e/s'
self._l1data[imgtype].data = img.astype(np.float32) / self._l1hdr_global['exptime']
elif imgtype == 'weight':
self._l1data[imgtype].header['EXTNAME'] = 'wht'
self._l1data[imgtype].data = img.astype(np.float32)
elif imgtype == 'flag':
self._l1data[imgtype].header['EXTNAME'] = 'flg'
self._l1data[imgtype].data = img.astype(np.uint16)
else:
raise TypeError('unknow type image')
except Exception as e: except Exception as e:
print(e) print(e)
print('save image data to l1data') print('save image data to l1data')
...@@ -93,7 +102,7 @@ class CsstMscData(CsstData): ...@@ -93,7 +102,7 @@ class CsstMscData(CsstData):
class CsstMscImgData(CsstMscData): class CsstMscImgData(CsstMscData):
def __init__(self, priHDU, imgHDU, **kwargs): def __init__(self, priHDU, imgHDU, **kwargs):
# print('create CsstMscImgData') # print('create CsstMscImgData')
super(CsstMscData, self).__init__(priHDU, imgHDU, **kwargs) super(CsstMscImgData, self).__init__(priHDU, imgHDU, **kwargs)
def __repr__(self): def __repr__(self):
return "<CsstMscImgData: {} {}>".format(self.instrument, self.detector) return "<CsstMscImgData: {} {}>".format(self.instrument, self.detector)
...@@ -124,14 +133,16 @@ class CsstMscImgData(CsstMscData): ...@@ -124,14 +133,16 @@ class CsstMscImgData(CsstMscData):
""" """
try: try:
hl = fits.open(fp) with fits.open(fp) as hdulist:
instrument = hl[0].header.get('INSTRUME') # strip or not? instrument = hdulist[0].header.get('INSTRUME') # strip or not?
detector = hl[0].header.get('DETECTOR') # strip or not? detector = hdulist[0].header.get('DETECTOR') # strip or not?
print("@CsstMscImgData: reading data {} ...".format(fp)) print("@CsstMscImgData: reading data {} ...".format(fp))
assert instrument in INSTRUMENT_LIST assert instrument in INSTRUMENT_LIST
if instrument == 'MSC' and 6 <= int(detector[3:5]) <= 25: if instrument == 'MSC' and 6 <= int(detector[3:5]) <= 25:
# multi-band imaging # multi-band imaging
data = CsstMscImgData(hl[0], hl[1], instrument=instrument, detector=detector) hdu0 = hdulist[0].copy()
return data hdu1 = hdulist[1].copy()
data = CsstMscImgData(hdu0, hdu1, instrument=instrument, detector=detector)
return data
except Exception as e: except Exception as e:
print(e) print(e)
...@@ -2,37 +2,107 @@ from collections import OrderedDict ...@@ -2,37 +2,107 @@ from collections import OrderedDict
from abc import ABCMeta, abstractmethod from abc import ABCMeta, abstractmethod
from enum import Enum from enum import Enum
import numpy as np import numpy as np
from deepCR import deepCR
from ..core.processor import CsstProcStatus, CsstProcessor from ..core.processor import CsstProcStatus, CsstProcessor
class CsstMscInstrumentProc(CsstProcessor): class CsstMscInstrumentProc(CsstProcessor):
_status = CsstProcStatus.empty _status = CsstProcStatus.empty
_switches = {'crosstalk': False, 'nonlinear': False, 'deepcr': False, 'cti': False, 'brighterfatter': False} _switches = {'crosstalk': False, 'nonlinear': False,
'deepcr': False, 'cti': False, 'brighterfatter': False}
def __init__(self): def __init__(self):
pass pass
def _do_crosstalk(self): def _do_fix(self, raw, bias, dark, flat, exptime):
if self._switches['crosstalk']: '''仪器效应改正
print('Crosstalk correction')
将raw扣除本底, 暗场, 平场. 并且避免了除0
def _do_nonlinear(self): Args:
if self._switches['nonlinear']: raw: 科学图生图
print('Nonlinear effect correction') bias: 本底
dark: 暗场
def _do_deepcr(self): flat: 平场
if self._switches['deepcr']: exptime: 曝光时长
print('Deep CR operation') '''
else: self.__l1img = np.divide(
print('Laplace CR correction') raw - bias - dark * exptime, flat,
out=np.zeros_like(raw, float),
def _do_cti(self): where=(flat != 0),
if self._switches['cti']: )
print('CTI effect correction')
def _do_badpix(self, flat):
def _do_brighterfatter(self): '''坏像元标记
if self._switches['brighterfatter']:
print('Brighter-Fatter effect correction') 因为探测器本身原因造成不可用于有效科学研究的像元, 像元响应小于0.5中值或大于1.5中值
Args:
flat: 平场
'''
med = np.median(flat)
flg = (flat < 0.5 * med) | (1.5 * med < flat)
self.__flagimg = self.__flagimg | (flg * 1)
def _do_hot_and_warm_pix(self, dark, exptime, rdnoise):
'''热像元与暖像元标记
因为探测器本身原因造成的影响科学研究结果的像元. 像元在曝光时长积分时间内,
热像元为: 暗流计数大于探测器平均读出噪声的平方.
暖像元为: 暗流计数大于0.5倍读出噪声的平方, 但小于1倍读出噪声的平方.
Args:
dark: 暗场
exptime: 曝光时长
rdnoise: 读出噪声
'''
tmp = dark * exptime
tmp[tmp < 0] = 0
flg = 1 * rdnoise ** 2 <= tmp # 不确定是否包含 暂定包含
self.__flagimg = self.__flagimg | (flg * 2)
flg = (0.5 * rdnoise ** 2 < tmp) & (tmp < 1 * rdnoise ** 2)
self.__flagimg = self.__flagimg | (flg * 4)
def _do_over_saturation(self, raw):
'''饱和溢出像元标记
饱和像元及流量溢出污染的像元.
Args:
raw: 科学图生图
'''
flg = raw == 65535
self.__flagimg = self.__flagimg | (flg * 8)
def _do_cray(self):
'''宇宙线像元标记
宇宙线污染的像元, 用deepCR进行标记
'''
flg, _ = deepCR(self.__l1img)
self.__flagimg = self.__flagimg | (flg * 16)
def _do_weight(self, bias, gain, rdnoise, exptime):
'''权重图
Args:
bias: 本底
gain: 增益
rdnoise: 读出噪声
exptime: 曝光时长
'''
data = self.__l1img.copy()
data[self.__l1img < 0] = 0
weight_raw = 1. / (gain * data + rdnoise ** 2)
bias_weight = np.std(bias)
weight = 1. / (1. / weight_raw + 1. / bias_weight) * exptime ** 2
weight[self.__flagimg > 0] = 0
self.__weightimg = weight
def prepare(self, **kwargs): def prepare(self, **kwargs):
for name in kwargs: for name in kwargs:
...@@ -40,19 +110,24 @@ class CsstMscInstrumentProc(CsstProcessor): ...@@ -40,19 +110,24 @@ class CsstMscInstrumentProc(CsstProcessor):
def run(self, data): def run(self, data):
if type(data).__name__ == 'CsstMscImgData' or type(data).__name__ == 'CsstMscSlsData': if type(data).__name__ == 'CsstMscImgData' or type(data).__name__ == 'CsstMscSlsData':
self.__l1img = data.get_l0data(copy=True) raw = data.get_l0data()
self.__weightimg = np.random.uniform(0, 1, (9216, 9232)) self.__l1img = raw.copy()
self.__flagimg = np.random.uniform(0, 1, (9216, 9232)) self.__weightimg = np.zeros_like(raw)
self.__flagimg = np.zeros_like(raw, dtype=np.uint16)
exptime = data.get_l0keyword('pri', 'EXPTIME')
gain = data.get_l0keyword('img', 'GAIN1')
rdnoise = data.get_l0keyword('img' ,'RDNOISE1')
flat = data.get_flat() flat = data.get_flat()
bias = data.get_bias() bias = data.get_bias()
dark = data.get_dark() dark = data.get_dark()
print('Flat and bias correction') print('Flat and bias correction')
self._do_crosstalk() self._do_fix(raw, bias, dark, flat, exptime)
self._do_nonlinear() self._do_badpix(flat)
self._do_cti() self._do_hot_and_warm_pix(dark, exptime, rdnoise)
self._do_deepcr() self._do_over_saturation(raw)
self._do_brighterfatter() # self._do_cray()
self._do_weight(bias, gain, rdnoise, exptime)
print('fake to finish the run and save the results back to CsstData') print('fake to finish the run and save the results back to CsstData')
...@@ -61,7 +136,8 @@ class CsstMscInstrumentProc(CsstProcessor): ...@@ -61,7 +136,8 @@ class CsstMscInstrumentProc(CsstProcessor):
data.set_l1data('flag', self.__flagimg) data.set_l1data('flag', self.__flagimg)
print('Update keywords') print('Update keywords')
data.set_l1keyword('SOMEKEY', 'some value', 'Test if I can append the header') data.set_l1keyword('SOMEKEY', 'some value',
'Test if I can append the header')
self._status = CsstProcStatus.normal self._status = CsstProcStatus.normal
else: else:
......
from csst.msc import CsstMscImgData
from csst.msc.instrument import CsstMscInstrumentProc
from astropy.io.fits import getdata
fp = "/data/cali_20211012/L0/150s/MSC_MS_210525120000_100000000_13_raw.fits"
bs = "/data/ref/MSC_CLB_210525190000_100000014_13_combine.fits"
dk = "/data/ref/MSC_CLD_210525192000_100000014_13_combine.fits"
ft = "/data/ref/MSC_CLF_210525191000_100000014_13_combine.fits"
op = "/data/test/"
data = CsstMscImgData.read(fp)
# print(repr(data._l1data.header))
data.set_bias(getdata(bs))
data.set_dark(getdata(dk))
data.set_flat(getdata(ft))
proc = CsstMscInstrumentProc()
proc.run(data)
data.save_l1data('sci', op+'sci.fits')
data.save_l1data('flag', op+'flag.fits')
data.save_l1data('weight', op+'weight.fits')
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment