Commit 190f1129 authored by GZhao's avatar GZhao
Browse files

pep 8 check.

parent b6e8bc32
Pipeline #7115 failed with stage
in 0 seconds
......@@ -2,7 +2,6 @@ import math
import numpy as np
import scipy.ndimage as nd
from astropy.io import fits
import matplotlib.pyplot as plt
from .config import config, S
from .utils import region_replace, random_seed_select
......@@ -13,6 +12,8 @@ cpism_refdata = config['cpism_refdata']
MAG_SYSTEM = config['mag_system']
solar_spectrum = S.FileSpectrum(config['solar_spectrum'])
solar_spectrum.convert('photlam')
def sky_frame_maker(band, skybg, platescale, shape):
"""
generate a sky background frame.
......@@ -301,7 +302,7 @@ class CpicVisEmccd(object):
self._defaut_config()
if config_dict is not None:
old_switch = self.switch
self.__dict__.update(config_dict) #not safe, be careful
self.__dict__.update(config_dict) # not safe, be careful
old_switch.update(self.switch)
self.switch = old_switch
self.config_init()
......@@ -347,7 +348,7 @@ class CpicVisEmccd(object):
self.flat = None
self.fullwell = 80_000
self.em_fullwell = 500_000 #780_000
self.em_fullwell = 500_000 # 780_000
self.em_cte = 0.9996
self.emreg_cal_num = 10 # 用来加速计算
self.emreg_num = 604
......@@ -372,12 +373,10 @@ class CpicVisEmccd(object):
self.nonlinear_coefficient = -0.1
self.detector_name = 'EMCCD'
self.ccd_label= 'CCD201-20'
self.detector_name = 'CCD201-20-EM'
self.ccd_label = 'EMCCD'
self.pitch_size = 13
def config_init(self):
"""initialize the camera.
If the config is set, call this function to update the config.
......@@ -431,7 +430,6 @@ class CpicVisEmccd(object):
cti_trail = cte_201(self.em_cte, start=0, length=10)
self.cti_trail = cti_trail / cti_trail.sum()
def em_fix_fuc_fit(self, emgain):
"""Calculate the emgain fix coeficient to fix the gamma distribution.
The coeficient is from fixing of ideal emgain distribution.
......@@ -448,6 +446,7 @@ class CpicVisEmccd(object):
"""
emgain = np.array([emgain]).flatten()
p = [0.01014486, -0.00712984, -0.17163414, 0.09523666, -0.53926089]
def kernel(em):
log_em = np.log10(em)
loglog_g = np.log10(log_em)
......@@ -465,7 +464,6 @@ class CpicVisEmccd(object):
output.append(kernel(em))
return np.array(output)
def bias_frame(self):
"""Generate bias frame
The bias frame contains vertical, horizontal, peper-salt noise, bias drift effect.
......@@ -565,7 +563,7 @@ class CpicVisEmccd(object):
# plt.title('vertical pattern')
# 接上制冷机后,会有亮暗点
#cooler interfence effect
# cooler interfence effect
ci_position = 10
ci_sub_struct = 80
ci_sub_exp = 2.5
......@@ -646,7 +644,7 @@ class CpicVisEmccd(object):
heat = self.volt * self.heat_speed
self.ccd_temp = heat + self.cooler_temp + (self.ccd_temp - self.cooler_temp) * np.exp(-dt * self.temper_speed)
if self.ccd_temp < self.cooler_temp: #
if self.ccd_temp < self.cooler_temp:
self.ccd_temp = self.cooler_temp
self.system_time += dt
......@@ -679,7 +677,8 @@ class CpicVisEmccd(object):
volt_coe_a = -0.01828
volt_coe_b = 43.61
volt_func = lambda es: volt_coe_a * es + volt_coe_b
def volt_func(es):
return volt_coe_a * es + volt_coe_b
self.volt = volt_func(em_set)
......@@ -846,7 +845,6 @@ class CpicVisEmccd(object):
image_shutter = np.random.poisson(image_shutter)
image[:, self.pscan1+self.ldark:-self.oscan1-self.rdark] += image_shutter
if self.switch['cic']:
cic_frame = np.zeros((self.dark_shape[0], self.bias_shape[1])) + self.cic
image[self.pscan2:-self.oscan2, :] += np.random.poisson(cic_frame)
......@@ -861,7 +859,6 @@ class CpicVisEmccd(object):
em_fix = self.em_fix_fuc_fit(emgain) * emgain
image = np.random.gamma(image, em_fix) + image * (emgain - em_fix)
if self.switch['em_blooming']:
image = self.emregester_blooming(image)
......
import os, yaml
import os
import yaml
import warnings
from datetime import datetime
import numpy as np
......@@ -37,8 +38,6 @@ def load_refdata_path(config_aim):
----------
config_aim : str
config_aim file path
"""
with open(config_aim, 'r') as f:
refdata_list = yaml.load(f, Loader=yaml.FullLoader)
......@@ -85,8 +84,8 @@ config['platescale'] = 0.016153
config['datamodel'] = f'{cpism_refdata}/io/csst-cpic-l0.yaml'
config['log_dir'] = f'{cpism_refdata}/log'
config['log_level'] = f'info'
config['output'] = f'./'
config['log_level'] = 'info'
config['output'] = './'
config['sp2teff_model'] = f'{cpism_refdata}/target_model/sptype2teff_lut.json'
config['dm_pickle'] = f'{cpism_refdata}/optics/dm_model.pkl'
config['pysyn_refdata'] = f'{cpism_refdata}/starmodel/grp/redcat/trds'
......@@ -95,9 +94,12 @@ config['csst_format'] = True
config['nsample'] = 5
update_able_keys = [
'apm_file', 'actuator_file', 'aberration', 'log_dir', 'log_level', 'catalog_folder', 'nsample', 'csst_format', 'output', 'check_fits_header'
'apm_file', 'actuator_file', 'aberration',
'log_dir', 'log_level', 'catalog_folder',
'nsample', 'csst_format', 'output', 'check_fits_header'
]
def replace_cpism_refdata(
config: dict,
output: str = '$') -> None:
......@@ -138,6 +140,7 @@ __version__ = '2.0.0'
with warnings.catch_warnings(): # pragma: no cover
warnings.filterwarnings("ignore")
import pysynphot as S
_ = S # S will be used in other modules, but I need to use it once here to pass the lint.
def setup_config(new_config):
......@@ -160,8 +163,10 @@ def setup_config(new_config):
config['default_band'] = list(config['bands'].keys())[0]
config['default_filter'] = config['bands'][config['default_band']]
setup_config({})
def which_focalplane(band):
"""
Return the name of the focalplane which the band belongs to.
......@@ -172,7 +177,6 @@ def which_focalplane(band):
band: str
The name of the band.
Returns
--------
str
......@@ -194,6 +198,7 @@ def which_focalplane(band):
return 'vis'
# raise ValueError(f"未知的波段{band}")
def iso_time(time):
"""Transfer relative time to iso time format
......@@ -210,7 +215,7 @@ def iso_time(time):
"""
if isinstance(time, str):
_ = datetime.fromisoformat(time)
_ = datetime.fromisoformat(time) # check if it is a iso time
return time
utc0 = config['utc0']
......@@ -218,6 +223,7 @@ def iso_time(time):
time = datetime.fromtimestamp(time0 + time)
return time.isoformat()
def relative_time(time):
"""Transfer iso time format to relative time in seconds
......@@ -240,4 +246,3 @@ def relative_time(time):
utc0 = config['utc0']
time0 = datetime.timestamp(datetime.fromisoformat(utc0))
return datetime.timestamp(datetime.fromisoformat(time)) - time0
\ No newline at end of file
import yaml, os, re
import yaml
import os
from datetime import datetime
import numpy as np
import pandas as pd
from astropy.io import fits
from astropy.coordinates import SkyCoord
import astropy.units as u
from .config import __version__, which_focalplane
from .utils import Logger
......@@ -14,13 +16,16 @@ default_output_dir = config['output']
log_level = config['log_level']
header_check = config['check_fits_header']
def set_up_logger(log_dir):
if not os.path.exists(log_dir):
os.makedirs(log_dir)
return Logger(log_dir+'/cpism_pack.log', log_level).logger
log = set_up_logger(config['log_dir'])
def check_and_update_fits_header(header):
"""
Check the header keywords and update the description according to the data model.
......@@ -43,7 +48,7 @@ def check_and_update_fits_header(header):
data_model = yaml.load(fid, Loader=yaml.FullLoader)
if 'FILETYPE' in header.keys():
header_model =data_model['HDU0']
header_model = data_model['HDU0']
hdu = 'hdu0'
else:
header_model = data_model['HDU1']
......@@ -88,7 +93,12 @@ def check_and_update_fits_header(header):
else:
key_type = 'ukn'
# print(f"keyword: {keyword} type: {key_type}, datamodel: {dtype}, value: {value}")
if key_type != dtype[0:3]:
if key_type == 'int' and dtype[0:3] == 'flo':
header[keyword] = float(header[keyword])
# print('transfer int to float with header keyword:', keyword)
else:
print_warning(
f"Keyword {keyword} has wrong type in [{hdu}]. {dtype} expected, {key_type} found.")
......@@ -146,6 +156,27 @@ def obsid_parser(
return obstype
def datetime_obj_to_iso(time_obj):
"""
transfer datetime object to iso format used in csst fits file
example '2014-02-10T12:32:12.4'
Parameters
----------
time_obj: datetime.datetime
The datetime object.
Returns
-------
str
The iso format of the datetime object.
"""
isotime = time_obj.isoformat(sep='T', timespec='milliseconds')
subsec = str(round(float(isotime[19:22]), 1))
return isotime[:18] + subsec
def datetime_obj_to_mjd(time_obj):
"""
transfer datetime object to mean julian date (MJD).
......@@ -225,7 +256,7 @@ def primary_hdu(
header['NEXTEND'] = 1 # + parameters['nframe']
# header['GROUPS'] = False
header['DATE'] = datetime.now().isoformat(timespec='seconds')
header['DATE'] = datetime_obj_to_iso(datetime.now())
heaer_filename = filename[:-4]
if len(heaer_filename) > 68:
heaer_filename = heaer_filename[:68]
......@@ -243,8 +274,10 @@ def primary_hdu(
cstar = obs_info['target']['cstar']
radec = SkyCoord(cstar['ra'], cstar['dec'])
target_name = radec.to_string('hmsdms')
target_name = re.sub(R'[hdms\s]', '', target_name)
ra_str = radec.ra.to_string(unit=u.hour, sep='', precision=1, pad=True)
dec_str = radec.dec.to_string(unit=u.deg, sep='', alwayssign=True, pad=True)
target_name = ra_str + dec_str
header['OBJECT'] = cstar.get('name', target_name)
header['TARGET'] = target_name
header['OBSID'] = str(obsid)
......@@ -253,7 +286,7 @@ def primary_hdu(
# telescope information
header['REFFRAME'] = 'CSSTGSC-1.0'
header['DATE-OBS'] = exp_start.isoformat(timespec='seconds')
header['DATE-OBS'] = datetime_obj_to_iso(exp_start)
header['SATESWV'] = '1'
header['EXPSTART'] = datetime_obj_to_mjd(exp_start)
......@@ -368,12 +401,12 @@ def frame_header(obs_info, index, primary_header, camera_dict):
header['BUNIT'] = 'ADU'
header['FILTER'] = obs_info['band']
header['DETSN'] = '0'
header['DETSN'] = '00000000000'
header['DETNAME'] = camera_config['detector_name']
header['CHIPLAB'] = camera_config['ccd_label']
header['DEWTEMP'] = float(camera_config['cooler_temp'])
header['DEWTEMP'] = float(camera_config['cooler_temp']) + 273.15
frame_info = obs_info['frame_info'][index]
header['CHIPTEMP'] = float(frame_info['chiptemp'])
header['CHIPTEMP'] = float(frame_info['chiptemp']) + 273.15
header['DETSIZE'] = f"{imgszx} * {imgszy}"
header['IMGINDEX'] = index + 1
......@@ -513,7 +546,6 @@ def save_fits_simple(images, obs_info, output_folder='./'):
shift = obs_info['shift']
header['shift'] = f"x:{shift[0]},y:{shift[1]}"
fullname = os.path.join(output_folder, filename)
print(fullname)
if not os.path.exists(output_folder):
......
import argparse, sys, tqdm, time, os, yaml
import argparse
import tqdm
import time
import os
import yaml
from glob import glob
from datetime import datetime
import traceback
......@@ -25,8 +30,8 @@ def vis_observation(
shift: list = [0, 0],
gnc_info: dict = {},
csst_format: bool = True,
camera = CpicVisEmccd(),
crmaker = CosmicRayFrameMaker(),
camera=CpicVisEmccd(),
crmaker=CosmicRayFrameMaker(),
nsample: int = 1,
emgain=None,
prograss_bar=None,
......@@ -49,7 +54,8 @@ def vis_observation(
emset: int
EM gain setting value. 1023(0x3FF) for ~1.0× EM gain.
obsid: int
observation ID. Start from 4 for CPIC, 01 for science observation. See the input of io.obsid_parser for more details.
observation ID. Start from 4 for CPIC, 01 for science observation.
See the input of io.obsid_parser for more details.
rotation: float
rotation of the telescope. in unit of degree. 0 means North is up.
shift: list
......@@ -174,6 +180,7 @@ def vis_observation(
print(f'\r Done [{time.time() - start_time:.1f}s] ')
return image_cube
def quick_run_v2(
target_str: str,
band: str,
......@@ -183,9 +190,9 @@ def quick_run_v2(
skybg: float = None,
rotation: float = 0,
shift: list = [0, 0],
emset_input: bool=False,
cr_frame: bool=True,
camera_effect: bool=True,
emset_input: bool = False,
cr_frame: bool = True,
camera_effect: bool = True,
prograss_bar=False,
output='./') -> np.ndarray:
......@@ -226,7 +233,6 @@ def quick_run_v2(
"""
print(f'Quick Run: {target_str}')
log.debug(
f"""input parameters:
target_str: {target_str}
......@@ -283,10 +289,9 @@ def quick_run_v2(
)
def deduplicate_names_add_count(names: list):
"""remove duplicate names and add count"""
for i in range(len(names)-1,-1,-1):
for i in range(len(names)-1, -1, -1):
if names.count(names[i]) > 1:
names[i] = names[i] + '_' + str(names.count(names[i]))
......@@ -337,7 +342,6 @@ def observation_simulation_from_config(obs_file, config_file):
if not file_list:
log.warning(f"No observation file found in {obs_file}")
for ind_target, file in enumerate(file_list):
try:
with open(file, 'r') as fid:
......@@ -405,6 +409,7 @@ def observation_simulation_from_config(obs_file, config_file):
except Exception as e:
log.error(f"{info_text} failed with {type(e).__name__}{e}.\n\n {traceback.format_exc()}")
def main(argv=None):
"""
Command line interface of csst_cpic_sim
......@@ -426,10 +431,18 @@ def main(argv=None):
parser_quickrun.add_argument('nframe', type=int, help='number of frames')
parser_quickrun.add_argument('-b', '--band', type=str, default='f661', help='band, one of f565/f661/f743/f883')
parser_quickrun.add_argument('-r', '--rotation', type=float, default=0, help='rotation angle [degree]')
parser_quickrun.add_argument('-s', '--skybk', type=float, default=21, help='magnitude of sky background [mag/arcsec^2]')
parser_quickrun.add_argument('-f', '--cr_frame', action='store_true', help='if True, cosmic ray frame will be added')
parser_quickrun.add_argument('-e', '--emset', action='store_true', help='if True, emgain set value will be used as input')
parser_quickrun.add_argument('-c', '--camera_effect', action='store_true', help='if True, camera effect will be added')
parser_quickrun.add_argument(
'-s', '--skybk', type=float, default=21,
help='magnitude of sky background [mag/arcsec^2]')
parser_quickrun.add_argument(
'-f', '--cr_frame', action='store_true',
help='if True, cosmic ray frame will be added')
parser_quickrun.add_argument(
'-e', '--emset', action='store_true',
help='if True, emgain set value will be used as input')
parser_quickrun.add_argument(
'-c', '--camera_effect', action='store_true',
help='if True, camera effect will be added')
parser_quickrun.add_argument('-o', '--output', type=str, default='./', help='output folder')
def quick_run_call(args):
......
......@@ -133,7 +133,7 @@ def focal_convolve(
rotation: float = 0,
nsample: int = 5,
error: float = 0,
platesize: list = [1024, 1024]) -> np.ndarray :
platesize: list = [1024, 1024]) -> np.ndarray:
"""PSF convolution of the ideal focus image.
Parameters
......
import os, pickle
import os
import pickle
import numpy as np
from astropy.io import fits
......@@ -73,6 +74,7 @@ aberration = SurfaceApodizer(
aberration_distance = 80 * focal_length
aberration = SurfaceAberrationAtDistance(aberration, aberration_distance)
def single_band_masked_psf(
wavelength: float,
error: float = 0,
......@@ -99,8 +101,10 @@ def single_band_masked_psf(
wf = Wavefront(aperture, wavelength)
shift = np.array(shift) * ARCSEC2RAD / 2
tiptilt_mirror.actuators = shift
wf = tiptilt_mirror(wf)
wf = aberration(wf)
wf = tiptilt_mirror(wf)
first_focal = prop_full_frame(deformable_mirror(wf))
strength = first_focal.intensity.shaped.sum()
......@@ -109,6 +113,41 @@ def single_band_masked_psf(
psf = second_focal.intensity.shaped
return psf / strength
def single_band_shift_psf(
wavelength: float,
error: float = 0,
shift: list = [0, 0]) -> np.ndarray:
"""CPIC PSF considering the focal plane mask.
Parameters
-----------
wavelength : float
observation wavelength in meter
error : float
deformable mirror control error in nm
shift : list
angular shift of the target in arcsec.
Returns
----------
psf : np.ndarray
psf in the focal plane. Normalized as the input flux is 1.
(Note that total flux of the psf is not 1, because it is masked)
"""
error = np.random.normal(0, error*1e-9, actuator.shape)
deformable_mirror.actuators = actuator + error
wf = Wavefront(aperture, wavelength)
shift = np.array(shift) * ARCSEC2RAD / 2
tiptilt_mirror.actuators = shift
wf = aberration(wf)
wf = tiptilt_mirror(wf)
first_focal = prop_full_frame(deformable_mirror(wf))
image = np.array(first_focal.intensity.shaped)
return image / image.sum()
def single_band_psf(
wavelength: float,
error: float = 0) -> np.ndarray:
......@@ -126,7 +165,6 @@ def single_band_psf(
----------
psf : np.ndarray
psf in the focal plane. Normalized. The total flux is 1.
"""
error = np.random.normal(0, error*1e-9, actuator.shape)
deformable_mirror.actuators = actuator + error
......@@ -136,7 +174,6 @@ def single_band_psf(
image = np.array(first_focal.intensity.shaped)
return image / image.sum()
# def single_band_psf(wavelength, error=0, aber_phase=None):
# error = np.random.normal(0, error*1e-9, actuator.shape)
# deformable_mirror.actuators = actuator + error
......
import os, re, json, yaml
import os
import re
import json
import yaml
from typing import Union
import numpy as np
from scipy import constants
......@@ -24,6 +27,7 @@ BCC_MODEL_FOLDER = config['bcc_model']
MAG_SYSTEM = config['mag_system']
CATALOG_CACHE = {}
class AlbedoCat(S.spectrum.TabularSpectralElement, S.catalog.Icat):
"""Generate albedo spectrum from the planet reflection model in Batalha et al. 2018
......@@ -48,13 +52,14 @@ class AlbedoCat(S.spectrum.TabularSpectralElement, S.catalog.Icat):
"""
def __init__(self,
def __init__(
self,
phase: float,
metallicity: float,
f_sed: float,
):
catname = 'BCCalbedo'
self.isAnalytic=False
self.isAnalytic = False
self.name = f"{catname}_{phase}_{metallicity}_{f_sed}"
self.parameter_names = ['phase', 'metallicity', 'f_sed']
self.catalog_folder = BCC_MODEL_FOLDER
......@@ -70,15 +75,15 @@ class AlbedoCat(S.spectrum.TabularSpectralElement, S.catalog.Icat):
indices = self._getArgs(indexList, filenameList)
CATALOG_CACHE[filename] = indices
list0,list1 = self._breakList(indices, 0, phase)
list0, list1 = self._breakList(indices, 0, phase)
list2,list3 = self._breakList(list0, 1, metallicity)
list4,list5 = self._breakList(list1, 1, metallicity)
list2, list3 = self._breakList(list0, 1, metallicity)
list4, list5 = self._breakList(list1, 1, metallicity)
list6,list7 = self._breakList(list2, 2, f_sed)
list8,list9 = self._breakList(list3, 2, f_sed)
list10,list11 = self._breakList(list4, 2, f_sed)
list12,list13 = self._breakList(list5, 2, f_sed)
list6, list7 = self._breakList(list2, 2, f_sed)
list8, list9 = self._breakList(list3, 2, f_sed)
list10, list11 = self._breakList(list4, 2, f_sed)
list12, list13 = self._breakList(list5, 2, f_sed)
sp1, wave, waveunits = self._getSpectrum(list6[0], catname, wave_output=True)
sp2 = self._getSpectrum(list7[0], catname)
......@@ -255,6 +260,7 @@ def star_photlam(
star_sp.convert('photlam')
return star_sp
def standard_spectrum(
magnitude: float) -> S.ArraySpectrum:
"""Standard spectrum of magnitude system.
......@@ -283,6 +289,7 @@ def standard_spectrum(
std_spectrum.convert('photlam')
return std_spectrum
def bcc_spectrum(
coe_cloud: float,
coe_metalicity: float) -> S.spectrum.ArraySpectralElement:
......@@ -563,19 +570,20 @@ class TargetOjbect(object):
elif sp_model == 'bcc_planet':
coe_c, coe_m = planet.get('coe_cloud', 2), planet.get('coe_metal', 0)
albedo_spect = bcc_spectrum(coe_c, coe_m)
else: #sp_model == 'template_planet'
else: # sp_model == 'template_planet'
albedo_spect = S.FileBandpass(detect_template_path(planet['template']))
contrast = 1
self.spectrum = cstar.spectrum * albedo_spect * contrast
def planet_contrast(
planet_x_au: float,
planet_y_au: float,
phase_angle: float,
radius: float) -> float:
"""
calculate the contrast of a planet
Calculate the contrast of a planet.
Parameters
----------
......@@ -610,10 +618,11 @@ def planet_contrast(
contrast = (radius / sep_3d * R_JUPITER_METER / AU_METER)**2 * phase
return contrast
def spectrum_generator(
targets: dict) -> list:
"""
generate the spectrum due to the input target list
Generate the spectrum due to the input target list.
Parameters
----------
......@@ -682,7 +691,7 @@ def target_file_load(
if not target: # None or empty string
return {}
if isinstance(target, str): #filename or formatted string
if isinstance(target, str): # filename or formatted string
target = target.strip()
if not target:
return {}
......
band: f661
band: f662
emgain: 1
emset: -1
expt: 10
......
band: f661
band: f662
emgain: 200
emset: -1
expt: 100
......
band: f565
band: f520
emgain: 1
emset: -1
expt: 10
......
band: f565
band: f520
emgain: 50
emset: -1
expt: 50
......
band: f661
band: f662
emgain: 50
emset: -1
expt: 20
......
band: f565
band: f520
emgain: 1
emset: -1
expt: 10
......
band: f565
band: f520
emgain: 2
emset: -1
expt: 10
......
band: f565
band: f720
emgain: 2
emset: -1
expt: 10
......
band: f565
band: f520
emgain: 50
emset: -1
expt: 10
......
......@@ -12,6 +12,10 @@ bands:
f743: ${cpism_refdata}/throughtput/f743_total.fits
f883: ${cpism_refdata}/throughtput/f883_total.fits
f565: ${cpism_refdata}/throughtput/f565_total.fits
f520: ${cpism_refdata}/throughtput/f520.fits
f662: ${cpism_refdata}/throughtput/f662.fits
f850: ${cpism_refdata}/throughtput/f850.fits
f720: ${cpism_refdata}/throughtput/f720.fits
diameter: 2
platescale: 0.016153
datamodel: ${cpism_refdata}/io/csst-cpic-l0.yaml
......
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