Commit fe70f366 authored by Fang Yuedong's avatar Fang Yuedong
Browse files

add unittest for focal plane

parent fcfee677
...@@ -280,774 +280,774 @@ class Chip(FocalPlane): ...@@ -280,774 +280,774 @@ class Chip(FocalPlane):
noise = self.dark_noise * exptime + self.read_noise**2 noise = self.dark_noise * exptime + self.read_noise**2
return noise return noise
def addEffects(self, config, img, chip_output, filt, ra_cen, dec_cen, img_rot, exptime=150., pointing_ID=0, timestamp_obs=1621915200, pointing_type='SCI', sky_map=None, post_flash_map=None, tel=None, logger=None): # def addEffects(self, config, img, chip_output, filt, ra_cen, dec_cen, img_rot, exptime=150., pointing_ID=0, timestamp_obs=1621915200, pointing_type='SCI', sky_map=None, post_flash_map=None, tel=None, logger=None):
# Set random seeds # # Set random seeds
SeedGainNonuni = int(config["random_seeds"]["seed_gainNonUniform"]) # SeedGainNonuni = int(config["random_seeds"]["seed_gainNonUniform"])
SeedBiasNonuni = int(config["random_seeds"]["seed_biasNonUniform"]) # SeedBiasNonuni = int(config["random_seeds"]["seed_biasNonUniform"])
SeedRnNonuni = int(config["random_seeds"]["seed_rnNonUniform"]) # SeedRnNonuni = int(config["random_seeds"]["seed_rnNonUniform"])
SeedBadColumns = int(config["random_seeds"]["seed_badcolumns"]) # SeedBadColumns = int(config["random_seeds"]["seed_badcolumns"])
SeedDefective = int(config["random_seeds"]["seed_defective"]) # SeedDefective = int(config["random_seeds"]["seed_defective"])
SeedCosmicRay = int(config["random_seeds"]["seed_CR"]) # SeedCosmicRay = int(config["random_seeds"]["seed_CR"])
fullwell = int(self.full_well) # fullwell = int(self.full_well)
if config["ins_effects"]["add_hotpixels"] == True: # if config["ins_effects"]["add_hotpixels"] == True:
BoolHotPix = True # BoolHotPix = True
else: # else:
BoolHotPix = False # BoolHotPix = False
if config["ins_effects"]["add_deadpixels"] == True: # if config["ins_effects"]["add_deadpixels"] == True:
BoolDeadPix = True # BoolDeadPix = True
else: # else:
BoolDeadPix = False # BoolDeadPix = False
self.logger = logger # self.logger = logger
# Get Poisson noise generator # # Get Poisson noise generator
rng_poisson, poisson_noise = chip_utils.get_poisson( # rng_poisson, poisson_noise = chip_utils.get_poisson(
seed=int(config["random_seeds"]["seed_poisson"]) + pointing_ID*30 + self.chipID, sky_level=0.) # seed=int(config["random_seeds"]["seed_poisson"]) + pointing_ID*30 + self.chipID, sky_level=0.)
# Add sky background # # Add sky background
if config["ins_effects"]["add_back"] == True: # if config["ins_effects"]["add_back"] == True:
img, sky_map = chip_utils.add_sky_background( # img, sky_map = chip_utils.add_sky_background(
img=img, filt=filt, exptime=exptime, sky_map=sky_map, tel=tel) # img=img, filt=filt, exptime=exptime, sky_map=sky_map, tel=tel)
del sky_map # del sky_map
# Apply flat-field large scale structure for one chip # # Apply flat-field large scale structure for one chip
if config["ins_effects"]["flat_fielding"] == True: # if config["ins_effects"]["flat_fielding"] == True:
chip_utils.log_info( # chip_utils.log_info(
msg=" Creating and applying Flat-Fielding", logger=self.logger) # msg=" Creating and applying Flat-Fielding", logger=self.logger)
chip_utils.log_info(msg=str(img.bounds), logger=self.logger) # chip_utils.log_info(msg=str(img.bounds), logger=self.logger)
flat_img, flat_normal = chip_utils.get_flat( # flat_img, flat_normal = chip_utils.get_flat(
img=img, seed=int(config["random_seeds"]["seed_flat"])) # img=img, seed=int(config["random_seeds"]["seed_flat"]))
if self.survey_type == "photometric": # if self.survey_type == "photometric":
img *= flat_normal # img *= flat_normal
del flat_normal # del flat_normal
if config["output_setting"]["flat_output"] == False: # if config["output_setting"]["flat_output"] == False:
del flat_img # del flat_img
if post_flash_map is not None: # if post_flash_map is not None:
img = img + post_flash_map # img = img + post_flash_map
# Apply Shutter-effect for one chip # # Apply Shutter-effect for one chip
if config["ins_effects"]["shutter_effect"] == True: # if config["ins_effects"]["shutter_effect"] == True:
chip_utils.log_info( # chip_utils.log_info(
msg=" Apply shutter effect", logger=self.logger) # msg=" Apply shutter effect", logger=self.logger)
# shutter effect normalized image for this chip # # shutter effect normalized image for this chip
shuttimg = effects.ShutterEffectArr( # shuttimg = effects.ShutterEffectArr(
img, t_shutter=1.3, dist_bearing=735, dt=1E-3) # img, t_shutter=1.3, dist_bearing=735, dt=1E-3)
if self.survey_type == "photometric": # if self.survey_type == "photometric":
img *= shuttimg # img *= shuttimg
# output 16-bit shutter effect image with pixel value <=65535 # # output 16-bit shutter effect image with pixel value <=65535
if config["output_setting"]["shutter_output"] == True: # if config["output_setting"]["shutter_output"] == True:
shutt_gsimg = galsim.ImageUS(shuttimg*6E4) # shutt_gsimg = galsim.ImageUS(shuttimg*6E4)
shutt_gsimg.write("%s/ShutterEffect_%s_1.fits" % # shutt_gsimg.write("%s/ShutterEffect_%s_1.fits" %
(chip_output.subdir, self.chipID)) # (chip_output.subdir, self.chipID))
del shutt_gsimg # del shutt_gsimg
del shuttimg # del shuttimg
# # Add Poisson noise to the resulting images # # # Add Poisson noise to the resulting images
# # (NOTE): this can only applied to the slitless image # # # (NOTE): this can only applied to the slitless image
# # since it dose not use photon shooting to draw stamps # # # since it dose not use photon shooting to draw stamps
# if self.survey_type == "spectroscopic": # # if self.survey_type == "spectroscopic":
# img.addNoise(poisson_noise) # # img.addNoise(poisson_noise)
# Add cosmic-rays # # Add cosmic-rays
if config["ins_effects"]["cosmic_ray"] == True and pointing_type == 'SCI': # if config["ins_effects"]["cosmic_ray"] == True and pointing_type == 'SCI':
chip_utils.log_info(msg=" Adding Cosmic-Ray", logger=self.logger) # chip_utils.log_info(msg=" Adding Cosmic-Ray", logger=self.logger)
img, crmap_gsimg, cr_event_num = chip_utils.add_cosmic_rays(img=img, chip=self, exptime=exptime, # img, crmap_gsimg, cr_event_num = chip_utils.add_cosmic_rays(img=img, chip=self, exptime=exptime,
seed=SeedCosmicRay+pointing_ID*30+self.chipID) # seed=SeedCosmicRay+pointing_ID*30+self.chipID)
chip_utils.outputCal( # chip_utils.outputCal(
chip=self, # chip=self,
img=crmap_gsimg, # img=crmap_gsimg,
ra_cen=ra_cen, # ra_cen=ra_cen,
dec_cen=dec_cen, # dec_cen=dec_cen,
img_rot=img_rot, # img_rot=img_rot,
im_type='CRS', # im_type='CRS',
pointing_ID=pointing_ID, # pointing_ID=pointing_ID,
output_dir=chip_output.subdir, # output_dir=chip_output.subdir,
exptime=exptime, # exptime=exptime,
project_cycle=config["project_cycle"], # project_cycle=config["project_cycle"],
run_counter=config["run_counter"], # run_counter=config["run_counter"],
timestamp=timestamp_obs) # timestamp=timestamp_obs)
del crmap_gsimg # del crmap_gsimg
# Apply PRNU effect and output PRNU flat file: # # Apply PRNU effect and output PRNU flat file:
if config["ins_effects"]["prnu_effect"] == True: # if config["ins_effects"]["prnu_effect"] == True:
chip_utils.log_info( # chip_utils.log_info(
msg=" Applying PRNU effect", logger=self.logger) # msg=" Applying PRNU effect", logger=self.logger)
img, prnu_img = chip_utils.add_PRNU(img=img, chip=self, # img, prnu_img = chip_utils.add_PRNU(img=img, chip=self,
seed=int(config["random_seeds"]["seed_prnu"]+self.chipID)) # seed=int(config["random_seeds"]["seed_prnu"]+self.chipID))
if config["output_setting"]["prnu_output"] == True: # if config["output_setting"]["prnu_output"] == True:
prnu_img.write("%s/FlatImg_PRNU_%s.fits" % # prnu_img.write("%s/FlatImg_PRNU_%s.fits" %
(chip_output.subdir, self.chipID)) # (chip_output.subdir, self.chipID))
if config["output_setting"]["flat_output"] == False: # if config["output_setting"]["flat_output"] == False:
del prnu_img # del prnu_img
# # Add dark current # # # Add dark current
# if config["ins_effects"]["add_dark"] == True: # # if config["ins_effects"]["add_dark"] == True:
# dark_noise = galsim.DeviateNoise(galsim.PoissonDeviate(rng_poisson, self.dark_noise*(exptime+0.5*self.readout_time))) # # dark_noise = galsim.DeviateNoise(galsim.PoissonDeviate(rng_poisson, self.dark_noise*(exptime+0.5*self.readout_time)))
# img.addNoise(dark_noise) # # img.addNoise(dark_noise)
# Add dark current & Poisson noise # # Add dark current & Poisson noise
InputDark = False # InputDark = False
if config["ins_effects"]["add_dark"] == True: # if config["ins_effects"]["add_dark"] == True:
if InputDark: # if InputDark:
img = chip_utils.add_inputdark( # img = chip_utils.add_inputdark(
img=img, chip=self, exptime=exptime) # img=img, chip=self, exptime=exptime)
else: # else:
img, _ = chip_utils.add_poisson( # img, _ = chip_utils.add_poisson(
img=img, chip=self, exptime=exptime, poisson_noise=poisson_noise) # img=img, chip=self, exptime=exptime, poisson_noise=poisson_noise)
else: # else:
img, _ = chip_utils.add_poisson( # img, _ = chip_utils.add_poisson(
img=img, chip=self, exptime=exptime, poisson_noise=poisson_noise, dark_noise=0.) # img=img, chip=self, exptime=exptime, poisson_noise=poisson_noise, dark_noise=0.)
# Add diffusion & brighter-fatter effects # # Add diffusion & brighter-fatter effects
if config["ins_effects"]["bright_fatter"] == True: # if config["ins_effects"]["bright_fatter"] == True:
img = chip_utils.add_brighter_fatter(img=img) # img = chip_utils.add_brighter_fatter(img=img)
# Add Hot Pixels or/and Dead Pixels # # Add Hot Pixels or/and Dead Pixels
rgbadpix = Generator(PCG64(int(SeedDefective+self.chipID))) # rgbadpix = Generator(PCG64(int(SeedDefective+self.chipID)))
badfraction = 5E-5*(rgbadpix.random()*0.5+0.7) # badfraction = 5E-5*(rgbadpix.random()*0.5+0.7)
img = effects.DefectivePixels(img, IfHotPix=BoolHotPix, IfDeadPix=BoolDeadPix, # img = effects.DefectivePixels(img, IfHotPix=BoolHotPix, IfDeadPix=BoolDeadPix,
fraction=badfraction, seed=SeedDefective+self.chipID, biaslevel=0) # fraction=badfraction, seed=SeedDefective+self.chipID, biaslevel=0)
# Apply Bad lines # # Apply Bad lines
if config["ins_effects"]["add_badcolumns"] == True: # if config["ins_effects"]["add_badcolumns"] == True:
img = effects.BadColumns( # img = effects.BadColumns(
img, seed=SeedBadColumns, chipid=self.chipID, logger=self.logger) # img, seed=SeedBadColumns, chipid=self.chipID, logger=self.logger)
# Apply Nonlinearity on the chip image # # Apply Nonlinearity on the chip image
if config["ins_effects"]["non_linear"] == True: # if config["ins_effects"]["non_linear"] == True:
chip_utils.log_info( # chip_utils.log_info(
msg=" Applying Non-Linearity on the chip image", logger=self.logger) # msg=" Applying Non-Linearity on the chip image", logger=self.logger)
img = effects.NonLinearity(GSImage=img, beta1=5.e-7, beta2=0) # img = effects.NonLinearity(GSImage=img, beta1=5.e-7, beta2=0)
# Apply CCD Saturation & Blooming # # Apply CCD Saturation & Blooming
if config["ins_effects"]["saturbloom"] == True: # if config["ins_effects"]["saturbloom"] == True:
chip_utils.log_info( # chip_utils.log_info(
msg=" Applying CCD Saturation & Blooming", logger=self.logger) # msg=" Applying CCD Saturation & Blooming", logger=self.logger)
img = effects.SaturBloom( # img = effects.SaturBloom(
GSImage=img, nsect_x=1, nsect_y=1, fullwell=fullwell) # GSImage=img, nsect_x=1, nsect_y=1, fullwell=fullwell)
# Apply CTE Effect # # Apply CTE Effect
# if config["ins_effects"]["cte_trail"] == True: # # if config["ins_effects"]["cte_trail"] == True:
# chip_utils.log_info(msg=" Apply CTE Effect", logger=self.logger) # # chip_utils.log_info(msg=" Apply CTE Effect", logger=self.logger)
# img = effects.CTE_Effect(GSImage=img, threshold=27) # # img = effects.CTE_Effect(GSImage=img, threshold=27)
pre1 = self.prescan_x # 27 # pre1 = self.prescan_x # 27
over1 = self.overscan_x # 71 # over1 = self.overscan_x # 71
pre2 = self.prescan_y # 0 #4 # pre2 = self.prescan_y # 0 #4
over2 = self.overscan_y # 84 #80 # over2 = self.overscan_y # 84 #80
if config["ins_effects"]["cte_trail"] == True: # if config["ins_effects"]["cte_trail"] == True:
chip_utils.log_info(msg=" Apply CTE Effect", logger=self.logger) # chip_utils.log_info(msg=" Apply CTE Effect", logger=self.logger)
# img = effects.CTE_Effect(GSImage=img, threshold=27) # # img = effects.CTE_Effect(GSImage=img, threshold=27)
# CTI_modeling # # CTI_modeling
# 2*8 -> 1*16 img-layout # # 2*8 -> 1*16 img-layout
img = chip_utils.formatOutput(GSImage=img) # img = chip_utils.formatOutput(GSImage=img)
self.nsecy = 1 # self.nsecy = 1
self.nsecx = 16 # self.nsecx = 16
img_arr = img.array # img_arr = img.array
ny, nx = img_arr.shape # ny, nx = img_arr.shape
dx = int(nx/self.nsecx) # dx = int(nx/self.nsecx)
dy = int(ny/self.nsecy) # dy = int(ny/self.nsecy)
newimg = galsim.Image(nx, int(ny+over2), init_value=0) # newimg = galsim.Image(nx, int(ny+over2), init_value=0)
for ichannel in range(16): # for ichannel in range(16):
print('\n***add CTI effects: pointing-{:} chip-{:} channel-{:}***'.format( # print('\n***add CTI effects: pointing-{:} chip-{:} channel-{:}***'.format(
pointing_ID, self.chipID, ichannel+1)) # pointing_ID, self.chipID, ichannel+1))
# nx,ny,noverscan,nsp,nmax = 4608,4616,84,3,10 # # nx,ny,noverscan,nsp,nmax = 4608,4616,84,3,10
noverscan, nsp, nmax = over2, 3, 10 # noverscan, nsp, nmax = over2, 3, 10
beta, w, c = 0.478, 84700, 0 # beta, w, c = 0.478, 84700, 0
t = np.array([0.74, 7.7, 37], dtype=np.float32) # t = np.array([0.74, 7.7, 37], dtype=np.float32)
rho_trap = np.array([0.6, 1.6, 1.4], dtype=np.float32) # rho_trap = np.array([0.6, 1.6, 1.4], dtype=np.float32)
trap_seeds = np.array( # trap_seeds = np.array(
[0, 1000, 10000], dtype=np.int32) + ichannel + self.chipID*16 # [0, 1000, 10000], dtype=np.int32) + ichannel + self.chipID*16
release_seed = 50 + ichannel + pointing_ID*30 + self.chipID*16 # release_seed = 50 + ichannel + pointing_ID*30 + self.chipID*16
newimg.array[:, 0+ichannel*dx:dx+ichannel*dx] = CTI_sim( # newimg.array[:, 0+ichannel*dx:dx+ichannel*dx] = CTI_sim(
img_arr[:, 0+ichannel*dx:dx+ichannel*dx], dx, dy, noverscan, nsp, nmax, beta, w, c, t, rho_trap, trap_seeds, release_seed) # img_arr[:, 0+ichannel*dx:dx+ichannel*dx], dx, dy, noverscan, nsp, nmax, beta, w, c, t, rho_trap, trap_seeds, release_seed)
newimg.wcs = img.wcs # newimg.wcs = img.wcs
del img # del img
img = newimg # img = newimg
# 1*16 -> 2*8 img-layout # # 1*16 -> 2*8 img-layout
img = chip_utils.formatRevert(GSImage=img) # img = chip_utils.formatRevert(GSImage=img)
self.nsecy = 2 # self.nsecy = 2
self.nsecx = 8 # self.nsecx = 8
# prescan & overscan # # prescan & overscan
if config["ins_effects"]["add_prescan"] == True: # if config["ins_effects"]["add_prescan"] == True:
chip_utils.log_info( # chip_utils.log_info(
msg=" Apply pre/over-scan", logger=self.logger) # msg=" Apply pre/over-scan", logger=self.logger)
if config["ins_effects"]["cte_trail"] == False: # if config["ins_effects"]["cte_trail"] == False:
img = chip_utils.AddPreScan( # img = chip_utils.AddPreScan(
GSImage=img, pre1=pre1, pre2=pre2, over1=over1, over2=over2) # GSImage=img, pre1=pre1, pre2=pre2, over1=over1, over2=over2)
if config["ins_effects"]["cte_trail"] == True: # if config["ins_effects"]["cte_trail"] == True:
img = chip_utils.AddPreScan( # img = chip_utils.AddPreScan(
GSImage=img, pre1=pre1, pre2=pre2, over1=over1, over2=0) # GSImage=img, pre1=pre1, pre2=pre2, over1=over1, over2=0)
# 1*16 output # # 1*16 output
if config["ins_effects"]["format_output"] == True: # if config["ins_effects"]["format_output"] == True:
chip_utils.log_info(msg=" Apply 1*16 format", logger=self.logger) # chip_utils.log_info(msg=" Apply 1*16 format", logger=self.logger)
img = chip_utils.formatOutput(GSImage=img) # img = chip_utils.formatOutput(GSImage=img)
self.nsecy = 1 # self.nsecy = 1
self.nsecx = 16 # self.nsecx = 16
# Add Bias level # # Add Bias level
if config["ins_effects"]["add_bias"] == True: # if config["ins_effects"]["add_bias"] == True:
chip_utils.log_info( # chip_utils.log_info(
msg=" Adding Bias level and 16-channel non-uniformity", logger=self.logger) # msg=" Adding Bias level and 16-channel non-uniformity", logger=self.logger)
if config["ins_effects"]["bias_16channel"] == True: # if config["ins_effects"]["bias_16channel"] == True:
img = effects.AddBiasNonUniform16(img, # img = effects.AddBiasNonUniform16(img,
bias_level=float( # bias_level=float(
self.bias_level), # self.bias_level),
nsecy=self.nsecy, nsecx=self.nsecx, # nsecy=self.nsecy, nsecx=self.nsecx,
seed=SeedBiasNonuni+self.chipID, # seed=SeedBiasNonuni+self.chipID,
logger=self.logger) # logger=self.logger)
elif config["ins_effects"]["bias_16channel"] == False: # elif config["ins_effects"]["bias_16channel"] == False:
img += self.bias_level # img += self.bias_level
# Add Read-out Noise # # Add Read-out Noise
if config["ins_effects"]["add_readout"] == True: # if config["ins_effects"]["add_readout"] == True:
seed = int(config["random_seeds"]["seed_readout"] # seed = int(config["random_seeds"]["seed_readout"]
) + pointing_ID*30 + self.chipID # ) + pointing_ID*30 + self.chipID
rng_readout = galsim.BaseDeviate(seed) # rng_readout = galsim.BaseDeviate(seed)
readout_noise = galsim.GaussianNoise( # readout_noise = galsim.GaussianNoise(
rng=rng_readout, sigma=self.read_noise) # rng=rng_readout, sigma=self.read_noise)
img.addNoise(readout_noise) # img.addNoise(readout_noise)
# Apply Gain & Quantization # # Apply Gain & Quantization
chip_utils.log_info( # chip_utils.log_info(
msg=" Applying Gain (and 16 channel non-uniformity) & Quantization", logger=self.logger) # msg=" Applying Gain (and 16 channel non-uniformity) & Quantization", logger=self.logger)
if config["ins_effects"]["gain_16channel"] == True: # if config["ins_effects"]["gain_16channel"] == True:
img, self.gain_channel = effects.ApplyGainNonUniform16( # img, self.gain_channel = effects.ApplyGainNonUniform16(
img, gain=self.gain, # img, gain=self.gain,
nsecy=self.nsecy, nsecx=self.nsecx, # nsecy=self.nsecy, nsecx=self.nsecx,
seed=SeedGainNonuni+self.chipID, # seed=SeedGainNonuni+self.chipID,
logger=self.logger) # logger=self.logger)
elif config["ins_effects"]["gain_16channel"] == False: # elif config["ins_effects"]["gain_16channel"] == False:
img /= self.gain # img /= self.gain
img.array[img.array > 65535] = 65535 # img.array[img.array > 65535] = 65535
img.replaceNegative(replace_value=0) # img.replaceNegative(replace_value=0)
img.quantize() # img.quantize()
###################################################################################### # ######################################################################################
# Output images for calibration pointing # # Output images for calibration pointing
###################################################################################### # ######################################################################################
# Bias output # # Bias output
if config["ins_effects"]["add_bias"] == True and config["output_setting"]["bias_output"] == True and pointing_type == 'CAL': # if config["ins_effects"]["add_bias"] == True and config["output_setting"]["bias_output"] == True and pointing_type == 'CAL':
if self.logger is not None: # if self.logger is not None:
self.logger.info(" Output N frame Bias files") # self.logger.info(" Output N frame Bias files")
else: # else:
print(" Output N frame Bias files", flush=True) # print(" Output N frame Bias files", flush=True)
NBias = int(config["output_setting"]["NBias"]) # NBias = int(config["output_setting"]["NBias"])
for i in range(NBias): # for i in range(NBias):
# BiasCombImg, BiasTag = effects.MakeBiasNcomb( # # BiasCombImg, BiasTag = effects.MakeBiasNcomb(
# self.npix_x, self.npix_y, # # self.npix_x, self.npix_y,
# bias_level=float(self.bias_level), # # bias_level=float(self.bias_level),
# ncombine=1, read_noise=self.read_noise, gain=1, # # ncombine=1, read_noise=self.read_noise, gain=1,
# seed=SeedBiasNonuni+self.chipID, # # seed=SeedBiasNonuni+self.chipID,
# logger=self.logger) # # logger=self.logger)
BiasCombImg = galsim.Image( # BiasCombImg = galsim.Image(
self.npix_x, self.npix_y, init_value=0) # self.npix_x, self.npix_y, init_value=0)
if config["ins_effects"]["add_bias"] == True: # if config["ins_effects"]["add_bias"] == True:
biaslevel = self.bias_level # biaslevel = self.bias_level
overscan = biaslevel-2 # overscan = biaslevel-2
elif config["ins_effects"]["add_bias"] == False: # elif config["ins_effects"]["add_bias"] == False:
biaslevel = 0 # biaslevel = 0
overscan = 0 # overscan = 0
# Readout noise for Biases is not generated with random seeds. So readout noise for bias images can't be reproduced. # # Readout noise for Biases is not generated with random seeds. So readout noise for bias images can't be reproduced.
if config["ins_effects"]["cosmic_ray"] == True: # if config["ins_effects"]["cosmic_ray"] == True:
if config["ins_effects"]["cray_differ"] == True: # if config["ins_effects"]["cray_differ"] == True:
cr_map, cr_event_num = effects.produceCR_Map( # cr_map, cr_event_num = effects.produceCR_Map(
xLen=self.npix_x, yLen=self.npix_y, # xLen=self.npix_x, yLen=self.npix_y,
exTime=0.01, # exTime=0.01,
cr_pixelRatio=0.003 * # cr_pixelRatio=0.003 *
(0.01+0.5*self.readout_time)/150., # (0.01+0.5*self.readout_time)/150.,
gain=self.gain, # gain=self.gain,
attachedSizes=self.attachedSizes, # attachedSizes=self.attachedSizes,
seed=SeedCosmicRay+pointing_ID*30+self.chipID+1) # seed=SeedCosmicRay+pointing_ID*30+self.chipID+1)
# seed: obj-imaging:+0; bias:+1; dark:+2; flat:+3; # # seed: obj-imaging:+0; bias:+1; dark:+2; flat:+3;
BiasCombImg += cr_map # BiasCombImg += cr_map
del cr_map # del cr_map
# Apply Bad lines # # Apply Bad lines
if config["ins_effects"]["add_badcolumns"] == True: # if config["ins_effects"]["add_badcolumns"] == True:
BiasCombImg = effects.BadColumns( # BiasCombImg = effects.BadColumns(
BiasCombImg-float(self.bias_level)+5, seed=SeedBadColumns, chipid=self.chipID, logger=self.logger) + float(self.bias_level)-5 # BiasCombImg-float(self.bias_level)+5, seed=SeedBadColumns, chipid=self.chipID, logger=self.logger) + float(self.bias_level)-5
# Non-Linearity for Bias # # Non-Linearity for Bias
if config["ins_effects"]["non_linear"] == True: # if config["ins_effects"]["non_linear"] == True:
if self.logger is not None: # if self.logger is not None:
self.logger.info( # self.logger.info(
" Applying Non-Linearity on the Bias image") # " Applying Non-Linearity on the Bias image")
else: # else:
print( # print(
" Applying Non-Linearity on the Bias image", flush=True) # " Applying Non-Linearity on the Bias image", flush=True)
BiasCombImg = effects.NonLinearity( # BiasCombImg = effects.NonLinearity(
GSImage=BiasCombImg, beta1=5.e-7, beta2=0) # GSImage=BiasCombImg, beta1=5.e-7, beta2=0)
# START # # START
pre1 = self.prescan_x # 27 # pre1 = self.prescan_x # 27
over1 = self.overscan_x # 71 # over1 = self.overscan_x # 71
pre2 = self.prescan_y # 0 #4 # pre2 = self.prescan_y # 0 #4
over2 = self.overscan_y # 84 #80 # over2 = self.overscan_y # 84 #80
# prescan & overscan # # prescan & overscan
if config["ins_effects"]["add_prescan"] == True: # if config["ins_effects"]["add_prescan"] == True:
chip_utils.log_info( # chip_utils.log_info(
msg=" Apply pre/over-scan", logger=self.logger) # msg=" Apply pre/over-scan", logger=self.logger)
BiasCombImg = chip_utils.AddPreScan( # BiasCombImg = chip_utils.AddPreScan(
GSImage=BiasCombImg, pre1=pre1, pre2=pre2, over1=over1, over2=over2) # GSImage=BiasCombImg, pre1=pre1, pre2=pre2, over1=over1, over2=over2)
# 1*16 output # # 1*16 output
if config["ins_effects"]["format_output"] == True: # if config["ins_effects"]["format_output"] == True:
chip_utils.log_info( # chip_utils.log_info(
msg=" Apply 1*16 format", logger=self.logger) # msg=" Apply 1*16 format", logger=self.logger)
BiasCombImg = chip_utils.formatOutput(GSImage=BiasCombImg) # BiasCombImg = chip_utils.formatOutput(GSImage=BiasCombImg)
self.nsecy = 1 # self.nsecy = 1
self.nsecx = 16 # self.nsecx = 16
# END # # END
# Add Bias level # # Add Bias level
if config["ins_effects"]["add_bias"] == True: # if config["ins_effects"]["add_bias"] == True:
if self.logger is not None: # if self.logger is not None:
self.logger.info( # self.logger.info(
" Adding Bias level and 16-channel non-uniformity") # " Adding Bias level and 16-channel non-uniformity")
else: # else:
print(" Adding Bias level and 16-channel non-uniformity") # print(" Adding Bias level and 16-channel non-uniformity")
BiasCombImg = effects.AddBiasNonUniform16(BiasCombImg, # BiasCombImg = effects.AddBiasNonUniform16(BiasCombImg,
bias_level=biaslevel, # bias_level=biaslevel,
nsecy=self.nsecy, nsecx=self.nsecx, # nsecy=self.nsecy, nsecx=self.nsecx,
seed=SeedBiasNonuni+self.chipID, # seed=SeedBiasNonuni+self.chipID,
logger=self.logger) # logger=self.logger)
rng = galsim.UniformDeviate() # rng = galsim.UniformDeviate()
ncombine = 1 # ncombine = 1
NoiseBias = galsim.GaussianNoise( # NoiseBias = galsim.GaussianNoise(
rng=rng, sigma=self.read_noise*ncombine**0.5) # rng=rng, sigma=self.read_noise*ncombine**0.5)
BiasCombImg.addNoise(NoiseBias) # BiasCombImg.addNoise(NoiseBias)
BiasCombImg, self.gain_channel = effects.ApplyGainNonUniform16(BiasCombImg, gain=self.gain, # BiasCombImg, self.gain_channel = effects.ApplyGainNonUniform16(BiasCombImg, gain=self.gain,
nsecy=self.nsecy, nsecx=self.nsecx, # nsecy=self.nsecy, nsecx=self.nsecx,
seed=SeedGainNonuni+self.chipID, # seed=SeedGainNonuni+self.chipID,
logger=self.logger) # logger=self.logger)
# BiasCombImg = effects.AddOverscan( # # BiasCombImg = effects.AddOverscan(
# BiasCombImg, # # BiasCombImg,
# overscan=float(config["ins_effects"]["bias_level"])-2, gain=self.gain, # # overscan=float(config["ins_effects"]["bias_level"])-2, gain=self.gain,
# widthl=27, widthr=27, widtht=8, widthb=8) # # widthl=27, widthr=27, widtht=8, widthb=8)
BiasCombImg.replaceNegative(replace_value=0) # BiasCombImg.replaceNegative(replace_value=0)
BiasCombImg.quantize() # BiasCombImg.quantize()
BiasCombImg = galsim.ImageUS(BiasCombImg) # BiasCombImg = galsim.ImageUS(BiasCombImg)
timestamp_obs += 10 * 60 # timestamp_obs += 10 * 60
chip_utils.outputCal( # chip_utils.outputCal(
chip=self, # chip=self,
img=BiasCombImg, # img=BiasCombImg,
ra_cen=ra_cen, # ra_cen=ra_cen,
dec_cen=dec_cen, # dec_cen=dec_cen,
img_rot=img_rot, # img_rot=img_rot,
im_type='BIAS', # im_type='BIAS',
pointing_ID=pointing_ID, # pointing_ID=pointing_ID,
output_dir=chip_output.subdir, # output_dir=chip_output.subdir,
exptime=0.0, # exptime=0.0,
project_cycle=config["project_cycle"], # project_cycle=config["project_cycle"],
run_counter=config["run_counter"], # run_counter=config["run_counter"],
timestamp=timestamp_obs) # timestamp=timestamp_obs)
del BiasCombImg # del BiasCombImg
# Export combined (ncombine, Vignetting + PRNU) & single vignetting flat-field file # # Export combined (ncombine, Vignetting + PRNU) & single vignetting flat-field file
if config["ins_effects"]["flat_fielding"] == True and config["output_setting"]["flat_output"] == True and pointing_type == 'CAL': # if config["ins_effects"]["flat_fielding"] == True and config["output_setting"]["flat_output"] == True and pointing_type == 'CAL':
if self.logger is not None: # if self.logger is not None:
self.logger.info(" Output N frame Flat-Field files") # self.logger.info(" Output N frame Flat-Field files")
else: # else:
print(" Output N frame Flat-Field files", flush=True) # print(" Output N frame Flat-Field files", flush=True)
NFlat = int(config["output_setting"]["NFlat"]) # NFlat = int(config["output_setting"]["NFlat"])
if config["ins_effects"]["add_bias"] == True: # if config["ins_effects"]["add_bias"] == True:
biaslevel = self.bias_level # biaslevel = self.bias_level
overscan = biaslevel-2 # overscan = biaslevel-2
elif config["ins_effects"]["add_bias"] == False: # elif config["ins_effects"]["add_bias"] == False:
biaslevel = 0 # biaslevel = 0
overscan = 0 # overscan = 0
darklevel = self.dark_noise * \ # darklevel = self.dark_noise * \
(self.flat_exptime+0.5*self.readout_time) # (self.flat_exptime+0.5*self.readout_time)
for i in range(NFlat): # for i in range(NFlat):
FlatSingle = flat_img * prnu_img + darklevel # FlatSingle = flat_img * prnu_img + darklevel
FlatCombImg, FlatTag = effects.MakeFlatNcomb( # FlatCombImg, FlatTag = effects.MakeFlatNcomb(
flat_single_image=FlatSingle, # flat_single_image=FlatSingle,
ncombine=1, # ncombine=1,
read_noise=self.read_noise, # read_noise=self.read_noise,
gain=1, # gain=1,
overscan=overscan, # overscan=overscan,
biaslevel=0, # biaslevel=0,
seed_bias=SeedDefective+self.chipID, # seed_bias=SeedDefective+self.chipID,
logger=self.logger # logger=self.logger
) # )
if config["ins_effects"]["cosmic_ray"] == True: # if config["ins_effects"]["cosmic_ray"] == True:
if config["ins_effects"]["cray_differ"] == True: # if config["ins_effects"]["cray_differ"] == True:
cr_map, cr_event_num = effects.produceCR_Map( # cr_map, cr_event_num = effects.produceCR_Map(
xLen=self.npix_x, yLen=self.npix_y, # xLen=self.npix_x, yLen=self.npix_y,
exTime=self.flat_exptime+0.5*self.readout_time, # exTime=self.flat_exptime+0.5*self.readout_time,
cr_pixelRatio=0.003 * # cr_pixelRatio=0.003 *
(self.flat_exptime+0.5*self.readout_time)/150., # (self.flat_exptime+0.5*self.readout_time)/150.,
gain=self.gain, # gain=self.gain,
attachedSizes=self.attachedSizes, # attachedSizes=self.attachedSizes,
seed=SeedCosmicRay+pointing_ID*30+self.chipID+3) # seed=SeedCosmicRay+pointing_ID*30+self.chipID+3)
# seed: obj-imaging:+0; bias:+1; dark:+2; flat:+3; # # seed: obj-imaging:+0; bias:+1; dark:+2; flat:+3;
FlatCombImg += cr_map # FlatCombImg += cr_map
del cr_map # del cr_map
# Add Hot Pixels or/and Dead Pixels # # Add Hot Pixels or/and Dead Pixels
rgbadpix = Generator(PCG64(int(SeedDefective+self.chipID))) # rgbadpix = Generator(PCG64(int(SeedDefective+self.chipID)))
badfraction = 5E-5*(rgbadpix.random()*0.5+0.7) # badfraction = 5E-5*(rgbadpix.random()*0.5+0.7)
FlatCombImg = effects.DefectivePixels( # FlatCombImg = effects.DefectivePixels(
FlatCombImg, IfHotPix=BoolHotPix, IfDeadPix=BoolDeadPix, fraction=badfraction, seed=SeedDefective+self.chipID, biaslevel=0) # FlatCombImg, IfHotPix=BoolHotPix, IfDeadPix=BoolDeadPix, fraction=badfraction, seed=SeedDefective+self.chipID, biaslevel=0)
# Apply Bad lines # # Apply Bad lines
if config["ins_effects"]["add_badcolumns"] == True: # if config["ins_effects"]["add_badcolumns"] == True:
FlatCombImg = effects.BadColumns( # FlatCombImg = effects.BadColumns(
FlatCombImg, seed=SeedBadColumns, chipid=self.chipID, logger=self.logger) # FlatCombImg, seed=SeedBadColumns, chipid=self.chipID, logger=self.logger)
if config["ins_effects"]["non_linear"] == True: # if config["ins_effects"]["non_linear"] == True:
if self.logger is not None: # if self.logger is not None:
self.logger.info( # self.logger.info(
" Applying Non-Linearity on the Flat image") # " Applying Non-Linearity on the Flat image")
else: # else:
print( # print(
" Applying Non-Linearity on the Flat image", flush=True) # " Applying Non-Linearity on the Flat image", flush=True)
FlatCombImg = effects.NonLinearity( # FlatCombImg = effects.NonLinearity(
GSImage=FlatCombImg, beta1=5.e-7, beta2=0) # GSImage=FlatCombImg, beta1=5.e-7, beta2=0)
# if config["ins_effects"]["cte_trail"] == True: # # if config["ins_effects"]["cte_trail"] == True:
# FlatCombImg = effects.CTE_Effect(GSImage=FlatCombImg, threshold=3) # # FlatCombImg = effects.CTE_Effect(GSImage=FlatCombImg, threshold=3)
# START # # START
pre1 = self.prescan_x # 27 # pre1 = self.prescan_x # 27
over1 = self.overscan_x # 71 # over1 = self.overscan_x # 71
pre2 = self.prescan_y # 0 #4 # pre2 = self.prescan_y # 0 #4
over2 = self.overscan_y # 84 #80 # over2 = self.overscan_y # 84 #80
if config["ins_effects"]["cte_trail"] == True: # if config["ins_effects"]["cte_trail"] == True:
chip_utils.log_info( # chip_utils.log_info(
msg=" Apply CTE Effect", logger=self.logger) # msg=" Apply CTE Effect", logger=self.logger)
# img = effects.CTE_Effect(GSImage=img, threshold=27) # # img = effects.CTE_Effect(GSImage=img, threshold=27)
# CTI_modeling # # CTI_modeling
# 2*8 -> 1*16 img-layout # # 2*8 -> 1*16 img-layout
FlatCombImg = chip_utils.formatOutput(GSImage=FlatCombImg) # FlatCombImg = chip_utils.formatOutput(GSImage=FlatCombImg)
self.nsecy = 1 # self.nsecy = 1
self.nsecx = 16 # self.nsecx = 16
img_arr = FlatCombImg.array # img_arr = FlatCombImg.array
ny, nx = img_arr.shape # ny, nx = img_arr.shape
dx = int(nx/self.nsecx) # dx = int(nx/self.nsecx)
dy = int(ny/self.nsecy) # dy = int(ny/self.nsecy)
newimg = galsim.Image(nx, int(ny+over2), init_value=0) # newimg = galsim.Image(nx, int(ny+over2), init_value=0)
for ichannel in range(16): # for ichannel in range(16):
print('\n***add CTI effects: pointing-{:} chip-{:} channel-{:}***'.format( # print('\n***add CTI effects: pointing-{:} chip-{:} channel-{:}***'.format(
pointing_ID, self.chipID, ichannel+1)) # pointing_ID, self.chipID, ichannel+1))
# nx,ny,noverscan,nsp,nmax = 4608,4616,84,3,10 # # nx,ny,noverscan,nsp,nmax = 4608,4616,84,3,10
noverscan, nsp, nmax = over2, 3, 10 # noverscan, nsp, nmax = over2, 3, 10
beta, w, c = 0.478, 84700, 0 # beta, w, c = 0.478, 84700, 0
t = np.array([0.74, 7.7, 37], dtype=np.float32) # t = np.array([0.74, 7.7, 37], dtype=np.float32)
rho_trap = np.array([0.6, 1.6, 1.4], dtype=np.float32) # rho_trap = np.array([0.6, 1.6, 1.4], dtype=np.float32)
trap_seeds = np.array( # trap_seeds = np.array(
[0, 1000, 10000], dtype=np.int32) + ichannel + self.chipID*16 # [0, 1000, 10000], dtype=np.int32) + ichannel + self.chipID*16
release_seed = 50 + ichannel + pointing_ID*30 + self.chipID*16 # release_seed = 50 + ichannel + pointing_ID*30 + self.chipID*16
newimg.array[:, 0+ichannel*dx:dx+ichannel*dx] = CTI_sim( # newimg.array[:, 0+ichannel*dx:dx+ichannel*dx] = CTI_sim(
img_arr[:, 0+ichannel*dx:dx+ichannel*dx], dx, dy, noverscan, nsp, nmax, beta, w, c, t, rho_trap, trap_seeds, release_seed) # img_arr[:, 0+ichannel*dx:dx+ichannel*dx], dx, dy, noverscan, nsp, nmax, beta, w, c, t, rho_trap, trap_seeds, release_seed)
newimg.wcs = FlatCombImg.wcs # newimg.wcs = FlatCombImg.wcs
del FlatCombImg # del FlatCombImg
FlatCombImg = newimg # FlatCombImg = newimg
# 1*16 -> 2*8 img-layout # # 1*16 -> 2*8 img-layout
FlatCombImg = chip_utils.formatRevert(GSImage=FlatCombImg) # FlatCombImg = chip_utils.formatRevert(GSImage=FlatCombImg)
self.nsecy = 2 # self.nsecy = 2
self.nsecx = 8 # self.nsecx = 8
# prescan & overscan # # prescan & overscan
if config["ins_effects"]["add_prescan"] == True: # if config["ins_effects"]["add_prescan"] == True:
chip_utils.log_info( # chip_utils.log_info(
msg=" Apply pre/over-scan", logger=self.logger) # msg=" Apply pre/over-scan", logger=self.logger)
if config["ins_effects"]["cte_trail"] == False: # if config["ins_effects"]["cte_trail"] == False:
FlatCombImg = chip_utils.AddPreScan( # FlatCombImg = chip_utils.AddPreScan(
GSImage=FlatCombImg, pre1=pre1, pre2=pre2, over1=over1, over2=over2) # GSImage=FlatCombImg, pre1=pre1, pre2=pre2, over1=over1, over2=over2)
if config["ins_effects"]["cte_trail"] == True: # if config["ins_effects"]["cte_trail"] == True:
FlatCombImg = chip_utils.AddPreScan( # FlatCombImg = chip_utils.AddPreScan(
GSImage=FlatCombImg, pre1=pre1, pre2=pre2, over1=over1, over2=0) # GSImage=FlatCombImg, pre1=pre1, pre2=pre2, over1=over1, over2=0)
# 1*16 output # # 1*16 output
if config["ins_effects"]["format_output"] == True: # if config["ins_effects"]["format_output"] == True:
chip_utils.log_info( # chip_utils.log_info(
msg=" Apply 1*16 format", logger=self.logger) # msg=" Apply 1*16 format", logger=self.logger)
FlatCombImg = chip_utils.formatOutput(GSImage=FlatCombImg) # FlatCombImg = chip_utils.formatOutput(GSImage=FlatCombImg)
self.nsecy = 1 # self.nsecy = 1
self.nsecx = 16 # self.nsecx = 16
# END # # END
# Add Bias level # # Add Bias level
if config["ins_effects"]["add_bias"] == True: # if config["ins_effects"]["add_bias"] == True:
if self.logger is not None: # if self.logger is not None:
self.logger.info( # self.logger.info(
" Adding Bias level and 16-channel non-uniformity") # " Adding Bias level and 16-channel non-uniformity")
else: # else:
print(" Adding Bias level and 16-channel non-uniformity") # print(" Adding Bias level and 16-channel non-uniformity")
# img += float(config["ins_effects"]["bias_level"]) # # img += float(config["ins_effects"]["bias_level"])
FlatCombImg = effects.AddBiasNonUniform16(FlatCombImg, # FlatCombImg = effects.AddBiasNonUniform16(FlatCombImg,
bias_level=biaslevel, # bias_level=biaslevel,
nsecy=self.nsecy, nsecx=self.nsecx, # nsecy=self.nsecy, nsecx=self.nsecx,
seed=SeedBiasNonuni+self.chipID, # seed=SeedBiasNonuni+self.chipID,
logger=self.logger) # logger=self.logger)
# Add Read-out Noise # # Add Read-out Noise
if config["ins_effects"]["add_readout"] == True: # if config["ins_effects"]["add_readout"] == True:
seed = int(config["random_seeds"]["seed_readout"] # seed = int(config["random_seeds"]["seed_readout"]
) + pointing_ID*30 + self.chipID + 3 # ) + pointing_ID*30 + self.chipID + 3
rng_readout = galsim.BaseDeviate(seed) # rng_readout = galsim.BaseDeviate(seed)
readout_noise = galsim.GaussianNoise( # readout_noise = galsim.GaussianNoise(
rng=rng_readout, sigma=self.read_noise) # rng=rng_readout, sigma=self.read_noise)
FlatCombImg.addNoise(readout_noise) # FlatCombImg.addNoise(readout_noise)
FlatCombImg, self.gain_channel = effects.ApplyGainNonUniform16(FlatCombImg, gain=self.gain, # FlatCombImg, self.gain_channel = effects.ApplyGainNonUniform16(FlatCombImg, gain=self.gain,
nsecy=self.nsecy, nsecx=self.nsecx, # nsecy=self.nsecy, nsecx=self.nsecx,
seed=SeedGainNonuni+self.chipID, # seed=SeedGainNonuni+self.chipID,
logger=self.logger) # logger=self.logger)
# FlatCombImg = effects.AddOverscan(FlatCombImg, overscan=overscan, gain=self.gain, widthl=27, widthr=27, widtht=8, widthb=8) # # FlatCombImg = effects.AddOverscan(FlatCombImg, overscan=overscan, gain=self.gain, widthl=27, widthr=27, widtht=8, widthb=8)
FlatCombImg.replaceNegative(replace_value=0) # FlatCombImg.replaceNegative(replace_value=0)
FlatCombImg.quantize() # FlatCombImg.quantize()
FlatCombImg = galsim.ImageUS(FlatCombImg) # FlatCombImg = galsim.ImageUS(FlatCombImg)
timestamp_obs += 10 * 60 # timestamp_obs += 10 * 60
chip_utils.outputCal( # chip_utils.outputCal(
chip=self, # chip=self,
img=FlatCombImg, # img=FlatCombImg,
ra_cen=ra_cen, # ra_cen=ra_cen,
dec_cen=dec_cen, # dec_cen=dec_cen,
img_rot=img_rot, # img_rot=img_rot,
im_type='FLAT', # im_type='FLAT',
pointing_ID=pointing_ID, # pointing_ID=pointing_ID,
output_dir=chip_output.subdir, # output_dir=chip_output.subdir,
exptime=self.flat_exptime, # exptime=self.flat_exptime,
project_cycle=config["project_cycle"], # project_cycle=config["project_cycle"],
run_counter=config["run_counter"], # run_counter=config["run_counter"],
timestamp=timestamp_obs) # timestamp=timestamp_obs)
del FlatCombImg, FlatSingle, prnu_img # del FlatCombImg, FlatSingle, prnu_img
# flat_img.replaceNegative(replace_value=0) # # flat_img.replaceNegative(replace_value=0)
# flat_img.quantize() # # flat_img.quantize()
# galsim.ImageUS(flat_img).write("%s/FlatImg_Vignette_%s.fits" % (chip_output.subdir, self.chipID)) # # galsim.ImageUS(flat_img).write("%s/FlatImg_Vignette_%s.fits" % (chip_output.subdir, self.chipID))
del flat_img # del flat_img
# Export Dark current images # # Export Dark current images
if config["ins_effects"]["add_dark"] == True and config["output_setting"]["dark_output"] == True and pointing_type == 'CAL': # if config["ins_effects"]["add_dark"] == True and config["output_setting"]["dark_output"] == True and pointing_type == 'CAL':
if self.logger is not None: # if self.logger is not None:
self.logger.info(" Output N frame Dark Current files") # self.logger.info(" Output N frame Dark Current files")
else: # else:
print(" Output N frame Dark Current files", flush=True) # print(" Output N frame Dark Current files", flush=True)
NDark = int(config["output_setting"]["NDark"]) # NDark = int(config["output_setting"]["NDark"])
if config["ins_effects"]["add_bias"] == True: # if config["ins_effects"]["add_bias"] == True:
biaslevel = self.bias_level # biaslevel = self.bias_level
overscan = biaslevel-2 # overscan = biaslevel-2
elif config["ins_effects"]["add_bias"] == False: # elif config["ins_effects"]["add_bias"] == False:
biaslevel = 0 # biaslevel = 0
overscan = 0 # overscan = 0
for i in range(NDark): # for i in range(NDark):
DarkCombImg, DarkTag = effects.MakeDarkNcomb( # DarkCombImg, DarkTag = effects.MakeDarkNcomb(
self.npix_x, self.npix_y, # self.npix_x, self.npix_y,
overscan=overscan, bias_level=0, darkpsec=0.02, exptime=self.dark_exptime+0.5*self.readout_time, # overscan=overscan, bias_level=0, darkpsec=0.02, exptime=self.dark_exptime+0.5*self.readout_time,
ncombine=1, read_noise=self.read_noise, # ncombine=1, read_noise=self.read_noise,
gain=1, seed_bias=SeedBiasNonuni+self.chipID, # gain=1, seed_bias=SeedBiasNonuni+self.chipID,
logger=self.logger) # logger=self.logger)
if config["ins_effects"]["cosmic_ray"] == True: # if config["ins_effects"]["cosmic_ray"] == True:
if config["ins_effects"]["cray_differ"] == True: # if config["ins_effects"]["cray_differ"] == True:
cr_map, cr_event_num = effects.produceCR_Map( # cr_map, cr_event_num = effects.produceCR_Map(
xLen=self.npix_x, yLen=self.npix_y, # xLen=self.npix_x, yLen=self.npix_y,
exTime=self.dark_exptime+0.5*self.readout_time, # exTime=self.dark_exptime+0.5*self.readout_time,
cr_pixelRatio=0.003 * # cr_pixelRatio=0.003 *
(self.dark_exptime+0.5*self.readout_time)/150., # (self.dark_exptime+0.5*self.readout_time)/150.,
gain=self.gain, # gain=self.gain,
attachedSizes=self.attachedSizes, # attachedSizes=self.attachedSizes,
seed=SeedCosmicRay+pointing_ID*30+self.chipID+2) # seed=SeedCosmicRay+pointing_ID*30+self.chipID+2)
# seed: obj-imaging:+0; bias:+1; dark:+2; flat:+3; # # seed: obj-imaging:+0; bias:+1; dark:+2; flat:+3;
DarkCombImg += cr_map # DarkCombImg += cr_map
cr_map[cr_map > 65535] = 65535 # cr_map[cr_map > 65535] = 65535
cr_map[cr_map < 0] = 0 # cr_map[cr_map < 0] = 0
crmap_gsimg = galsim.Image(cr_map, dtype=np.uint16) # crmap_gsimg = galsim.Image(cr_map, dtype=np.uint16)
del cr_map # del cr_map
# START # # START
# prescan & overscan # # prescan & overscan
if config["ins_effects"]["add_prescan"] == True: # if config["ins_effects"]["add_prescan"] == True:
chip_utils.log_info( # chip_utils.log_info(
msg=" Apply pre/over-scan", logger=self.logger) # msg=" Apply pre/over-scan", logger=self.logger)
crmap_gsimg = chip_utils.AddPreScan( # crmap_gsimg = chip_utils.AddPreScan(
GSImage=crmap_gsimg, pre1=pre1, pre2=pre2, over1=over1, over2=over2) # GSImage=crmap_gsimg, pre1=pre1, pre2=pre2, over1=over1, over2=over2)
# 1*16 output # # 1*16 output
if config["ins_effects"]["format_output"] == True: # if config["ins_effects"]["format_output"] == True:
chip_utils.log_info( # chip_utils.log_info(
msg=" Apply 1*16 format", logger=self.logger) # msg=" Apply 1*16 format", logger=self.logger)
crmap_gsimg = chip_utils.formatOutput( # crmap_gsimg = chip_utils.formatOutput(
GSImage=crmap_gsimg) # GSImage=crmap_gsimg)
self.nsecy = 1 # self.nsecy = 1
self.nsecx = 16 # self.nsecx = 16
# END # # END
chip_utils.outputCal( # chip_utils.outputCal(
chip=self, # chip=self,
img=crmap_gsimg, # img=crmap_gsimg,
ra_cen=ra_cen, # ra_cen=ra_cen,
dec_cen=dec_cen, # dec_cen=dec_cen,
img_rot=img_rot, # img_rot=img_rot,
im_type='CRD', # im_type='CRD',
pointing_ID=pointing_ID, # pointing_ID=pointing_ID,
output_dir=chip_output.subdir, # output_dir=chip_output.subdir,
exptime=self.dark_exptime, # exptime=self.dark_exptime,
project_cycle=config["project_cycle"], # project_cycle=config["project_cycle"],
run_counter=config["run_counter"], # run_counter=config["run_counter"],
timestamp=timestamp_obs) # timestamp=timestamp_obs)
del crmap_gsimg # del crmap_gsimg
# Add Hot Pixels or/and Dead Pixels # # Add Hot Pixels or/and Dead Pixels
rgbadpix = Generator(PCG64(int(SeedDefective+self.chipID))) # rgbadpix = Generator(PCG64(int(SeedDefective+self.chipID)))
badfraction = 5E-5*(rgbadpix.random()*0.5+0.7) # badfraction = 5E-5*(rgbadpix.random()*0.5+0.7)
DarkCombImg = effects.DefectivePixels( # DarkCombImg = effects.DefectivePixels(
DarkCombImg, IfHotPix=BoolHotPix, IfDeadPix=BoolDeadPix, fraction=badfraction, seed=SeedDefective+self.chipID, biaslevel=0) # DarkCombImg, IfHotPix=BoolHotPix, IfDeadPix=BoolDeadPix, fraction=badfraction, seed=SeedDefective+self.chipID, biaslevel=0)
# Apply Bad lines # # Apply Bad lines
if config["ins_effects"]["add_badcolumns"] == True: # if config["ins_effects"]["add_badcolumns"] == True:
DarkCombImg = effects.BadColumns( # DarkCombImg = effects.BadColumns(
DarkCombImg, seed=SeedBadColumns, chipid=self.chipID, logger=self.logger) # DarkCombImg, seed=SeedBadColumns, chipid=self.chipID, logger=self.logger)
# Non-Linearity for Dark # # Non-Linearity for Dark
if config["ins_effects"]["non_linear"] == True: # if config["ins_effects"]["non_linear"] == True:
if self.logger is not None: # if self.logger is not None:
self.logger.info( # self.logger.info(
" Applying Non-Linearity on the Dark image") # " Applying Non-Linearity on the Dark image")
else: # else:
print( # print(
" Applying Non-Linearity on the Dark image", flush=True) # " Applying Non-Linearity on the Dark image", flush=True)
DarkCombImg = effects.NonLinearity( # DarkCombImg = effects.NonLinearity(
GSImage=DarkCombImg, beta1=5.e-7, beta2=0) # GSImage=DarkCombImg, beta1=5.e-7, beta2=0)
# if config["ins_effects"]["cte_trail"] == True: # # if config["ins_effects"]["cte_trail"] == True:
# DarkCombImg = effects.CTE_Effect(GSImage=DarkCombImg, threshold=3) # # DarkCombImg = effects.CTE_Effect(GSImage=DarkCombImg, threshold=3)
# START # # START
pre1 = self.prescan_x # 27 # pre1 = self.prescan_x # 27
over1 = self.overscan_x # 71 # over1 = self.overscan_x # 71
pre2 = self.prescan_y # 0 #4 # pre2 = self.prescan_y # 0 #4
over2 = self.overscan_y # 84 #80 # over2 = self.overscan_y # 84 #80
if config["ins_effects"]["cte_trail"] == True: # if config["ins_effects"]["cte_trail"] == True:
chip_utils.log_info( # chip_utils.log_info(
msg=" Apply CTE Effect", logger=self.logger) # msg=" Apply CTE Effect", logger=self.logger)
# img = effects.CTE_Effect(GSImage=img, threshold=27) # # img = effects.CTE_Effect(GSImage=img, threshold=27)
# CTI_modeling # # CTI_modeling
# 2*8 -> 1*16 img-layout # # 2*8 -> 1*16 img-layout
DarkCombImg = chip_utils.formatOutput(GSImage=DarkCombImg) # DarkCombImg = chip_utils.formatOutput(GSImage=DarkCombImg)
self.nsecy = 1 # self.nsecy = 1
self.nsecx = 16 # self.nsecx = 16
img_arr = DarkCombImg.array # img_arr = DarkCombImg.array
ny, nx = img_arr.shape # ny, nx = img_arr.shape
dx = int(nx/self.nsecx) # dx = int(nx/self.nsecx)
dy = int(ny/self.nsecy) # dy = int(ny/self.nsecy)
newimg = galsim.Image(nx, int(ny+over2), init_value=0) # newimg = galsim.Image(nx, int(ny+over2), init_value=0)
for ichannel in range(16): # for ichannel in range(16):
print('\n***add CTI effects: pointing-{:} chip-{:} channel-{:}***'.format( # print('\n***add CTI effects: pointing-{:} chip-{:} channel-{:}***'.format(
pointing_ID, self.chipID, ichannel+1)) # pointing_ID, self.chipID, ichannel+1))
# nx,ny,noverscan,nsp,nmax = 4608,4616,84,3,10 # # nx,ny,noverscan,nsp,nmax = 4608,4616,84,3,10
noverscan, nsp, nmax = over2, 3, 10 # noverscan, nsp, nmax = over2, 3, 10
beta, w, c = 0.478, 84700, 0 # beta, w, c = 0.478, 84700, 0
t = np.array([0.74, 7.7, 37], dtype=np.float32) # t = np.array([0.74, 7.7, 37], dtype=np.float32)
rho_trap = np.array([0.6, 1.6, 1.4], dtype=np.float32) # rho_trap = np.array([0.6, 1.6, 1.4], dtype=np.float32)
trap_seeds = np.array( # trap_seeds = np.array(
[0, 1000, 10000], dtype=np.int32) + ichannel + self.chipID*16 # [0, 1000, 10000], dtype=np.int32) + ichannel + self.chipID*16
release_seed = 50 + ichannel + pointing_ID*30 + self.chipID*16 # release_seed = 50 + ichannel + pointing_ID*30 + self.chipID*16
newimg.array[:, 0+ichannel*dx:dx+ichannel*dx] = CTI_sim( # newimg.array[:, 0+ichannel*dx:dx+ichannel*dx] = CTI_sim(
img_arr[:, 0+ichannel*dx:dx+ichannel*dx], dx, dy, noverscan, nsp, nmax, beta, w, c, t, rho_trap, trap_seeds, release_seed) # img_arr[:, 0+ichannel*dx:dx+ichannel*dx], dx, dy, noverscan, nsp, nmax, beta, w, c, t, rho_trap, trap_seeds, release_seed)
newimg.wcs = DarkCombImg.wcs # newimg.wcs = DarkCombImg.wcs
del DarkCombImg # del DarkCombImg
DarkCombImg = newimg # DarkCombImg = newimg
# 1*16 -> 2*8 img-layout # # 1*16 -> 2*8 img-layout
DarkCombImg = chip_utils.formatRevert(GSImage=DarkCombImg) # DarkCombImg = chip_utils.formatRevert(GSImage=DarkCombImg)
self.nsecy = 2 # self.nsecy = 2
self.nsecx = 8 # self.nsecx = 8
# prescan & overscan # # prescan & overscan
if config["ins_effects"]["add_prescan"] == True: # if config["ins_effects"]["add_prescan"] == True:
chip_utils.log_info( # chip_utils.log_info(
msg=" Apply pre/over-scan", logger=self.logger) # msg=" Apply pre/over-scan", logger=self.logger)
if config["ins_effects"]["cte_trail"] == False: # if config["ins_effects"]["cte_trail"] == False:
DarkCombImg = chip_utils.AddPreScan( # DarkCombImg = chip_utils.AddPreScan(
GSImage=DarkCombImg, pre1=pre1, pre2=pre2, over1=over1, over2=over2) # GSImage=DarkCombImg, pre1=pre1, pre2=pre2, over1=over1, over2=over2)
if config["ins_effects"]["cte_trail"] == True: # if config["ins_effects"]["cte_trail"] == True:
DarkCombImg = chip_utils.AddPreScan( # DarkCombImg = chip_utils.AddPreScan(
GSImage=DarkCombImg, pre1=pre1, pre2=pre2, over1=over1, over2=0) # GSImage=DarkCombImg, pre1=pre1, pre2=pre2, over1=over1, over2=0)
# 1*16 output # # 1*16 output
if config["ins_effects"]["format_output"] == True: # if config["ins_effects"]["format_output"] == True:
chip_utils.log_info( # chip_utils.log_info(
msg=" Apply 1*16 format", logger=self.logger) # msg=" Apply 1*16 format", logger=self.logger)
DarkCombImg = chip_utils.formatOutput(GSImage=DarkCombImg) # DarkCombImg = chip_utils.formatOutput(GSImage=DarkCombImg)
self.nsecy = 1 # self.nsecy = 1
self.nsecx = 16 # self.nsecx = 16
# END # # END
# Add Bias level # # Add Bias level
if config["ins_effects"]["add_bias"] == True: # if config["ins_effects"]["add_bias"] == True:
if self.logger is not None: # if self.logger is not None:
self.logger.info( # self.logger.info(
" Adding Bias level and 16-channel non-uniformity") # " Adding Bias level and 16-channel non-uniformity")
else: # else:
print(" Adding Bias level and 16-channel non-uniformity") # print(" Adding Bias level and 16-channel non-uniformity")
# img += float(config["ins_effects"]["bias_level"]) # # img += float(config["ins_effects"]["bias_level"])
DarkCombImg = effects.AddBiasNonUniform16(DarkCombImg, # DarkCombImg = effects.AddBiasNonUniform16(DarkCombImg,
bias_level=biaslevel, # bias_level=biaslevel,
nsecy=self.nsecy, nsecx=self.nsecx, # nsecy=self.nsecy, nsecx=self.nsecx,
seed=SeedBiasNonuni+self.chipID, # seed=SeedBiasNonuni+self.chipID,
logger=self.logger) # logger=self.logger)
# Add Read-out Noise # # Add Read-out Noise
if config["ins_effects"]["add_readout"] == True: # if config["ins_effects"]["add_readout"] == True:
seed = int(config["random_seeds"]["seed_readout"] # seed = int(config["random_seeds"]["seed_readout"]
) + pointing_ID*30 + self.chipID + 2 # ) + pointing_ID*30 + self.chipID + 2
rng_readout = galsim.BaseDeviate(seed) # rng_readout = galsim.BaseDeviate(seed)
readout_noise = galsim.GaussianNoise( # readout_noise = galsim.GaussianNoise(
rng=rng_readout, sigma=self.read_noise) # rng=rng_readout, sigma=self.read_noise)
DarkCombImg.addNoise(readout_noise) # DarkCombImg.addNoise(readout_noise)
DarkCombImg, self.gain_channel = effects.ApplyGainNonUniform16( # DarkCombImg, self.gain_channel = effects.ApplyGainNonUniform16(
DarkCombImg, gain=self.gain, # DarkCombImg, gain=self.gain,
nsecy=self.nsecy, nsecx=self.nsecx, # nsecy=self.nsecy, nsecx=self.nsecx,
seed=SeedGainNonuni+self.chipID, # seed=SeedGainNonuni+self.chipID,
logger=self.logger) # logger=self.logger)
# DarkCombImg = effects.AddOverscan( # # DarkCombImg = effects.AddOverscan(
# DarkCombImg, # # DarkCombImg,
# overscan=overscan, gain=self.gain, # # overscan=overscan, gain=self.gain,
# widthl=27, widthr=27, widtht=8, widthb=8) # # widthl=27, widthr=27, widtht=8, widthb=8)
DarkCombImg.replaceNegative(replace_value=0) # DarkCombImg.replaceNegative(replace_value=0)
DarkCombImg.quantize() # DarkCombImg.quantize()
DarkCombImg = galsim.ImageUS(DarkCombImg) # DarkCombImg = galsim.ImageUS(DarkCombImg)
timestamp_obs += 10 * 60 # timestamp_obs += 10 * 60
chip_utils.outputCal( # chip_utils.outputCal(
chip=self, # chip=self,
img=DarkCombImg, # img=DarkCombImg,
ra_cen=ra_cen, # ra_cen=ra_cen,
dec_cen=dec_cen, # dec_cen=dec_cen,
img_rot=img_rot, # img_rot=img_rot,
im_type='DARK', # im_type='DARK',
pointing_ID=pointing_ID, # pointing_ID=pointing_ID,
output_dir=chip_output.subdir, # output_dir=chip_output.subdir,
exptime=self.dark_exptime, # exptime=self.dark_exptime,
project_cycle=config["project_cycle"], # project_cycle=config["project_cycle"],
run_counter=config["run_counter"], # run_counter=config["run_counter"],
timestamp=timestamp_obs) # timestamp=timestamp_obs)
del DarkCombImg # del DarkCombImg
# img = galsim.ImageUS(img) # # img = galsim.ImageUS(img)
# # 16 output channel, with each a single image file # # # 16 output channel, with each a single image file
# if config["ins_effects"]["readout16"] == True: # # if config["ins_effects"]["readout16"] == True:
# print(" 16 Output Channel simulation") # # print(" 16 Output Channel simulation")
# for coli in [0, 1]: # # for coli in [0, 1]:
# for rowi in range(8): # # for rowi in range(8):
# sub_img = effects.readout16( # # sub_img = effects.readout16(
# GSImage=img, # # GSImage=img,
# rowi=rowi, # # rowi=rowi,
# coli=coli, # # coli=coli,
# overscan_value=self.overscan) # # overscan_value=self.overscan)
# rowcoltag = str(rowi) + str(coli) # # rowcoltag = str(rowi) + str(coli)
# img_name_root = chip_output.img_name.split(".")[0] # # img_name_root = chip_output.img_name.split(".")[0]
# sub_img.write("%s/%s_%s.fits" % (chip_output.subdir, img_name_root, rowcoltag)) # # sub_img.write("%s/%s_%s.fits" % (chip_output.subdir, img_name_root, rowcoltag))
# del sub_img # # del sub_img
return img # return img
import galsim import galsim
import numpy as np import numpy as np
class FocalPlane(object): class FocalPlane(object):
def __init__(self, config=None, chip_list=None, survey_type='Photometric', bad_chips=None): def __init__(self, chip_list=None, survey_type='Photometric', bad_chips=None):
"""Get the focal plane layout """Get the focal plane layout
""" """
self.nchips = 42 self.nchips = 42
...@@ -14,7 +15,7 @@ class FocalPlane(object): ...@@ -14,7 +15,7 @@ class FocalPlane(object):
self.bad_chips = bad_chips self.bad_chips = bad_chips
for chip_id in bad_chips: for chip_id in bad_chips:
self.ignore_chips.append(chip_id) self.ignore_chips.append(chip_id)
if chip_list is not None: if chip_list is not None:
for i in range(42): for i in range(42):
if not (i+1 in chip_list): if not (i+1 in chip_list):
...@@ -39,25 +40,25 @@ class FocalPlane(object): ...@@ -39,25 +40,25 @@ class FocalPlane(object):
for i in range(1, 31): for i in range(1, 31):
self.ignore_chips.append(i) self.ignore_chips.append(i)
if config is not None: # if config is not None:
self.nchip_x = config["nchip_x"] # self.nchip_x = config["nchip_x"]
self.nchip_y = config["nchip_y"] # self.nchip_y = config["nchip_y"]
self.npix_tot_x = config["npix_tot_x"] # self.npix_tot_x = config["npix_tot_x"]
self.npix_tot_y = config["npix_tot_y"] # self.npix_tot_y = config["npix_tot_y"]
self.npix_gap_x = config["npix_gap_x"] # self.npix_gap_x = config["npix_gap_x"]
self.npix_gap_y = config["npix_gap_y"] # self.npix_gap_y = config["npix_gap_y"]
if "chipLabelIDs" in config: # if "chipLabelIDs" in config:
self.chipLabelIDs = config["chipLabelIDs"] # self.chipLabelIDs = config["chipLabelIDs"]
if "bad_chips" in config: # if "bad_chips" in config:
self.bad_chips = config["bad_chips"] # self.bad_chips = config["bad_chips"]
else: # else:
self.nchip_x = 6 self.nchip_x = 6
self.nchip_y = 5 self.nchip_y = 5
self.npix_tot_x = 59516 self.npix_tot_x = 59516
self.npix_tot_y = 49752 self.npix_tot_y = 49752
self.npix_gap_x = (534, 1309) self.npix_gap_x = (534, 1309)
self.npix_gap_y = 898 self.npix_gap_y = 898
self._getCenter() self._getCenter()
def _getCenter(self): def _getCenter(self):
...@@ -65,7 +66,7 @@ class FocalPlane(object): ...@@ -65,7 +66,7 @@ class FocalPlane(object):
self.cen_pix_y = 0 self.cen_pix_y = 0
def getChipLabel(self, chipID): def getChipLabel(self, chipID):
return str("0%d"%chipID)[-2:] return str("0%d" % chipID)[-2:]
def isBadChip(self, chipID): def isBadChip(self, chipID):
"""Check if chip #(chipID) on the focal plane is bad or not """Check if chip #(chipID) on the focal plane is bad or not
...@@ -89,7 +90,8 @@ class FocalPlane(object): ...@@ -89,7 +90,8 @@ class FocalPlane(object):
WCS of the focal plane WCS of the focal plane
""" """
if logger is not None: if logger is not None:
logger.info(" Construct the wcs of the entire image mosaic using Gnomonic/TAN projection") logger.info(
" Construct the wcs of the entire image mosaic using Gnomonic/TAN projection")
if (xcen == None) or (ycen == None): if (xcen == None) or (ycen == None):
xcen = self.cen_pix_x xcen = self.cen_pix_x
ycen = self.cen_pix_y ycen = self.cen_pix_y
...@@ -98,13 +100,14 @@ class FocalPlane(object): ...@@ -98,13 +100,14 @@ class FocalPlane(object):
# dvdx = -np.sin(img_rot.rad) * pix_scale # dvdx = -np.sin(img_rot.rad) * pix_scale
# dvdy = +np.cos(img_rot.rad) * pix_scale # dvdy = +np.cos(img_rot.rad) * pix_scale
dudx = -np.cos(img_rot.rad) * pix_scale dudx = -np.cos(img_rot.rad) * pix_scale
dudy = +np.sin(img_rot.rad) * pix_scale dudy = +np.sin(img_rot.rad) * pix_scale
dvdx = -np.sin(img_rot.rad) * pix_scale dvdx = -np.sin(img_rot.rad) * pix_scale
dvdy = -np.cos(img_rot.rad) * pix_scale dvdy = -np.cos(img_rot.rad) * pix_scale
moscen = galsim.PositionD(x=xcen, y=ycen) moscen = galsim.PositionD(x=xcen, y=ycen)
sky_center = galsim.CelestialCoord(ra=ra*galsim.degrees, dec=dec*galsim.degrees) sky_center = galsim.CelestialCoord(
ra=ra*galsim.degrees, dec=dec*galsim.degrees)
affine = galsim.AffineTransform(dudx, dudy, dvdx, dvdy, origin=moscen) affine = galsim.AffineTransform(dudx, dudy, dvdx, dvdy, origin=moscen)
WCS = galsim.TanWCS(affine, sky_center, units=galsim.arcsec) WCS = galsim.TanWCS(affine, sky_center, units=galsim.arcsec)
...@@ -115,10 +118,10 @@ class FocalPlane(object): ...@@ -115,10 +118,10 @@ class FocalPlane(object):
The sky coverage of an area The sky coverage of an area
""" """
r2d = 180.0/np.pi r2d = 180.0/np.pi
s1 = wcs.toWorld(galsim.PositionD(x0,y0)) s1 = wcs.toWorld(galsim.PositionD(x0, y0))
s2 = wcs.toWorld(galsim.PositionD(x0,y1)) s2 = wcs.toWorld(galsim.PositionD(x0, y1))
s3 = wcs.toWorld(galsim.PositionD(x1,y0)) s3 = wcs.toWorld(galsim.PositionD(x1, y0))
s4 = wcs.toWorld(galsim.PositionD(x1,y1)) s4 = wcs.toWorld(galsim.PositionD(x1, y1))
ra = [s1.ra.rad*r2d, s2.ra.rad*r2d, s3.ra.rad*r2d, s4.ra.rad*r2d] ra = [s1.ra.rad*r2d, s2.ra.rad*r2d, s3.ra.rad*r2d, s4.ra.rad*r2d]
dec = [s1.dec.rad*r2d, s2.dec.rad*r2d, s3.dec.rad*r2d, s4.dec.rad*r2d] dec = [s1.dec.rad*r2d, s2.dec.rad*r2d, s3.dec.rad*r2d, s4.dec.rad*r2d]
......
import unittest
import os
import galsim
from ObservationSim.Instrument import FocalPlane, Chip
class TestFocalPlane(unittest.TestCase):
def __init__(self, methodName='runTest'):
super(TestFocalPlane, self).__init__(methodName)
self.dataPath = os.path.join(
os.getenv('UNIT_TEST_DATA_ROOT'), 'csst_msc_sim/csst_fz_msc')
self.focal_plane = FocalPlane(
chip_list=['8'])
self.assertTrue(self.focal_plane.cen_pix_x == 0)
self.assertTrue(self.focal_plane.cen_pix_y == 0)
test_focal_plane_phot = FocalPlane(survey_type='Photometric')
test_focal_plane_spec = FocalPlane(survey_type='Spectroscopic')
test_focal_plane_FGS = FocalPlane(survey_type='FGS')
test_focal_plane_bad_chips = FocalPlane(bad_chips=["1"])
def test_fp_method(self):
wcs = self.focal_plane.getTanWCS(
192.8595, 0., 0.*galsim.degrees, 0.0074)
sky_coverage = self.focal_plane.getSkyCoverage(
wcs, x0=-1, x1=0, y0=-1, y1=0)
print(sky_coverage.area())
self.assertTrue(abs(sky_coverage.area() - 0.0074**2/(3600.**2)) < 1e13)
if __name__ == '__main_':
unittest.main()
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