From b8be6e98f2fc39ecff04cf11082c11fe8e86d891 Mon Sep 17 00:00:00 2001 From: zhangxin Date: Thu, 15 Aug 2024 10:17:35 +0800 Subject: [PATCH 01/64] add gain value for closing 16 channel; fix sls bug: in two grating stitch --- observation_sim/mock_objects/Galaxy.py | 6 +++--- observation_sim/sim_steps/readout_output.py | 1 + 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/observation_sim/mock_objects/Galaxy.py b/observation_sim/mock_objects/Galaxy.py index b0404e7..8dc9772 100755 --- a/observation_sim/mock_objects/Galaxy.py +++ b/observation_sim/mock_objects/Galaxy.py @@ -375,7 +375,7 @@ class Galaxy(MockObject): 1, origin_star[1] + galImg.array.shape[1] - 1] if gal_origin[1] < grating_split_pos_chip < gal_end[1]: - subSlitPos = int(grating_split_pos_chip - gal_origin[1] + 1) + subSlitPos = int(grating_split_pos_chip - gal_origin[1]) # part img disperse star_p1s=[] @@ -407,12 +407,12 @@ class Galaxy(MockObject): for galImg in galImg_List: subImg_p2 = galImg.array[:, - subSlitPos + 1:galImg.array.shape[1]] + subSlitPos:galImg.array.shape[1]] star_p2 = galsim.Image(subImg_p2) star_p2.setOrigin(0, 0) star_p2s.append(star_p2) origin_p2 = [origin_star[0], grating_split_pos_chip] - xcenter_p2 = max(x_nominal, grating_split_pos_chip - 1) - 0 + xcenter_p2 = max(x_nominal, grating_split_pos_chip) - 0 ycenter_p2 = y_nominal - 0 sdp_p2 = SpecDisperser(orig_img=star_p2s, xcenter=xcenter_p2, diff --git a/observation_sim/sim_steps/readout_output.py b/observation_sim/sim_steps/readout_output.py index c2cb8a1..0f3f4f5 100644 --- a/observation_sim/sim_steps/readout_output.py +++ b/observation_sim/sim_steps/readout_output.py @@ -44,6 +44,7 @@ def apply_gain(self, chip, filt, tel, pointing, catalog, obs_param): seed=self.overall_config["random_seeds"]["seed_gainNonUniform"]+chip.chipID) elif obs_param["gain_16channel"] == False: chip.img /= chip.gain + chip.gain_channel = np.ones(chip.nsecy*chip.nsecx)*chip.gain return chip, filt, tel, pointing -- GitLab From 410316ee180b39ce11874ea336439685118a762c Mon Sep 17 00:00:00 2001 From: fangyuedong Date: Tue, 17 Sep 2024 05:09:56 +0800 Subject: [PATCH 02/64] output Av values for galaxies --- catalog/C9_Catalog.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/catalog/C9_Catalog.py b/catalog/C9_Catalog.py index 146205d..7081abc 100644 --- a/catalog/C9_Catalog.py +++ b/catalog/C9_Catalog.py @@ -380,7 +380,7 @@ class Catalog(CatalogBase): obj = Galaxy(param, logger=self.logger) # Need to deal with additional output columns for (host) galaxy - obj.additional_output_str = self.add_fmt % (0., 0., 0., 0., 0., 0., + obj.additional_output_str = self.add_fmt % (param['mw_Av'], 0., 0., 0., 0., 0., param['bulgemass'], param['diskmass'], param['detA'], param['e1'], param['e2'], param['kappa'], param['g1'], param['g2'], param['size'], param['galType'], param['veldisp']) -- GitLab From f9c38528927f7bd720d77ae605752fd91a714cdb Mon Sep 17 00:00:00 2001 From: Chengliang Date: Fri, 25 Oct 2024 11:26:36 +0800 Subject: [PATCH 03/64] update Pointing.py: if is_deep --- observation_sim/config/Pointing.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/observation_sim/config/Pointing.py b/observation_sim/config/Pointing.py index 1b39959..a7692ae 100644 --- a/observation_sim/config/Pointing.py +++ b/observation_sim/config/Pointing.py @@ -88,7 +88,7 @@ class Pointing(object): self.exp_time = float(columns[18]) is_deep = float(columns[19]) # [TODO] Can also define other survey types - if is_deep != -1.0: + if is_deep == 2: self.survey_field_type = "DEEP" if not self.obs_config_file: -- GitLab From dec10f3eaf03db841e7ad4678ae0d8bf5bc7e84a Mon Sep 17 00:00:00 2001 From: Chengliang Date: Fri, 25 Oct 2024 21:57:51 +0800 Subject: [PATCH 04/64] update style-PEP8 --- observation_sim/psf/PSFInterp.py | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/observation_sim/psf/PSFInterp.py b/observation_sim/psf/PSFInterp.py index 97435ad..ab902d9 100644 --- a/observation_sim/psf/PSFInterp.py +++ b/observation_sim/psf/PSFInterp.py @@ -19,7 +19,7 @@ NPSF = 900 # ***# 30*30 PixSizeInMicrons = 5. # ***# in microns -### find neighbors-KDtree### +# find neighbors-KDtree # def findNeighbors(tx, ty, px, py, dr=0.1, dn=1, OnlyDistance=True): """ find nearest neighbors by 2D-KDTree @@ -40,9 +40,9 @@ def findNeighbors(tx, ty, px, py, dr=0.1, dn=1, OnlyDistance=True): dataq = [] rr = dr - if OnlyDistance == True: + if OnlyDistance is True: dataq = tree.query_ball_point([tx, ty], rr) - if OnlyDistance == False: + if OnlyDistance is False: while len(dataq) < dn: dataq = tree.query_ball_point([tx, ty], rr) rr += dr @@ -51,7 +51,7 @@ def findNeighbors(tx, ty, px, py, dr=0.1, dn=1, OnlyDistance=True): dataq = np.array(dataq)[ddSortindx[0:dn]] return dataq -### find neighbors-hoclist### +# find neighbors-hoclist# def hocBuild(partx, party, nhocx, nhocy, dhocx, dhocy): @@ -139,7 +139,7 @@ def findNeighbors_hoclist(px, py, tx=None, ty=None, dn=4, hoc=None, hoclist=None return neigh -### PSF-IDW### +# PSF-IDW# def psfMaker_IDW(px, py, PSFMat, cen_col, cen_row, IDWindex=2, OnlyNeighbors=True, hoc=None, hoclist=None, PSFCentroidWgt=False): """ psf interpolation by IDW @@ -163,7 +163,7 @@ def psfMaker_IDW(px, py, PSFMat, cen_col, cen_row, IDWindex=2, OnlyNeighbors=Tru npsf = PSFMat[:, :, :].shape[0] psfWeight = np.zeros([npsf]) - if OnlyNeighbors == True: + if OnlyNeighbors is True: if hoc is None: neigh = findNeighbors(px, py, cen_col, cen_row, dr=5., dn=4, OnlyDistance=False) @@ -175,7 +175,7 @@ def psfMaker_IDW(px, py, PSFMat, cen_col, cen_row, IDWindex=2, OnlyNeighbors=Tru neighFlag[neigh] = 1 for ipsf in range(npsf): - if OnlyNeighbors == True: + if OnlyNeighbors is True: if neighFlag[ipsf] != 1: continue @@ -195,7 +195,7 @@ def psfMaker_IDW(px, py, PSFMat, cen_col, cen_row, IDWindex=2, OnlyNeighbors=Tru psfMaker = np.zeros([ngy, ngx], dtype=np.float32) for ipsf in range(npsf): - if OnlyNeighbors == True: + if OnlyNeighbors is True: if neighFlag[ipsf] != 1: continue @@ -208,7 +208,7 @@ def psfMaker_IDW(px, py, PSFMat, cen_col, cen_row, IDWindex=2, OnlyNeighbors=Tru return psfMaker -### define PSFInterp### +# define PSFInterp# class PSFInterp(PSFModel): def __init__(self, chip, npsf=NPSF, PSF_data=None, PSF_data_file=None, PSF_data_prefix="", sigSpin=0, psfRa=0.15, HocBuild=False, LOG_DEBUG=False): self.LOG_DEBUG = LOG_DEBUG @@ -223,7 +223,7 @@ class PSFInterp(PSFModel): self.iccd = int(chip.getChipLabel(chipID=chip.chipID)) # self.iccd = chip.chip_name - if PSF_data_file == None: + if PSF_data_file is None: print('Error - PSF_data_file is None') sys.exit() @@ -402,7 +402,7 @@ class PSFInterp(PSFModel): Spinned PSF: g1, g2 and axis ratio 'a/b' """ a2Rad = np.pi/(60.0*60.0*180.0) - + ff = self.sigGauss * 0.107 * (1000.0/10.0) # in unit of [pixels] rc = np.sqrt(x*x + y*y) cpix = rc*(self.sigSpin*a2Rad) -- GitLab From 27cb83b15034d75c411a21b5296c6a86b7a90223 Mon Sep 17 00:00:00 2001 From: Chengliang Date: Fri, 25 Oct 2024 22:19:01 +0800 Subject: [PATCH 05/64] update codestyle-PEP8 --- tests/test_prescan_overscan_func.py | 47 +++++++++++++++-------------- 1 file changed, 25 insertions(+), 22 deletions(-) diff --git a/tests/test_prescan_overscan_func.py b/tests/test_prescan_overscan_func.py index b1a11a3..455042d 100644 --- a/tests/test_prescan_overscan_func.py +++ b/tests/test_prescan_overscan_func.py @@ -1,6 +1,8 @@ import unittest -import sys,os,math +import sys +import os +import math from itertools import islice import numpy as np import galsim @@ -8,14 +10,14 @@ import yaml from observation_sim.instruments import Chip, Filter, FilterParam, FocalPlane -### test FUNCTION --- START ### -def AddPreScan(GSImage, pre1=27, pre2=4, over1=71, over2=80, nsecy = 2, nsecx=8): - img= GSImage.array +# test FUNCTION --- START # +def AddPreScan(GSImage, pre1=27, pre2=4, over1=71, over2=80, nsecy=2, nsecx=8): + img = GSImage.array ny, nx = img.shape dx = int(nx/nsecx) dy = int(ny/nsecy) - imgt=np.zeros([int(nsecy*nsecx), int(ny/nsecy+pre2+over2), int(nx/nsecx+pre1+over1)]) + imgt = np.zeros([int(nsecy*nsecx), int(ny/nsecy+pre2+over2), int(nx/nsecx+pre1+over1)]) for iy in range(nsecy): for ix in range(nsecx): if iy % 2 == 0: @@ -23,7 +25,7 @@ def AddPreScan(GSImage, pre1=27, pre2=4, over1=71, over2=80, nsecy = 2, nsecx=8) else: tx = (nsecx-1)-ix ty = iy - chunkidx = int(tx+ty*nsecx) #chunk1-[1,2,3,4], chunk2-[5,6,7,8], chunk3-[9,10,11,12], chunk4-[13,14,15,16] + chunkidx = int(tx+ty*nsecx) # chunk1-[1,2,3,4], chunk2-[5,6,7,8], chunk3-[9,10,11,12], chunk4-[13,14,15,16] imgtemp = np.zeros([int(ny/nsecy+pre2+over2), int(nx/nsecx+pre1+over1)]) if int(chunkidx/4) == 0: @@ -31,40 +33,41 @@ def AddPreScan(GSImage, pre1=27, pre2=4, over1=71, over2=80, nsecy = 2, nsecx=8) imgt[chunkidx, :, :] = imgtemp if int(chunkidx/4) == 1: imgtemp[pre2:pre2+dy, over1:over1+dx] = img[iy*dy:(iy+1)*dy, ix*dx:(ix+1)*dx] - imgt[chunkidx, :, :] = imgtemp #[:, ::-1] + imgt[chunkidx, :, :] = imgtemp # [:, ::-1] if int(chunkidx/4) == 2: imgtemp[over2:over2+dy, over1:over1+dx] = img[iy*dy:(iy+1)*dy, ix*dx:(ix+1)*dx] - imgt[chunkidx, :, :] = imgtemp #[::-1, ::-1] + imgt[chunkidx, :, :] = imgtemp # [::-1, ::-1] if int(chunkidx/4) == 3: imgtemp[over2:over2+dy, pre1:pre1+dx] = img[iy*dy:(iy+1)*dy, ix*dx:(ix+1)*dx] - imgt[chunkidx, :, :] = imgtemp #[::-1, :] + imgt[chunkidx, :, :] = imgtemp # [::-1, :] - imgtx1 = np.hstack(imgt[:nsecx:, :, :]) #hstack chunk(1,2)-[1,2,3,4,5,6,7,8] - imgtx2 = np.hstack(imgt[:(nsecx-1):-1, :, :]) #hstack chunk(4,3)-[16,15,14,13,12,11,,10,9] + imgtx1 = np.hstack(imgt[:nsecx:, :, :]) # hstack chunk(1,2)-[1,2,3,4,5,6,7,8] + imgtx2 = np.hstack(imgt[:(nsecx-1):-1, :, :]) # hstack chunk(4,3)-[16,15,14,13,12,11,,10,9] newimg = galsim.Image(int(nx+(pre1+over1)*nsecx), int(ny+(pre2+over2)*nsecy), init_value=0) - newimg.array[:, :] = np.concatenate([imgtx1, imgtx2]) #vstack chunk(1,2) & chunk(4,3) + newimg.array[:, :] = np.concatenate([imgtx1, imgtx2]) # vstack chunk(1,2) & chunk(4,3) newimg.wcs = GSImage.wcs return newimg -### test FUNCTION --- END ### +# test FUNCTION --- END # def defineCCD(iccd, config_file): with open(config_file, "r") as stream: try: config = yaml.safe_load(stream) - #for key, value in config.items(): - # print (key + " : " + str(value)) + # for key, value in config.items(): + # print (key + " : " + str(value)) except yaml.YAMLError as exc: print(exc) chip = Chip(chipID=iccd, config=config) chip.img = galsim.ImageF(chip.npix_x, chip.npix_y) focal_plane = FocalPlane(chip_list=[iccd]) - chip.img.wcs= focal_plane.getTanWCS(192.8595, 27.1283, -113.4333*galsim.degrees, chip.pix_scale) + chip.img.wcs = focal_plane.getTanWCS(192.8595, 27.1283, -113.4333*galsim.degrees, chip.pix_scale) return chip + def defineFilt(chip): filter_param = FilterParam() filter_id, filter_type = chip.getChipFilter() @@ -91,13 +94,13 @@ class detModule_coverage(unittest.TestCase): print(chip.cen_pix_x, chip.cen_pix_y) chip.img = AddPreScan(GSImage=chip.img, - pre1=chip.prescan_x, - pre2=chip.prescan_y, - over1=chip.overscan_x, - over2=chip.overscan_y) + pre1=chip.prescan_x, + pre2=chip.prescan_y, + over1=chip.overscan_x, + over2=chip.overscan_y) - self.assertTrue( (chip.prescan_x+chip.overscan_x)*8+chip.npix_x == np.shape(chip.img.array)[1] ) - self.assertTrue( (chip.prescan_y+chip.overscan_y)*2+chip.npix_y == np.shape(chip.img.array)[0] ) + self.assertTrue((chip.prescan_x+chip.overscan_x)*8+chip.npix_x == np.shape(chip.img.array)[1]) + self.assertTrue((chip.prescan_y+chip.overscan_y)*2+chip.npix_y == np.shape(chip.img.array)[0]) if __name__ == '__main__': -- GitLab From 00508e40aa7a577066e51805e0553e53b056c239 Mon Sep 17 00:00:00 2001 From: Chengliang Date: Fri, 25 Oct 2024 22:21:44 +0800 Subject: [PATCH 06/64] update codestyle-PEP8 --- tests/test_prescan_overscan_func.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/tests/test_prescan_overscan_func.py b/tests/test_prescan_overscan_func.py index 455042d..01ec75f 100644 --- a/tests/test_prescan_overscan_func.py +++ b/tests/test_prescan_overscan_func.py @@ -10,6 +10,7 @@ import yaml from observation_sim.instruments import Chip, Filter, FilterParam, FocalPlane + # test FUNCTION --- START # def AddPreScan(GSImage, pre1=27, pre2=4, over1=71, over2=80, nsecy=2, nsecx=8): img = GSImage.array @@ -94,10 +95,10 @@ class detModule_coverage(unittest.TestCase): print(chip.cen_pix_x, chip.cen_pix_y) chip.img = AddPreScan(GSImage=chip.img, - pre1=chip.prescan_x, - pre2=chip.prescan_y, - over1=chip.overscan_x, - over2=chip.overscan_y) + pre1=chip.prescan_x, + pre2=chip.prescan_y, + over1=chip.overscan_x, + over2=chip.overscan_y) self.assertTrue((chip.prescan_x+chip.overscan_x)*8+chip.npix_x == np.shape(chip.img.array)[1]) self.assertTrue((chip.prescan_y+chip.overscan_y)*2+chip.npix_y == np.shape(chip.img.array)[0]) -- GitLab From 20c5ee5f6aa5cb61842fbb3a6f32bfa66f24e262 Mon Sep 17 00:00:00 2001 From: Chengliang Date: Sat, 26 Oct 2024 08:47:09 +0800 Subject: [PATCH 07/64] update codestyle-PEP8 --- observation_sim/instruments/chip/libCTI/CTI_modeling.py | 4 ++-- observation_sim/psf/PSFGauss.py | 7 ++++--- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/observation_sim/instruments/chip/libCTI/CTI_modeling.py b/observation_sim/instruments/chip/libCTI/CTI_modeling.py index 6c84059..fdf8b41 100644 --- a/observation_sim/instruments/chip/libCTI/CTI_modeling.py +++ b/observation_sim/instruments/chip/libCTI/CTI_modeling.py @@ -31,7 +31,7 @@ def get_trap_map(seeds,nx,ny,nmax,rho_trap,beta,c,out_dir): get_trap_h(seeds_p,c_int(int(nsp)),c_int(int(nx)),c_int(int(ny)),\ c_int(int(nmax)),rho_trap_p,c_float(beta),\ c_float(c),filename) - + def bin2fits(bin_file,fits_dir,nsp,nx,ny,nmax): data = np.fromfile(bin_file,dtype=np.float32) data = data.reshape(nx,nsp,ny,nmax).transpose(1,3,2,0) @@ -101,6 +101,6 @@ if __name__ =='__main__': image = fits.getdata("inputdata/image.fits").astype(np.int32) get_trap_map(trap_seeds,nx,ny,nmax,rho_trap,beta,c,".") bin2fits("trap.bin",".",nsp,nx,ny,nmax) - image_cti = CTI_sim(image,nx,ny,noverscan,nsp,nmax,beta,w,c,t,rho_trap,trap_seeds,release_seed) + image_cti = CTI_sim(image,nx,ny,noverscan,nsp,nmax,beta,w,c,t,rho_trap,trap_seeds,release_seed) fits.writeto("output/image_CTI.fits",data=image_cti,overwrite=True) """ diff --git a/observation_sim/psf/PSFGauss.py b/observation_sim/psf/PSFGauss.py index e3036d9..0d3e8b0 100644 --- a/observation_sim/psf/PSFGauss.py +++ b/observation_sim/psf/PSFGauss.py @@ -50,7 +50,7 @@ class PSFGauss(PSFModel): Return: the flux ratio """ - if pscale == None: + if pscale is None: pscale = self.pix_size gaussx = galsim.Gaussian(flux=1.0, sigma=sig) gaussImg = gaussx.drawImage(scale=pscale, method='no_pixel') @@ -68,7 +68,7 @@ class PSFGauss(PSFModel): return the fwhm in arcsec """ - if pscale == None: + if pscale is None: pscale = self.pix_size err = 1.0e-3 nxx = 100 @@ -122,4 +122,5 @@ class PSFGauss(PSFModel): # return ell, beta, qr PSFshear = galsim.Shear(e=ell, beta=beta*galsim.radians) - return self.psf.shear(PSFshear), PSFshear \ No newline at end of file + return self.psf.shear(PSFshear), PSFshear + -- GitLab From 0d574e7a89c09755fcb3771969fc4e3f6e843676 Mon Sep 17 00:00:00 2001 From: Chengliang Date: Sat, 26 Oct 2024 08:52:04 +0800 Subject: [PATCH 08/64] update codestyle-PEP8 --- tests/test_BF_CTE.py | 4 ++-- tests/test_PSFmodule.py | 2 +- tests/test_imaging.py | 2 +- tools/get_PSF.py | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/test_BF_CTE.py b/tests/test_BF_CTE.py index 26b9dad..a37bf39 100644 --- a/tests/test_BF_CTE.py +++ b/tests/test_BF_CTE.py @@ -22,7 +22,7 @@ except ImportError: import importlib_resources as pkg_resources -### test FUNCTION --- START ### +# test FUNCTION --- START # def add_brighter_fatter(img): # Inital dynamic lib try: @@ -50,7 +50,7 @@ def add_brighter_fatter(img): img.array[:, :] = np.reshape(arr_imc, [nx, ny]) del arr_ima, arr_imc return img -### test FUNCTION --- END ### +# test FUNCTION --- END # def defineCCD(iccd, config_file): diff --git a/tests/test_PSFmodule.py b/tests/test_PSFmodule.py index a977dd9..434c2ec 100644 --- a/tests/test_PSFmodule.py +++ b/tests/test_PSFmodule.py @@ -72,7 +72,7 @@ class PSFInterpModule_coverage(unittest.TestCase): psfB = psfModel.get_PSF( chip=chip, pos_img=pos_img, findNeighMode='hoclistFind', bandpass=bandpass[0], galsimGSObject=False) - self.assertTrue(psf != None) + self.assertTrue(psf is not None) self.assertTrue(np.max(np.abs(psfA-psfB)) < 1e-6) diff --git a/tests/test_imaging.py b/tests/test_imaging.py index 6fa0bca..5ba5cdc 100644 --- a/tests/test_imaging.py +++ b/tests/test_imaging.py @@ -209,7 +209,7 @@ class imagingModule_coverage(unittest.TestCase): gal = gal + gal_temp print(gal) - self.assertTrue(gal != None) + self.assertTrue(gal is not None) if __name__ == '__main__': diff --git a/tools/get_PSF.py b/tools/get_PSF.py index f861bd5..de711c9 100644 --- a/tools/get_PSF.py +++ b/tools/get_PSF.py @@ -79,7 +79,7 @@ for iobj in range(nobj): if True: fn = "psf_{:}.{:}.{:}.fits".format(chipID, iobj, i) - if fn != None: + if fn is not None: if os.path.exists(fn): os.remove(fn) hdu = fitsio.PrimaryHDU() -- GitLab From c0fe8def294254ab42132357105b46900622acb2 Mon Sep 17 00:00:00 2001 From: Chengliang Date: Sat, 26 Oct 2024 08:56:45 +0800 Subject: [PATCH 09/64] update codestyle-PEP8 --- observation_sim/psf/PSFGauss.py | 1 - observation_sim/psf/__init__.py | 3 ++- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/observation_sim/psf/PSFGauss.py b/observation_sim/psf/PSFGauss.py index 0d3e8b0..db8b3ea 100644 --- a/observation_sim/psf/PSFGauss.py +++ b/observation_sim/psf/PSFGauss.py @@ -123,4 +123,3 @@ class PSFGauss(PSFModel): # return ell, beta, qr PSFshear = galsim.Shear(e=ell, beta=beta*galsim.radians) return self.psf.shear(PSFshear), PSFshear - diff --git a/observation_sim/psf/__init__.py b/observation_sim/psf/__init__.py index 80bf7d3..ae873c6 100755 --- a/observation_sim/psf/__init__.py +++ b/observation_sim/psf/__init__.py @@ -3,4 +3,5 @@ from .PSFGauss import PSFGauss # from .PSFInterp.PSFInterp import PSFInterp from .PSFInterp import PSFInterp from .PSFInterpSLS import PSFInterpSLS -from .FieldDistortion import FieldDistortion \ No newline at end of file +from .FieldDistortion import FieldDistortion + -- GitLab From ab1521fe3ee5e5bd70ad7e3318a930119a6f3e6d Mon Sep 17 00:00:00 2001 From: Chengliang Date: Sat, 26 Oct 2024 08:59:22 +0800 Subject: [PATCH 10/64] update codestyle-PEP8 --- observation_sim/psf/__init__.py | 1 - 1 file changed, 1 deletion(-) diff --git a/observation_sim/psf/__init__.py b/observation_sim/psf/__init__.py index ae873c6..43e878c 100755 --- a/observation_sim/psf/__init__.py +++ b/observation_sim/psf/__init__.py @@ -4,4 +4,3 @@ from .PSFGauss import PSFGauss from .PSFInterp import PSFInterp from .PSFInterpSLS import PSFInterpSLS from .FieldDistortion import FieldDistortion - -- GitLab From b8b5bed920ec9855906edb37d6ece2679c603739 Mon Sep 17 00:00:00 2001 From: Chengliang Date: Sat, 26 Oct 2024 09:36:35 +0800 Subject: [PATCH 11/64] update codestyle-PEP8 --- observation_sim/instruments/chip/effects.py | 326 ++++++++++---------- 1 file changed, 162 insertions(+), 164 deletions(-) diff --git a/observation_sim/instruments/chip/effects.py b/observation_sim/instruments/chip/effects.py index 21735ed..7620f85 100644 --- a/observation_sim/instruments/chip/effects.py +++ b/observation_sim/instruments/chip/effects.py @@ -22,7 +22,7 @@ def AddOverscan(GSImage, overscan=1000, gain=1, widthl=27, widthr=27, widtht=8, NoiseOS = galsim.GaussianNoise(rng, sigma=read_noise) newimg.addNoise(NoiseOS) newimg = (newimg+overscan)/gain - newimg.array[widtht:(widtht+imgshape[0]),widthl:(widthl+imgshape[1])] = GSImage.array + newimg.array[widtht:(widtht+imgshape[0]), widthl:(widthl+imgshape[1])] = GSImage.array newimg.wcs = GSImage.wcs # if GSImage.wcs is not None: # newwcs = GSImage.wcs.withOrigin(galsim.PositionD(widthl,widtht)) @@ -37,11 +37,11 @@ def DefectivePixels(GSImage, IfHotPix=True, IfDeadPix=True, fraction=1E-4, seed= # Hot Pixel > 20e-/s # Dead Pixel < 70%*Mean rgf = Generator(PCG64(int(seed*1.1))) - if IfHotPix==True and IfDeadPix==True: + if IfHotPix is True and IfDeadPix is True: HotFraction = rgf.random() # fraction in total bad pixels - elif IfHotPix==False and IfDeadPix==False: + elif IfHotPix is False and IfDeadPix is False: return GSImage - elif IfHotPix==True: + elif IfHotPix is True: HotFraction = 1 else: HotFraction = 0 @@ -55,23 +55,23 @@ def DefectivePixels(GSImage, IfHotPix=True, IfDeadPix=True, fraction=1E-4, seed= mean = np.mean(GSImage.array) rgp = Generator(PCG64(int(seed))) yxposfrac = rgp.random((NPixBad,2)) - YPositHot = np.array(NPix_y*yxposfrac[0:NPixHot,0]).astype(np.int32) - XPositHot = np.array(NPix_x*yxposfrac[0:NPixHot,1]).astype(np.int32) - YPositDead = np.array(NPix_y*yxposfrac[NPixHot:,0]).astype(np.int32) - XPositDead = np.array(NPix_x*yxposfrac[NPixHot:,1]).astype(np.int32) + YPositHot = np.array(NPix_y*yxposfrac[0:NPixHot, 0]).astype(np.int32) + XPositHot = np.array(NPix_x*yxposfrac[0:NPixHot, 1]).astype(np.int32) + YPositDead = np.array(NPix_y*yxposfrac[NPixHot:, 0]).astype(np.int32) + XPositDead = np.array(NPix_x*yxposfrac[NPixHot:, 1]).astype(np.int32) rgh = Generator(PCG64(int(seed*1.2))) rgd = Generator(PCG64(int(seed*1.3))) - if IfHotPix==True: - GSImage.array[YPositHot,XPositHot] += rgh.gamma(2,25*150,size=NPixHot) - if IfDeadPix==True: - GSImage.array[YPositDead,XPositDead] = rgd.random(NPixDead)*(mean-biaslevel)*0.7+biaslevel+rgp.standard_normal()*5 + if IfHotPix is True: + GSImage.array[YPositHot, XPositHot] += rgh.gamma(2, 25*150, size=NPixHot) + if IfDeadPix is True: + GSImage.array[YPositDead, XPositDead] = rgd.random(NPixDead)*(mean-biaslevel)*0.7+biaslevel+rgp.standard_normal()*5 return GSImage def BadColumns(GSImage, seed=20240309, chipid=1, logger=None): # Set bad column values - ysize,xsize = GSImage.array.shape + ysize, xsize = GSImage.array.shape subarr = GSImage.array[int(ysize*0.1):int(ysize*0.12), int(xsize*0.1):int(xsize*0.12)] subarr = stats.sigma_clip(subarr, sigma=4, cenfunc='median', maxiters=3, masked=False) meanimg = np.median(subarr) @@ -82,8 +82,8 @@ def BadColumns(GSImage, seed=20240309, chipid=1, logger=None): rgxpos = Generator(PCG64(int(seed*1.2))) rgdn = Generator(PCG64(int(seed*1.3))) - nbadsecA,nbadsecD = rgn.integers(low=1, high=5, size=2) - collen = rgcollen.integers(low=int(ysize*0.1), high=int(ysize*0.7), size=(nbadsecA+nbadsecD)) + nbadsecA, nbadsecD = rgn.integers(low=1, high=5, size=2) + collen = rgcollen.integers(low=int(ysize*0.1), high=int(ysize*0.7), size=(nbadsecA+nbadsecD)) xposit = rgxpos.integers(low=int(xsize*0.05), high=int(xsize*0.95), size=(nbadsecA+nbadsecD)) if logger is not None: logger.info(xposit+1) @@ -91,47 +91,47 @@ def BadColumns(GSImage, seed=20240309, chipid=1, logger=None): print(xposit+1) # signs = 2*rgdn.integers(0,2,size=(nbadsecA+nbadsecD))-1 # if meanimg>0: - dn = rgdn.integers(low=np.abs(meanimg)*1.3+50, high=np.abs(meanimg)*2+150, size=(nbadsecA+nbadsecD)) #*signs + dn = rgdn.integers(low=np.abs(meanimg)*1.3+50, high=np.abs(meanimg)*2+150, size=(nbadsecA+nbadsecD)) # *signs # elif meanimg<0: # dn = rgdn.integers(low=meanimg*2-150, high=meanimg*1.3-50, size=(nbadsecA+nbadsecD)) #*signs for badcoli in range(nbadsecA): - GSImage.array[(ysize-collen[badcoli]):ysize,xposit[badcoli]:(xposit[badcoli]+1)] = (np.abs(np.random.normal(0, stdimg*2, (collen[badcoli],1)))+dn[badcoli]) + GSImage.array[(ysize-collen[badcoli]):ysize, xposit[badcoli]:(xposit[badcoli]+1)] = (np.abs(np.random.normal(0, stdimg*2, (collen[badcoli], 1)))+dn[badcoli]) for badcoli in range(nbadsecD): - GSImage.array[0:collen[badcoli+nbadsecA],xposit[badcoli+nbadsecA]:(xposit[badcoli+nbadsecA]+1)] = (np.abs(np.random.normal(0, stdimg*2, (collen[badcoli+nbadsecA],1)))+dn[badcoli+nbadsecA]) + GSImage.array[0:collen[badcoli+nbadsecA], xposit[badcoli+nbadsecA]:(xposit[badcoli+nbadsecA]+1)] = (np.abs(np.random.normal(0, stdimg*2, (collen[badcoli+nbadsecA], 1)))+dn[badcoli+nbadsecA]) return GSImage -def AddBiasNonUniform16(GSImage, bias_level = 500, nsecy = 2, nsecx=8, seed=202102, logger=None): +def AddBiasNonUniform16(GSImage, bias_level=500, nsecy=2, nsecx=8, seed=202102, logger=None): # Generate Bias and its non-uniformity, and add the 16 bias values to the GS-Image rg = Generator(PCG64(int(seed))) Random16 = (rg.random(nsecy*nsecx)-0.5)*20 - if int(bias_level)==0: - BiasLevel = np.zeros((nsecy,nsecx)) - elif bias_level>0: + if int(bias_level) == 0: + BiasLevel = np.zeros((nsecy, nsecx)) + elif bias_level > 0: BiasLevel = Random16.reshape((nsecy,nsecx)) + bias_level if logger is not None: msg = str(" Biases of 16 channels: " + str(BiasLevel)) logger.info(msg) else: - print(" Biases of 16 channels:\n",BiasLevel) + print(" Biases of 16 channels:\n", BiasLevel) arrshape = GSImage.array.shape secsize_x = int(arrshape[1]/nsecx) secsize_y = int(arrshape[0]/nsecy) for rowi in range(nsecy): for coli in range(nsecx): - GSImage.array[rowi*secsize_y:(rowi+1)*secsize_y,coli*secsize_x:(coli+1)*secsize_x] += BiasLevel[rowi,coli] + GSImage.array[rowi*secsize_y:(rowi+1)*secsize_y, coli*secsize_x:(coli+1)*secsize_x] += BiasLevel[rowi, coli] return GSImage def MakeBiasNcomb(npix_x, npix_y, bias_level=500, ncombine=1, read_noise=5, gain=1, seed=202102, logger=None): # Start with 0 value bias GS-Image - ncombine=int(ncombine) + ncombine = int(ncombine) BiasSngImg0 = galsim.Image(npix_x, npix_y, init_value=0) - BiasSngImg = AddBiasNonUniform16(BiasSngImg0, - bias_level=bias_level, - nsecy = 2, nsecx=8, - seed=int(seed), - logger=logger) + BiasSngImg = AddBiasNonUniform16(BiasSngImg0, + bias_level=bias_level, + nsecy = 2, nsecx=8, + seed=int(seed), + logger=logger) BiasCombImg = BiasSngImg*ncombine rng = galsim.UniformDeviate() NoiseBias = galsim.GaussianNoise(rng=rng, sigma=read_noise*ncombine**0.5) @@ -139,7 +139,7 @@ def MakeBiasNcomb(npix_x, npix_y, bias_level=500, ncombine=1, read_noise=5, gain if ncombine == 1: BiasTag = 'Single' pass - elif ncombine >1: + elif ncombine > 1: BiasCombImg /= ncombine BiasTag = 'Combine' # BiasCombImg.replaceNegative(replace_value=0) @@ -147,32 +147,32 @@ def MakeBiasNcomb(npix_x, npix_y, bias_level=500, ncombine=1, read_noise=5, gain return BiasCombImg, BiasTag -def ApplyGainNonUniform16(GSImage, gain=1, nsecy = 2, nsecx=8, seed=202102, logger=None): +def ApplyGainNonUniform16(GSImage, gain=1, nsecy=2, nsecx=8, seed=202102, logger=None): # Generate Gain non-uniformity, and multipy the different factors (mean~1 with sigma~1%) to the GS-Image rg = Generator(PCG64(int(seed))) Random16 = (rg.random(nsecy*nsecx)-0.5)*0.04+1 # sigma~1% - Gain16 = Random16.reshape((nsecy,nsecx))/gain + Gain16 = Random16.reshape((nsecy, nsecx))/gain gain_array = np.ones(nsecy*nsecx)*gain if logger is not None: msg = str("Gain of 16 channels: " + str(Gain16)) logger.info(msg) else: - print("Gain of 16 channels: ",Gain16) + print("Gain of 16 channels: ", Gain16) arrshape = GSImage.array.shape secsize_x = int(arrshape[1]/nsecx) secsize_y = int(arrshape[0]/nsecy) for rowi in range(nsecy): for coli in range(nsecx): - GSImage.array[rowi*secsize_y:(rowi+1)*secsize_y,coli*secsize_x:(coli+1)*secsize_x] *= Gain16[rowi,coli] - gain_array[rowi*nsecx+coli] = 1/Gain16[rowi,coli] + GSImage.array[rowi*secsize_y:(rowi+1)*secsize_y, coli*secsize_x:(coli+1)*secsize_x] *= Gain16[rowi, coli] + gain_array[rowi*nsecx+coli] = 1/Gain16[rowi, coli] return GSImage, gain_array -def GainsNonUniform16(GSImage, gain=1, nsecy = 2, nsecx=8, seed=202102, logger=None): +def GainsNonUniform16(GSImage, gain=1, nsecy=2, nsecx=8, seed=202102, logger=None): # Generate Gain non-uniformity, and multipy the different factors (mean~1 with sigma~1%) to the GS-Image rg = Generator(PCG64(int(seed))) Random16 = (rg.random(nsecy*nsecx)-0.5)*0.04+1 # sigma~1% - Gain16 = Random16.reshape((nsecy,nsecx))/gain + Gain16 = Random16.reshape((nsecy, nsecx))/gain if logger is not None: msg = str(seed-20210202, "Gains of 16 channels: " + str(Gain16)) logger.info(msg) @@ -190,22 +190,22 @@ def GainsNonUniform16(GSImage, gain=1, nsecy = 2, nsecx=8, seed=202102, logger=N def MakeFlatSmooth(GSBounds, seed): rg = Generator(PCG64(int(seed))) - r1,r2,r3,r4 = rg.random(4) + r1, r2, r3, r4 = rg.random(4) a1 = -0.5 + 0.2*r1 a2 = -0.5 + 0.2*r2 a3 = r3+5 a4 = r4+5 - xmin,xmax,ymin,ymax = GSBounds.getXMin(), GSBounds.getXMax(), GSBounds.getYMin(), GSBounds.getYMax() + xmin, xmax, ymin, ymax = GSBounds.getXMin(), GSBounds.getXMax(), GSBounds.getYMin(), GSBounds.getYMax() Flty, Fltx = np.mgrid[ymin:(ymax+1), xmin:(xmax+1)] rg = Generator(PCG64(int(seed))) - p1,p2,bg=rg.poisson(1000, 3) + p1, p2, bg=rg.poisson(1000, 3) Fltz = 0.6*1e-7*(a1 * (Fltx-p1) ** 2 + a2 * (Flty-p2) ** 2 - a3*Fltx - a4*Flty) + bg*20 FlatImg = galsim.ImageF(Fltz) return FlatImg def MakeFlatNcomb(flat_single_image, ncombine=1, read_noise=5, gain=1, overscan=500, biaslevel=500, seed_bias=20210311, logger=None): - ncombine=int(ncombine) + ncombine = int(ncombine) FlatCombImg = flat_single_image*ncombine rng = galsim.UniformDeviate() NoiseFlatPoi = galsim.PoissonNoise(rng=rng, sky_level=0) @@ -215,15 +215,15 @@ def MakeFlatNcomb(flat_single_image, ncombine=1, read_noise=5, gain=1, overscan= # NoiseFlat = galsim.CCDNoise(rng, gain=gain, read_noise=read_noise*ncombine**0.5, sky_level=0) for i in range(ncombine): FlatCombImg = AddBiasNonUniform16( - FlatCombImg, - bias_level=biaslevel, - nsecy=2, nsecx=8, + FlatCombImg, + bias_level=biaslevel, + nsecy=2, nsecx=8, seed=seed_bias, logger=logger) if ncombine == 1: FlatTag = 'Single' pass - elif ncombine >1: + elif ncombine > 1: FlatCombImg /= ncombine FlatTag = 'Combine' # FlatCombImg.replaceNegative(replace_value=0) @@ -232,7 +232,7 @@ def MakeFlatNcomb(flat_single_image, ncombine=1, read_noise=5, gain=1, overscan= def MakeDarkNcomb(npix_x, npix_y, overscan=500, bias_level=500, seed_bias=202102, darkpsec=0.02, exptime=150, ncombine=10, read_noise=5, gain=1, logger=None): - ncombine=int(ncombine) + ncombine = int(ncombine) darkpix = darkpsec*exptime DarkSngImg = galsim.Image(npix_x, npix_y, init_value=darkpix) rng = galsim.UniformDeviate() @@ -243,15 +243,15 @@ def MakeDarkNcomb(npix_x, npix_y, overscan=500, bias_level=500, seed_bias=202102 DarkCombImg.addNoise(NoiseReadN) for i in range(ncombine): DarkCombImg = AddBiasNonUniform16( - DarkCombImg, - bias_level=bias_level, - nsecy = 2, nsecx=8, + DarkCombImg, + bias_level=bias_level, + nsecy = 2, nsecx=8, seed=int(seed_bias), logger=logger) if ncombine == 1: DarkTag = 'Single' pass - elif ncombine >1: + elif ncombine > 1: DarkCombImg /= ncombine DarkTag = 'Combine' # DarkCombImg.replaceNegative(replace_value=0) @@ -261,7 +261,7 @@ def MakeDarkNcomb(npix_x, npix_y, overscan=500, bias_level=500, seed_bias=202102 def PRNU_Img(xsize, ysize, sigma=0.01, seed=202101): rg = Generator(PCG64(int(seed))) - prnuarr = rg.normal(1, sigma, (ysize,xsize)) + prnuarr = rg.normal(1, sigma, (ysize, xsize)) prnuimg = galsim.ImageF(prnuarr) return prnuimg @@ -272,11 +272,10 @@ def NonLinearity(GSImage, beta1=5E-7, beta2=0): return GSImage -######################################## Saturation & Bleeding Start ############################### - +#Saturation & Bleeding Start# def BleedingTrail(aa, yy): - if aa<0.2: - aa=0.2 + if aa < 0.2: + aa = 0.2 else: pass try: @@ -289,77 +288,78 @@ def BleedingTrail(aa, yy): return trail_frac + def MakeTrail(imgarr, satuyxtuple, charge, fullwell=9e4, direction='up', trailcutfrac=0.9): ''' direction: "up" or "down". For "up", bleeds along Y-decreasing direction; for "down", bleeds along Y-increasing direction. ''' - yi,xi = satuyxtuple + yi, xi = satuyxtuple aa = np.log(charge/fullwell)**3 # scale length of the bleeding trail yy = 1 - while charge>0: - if yi<0 or yi>imgarr.shape[0]-1: + while charge > 0: + if yi < 0 or yi > imgarr.shape[0]-1: break - if yi==0 or yi==imgarr.shape[0]-1: - imgarr[yi,xi] = fullwell + if yi == 0 or yi == imgarr.shape[0]-1: + imgarr[yi, xi] = fullwell break - if direction=='up': - if imgarr[yi-1,xi]>=fullwell: - imgarr[yi,xi] = fullwell + if direction == 'up': + if imgarr[yi-1, xi] >= fullwell: + imgarr[yi, xi] = fullwell yi-=1 continue - elif direction=='down': - if imgarr[yi+1,xi]>=fullwell: - imgarr[yi,xi] = fullwell - yi+=1 + elif direction == 'down': + if imgarr[yi+1, xi] >= fullwell: + imgarr[yi, xi] = fullwell + yi += 1 continue if aa<=1: - while imgarr[yi,xi] >= fullwell: - imgarr[yi,xi] = fullwell - if direction=='up': - imgarr[yi-1,xi] += charge - charge = imgarr[yi-1,xi]-fullwell - yi-=1 - if yi<0: + while imgarr[yi, xi] >= fullwell: + imgarr[yi, xi] = fullwell + if direction == 'up': + imgarr[yi-1, xi] += charge + charge = imgarr[yi-1, xi]-fullwell + yi -= 1 + if yi < 0: break - elif direction=='down': - imgarr[yi+1,xi] += charge - charge = imgarr[yi+1,xi]-fullwell - yi+=1 - if yi>imgarr.shape[0]: + elif direction == 'down': + imgarr[yi+1, xi] += charge + charge = imgarr[yi+1, xi]-fullwell + yi += 1 + if yi > imgarr.shape[0]: break else: # calculate bleeding trail: - trail_frac = BleedingTrail(aa,yy) + trail_frac = BleedingTrail(aa, yy) # put charge upwards - if trail_frac>=0.99: - imgarr[yi,xi] = fullwell - if direction=='up': - yi-=1 - elif direction=='down': - yi+=1 + if trail_frac >= 0.99: + imgarr[yi, xi] = fullwell + if direction == 'up': + yi -= 1 + elif direction == 'down': + yi += 1 yy += 1 else: - if trail_fracfullwell: - imgarr[yi,xi] = fullwell - - if direction=='up': - yi-=1 - elif direction=='down': - yi+=1 + imgarr[yi, xi] += charge + if imgarr[yi, xi] > fullwell: + imgarr[yi, xi] = fullwell + + if direction == 'up': + yi -= 1 + elif direction == 'down': + yi += 1 yy += 1 return imgarr def ChargeFlow(imgarr, fullwell=9E4): - size_y,size_x = imgarr.shape - satupos_y,satupos_x = np.where(imgarr>fullwell) + size_y, size_x = imgarr.shape + satupos_y, satupos_x = np.where(imgarr>fullwell) if satupos_y.shape[0]==0: # make no change for the image array @@ -371,12 +371,12 @@ def ChargeFlow(imgarr, fullwell=9E4): chargedict = {} imgarrorig = copy.deepcopy(imgarr) - for yi,xi in zip(satupos_y,satupos_x): - yxidx = ''.join([str(yi),str(xi)]) - chargedict[yxidx] = imgarrorig[yi,xi]-fullwell + for yi, xi in zip(satupos_y, satupos_x): + yxidx = ''.join([str(yi), str(xi)]) + chargedict[yxidx] = imgarrorig[yi, xi]-fullwell - for yi,xi in zip(satupos_y,satupos_x): - yxidx = ''.join([str(yi),str(xi)]) + for yi, xi in zip(satupos_y, satupos_x): + yxidx = ''.join([str(yi), str(xi)]) satcharge = chargedict[yxidx] chargeup = ((np.random.random()-0.5)*0.05+0.5)*satcharge chargedn = satcharge - chargeup @@ -384,11 +384,11 @@ def ChargeFlow(imgarr, fullwell=9E4): try: # Charge Clump moves up if yi>=0 and yi=4 and rowi<8 and coli==0: + OutputSubimg.array[27:int(npix_y/8)+27, 8:int(npix_x/2)+8] = subimg.array + elif rowi >= 4 and rowi < 8 and coli == 0: subbounds = galsim.BoundsI(1, npix_x/2, npix_y/8*rowi+1, npix_y/8*(rowi+1)) subbounds = subbounds.shift(galsim.PositionI(GSImage.bounds.getXMin()-1, GSImage.bounds.getYMin()-1)) subimg = GSImage[subbounds] - OutputSubimg.array[16:int(npix_y/8)+16,8:int(npix_x/2)+8] = subimg.array - elif rowi>=4 and rowi<8 and coli==1: + OutputSubimg.array[16:int(npix_y/8)+16, 8:int(npix_x/2)+8] = subimg.array + elif rowi >= 4 and rowi < 8 and coli == 1: subbounds = galsim.BoundsI(npix_x/2+1, npix_x, npix_y/8*rowi+1, npix_y/8*(rowi+1)) subbounds = subbounds.shift(galsim.PositionI(GSImage.bounds.getXMin()-1, GSImage.bounds.getYMin()-1)) subimg = GSImage[subbounds] - OutputSubimg.array[16 :int(npix_y/8)+16,8:int(npix_x/2)+8] = subimg.array + OutputSubimg.array[16 :int(npix_y/8)+16, 8:int(npix_x/2)+8] = subimg.array else: print("\n\033[31mError: "+"Wrong rowi or coli assignment. Permitted: 0<=rowi<=7, 0<=coli<=1."+"\033[0m\n") return OutputSubimg @@ -463,16 +463,16 @@ def readout16(GSImage, rowi=0, coli=0, overscan_value=0): def CTE_Effect(GSImage, threshold=27, direction='column'): # Devide the image into 4 sections and apply CTE effect with different trail directions. # GSImage: a GalSim Image object. - size_y,size_x = GSImage.array.shape + size_y, size_x = GSImage.array.shape size_sect_y = int(size_y/2) size_sect_x = int(size_x/2) imgarr = GSImage.array if direction == 'column': - imgarr[0:size_sect_y,:] = CTEModelColRow(imgarr[0:size_sect_y,:], trail_direction='down', direction='column', threshold=threshold) - imgarr[size_sect_y:size_y,:] = CTEModelColRow(imgarr[size_sect_y:size_y,:], trail_direction='up', direction='column', threshold=threshold) + imgarr[0:size_sect_y, :] = CTEModelColRow(imgarr[0:size_sect_y, :], trail_direction='down', direction='column', threshold=threshold) + imgarr[size_sect_y:size_y, :] = CTEModelColRow(imgarr[size_sect_y:size_y,:], trail_direction='up', direction='column', threshold=threshold) elif direction == 'row': - imgarr[:,0:size_sect_x] = CTEModelColRow(imgarr[:,0:size_sect_x], trail_direction='right', direction='row', threshold=threshold) - imgarr[:,size_sect_x:size_x] = CTEModelColRow(imgarr[:,size_sect_x:size_x], trail_direction='left', direction='row', threshold=threshold) + imgarr[:,0:size_sect_x] = CTEModelColRow(imgarr[:,0:size_sect_x], trail_direction='right', direction='row', threshold=threshold) + imgarr[:,size_sect_x:size_x] = CTEModelColRow(imgarr[:,size_sect_x:size_x], trail_direction='left', direction='row', threshold=threshold) return GSImage @@ -482,50 +482,50 @@ def CTEModelColRow(img, trail_direction = 'up', direction='column', threshold=27 #total trail flux vs (pixel flux)^1/2 is approximately linear #total trail flux = trail_a * (pixel flux)^1/2 + trail_b #trail pixel flux = pow(0.5,x)/0.5, normalize to 1 - trail_a = 5.651803799619966 + trail_a = 5.651803799619966 trail_b = -2.671933068990729 sh1 = img.shape[0] sh2 = img.shape[1] n_img = img*0 - idx = np.where(img0: n_img[idx] = img[idx] - yidx,xidx = np.where(img>=threshold) + yidx, xidx = np.where(img >= threshold) if len(yidx) == 0: pass - elif len(yidx)>0: + elif len(yidx) > 0: # print(index) - for i, j in zip(yidx,xidx): - f = img[i,j] + for i, j in zip(yidx, xidx): + f = img[i, j] trail_f = (np.sqrt(f)*trail_a + trail_b)*0.5 # trail_f=5E-5*f**1.5 xy_num = 10 all_trail = np.zeros(xy_num) - xy_upstr = np.arange(1,xy_num,1) + xy_upstr = np.arange(1, xy_num, 1) # all_trail_pix = np.sum(pow(0.5,xy_upstr)/0.5) all_trail_pix = 0 for m in xy_upstr: - a1=12.97059491 - b1=0.54286652 - c1=0.69093105 - a2=2.77298856 - b2=0.11231055 - c2=-0.01038675 + a1 = 12.97059491 + b1 = 0.54286652 + c1 = 0.69093105 + a2 = 2.77298856 + b2 = 0.11231055 + c2 = -0.01038675 # t_pow = 0 - am=1 - bm=1 + am = 1 + bm = 1 t_pow = am*np.exp(-bm*m) # if m < 5: # t_pow = a1*np.exp(-b1*m)+c1 # else: # t_pow = a2*np.exp(-b2*m)+c2 - if t_pow <0: + if t_pow < 0: t_pow = 0 all_trail_pix += t_pow @@ -538,23 +538,23 @@ def CTEModelColRow(img, trail_direction = 'up', direction='column', threshold=27 all_trail[0] = f - trail_f - for m in np.arange(0,xy_num,1): + for m in np.arange(0, xy_num, 1): if direction == 'column': if trail_direction == 'down': y_pos = i + m elif trail_direction == 'up': y_pos = i - m - if y_pos < 0 or y_pos >=sh1: + if y_pos < 0 or y_pos >= sh1: break - n_img[y_pos,j] = n_img[y_pos,j] + all_trail[m] + n_img[y_pos, j] = n_img[y_pos, j] + all_trail[m] elif direction == 'row': if trail_direction == 'left': x_pos = j - m elif trail_direction == 'right': x_pos = j + m - if x_pos < 0 or x_pos >=sh2: + if x_pos < 0 or x_pos >= sh2: break - n_img[i,x_pos] = n_img[i,x_pos] + all_trail[m] + n_img[i, x_pos] = n_img[i, x_pos] + all_trail[m] return n_img @@ -566,7 +566,7 @@ def CTEModelColRow(img, trail_direction = 'up', direction='column', threshold=27 def getYValue(collection, x): index = 0; if (collection.shape[1] == 2): - while(x>collection[index,0] and index < collection.shape[0]): + while(x>collection[index, 0] and index < collection.shape[0]): index= index + 1; if (index == collection.shape[0] or index == 0): return 0; @@ -578,11 +578,11 @@ def getYValue(collection, x): return (collection[index, 1] + collection[index-1, 1])/2.0 else: a = deltY/deltX; - return a * (x - collection[index-1,0]) + collection[index-1, 1]; + return a * (x - collection[index-1, 0]) + collection[index-1, 1]; return 0; -def selectCosmicRayCollection(attachedSizes, xLen, yLen,cr_pixelRatio,CR_max_size): +def selectCosmicRayCollection(attachedSizes, xLen, yLen, cr_pixelRatio, CR_max_size): normalRay = 0.90 nnormalRay = 1-normalRay @@ -591,7 +591,7 @@ def selectCosmicRayCollection(attachedSizes, xLen, yLen,cr_pixelRatio,CR_max_siz pixelNum_n = int(xLen * yLen * cr_pixelRatio * nnormalRay ) CRPixelNum = 0; - maxValue = max(attachedSizes[:,1]) + maxValue = max(attachedSizes[:, 1]) maxValue += 0.1; cr_event_num = 0; @@ -613,7 +613,7 @@ def selectCosmicRayCollection(attachedSizes, xLen, yLen,cr_pixelRatio,CR_max_siz return CRs[0:cr_event_num]; -def defineEnergyForCR(cr_event_size,seed = 12345): +def defineEnergyForCR(cr_event_size, seed = 12345): import random sigma = 0.6 / 2.355; mean = 3.3; @@ -637,7 +637,7 @@ def convCR(CRmap=None, addPSF=None, sp_n = 4): if CRmap[i,j] ==0: continue j_st = sp_n*j - pix_v1 = CRmap[i,j]*pix_v0 + pix_v1 = CRmap[i, j]*pix_v0 for m in np.arange(sp_n): for n in np.arange(sp_n): subCRmap[i_st+m, j_st + n] = pix_v1 @@ -648,9 +648,9 @@ def convCR(CRmap=None, addPSF=None, sp_n = 4): for i in np.arange(subCRmap.shape[0]): for j in np.arange(subCRmap.shape[1]): - if subCRmap[i,j]>0: - convPix = addPSF*subCRmap[i,j] - subCRmap_n[i:i+m_size,j:j+m_size]+=convPix + if subCRmap[i, j]>0: + convPix = addPSF*subCRmap[i, j] + subCRmap_n[i:i+m_size, j:j+m_size] += convPix CRmap_n = np.zeros((np.array(subCRmap_n.shape)/sp_n).astype(np.int32)) sh_n = CRmap_n.shape @@ -664,7 +664,7 @@ def convCR(CRmap=None, addPSF=None, sp_n = 4): for n in np.arange(sp_n): p_v += subCRmap_n[i_st+m, j_st + n] - CRmap_n[i,j] = p_v + CRmap_n[i, j] = p_v return CRmap_n @@ -681,7 +681,7 @@ def produceCR_Map(xLen, yLen, exTime, cr_pixelRatio, gain, attachedSizes, seed=2 CRmap = np.zeros([yLen, xLen]); - ## produce conv kernel + # produce conv kernel from astropy.modeling.models import Gaussian2D o_size = 4 sp_n = 8 @@ -694,7 +694,7 @@ def produceCR_Map(xLen, yLen, exTime, cr_pixelRatio, gain, attachedSizes, seed=2 addPSF = addPSF_(xp, yp) convKernel = addPSF/addPSF.sum() - ################################# + #--------------------------------- for i in np.arange(cr_event_size): @@ -713,9 +713,9 @@ def produceCR_Map(xLen, yLen, exTime, cr_pixelRatio, gain, attachedSizes, seed=2 if x_n < 0: x_n = x_n + cr_lens+1 y_n = int(np.sin(pos_angle)*j + np.cos(pos_angle)*0); - if x_n<0 or x_n >cr_lens or y_n < 0 or y_n > cr_lens: + if x_n < 0 or x_n > cr_lens or y_n < 0 or y_n > cr_lens: continue; - crMatrix[y_n,x_n] = pix_energy; + crMatrix[y_n, x_n] = pix_energy; crMatrix_n = convCR(crMatrix, convKernel, sp_n) # crMatrix_n = crMatrix @@ -729,9 +729,7 @@ def produceCR_Map(xLen, yLen, exTime, cr_pixelRatio, gain, attachedSizes, seed=2 sly = slice(ypix[oky].min(), ypix[oky].max()+1) slx = slice(xpix[okx].min(), xpix[okx].max()+1) - CRmap[sly, slx] += crMatrix_n[oky,:][:,okx] - - + CRmap[sly, slx] += crMatrix_n[oky, :][:, okx] return CRmap.astype(np.int32), cr_event_size @@ -770,9 +768,9 @@ def ShutterEffectArr(GSImage, t_exp=150, t_shutter=1.3, dist_bearing=735, dt=1E- s2[i] = dist_bearing-DistHalf*np.cos(theta[i]) s1idx[i] = int(s1[i]/dist_bearing*(SampleNumb)) s2idx[i] = int(s2[i]/dist_bearing*(SampleNumb)) - brt[(idx>s1idx[i]) & (idx s1idx[i]) & (idx < s2idx[i])] += dt - if t_exp>t_shutter*2: + if t_exp > t_shutter*2: brt = brt*2+(t_exp-t_shutter*2) else: brt = brt*2 @@ -785,16 +783,16 @@ def ShutterEffectArr(GSImage, t_exp=150, t_shutter=1.3, dist_bearing=735, dt=1E- xmax = GSImage.bounds.getXMax() ymin = GSImage.bounds.getYMin() ymax = GSImage.bounds.getYMax() - if xminnp.max(x): + if xmin < np.min(x) or xmax > np.max(x): raise LookupError("Out of focal-plane bounds in X-direction.") - if ymin<-25331 or ymax>25331: + if ymin < -25331 or ymax > 25331: raise LookupError("Out of focal-plane bounds in Y-direction.") sizex = xmax-xmin+1 sizey = ymax-ymin+1 xnewgrid = np.mgrid[xmin:(xmin+sizex)] expeffect = interpolate.splev(xnewgrid, intp, der=0) expeffect /= t_exp - exparrnormal = np.tile(expeffect, (sizey,1)) + exparrnormal = np.tile(expeffect, (sizey, 1)) # GSImage *= exparrnormal return exparrnormal -- GitLab From 2c0a94777e4c31f0b895c88bfbe992f5b0b3b870 Mon Sep 17 00:00:00 2001 From: Chengliang Date: Sat, 26 Oct 2024 09:46:55 +0800 Subject: [PATCH 12/64] update codestyle-PEP8 --- observation_sim/instruments/chip/effects.py | 69 ++++++++++----------- 1 file changed, 32 insertions(+), 37 deletions(-) diff --git a/observation_sim/instruments/chip/effects.py b/observation_sim/instruments/chip/effects.py index 7620f85..f215a21 100644 --- a/observation_sim/instruments/chip/effects.py +++ b/observation_sim/instruments/chip/effects.py @@ -3,7 +3,8 @@ from matplotlib.pyplot import flag import numpy as np from numpy.core.fromnumeric import mean, size from numpy.random import Generator, PCG64 -import math,copy +import math +import copy from numba import jit from astropy import stats @@ -50,11 +51,11 @@ def DefectivePixels(GSImage, IfHotPix=True, IfDeadPix=True, fraction=1E-4, seed= NPixBad = int(NPix*fraction) NPixHot = int(NPix*fraction*HotFraction) NPixDead = NPixBad-NPixHot - - NPix_y,NPix_x = GSImage.array.shape + + NPix_y, NPix_x = GSImage.array.shape mean = np.mean(GSImage.array) rgp = Generator(PCG64(int(seed))) - yxposfrac = rgp.random((NPixBad,2)) + yxposfrac = rgp.random((NPixBad, 2)) YPositHot = np.array(NPix_y*yxposfrac[0:NPixHot, 0]).astype(np.int32) XPositHot = np.array(NPix_x*yxposfrac[0:NPixHot, 1]).astype(np.int32) YPositDead = np.array(NPix_y*yxposfrac[NPixHot:, 0]).astype(np.int32) @@ -108,7 +109,7 @@ def AddBiasNonUniform16(GSImage, bias_level=500, nsecy=2, nsecx=8, seed=202102, if int(bias_level) == 0: BiasLevel = np.zeros((nsecy, nsecx)) elif bias_level > 0: - BiasLevel = Random16.reshape((nsecy,nsecx)) + bias_level + BiasLevel = Random16.reshape((nsecy, nsecx)) + bias_level if logger is not None: msg = str(" Biases of 16 channels: " + str(BiasLevel)) logger.info(msg) @@ -129,7 +130,7 @@ def MakeBiasNcomb(npix_x, npix_y, bias_level=500, ncombine=1, read_noise=5, gain BiasSngImg0 = galsim.Image(npix_x, npix_y, init_value=0) BiasSngImg = AddBiasNonUniform16(BiasSngImg0, bias_level=bias_level, - nsecy = 2, nsecx=8, + nsecy=2, nsecx=8, seed=int(seed), logger=logger) BiasCombImg = BiasSngImg*ncombine @@ -198,7 +199,7 @@ def MakeFlatSmooth(GSBounds, seed): xmin, xmax, ymin, ymax = GSBounds.getXMin(), GSBounds.getXMax(), GSBounds.getYMin(), GSBounds.getYMax() Flty, Fltx = np.mgrid[ymin:(ymax+1), xmin:(xmax+1)] rg = Generator(PCG64(int(seed))) - p1, p2, bg=rg.poisson(1000, 3) + p1, p2, bg = rg.poisson(1000, 3) Fltz = 0.6*1e-7*(a1 * (Fltx-p1) ** 2 + a2 * (Flty-p2) ** 2 - a3*Fltx - a4*Flty) + bg*20 FlatImg = galsim.ImageF(Fltz) return FlatImg @@ -245,7 +246,7 @@ def MakeDarkNcomb(npix_x, npix_y, overscan=500, bias_level=500, seed_bias=202102 DarkCombImg = AddBiasNonUniform16( DarkCombImg, bias_level=bias_level, - nsecy = 2, nsecx=8, + nsecy=2, nsecx=8, seed=int(seed_bias), logger=logger) if ncombine == 1: @@ -272,7 +273,7 @@ def NonLinearity(GSImage, beta1=5E-7, beta2=0): return GSImage -#Saturation & Bleeding Start# +# Saturation & Bleeding Start# def BleedingTrail(aa, yy): if aa < 0.2: aa = 0.2 @@ -280,7 +281,7 @@ def BleedingTrail(aa, yy): pass try: fy = 0.5*(math.exp(math.log(yy+1)**3/aa)+np.exp(-1*math.log(yy+1)**3/aa)) - faa= 0.5*(math.e+1/math.e) + faa = 0.5*(math.e+1/math.e) trail_frac = 1-0.1*(fy-1)/(faa-1) except Exception as e: print(e) @@ -306,14 +307,14 @@ def MakeTrail(imgarr, satuyxtuple, charge, fullwell=9e4, direction='up', trailcu if direction == 'up': if imgarr[yi-1, xi] >= fullwell: imgarr[yi, xi] = fullwell - yi-=1 + yi -= 1 continue elif direction == 'down': if imgarr[yi+1, xi] >= fullwell: imgarr[yi, xi] = fullwell yi += 1 continue - if aa<=1: + if aa <= 1: while imgarr[yi, xi] >= fullwell: imgarr[yi, xi] = fullwell if direction == 'up': @@ -359,9 +360,9 @@ def MakeTrail(imgarr, satuyxtuple, charge, fullwell=9e4, direction='up', trailcu def ChargeFlow(imgarr, fullwell=9E4): size_y, size_x = imgarr.shape - satupos_y, satupos_x = np.where(imgarr>fullwell) + satupos_y, satupos_x = np.where(imgarr > fullwell) - if satupos_y.shape[0]==0: + if satupos_y.shape[0] == 0: # make no change for the image array return imgarr elif satupos_y.shape[0]/imgarr.size > 0.5: @@ -383,16 +384,16 @@ def ChargeFlow(imgarr, fullwell=9E4): try: # Charge Clump moves up - if yi>=0 and yi= 0 and yi < imgarr.shape[0]: imgarr = MakeTrail(imgarr, (yi, xi), chargeup, fullwell=9e4, direction='up', trailcutfrac=0.9) # Charge Clump moves down imgarr = MakeTrail(imgarr, (yi, xi), chargedn, fullwell=9e4, direction='down', trailcutfrac=0.9) except Exception as e: - print(e,'@pix ',(yi+1, xi+1)) + print(e, '@pix ', (yi+1, xi+1)) return imgarr - return imgarr + def SaturBloom(GSImage, nsect_x=1, nsect_y=1, fullwell=9e4): """ To simulate digital detector's saturation and blooming effect. The blooming is along the read-out direction, perpendicular to the charge transfer direction. Charge clumpy overflows the pixel well will flow to two oposite directions with nearly same charges. @@ -424,7 +425,7 @@ def SaturBloom(GSImage, nsect_x=1, nsect_y=1, fullwell=9e4): def readout16(GSImage, rowi=0, coli=0, overscan_value=0): # readout image as 16 outputs of sub-images plus prescan & overscan. # assuming image width and height sizes are both even. - # assuming image has 2 columns and 8 rows of output channels. + # assuming image has 2 columns and 8 rows of output channels. # 00 01 # 10 11 # 20 21 @@ -453,7 +454,7 @@ def readout16(GSImage, rowi=0, coli=0, overscan_value=0): subbounds = galsim.BoundsI(npix_x/2+1, npix_x, npix_y/8*rowi+1, npix_y/8*(rowi+1)) subbounds = subbounds.shift(galsim.PositionI(GSImage.bounds.getXMin()-1, GSImage.bounds.getYMin()-1)) subimg = GSImage[subbounds] - OutputSubimg.array[16 :int(npix_y/8)+16, 8:int(npix_x/2)+8] = subimg.array + OutputSubimg.array[16:int(npix_y/8)+16, 8:int(npix_x/2)+8] = subimg.array else: print("\n\033[31mError: "+"Wrong rowi or coli assignment. Permitted: 0<=rowi<=7, 0<=coli<=1."+"\033[0m\n") return OutputSubimg @@ -469,19 +470,19 @@ def CTE_Effect(GSImage, threshold=27, direction='column'): imgarr = GSImage.array if direction == 'column': imgarr[0:size_sect_y, :] = CTEModelColRow(imgarr[0:size_sect_y, :], trail_direction='down', direction='column', threshold=threshold) - imgarr[size_sect_y:size_y, :] = CTEModelColRow(imgarr[size_sect_y:size_y,:], trail_direction='up', direction='column', threshold=threshold) + imgarr[size_sect_y:size_y, :] = CTEModelColRow(imgarr[size_sect_y:size_y, :], trail_direction='up', direction='column', threshold=threshold) elif direction == 'row': - imgarr[:,0:size_sect_x] = CTEModelColRow(imgarr[:,0:size_sect_x], trail_direction='right', direction='row', threshold=threshold) - imgarr[:,size_sect_x:size_x] = CTEModelColRow(imgarr[:,size_sect_x:size_x], trail_direction='left', direction='row', threshold=threshold) + imgarr[:, 0:size_sect_x] = CTEModelColRow(imgarr[:, 0:size_sect_x], trail_direction='right', direction='row', threshold=threshold) + imgarr[:, size_sect_x:size_x] = CTEModelColRow(imgarr[:, size_sect_x:size_x], trail_direction='left', direction='row', threshold=threshold) return GSImage @jit() -def CTEModelColRow(img, trail_direction = 'up', direction='column', threshold=27): +def CTEModelColRow(img, trail_direction='up', direction='column', threshold=27): - #total trail flux vs (pixel flux)^1/2 is approximately linear - #total trail flux = trail_a * (pixel flux)^1/2 + trail_b - #trail pixel flux = pow(0.5,x)/0.5, normalize to 1 + # total trail flux vs (pixel flux)^1/2 is approximately linear + # total trail flux = trail_a * (pixel flux)^1/2 + trail_b + # trail pixel flux = pow(0.5,x)/0.5, normalize to 1 trail_a = 5.651803799619966 trail_b = -2.671933068990729 @@ -491,7 +492,7 @@ def CTEModelColRow(img, trail_direction = 'up', direction='column', threshold=27 idx = np.where(img < threshold) if len(idx[0]) == 0: pass - elif len(idx[0])>0: + elif len(idx[0]) > 0: n_img[idx] = img[idx] yidx, xidx = np.where(img >= threshold) @@ -505,13 +506,13 @@ def CTEModelColRow(img, trail_direction = 'up', direction='column', threshold=27 # trail_f=5E-5*f**1.5 xy_num = 10 all_trail = np.zeros(xy_num) - + xy_upstr = np.arange(1, xy_num, 1) # all_trail_pix = np.sum(pow(0.5,xy_upstr)/0.5) all_trail_pix = 0 for m in xy_upstr: - a1 = 12.97059491 + a1 = 12.97059491 b1 = 0.54286652 c1 = 0.69093105 a2 = 2.77298856 @@ -530,12 +531,8 @@ def CTEModelColRow(img, trail_direction = 'up', direction='column', threshold=27 all_trail_pix += t_pow all_trail[m] = t_pow - - trail_pix_eff = trail_f/all_trail_pix - all_trail = trail_pix_eff*all_trail - all_trail[0] = f - trail_f for m in np.arange(0, xy_num, 1): @@ -559,10 +556,8 @@ def CTEModelColRow(img, trail_direction = 'up', direction='column', threshold=27 return n_img - -#---------- For Cosmic-Ray Simulation ------------ -#---------- Zhang Xin ---------------------------- - +# ---------- For Cosmic-Ray Simulation ------------ +# ---------- Zhang Xin ---------------------------- def getYValue(collection, x): index = 0; if (collection.shape[1] == 2): -- GitLab From 5254ae8010937e5400900afe53f9ed01e7f9f487 Mon Sep 17 00:00:00 2001 From: Chengliang Date: Sat, 26 Oct 2024 09:57:54 +0800 Subject: [PATCH 13/64] update codestyle-PEP8 --- observation_sim/instruments/chip/effects.py | 108 ++++++++++---------- 1 file changed, 53 insertions(+), 55 deletions(-) diff --git a/observation_sim/instruments/chip/effects.py b/observation_sim/instruments/chip/effects.py index f215a21..9e80182 100644 --- a/observation_sim/instruments/chip/effects.py +++ b/observation_sim/instruments/chip/effects.py @@ -534,7 +534,7 @@ def CTEModelColRow(img, trail_direction='up', direction='column', threshold=27): trail_pix_eff = trail_f/all_trail_pix all_trail = trail_pix_eff*all_trail all_trail[0] = f - trail_f - + for m in np.arange(0, xy_num, 1): if direction == 'column': if trail_direction == 'down': @@ -559,22 +559,22 @@ def CTEModelColRow(img, trail_direction='up', direction='column', threshold=27): # ---------- For Cosmic-Ray Simulation ------------ # ---------- Zhang Xin ---------------------------- def getYValue(collection, x): - index = 0; + index = 0 if (collection.shape[1] == 2): - while(x>collection[index, 0] and index < collection.shape[0]): - index= index + 1; + while(x > collection[index, 0] and index < collection.shape[0]): + index = index + 1 if (index == collection.shape[0] or index == 0): - return 0; + return 0 - deltX = collection[index, 0] - collection[index-1, 0]; - deltY = collection[index, 1] - collection[index-1, 1]; + deltX = collection[index, 0] - collection[index-1, 0] + deltY = collection[index, 1] - collection[index-1, 1] if deltX == 0: return (collection[index, 1] + collection[index-1, 1])/2.0 else: - a = deltY/deltX; - return a * (x - collection[index-1, 0]) + collection[index-1, 1]; - return 0; + a = deltY/deltX + return a * (x - collection[index-1, 0]) + collection[index-1, 1] + return 0 def selectCosmicRayCollection(attachedSizes, xLen, yLen, cr_pixelRatio, CR_max_size): @@ -582,45 +582,45 @@ def selectCosmicRayCollection(attachedSizes, xLen, yLen, cr_pixelRatio, CR_max_s normalRay = 0.90 nnormalRay = 1-normalRay max_nrayLen = 100 - pixelNum = int(xLen * yLen * cr_pixelRatio * normalRay ); - pixelNum_n = int(xLen * yLen * cr_pixelRatio * nnormalRay ) - CRPixelNum = 0; - + pixelNum = int(xLen * yLen * cr_pixelRatio * normalRay) + pixelNum_n = int(xLen * yLen * cr_pixelRatio * nnormalRay) + CRPixelNum = 0 + maxValue = max(attachedSizes[:, 1]) - maxValue += 0.1; + maxValue += 0.1 - cr_event_num = 0; - CRs = np.zeros(pixelNum); + cr_event_num = 0 + CRs = np.zeros(pixelNum) while (CRPixelNum < pixelNum): - x = CR_max_size * np.random.random(); - y = maxValue * np.random.random(); + x = CR_max_size * np.random.random() + y = maxValue * np.random.random() if (y <= getYValue(attachedSizes, x)): - CRs[cr_event_num] = np.ceil(x); - cr_event_num = cr_event_num + 1; - CRPixelNum = CRPixelNum + round(x); + CRs[cr_event_num] = np.ceil(x) + cr_event_num = cr_event_num + 1 + CRPixelNum = CRPixelNum + round(x) while (CRPixelNum < pixelNum + pixelNum_n): nx = np.random.random()*(max_nrayLen-CR_max_size)+CR_max_size - CRs[cr_event_num] = np.ceil(nx); - cr_event_num = cr_event_num + 1; - CRPixelNum = CRPixelNum + np.ceil(nx); + CRs[cr_event_num] = np.ceil(nx) + cr_event_num = cr_event_num + 1 + CRPixelNum = CRPixelNum + np.ceil(nx) - return CRs[0:cr_event_num]; + return CRs[0:cr_event_num] -def defineEnergyForCR(cr_event_size, seed = 12345): +def defineEnergyForCR(cr_event_size, seed=12345): import random - sigma = 0.6 / 2.355; - mean = 3.3; + sigma = 0.6 / 2.355 + mean = 3.3 random.seed(seed) - energys = np.zeros(cr_event_size); + energys = np.zeros(cr_event_size) for i in np.arange(cr_event_size): - energy_index = random.normalvariate(mean,sigma); - energys[i] = pow(10, energy_index); + energy_index = random.normalvariate(mean, sigma); + energys[i] = pow(10, energy_index) - return energys; + return energys -def convCR(CRmap=None, addPSF=None, sp_n = 4): +def convCR(CRmap=None, addPSF=None, sp_n=4): sh = CRmap.shape # sp_n = 4 @@ -629,7 +629,7 @@ def convCR(CRmap=None, addPSF=None, sp_n = 4): for i in np.arange(sh[0]): i_st = sp_n*i for j in np.arange(sh[1]): - if CRmap[i,j] ==0: + if CRmap[i, j] == 0: continue j_st = sp_n*j pix_v1 = CRmap[i, j]*pix_v0 @@ -639,11 +639,11 @@ def convCR(CRmap=None, addPSF=None, sp_n = 4): m_size = addPSF.shape[0] - subCRmap_n = np.zeros(np.array(subCRmap.shape) + m_size -1) + subCRmap_n = np.zeros(np.array(subCRmap.shape) + m_size - 1) for i in np.arange(subCRmap.shape[0]): for j in np.arange(subCRmap.shape[1]): - if subCRmap[i, j]>0: + if subCRmap[i, j] > 0: convPix = addPSF*subCRmap[i, j] subCRmap_n[i:i+m_size, j:j+m_size] += convPix @@ -654,7 +654,7 @@ def convCR(CRmap=None, addPSF=None, sp_n = 4): i_st = sp_n*i for j in np.arange(sh_n[1]): p_v = 0 - j_st=sp_n*j + j_st = sp_n*j for m in np.arange(sp_n): for n in np.arange(sp_n): p_v += subCRmap_n[i_st+m, j_st + n] @@ -668,13 +668,13 @@ def produceCR_Map(xLen, yLen, exTime, cr_pixelRatio, gain, attachedSizes, seed=2 # Return: an 2-D numpy array # attachedSizes = np.loadtxt('./wfc-cr-attachpixel.dat'); np.random.seed(seed) - CR_max_size = 20.0; - cr_size = selectCosmicRayCollection(attachedSizes, xLen, yLen, cr_pixelRatio, CR_max_size); + CR_max_size = 20.0 + cr_size = selectCosmicRayCollection(attachedSizes, xLen, yLen, cr_pixelRatio, CR_max_size) - cr_event_size = cr_size.shape[0]; - cr_energys = defineEnergyForCR(cr_event_size,seed = seed); + cr_event_size = cr_size.shape[0] + cr_energys = defineEnergyForCR(cr_event_size, seed=seed) - CRmap = np.zeros([yLen, xLen]); + CRmap = np.zeros([yLen, xLen]) # produce conv kernel from astropy.modeling.models import Gaussian2D @@ -689,28 +689,26 @@ def produceCR_Map(xLen, yLen, exTime, cr_pixelRatio, gain, attachedSizes, seed=2 addPSF = addPSF_(xp, yp) convKernel = addPSF/addPSF.sum() - #--------------------------------- - - + # --------------------------------- for i in np.arange(cr_event_size): xPos = round((xLen - 1)* np.random.random()); yPos = round((yLen - 1)* np.random.random()); cr_lens = int(cr_size[i]); - if cr_lens ==0: - continue; - pix_energy = cr_energys[i]/gain/cr_lens; - pos_angle = 1/2*math.pi*np.random.random(); + if cr_lens == 0: + continue + pix_energy = cr_energys[i]/gain/cr_lens + pos_angle = 1/2*math.pi*np.random.random() crMatrix = np.zeros([cr_lens+1, cr_lens + 1]) for j in np.arange(cr_lens): - x_n = int(np.cos(pos_angle)*j - np.sin(pos_angle)*0); + x_n = int(np.cos(pos_angle)*j - np.sin(pos_angle)*0) if x_n < 0: x_n = x_n + cr_lens+1 - y_n = int(np.sin(pos_angle)*j + np.cos(pos_angle)*0); + y_n = int(np.sin(pos_angle)*j + np.cos(pos_angle)*0) if x_n < 0 or x_n > cr_lens or y_n < 0 or y_n > cr_lens: - continue; - crMatrix[y_n, x_n] = pix_energy; + continue + crMatrix[y_n, x_n] = pix_energy crMatrix_n = convCR(crMatrix, convKernel, sp_n) # crMatrix_n = crMatrix @@ -747,7 +745,7 @@ def ShutterEffectArr(GSImage, t_exp=150, t_shutter=1.3, dist_bearing=735, dt=1E- s = np.zeros(SampleNumb) s1 = np.zeros(SampleNumb) s2 = np.zeros(SampleNumb) - brt = np.zeros(SampleNumb) + brt = np.zeros(SampleNumb) idx = np.arange(SampleNumb) sidx = np.zeros(SampleNumb) s1idx = np.zeros(SampleNumb) -- GitLab From 1742c3e2ac7c5a652aa6a29558b59a9c8c7cfb02 Mon Sep 17 00:00:00 2001 From: Chengliang Date: Sat, 26 Oct 2024 10:02:58 +0800 Subject: [PATCH 14/64] update codestyle-PEP8 --- observation_sim/instruments/chip/effects.py | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/observation_sim/instruments/chip/effects.py b/observation_sim/instruments/chip/effects.py index 9e80182..4aa0fc9 100644 --- a/observation_sim/instruments/chip/effects.py +++ b/observation_sim/instruments/chip/effects.py @@ -267,8 +267,12 @@ def PRNU_Img(xsize, ysize, sigma=0.01, seed=202101): return prnuimg +def NonLinear_f(x, beta_1, beta_2): + return x - beta_1 * x * x + beta_2 * x * x * x + + def NonLinearity(GSImage, beta1=5E-7, beta2=0): - NonLinear_f = lambda x, beta_1, beta_2: x - beta_1*x*x + beta_2*x*x*x + # NonLinear_f = lambda x, beta_1, beta_2: x - beta_1*x*x + beta_2*x*x*x GSImage.applyNonlinearity(NonLinear_f, beta1, beta2) return GSImage @@ -561,7 +565,7 @@ def CTEModelColRow(img, trail_direction='up', direction='column', threshold=27): def getYValue(collection, x): index = 0 if (collection.shape[1] == 2): - while(x > collection[index, 0] and index < collection.shape[0]): + while (x > collection[index, 0] and index < collection.shape[0]): index = index + 1 if (index == collection.shape[0] or index == 0): return 0 @@ -615,11 +619,11 @@ def defineEnergyForCR(cr_event_size, seed=12345): random.seed(seed) energys = np.zeros(cr_event_size) for i in np.arange(cr_event_size): - energy_index = random.normalvariate(mean, sigma); + energy_index = random.normalvariate(mean, sigma) energys[i] = pow(10, energy_index) - return energys + def convCR(CRmap=None, addPSF=None, sp_n=4): sh = CRmap.shape @@ -691,8 +695,8 @@ def produceCR_Map(xLen, yLen, exTime, cr_pixelRatio, gain, attachedSizes, seed=2 # --------------------------------- for i in np.arange(cr_event_size): - xPos = round((xLen - 1)* np.random.random()); - yPos = round((yLen - 1)* np.random.random()); + xPos = round((xLen - 1) * np.random.random()) + yPos = round((yLen - 1) * np.random.random()) cr_lens = int(cr_size[i]); if cr_lens == 0: continue -- GitLab From ba121152c1cf3e4342713dd9ab7f34de650a1b5e Mon Sep 17 00:00:00 2001 From: Chengliang Date: Sat, 26 Oct 2024 10:05:08 +0800 Subject: [PATCH 15/64] update codestyle-PEP8 --- observation_sim/instruments/chip/effects.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/observation_sim/instruments/chip/effects.py b/observation_sim/instruments/chip/effects.py index 4aa0fc9..bef8da0 100644 --- a/observation_sim/instruments/chip/effects.py +++ b/observation_sim/instruments/chip/effects.py @@ -267,7 +267,7 @@ def PRNU_Img(xsize, ysize, sigma=0.01, seed=202101): return prnuimg -def NonLinear_f(x, beta_1, beta_2): +def NonLinear_f(x, beta_1, beta_2): return x - beta_1 * x * x + beta_2 * x * x * x @@ -697,7 +697,7 @@ def produceCR_Map(xLen, yLen, exTime, cr_pixelRatio, gain, attachedSizes, seed=2 for i in np.arange(cr_event_size): xPos = round((xLen - 1) * np.random.random()) yPos = round((yLen - 1) * np.random.random()) - cr_lens = int(cr_size[i]); + cr_lens = int(cr_size[i]) if cr_lens == 0: continue pix_energy = cr_energys[i]/gain/cr_lens -- GitLab From c326c535bdaa744576b4d9eecef3acb53ccc77b4 Mon Sep 17 00:00:00 2001 From: Chengliang Date: Sat, 26 Oct 2024 10:12:01 +0800 Subject: [PATCH 16/64] update codestyle-PEP8 --- catalog/Catalog_example.py | 6 +++--- catalog/testCat_fits.py | 2 +- observation_sim/ObservationSim.py | 2 +- observation_sim/config/__init__.py | 2 +- observation_sim/config/header/__init__.py | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/catalog/Catalog_example.py b/catalog/Catalog_example.py index 4b51f0a..d3a6f28 100644 --- a/catalog/Catalog_example.py +++ b/catalog/Catalog_example.py @@ -72,7 +72,7 @@ class Catalog(CatalogBase): This is a must implemented method which is used to read in all objects, and then convert them to observation_sim.mock_objects (Star, Galaxy, or Quasar). - Currently, + Currently, the model of observation_sim.mock_objects.Star class requires: param["star"] : int specify the object type: 0: galaxy, 1: star, 2: quasar @@ -84,7 +84,7 @@ class Catalog(CatalogBase): Declination (in degrees) param["mag_use_normal"]: float the absolute magnitude in a particular filter - NOTE: if that filter is not the corresponding CSST filter, the + NOTE: if that filter is not the corresponding CSST filter, the load_norm_filt(obj) function must be implemented to load the filter throughput of that particular photometric system @@ -99,7 +99,7 @@ class Catalog(CatalogBase): Declination (in degrees) param["mag_use_normal"]: float the absolute magnitude in a particular filter - NOTE: if that filter is not the corresponding CSST filter, the + NOTE: if that filter is not the corresponding CSST filter, the load_norm_filt(obj) function must be implemented to load the filter throughput of that particular photometric system param["bfrac"] : float diff --git a/catalog/testCat_fits.py b/catalog/testCat_fits.py index 6ae1bad..9717b22 100644 --- a/catalog/testCat_fits.py +++ b/catalog/testCat_fits.py @@ -177,7 +177,7 @@ class Catalog(CatalogBase): # param["CSSTmag"]= True # param["mag_r"] = 20. # param[''] - ### more keywords for stamp### + # more keywords for stamp# param['image'] = hdu[0].data param['image'] = param['image']/(np.sum(param['image'])) obj = Stamp(param) diff --git a/observation_sim/ObservationSim.py b/observation_sim/ObservationSim.py index cb060ab..523406e 100755 --- a/observation_sim/ObservationSim.py +++ b/observation_sim/ObservationSim.py @@ -25,7 +25,7 @@ class Observation(object): def prepare_chip_for_exposure(self, chip, ra_cen, dec_cen, pointing, wcs_fp=None, slsPSFOptim=False): # Get WCS for the focal plane - if wcs_fp == None: + if wcs_fp is None: wcs_fp = self.focal_plane.getTanWCS( ra_cen, dec_cen, pointing.img_pa, chip.pix_scale) diff --git a/observation_sim/config/__init__.py b/observation_sim/config/__init__.py index bf03e61..6d22c04 100644 --- a/observation_sim/config/__init__.py +++ b/observation_sim/config/__init__.py @@ -1,2 +1,2 @@ from .ChipOutput import ChipOutput -from .Pointing import Pointing \ No newline at end of file +from .Pointing import Pointing diff --git a/observation_sim/config/header/__init__.py b/observation_sim/config/header/__init__.py index db07f26..bbe9ba5 100755 --- a/observation_sim/config/header/__init__.py +++ b/observation_sim/config/header/__init__.py @@ -1,2 +1,2 @@ from .ImageHeader import generatePrimaryHeader -from .ImageHeader import generateExtensionHeader \ No newline at end of file +from .ImageHeader import generateExtensionHeader -- GitLab From 5fd170d74416fc580406e4a910652b2bb83c5942 Mon Sep 17 00:00:00 2001 From: Chengliang Date: Sat, 26 Oct 2024 10:30:31 +0800 Subject: [PATCH 17/64] update codestyle-PEP8 --- observation_sim/sim_steps/readout_output.py | 47 +++++++++++++++++++-- 1 file changed, 43 insertions(+), 4 deletions(-) diff --git a/observation_sim/sim_steps/readout_output.py b/observation_sim/sim_steps/readout_output.py index 0f3f4f5..094dea2 100644 --- a/observation_sim/sim_steps/readout_output.py +++ b/observation_sim/sim_steps/readout_output.py @@ -17,13 +17,52 @@ def add_prescan_overscan(self, chip, filt, tel, pointing, catalog, obs_param): over1=chip.overscan_x, over2=chip.overscan_y) - if obs_param["add_dark"] == True: + if obs_param["add_dark"] is True: ny = int(chip.npix_y/2) base_dark = (ny-1)*(chip.readout_time/ny)*chip.dark_noise chip.img.array[(chip.prescan_y+ny):-(chip.prescan_y+ny), :] = base_dark return chip, filt, tel, pointing +def add_crosstalk(self, chip, filt, tel, pointing, catalog, obs_param): + crosstalk=np.zeros([16,16]) + crosstalk[0,:] = np.array([1., 1e-4, 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.]) + crosstalk[1,:] = np.array([1e-4, 1., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.]) + crosstalk[2,:] = np.array([0., 0., 1., 1e-4, 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.]) + crosstalk[3,:] = np.array([0., 0., 1e-4, 1., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.]) + crosstalk[4,:] = np.array([0., 0., 0., 0., 1., 1e-4, 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.]) + crosstalk[5,:] = np.array([0., 0., 0., 0., 1e-4, 1., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.]) + crosstalk[6,:] = np.array([0., 0., 0., 0., 0., 0., 1., 1e-4, 0., 0., 0., 0., 0., 0., 0., 0.]) + crosstalk[7,:] = np.array([0., 0., 0., 0., 0., 0., 1e-4, 1., 0., 0., 0., 0., 0., 0., 0., 0.]) + crosstalk[8,:] = np.array([0., 0., 0., 0., 0., 0., 0., 0., 1., 1e-4, 0., 0., 0., 0., 0., 0.]) + crosstalk[9,:] = np.array([0., 0., 0., 0., 0., 0., 0., 0., 1e-4, 1., 0., 0., 0., 0., 0., 0.]) + crosstalk[10,:]= np.array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 1., 1e-4, 0., 0., 0., 0.]) + crosstalk[11,:]= np.array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 1e-4, 1., 0., 0., 0., 0.]) + crosstalk[12,:]= np.array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 1., 1e-4, 0., 0.]) + crosstalk[13,:]= np.array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 1e-4, 1., 0., 0.]) + crosstalk[14,:]= np.array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 1., 1e-4]) + crosstalk[15,:]= np.array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 1e-4, 1.]) + + # 2*8 -> 1*16 + img = formatOutput(chip.img) + ny, nx = img.array.shape + nsecy=1 + nsecx=16 + dy = int(ny/nsecy) + dx = int(nx/nsecx) + + newimg = galsim.Image(nx, ny, init_value=0) + for i in range(16): + for j in range(16): + newimg.array[:, int(i*dx):int(i*dx+dx)] += crosstalk[i,j]*img.array[:, int(j*dx):int(j*dx+dx)] + + # 1*16 -> 2*8 + newimg = formatRevert(newimg) + chip.img.array[:, :] = newimg.array[:, :] + + return chip, filt, tel, pointing + + def add_readout_noise(self, chip, filt, tel, pointing, catalog, obs_param): seed = int(self.overall_config["random_seeds"] ["seed_readout"]) + pointing.id*30 + chip.chipID @@ -36,13 +75,13 @@ def add_readout_noise(self, chip, filt, tel, pointing, catalog, obs_param): def apply_gain(self, chip, filt, tel, pointing, catalog, obs_param): self.chip_output.Log_info(" Applying Gain") - if obs_param["gain_16channel"] == True: + if obs_param["gain_16channel"] is True: chip.img, chip.gain_channel = effects.ApplyGainNonUniform16(chip.img, gain=chip.gain, nsecy=chip.nsecy, nsecx=chip.nsecx, seed=self.overall_config["random_seeds"]["seed_gainNonUniform"]+chip.chipID) - elif obs_param["gain_16channel"] == False: + elif obs_param["gain_16channel"] is False: chip.img /= chip.gain chip.gain_channel = np.ones(chip.nsecy*chip.nsecx)*chip.gain return chip, filt, tel, pointing @@ -74,7 +113,7 @@ def quantization_and_output(self, chip, filt, tel, pointing, catalog, obs_param) self.updateHeaderInfo(header_flag='ext', keys=['GAIN01', 'GAIN02', 'GAIN03', 'GAIN04', 'GAIN05', 'GAIN06', 'GAIN07', 'GAIN08', 'GAIN09', 'GAIN10', 'GAIN11', 'GAIN12', 'GAIN13', 'GAIN14', 'GAIN15', 'GAIN16'], values=gains) - if obs_param["format_output"] == True: + if obs_param["format_output"] is True: self.chip_output.Log_info(" Apply 1*16 format") chip.img = chip_utils.formatOutput(GSImage=chip.img) chip.nsecy = 1 -- GitLab From 99502553970957d6d6a4112ead3be0898533af32 Mon Sep 17 00:00:00 2001 From: Chengliang Date: Sat, 26 Oct 2024 10:33:56 +0800 Subject: [PATCH 18/64] update codestyle-PEP8 --- observation_sim/sim_steps/readout_output.py | 40 ++++++++++----------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/observation_sim/sim_steps/readout_output.py b/observation_sim/sim_steps/readout_output.py index 094dea2..adbaa42 100644 --- a/observation_sim/sim_steps/readout_output.py +++ b/observation_sim/sim_steps/readout_output.py @@ -25,36 +25,36 @@ def add_prescan_overscan(self, chip, filt, tel, pointing, catalog, obs_param): def add_crosstalk(self, chip, filt, tel, pointing, catalog, obs_param): - crosstalk=np.zeros([16,16]) - crosstalk[0,:] = np.array([1., 1e-4, 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.]) - crosstalk[1,:] = np.array([1e-4, 1., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.]) - crosstalk[2,:] = np.array([0., 0., 1., 1e-4, 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.]) - crosstalk[3,:] = np.array([0., 0., 1e-4, 1., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.]) - crosstalk[4,:] = np.array([0., 0., 0., 0., 1., 1e-4, 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.]) - crosstalk[5,:] = np.array([0., 0., 0., 0., 1e-4, 1., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.]) - crosstalk[6,:] = np.array([0., 0., 0., 0., 0., 0., 1., 1e-4, 0., 0., 0., 0., 0., 0., 0., 0.]) - crosstalk[7,:] = np.array([0., 0., 0., 0., 0., 0., 1e-4, 1., 0., 0., 0., 0., 0., 0., 0., 0.]) - crosstalk[8,:] = np.array([0., 0., 0., 0., 0., 0., 0., 0., 1., 1e-4, 0., 0., 0., 0., 0., 0.]) - crosstalk[9,:] = np.array([0., 0., 0., 0., 0., 0., 0., 0., 1e-4, 1., 0., 0., 0., 0., 0., 0.]) - crosstalk[10,:]= np.array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 1., 1e-4, 0., 0., 0., 0.]) - crosstalk[11,:]= np.array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 1e-4, 1., 0., 0., 0., 0.]) - crosstalk[12,:]= np.array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 1., 1e-4, 0., 0.]) - crosstalk[13,:]= np.array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 1e-4, 1., 0., 0.]) - crosstalk[14,:]= np.array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 1., 1e-4]) - crosstalk[15,:]= np.array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 1e-4, 1.]) + crosstalk=np.zeros([16, 16]) + crosstalk[0, :] = np.array([1., 1e-4, 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.]) + crosstalk[1, :] = np.array([1e-4, 1., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.]) + crosstalk[2, :] = np.array([0., 0., 1., 1e-4, 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.]) + crosstalk[3, :] = np.array([0., 0., 1e-4, 1., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.]) + crosstalk[4, :] = np.array([0., 0., 0., 0., 1., 1e-4, 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.]) + crosstalk[5, :] = np.array([0., 0., 0., 0., 1e-4, 1., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.]) + crosstalk[6, :] = np.array([0., 0., 0., 0., 0., 0., 1., 1e-4, 0., 0., 0., 0., 0., 0., 0., 0.]) + crosstalk[7, :] = np.array([0., 0., 0., 0., 0., 0., 1e-4, 1., 0., 0., 0., 0., 0., 0., 0., 0.]) + crosstalk[8, :] = np.array([0., 0., 0., 0., 0., 0., 0., 0., 1., 1e-4, 0., 0., 0., 0., 0., 0.]) + crosstalk[9, :] = np.array([0., 0., 0., 0., 0., 0., 0., 0., 1e-4, 1., 0., 0., 0., 0., 0., 0.]) + crosstalk[10, :] = np.array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 1., 1e-4, 0., 0., 0., 0.]) + crosstalk[11, :] = np.array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 1e-4, 1., 0., 0., 0., 0.]) + crosstalk[12, :] = np.array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 1., 1e-4, 0., 0.]) + crosstalk[13, :] = np.array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 1e-4, 1., 0., 0.]) + crosstalk[14, :] = np.array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 1., 1e-4]) + crosstalk[15, :] = np.array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 1e-4, 1.]) # 2*8 -> 1*16 img = formatOutput(chip.img) ny, nx = img.array.shape - nsecy=1 - nsecx=16 + nsecy = 1 + nsecx = 16 dy = int(ny/nsecy) dx = int(nx/nsecx) newimg = galsim.Image(nx, ny, init_value=0) for i in range(16): for j in range(16): - newimg.array[:, int(i*dx):int(i*dx+dx)] += crosstalk[i,j]*img.array[:, int(j*dx):int(j*dx+dx)] + newimg.array[:, int(i*dx):int(i*dx+dx)] += crosstalk[i, j]*img.array[:, int(j*dx):int(j*dx+dx)] # 1*16 -> 2*8 newimg = formatRevert(newimg) -- GitLab From 9a4dead86ed5c677a30b12bf17f9e8101cbb31e2 Mon Sep 17 00:00:00 2001 From: Chengliang Date: Sat, 26 Oct 2024 10:39:53 +0800 Subject: [PATCH 19/64] update codestyle-PEP8 --- observation_sim/sim_steps/add_LED_flat.py | 2 +- observation_sim/sim_steps/add_objects.py | 6 +++--- observation_sim/sim_steps/add_pattern_noise.py | 8 ++++---- observation_sim/sim_steps/add_sky_background.py | 14 +++++++------- observation_sim/sim_steps/readout_output.py | 2 +- 5 files changed, 16 insertions(+), 16 deletions(-) diff --git a/observation_sim/sim_steps/add_LED_flat.py b/observation_sim/sim_steps/add_LED_flat.py index 76bcdbd..7c5683c 100644 --- a/observation_sim/sim_steps/add_LED_flat.py +++ b/observation_sim/sim_steps/add_LED_flat.py @@ -27,7 +27,7 @@ def add_LED_Flat(self, chip, filt, tel, pointing, catalog, obs_param): self.updateHeaderInfo(header_flag='ext', keys=['LEDT01', 'LEDT02', 'LEDT03', 'LEDT04', 'LEDT05', 'LEDT06', 'LEDT07', 'LEDT08', 'LEDT09', 'LEDT10', 'LEDT11', 'LEDT12', 'LEDT13', 'LEDT14'], values=letts) - if obs_param["shutter_effect"] == True: + if obs_param["shutter_effect"] is True: pf_map = pf_map * chip.shutter_img pf_map = np.array(pf_map, dtype='float32') self.updateHeaderInfo(header_flag='ext', keys=[ diff --git a/observation_sim/sim_steps/add_objects.py b/observation_sim/sim_steps/add_objects.py index 6c9c7c1..bbe8baa 100644 --- a/observation_sim/sim_steps/add_objects.py +++ b/observation_sim/sim_steps/add_objects.py @@ -48,7 +48,7 @@ def add_objects(self, chip, filt, tel, pointing, catalog, obs_param): self.chip_output.Log_error("unrecognized PSF model type!!", flush=True) # Apply field distortion model - if obs_param["field_dist"] == True: + if obs_param["field_dist"] is True: fd_model = FieldDistortion(chip=chip, img_rot=pointing.img_pa.deg) else: fd_model = None @@ -253,10 +253,10 @@ def add_objects(self, chip, filt, tel, pointing, catalog, obs_param): # Apply flat fielding (with shutter effects) flat_normal = np.ones_like(chip.img.array) - if obs_param["flat_fielding"] == True: + if obs_param["flat_fielding"] is True: flat_normal = flat_normal * chip.flat_img.array / \ np.mean(chip.flat_img.array) - if obs_param["shutter_effect"] == True: + if obs_param["shutter_effect"] is True: flat_normal = flat_normal * chip.shutter_img flat_normal = np.array(flat_normal, dtype='float32') self.updateHeaderInfo(header_flag='ext', keys=[ diff --git a/observation_sim/sim_steps/add_pattern_noise.py b/observation_sim/sim_steps/add_pattern_noise.py index f92cf36..959ce84 100644 --- a/observation_sim/sim_steps/add_pattern_noise.py +++ b/observation_sim/sim_steps/add_pattern_noise.py @@ -5,7 +5,7 @@ from observation_sim.instruments.chip import effects def apply_PRNU(self, chip, filt, tel, pointing, catalog, obs_param): chip.img *= chip.prnu_img - if self.overall_config["output_setting"]["prnu_output"] == True: + if self.overall_config["output_setting"]["prnu_output"] is True: chip.prnu_img.write("%s/FlatImg_PRNU_%s.fits" % (self.chip_output.subdir, str(chip.chipID).rjust(2, '0'))) return chip, filt, tel, pointing @@ -19,7 +19,7 @@ def add_poisson_and_dark(self, chip, filt, tel, pointing, catalog, obs_param): else: exptime = pointing.exp_time - if obs_param["add_dark"] == True: + if obs_param["add_dark"] is True: chip.img, _ = chip_utils.add_poisson(img=chip.img, chip=chip, exptime=pointing.exp_time, @@ -46,7 +46,7 @@ def add_detector_defects(self, chip, filt, tel, pointing, catalog, obs_param): fraction=badfraction, seed=self.overall_config["random_seeds"]["seed_defective"]+chip.chipID, biaslevel=0) # Apply Bad columns - if obs_param["bad_columns"] == True: + if obs_param["bad_columns"] is True: chip.img = effects.BadColumns(chip.img, seed=self.overall_config["random_seeds"]["seed_badcolumns"], chipid=chip.chipID) @@ -73,7 +73,7 @@ def add_blooming(self, chip, filt, tel, pointing, catalog, obs_param): def add_bias(self, chip, filt, tel, pointing, catalog, obs_param): self.chip_output.Log_info( " Adding Bias level and 16-channel non-uniformity") - if obs_param["bias_16channel"] == True: + if obs_param["bias_16channel"] is True: chip.img = effects.AddBiasNonUniform16(chip.img, bias_level=float( chip.bias_level), diff --git a/observation_sim/sim_steps/add_sky_background.py b/observation_sim/sim_steps/add_sky_background.py index ab013f3..082e3aa 100644 --- a/observation_sim/sim_steps/add_sky_background.py +++ b/observation_sim/sim_steps/add_sky_background.py @@ -16,10 +16,10 @@ def add_sky_background_sci(self, chip, filt, tel, pointing, catalog, obs_param): exptime = pointing.exp_time flat_normal = np.ones_like(chip.img.array) - if obs_param["flat_fielding"] == True: + if obs_param["flat_fielding"] is True: flat_normal = flat_normal * chip.flat_img.array / \ np.mean(chip.flat_img.array) - if obs_param["shutter_effect"] == True: + if obs_param["shutter_effect"] is True: flat_normal = flat_normal * chip.shutter_img flat_normal = np.array(flat_normal, dtype='float32') self.updateHeaderInfo(header_flag='ext', keys=[ @@ -81,14 +81,14 @@ def add_sky_flat_calibration(self, chip, filt, tel, pointing, catalog, obs_param norm_scaler = skyback_level/exptime / filter_param.param[sky_level_filt][5] flat_normal = np.ones_like(chip.img.array) - if obs_param["flat_fielding"] == True: + if obs_param["flat_fielding"] is True: flat_normal = flat_normal * chip.flat_img.array / \ np.mean(chip.flat_img.array) - if obs_param["shutter_effect"] == True: + if obs_param["shutter_effect"] is True: flat_normal = flat_normal * chip.shutter_img flat_normal = np.array(flat_normal, dtype='float32') # output 16-bit shutter effect image with pixel value <=65535 - if self.overall_config["output_setting"]["shutter_output"] == True: + if self.overall_config["output_setting"]["shutter_output"] is True: shutt_gsimg = galsim.ImageUS(chip.shutter_img*6E4) shutt_gsimg.write("%s/ShutterEffect_%s_1.fits" % (self.chip_output.subdir, str(chip.chipID).rjust(2, '0'))) @@ -103,11 +103,11 @@ def add_sky_flat_calibration(self, chip, filt, tel, pointing, catalog, obs_param filter_param.param[chip.filter_type][5] / tel.pupil_area * exptime elif chip.survey_type == "spectroscopic": # flat_normal = np.ones_like(chip.img.array) - if obs_param["flat_fielding"] == True: + if obs_param["flat_fielding"] is True: flat_normal = flat_normal * chip.flat_img.array / \ np.mean(chip.flat_img.array) - if obs_param["shutter_effect"] == True: + if obs_param["shutter_effect"] is True: flat_normal = flat_normal * chip.shutter_img flat_normal = np.array(flat_normal, dtype='float32') diff --git a/observation_sim/sim_steps/readout_output.py b/observation_sim/sim_steps/readout_output.py index adbaa42..c936669 100644 --- a/observation_sim/sim_steps/readout_output.py +++ b/observation_sim/sim_steps/readout_output.py @@ -25,7 +25,7 @@ def add_prescan_overscan(self, chip, filt, tel, pointing, catalog, obs_param): def add_crosstalk(self, chip, filt, tel, pointing, catalog, obs_param): - crosstalk=np.zeros([16, 16]) + crosstalk = np.zeros([16, 16]) crosstalk[0, :] = np.array([1., 1e-4, 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.]) crosstalk[1, :] = np.array([1e-4, 1., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.]) crosstalk[2, :] = np.array([0., 0., 1., 1e-4, 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.]) -- GitLab From 8fd9723d5b7893daf42f5d45bfe2a095d0e48bf6 Mon Sep 17 00:00:00 2001 From: Chengliang Date: Sat, 26 Oct 2024 10:47:18 +0800 Subject: [PATCH 20/64] update codestyle-PEP8 --- observation_sim/instruments/FilterParam.py | 2 +- observation_sim/instruments/FocalPlane.py | 4 ++-- observation_sim/instruments/_util.py | 2 +- observation_sim/instruments/chip/Chip.py | 2 +- observation_sim/instruments/chip/chip_utils.py | 4 ++-- observation_sim/sim_steps/add_pattern_noise.py | 2 +- run_sim.py | 2 +- 7 files changed, 9 insertions(+), 9 deletions(-) diff --git a/observation_sim/instruments/FilterParam.py b/observation_sim/instruments/FilterParam.py index fe10927..6235eb3 100755 --- a/observation_sim/instruments/FilterParam.py +++ b/observation_sim/instruments/FilterParam.py @@ -25,7 +25,7 @@ class FilterParam(object): # 6) sky background: e/pix/s # 7) saturation magnitude # 8) dim end magnitude - if filter_param == None: + if filter_param is None: filtP = { "NUV": [2867.7, 705.4, 2470.0, 3270.0, 0.1404, 0.004, 15.7, 25.4], "u": [3601.1, 852.1, 3120.0, 4090.0, 0.2176, 0.021, 16.1, 25.4], diff --git a/observation_sim/instruments/FocalPlane.py b/observation_sim/instruments/FocalPlane.py index 90c2e0e..8987fcb 100755 --- a/observation_sim/instruments/FocalPlane.py +++ b/observation_sim/instruments/FocalPlane.py @@ -9,7 +9,7 @@ class FocalPlane(object): self.nchips = 42 self.ignore_chips = [] - if bad_chips == None: + if bad_chips is None: self.bad_chips = [] else: self.bad_chips = bad_chips @@ -80,7 +80,7 @@ class FocalPlane(object): if logger is not None: logger.info( " Construct the wcs of the entire image mosaic using Gnomonic/TAN projection") - if (xcen == None) or (ycen == None): + if (xcen is None) or (ycen is None): xcen = self.cen_pix_x ycen = self.cen_pix_y diff --git a/observation_sim/instruments/_util.py b/observation_sim/instruments/_util.py index 953d229..0947b0a 100755 --- a/observation_sim/instruments/_util.py +++ b/observation_sim/instruments/_util.py @@ -46,7 +46,7 @@ def photonEnergy(lambd): def calculateLimitMag(aperture=2.0, psf_fwhm=0.1969, pixelSize=0.074, pmRation=0.8, throughputFn='i_throughput.txt', readout=5.0, skyFn='sky_emiss_hubble_50_50_A.dat', darknoise=0.02, exTime=150, exNum=1, fw=90000): ''' - description: + description: param {*} aperture: unit m, default 2 m param {*} psf_fwhm: psf fwhm, default 0.1969" param {*} pixelSize: pixel size, default 0.074" diff --git a/observation_sim/instruments/chip/Chip.py b/observation_sim/instruments/chip/Chip.py index e50b664..ba6bf3b 100755 --- a/observation_sim/instruments/chip/Chip.py +++ b/observation_sim/instruments/chip/Chip.py @@ -191,7 +191,7 @@ class Chip(FocalPlane): """Return the filter index and type for a given chip #(chipID) """ filter_type_list = _util.ALL_FILTERS - if chipID == None: + if chipID is None: chipID = self.chipID # updated configurations diff --git a/observation_sim/instruments/chip/chip_utils.py b/observation_sim/instruments/chip/chip_utils.py index cb16118..542ed12 100644 --- a/observation_sim/instruments/chip/chip_utils.py +++ b/observation_sim/instruments/chip/chip_utils.py @@ -206,7 +206,7 @@ def get_poisson(seed=0, sky_level=0.): def get_base_img(img, chip, read_noise, readout_time, dark_noise, exptime=150., InputDark=None): - if InputDark == None: + if InputDark is None: # base_level = read_noise**2 + dark_noise*(exptime+0.5*readout_time) # base_level = dark_noise*(exptime+0.5*readout_time) base_level = dark_noise*(exptime) @@ -237,7 +237,7 @@ def add_poisson(img, chip, exptime=150., seed=0, sky_level=0., poisson_noise=Non img.addNoise(poisson_noise) # img -= read_noise**2 - if InputDark != None: + if InputDark is not None: # "Instrument/data/dark/dark_1000s_example_0.fits" hdu = fits.open(InputDark) img += hdu[0].data/hdu[0].header['exptime']*exptime diff --git a/observation_sim/sim_steps/add_pattern_noise.py b/observation_sim/sim_steps/add_pattern_noise.py index 959ce84..dd487ce 100644 --- a/observation_sim/sim_steps/add_pattern_noise.py +++ b/observation_sim/sim_steps/add_pattern_noise.py @@ -80,6 +80,6 @@ def add_bias(self, chip, filt, tel, pointing, catalog, obs_param): nsecy=chip.nsecy, nsecx=chip.nsecx, seed=self.overall_config["random_seeds"]["seed_biasNonUniform"]+chip.chipID) - elif obs_param["bias_16channel"] == False: + elif obs_param["bias_16channel"] is False: chip.img += chip.bias_level return chip, filt, tel, pointing diff --git a/run_sim.py b/run_sim.py index f117985..5f14038 100755 --- a/run_sim.py +++ b/run_sim.py @@ -18,7 +18,7 @@ def run_sim(): Parameters ---------- Catalog : Class - a catalog class which is inherited from observation_sim.mock_objects.CatalogBase + a catalog class which is inherited from observation_sim.mock_objects.CatalogBase Returns ---------- -- GitLab From 3515cc73e9b513df347fb046d2e2e878ad49c912 Mon Sep 17 00:00:00 2001 From: Zhang Xin Date: Sat, 26 Oct 2024 10:49:08 +0800 Subject: [PATCH 21/64] pep8 formatting --- .../SpecDisperser/SpecDisperser.py | 271 +++++++++--------- 1 file changed, 143 insertions(+), 128 deletions(-) diff --git a/observation_sim/mock_objects/SpecDisperser/SpecDisperser.py b/observation_sim/mock_objects/SpecDisperser/SpecDisperser.py index 2b2d7c2..6936eb1 100644 --- a/observation_sim/mock_objects/SpecDisperser/SpecDisperser.py +++ b/observation_sim/mock_objects/SpecDisperser/SpecDisperser.py @@ -50,8 +50,21 @@ def rotate90(array_orig=None, xc=0, yc=0, isClockwise=0): class SpecDisperser(object): - def __init__(self, orig_img=None, xcenter=0, ycenter=0, origin=[100, 100], tar_spec=None, band_start=6200, - band_end=10000, isAlongY=0, conf='../param/CONF/csst.conf', gid=0, flat_cube=None, ignoreBeam=[]): + def __init__( + self, + orig_img=None, + xcenter=0, + ycenter=0, + origin=[100, 100], + tar_spec=None, + band_start=6200, + band_end=10000, + isAlongY=0, + conf="../param/CONF/csst.conf", + gid=0, + flat_cube=None, + ignoreBeam=[], + ): """ orig_img: normal image,galsim image xcenter, ycenter: the center of galaxy in orig_img @@ -66,23 +79,21 @@ class SpecDisperser(object): # self.img_y = orig_img.shape[0] # 5 orders, A, B , - orderName=["A","B","C","D","E"] + orderName = ["A", "B", "C", "D", "E"] self.orig_img_orders = OrderedDict() if isinstance(orig_img, list): orig_img_list = orig_img list_len = len(orig_img_list) if list_len < 5: - for i in np.arange(5-list_len): - orig_img_list.append(orig_img_list[list_len-1]) + for i in np.arange(5 - list_len): + orig_img_list.append(orig_img_list[list_len - 1]) for i, k in enumerate(orig_img_list): self.orig_img_orders[orderName[i]] = k - if isinstance(orig_img, galsim.Image): for i in np.arange(5): self.orig_img_orders[orderName[i]] = orig_img - orig_img_one = self.orig_img_orders["A"] self.thumb_img = np.abs(orig_img_one.array) @@ -99,8 +110,12 @@ class SpecDisperser(object): self.flat_cube = flat_cube if self.isAlongY == 1: for order in orderName: - self.orig_img_orders[order], self.thumb_x, self.thumb_y = rotate90(array_orig=self.orig_img_orders[order], xc=orig_img_one.center.x, - yc=orig_img_one.center.y, isClockwise=1) + self.orig_img_orders[order], self.thumb_x, self.thumb_y = rotate90( + array_orig=self.orig_img_orders[order], + xc=orig_img_one.center.x, + yc=orig_img_one.center.y, + isClockwise=1, + ) # self.thumb_img, self.thumb_x, self.thumb_y = rotate90(array_orig=self.thumb_img, xc=orig_img_one.center.x, # yc=orig_img_one.center.y, isClockwise=1) @@ -139,6 +154,7 @@ class SpecDisperser(object): from .disperse_c import interp from .disperse_c import disperse + # from MockObject.disperse_c import disperse self.thumb_img = np.abs(self.orig_img_orders[beam].array) self.thumb_x = self.orig_img_orders[beam].center.x @@ -146,22 +162,21 @@ class SpecDisperser(object): self.img_sh = self.orig_img_orders[beam].array.shape dx = self.grating_conf.dxlam[beam] xoff = 0 - ytrace_beam, lam_beam = self.grating_conf.get_beam_trace(x=self.xcenter, y=self.ycenter, dx=(dx + xoff), - beam=beam) + ytrace_beam, lam_beam = self.grating_conf.get_beam_trace( + x=self.xcenter, y=self.ycenter, dx=(dx + xoff), beam=beam + ) # Account for pixel centering of the trace - yfrac_beam = ytrace_beam - floor(ytrace_beam+0.5) + yfrac_beam = ytrace_beam - floor(ytrace_beam + 0.5) ysens = lam_beam * 0 lam_index = argsort(lam_beam) conf_sens = self.grating_conf.sens[beam] - lam_intep = np.linspace(self.band_start, self.band_end, int( - (self.band_end - self.band_start) / 0.1)) + lam_intep = np.linspace(self.band_start, self.band_end, int((self.band_end - self.band_start) / 0.1)) - thri = interpolate.interp1d( - conf_sens['WAVELENGTH'], conf_sens['SENSITIVITY']) - spci = interpolate.interp1d(self.spec['WAVELENGTH'], self.spec['FLUX']) + thri = interpolate.interp1d(conf_sens["WAVELENGTH"], conf_sens["SENSITIVITY"]) + spci = interpolate.interp1d(self.spec["WAVELENGTH"], self.spec["FLUX"]) beam_thr = thri(lam_intep) spec_sample = spci(lam_intep) @@ -179,14 +194,14 @@ class SpecDisperser(object): # # self.writerSensitivityFile(conffile = self.grating_conf_file, beam = beam, w = lam_beam[lam_index], sens = ysensitivity[lam_index]) - ysens[lam_index] = interp.interp_conserve_c(lam_beam[lam_index], lam_intep, bean_thr_spec, integrate=1, left=0, - right=0) + ysens[lam_index] = interp.interp_conserve_c( + lam_beam[lam_index], lam_intep, bean_thr_spec, integrate=1, left=0, right=0 + ) sensitivity_beam = ysens len_spec_x = len(dx) - len_spec_y = int( - abs(ceil(ytrace_beam[-1]) - floor(ytrace_beam[0])) + 1) + len_spec_y = int(abs(ceil(ytrace_beam[-1]) - floor(ytrace_beam[0])) + 1) beam_sh = (self.img_sh[0] + len_spec_y, self.img_sh[1] + len_spec_x) modelf = zeros(product(beam_sh), dtype=float) @@ -196,7 +211,7 @@ class SpecDisperser(object): dxpix = dx - dx[0] + x0[1] - dyc = cast[int](np.floor(ytrace_beam+0.5)) + dyc = cast[int](np.floor(ytrace_beam + 0.5)) # dypix = cast[int](np.floor(ytrace_beam - dyc[0] + x0[0] + 0.5)) dypix = dyc - dyc[0] + x0[0] @@ -204,7 +219,7 @@ class SpecDisperser(object): frac_ids = yfrac_beam < 0 dypix[frac_ids] = dypix[frac_ids] - 1 - yfrac_beam[frac_ids] = 1+yfrac_beam[frac_ids] + yfrac_beam[frac_ids] = 1 + yfrac_beam[frac_ids] flat_index = idx[dypix, dxpix] @@ -231,9 +246,8 @@ class SpecDisperser(object): else: beam_flat = zeros([len(modelf), len(self.flat_cube)]) - sub_flat_cube = zeros( - [len(self.flat_cube), beam_sh[0], beam_sh[1]]) - sub_flat_cube[0] = sub_flat_cube[0] + 1. + sub_flat_cube = zeros([len(self.flat_cube), beam_sh[0], beam_sh[1]]) + sub_flat_cube[0] = sub_flat_cube[0] + 1.0 overlap_flag = 1 @@ -260,33 +274,38 @@ class SpecDisperser(object): overlap_flag = 0 if overlap_flag == 1: - sub_flat_cube[:, beam_y_s-originOut_y:beam_y_e-originOut_y+1, beam_x_s-originOut_x:beam_x_e - - originOut_x+1] = self.flat_cube[:, beam_y_s:beam_y_e+1, beam_x_s:beam_x_e+1] + sub_flat_cube[ + :, + beam_y_s - originOut_y : beam_y_e - originOut_y + 1, + beam_x_s - originOut_x : beam_x_e - originOut_x + 1, + ] = self.flat_cube[:, beam_y_s : beam_y_e + 1, beam_x_s : beam_x_e + 1] for i in arange(0, len(self.flat_cube), 1): beam_flat[:, i] = sub_flat_cube[i].flatten() -# beam_flat = zeros([len(modelf), len(self.flat_cube)]) -# flat_sh = self.flat_cube[0].shape -# for i in arange(0, beam_sh[0], 1): -# for j in arange(0, beam_sh[1], 1): -# k = i * beam_sh[1] + j -# if originOut_y + i >= flat_sh[0] or originOut_y + i < 0 or originOut_x + j>= flat_sh[1] or originOut_x+j < 0: -# temp_bf = np.zeros_like(self.flat_cube[:, 0, 0]) -# temp_bf[0] = 1.0 -# beam_flat[k] = temp_bf -# else: -# beam_flat[k] = self.flat_cube[:, originOut_y + i, originOut_x + j] - - status = disperse.disperse_grism_object(self.thumb_img.astype(np.float32), - flat_index[nonz], - yfrac_beam[nonz], - sensitivity_beam[nonz], - modelf, x0, - array(self.img_sh, - dtype=int64), - array(beam_sh, dtype=int64), - beam_flat, - lam_beam[lam_index][nonz]) + # beam_flat = zeros([len(modelf), len(self.flat_cube)]) + # flat_sh = self.flat_cube[0].shape + # for i in arange(0, beam_sh[0], 1): + # for j in arange(0, beam_sh[1], 1): + # k = i * beam_sh[1] + j + # if originOut_y + i >= flat_sh[0] or originOut_y + i < 0 or originOut_x + j>= flat_sh[1] or originOut_x+j < 0: + # temp_bf = np.zeros_like(self.flat_cube[:, 0, 0]) + # temp_bf[0] = 1.0 + # beam_flat[k] = temp_bf + # else: + # beam_flat[k] = self.flat_cube[:, originOut_y + i, originOut_x + j] + + status = disperse.disperse_grism_object( + self.thumb_img.astype(np.float32), + flat_index[nonz], + yfrac_beam[nonz], + sensitivity_beam[nonz], + modelf, + x0, + array(self.img_sh, dtype=int64), + array(beam_sh, dtype=int64), + beam_flat, + lam_beam[lam_index][nonz], + ) model = modelf.reshape(beam_sh) # n1 = np.sum(np.isinf(model)) @@ -296,27 +315,25 @@ class SpecDisperser(object): # if n1>0 or n2 > 0: # print("DEBUG: SpecDisperser, inf:%d, nan:%d--------%d,%d"%(n1, n2, n3, n4)) # print(dypix) - # n1 = np.sum(np.isinf(self.thumb_img.astype(np.float32))) - # n2 = np.sum(np.isnan(self.thumb_img.astype(np.float32))) - # n3 = np.sum(np.isinf(yfrac_beam)) - # n4 = np.sum(np.isnan(yfrac_beam)) - # n5 = np.sum(np.isinf(sensitivity_beam)) - # n6 = np.sum(np.isnan(sensitivity_beam)) - # print("DEBUG: SpecDisperser, innput ---inf:%d, nan:%d, yfrac_beam:%d/%d, sensitivity_beam:%d/%d"%(n1, n2, n3, n4, n5, n6)) + # n1 = np.sum(np.isinf(self.thumb_img.astype(np.float32))) + # n2 = np.sum(np.isnan(self.thumb_img.astype(np.float32))) + # n3 = np.sum(np.isinf(yfrac_beam)) + # n4 = np.sum(np.isnan(yfrac_beam)) + # n5 = np.sum(np.isinf(sensitivity_beam)) + # n6 = np.sum(np.isnan(sensitivity_beam)) + # print("DEBUG: SpecDisperser, innput ---inf:%d, nan:%d, yfrac_beam:%d/%d, sensitivity_beam:%d/%d"%(n1, n2, n3, n4, n5, n6)) self.beam_flux[beam] = sum(modelf) if self.isAlongY == 1: model, _, _ = rotate90(array_orig=model, isClockwise=0) return model, originOut_x, originOut_y, dxpix, dypix, lam_beam, ysens - def writerSensitivityFile(self, conffile='', beam='', w=None, sens=None): - orders = {'A': '1st', 'B': '0st', 'C': '2st', 'D': '-1st', 'E': '-2st'} - sens_file_name = conffile[0:-5] + \ - '_sensitivity_' + orders[beam] + '.fits' + def writerSensitivityFile(self, conffile="", beam="", w=None, sens=None): + orders = {"A": "1st", "B": "0st", "C": "2st", "D": "-1st", "E": "-2st"} + sens_file_name = conffile[0:-5] + "_sensitivity_" + orders[beam] + ".fits" if not os.path.exists(sens_file_name) == True: - senstivity_out = Table( - array([w, sens]).T, names=('WAVELENGTH', 'SENSITIVITY')) - senstivity_out.write(sens_file_name, format='fits') + senstivity_out = Table(array([w, sens]).T, names=("WAVELENGTH", "SENSITIVITY")) + senstivity_out.write(sens_file_name, format="fits") """ @@ -324,8 +341,8 @@ Demonstrate aXe trace polynomials. """ -class aXeConf(): - def __init__(self, conf_file='WFC3.IR.G141.V2.5.conf'): +class aXeConf: + def __init__(self, conf_file="WFC3.IR.G141.V2.5.conf"): """Read an aXe-compatible configuration file Parameters @@ -340,17 +357,17 @@ class aXeConf(): self.count_beam_orders() # Global XOFF/YOFF offsets - if 'XOFF' in self.conf.keys(): - self.xoff = np.float(self.conf['XOFF']) + if "XOFF" in self.conf.keys(): + self.xoff = np.float(self.conf["XOFF"]) else: - self.xoff = 0. + self.xoff = 0.0 - if 'YOFF' in self.conf.keys(): - self.yoff = np.float(self.conf['YOFF']) + if "YOFF" in self.conf.keys(): + self.yoff = np.float(self.conf["YOFF"]) else: - self.yoff = 0. + self.yoff = 0.0 - def read_conf_file(self, conf_file='WFC3.IR.G141.V2.5.conf'): + def read_conf_file(self, conf_file="WFC3.IR.G141.V2.5.conf"): """Read an aXe config file, convert floats and arrays Parameters @@ -366,11 +383,11 @@ class aXeConf(): lines = open(conf_file).readlines() for line in lines: # empty / commented lines - if (line.startswith('#')) | (line.strip() == '') | ('"' in line): + if (line.startswith("#")) | (line.strip() == "") | ('"' in line): continue # split the line, taking out ; and # comments - spl = line.split(';')[0].split('#')[0].split() + spl = line.split(";")[0].split("#")[0].split() param = spl[0] if len(spl) > 2: value = np.cast[float](spl[1:]) @@ -385,22 +402,20 @@ class aXeConf(): return conf def count_beam_orders(self): - """Get the maximum polynomial order in DYDX or DLDP for each beam - """ + """Get the maximum polynomial order in DYDX or DLDP for each beam""" self.orders = {} - for beam in ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J']: + for beam in ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J"]: order = 0 - while 'DYDX_{0:s}_{1:d}'.format(beam, order) in self.conf.keys(): + while "DYDX_{0:s}_{1:d}".format(beam, order) in self.conf.keys(): order += 1 - while 'DLDP_{0:s}_{1:d}'.format(beam, order) in self.conf.keys(): + while "DLDP_{0:s}_{1:d}".format(beam, order) in self.conf.keys(): order += 1 self.orders[beam] = order - 1 def get_beams(self): - """Get beam parameters and read sensitivity curves - """ + """Get beam parameters and read sensitivity curves""" import os from collections import OrderedDict from astropy.table import Table, Column @@ -413,12 +428,13 @@ class aXeConf(): for beam in self.orders: if self.orders[beam] > 0: self.beams.append(beam) - self.dxlam[beam] = np.arange(self.conf['BEAM{0}'.format(beam)].min(), - self.conf['BEAM{0}'.format(beam)].max(), dtype=int) - self.nx[beam] = int(self.dxlam[beam].max() - - self.dxlam[beam].min()) + 1 + self.dxlam[beam] = np.arange( + self.conf["BEAM{0}".format(beam)].min(), self.conf["BEAM{0}".format(beam)].max(), dtype=int + ) + self.nx[beam] = int(self.dxlam[beam].max() - self.dxlam[beam].min()) + 1 self.sens[beam] = Table.read( - '{0}/{1}'.format(os.path.dirname(self.conf_file), self.conf['SENSITIVITY_{0}'.format(beam)])) + "{0}/{1}".format(os.path.dirname(self.conf_file), self.conf["SENSITIVITY_{0}".format(beam)]) + ) # self.sens[beam].wave = np.cast[np.double](self.sens[beam]['WAVELENGTH']) # self.sens[beam].sens = np.cast[np.double](self.sens[beam]['SENSITIVITY']) @@ -505,7 +521,7 @@ class aXeConf(): # $\lambda = dldp_0 + dldp_1 dp + dldp_2 dp^2$ ... poly_order = len(dydx) - 1 - if (poly_order == 2): + if poly_order == 2: if np.abs(np.unique(dydx[2])).max() == 0: poly_order = 1 @@ -515,10 +531,9 @@ class aXeConf(): dp = np.sqrt(1 + dydx[1] ** 2) * (dx) elif poly_order == 2: # quadratic trace u0 = dydx[1] + 2 * dydx[2] * (0) - dp0 = (u0 * np.sqrt(1 + u0 ** 2) + np.arcsinh(u0)) / (4 * dydx[2]) + dp0 = (u0 * np.sqrt(1 + u0**2) + np.arcsinh(u0)) / (4 * dydx[2]) u = dydx[1] + 2 * dydx[2] * (dx) - dp = (u * np.sqrt(1 + u ** 2) + np.arcsinh(u)) / \ - (4 * dydx[2]) - dp0 + dp = (u * np.sqrt(1 + u**2) + np.arcsinh(u)) / (4 * dydx[2]) - dp0 else: # high order shape, numerical integration along trace # (this can be slow) @@ -530,11 +545,10 @@ class aXeConf(): dyfull += i * dydx[i] * (xfull - 0.5) ** (i - 1) # Integrate from 0 to dx / -dx - dpfull = xfull * 0. + dpfull = xfull * 0.0 lt0 = xfull < 0 if lt0.sum() > 1: - dpfull[lt0] = np.cumsum( - np.sqrt(1 + dyfull[lt0][::-1] ** 2))[::-1] + dpfull[lt0] = np.cumsum(np.sqrt(1 + dyfull[lt0][::-1] ** 2))[::-1] dpfull[lt0] *= -1 # @@ -548,7 +562,7 @@ class aXeConf(): return dp - def get_beam_trace(self, x=507, y=507, dx=0., beam='A'): + def get_beam_trace(self, x=507, y=507, dx=0.0, beam="A"): """Get an aXe beam trace for an input reference pixel and list of output x pixels `dx` Parameters @@ -578,18 +592,16 @@ class aXeConf(): NORDER = self.orders[beam] + 1 xi, yi = x - self.xoff, y - self.yoff - xoff_beam = self.field_dependent( - xi, yi, self.conf['XOFF_{0}'.format(beam)]) - yoff_beam = self.field_dependent( - xi, yi, self.conf['YOFF_{0}'.format(beam)]) + xoff_beam = self.field_dependent(xi, yi, self.conf["XOFF_{0}".format(beam)]) + yoff_beam = self.field_dependent(xi, yi, self.conf["YOFF_{0}".format(beam)]) # y offset of trace (DYDX) dydx = np.zeros(NORDER) # 0 #+1.e-80 dydx = [0] * NORDER for i in range(NORDER): - if 'DYDX_{0:s}_{1:d}'.format(beam, i) in self.conf.keys(): - coeffs = self.conf['DYDX_{0:s}_{1:d}'.format(beam, i)] + if "DYDX_{0:s}_{1:d}".format(beam, i) in self.conf.keys(): + coeffs = self.conf["DYDX_{0:s}_{1:d}".format(beam, i)] dydx[i] = self.field_dependent(xi, yi, coeffs) # $dy = dydx_0+dydx_1 dx+dydx_2 dx^2+$ ... @@ -603,14 +615,20 @@ class aXeConf(): dldp = [0] * NORDER for i in range(NORDER): - if 'DLDP_{0:s}_{1:d}'.format(beam, i) in self.conf.keys(): - coeffs = self.conf['DLDP_{0:s}_{1:d}'.format(beam, i)] + if "DLDP_{0:s}_{1:d}".format(beam, i) in self.conf.keys(): + coeffs = self.conf["DLDP_{0:s}_{1:d}".format(beam, i)] dldp[i] = self.field_dependent(xi, yi, coeffs) - self.eval_input = {'x': x, 'y': y, 'beam': beam, 'dx': dx} - self.eval_output = {'xi': xi, 'yi': yi, 'dldp': dldp, 'dydx': dydx, - 'xoff_beam': xoff_beam, 'yoff_beam': yoff_beam, - 'dy': dy} + self.eval_input = {"x": x, "y": y, "beam": beam, "dx": dx} + self.eval_output = { + "xi": xi, + "yi": yi, + "dldp": dldp, + "dydx": dydx, + "xoff_beam": xoff_beam, + "yoff_beam": yoff_beam, + "dy": dy, + } dp = self.evaluate_dp(dx - xoff_beam, dydx) # ## dp is the arc length along the trace @@ -648,13 +666,13 @@ class aXeConf(): # dp = np.interp(dx-xoff_beam, xfull, dpfull) # Evaluate dldp - lam = dp * 0. + lam = dp * 0.0 for i in range(NORDER): - lam += dldp[i] * dp ** i + lam += dldp[i] * dp**i return dy, lam - def show_beams(self, beams=['E', 'D', 'C', 'B', 'A']): + def show_beams(self, beams=["E", "D", "C", "B", "A"]): """ Make a demo plot of the beams of a given configuration file """ @@ -663,45 +681,42 @@ class aXeConf(): x0, x1 = 507, 507 dx = np.arange(-800, 1200) - if 'WFC3.UV' in self.conf_file: + if "WFC3.UV" in self.conf_file: x0, x1 = 2073, 250 dx = np.arange(-1200, 1200) - if 'G800L' in self.conf_file: + if "G800L" in self.conf_file: x0, x1 = 2124, 1024 dx = np.arange(-1200, 1200) s = 200 # marker size fig = plt.figure(figsize=[10, 3]) - plt.scatter(0, 0, marker='s', s=s, color='black', edgecolor='0.8', - label='Direct') + plt.scatter(0, 0, marker="s", s=s, color="black", edgecolor="0.8", label="Direct") for beam in beams: - if 'XOFF_{0}'.format(beam) not in self.conf.keys(): + if "XOFF_{0}".format(beam) not in self.conf.keys(): continue - xoff = self.field_dependent( - x0, x1, self.conf['XOFF_{0}'.format(beam)]) + xoff = self.field_dependent(x0, x1, self.conf["XOFF_{0}".format(beam)]) dy, lam = self.get_beam_trace(x0, x1, dx=dx, beam=beam) - xlim = self.conf['BEAM{0}'.format(beam)] + xlim = self.conf["BEAM{0}".format(beam)] ok = (dx >= xlim[0]) & (dx <= xlim[1]) - plt.scatter(dx[ok] + xoff, dy[ok], c=lam[ok] / 1.e4, marker='s', s=s, - alpha=0.5, edgecolor='None') - plt.text(np.median(dx[ok]), np.median(dy[ok]) + 1, beam, - ha='center', va='center', fontsize=14) - print('Beam {0}, lambda=({1:.1f} - {2:.1f})'.format(beam, - lam[ok].min(), lam[ok].max())) + plt.scatter(dx[ok] + xoff, dy[ok], c=lam[ok] / 1.0e4, marker="s", s=s, alpha=0.5, edgecolor="None") + plt.text(np.median(dx[ok]), np.median(dy[ok]) + 1, beam, ha="center", va="center", fontsize=14) + print("Beam {0}, lambda=({1:.1f} - {2:.1f})".format(beam, lam[ok].min(), lam[ok].max())) plt.grid() - plt.xlabel(r'$\Delta x$') - plt.ylabel(r'$\Delta y$') + plt.xlabel(r"$\Delta x$") + plt.ylabel(r"$\Delta y$") cb = plt.colorbar(pad=0.01, fraction=0.05) - cb.set_label(r'$\lambda\,(\mu\mathrm{m})$') + cb.set_label(r"$\lambda\,(\mu\mathrm{m})$") plt.title(self.conf_file) plt.tight_layout() - plt.savefig('{0}.pdf'.format(self.conf_file)) + plt.savefig("{0}.pdf".format(self.conf_file)) # def load_grism_config(conf_file): + + # """Load parameters from an aXe configuration file # Parameters -- GitLab From 3351be2249de2beaf8beacd332e1a927e8324305 Mon Sep 17 00:00:00 2001 From: Chengliang Date: Sat, 26 Oct 2024 11:00:45 +0800 Subject: [PATCH 22/64] update codestyle-PEP8 --- observation_sim/mock_objects/Quasar.py | 2 +- observation_sim/mock_objects/Stamp.py | 2 +- observation_sim/mock_objects/Star.py | 4 ++-- observation_sim/mock_objects/_util.py | 6 +++--- tests/test_SpecDisperse.py | 4 ++-- tests/test_Straylight.py | 2 +- tests/test_darknoise_func.py | 6 +++--- tools/target_location_check.py | 10 +++++----- 8 files changed, 18 insertions(+), 18 deletions(-) diff --git a/observation_sim/mock_objects/Quasar.py b/observation_sim/mock_objects/Quasar.py index b27cb8c..3589b0d 100755 --- a/observation_sim/mock_objects/Quasar.py +++ b/observation_sim/mock_objects/Quasar.py @@ -98,7 +98,7 @@ class Quasar(MockObject): del self.sed def getGSObj(self, psf, g1=0, g2=0, flux=None, filt=None, tel=None, exptime=150.): - if flux == None: + if flux is None: flux = self.getElectronFluxFilt(filt, tel, exptime) qso = galsim.Gaussian(sigma=1.e-8, flux=1.) qso = qso.withFlux(flux) diff --git a/observation_sim/mock_objects/Stamp.py b/observation_sim/mock_objects/Stamp.py index 51de71c..d39ace7 100644 --- a/observation_sim/mock_objects/Stamp.py +++ b/observation_sim/mock_objects/Stamp.py @@ -21,7 +21,7 @@ class Stamp(MockObject): del self.sed def drawObj_multiband(self, tel, pos_img, psf_model, bandpass_list, filt, chip, nphotons_tot=None, g1=0, g2=0, exptime=150., fd_shear=None): - if nphotons_tot == None: + if nphotons_tot is None: nphotons_tot = self.getElectronFluxFilt(filt, tel, exptime) try: diff --git a/observation_sim/mock_objects/Star.py b/observation_sim/mock_objects/Star.py index c27b4ba..c0aceb3 100755 --- a/observation_sim/mock_objects/Star.py +++ b/observation_sim/mock_objects/Star.py @@ -22,7 +22,7 @@ class Star(MockObject): del self.sed def getGSObj(self, psf, g1=0, g2=0, flux=None, filt=None, tel=None, exptime=150.): - if flux == None: + if flux is None: flux = self.getElectronFluxFilt(filt, tel, exptime) # star = galsim.Gaussian(sigma=1.e-8, flux=1.) star = galsim.DeltaFunction() @@ -35,7 +35,7 @@ class Star(MockObject): raise ValueError( "!!!The number of PSF profiles and the number of bandpasses must be equal.") objs = [] - if nphotons_tot == None: + if nphotons_tot is None: nphotons_tot = self.getElectronFluxFilt(filt, tel, exptime) try: diff --git a/observation_sim/mock_objects/_util.py b/observation_sim/mock_objects/_util.py index f5b0c06..5707fd4 100755 --- a/observation_sim/mock_objects/_util.py +++ b/observation_sim/mock_objects/_util.py @@ -58,7 +58,7 @@ def seds(sedlistn, seddir="./", unit="A"): read SEDs and save into Python dictionary Parameters: - sedlistn: filename of the sed template list and corresponding intrinsic + sedlistn: filename of the sed template list and corresponding intrinsic extinction model, see tmag_dz.py for detailes listdir: directory of the list unit: wavelength unit of the input templates @@ -420,7 +420,7 @@ def sed2mag(mag_i, sedCat, filter_list, redshift=0.0, av=0.0, redden=0): def eObs(e1, e2, g1, g2): """ - Calculate the sheared (observed) ellipticity using the + Calculate the sheared (observed) ellipticity using the intrinsic ellipticity and cosmic shear components. Parameters: @@ -558,7 +558,7 @@ def getNormFactorForSpecWithABMAG(ABMag=20., spectrum=None, norm_thr=None, sWave eWave: the end of norm_thr Return: - the normalization factor flux of AB system(fix a band and magnitude ) /the flux of inpute spectrum(fix a band) + the normalization factor flux of AB system(fix a band and magnitude ) /the flux of inpute spectrum(fix a band) """ spectrumi = interpolate.interp1d(spectrum['WAVELENGTH'], spectrum['FLUX']) norm_thri = interpolate.interp1d( diff --git a/tests/test_SpecDisperse.py b/tests/test_SpecDisperse.py index 4a6553e..df7a780 100644 --- a/tests/test_SpecDisperse.py +++ b/tests/test_SpecDisperse.py @@ -428,8 +428,8 @@ class TestSpecDisperse(unittest.TestCase): plt.xlim(6200, 10000) plt.ylim(1, 4) plt.yscale('log') - plt.xlabel('$\lambda$') - plt.ylabel('$F\lambda$') + plt.xlabel(r'$\lambda$') + plt.ylabel(r'$F\lambda$') plt.legend(['one spec', 'split in 8000 A']) plt.show() diff --git a/tests/test_Straylight.py b/tests/test_Straylight.py index 90f82a9..63c1376 100644 --- a/tests/test_Straylight.py +++ b/tests/test_Straylight.py @@ -192,7 +192,7 @@ class TestStraylight(unittest.TestCase): plt.figure() plt.plot(spec['WAVELENGTH'], spec['FLUX'], 'r') plt.xlabel('WAVELENGTH') - plt.ylabel('F$\lambda$(erg/s/cm2/A/arcsec2)') + plt.ylabel(r'F$\lambda$(erg/s/cm2/A/arcsec2)') plt.xlim(2000, 10000) plt.show() median = np.median(sl_e_pix[0:tnum]) diff --git a/tests/test_darknoise_func.py b/tests/test_darknoise_func.py index 42bf398..58afd45 100644 --- a/tests/test_darknoise_func.py +++ b/tests/test_darknoise_func.py @@ -10,11 +10,11 @@ import yaml from observation_sim.instruments import Chip, Filter, FilterParam, FocalPlane -### test FUNCTION --- START ### +# test FUNCTION --- START ### def get_base_img(img, chip, read_noise, readout_time, dark_noise, exptime=150., InputDark=None): - if InputDark == None: + if InputDark is None: # base_level = read_noise**2 + dark_noise*(exptime+0.5*readout_time) # base_level = dark_noise*(exptime+0.5*readout_time) base_level = dark_noise*(exptime) @@ -31,7 +31,7 @@ def get_base_img(img, chip, read_noise, readout_time, dark_noise, exptime=150., base_img2[ny:, :] = arr[::-1, :] base_img2[:, :] = base_img2[:, :]*(readout_time/ny)*dark_noise return base_img1+base_img2 -### test FUNCTION --- END ### +# test FUNCTION --- END ### def defineCCD(iccd, config_file): diff --git a/tools/target_location_check.py b/tools/target_location_check.py index 11f22ba..6e0f525 100644 --- a/tools/target_location_check.py +++ b/tools/target_location_check.py @@ -26,7 +26,7 @@ def focalPlaneInf(ra_target, dec_target, ra_point, dec_point, image_rot=-113.433 float, in unit of degrees; image_rot : orientation of the camera with respect the sky; float, in unit of degrees; - NOTE: image_rot=-113.4333 is the default value + NOTE: image_rot=-113.4333 is the default value in current CSST image simulation; figout : location of the target object in the focal plane; str @@ -36,7 +36,7 @@ def focalPlaneInf(ra_target, dec_target, ra_point, dec_point, image_rot=-113.433 the pointing center (ra_point dec_point) of the telescope 1) open a terminal 2) type >> python TargetLocationCheck.py ra_target dec_target ra_point dec_point - or type >> python TargetLocationCheck.py ra_target dec_target ra_point dec_point -image_rot=floatNum + or type >> python TargetLocationCheck.py ra_target dec_target ra_point dec_point -image_rot=floatNum or type >> python TargetLocationCheck.py ra_target dec_target ra_point dec_point -image_rot=floatNum -figout=FigureName """ print("^_^ Input target coordinate: [Ra, Dec] = [%10.6f, %10.6f]" % ( @@ -105,7 +105,7 @@ def ccdParam(): def getTanWCS(ra, dec, img_rot, pix_scale=0.074): - """ + """ Get the WCS of the image mosaic using Gnomonic/TAN projection Parameter: ra, dec: float @@ -221,8 +221,8 @@ def ccdLayout(xpixTar, ypixTar, figout="ccdLayout.pdf"): ax.text(ix0+500, iy0+1500, "%s#%s" % (fType, ischip), fontsize=12, color="grey") ax.plot(xpixTar, ypixTar, "r*", ms=12) - ax.set_xlabel("$X\,[\mathrm{pixels}]$", fontsize=20) - ax.set_ylabel("$Y\,[\mathrm{pixels}]$", fontsize=20) + ax.set_xlabel(r"$X\,[\mathrm{pixels}]$", fontsize=20) + ax.set_ylabel(r"$Y\,[\mathrm{pixels}]$", fontsize=20) ax.invert_yaxis() ax.axis('off') plt.savefig(figout) -- GitLab From d10eb6a8852d34c44856f50ac9bc7f4288c5d173 Mon Sep 17 00:00:00 2001 From: Zhang Xin Date: Sat, 26 Oct 2024 11:16:50 +0800 Subject: [PATCH 23/64] pep8 formatting --- .../SpecDisperser/SpecDisperser.py | 54 ++++++++++++------- 1 file changed, 35 insertions(+), 19 deletions(-) diff --git a/observation_sim/mock_objects/SpecDisperser/SpecDisperser.py b/observation_sim/mock_objects/SpecDisperser/SpecDisperser.py index 6936eb1..2a8bfe4 100644 --- a/observation_sim/mock_objects/SpecDisperser/SpecDisperser.py +++ b/observation_sim/mock_objects/SpecDisperser/SpecDisperser.py @@ -173,9 +173,11 @@ class SpecDisperser(object): lam_index = argsort(lam_beam) conf_sens = self.grating_conf.sens[beam] - lam_intep = np.linspace(self.band_start, self.band_end, int((self.band_end - self.band_start) / 0.1)) + lam_intep = np.linspace(self.band_start, self.band_end, int( + (self.band_end - self.band_start) / 0.1)) - thri = interpolate.interp1d(conf_sens["WAVELENGTH"], conf_sens["SENSITIVITY"]) + thri = interpolate.interp1d( + conf_sens["WAVELENGTH"], conf_sens["SENSITIVITY"]) spci = interpolate.interp1d(self.spec["WAVELENGTH"], self.spec["FLUX"]) beam_thr = thri(lam_intep) @@ -201,7 +203,8 @@ class SpecDisperser(object): sensitivity_beam = ysens len_spec_x = len(dx) - len_spec_y = int(abs(ceil(ytrace_beam[-1]) - floor(ytrace_beam[0])) + 1) + len_spec_y = int( + abs(ceil(ytrace_beam[-1]) - floor(ytrace_beam[0])) + 1) beam_sh = (self.img_sh[0] + len_spec_y, self.img_sh[1] + len_spec_x) modelf = zeros(product(beam_sh), dtype=float) @@ -246,7 +249,8 @@ class SpecDisperser(object): else: beam_flat = zeros([len(modelf), len(self.flat_cube)]) - sub_flat_cube = zeros([len(self.flat_cube), beam_sh[0], beam_sh[1]]) + sub_flat_cube = zeros( + [len(self.flat_cube), beam_sh[0], beam_sh[1]]) sub_flat_cube[0] = sub_flat_cube[0] + 1.0 overlap_flag = 1 @@ -276,9 +280,9 @@ class SpecDisperser(object): if overlap_flag == 1: sub_flat_cube[ :, - beam_y_s - originOut_y : beam_y_e - originOut_y + 1, - beam_x_s - originOut_x : beam_x_e - originOut_x + 1, - ] = self.flat_cube[:, beam_y_s : beam_y_e + 1, beam_x_s : beam_x_e + 1] + beam_y_s - originOut_y: beam_y_e - originOut_y + 1, + beam_x_s - originOut_x: beam_x_e - originOut_x + 1, + ] = self.flat_cube[:, beam_y_s: beam_y_e + 1, beam_x_s: beam_x_e + 1] for i in arange(0, len(self.flat_cube), 1): beam_flat[:, i] = sub_flat_cube[i].flatten() @@ -330,9 +334,11 @@ class SpecDisperser(object): def writerSensitivityFile(self, conffile="", beam="", w=None, sens=None): orders = {"A": "1st", "B": "0st", "C": "2st", "D": "-1st", "E": "-2st"} - sens_file_name = conffile[0:-5] + "_sensitivity_" + orders[beam] + ".fits" + sens_file_name = conffile[0:-5] + \ + "_sensitivity_" + orders[beam] + ".fits" if not os.path.exists(sens_file_name) == True: - senstivity_out = Table(array([w, sens]).T, names=("WAVELENGTH", "SENSITIVITY")) + senstivity_out = Table( + array([w, sens]).T, names=("WAVELENGTH", "SENSITIVITY")) senstivity_out.write(sens_file_name, format="fits") @@ -431,9 +437,11 @@ class aXeConf: self.dxlam[beam] = np.arange( self.conf["BEAM{0}".format(beam)].min(), self.conf["BEAM{0}".format(beam)].max(), dtype=int ) - self.nx[beam] = int(self.dxlam[beam].max() - self.dxlam[beam].min()) + 1 + self.nx[beam] = int(self.dxlam[beam].max() - + self.dxlam[beam].min()) + 1 self.sens[beam] = Table.read( - "{0}/{1}".format(os.path.dirname(self.conf_file), self.conf["SENSITIVITY_{0}".format(beam)]) + "{0}/{1}".format(os.path.dirname(self.conf_file), + self.conf["SENSITIVITY_{0}".format(beam)]) ) # self.sens[beam].wave = np.cast[np.double](self.sens[beam]['WAVELENGTH']) # self.sens[beam].sens = np.cast[np.double](self.sens[beam]['SENSITIVITY']) @@ -548,7 +556,8 @@ class aXeConf: dpfull = xfull * 0.0 lt0 = xfull < 0 if lt0.sum() > 1: - dpfull[lt0] = np.cumsum(np.sqrt(1 + dyfull[lt0][::-1] ** 2))[::-1] + dpfull[lt0] = np.cumsum( + np.sqrt(1 + dyfull[lt0][::-1] ** 2))[::-1] dpfull[lt0] *= -1 # @@ -592,8 +601,10 @@ class aXeConf: NORDER = self.orders[beam] + 1 xi, yi = x - self.xoff, y - self.yoff - xoff_beam = self.field_dependent(xi, yi, self.conf["XOFF_{0}".format(beam)]) - yoff_beam = self.field_dependent(xi, yi, self.conf["YOFF_{0}".format(beam)]) + xoff_beam = self.field_dependent( + xi, yi, self.conf["XOFF_{0}".format(beam)]) + yoff_beam = self.field_dependent( + xi, yi, self.conf["YOFF_{0}".format(beam)]) # y offset of trace (DYDX) dydx = np.zeros(NORDER) # 0 #+1.e-80 @@ -690,19 +701,24 @@ class aXeConf: s = 200 # marker size fig = plt.figure(figsize=[10, 3]) - plt.scatter(0, 0, marker="s", s=s, color="black", edgecolor="0.8", label="Direct") + plt.scatter(0, 0, marker="s", s=s, color="black", + edgecolor="0.8", label="Direct") for beam in beams: if "XOFF_{0}".format(beam) not in self.conf.keys(): continue - xoff = self.field_dependent(x0, x1, self.conf["XOFF_{0}".format(beam)]) + xoff = self.field_dependent( + x0, x1, self.conf["XOFF_{0}".format(beam)]) dy, lam = self.get_beam_trace(x0, x1, dx=dx, beam=beam) xlim = self.conf["BEAM{0}".format(beam)] ok = (dx >= xlim[0]) & (dx <= xlim[1]) - plt.scatter(dx[ok] + xoff, dy[ok], c=lam[ok] / 1.0e4, marker="s", s=s, alpha=0.5, edgecolor="None") - plt.text(np.median(dx[ok]), np.median(dy[ok]) + 1, beam, ha="center", va="center", fontsize=14) - print("Beam {0}, lambda=({1:.1f} - {2:.1f})".format(beam, lam[ok].min(), lam[ok].max())) + plt.scatter(dx[ok] + xoff, dy[ok], c=lam[ok] / 1.0e4, + marker="s", s=s, alpha=0.5, edgecolor="None") + plt.text(np.median(dx[ok]), np.median( + dy[ok]) + 1, beam, ha="center", va="center", fontsize=14) + print("Beam {0}, lambda=({1:.1f} - {2:.1f})".format(beam, + lam[ok].min(), lam[ok].max())) plt.grid() plt.xlabel(r"$\Delta x$") -- GitLab From 456825709ab4635616fc88e2219522c41e8e1be8 Mon Sep 17 00:00:00 2001 From: Zhang Xin Date: Sat, 26 Oct 2024 11:23:37 +0800 Subject: [PATCH 24/64] pep8 --- .../SpecDisperser/SpecDisperser.py | 2 +- .../mock_objects/SpecDisperser/setup_c.py | 14 +-- observation_sim/psf/PSFInterpSLS.py | 84 +++++++------ tools/get_pointing.py | 111 ++++++++++-------- tools/get_pointing_accuracy.py | 57 +++++---- 5 files changed, 144 insertions(+), 124 deletions(-) diff --git a/observation_sim/mock_objects/SpecDisperser/SpecDisperser.py b/observation_sim/mock_objects/SpecDisperser/SpecDisperser.py index 2a8bfe4..a6073a7 100644 --- a/observation_sim/mock_objects/SpecDisperser/SpecDisperser.py +++ b/observation_sim/mock_objects/SpecDisperser/SpecDisperser.py @@ -336,7 +336,7 @@ class SpecDisperser(object): orders = {"A": "1st", "B": "0st", "C": "2st", "D": "-1st", "E": "-2st"} sens_file_name = conffile[0:-5] + \ "_sensitivity_" + orders[beam] + ".fits" - if not os.path.exists(sens_file_name) == True: + if os.path.exists(sens_file_name) if False: senstivity_out = Table( array([w, sens]).T, names=("WAVELENGTH", "SENSITIVITY")) senstivity_out.write(sens_file_name, format="fits") diff --git a/observation_sim/mock_objects/SpecDisperser/setup_c.py b/observation_sim/mock_objects/SpecDisperser/setup_c.py index feceb97..e5a4467 100644 --- a/observation_sim/mock_objects/SpecDisperser/setup_c.py +++ b/observation_sim/mock_objects/SpecDisperser/setup_c.py @@ -8,16 +8,16 @@ import numpy extensions = [ Extension("disperse_c.interp", ["disperse_c/interp.pyx"], - include_dirs = [numpy.get_include()], - libraries=["m"]), - + include_dirs=[numpy.get_include()], + libraries=["m"]), + Extension("disperse_c.disperse", ["disperse_c/disperse.pyx"], - include_dirs = [numpy.get_include()], - libraries=["m"]), + include_dirs=[numpy.get_include()], + libraries=["m"]), ] setup( - name = "slssim_disperse", - ext_modules = cythonize(extensions), + name="slssim_disperse", + ext_modules=cythonize(extensions), ) diff --git a/observation_sim/psf/PSFInterpSLS.py b/observation_sim/psf/PSFInterpSLS.py index 90ac027..50521b8 100644 --- a/observation_sim/psf/PSFInterpSLS.py +++ b/observation_sim/psf/PSFInterpSLS.py @@ -435,14 +435,15 @@ class PSFInterpSLS(PSFModel): # PSF_int_trans[ids_szero] = 0 # print(PSF_int_trans[ids_szero].shape[0],PSF_int_trans.shape) PSF_int_trans = PSF_int_trans/np.sum(PSF_int_trans) - ###DEBGU - ids_szero = PSF_int_trans<0 + # DEBGU + ids_szero = PSF_int_trans < 0 n01 = PSF_int_trans[ids_szero].shape[0] n1 = np.sum(np.isinf(PSF_int_trans)) n2 = np.sum(np.isnan(PSF_int_trans)) - if n1>0 or n2>0: - print("DEBUG: PSFInterpSLS, inf:%d, nan:%d, 0 num:%d"%(n1, n2, n01)) + if n1 > 0 or n2 > 0: + print("DEBUG: PSFInterpSLS, inf:%d, nan:%d, 0 num:%d" % + (n1, n2, n01)) #### # from astropy.io import fits @@ -537,36 +538,37 @@ class PSFInterpSLS(PSFModel): sumImg = np.sum(cutImg.array) tmp_img = cutImg*0 for j in np.arange(npc): - X_ = np.hstack((pos_p[:,1].flatten()[:, None], pos_p[:,0].flatten()[:, None]),dtype=np.float32) + X_ = np.hstack((pos_p[:, 1].flatten()[:, None], pos_p[:, 0].flatten()[ + :, None]), dtype=np.float32) Z_ = (pc_coeff[j].astype(np.float32)).flatten() # print(pc_coeff[j].shape[0], pos_p[:,1].shape[0], pos_p[:,0].shape[0]) cx_len = int(chip.npix_x) cy_len = int(chip.npix_y) - n_x = np.arange(0, cx_len, 1, dtype = int) - n_y = np.arange(0, cy_len, 1, dtype = int) + n_x = np.arange(0, cx_len, 1, dtype=int) + n_y = np.arange(0, cy_len, 1, dtype=int) M, N = np.meshgrid(n_x, n_y) # t1=datetime.datetime.now() # U = interpolate.griddata(X_, Z_, (M[0:cy_len, 0:cx_len],N[0:cy_len, 0:cx_len]), # method='nearest',fill_value=1.0) b_img = galsim.Image(cx_len, cy_len) - b_img.setOrigin(0,0) + b_img.setOrigin(0, 0) bounds = cutImg.bounds & b_img.bounds if bounds.area() == 0: continue # ys = cutImg.ymin - # if ys < 0: + # if ys < 0: # ys = 0 # ye = cutImg.ymin+cutImg.nrow - # if ye >= cy_len-1: + # if ye >= cy_len-1: # ye = cy_len-1 # if ye - ys <=0: # continue # xs = cutImg.xmin - # if xs < 0: + # if xs < 0: # xs = 0 # xe = cutImg.xmin+cutImg.ncol - # if xe >= cx_len-1: + # if xe >= cx_len-1: # xe = cx_len-1 # if xe - xs <=0: # continue @@ -574,10 +576,10 @@ class PSFInterpSLS(PSFModel): ye = bounds.ymax+1 xs = bounds.xmin xe = bounds.xmax+1 - U = interpolate.griddata(X_, Z_, (M[ys:ye, xs:xe],N[ys:ye, xs:xe]), - method='nearest',fill_value=1.0) + U = interpolate.griddata(X_, Z_, (M[ys:ye, xs:xe], N[ys:ye, xs:xe]), + method='nearest', fill_value=1.0) # t2=datetime.datetime.now() - + # print("time interpolate:", t2-t1) # if U.shape != cutImg.array.shape: @@ -586,53 +588,53 @@ class PSFInterpSLS(PSFModel): img_tmp = cutImg img_tmp[bounds] = img_tmp[bounds]*U psf = pcs[:, j].reshape(m_size, m_size) - tmp_img = tmp_img + signal.fftconvolve(img_tmp.array, psf, mode='same', axes=None) + tmp_img = tmp_img + \ + signal.fftconvolve(img_tmp.array, psf, mode='same', axes=None) # t3=datetime.datetime.now() # print("time convole:", t3-t2) del U del img_tmp - if np.sum(tmp_img.array)==0: + if np.sum(tmp_img.array) == 0: tmp_img = cutImg else: tmp_img = tmp_img/np.sum(tmp_img.array)*sumImg return tmp_img - def convolveFullImgWithPCAPSF(self, chip, folding_threshold=5.e-3): - keys_L1= chip_utils.getChipSLSGratingID(chip.chipID) + keys_L1 = chip_utils.getChipSLSGratingID(chip.chipID) # keys_L2 = ['order-2','order-1','order0','order1','order2'] - keys_L2 = ['order0','order1'] - keys_L3 = ['w1','w2','w3','w4'] + keys_L2 = ['order0', 'order1'] + keys_L3 = ['w1', 'w2', 'w3', 'w4'] npca = 10 x_start = chip.x_cen/chip.pix_size - chip.npix_x / 2. y_start = chip.y_cen/chip.pix_size - chip.npix_y / 2. - for i,gt in enumerate(keys_L1): + for i, gt in enumerate(keys_L1): psfCo = self.grating1_data if i > 0: psfCo = self.grating2_data for od in keys_L2: psfCo_L2 = psfCo['order1'] - if od in ['order-2','order-1','order0','order2']: + if od in ['order-2', 'order-1', 'order0', 'order2']: psfCo_L2 = psfCo['order0'] for w in keys_L3: img = chip.img_stack[gt][od][w] pcs = psfCo_L2['band'+w[1]]['band_data'][0].data - pos_p = psfCo_L2['band'+w[1]]['band_data'][1].data/chip.pix_size - np.array([y_start, x_start]) + pos_p = psfCo_L2['band'+w[1]]['band_data'][1].data / \ + chip.pix_size - np.array([y_start, x_start]) pc_coeff = psfCo_L2['band'+w[1]]['band_data'][2].data # print("DEBUG-----------",np.max(pos_p[:,1]),np.min(pos_p[:,1]), np.max(pos_p[:,0]),np.min(pos_p[:,0])) sum_img = np.sum(img.array) - - + # coeff_mat = np.zeros([npca, chip.npix_y, chip.npix_x]) # for m in np.arange(chip.npix_y): # for n in np.arange(chip.npix_x): # px = n # py = m - + # dist2 = (pos_p[:, 1] - px)*(pos_p[:, 1] - px) + (pos_p[:, 0] - py)*(pos_p[:, 0] - py) # temp_sort_dist = np.zeros([dist2.shape[0], 2]) # temp_sort_dist[:, 0] = np.arange(0, dist2.shape[0], 1) @@ -660,41 +662,45 @@ class PSFInterpSLS(PSFModel): # coeff_mat[:, m, n] = coeff_int m_size = int(pcs.shape[0]**0.5) - tmp_img = np.zeros_like(img.array,dtype=np.float32) + tmp_img = np.zeros_like(img.array, dtype=np.float32) for j in np.arange(npca): print(gt, od, w, j) - X_ = np.hstack((pos_p[:,1].flatten()[:, None], pos_p[:,0].flatten()[:, None]),dtype=np.float32) + X_ = np.hstack((pos_p[:, 1].flatten()[:, None], pos_p[:, 0].flatten()[ + :, None]), dtype=np.float32) Z_ = (pc_coeff[j].astype(np.float32)).flatten() # print(pc_coeff[j].shape[0], pos_p[:,1].shape[0], pos_p[:,0].shape[0]) sub_size = 4 cx_len = int(chip.npix_x/sub_size) cy_len = int(chip.npix_y/sub_size) - n_x = np.arange(0, chip.npix_x, sub_size, dtype = int) - n_y = np.arange(0, chip.npix_y, sub_size, dtype = int) + n_x = np.arange(0, chip.npix_x, sub_size, dtype=int) + n_y = np.arange(0, chip.npix_y, sub_size, dtype=int) M, N = np.meshgrid(n_x, n_y) - t1=datetime.datetime.now() + t1 = datetime.datetime.now() # U = interpolate.griddata(X_, Z_, (M[0:cy_len, 0:cx_len],N[0:cy_len, 0:cx_len]), # method='nearest',fill_value=1.0) U1 = interpolate.griddata(X_, Z_, (M, N), - method='nearest',fill_value=1.0) + method='nearest', fill_value=1.0) U = np.zeros_like(chip.img.array, dtype=np.float32) for mi in np.arange(cy_len): for mj in np.arange(cx_len): - U[mi*sub_size:(mi+1)*sub_size, mj*sub_size:(mj+1)*sub_size]=U1[mi,mj] - t2=datetime.datetime.now() - + U[mi*sub_size:(mi+1)*sub_size, mj * + sub_size:(mj+1)*sub_size] = U1[mi, mj] + t2 = datetime.datetime.now() + print("time interpolate:", t2-t1) img_tmp = img.array*U psf = pcs[:, j].reshape(m_size, m_size) - tmp_img = tmp_img + signal.fftconvolve(img_tmp, psf, mode='same', axes=None) + tmp_img = tmp_img + \ + signal.fftconvolve( + img_tmp, psf, mode='same', axes=None) - t3=datetime.datetime.now() + t3 = datetime.datetime.now() print("time convole:", t3-t2) del U del U1 - + chip.img = chip.img + tmp_img*sum_img/np.sum(tmp_img) del tmp_img gc.collect() diff --git a/tools/get_pointing.py b/tools/get_pointing.py index 39216a1..d5c1d17 100755 --- a/tools/get_pointing.py +++ b/tools/get_pointing.py @@ -2,7 +2,7 @@ # get_pointing # PURPOSE: # Return the pointing of CSST from a given [ra, dec] -# CALLING: +# CALLING: # pointing = findPointingbyChipID(chipID=tchip, ra=tra, dec=tdec) # INPUTS: # chipID - chip-# of CSST, int @@ -13,8 +13,8 @@ # HISTORY: # Written by Xin Zhang, 23 Apr. 2023 # Included by csst-simulation, C.W. 25 Apr. 2023 -# -# +# +# from tkinter.tix import INTEGER import astropy.coordinates as coord @@ -25,6 +25,7 @@ import galsim import math # from numba import jit + class Chip(object): def __init__(self, chipID): self.chipID = chipID @@ -41,9 +42,9 @@ class Chip(object): self.npix_x = 9216 self.npix_y = 9232 - self.pix_scale = 0.074 + self.pix_scale = 0.074 - def getTanWCS(self, ra, dec, img_rot, pix_scale = None, xcen=None, ycen=None, logger=None): + def getTanWCS(self, ra, dec, img_rot, pix_scale=None, xcen=None, ycen=None, logger=None): """ Get the WCS of the image mosaic using Gnomonic/TAN projection Parameter: @@ -57,7 +58,8 @@ class Chip(object): WCS of the focal plane """ 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): xcen = self.cen_pix_x ycen = self.cen_pix_y @@ -72,23 +74,24 @@ class Chip(object): dudy = +np.sin(img_rot.rad) * pix_scale dvdx = -np.sin(img_rot.rad) * pix_scale dvdy = -np.cos(img_rot.rad) * pix_scale - + # dudx = +np.sin(img_rot.rad) * pix_scale # dudy = +np.cos(img_rot.rad) * pix_scale # dvdx = -np.cos(img_rot.rad) * pix_scale # dvdy = +np.sin(img_rot.rad) * pix_scale 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) WCS = galsim.TanWCS(affine, sky_center, units=galsim.arcsec) return WCS - + def getChipRowCol(self, chipID): rowID = ((chipID - 1) % 5) + 1 colID = 6 - ((chipID - 1) // 5) return rowID, colID - + def getChipCenter(self): """Calculate the edges in pixel for a given CCD chip on the focal plane NOTE: There are 5*4 CCD chips in the focus plane for photometric observation. @@ -99,8 +102,6 @@ class Chip(object): A galsim BoundsD object """ - - chipID = self.chipID rowID, colID = self.getChipRowCol(chipID) @@ -125,37 +126,42 @@ class Chip(object): return galsim.PositionD(xcen, ycen) + def transRaDec2D(ra, dec): - x1 = np.cos(dec / 57.2957795) * np.cos(ra / 57.2957795); - y1 = np.cos(dec / 57.2957795) * np.sin(ra / 57.2957795); - z1 = np.sin(dec / 57.2957795); + x1 = np.cos(dec / 57.2957795) * np.cos(ra / 57.2957795) + y1 = np.cos(dec / 57.2957795) * np.sin(ra / 57.2957795) + z1 = np.sin(dec / 57.2957795) return np.array([x1, y1, z1]) + def getobsPA(ra, dec): - l1 = np.array([0,0,1]) + l1 = np.array([0, 0, 1]) l2 = transRaDec2D(ra, dec) - polar_ec = coord.SkyCoord(0*u.degree, 90*u.degree,frame='barycentrictrueecliptic') + polar_ec = coord.SkyCoord(0*u.degree, 90*u.degree, + frame='barycentrictrueecliptic') polar_eq = polar_ec.transform_to('icrs') # print(polar_eq.ra.value,polar_eq.dec.value) polar_d = transRaDec2D(polar_eq.ra.value, polar_eq.dec.value) - l1l2cross = np.cross(l2,l1) - pdl2cross = np.cross(l2,polar_d) - angle = math.acos(np.dot(l1l2cross,pdl2cross)/(np.linalg.norm(l1l2cross)*np.linalg.norm(pdl2cross))) + l1l2cross = np.cross(l2, l1) + pdl2cross = np.cross(l2, polar_d) + angle = math.acos(np.dot(l1l2cross, pdl2cross) / + (np.linalg.norm(l1l2cross)*np.linalg.norm(pdl2cross))) angle = (angle)/math.pi*180 angle = angle + 90 - if (ra<90 or ra> 270): - angle=-angle + if (ra < 90 or ra > 270): + angle = -angle return angle # @jit() -def getSelectPointingList(center = [60,-40], radius = 2): + + +def getSelectPointingList(center=[60, -40], radius=2): points = np.loadtxt('sky.dat') - - center = center#ra dec - radius = radius # degree + center = center # ra dec + radius = radius # degree radii_dec = 1 radii_ra = 1/math.cos(math.pi*center[1]/180) @@ -163,7 +169,8 @@ def getSelectPointingList(center = [60,-40], radius = 2): if radii_ra > 180: radii_ra = 180 - c_eclip = coord.SkyCoord(points[:,2]*u.degree, points[:,1]*u.degree,frame='barycentrictrueecliptic') + c_eclip = coord.SkyCoord( + points[:, 2]*u.degree, points[:, 1]*u.degree, frame='barycentrictrueecliptic') c_equtor = c_eclip.transform_to('icrs') # print(np.min((c_equtor.ra*u.degree).value), np.max((c_equtor.ra*u.degree).value)) @@ -174,13 +181,15 @@ def getSelectPointingList(center = [60,-40], radius = 2): ra_range_lo = center[0]-radii_ra ra_range_hi = center[0]+radii_ra - if ra_range_lo< 0: - ids1 = ((c_equtor.ra*u.degree).value360+ra_range_lo) + if ra_range_lo < 0: + ids1 = ((c_equtor.ra*u.degree).value < + ra_range_hi) | ((c_equtor.ra*u.degree).value > 360+ra_range_lo) elif ra_range_hi > 360: - ids1 = ((c_equtor.ra*u.degree).value>ra_range_lo) | ((c_equtor.ra*u.degree).value + ra_range_lo) | ((c_equtor.ra*u.degree).value < ra_range_hi-360) else: - ids1 = ((c_equtor.ra*u.degree).value > ra_range_lo) & ((c_equtor.ra*u.degree).value < ra_range_hi) - + ids1 = ((c_equtor.ra*u.degree).value > + ra_range_lo) & ((c_equtor.ra*u.degree).value < ra_range_hi) dec_range_lo = center[1]-radii_dec if center[1]-radii_dec < -90: @@ -189,7 +198,7 @@ def getSelectPointingList(center = [60,-40], radius = 2): dec_range_hi = center[1]+radii_dec if center[1]+radii_dec > 90: dec_range_hi = 90 - + ids3 = (c_equtor[ids1].dec*u.degree).value > dec_range_lo ids4 = (c_equtor[ids1][ids3].dec*u.degree).value < dec_range_hi @@ -198,25 +207,24 @@ def getSelectPointingList(center = [60,-40], radius = 2): p_result = np.zeros([num, 5]) i = 0 - for p,p_ in zip(points[ids1][ids3][ids4],c_equtor[ids1][ids3][ids4]): + for p, p_ in zip(points[ids1][ids3][ids4], c_equtor[ids1][ids3][ids4]): ra = (p_.ra*u.degree).value dec = (p_.dec*u.degree).value # print(ra, dec) lon = p[2] lat = p[1] - p_result[i,0] = ra - p_result[i,1] = dec - p_result[i,2] = lon - p_result[i,3] = lat - p_result[i,4] = getobsPA(ra, dec) + 90 + p_result[i, 0] = ra + p_result[i, 1] = dec + p_result[i, 2] = lon + p_result[i, 3] = lat + p_result[i, 4] = getobsPA(ra, dec) + 90 i = i + 1 - - return p_result + return p_result -def findPointingbyChipID(chipID = 8, ra = 60., dec = -40.): +def findPointingbyChipID(chipID=8, ra=60., dec=-40.): """_summary_ Args: @@ -226,9 +234,9 @@ def findPointingbyChipID(chipID = 8, ra = 60., dec = -40.): Returns: _type_: [ra, dec, rotation angle] - """ + """ chip_center = [ra, dec] - p_list = getSelectPointingList(center = chip_center) + p_list = getSelectPointingList(center=chip_center) pchip = Chip(chipID) p_num = p_list.shape[0] @@ -238,10 +246,10 @@ def findPointingbyChipID(chipID = 8, ra = 60., dec = -40.): r_ra = ra r_dec = dec r_rot = 0. - for i in np.arange(0,p_num,1): - ra_n = p_list[i,0] - dec_n = p_list[i,1] - rot = p_list[i,4]*galsim.degrees + for i in np.arange(0, p_num, 1): + ra_n = p_list[i, 0] + dec_n = p_list[i, 1] + rot = p_list[i, 4]*galsim.degrees chip_wcs = pchip.getTanWCS(ra_n, dec_n, rot) c_center = pchip.getChipCenter() @@ -257,15 +265,14 @@ def findPointingbyChipID(chipID = 8, ra = 60., dec = -40.): r_ra = ra_n r_dec = dec_n r_rot = rot.deg - + if min_d == max_value: - print("RA:%f,Dec:%fä¸åœ¨æŒ‡å‘范围内,请于巡天规划åºåˆ—比对ï¼ï¼ï¼ï¼ï¼"%(ra, dec)) + print("RA:%f,Dec:%fä¸åœ¨æŒ‡å‘范围内,请于巡天规划åºåˆ—比对ï¼ï¼ï¼ï¼ï¼" % (ra, dec)) - return [r_ra, r_dec , r_rot] + return [r_ra, r_dec, r_rot] if __name__ == "__main__": tchip, tra, tdec = 13, 60., -40. pointing = findPointingbyChipID(chipID=tchip, ra=tra, dec=tdec) print("[ra_center, dec_center, image_rot]: ", pointing) - diff --git a/tools/get_pointing_accuracy.py b/tools/get_pointing_accuracy.py index 33d8575..7c53134 100644 --- a/tools/get_pointing_accuracy.py +++ b/tools/get_pointing_accuracy.py @@ -1,6 +1,8 @@ from pylab import * -import math, sys, numpy as np +import math +import sys +import numpy as np import astropy.coordinates as coord from astropy.coordinates import SkyCoord from astropy import wcs, units as u @@ -14,8 +16,9 @@ def transRaDec2D(ra, dec): z1 = np.sin(dec / 57.2957795) return np.array([x1, y1, z1]) + def ecl2radec(lon_ecl, lat_ecl): - ## convert from ecliptic coordinates to equatorial coordinates + # convert from ecliptic coordinates to equatorial coordinates c_ecl = SkyCoord( lon=lon_ecl * u.degree, lat=lat_ecl * u.degree, frame="barycentrictrueecliptic" ) @@ -25,25 +28,26 @@ def ecl2radec(lon_ecl, lat_ecl): def radec2ecl(ra, dec): - ## convert from equatorial coordinates to ecliptic coordinates + # convert from equatorial coordinates to ecliptic coordinates c_eq = SkyCoord(ra=ra * u.degree, dec=dec * u.degree, frame="icrs") c_ecl = c_eq.transform_to("barycentrictrueecliptic") lon_ecl, lat_ecl = c_ecl.lon.degree, c_ecl.lat.degree return lon_ecl, lat_ecl -def cal_FoVcenter_1P_equatorial(ra_FieldCenter, dec_FieldCenter, chipID = 1, pa = -23.5): - ### [ra_FieldCenter, dec_FieldCenter] is the center ra, dec of calibration fileds, such as: NEP, NGC 6397, etc. - ### [ra_ChipCenter, dec_ChipCenter] is the center ra, dec of the Chip center. - ### [ra_PointCenter, dec_PointCenter] is the telescope pointing center. - ## Calculate PA angle +def cal_FoVcenter_1P_equatorial(ra_FieldCenter, dec_FieldCenter, chipID=1, pa=-23.5): + + # [ra_FieldCenter, dec_FieldCenter] is the center ra, dec of calibration fileds, such as: NEP, NGC 6397, etc. + # [ra_ChipCenter, dec_ChipCenter] is the center ra, dec of the Chip center. + # [ra_PointCenter, dec_PointCenter] is the telescope pointing center. + # Calculate PA angle chip = Chip(chipID) h_ext = ImageHeader.generateExtensionHeader( chip=chip, xlen=chip.npix_x, ylen=chip.npix_y, - ra=(ra_FieldCenter * u.degree).value, + ra=(ra_FieldCenter * u.degree).value, dec=(dec_FieldCenter * u.degree).value, pa=pa, gain=chip.gain, @@ -54,7 +58,7 @@ def cal_FoVcenter_1P_equatorial(ra_FieldCenter, dec_FieldCenter, chipID = 1, pa pixel_size=chip.pix_size, xcen=chip.x_cen, ycen=chip.y_cen, - ) + ) # assume that the telescope point to the sky center; then abtain the chip center under this situation; then calculate the differenc between the assumed telescope center and chip center; then add this difference to the sky center @@ -75,24 +79,25 @@ def cal_FoVcenter_1P_equatorial(ra_FieldCenter, dec_FieldCenter, chipID = 1, pa return ra_PointCenter, dec_PointCenter, lon_ecl_PointCenter, lat_ecl_PointCenter -def cal_FoVcenter_1P_ecliptic(lon_ecl_FieldCenter, lat_ecl_FieldCenter, chipID = 1, pa = -23.5): - ### [ra_FieldCenter, dec_FieldCenter] is the center ra, dec of calibration fileds, such as: NEP, NGC 6397, etc. - ### [ra_ChipCenter, dec_ChipCenter] is the center ra, dec of the Chip center. - ### [ra_PointCenter, dec_PointCenter] is the telescope pointing center. +def cal_FoVcenter_1P_ecliptic(lon_ecl_FieldCenter, lat_ecl_FieldCenter, chipID=1, pa=-23.5): + + # [ra_FieldCenter, dec_FieldCenter] is the center ra, dec of calibration fileds, such as: NEP, NGC 6397, etc. + # [ra_ChipCenter, dec_ChipCenter] is the center ra, dec of the Chip center. + # [ra_PointCenter, dec_PointCenter] is the telescope pointing center. ra_FieldCenter, dec_FieldCenter = ecl2radec( lon_ecl_FieldCenter, lat_ecl_FieldCenter ) - ## Calculate PA angle + # Calculate PA angle chip = Chip(chipID) h_ext = ImageHeader.generateExtensionHeader( chip=chip, xlen=chip.npix_x, ylen=chip.npix_y, - ra=(ra_FieldCenter * u.degree).value, + ra=(ra_FieldCenter * u.degree).value, dec=(dec_FieldCenter * u.degree).value, pa=pa, gain=chip.gain, @@ -103,7 +108,7 @@ def cal_FoVcenter_1P_ecliptic(lon_ecl_FieldCenter, lat_ecl_FieldCenter, chipID = pixel_size=chip.pix_size, xcen=chip.x_cen, ycen=chip.y_cen, - ) + ) # assume that the telescope point to the sky center; then abtain the chip center under this situation; then calculate the differenc between the assumed telescope center and chip center; then add this difference to the sky center @@ -124,14 +129,15 @@ def cal_FoVcenter_1P_ecliptic(lon_ecl_FieldCenter, lat_ecl_FieldCenter, chipID = return ra_PointCenter, dec_PointCenter, lon_ecl_PointCenter, lat_ecl_PointCenter -def getChipCenterRaDec(chipID = 1, p_ra = 60., p_dec = -40.): + +def getChipCenterRaDec(chipID=1, p_ra=60., p_dec=-40.): chip = Chip(chipID) h_ext = ImageHeader.generateExtensionHeader( chip=chip, xlen=chip.npix_x, ylen=chip.npix_y, - ra=(p_ra * u.degree).value, + ra=(p_ra * u.degree).value, dec=(p_dec * u.degree).value, pa=pa, gain=chip.gain, @@ -142,24 +148,25 @@ def getChipCenterRaDec(chipID = 1, p_ra = 60., p_dec = -40.): pixel_size=chip.pix_size, xcen=chip.x_cen, ycen=chip.y_cen, - ) + ) wcs_h = wcs.WCS(h_ext) pixs = np.array([[4608, 4616]]) world_point = wcs_h.wcs_pix2world(pixs, 0) RA_chip, Dec_chip = world_point[0][0], world_point[0][1] return RA_chip, Dec_chip + if __name__ == '__main__': ra_input, dec_input = 270.00000, 66.56000 # NEP pa = 23.5 # chipid = 2 - for chipid in np.arange(1,31,1): + for chipid in np.arange(1, 31, 1): ra, dec, lon_ecl, lat_ecl = cal_FoVcenter_1P_equatorial( - ra_input, dec_input,chipID=chipid, pa=pa) + ra_input, dec_input, chipID=chipid, pa=pa) - print("chip id is %d, chip center [ra,dec] is [%f, %f], pointing center calculated [ra,dec] is [%f, %f]"%(chipid, ra_input, dec_input, ra, dec)) - #for check the result + print("chip id is %d, chip center [ra,dec] is [%f, %f], pointing center calculated [ra,dec] is [%f, %f]" % ( + chipid, ra_input, dec_input, ra, dec)) + # for check the result # testRA, testDec = getChipCenterRaDec(chipID = chipid, p_ra = ra, p_dec = dec) # print(ra_input-testRA, dec_input-testDec) - -- GitLab From 2166c80ee183c5ec7a75fadf420db8990dbca15d Mon Sep 17 00:00:00 2001 From: Zhang Xin Date: Sat, 26 Oct 2024 12:07:29 +0800 Subject: [PATCH 25/64] pep8 --- observation_sim/mock_objects/Galaxy.py | 32 ++++++---- observation_sim/mock_objects/MockObject.py | 71 ++++++++++++---------- observation_sim/psf/PSFInterpSLS.py | 4 +- tools/get_pointing.py | 2 +- 4 files changed, 62 insertions(+), 47 deletions(-) diff --git a/observation_sim/mock_objects/Galaxy.py b/observation_sim/mock_objects/Galaxy.py index 8dc9772..5d6cf74 100755 --- a/observation_sim/mock_objects/Galaxy.py +++ b/observation_sim/mock_objects/Galaxy.py @@ -325,23 +325,25 @@ class Galaxy(MockObject): galImg_List = [] try: - pos_img_local = [0,0] + pos_img_local = [0, 0] x_start = chip.x_cen/chip.pix_size - chip.npix_x / 2. y_start = chip.y_cen/chip.pix_size - chip.npix_y / 2. pos_img_local[0] = pos_img.x - x_start pos_img_local[1] = pos_img.y - y_start nnx = 0 nny = 0 - for order in ["A","B"]: + for order in ["A", "B"]: psf, pos_shear = psf_model.get_PSF( chip, pos_img_local=pos_img_local, bandNo=i+1, galsimGSObject=True, g_order=order, grating_split_pos=grating_split_pos) star_p = galsim.Convolve(psf, gal) if nnx == 0: - galImg = star_p.drawImage(wcs=chip_wcs_local, offset=offset) + galImg = star_p.drawImage( + wcs=chip_wcs_local, offset=offset) nnx = galImg.xmax - galImg.xmin + 1 nny = galImg.ymax - galImg.ymin + 1 else: - galImg = star_p.drawImage(nx = nnx, ny = nny, wcs=chip_wcs_local, offset=offset) + galImg = star_p.drawImage( + nx=nnx, ny=nny, wcs=chip_wcs_local, offset=offset) galImg.setOrigin(0, 0) # n1 = np.sum(np.isinf(galImg.array)) # n2 = np.sum(np.isnan(galImg.array)) @@ -351,7 +353,7 @@ class Galaxy(MockObject): # ERROR happens return 2, pos_shear galImg_List.append(galImg) - for order in ["C","D","E"]: + for order in ["C", "D", "E"]: galImg_List.append(galImg) except: psf, pos_shear = psf_model.get_PSF(chip=chip, pos_img=pos_img) @@ -361,7 +363,7 @@ class Galaxy(MockObject): if np.sum(np.isnan(galImg.array)) > 0: # ERROR happens return 2, pos_shear - for order in ["A","B","C","D","E"]: + for order in ["A", "B", "C", "D", "E"]: galImg_List.append(galImg) # starImg = gal.drawImage( @@ -378,7 +380,7 @@ class Galaxy(MockObject): subSlitPos = int(grating_split_pos_chip - gal_origin[1]) # part img disperse - star_p1s=[] + star_p1s = [] for galImg in galImg_List: subImg_p1 = galImg.array[:, 0:subSlitPos] @@ -397,17 +399,18 @@ class Galaxy(MockObject): isAlongY=0, flat_cube=flat_cube) - self.addSLStoChipImage(sdp=sdp_p1, chip=chip, xOrderSigPlus = xOrderSigPlus, local_wcs=chip_wcs_local) + self.addSLStoChipImage( + sdp=sdp_p1, chip=chip, xOrderSigPlus=xOrderSigPlus, local_wcs=chip_wcs_local) # pos_shear = self.addSLStoChipImageWithPSF(sdp=sdp_p1, chip=chip, pos_img_local=[xcenter_p1, ycenter_p1], # psf_model=psf_model, bandNo=i + 1, # grating_split_pos=grating_split_pos, # local_wcs=chip_wcs_local, pos_img=pos_img) - star_p2s=[] + star_p2s = [] for galImg in galImg_List: subImg_p2 = galImg.array[:, - subSlitPos:galImg.array.shape[1]] + subSlitPos:galImg.array.shape[1]] star_p2 = galsim.Image(subImg_p2) star_p2.setOrigin(0, 0) star_p2s.append(star_p2) @@ -423,7 +426,8 @@ class Galaxy(MockObject): isAlongY=0, flat_cube=flat_cube) - self.addSLStoChipImage(sdp=sdp_p2, chip=chip, xOrderSigPlus = xOrderSigPlus, local_wcs=chip_wcs_local) + self.addSLStoChipImage( + sdp=sdp_p2, chip=chip, xOrderSigPlus=xOrderSigPlus, local_wcs=chip_wcs_local) # pos_shear = self.addSLStoChipImageWithPSF(sdp=sdp_p2, chip=chip, pos_img_local=[xcenter_p2, ycenter_p2], # psf_model=psf_model, bandNo=i + 1, # grating_split_pos=grating_split_pos, @@ -439,7 +443,8 @@ class Galaxy(MockObject): conf=chip.sls_conf[1], isAlongY=0, flat_cube=flat_cube) - self.addSLStoChipImage(sdp=sdp, chip=chip, xOrderSigPlus = xOrderSigPlus, local_wcs=chip_wcs_local) + self.addSLStoChipImage( + sdp=sdp, chip=chip, xOrderSigPlus=xOrderSigPlus, local_wcs=chip_wcs_local) # pos_shear = self.addSLStoChipImageWithPSF(sdp=sdp, chip=chip, pos_img_local=[x_nominal, y_nominal], # psf_model=psf_model, bandNo=i + 1, # grating_split_pos=grating_split_pos, @@ -453,7 +458,8 @@ class Galaxy(MockObject): conf=chip.sls_conf[0], isAlongY=0, flat_cube=flat_cube) - self.addSLStoChipImage(sdp=sdp, chip=chip, xOrderSigPlus = xOrderSigPlus, local_wcs=chip_wcs_local) + self.addSLStoChipImage( + sdp=sdp, chip=chip, xOrderSigPlus=xOrderSigPlus, local_wcs=chip_wcs_local) # pos_shear = self.addSLStoChipImageWithPSF(sdp=sdp, chip=chip, pos_img_local=[x_nominal, y_nominal], # psf_model=psf_model, bandNo=i + 1, # grating_split_pos=grating_split_pos, diff --git a/observation_sim/mock_objects/MockObject.py b/observation_sim/mock_objects/MockObject.py index 443df4f..813a0b2 100755 --- a/observation_sim/mock_objects/MockObject.py +++ b/observation_sim/mock_objects/MockObject.py @@ -235,14 +235,14 @@ class MockObject(object): if chip.slsPSFOptim: for k, v in spec_orders.items(): img_s = v[0] - + nan_ids = np.isnan(img_s) if img_s[nan_ids].shape[0] > 0: img_s[nan_ids] = 0 print("DEBUG: specImg nan num is", img_s[nan_ids].shape[0]) ######################################################### # img_s, orig_off = convolveImg(img_s, psf_img_m) - orig_off = [0,0] + orig_off = [0, 0] origin_order_x = v[1] - orig_off[0] origin_order_y = v[2] - orig_off[1] @@ -257,15 +257,18 @@ class MockObject(object): continue # orders = {'A': 'order1', 'B': 'order0', 'C': 'order2', 'D': 'order-1', 'E': 'order-2'} - orders = {'A': 'order1', 'B': 'order0', 'C': 'order0', 'D': 'order0', 'E': 'order0'} + orders = {'A': 'order1', 'B': 'order0', + 'C': 'order0', 'D': 'order0', 'E': 'order0'} gratingN = chip_utils.getChipSLSGratingID(chip.chipID)[1] if pos_img_local[0] < grating_split_pos: gratingN = chip_utils.getChipSLSGratingID(chip.chipID)[0] - - chip.img_stack[gratingN][orders[k]]['w' + str(bandNo)].setOrigin(0, 0) - chip.img_stack[gratingN][orders[k]]['w' + str(bandNo)][bounds] = chip.img_stack[gratingN][orders[k]]['w' + str(bandNo)][bounds] + specImg[bounds] - chip.img_stack[gratingN][orders[k]]['w' + str(bandNo)].setOrigin(chip.bound.xmin, chip.bound.ymin) + chip.img_stack[gratingN][orders[k] + ]['w' + str(bandNo)].setOrigin(0, 0) + chip.img_stack[gratingN][orders[k]]['w' + str( + bandNo)][bounds] = chip.img_stack[gratingN][orders[k]]['w' + str(bandNo)][bounds] + specImg[bounds] + chip.img_stack[gratingN][orders[k]]['w' + + str(bandNo)].setOrigin(chip.bound.xmin, chip.bound.ymin) else: for k, v in spec_orders.items(): @@ -313,11 +316,11 @@ class MockObject(object): # specImg.wcs = local_wcs # specImg.setOrigin(origin_order_x, origin_order_y) - + # print('DEBUG: BEGIN -----------',bandNo,k) - + img_s = v[0] - + nan_ids = np.isnan(img_s) if img_s[nan_ids].shape[0] > 0: img_s[nan_ids] = 0 @@ -330,9 +333,11 @@ class MockObject(object): specImg.wcs = local_wcs specImg.setOrigin(origin_order_x, origin_order_y) try: - specImg = psf_model.get_PSF_AND_convolve_withsubImg(chip, cutImg=specImg, pos_img_local=pos_img_local, bandNo=bandNo, g_order=k, grating_split_pos=grating_split_pos) + specImg = psf_model.get_PSF_AND_convolve_withsubImg( + chip, cutImg=specImg, pos_img_local=pos_img_local, bandNo=bandNo, g_order=k, grating_split_pos=grating_split_pos) except: - psf, pos_shear = psf_model.get_PSF(chip=chip, pos_img=pos_img) + psf, pos_shear = psf_model.get_PSF( + chip=chip, pos_img=pos_img) psf_img = psf.drawImage(nx=100, ny=100, wcs=local_wcs) @@ -425,45 +430,46 @@ class MockObject(object): # star = galsim.DeltaFunction(gsparams=gsp) # star = star.withFlux(tel.pupil_area * exptime) - #psf list :["A","B","C","D","E"] + # psf list :["A","B","C","D","E"] starImg_List = [] try: - pos_img_local = [0,0] + pos_img_local = [0, 0] x_start = chip.x_cen/chip.pix_size - chip.npix_x / 2. y_start = chip.y_cen/chip.pix_size - chip.npix_y / 2. pos_img_local[0] = pos_img.x - x_start pos_img_local[1] = pos_img.y - y_start nnx = 0 nny = 0 - for order in ["A","B"]: + for order in ["A", "B"]: psf, pos_shear = psf_model.get_PSF( chip, pos_img_local=pos_img_local, bandNo=i+1, galsimGSObject=True, g_order=order, grating_split_pos=grating_split_pos) # star_p = galsim.Convolve(psf, star) - star_p = psf.withFlux(tel.pupil_area * exptime) + star_p = psf.withFlux(tel.pupil_area * exptime) if nnx == 0: - starImg = star_p.drawImage(wcs=chip_wcs_local, offset=offset) + starImg = star_p.drawImage( + wcs=chip_wcs_local, offset=offset) nnx = starImg.xmax - starImg.xmin + 1 nny = starImg.ymax - starImg.ymin + 1 else: - starImg = star_p.drawImage(nx = nnx, ny = nny, wcs=chip_wcs_local, offset=offset) + starImg = star_p.drawImage( + nx=nnx, ny=nny, wcs=chip_wcs_local, offset=offset) # n1 = np.sum(np.isinf(starImg.array)) # n2 = np.sum(np.isnan(starImg.array)) # if n1>0 or n2 > 0: # print("DEBUG: MockObject, inf:%d, nan:%d"%(n1, n2)) starImg.setOrigin(0, 0) starImg_List.append(starImg) - for order in ["C","D","E"]: + for order in ["C", "D", "E"]: starImg_List.append(starImg) except: psf, pos_shear = psf_model.get_PSF(chip=chip, pos_img=pos_img) # star_p = galsim.Convolve(psf, star) - star_p = psf.withFlux(tel.pupil_area * exptime) + star_p = psf.withFlux(tel.pupil_area * exptime) starImg = star_p.drawImage(wcs=chip_wcs_local, offset=offset) starImg.setOrigin(0, 0) - for order in ["A","B","C","D","E"]: + for order in ["A", "B", "C", "D", "E"]: starImg_List.append(starImg) - # psf_tmp = galsim.Gaussian(sigma=0.002) # star = galsim.Convolve(psf_tmp, star) @@ -472,14 +478,14 @@ class MockObject(object): origin_star = [y_nominal - (starImg.center.y - starImg.ymin), x_nominal - (starImg.center.x - starImg.xmin)] - + gal_origin = [origin_star[0], origin_star[1]] gal_end = [origin_star[0] + starImg.array.shape[0] - 1, origin_star[1] + starImg.array.shape[1] - 1] if gal_origin[1] < grating_split_pos_chip < gal_end[1]: subSlitPos = int(grating_split_pos_chip - gal_origin[1]) # part img disperse - star_p1s=[] + star_p1s = [] for starImg in starImg_List: subImg_p1 = starImg.array[:, 0:subSlitPos] @@ -498,17 +504,17 @@ class MockObject(object): isAlongY=0, flat_cube=flat_cube) - self.addSLStoChipImage(sdp=sdp_p1, chip=chip, xOrderSigPlus=xOrderSigPlus, local_wcs=chip_wcs_local) + self.addSLStoChipImage( + sdp=sdp_p1, chip=chip, xOrderSigPlus=xOrderSigPlus, local_wcs=chip_wcs_local) # pos_shear = self.addSLStoChipImageWithPSF(sdp=sdp_p1, chip=chip, pos_img_local=[xcenter_p1, ycenter_p1], # psf_model=psf_model, bandNo=i+1, grating_split_pos=grating_split_pos, # local_wcs=chip_wcs_local, pos_img=pos_img) - - star_p2s=[] + star_p2s = [] for starImg in starImg_List: subImg_p2 = starImg.array[:, - subSlitPos:starImg.array.shape[1]] + subSlitPos:starImg.array.shape[1]] star_p2 = galsim.Image(subImg_p2) star_p2.setOrigin(0, 0) star_p2s.append(star_p2) @@ -524,7 +530,8 @@ class MockObject(object): isAlongY=0, flat_cube=flat_cube) - self.addSLStoChipImage(sdp=sdp_p2, chip=chip, xOrderSigPlus=xOrderSigPlus, local_wcs=chip_wcs_local) + self.addSLStoChipImage( + sdp=sdp_p2, chip=chip, xOrderSigPlus=xOrderSigPlus, local_wcs=chip_wcs_local) # pos_shear = self.addSLStoChipImageWithPSF(sdp=sdp_p2, chip=chip, pos_img_local=[xcenter_p2, ycenter_p2], # psf_model=psf_model, bandNo=i + 1, grating_split_pos=grating_split_pos, # local_wcs=chip_wcs_local, pos_img=pos_img) @@ -539,7 +546,8 @@ class MockObject(object): conf=chip.sls_conf[1], isAlongY=0, flat_cube=flat_cube) - self.addSLStoChipImage(sdp=sdp, chip=chip, xOrderSigPlus=xOrderSigPlus, local_wcs=chip_wcs_local) + self.addSLStoChipImage( + sdp=sdp, chip=chip, xOrderSigPlus=xOrderSigPlus, local_wcs=chip_wcs_local) # pos_shear = self.addSLStoChipImageWithPSF(sdp=sdp, chip=chip, pos_img_local=[x_nominal, y_nominal], # psf_model=psf_model, bandNo=i + 1, grating_split_pos=grating_split_pos, # local_wcs=chip_wcs_local, pos_img=pos_img) @@ -552,7 +560,8 @@ class MockObject(object): conf=chip.sls_conf[0], isAlongY=0, flat_cube=flat_cube) - self.addSLStoChipImage(sdp=sdp, chip=chip, xOrderSigPlus=xOrderSigPlus, local_wcs=chip_wcs_local) + self.addSLStoChipImage( + sdp=sdp, chip=chip, xOrderSigPlus=xOrderSigPlus, local_wcs=chip_wcs_local) # pos_shear = self.addSLStoChipImageWithPSF(sdp=sdp, chip=chip, pos_img_local=[x_nominal, y_nominal], # psf_model=psf_model, bandNo=i + 1, grating_split_pos=grating_split_pos, # local_wcs=chip_wcs_local, pos_img=pos_img) diff --git a/observation_sim/psf/PSFInterpSLS.py b/observation_sim/psf/PSFInterpSLS.py index 50521b8..1d1f4b5 100644 --- a/observation_sim/psf/PSFInterpSLS.py +++ b/observation_sim/psf/PSFInterpSLS.py @@ -30,7 +30,7 @@ NPSF = 900 # ***# 30*30 PIX_SIZE_MICRON = 5. # ***# in microns -### find neighbors-KDtree### +# find neighbors-KDtree # def findNeighbors(tx, ty, px, py, dr=0.1, dn=1, OnlyDistance=True): # """ # find nearest neighbors by 2D-KDTree @@ -212,7 +212,7 @@ PIX_SIZE_MICRON = 5. # ***# in microns # return psfMaker -### define PSFInterp### +# define PSFInterp class PSFInterpSLS(PSFModel): def __init__(self, chip, filt, PSF_data_prefix="", sigSpin=0, psfRa=0.15, pix_size=0.005): if LOG_DEBUG: diff --git a/tools/get_pointing.py b/tools/get_pointing.py index d5c1d17..3131dc8 100755 --- a/tools/get_pointing.py +++ b/tools/get_pointing.py @@ -60,7 +60,7 @@ class Chip(object): if logger is not None: logger.info( " Construct the wcs of the entire image mosaic using Gnomonic/TAN projection") - if (xcen == None) or (ycen == None): + if (xcen is None) or (ycen is None): xcen = self.cen_pix_x ycen = self.cen_pix_y if pix_scale == None: -- GitLab From dc74ba7f4f07025797fe6a817201aba389a5e667 Mon Sep 17 00:00:00 2001 From: Zhang Xin Date: Sat, 26 Oct 2024 12:14:57 +0800 Subject: [PATCH 26/64] pep8 --- observation_sim/astrometry/Astrometry_util.py | 4 ++-- observation_sim/mock_objects/Galaxy.py | 6 +++--- observation_sim/mock_objects/MockObject.py | 6 +++--- observation_sim/mock_objects/SpecDisperser/__init__.py | 2 +- tools/get_pointing.py | 2 +- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/observation_sim/astrometry/Astrometry_util.py b/observation_sim/astrometry/Astrometry_util.py index dba4466..bdfe613 100644 --- a/observation_sim/astrometry/Astrometry_util.py +++ b/observation_sim/astrometry/Astrometry_util.py @@ -12,8 +12,8 @@ def checkInputList(input_list, n): if not isinstance(input_list, list): raise TypeError("Input type is not list!", input_list) for i in input_list: - if type(i) != type(1.1): - if type(i) != type(1): + if type(i) is not type(1.1): + if type(i) is not type(1): raise TypeError( "Input list's element is not float or int!", input_list) if len(input_list) != n: diff --git a/observation_sim/mock_objects/Galaxy.py b/observation_sim/mock_objects/Galaxy.py index 5d6cf74..03df3eb 100755 --- a/observation_sim/mock_objects/Galaxy.py +++ b/observation_sim/mock_objects/Galaxy.py @@ -33,7 +33,7 @@ class Galaxy(MockObject): raise ValueError( "!!!The number of PSF profiles and the number of bandpasses must be equal.") objs = [] - if nphotons_tot == None: + if nphotons_tot is None: nphotons_tot = self.getElectronFluxFilt(filt, tel, exptime) # print("nphotons_tot = ", nphotons_tot) @@ -92,7 +92,7 @@ class Galaxy(MockObject): return final def drawObj_multiband(self, tel, pos_img, psf_model, bandpass_list, filt, chip, nphotons_tot=None, g1=0, g2=0, exptime=150., fd_shear=None): - if nphotons_tot == None: + if nphotons_tot is None: nphotons_tot = self.getElectronFluxFilt(filt, tel, exptime) # print("nphotons_tot = ", nphotons_tot) @@ -471,7 +471,7 @@ class Galaxy(MockObject): return 1, pos_shear def getGSObj(self, psf, g1=0, g2=0, flux=None, filt=None, tel=None, exptime=150.): - if flux == None: + if flux is None: flux = self.getElectronFluxFilt(filt, tel, exptime) disk = galsim.Sersic(n=self.disk_sersic_idx, half_light_radius=self.hlr_disk, flux=1.0) diff --git a/observation_sim/mock_objects/MockObject.py b/observation_sim/mock_objects/MockObject.py index 813a0b2..38608fa 100755 --- a/observation_sim/mock_objects/MockObject.py +++ b/observation_sim/mock_objects/MockObject.py @@ -108,7 +108,7 @@ class MockObject(object): def drawObj_multiband(self, tel, pos_img, psf_model, bandpass_list, filt, chip, nphotons_tot=None, g1=0, g2=0, exptime=150., fd_shear=None): - if nphotons_tot == None: + if nphotons_tot is None: nphotons_tot = self.getElectronFluxFilt(filt, tel, exptime) # print("nphotons_tot = ", nphotons_tot) @@ -581,7 +581,7 @@ class MockObject(object): def drawObj_PSF(self, tel, pos_img, psf_model, bandpass_list, filt, chip, nphotons_tot=None, g1=0, g2=0, exptime=150., fd_shear=None, chip_output=None): - if nphotons_tot == None: + if nphotons_tot is None: nphotons_tot = self.getElectronFluxFilt(filt, tel, exptime) # print("nphotons_tot = ", nphotons_tot) @@ -650,7 +650,7 @@ class MockObject(object): os.makedirs(fn, exist_ok=True) fn = fn + "/ccd_{:}".format(chip.chipID) + \ "_psf_"+str(self.param['id'])+".fits" - if fn != None: + if fn is not None: if os.path.exists(fn): os.remove(fn) hdu = fitsio.PrimaryHDU() diff --git a/observation_sim/mock_objects/SpecDisperser/__init__.py b/observation_sim/mock_objects/SpecDisperser/__init__.py index c5d9a48..6165f8d 100644 --- a/observation_sim/mock_objects/SpecDisperser/__init__.py +++ b/observation_sim/mock_objects/SpecDisperser/__init__.py @@ -1,2 +1,2 @@ from .SpecDisperser import * -from .disperse_c import disperse, interp \ No newline at end of file +from .disperse_c import disperse, interp diff --git a/tools/get_pointing.py b/tools/get_pointing.py index 3131dc8..057fac6 100755 --- a/tools/get_pointing.py +++ b/tools/get_pointing.py @@ -63,7 +63,7 @@ class Chip(object): if (xcen is None) or (ycen is None): xcen = self.cen_pix_x ycen = self.cen_pix_y - if pix_scale == None: + if pix_scale is None: pix_scale = self.pix_scale # dudx = -np.cos(img_rot.rad) * pix_scale # dudy = -np.sin(img_rot.rad) * pix_scale -- GitLab From 4d79505a2d5830e276b8b0210edb7ebb5047a7ea Mon Sep 17 00:00:00 2001 From: Zhang Xin Date: Sat, 26 Oct 2024 12:18:41 +0800 Subject: [PATCH 27/64] pep8 --- .../SpecDisperser/SpecDisperser.py | 42 +++++++++---------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/observation_sim/mock_objects/SpecDisperser/SpecDisperser.py b/observation_sim/mock_objects/SpecDisperser/SpecDisperser.py index a6073a7..7f1626e 100644 --- a/observation_sim/mock_objects/SpecDisperser/SpecDisperser.py +++ b/observation_sim/mock_objects/SpecDisperser/SpecDisperser.py @@ -495,36 +495,36 @@ class aXeConf: return a def evaluate_dp(self, dx, dydx): - """Evalate arc length along the trace given trace polynomial coefficients + # """Evalate arc length along the trace given trace polynomial coefficients - Parameters - ---------- - dx : array-like - x pixel to evaluate + # Parameters + # ---------- + # dx : array-like + # x pixel to evaluate - dydx : array-like - Coefficients of the trace polynomial + # dydx : array-like + # Coefficients of the trace polynomial - Returns - ------- - dp : array-like - Arc length along the trace at position `dx`. + # Returns + # ------- + # dp : array-like + # Arc length along the trace at position `dx`. - For `dydx` polynomial orders 0, 1 or 2, integrate analytically. - Higher orders must be integrated numerically. + # For `dydx` polynomial orders 0, 1 or 2, integrate analytically. + # Higher orders must be integrated numerically. - **Constant:** - .. math:: dp = dx + # **Constant:** + # .. math:: dp = dx - **Linear:** - .. math:: dp = \sqrt{1+\mathrm{DYDX}[1]}\cdot dx + # **Linear:** + # .. math:: dp = \sqrt{1+\mathrm{DYDX}[1]}\cdot dx - **Quadratic:** - .. math:: u = \mathrm{DYDX}[1] + 2\ \mathrm{DYDX}[2]\cdot dx + # **Quadratic:** + # .. math:: u = \mathrm{DYDX}[1] + 2\ \mathrm{DYDX}[2]\cdot dx - .. math:: dp = (u \sqrt{1+u^2} + \mathrm{arcsinh}\ u) / (4\cdot \mathrm{DYDX}[2]) + # .. math:: dp = (u \sqrt{1+u^2} + \mathrm{arcsinh}\ u) / (4\cdot \mathrm{DYDX}[2]) - """ + # """ # dp is the arc length along the trace # $\lambda = dldp_0 + dldp_1 dp + dldp_2 dp^2$ ... -- GitLab From 50e37e55c79004236e6f42963f3fb210ab2e5776 Mon Sep 17 00:00:00 2001 From: Chengliang Date: Sat, 26 Oct 2024 13:48:31 +0800 Subject: [PATCH 28/64] typo fix --- observation_sim/mock_objects/SpecDisperser/SpecDisperser.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/observation_sim/mock_objects/SpecDisperser/SpecDisperser.py b/observation_sim/mock_objects/SpecDisperser/SpecDisperser.py index 7f1626e..fb65af3 100644 --- a/observation_sim/mock_objects/SpecDisperser/SpecDisperser.py +++ b/observation_sim/mock_objects/SpecDisperser/SpecDisperser.py @@ -336,7 +336,7 @@ class SpecDisperser(object): orders = {"A": "1st", "B": "0st", "C": "2st", "D": "-1st", "E": "-2st"} sens_file_name = conffile[0:-5] + \ "_sensitivity_" + orders[beam] + ".fits" - if os.path.exists(sens_file_name) if False: + if os.path.exists(sens_file_name) is False: senstivity_out = Table( array([w, sens]).T, names=("WAVELENGTH", "SENSITIVITY")) senstivity_out.write(sens_file_name, format="fits") -- GitLab From 1a887d442ade107cf1297beb4c8f531c85a3d6e0 Mon Sep 17 00:00:00 2001 From: Chengliang Date: Mon, 28 Oct 2024 11:04:53 +0800 Subject: [PATCH 29/64] update module-crosstalk --- observation_sim/sim_steps/readout_output.py | 4 +- tests/test_crosstalk.py | 100 ++++++++++++++++++++ 2 files changed, 102 insertions(+), 2 deletions(-) create mode 100644 tests/test_crosstalk.py diff --git a/observation_sim/sim_steps/readout_output.py b/observation_sim/sim_steps/readout_output.py index c936669..f21461d 100644 --- a/observation_sim/sim_steps/readout_output.py +++ b/observation_sim/sim_steps/readout_output.py @@ -44,7 +44,7 @@ def add_crosstalk(self, chip, filt, tel, pointing, catalog, obs_param): crosstalk[15, :] = np.array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 1e-4, 1.]) # 2*8 -> 1*16 - img = formatOutput(chip.img) + img = chip_utils.formatOutput(chip.img) ny, nx = img.array.shape nsecy = 1 nsecx = 16 @@ -57,7 +57,7 @@ def add_crosstalk(self, chip, filt, tel, pointing, catalog, obs_param): newimg.array[:, int(i*dx):int(i*dx+dx)] += crosstalk[i, j]*img.array[:, int(j*dx):int(j*dx+dx)] # 1*16 -> 2*8 - newimg = formatRevert(newimg) + newimg = chip_utils.formatRevert(newimg) chip.img.array[:, :] = newimg.array[:, :] return chip, filt, tel, pointing diff --git a/tests/test_crosstalk.py b/tests/test_crosstalk.py new file mode 100644 index 0000000..725b3e0 --- /dev/null +++ b/tests/test_crosstalk.py @@ -0,0 +1,100 @@ +import unittest + +import sys +import os +import math +from itertools import islice +import numpy as np +import copy +import ctypes +import galsim +import yaml +from astropy.io import fits + +from observation_sim.instruments.chip import chip_utils +import matplotlib.pyplot as plt + + +# test FUNCTION --- START # +def add_crosstalk(GSimg): + crosstalk = np.zeros([16, 16]) + crosstalk[0, :] = np.array([1., 1e-4, 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.]) + crosstalk[1, :] = np.array([1e-4, 1., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.]) + crosstalk[2, :] = np.array([0., 0., 1., 1e-4, 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.]) + crosstalk[3, :] = np.array([0., 0., 1e-4, 1., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.]) + crosstalk[4, :] = np.array([0., 0., 0., 0., 1., 1e-4, 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.]) + crosstalk[5, :] = np.array([0., 0., 0., 0., 1e-4, 1., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.]) + crosstalk[6, :] = np.array([0., 0., 0., 0., 0., 0., 1., 1e-4, 0., 0., 0., 0., 0., 0., 0., 0.]) + crosstalk[7, :] = np.array([0., 0., 0., 0., 0., 0., 1e-4, 1., 0., 0., 0., 0., 0., 0., 0., 0.]) + crosstalk[8, :] = np.array([0., 0., 0., 0., 0., 0., 0., 0., 1., 1e-4, 0., 0., 0., 0., 0., 0.]) + crosstalk[9, :] = np.array([0., 0., 0., 0., 0., 0., 0., 0., 1e-4, 1., 0., 0., 0., 0., 0., 0.]) + crosstalk[10, :] = np.array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 1., 1e-4, 0., 0., 0., 0.]) + crosstalk[11, :] = np.array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 1e-4, 1., 0., 0., 0., 0.]) + crosstalk[12, :] = np.array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 1., 1e-4, 0., 0.]) + crosstalk[13, :] = np.array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 1e-4, 1., 0., 0.]) + crosstalk[14, :] = np.array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 1., 1e-4]) + crosstalk[15, :] = np.array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 1e-4, 1.]) + + # 2*8 -> 1*16 + img = chip_utils.formatOutput(GSimg) + ny, nx = img.array.shape + nsecy = 1 + nsecx = 16 + dy = int(ny/nsecy) + dx = int(nx/nsecx) + + newimg = galsim.Image(nx, ny, init_value=0) + for i in range(16): + for j in range(16): + newimg.array[:, int(i*dx):int(i*dx+dx)] += crosstalk[i, j]*img.array[:, int(j*dx):int(j*dx+dx)] + + # 1*16 -> 2*8 + newimg = chip_utils.formatRevert(newimg) + + return newimg +# test FUNCTION --- END # + + +class detModule_coverage(unittest.TestCase): + def __init__(self, methodName='runTest'): + super(detModule_coverage, self).__init__(methodName) + self.dataPath = os.path.join( + os.getenv('UNIT_TEST_DATA_ROOT'), 'csst_msc_sim/csst_fz_msc') + + def test_add_crosstalk(self): + nsecy = 2 + nsecx = 8 + ny, nx = 1024,1024 + dy = int(ny/nsecy) + dx = int(nx/nsecx) + mapclip = np.zeros([dy, int(nsecx*nsecy*dx)]) + for i in range(int(nsecx*nsecy)): + mapclip[:, i*dx:dx+i*dx] = np.random.randint(10)+np.random.rand(int(dy*dx)).reshape([dy, dx]) + mapclip = galsim.ImageF(mapclip) + + nsecy = 1 + nsecx = 16 + ny,nx = mapclip.array.shape + dy = int(ny/nsecy) + dx = int(nx/nsecx) + for i in range(int(nsecy*nsecx)): + gal = galsim.Gaussian(sigma=0.2, flux=500000).drawImage(nx=32, ny=32).array + py = np.random.randint(450)+10 + mapclip.array[py:py+32, int(i*dx)+10:int(i*dx)+42] += gal + + tmap = chip_utils.formatRevert(mapclip, nsecy=1, nsecx=16) # 1*16 -> 2*8 + temp = add_crosstalk(tmap) + + fig = plt.figure(figsize=(20,60)) + ax = plt.subplot(311) + plt.imshow(np.log10(mapclip.array+1), origin='lower', cmap='gray') + ax = plt.subplot(312) + plt.imshow(np.log10(temp.array+1), origin='lower', cmap='gray') + ax = plt.subplot(313) + plt.imshow(np.log10(temp.array-tmap.array+1), origin='lower', cmap='gray') + plt.savefig(os.path.join(self.dataPath, "./test_crosstalk.png"), dpi=300, bbox_inches='tight') + self.assertTrue(True) + + +if __name__ == '__main__': + unittest.main() -- GitLab From 2eb4e6b517f109742ca5baa1133bce7ca2759d47 Mon Sep 17 00:00:00 2001 From: Chengliang Date: Mon, 28 Oct 2024 11:07:51 +0800 Subject: [PATCH 30/64] update codestyle-PEP8 --- tests/test_crosstalk.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/test_crosstalk.py b/tests/test_crosstalk.py index 725b3e0..bafe9fd 100644 --- a/tests/test_crosstalk.py +++ b/tests/test_crosstalk.py @@ -51,7 +51,7 @@ def add_crosstalk(GSimg): # 1*16 -> 2*8 newimg = chip_utils.formatRevert(newimg) - return newimg + return newimg # test FUNCTION --- END # @@ -64,7 +64,7 @@ class detModule_coverage(unittest.TestCase): def test_add_crosstalk(self): nsecy = 2 nsecx = 8 - ny, nx = 1024,1024 + ny, nx = 1024, 1024 dy = int(ny/nsecy) dx = int(nx/nsecx) mapclip = np.zeros([dy, int(nsecx*nsecy*dx)]) @@ -74,18 +74,18 @@ class detModule_coverage(unittest.TestCase): nsecy = 1 nsecx = 16 - ny,nx = mapclip.array.shape + ny, nx = mapclip.array.shape dy = int(ny/nsecy) dx = int(nx/nsecx) for i in range(int(nsecy*nsecx)): gal = galsim.Gaussian(sigma=0.2, flux=500000).drawImage(nx=32, ny=32).array py = np.random.randint(450)+10 mapclip.array[py:py+32, int(i*dx)+10:int(i*dx)+42] += gal - + tmap = chip_utils.formatRevert(mapclip, nsecy=1, nsecx=16) # 1*16 -> 2*8 temp = add_crosstalk(tmap) - fig = plt.figure(figsize=(20,60)) + fig = plt.figure(figsize=(20, 60)) ax = plt.subplot(311) plt.imshow(np.log10(mapclip.array+1), origin='lower', cmap='gray') ax = plt.subplot(312) -- GitLab From f058808a852d849115f8922f8199e702658e7784 Mon Sep 17 00:00:00 2001 From: fangyuedong Date: Sat, 2 Nov 2024 17:11:13 +0800 Subject: [PATCH 31/64] add crosstalk step. add validation for objects parameters --- config/obs_config_SCI.yaml | 2 ++ observation_sim/mock_objects/CatalogBase.py | 16 +++++++------- observation_sim/sim_steps/__init__.py | 5 +++-- observation_sim/sim_steps/add_objects.py | 23 +++++++++++++++++++-- 4 files changed, 34 insertions(+), 12 deletions(-) diff --git a/config/obs_config_SCI.yaml b/config/obs_config_SCI.yaml index ef82bcd..fecdf01 100644 --- a/config/obs_config_SCI.yaml +++ b/config/obs_config_SCI.yaml @@ -74,6 +74,8 @@ call_sequence: # Add bias bias: bias_16channel: YES + # Add cross-talk + cross_talk: {} # Add readout noise readout_noise: {} # Apply gain diff --git a/observation_sim/mock_objects/CatalogBase.py b/observation_sim/mock_objects/CatalogBase.py index cd1b669..77c9896 100644 --- a/observation_sim/mock_objects/CatalogBase.py +++ b/observation_sim/mock_objects/CatalogBase.py @@ -29,8 +29,8 @@ class CatalogBase(metaclass=ABCMeta): param = { "star": -1, "id": -1, - "ra": 0, - "dec": 0., + "ra": -999., + "dec": -999., "ra_orig": 0., "dec_orig": 0., "z": 0., @@ -44,15 +44,15 @@ class CatalogBase(metaclass=ABCMeta): "bfrac": 0., "av": 0., "redden": 0., - "hlr_bulge": 0., - "hlr_disk": 0., + "hlr_bulge": -999., + "hlr_disk": -999., "ell_bulge": 0., "ell_disk": 0., "ell_tot": 0., - "e1_disk": 0., - "e2_disk": 0., - "e1_bulge": 0., - "e2_bulge": 0., + "e1_disk": -999., + "e2_disk": -999., + "e1_bulge": -999., + "e2_bulge": -999., "teff": 0., "logg": 0., "feh": 0., diff --git a/observation_sim/sim_steps/__init__.py b/observation_sim/sim_steps/__init__.py index e8e2661..7669fe4 100644 --- a/observation_sim/sim_steps/__init__.py +++ b/observation_sim/sim_steps/__init__.py @@ -11,11 +11,11 @@ class SimSteps: from .prepare_headers import prepare_headers, updateHeaderInfo from .add_sky_background import add_sky_background_sci, add_sky_flat_calibration, add_sky_background - from .add_objects import add_objects + from .add_objects import add_objects, _is_obj_valid from .add_cosmic_rays import add_cosmic_rays from .add_pattern_noise import apply_PRNU, add_poisson_and_dark, add_detector_defects, add_nonlinearity, add_blooming, add_bias from .add_brighter_fatter_CTE import add_brighter_fatter, apply_CTE - from .readout_output import add_prescan_overscan, add_readout_noise, apply_gain, quantization_and_output + from .readout_output import add_prescan_overscan, add_readout_noise, apply_gain, quantization_and_output, add_crosstalk from .add_LED_flat import add_LED_Flat @@ -37,4 +37,5 @@ SIM_STEP_TYPES = { "quantization_and_output": "quantization_and_output", "led_calib_model": "add_LED_Flat", "sky_flatField": "add_sky_flat_calibration", + "cross_talk": "add_crosstalk" } diff --git a/observation_sim/sim_steps/add_objects.py b/observation_sim/sim_steps/add_objects.py index bbe8baa..49707d4 100644 --- a/observation_sim/sim_steps/add_objects.py +++ b/observation_sim/sim_steps/add_objects.py @@ -10,6 +10,22 @@ from observation_sim.psf import PSFGauss, FieldDistortion, PSFInterp, PSFInterpS from astropy.time import Time from datetime import datetime, timezone +def _is_obj_valid(self, obj): + if obj.param['star'] == 4: + # Currently there's no parameter checks for 'calib' type + return True + pos_keys = ['ra', 'dec'] + shape_keys = ['hlr_bulge', 'hlr_disk', 'e1_disk', 'e2_disk', 'e1_bulge', 'e2_bulge'] + if any(obj.param[key] == -999. for key in pos_keys): + msg = 'One or more positional information (ra, dec) is missing' + self.chip_output.Log_error(msg) + return False + if obj.param['star'] == 0 and any(obj.param[key] == -999. for key in shape_keys): + msg = 'One or more shape information (hlr_bulge, hlr_disk, e1_disk, e2_disk, e1_bulge, e2_bulge) is missing' + self.chip_output.Log_error(msg) + return False + return True + def add_objects(self, chip, filt, tel, pointing, catalog, obs_param): @@ -85,6 +101,9 @@ def add_objects(self, chip, filt, tel, pointing, catalog, obs_param): # break obj = cat.objs[j] + if not self._is_obj_valid(obj): + continue + # load and convert SED; also caculate object's magnitude in all CSST bands try: sed_data = cat.load_sed(obj) @@ -153,7 +172,7 @@ def add_objects(self, chip, filt, tel, pointing, catalog, obs_param): if pos_img.x == -1 or pos_img.y == -1: self.chip_output.Log_info('obj_ra = %.6f, obj_dec = %.6f, obj_ra_orig = %.6f, obj_dec_orig = %.6f' % ( obj.ra, obj.dec, obj.ra_orig, obj.dec_orig)) - self.chip_output.Log_error("Objected missed: %s" % (obj.id)) + self.chip_output.Log_error("Object missed: %s" % (obj.id)) missed_obj += 1 obj.unload_SED() continue @@ -199,7 +218,7 @@ def add_objects(self, chip, filt, tel, pointing, catalog, obs_param): pass elif isUpdated == 0: missed_obj += 1 - self.chip_output.Log_error("Objected missed: %s" % (obj.id)) + self.chip_output.Log_error("Object missed: %s" % (obj.id)) else: self.chip_output.Log_error( "Draw error, object omitted: %s" % (obj.id)) -- GitLab From 60a424bf4805ed5a2d7b8f4d9365be33aa380b3a Mon Sep 17 00:00:00 2001 From: fangyuedong Date: Sun, 3 Nov 2024 10:57:27 +0800 Subject: [PATCH 32/64] add blank line to meet pep8 standard --- observation_sim/sim_steps/add_objects.py | 1 + 1 file changed, 1 insertion(+) diff --git a/observation_sim/sim_steps/add_objects.py b/observation_sim/sim_steps/add_objects.py index 49707d4..0d89b93 100644 --- a/observation_sim/sim_steps/add_objects.py +++ b/observation_sim/sim_steps/add_objects.py @@ -10,6 +10,7 @@ from observation_sim.psf import PSFGauss, FieldDistortion, PSFInterp, PSFInterpS from astropy.time import Time from datetime import datetime, timezone + def _is_obj_valid(self, obj): if obj.param['star'] == 4: # Currently there's no parameter checks for 'calib' type -- GitLab From 26a0eb7de04da47cb9587f9f39ac3c4dc6307336 Mon Sep 17 00:00:00 2001 From: Chengliang Date: Thu, 14 Nov 2024 18:32:24 +0800 Subject: [PATCH 33/64] reset config.yaml with html --- tools/setConfig/.DS_Store | Bin 0 -> 8196 bytes tools/setConfig/reset_obs.py | 118 ++++++++ tools/setConfig/reset_overall.py | 127 +++++++++ tools/setConfig/templates/config_overall.yaml | 145 ++++++++++ tools/setConfig/templates/index_obs.html | 246 +++++++++++++++++ tools/setConfig/templates/index_overall.html | 258 ++++++++++++++++++ tools/setConfig/templates/obs_config_SCI.yaml | 85 ++++++ 7 files changed, 979 insertions(+) create mode 100644 tools/setConfig/.DS_Store create mode 100644 tools/setConfig/reset_obs.py create mode 100644 tools/setConfig/reset_overall.py create mode 100644 tools/setConfig/templates/config_overall.yaml create mode 100644 tools/setConfig/templates/index_obs.html create mode 100644 tools/setConfig/templates/index_overall.html create mode 100644 tools/setConfig/templates/obs_config_SCI.yaml diff --git a/tools/setConfig/.DS_Store b/tools/setConfig/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..316c88df0f1de73f1e37a841b6e985fdc1b95458 GIT binary patch literal 8196 zcmeHMzi-n(6n@u+)FDL#l}hb^WC_Nqv;|clmXHRCt{A}pG{j9vA{?KU9}QI$lno?y zHY6q{Bqk*i#k*0^qEyi20T$fhr1r%cRlXTXqyv;0mFb{z%XDKFbo_A2Jp-l#Y%bZtE;9p z3>XIfO9sULV516I)N-t(+&a+66aX@V)3TtCJV0V>EsI)?m6TA}RM`X5P^ME1rr@}4 z3w6k%mSZIqoS1?W(<3vTp)ff*aJEz@R#eioh5^ICECV8U&r%hcdqC^4{9T07b=0?C zWs%@K?Gq=T9#M-LKpXckF-*Oy*hPK zd#M)R#a6QzvpBU7T@QN!+y1fQ_Ll z``su)vKpRW0^(l?!-Qo;1F$J*PS6U6-p##Nlh8}l33G5W*9IG{4xV9Q+CQFn3=p4#x06m+eUqeDvHn>D=8sp tWI7Hh({ae@ABO1LP!*V>mSZJx2IY@`2>4rG!xNsu=J_vO#x%cyfp4pI{cr#P literal 0 HcmV?d00001 diff --git a/tools/setConfig/reset_obs.py b/tools/setConfig/reset_obs.py new file mode 100644 index 0000000..c8c7a65 --- /dev/null +++ b/tools/setConfig/reset_obs.py @@ -0,0 +1,118 @@ +from flask import Flask, render_template, request, redirect +import yaml +import ast + +app = Flask(__name__) + + +key_type_map = { + 'obs_type': str, + 'obs_type_code': str, + 'obs_id': str, + 'run_chips': list, + 'call_sequence':{ + 'scie_obs':{ + 'shutter_effect': bool, + 'flat_fielding': bool, + 'field_dist': bool, + }, + 'sky_background':{ + 'shutter_effect': bool, + 'flat_fielding': bool, + 'enable_straylight_model': bool, + 'flat_level': None, + 'flat_level_filt': None, + }, + 'PRNU_effect': {}, + 'cosmic_rays':{ + 'save_cosmic_img': bool, + }, + 'poisson_and_dark':{ + 'add_dark': bool, + }, + 'bright_fatter': {}, + 'detector_defects':{ + 'hot_pixels': bool, + 'dead_pixels': bool, + 'bad_columns': bool, + }, + 'nonlinearity': {}, + 'blooming': {}, + 'prescan_overscan':{ + 'add_dark': bool, + }, + 'bias':{ + 'bias_16channel': bool, + }, + 'readout_noise': {}, + 'gain':{ + 'gain_16channel': bool, + }, + 'quantization_and_output':{ + 'format_output': bool, + }, + }, +} +def convert_dict_values(d, key_type_map): + for key, value in d.items(): + if isinstance(value, dict): + convert_dict_values(value, key_type_map[key]) + elif key in key_type_map: + if key_type_map[key] is int: + d[key] = int(value) + if key_type_map[key] is float: + d[key] = float(value) + if key_type_map[key] is bool: + if d[key].lower() == 'yes' or d[key].lower() == 'true': + d[key] = True + else: + d[key] = False + if key_type_map[key] is str: + d[key] = str(value) + if key_type_map[key] is list: + d[key] = ast.literal_eval(value) + if key_type_map[key] is None: + d[key] = None + + + +def load_yaml(): + with open('templates/obs_config_SCI.yaml', 'r') as file: + return yaml.safe_load(file) + +def save_yaml(data): + convert_dict_values(data, key_type_map) + with open('config_reset/obs_config_SCI_reset.yaml', 'w') as file: + yaml.dump(data, file, default_flow_style=False, sort_keys=False) + +def render_form(data, parent_key=''): + form_html = '' + for key, value in data.items(): + full_key = f"{parent_key}.{key}" if parent_key else key + if isinstance(value, dict): # 处ç†å­—å…¸ + form_html += f"

{key}

{render_form(value, full_key)}
" + else: + form_html += f"" + form_html += f"
" + return form_html + +@app.route('/', methods=['GET', 'POST']) +def index(): + if request.method == 'POST': + data = load_yaml() + for key in request.form: + keys = key.split('.') + temp = data + for k in keys[:-1]: + temp = temp[k] + temp[keys[-1]] = request.form[key] + save_yaml(data) + return redirect('/') + + data = load_yaml() + form_html = render_form(data) + return render_template('index_obs.html', form_html=form_html) + +if __name__ == '__main__': + app.run(debug=True) + diff --git a/tools/setConfig/reset_overall.py b/tools/setConfig/reset_overall.py new file mode 100644 index 0000000..df51b24 --- /dev/null +++ b/tools/setConfig/reset_overall.py @@ -0,0 +1,127 @@ +from flask import Flask, render_template, request, redirect +import yaml +import ast + +app = Flask(__name__) + +key_type_map = { + 'work_dir': str, + 'run_name': str, + 'project_cycle': int, + 'run_counter': int, + 'run_option':{ + 'out_cat_only': bool, + }, + 'catalog_options':{ + 'input_path':{ + 'cat_dir': str, + 'star_cat': str, + 'galaxy_cat': str, + }, + 'SED_templates_path':{ + 'star_SED': str, + 'galaxy_SED': str, + 'AGN_SED': str, + }, + 'star_only': bool, + 'galaxy_only': bool, + 'rotateEll': float, + 'enable_mw_ext_gal': bool, + 'planck_ebv_map':str, + }, + 'obs_setting':{ + 'pointing_file': str, + 'obs_config_file': str, + 'run_pointings': list, + 'enable_astrometric_model': bool, + 'cut_in_band': str, + 'mag_sat_margin': float, + 'mag_lim_margin': float, + }, + 'psf_setting':{ + 'psf_model': str, + 'psf_pho_dir': str, + 'psf_sls_dir': str, + }, + 'shear_setting':{ + 'shear_type': str, + 'reduced_g1': float, + 'reduced_g2': float, + }, + 'output_setting':{ + 'output_format': str, + 'shutter_output': bool, + 'prnu_output': bool, + }, + 'random_seeds':{ + 'seed_poisson': int, + 'seed_CR': int, + 'seed_flat': int, + 'seed_prnu': int, + 'seed_gainNonUniform': int, + 'seed_biasNonUniform': int, + 'seed_rnNonUniform': int, + 'seed_badcolumns': int, + 'seed_defective': int, + 'seed_readout': int, + }, +} +def convert_dict_values(d, key_type_map): + for key, value in d.items(): + if isinstance(value, dict): + convert_dict_values(value, key_type_map[key]) + elif key in key_type_map: + if key_type_map[key] is int: + d[key] = int(value) + if key_type_map[key] is float: + d[key] = float(value) + if key_type_map[key] is bool: + if d[key].lower() == 'yes' or d[key].lower() == 'true': + d[key] = True + else: + d[key] = False + if key_type_map[key] is str: + d[key] = str(value) + if key_type_map[key] is list: + d[key] = ast.literal_eval(value) + +def load_yaml(): + with open('templates/config_overall.yaml', 'r') as file: + return yaml.safe_load(file) + +def save_yaml(data): + convert_dict_values(data, key_type_map) + with open('config_reset/config_overall_reset.yaml', 'w') as file: + yaml.dump(data, file, default_flow_style=False, sort_keys=False) + +def render_form(data, parent_key=''): + form_html = '' + for key, value in data.items(): + full_key = f"{parent_key}.{key}" if parent_key else key + if isinstance(value, dict): # 处ç†å­—å…¸ + form_html += f"

{key}

{render_form(value, full_key)}
" + else: + form_html += f"" + form_html += f"
" + return form_html + +@app.route('/', methods=['GET', 'POST']) +def index(): + if request.method == 'POST': + data = load_yaml() + for key in request.form: + keys = key.split('.') + temp = data + for k in keys[:-1]: + temp = temp[k] + temp[keys[-1]] = request.form[key] + save_yaml(data) + return redirect('/') + + data = load_yaml() + form_html = render_form(data) + return render_template('index_overall.html', form_html=form_html) + +if __name__ == '__main__': + app.run(debug=True) + diff --git a/tools/setConfig/templates/config_overall.yaml b/tools/setConfig/templates/config_overall.yaml new file mode 100644 index 0000000..d22dc68 --- /dev/null +++ b/tools/setConfig/templates/config_overall.yaml @@ -0,0 +1,145 @@ +--- +############################################### +# +# Configuration file for CSST simulation +# Overall settings +# CSST-Sim Group, 2024/01/08 +# +############################################### + +# Base diretories and naming setup +# can add some of the command-line arguments here as well; +# ok to pass either way or both, as long as they are consistent +work_dir: "/public/home/fangyuedong/project/workplace/" +run_name: "ext_on" + +# Project cycle and run counter are used to name the outputs +project_cycle: 9 +run_counter: 1 + +# Run options +run_option: + # Output catalog only? + # If yes, no imaging simulation will be run. Only the catalogs + # of corresponding footprints will be generated. + out_cat_only: NO + +############################################### +# Catalog setting +############################################### +# Configure the input catalog: options should be implemented +# in the corresponding (user defined) 'Catalog' class +catalog_options: + input_path: + cat_dir: "/public/share/yangxuliu/CSSOSDataProductsSims/data_50sqDeg/" + star_cat: "starcat_C9/" + galaxy_cat: "qsocat/cat2CSSTSim_bundle-50sqDeg/" + + SED_templates_path: + star_SED: "/public/share/yangxuliu/CSSOSDataProductsSims/data_50sqDeg/starcat_C9/" + galaxy_SED: "/public/share/yangxuliu/CSSOSDataProductsSims/data_50sqDeg/sedlibs/" + AGN_SED: "/public/share/yangxuliu/CSSOSDataProductsSims/data_50sqDeg/qsocat/qsosed/" + + # Only simulate stars? + star_only: NO + + # Only simulate galaxies? + galaxy_only: NO + + # rotate galaxy ellipticity + rotateEll: 0. # [degree] + + # Whether to apply milky way extinction to galaxies + enable_mw_ext_gal: YES + planck_ebv_map: "/public/home/fangyuedong/project/ext_maps/planck/HFI_CompMap_ThermalDustModel_2048_R1.20.fits" + +############################################### +# Observation setting +############################################### +obs_setting: + # (Optional) a file of point list + # if you just want to run default pointing: + # - pointing_dir: null + # - pointing_file: null + pointing_file: "/public/share/yangxuliu/CSSOSDataProductsSims/data_50sqDeg/pointing50_C9/pointing_50_1_n.dat" + + obs_config_file: "/public/home/fangyuedong/project/csst_msc_sim/config/obs_config_SCI.yaml" + + # Run specific pointing(s): + # - give a list of indexes of pointings: [ip_1, ip_2...] + # - run all pointings: null + # Note: only valid when a pointing list is specified + run_pointings: [0, 1, 2, 3, 4] + + # Whether to enable astrometric modeling + enable_astrometric_model: YES + + # Cut by saturation magnitude in which band? + cut_in_band: "z" + + # saturation magnitude margin + mag_sat_margin: -2.5 + # mag_sat_margin: -15. + + # limiting magnitude margin + mag_lim_margin: +1.0 + +############################################### +# PSF setting +############################################### +psf_setting: + + # Which PSF model to use: + # "Gauss": simple gaussian profile + # "Interp": Interpolated PSF from sampled ray-tracing data + psf_model: "Interp" + + # PSF size [arcseconds] + # radius of 80% energy encircled + # NOTE: only valid for "Gauss" PSF + # psf_rcont: 0.15 + + # path to PSF data + # NOTE: only valid for "Interp" PSF + # PSF models for photometry survey simulation + psf_pho_dir: "/public/share/yangxuliu/CSSOSDataProductsSims/dataC6/psfCube1" + # PSF models for slitless spectrum survey simulation + psf_sls_dir: "/public/share/yangxuliu/CSSOSDataProductsSims/data_50sqDeg/SLS_PSF_PCA_fp/" + +############################################### +# Shear setting +############################################### + +shear_setting: + # Options to generate mock shear field: + # "constant": all galaxies are assigned a constant reduced shear + # "catalog": get shear values from catalog + shear_type: "constant" + + # For constant shear field + reduced_g1: 0. + reduced_g2: 0. + +############################################### +# Output options +############################################### +output_setting: + output_format: "channels" # Whether to export as 16 channels (subimages) with pre- and over-scan ("image"/"channels") + shutter_output: NO # Whether to export shutter effect 16-bit image + prnu_output: NO # Whether to export the PRNU (pixel-to-pixel flat-fielding) files + +############################################### +# Random seeds +############################################### +random_seeds: + seed_poisson: 20210601 # Seed for Poisson noise + seed_CR: 20210317 # Seed for generating random cosmic ray maps + seed_flat: 20210101 # Seed for generating random flat fields + seed_prnu: 20210102 # Seed for photo-response non-uniformity + seed_gainNonUniform: 20210202 # Seed for gain nonuniformity + seed_biasNonUniform: 20210203 # Seed for bias nonuniformity + seed_rnNonUniform: 20210204 # Seed for readout-noise nonuniformity + seed_badcolumns: 20240309 # Seed for bad columns + seed_defective: 20210304 # Seed for defective (bad) pixels + seed_readout: 20210601 # Seed for read-out gaussian noise +... \ No newline at end of file diff --git a/tools/setConfig/templates/index_obs.html b/tools/setConfig/templates/index_obs.html new file mode 100644 index 0000000..5199558 --- /dev/null +++ b/tools/setConfig/templates/index_obs.html @@ -0,0 +1,246 @@ + + + + + + csst_msc_sim_CONF + + + + +
+

é…ç½®obs_config_SCI.yaml

+

说明: + 1,该脚本å¯ç”¨äºŽç”ŸæˆCSST主巡天æˆåƒä»¿çœŸçš„傿•°æ–‡ä»¶,ç›¸å…³å‚æ•°è¯´æ˜Žè§æœ¬é¡µè„𿳍;2,ç”¨æˆ·å¿…é¡»ä¿®æ”¹ç›¸å…³è·¯å¾„å‚æ•°ï¼Œå…¶ä»–傿•°å¯å‚考默认值 +. +

+
+
+ {{ form_html | safe }} + +
+
+ +
+

这是一个有用的网页

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
KEYSVALUESCOMMENTS
obs_type"SCI", [str]仿真图åƒç±»åž‹
obs_type_code"101", [str]æ•°æ®ç³»ç»Ÿå†…部标å·
obs_id"00000001", [str]this setting will only be used if pointing list file is not given
run_chips[7,8,9], [list]Define list of chips
scie_obs:shutter_effectYES, [bool]是å¦åº”用快门效应
scie_obs:flat_fieldingYES, [bool]是å¦åº”用平场模å—
scie_obs:field_distYES, [bool]
sky_background:shutter_effectYES, [bool]是å¦åº”用快门效应
sky_background:flat_fieldingYES, [bool]是å¦åº”用平场模å—
sky_background:enable_straylight_modelYES, [bool]是å¦åº”ç”¨æ‚æ•£å…‰æ¨¡å—
sky_background:flat_levelnull [null or int]set the total skybackground value (e-) in the exptime,if none,set null, or delete the key
sky_background:flat_level_filtnull, [str]the vale of "flat_level" is in the filter "flat_level_filt", can set NUV, u, g, r, i, z, y, if none,set null,or delete the key
PRNU_effect---应用åƒç´ é—´ä¸å‡åŒ€å“应模å—;如果需关闭,请在生æˆçš„yaml文件中直接注释
cosmic_rays:save_cosmic_imgYES, [bool]是å¦ä¿å­˜å®‡å®™çº¿å›¾åƒ
poisson_and_dark:add_darkYES, [bool]æ˜¯å¦æ·»åŠ æš—ç”µæµ
bright_fatterYES, [bool]应用亮胖效应模å—;如果需关闭,请在生æˆçš„yaml文件中直接注释
detector_defects:hot_pixelsYES, [bool]æ˜¯å¦æ·»åŠ çƒ­åƒå…ƒ
detector_defects:dead_pixelsYES, [bool]æ˜¯å¦æ·»åŠ ååƒå…ƒ
detector_defects:bad_columnsYES, [bool]æ˜¯å¦æ·»åŠ ååƒåˆ—
nonlinearity---应用éžçº¿æ€§å“应模å—;如果需关闭,请在生æˆçš„yaml文件中直接注释
blooming---是å¦åº”用饱和溢出模å—;如果需关闭,请在生æˆçš„yaml文件中直接注释
prescan_overscan:add_darkYES, [bool] 是å¦åœ¨pre/over-scan区域添加暗电æµ/
bias:bias_16channelYES, [bool]æ˜¯å¦æ·»åŠ 16通é“çš„å置电压
readout_noise---添加读出噪声;如果需关闭,请在生æˆçš„yaml文件中直接注释
gain:gain_16channelYES, [bool]是å¦åº”用增益
quantization_and_output:format_outputYES, [bool]æ˜¯å¦æŒ‰0çº§æ•°æ®æ ¼å¼å®šä¹‰è¾“出图åƒ
+
+ + + diff --git a/tools/setConfig/templates/index_overall.html b/tools/setConfig/templates/index_overall.html new file mode 100644 index 0000000..d61ccf8 --- /dev/null +++ b/tools/setConfig/templates/index_overall.html @@ -0,0 +1,258 @@ + + + + + + csst_msc_sim_CONF + + + + +
+

é…ç½®config_overall.yaml

+

说明: + 1,该脚本å¯ç”¨äºŽç”ŸæˆCSST主巡天æˆåƒä»¿çœŸçš„傿•°æ–‡ä»¶,ç›¸å…³å‚æ•°è¯´æ˜Žè§æœ¬é¡µè„𿳍;2,ç”¨æˆ·å¿…é¡»ä¿®æ”¹ç›¸å…³è·¯å¾„å‚æ•°ï¼Œå…¶ä»–傿•°å¯å‚考默认值. +

+
+
+ {{ form_html | safe }} + +
+
+ +
+

这是一个有用的网页

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
KEYSVALUESCOMMENTS
work_dir/localpath, [str]工作目录-仿真输出的文件路径
run_nametestRun, [str]当å‰ä»¿çœŸç›®å½•
project_cycle10, [int]CSSTæ•°æ®ç³»ç»Ÿå¼€å‘阶段-C10
project_cycle0, [int]仿真次数标å·-0
run_option:out_cat_onlyNO, [bool]是å¦ä»…输出星表-YES,ä¸äº§ç”Ÿå¼€å±•æˆåƒä»¿çœŸï¼Œç›´æŽ¥è¾“出星表文件;NO,开展æˆåƒä»¿çœŸ
catalog_options:input_path/localpath, [str]"cat_dir": 输入星表路径, "star_cat": æ’æ˜Ÿæ˜Ÿè¡¨ç›®å½•, "galaxy_cat": 星系星表目录
catalog_options:SED_templates_path/localpath, [str]"star_SED": æ’æ˜ŸSED路径,"galaxy_SED": 星系SED路径,"AGN_SED": 类星体SED路径
catalog_options:star_onlyNO, [bool]YES,åªå¯¹æ’星æˆåƒï¼›NO,包å«å…¶ä»–天体æˆåƒ
catalog_options:galaxy_onlyNO, [bool]YES,åªå¯¹æ˜Ÿç³»æˆåƒï¼›NO,包å«å…¶ä»–天体æˆåƒ
catalog_options:rotateEll0.0, [float]旋转星系指å‘(度)
catalog_options:enable_mw_ext_galNO, [bool]是å¦åº”用银河系消光
catalog_options:planck_ebv_map/localpath, [str]消光模型
obs_setting:pointing_file/localpath, [str]æ›å…‰æŒ‡å‘文件路径
obs_setting:obs_config_file/localpath, [str]观测é…置文件路径
obs_setting:run_pointings[0], [int]give a list of indexes of pointings
obs_setting:enable_astrometric_modelYES, [bool]是å¦åº”用天测模å—
obs_setting:cut_in_band"z", [str]Cut by saturation magnitude in which band
obs_setting:mag_sat_margin-2.5, [float]saturation magnitude margin
obs_setting:mag_lim_margin+1.0, [float]limiting magnitude margin
psf_setting:psf_model"Interp", [str]Interp-Interpolated PSF from sampled ray-tracing data; Gauss-simple gaussian profile
psf_setting:psf_pho_dir/localpath, [str]多色æˆåƒPSFæ•°æ®åº“路径
psf_setting:psf_sls_dir/localpath, [str]æ— ç¼å…‰è°±PSFæ•°æ®åº“路径
shear_setting:shear_typeconstant, [str]constant-all galaxies are assigned a constant reduced shear; catalog-get shear values from catalog
shear_setting:reduced_g10.0, [float]weak lensing shear, gamma_1
shear_setting:reduced_g10.0, [float]weak lensing shear, gamma_2
output_setting:output_formatchannels, [str]Whether to export as 16 channels (subimages) with pre- and over-scan (\"image\"/\"channels\")
output_setting:shutter_outputNO, [bool]Whether to export shutter effect 16-bit image
output_setting:prnu_outputNO, [bool]Whether to export the PRNU (pixel-to-pixel flat-fielding) files
random_seeds[int]è®¾ç½®éšæœºæ•°ç§å­
+
+ + + diff --git a/tools/setConfig/templates/obs_config_SCI.yaml b/tools/setConfig/templates/obs_config_SCI.yaml new file mode 100644 index 0000000..ef82bcd --- /dev/null +++ b/tools/setConfig/templates/obs_config_SCI.yaml @@ -0,0 +1,85 @@ +--- +############################################### +# +# Configuration file for CSST simulation +# For single exposure type: +# SCI-WIDE +# CSST-Sim Group, 2024/01/08 +# +############################################### + +# Observation type +obs_type: "SCI" +obs_type_code: "101" +obs_id: "00000001" # this setting will only be used if pointing list file is not given + +# Define list of chips +# run_chips: [6,7,8,9,11,12,13,14,15,16,17,18,19,20,22,23,24,25] # Photometric chips +#run_chips: [1,2,3,4,5,10,21,26,27,28,29,30] # Spectroscopic chips +run_chips: [17, 22] + +# Define observation sequence +call_sequence: + # Accumulate fluxes from objects + scie_obs: + # [Optional]: exposure time of the pointing will be used as default. + # Set it here is you want to override the default + # exptime: 150. # [s] + shutter_effect: YES + flat_fielding: YES + field_dist: YES + # Accumulate fluxes from sky background + sky_background: + # [Optional]: exposure time of the pointing will be used as default. + # Set it here is you want to override the default + # exptime: 150. # [s] + shutter_effect: YES + flat_fielding: YES + enable_straylight_model: YES + # flat_level: set the total skybackground value (e-) in the exptime,if none,set null, or delete the key + # flat_level_filt: the vale of "flat_level" is in the filter "flat_level_filt", can set NUV, u, g, r, i, z, y, if + # none,set null,or delete the key + flat_level: null + flat_level_filt: null + # Apply PRNU to accumulated photons + PRNU_effect: {} + # Accumulate photons caused by cosmic rays + cosmic_rays: + # [Optional]: exposure time of the pointing will be used as default. + # Set it here is you want to override the default + # exptime: 150. # [s] + save_cosmic_img: YES # # Whether to export cosmic ray image + # Add Poission noise and dark current + poisson_and_dark: + # [Optional]: exposure time of the pointing will be used as default. + # Set it here is you want to override the default + # exptime: 150. # [s] + add_dark: YES + # Simulate brighter fatter effects + bright_fatter: {} + # Add detector defects: hot/warm pixels, bad columns + detector_defects: + hot_pixels: YES + dead_pixels: YES + bad_columns: YES + # Apply response nonlinearity + nonlinearity: {} + # Apply CCD Saturation & Blooming + blooming: {} + # Run CTE simulation + # CTE_effect: {} + # Add prescan and overscan + prescan_overscan: + add_dark: YES + # Add bias + bias: + bias_16channel: YES + # Add readout noise + readout_noise: {} + # Apply gain + gain: + gain_16channel: YES + # Output the final image + quantization_and_output: + format_output: YES +... -- GitLab From 4a0ff3ab05557159ddd3477bdac90f76662924eb Mon Sep 17 00:00:00 2001 From: Chengliang Date: Thu, 14 Nov 2024 18:37:02 +0800 Subject: [PATCH 34/64] delete DS_Store --- tools/setConfig/.DS_Store | Bin 8196 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 tools/setConfig/.DS_Store diff --git a/tools/setConfig/.DS_Store b/tools/setConfig/.DS_Store deleted file mode 100644 index 316c88df0f1de73f1e37a841b6e985fdc1b95458..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8196 zcmeHMzi-n(6n@u+)FDL#l}hb^WC_Nqv;|clmXHRCt{A}pG{j9vA{?KU9}QI$lno?y zHY6q{Bqk*i#k*0^qEyi20T$fhr1r%cRlXTXqyv;0mFb{z%XDKFbo_A2Jp-l#Y%bZtE;9p z3>XIfO9sULV516I)N-t(+&a+66aX@V)3TtCJV0V>EsI)?m6TA}RM`X5P^ME1rr@}4 z3w6k%mSZIqoS1?W(<3vTp)ff*aJEz@R#eioh5^ICECV8U&r%hcdqC^4{9T07b=0?C zWs%@K?Gq=T9#M-LKpXckF-*Oy*hPK zd#M)R#a6QzvpBU7T@QN!+y1fQ_Ll z``su)vKpRW0^(l?!-Qo;1F$J*PS6U6-p##Nlh8}l33G5W*9IG{4xV9Q+CQFn3=p4#x06m+eUqeDvHn>D=8sp tWI7Hh({ae@ABO1LP!*V>mSZJx2IY@`2>4rG!xNsu=J_vO#x%cyfp4pI{cr#P -- GitLab From cda4116582234b8c2ff670a0940e848e0525d0dc Mon Sep 17 00:00:00 2001 From: Chengliang Date: Fri, 15 Nov 2024 15:12:13 +0800 Subject: [PATCH 35/64] format codestyle-PEP8 --- tools/setConfig/reset_obs.py | 28 ++++++++++++++++------------ tools/setConfig/reset_overall.py | 26 ++++++++++++++++---------- 2 files changed, 32 insertions(+), 22 deletions(-) diff --git a/tools/setConfig/reset_obs.py b/tools/setConfig/reset_obs.py index c8c7a65..f05b9d2 100644 --- a/tools/setConfig/reset_obs.py +++ b/tools/setConfig/reset_obs.py @@ -10,13 +10,13 @@ key_type_map = { 'obs_type_code': str, 'obs_id': str, 'run_chips': list, - 'call_sequence':{ - 'scie_obs':{ + 'call_sequence': { + 'scie_obs': { 'shutter_effect': bool, 'flat_fielding': bool, 'field_dist': bool, }, - 'sky_background':{ + 'sky_background': { 'shutter_effect': bool, 'flat_fielding': bool, 'enable_straylight_model': bool, @@ -24,35 +24,37 @@ key_type_map = { 'flat_level_filt': None, }, 'PRNU_effect': {}, - 'cosmic_rays':{ + 'cosmic_rays': { 'save_cosmic_img': bool, }, - 'poisson_and_dark':{ + 'poisson_and_dark': { 'add_dark': bool, }, 'bright_fatter': {}, - 'detector_defects':{ + 'detector_defects': { 'hot_pixels': bool, 'dead_pixels': bool, 'bad_columns': bool, }, 'nonlinearity': {}, 'blooming': {}, - 'prescan_overscan':{ + 'prescan_overscan': { 'add_dark': bool, }, - 'bias':{ + 'bias': { 'bias_16channel': bool, }, 'readout_noise': {}, - 'gain':{ + 'gain': { 'gain_16channel': bool, }, - 'quantization_and_output':{ + 'quantization_and_output': { 'format_output': bool, }, }, } + + def convert_dict_values(d, key_type_map): for key, value in d.items(): if isinstance(value, dict): @@ -75,16 +77,17 @@ def convert_dict_values(d, key_type_map): d[key] = None - def load_yaml(): with open('templates/obs_config_SCI.yaml', 'r') as file: return yaml.safe_load(file) + def save_yaml(data): convert_dict_values(data, key_type_map) with open('config_reset/obs_config_SCI_reset.yaml', 'w') as file: yaml.dump(data, file, default_flow_style=False, sort_keys=False) + def render_form(data, parent_key=''): form_html = '' for key, value in data.items(): @@ -96,6 +99,7 @@ def render_form(data, parent_key=''): form_html += f"
" return form_html + @app.route('/', methods=['GET', 'POST']) def index(): if request.method == 'POST': @@ -113,6 +117,6 @@ def index(): form_html = render_form(data) return render_template('index_obs.html', form_html=form_html) + if __name__ == '__main__': app.run(debug=True) - diff --git a/tools/setConfig/reset_overall.py b/tools/setConfig/reset_overall.py index df51b24..540627f 100644 --- a/tools/setConfig/reset_overall.py +++ b/tools/setConfig/reset_overall.py @@ -9,16 +9,16 @@ key_type_map = { 'run_name': str, 'project_cycle': int, 'run_counter': int, - 'run_option':{ + 'run_option': { 'out_cat_only': bool, }, - 'catalog_options':{ - 'input_path':{ + 'catalog_options': { + 'input_path': { 'cat_dir': str, 'star_cat': str, 'galaxy_cat': str, }, - 'SED_templates_path':{ + 'SED_templates_path': { 'star_SED': str, 'galaxy_SED': str, 'AGN_SED': str, @@ -29,7 +29,7 @@ key_type_map = { 'enable_mw_ext_gal': bool, 'planck_ebv_map':str, }, - 'obs_setting':{ + 'obs_setting': { 'pointing_file': str, 'obs_config_file': str, 'run_pointings': list, @@ -38,22 +38,22 @@ key_type_map = { 'mag_sat_margin': float, 'mag_lim_margin': float, }, - 'psf_setting':{ + 'psf_setting': { 'psf_model': str, 'psf_pho_dir': str, 'psf_sls_dir': str, }, - 'shear_setting':{ + 'shear_setting': { 'shear_type': str, 'reduced_g1': float, 'reduced_g2': float, }, - 'output_setting':{ + 'output_setting': { 'output_format': str, 'shutter_output': bool, 'prnu_output': bool, }, - 'random_seeds':{ + 'random_seeds': { 'seed_poisson': int, 'seed_CR': int, 'seed_flat': int, @@ -66,6 +66,8 @@ key_type_map = { 'seed_readout': int, }, } + + def convert_dict_values(d, key_type_map): for key, value in d.items(): if isinstance(value, dict): @@ -85,15 +87,18 @@ def convert_dict_values(d, key_type_map): if key_type_map[key] is list: d[key] = ast.literal_eval(value) + def load_yaml(): with open('templates/config_overall.yaml', 'r') as file: return yaml.safe_load(file) + def save_yaml(data): convert_dict_values(data, key_type_map) with open('config_reset/config_overall_reset.yaml', 'w') as file: yaml.dump(data, file, default_flow_style=False, sort_keys=False) + def render_form(data, parent_key=''): form_html = '' for key, value in data.items(): @@ -105,6 +110,7 @@ def render_form(data, parent_key=''): form_html += f"
" return form_html + @app.route('/', methods=['GET', 'POST']) def index(): if request.method == 'POST': @@ -122,6 +128,6 @@ def index(): form_html = render_form(data) return render_template('index_overall.html', form_html=form_html) + if __name__ == '__main__': app.run(debug=True) - -- GitLab From 4325fe995f1e870379ad2ed9a05756559e792f27 Mon Sep 17 00:00:00 2001 From: Chengliang Date: Fri, 15 Nov 2024 15:19:38 +0800 Subject: [PATCH 36/64] format codestyle-PEP8 --- tools/setConfig/reset_overall.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/tools/setConfig/reset_overall.py b/tools/setConfig/reset_overall.py index 540627f..cacb204 100644 --- a/tools/setConfig/reset_overall.py +++ b/tools/setConfig/reset_overall.py @@ -4,7 +4,7 @@ import ast app = Flask(__name__) -key_type_map = { +key_type_map = { 'work_dir': str, 'run_name': str, 'project_cycle': int, @@ -23,11 +23,11 @@ key_type_map = { 'galaxy_SED': str, 'AGN_SED': str, }, - 'star_only': bool, + 'star_only': bool, 'galaxy_only': bool, 'rotateEll': float, 'enable_mw_ext_gal': bool, - 'planck_ebv_map':str, + 'planck_ebv_map': str, }, 'obs_setting': { 'pointing_file': str, @@ -68,11 +68,11 @@ key_type_map = { } -def convert_dict_values(d, key_type_map): - for key, value in d.items(): - if isinstance(value, dict): - convert_dict_values(value, key_type_map[key]) - elif key in key_type_map: +def convert_dict_values(d, key_type_map): + for key, value in d.items(): + if isinstance(value, dict): + convert_dict_values(value, key_type_map[key]) + elif key in key_type_map: if key_type_map[key] is int: d[key] = int(value) if key_type_map[key] is float: @@ -94,7 +94,7 @@ def load_yaml(): def save_yaml(data): - convert_dict_values(data, key_type_map) + convert_dict_values(data, key_type_map) with open('config_reset/config_overall_reset.yaml', 'w') as file: yaml.dump(data, file, default_flow_style=False, sort_keys=False) -- GitLab From a03daa9438870d8d4b7c58380e19efc3602e5459 Mon Sep 17 00:00:00 2001 From: Chengliang Date: Tue, 26 Nov 2024 17:13:53 +0800 Subject: [PATCH 37/64] bug fixes & extrapolate PSF for saturated objects --- config/obs_config_SCI.yaml | 4 +- .../instruments/chip/libBF/diffusion_X1.c | 21 +++--- observation_sim/mock_objects/Galaxy.py | 7 +- observation_sim/mock_objects/MockObject.py | 9 ++- observation_sim/psf/PSFInterp.py | 24 ++++--- observation_sim/psf/_util.py | 64 +++++++++++++++++++ 6 files changed, 100 insertions(+), 29 deletions(-) create mode 100644 observation_sim/psf/_util.py diff --git a/config/obs_config_SCI.yaml b/config/obs_config_SCI.yaml index fecdf01..fb8f538 100644 --- a/config/obs_config_SCI.yaml +++ b/config/obs_config_SCI.yaml @@ -62,10 +62,10 @@ call_sequence: hot_pixels: YES dead_pixels: YES bad_columns: YES - # Apply response nonlinearity - nonlinearity: {} # Apply CCD Saturation & Blooming blooming: {} + # Apply response nonlinearity + nonlinearity: {} # Run CTE simulation # CTE_effect: {} # Add prescan and overscan diff --git a/observation_sim/instruments/chip/libBF/diffusion_X1.c b/observation_sim/instruments/chip/libBF/diffusion_X1.c index 199b48c..b0259e8 100644 --- a/observation_sim/instruments/chip/libBF/diffusion_X1.c +++ b/observation_sim/instruments/chip/libBF/diffusion_X1.c @@ -37,7 +37,7 @@ void addEffects(int ngx_ima, int ngy_ima, float *arr_ima, float *arr_imc, int bi { printf("Adding BF effect...\n"); //setup BF correlation fliter - float neX; + float neX, neXtemp; float neP1 = 50000; float bfaP1[9]={0.9707182, 0.002143905, 0.004131103, 0.001149542, 0.0005501739, 0.0005469659, 0.0003726081, 0.0003795207, 0.0001633302}; float neP2 = 10000; @@ -56,15 +56,18 @@ void addEffects(int ngx_ima, int ngy_ima, float *arr_ima, float *arr_imc, int bi neX = arr_ima[j+i*ny]; if(neX >= 10000) { + neXtemp = neX; + if(neXtemp > 100000) + neXtemp = 100000; bfa[0][0]=0; //linearInterp(neX, neP1, bfaP1[0], neP2, bfaP2[0]); //0; - bfa[0][1]=bfa[0][-1]=linearInterp(neX, neP1, bfaP1[1], neP2, bfaP2[1]); //0.01575; - bfa[-1][0]=bfa[1][0]=linearInterp(neX, neP1, bfaP1[2], neP2, bfaP2[2]); //0.00652; - bfa[-1][-1]=bfa[1][1]=bfa[-1][1]=bfa[1][-1]=linearInterp(neX, neP1, bfaP1[3], neP2, bfaP2[3]); //0.00335; - bfa[0][-2]=bfa[0][2]=linearInterp(neX, neP1, bfaP1[4], neP2, bfaP2[4]); - bfa[-2][0]=bfa[2][0]=linearInterp(neX, neP1, bfaP1[5], neP2, bfaP2[5]); //0.00118; - bfa[-2][-1]=bfa[-2][1]=bfa[2][1]=bfa[2][-1]=linearInterp(neX, neP1, bfaP1[6], neP2, bfaP2[6]); - bfa[-1][-2]=bfa[1][2]=bfa[-1][2]=bfa[1][-2]=linearInterp(neX, neP1, bfaP1[7], neP2, bfaP2[7]); //0.00083; - bfa[-2][-2]=bfa[-2][2]=bfa[2][-2]=bfa[2][2]=linearInterp(neX, neP1, bfaP1[8], neP2, bfaP2[8]); //0.00043; + bfa[0][1]=bfa[0][-1]=linearInterp(neXtemp, neP1, bfaP1[1], neP2, bfaP2[1]); //0.01575; + bfa[-1][0]=bfa[1][0]=linearInterp(neXtemp, neP1, bfaP1[2], neP2, bfaP2[2]); //0.00652; + bfa[-1][-1]=bfa[1][1]=bfa[-1][1]=bfa[1][-1]=linearInterp(neXtemp, neP1, bfaP1[3], neP2, bfaP2[3]); //0.00335; + bfa[0][-2]=bfa[0][2]=linearInterp(neXtemp, neP1, bfaP1[4], neP2, bfaP2[4]); + bfa[-2][0]=bfa[2][0]=linearInterp(neXtemp, neP1, bfaP1[5], neP2, bfaP2[5]); //0.00118; + bfa[-2][-1]=bfa[-2][1]=bfa[2][1]=bfa[2][-1]=linearInterp(neXtemp, neP1, bfaP1[6], neP2, bfaP2[6]); + bfa[-1][-2]=bfa[1][2]=bfa[-1][2]=bfa[1][-2]=linearInterp(neXtemp, neP1, bfaP1[7], neP2, bfaP2[7]); //0.00083; + bfa[-2][-2]=bfa[-2][2]=bfa[2][-2]=bfa[2][2]=linearInterp(neXtemp, neP1, bfaP1[8], neP2, bfaP2[8]); //0.00043; } else { diff --git a/observation_sim/mock_objects/Galaxy.py b/observation_sim/mock_objects/Galaxy.py index 03df3eb..8d22344 100755 --- a/observation_sim/mock_objects/Galaxy.py +++ b/observation_sim/mock_objects/Galaxy.py @@ -115,7 +115,7 @@ class Galaxy(MockObject): # Set Galsim Parameters if self.getMagFilter(filt) <= 15 and (not big_galaxy): - folding_threshold = 5.e-4 + folding_threshold = 5.e-8 else: folding_threshold = 5.e-3 gsp = galsim.GSParams(folding_threshold=folding_threshold) @@ -170,8 +170,11 @@ class Galaxy(MockObject): # print("nphotons_sub-band_%d = %.2f"%(i, nphotons)) # Get PSF model + EXTRA = False + if self.getMagFilter(filt) <= filt.mag_saturation-1.: + EXTRA = True psf, pos_shear = psf_model.get_PSF( - chip=chip, pos_img=pos_img, bandpass=bandpass, folding_threshold=folding_threshold) + chip=chip, pos_img=pos_img, bandpass=bandpass, folding_threshold=folding_threshold, extrapolate=EXTRA) if self.bfrac == 0: gal_temp = disk diff --git a/observation_sim/mock_objects/MockObject.py b/observation_sim/mock_objects/MockObject.py index 38608fa..8ef57be 100755 --- a/observation_sim/mock_objects/MockObject.py +++ b/observation_sim/mock_objects/MockObject.py @@ -122,7 +122,7 @@ class MockObject(object): return 2, None # Set Galsim Parameters if self.getMagFilter(filt) <= 15: - folding_threshold = 5.e-4 + folding_threshold = 5.e-8 else: folding_threshold = 5.e-3 gsp = galsim.GSParams(folding_threshold=folding_threshold) @@ -160,14 +160,17 @@ class MockObject(object): # print("nphotons_sub-band_%d = %.2f"%(i, nphotons)) # Get PSF model + EXTRA = False + if self.getMagFilter(filt) <= filt.mag_saturation-1.: + EXTRA = True psf, pos_shear = psf_model.get_PSF(chip=chip, pos_img=pos_img, bandpass=bandpass, - folding_threshold=folding_threshold) + folding_threshold=folding_threshold, extrapolate=EXTRA) # star = galsim.DeltaFunction(gsparams=gsp) # star = star.withFlux(nphotons) # star = galsim.Convolve(psf, star) star = psf.withFlux(nphotons) - stamp = star.drawImage(wcs=chip_wcs_local, offset=offset) + stamp = star.drawImage(method='no_pixel', wcs=chip_wcs_local, offset=offset) if np.sum(np.isnan(stamp.array)) > 0: continue stamp.setCenter(x_nominal, y_nominal) diff --git a/observation_sim/psf/PSFInterp.py b/observation_sim/psf/PSFInterp.py index ab902d9..7c439bb 100644 --- a/observation_sim/psf/PSFInterp.py +++ b/observation_sim/psf/PSFInterp.py @@ -13,6 +13,7 @@ import galsim import h5py from observation_sim.psf.PSFModel import PSFModel +from observation_sim.psf._util import psf_extrapolate NPSF = 900 # ***# 30*30 @@ -324,7 +325,7 @@ class PSFInterp(PSFModel): return twave return -1 - def get_PSF(self, chip, pos_img, bandpass, galsimGSObject=True, findNeighMode='treeFind', folding_threshold=5.e-3, pointing_pa=0.0): + def get_PSF(self, chip, pos_img, bandpass, galsimGSObject=True, findNeighMode='treeFind', folding_threshold=5.e-3, pointing_pa=0.0, extrapolate=False, ngg=2048): """ Get the PSF at a given image position @@ -358,20 +359,17 @@ class PSFInterp(PSFModel): imPSF = psfMaker_IDW(px, py, PSFMat, cen_col, cen_row, IDWindex=2, OnlyNeighbors=True, hoc=self.hoc[twave], hoclist=self.hoclist[twave], PSFCentroidWgt=True) - ''' - ############TEST: START - TestGaussian = False - if TestGaussian: - gsx = galsim.Gaussian(sigma=0.04) - #pointing_pa = -23.433333 - imPSF= gsx.shear(g1=0.8, g2=0.).rotate(0.*galsim.degrees).drawImage(nx = 256, ny=256, scale=pixSize).array - ############TEST: END - ''' + if extrapolate is True: + ccdList = [ 6, 7, 8, 9, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 22, 23, 24, 25] + rr_trim_list = [72, 64, 96, 88, 64, 72, 72, 76, 72, 72, 76, 72, 72, 64, 88, 96, 64, 72] + imPSF = psf_extrapolate(imPSF, rr_trim=rr_trim_list[ccdList.index(chip.chipID)], ngg=ngg) if galsimGSObject: - imPSFt = np.zeros([257, 257]) - imPSFt[0:256, 0:256] = imPSF - # imPSFt[120:130, 0:256] = 1. + if extrapolate is True: + imPSFt = imPSF + else: + imPSFt = np.zeros([257, 257]) + imPSFt[0:256, 0:256] = imPSF img = galsim.ImageF(imPSFt, scale=pixSize) gsp = galsim.GSParams(folding_threshold=folding_threshold) diff --git a/observation_sim/psf/_util.py b/observation_sim/psf/_util.py new file mode 100644 index 0000000..e57f969 --- /dev/null +++ b/observation_sim/psf/_util.py @@ -0,0 +1,64 @@ +import numpy as np +from scipy.interpolate import interp1d + +def binningPSF(img, ngg): + imgX = img.reshape(ngg, img.shape[0]//ngg, ngg, img.shape[1]//ngg).mean(-1).mean(1) + return imgX + + +def radial_average_at_pixel(image, center_x, center_y, dr=10): + # Get coordinates relative to the specified center pixel (x, y) + y, x = np.indices(image.shape) + r = np.sqrt((x - center_x)**2 + (y - center_y)**2) + + # Set up bins + max_radius = int(r.max()) # Maximum distance from the center pixel + radial_bins = np.arange(0, max_radius, dr) + + # Compute average value in each bin + radial_means = [] + for i in range(len(radial_bins) - 1): + mask = (r >= radial_bins[i]) & (r < radial_bins[i + 1]) + if np.any(mask): + radial_means.append(image[mask].mean()) + else: + radial_means.append(0) # In case no pixels are in the bin + return radial_bins[:-1], radial_means # Exclude last bin since no mean calculated + + +def psf_extrapolate(psf, rr_trim=64, ngg=256): + # ngg = 256 + # extrapolate PSF + if True: + xim = np.arange(256)-128 + xim,yim = np.meshgrid(xim, xim) + rim = np.sqrt(xim**2 +yim**2) + + # rr_trim = 96 + psf_temp = psf + psf_temp[rim > rr_trim] = 0 + radii, means = radial_average_at_pixel(psf_temp, 128, 128, dr=4) + + radii_log = np.log(radii[1:]) + means_log = np.log(means[1:]) + + finite_mask = np.isfinite(means_log) + f_interp = interp1d(radii_log[finite_mask][:-1], means_log[finite_mask][:-1], kind='linear', fill_value="extrapolate") + + # ngg = 1024 + xim = np.arange(ngg)-int(ngg/2) + xim,yim = np.meshgrid(xim, xim) + rim = np.sqrt(xim**2 +yim**2) + rim[int(ngg/2),int(ngg/2)] = np.finfo(float).eps # 1e-7 + rim_log = np.log(rim) + y_new = f_interp(rim_log) + + arr = np.zeros([ngg, ngg]) + arr[int(ngg/2-128):int(ngg/2+128), int(ngg/2-128):int(ngg/2+128)] = np.log(psf_temp + np.finfo(float).eps) + arr[rim > rr_trim] = 0 + arr[arr==0] = y_new[arr==0] + psf = np.exp(arr) + psf[rim > int(ngg/2)] = 0 + imPSF = psf # binningPSF(psf, int(ngg/2)) + imPSF = imPSF/np.nansum(imPSF) + return imPSF -- GitLab From 07f72bde4994af3103879586f230dd37788a14e3 Mon Sep 17 00:00:00 2001 From: Chengliang Date: Tue, 26 Nov 2024 17:18:51 +0800 Subject: [PATCH 38/64] added C10_Catalog.py --- catalog/C10_Catalog.py | 574 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 574 insertions(+) create mode 100644 catalog/C10_Catalog.py diff --git a/catalog/C10_Catalog.py b/catalog/C10_Catalog.py new file mode 100644 index 0000000..8bbebcb --- /dev/null +++ b/catalog/C10_Catalog.py @@ -0,0 +1,574 @@ +import os +import galsim +import random +import copy +import numpy as np +import h5py as h5 +import healpy as hp +import astropy.constants as cons +import traceback +from astropy.coordinates import spherical_to_cartesian +from astropy.table import Table +from scipy import interpolate +from datetime import datetime + +from observation_sim.mock_objects import CatalogBase, Star, Galaxy, Quasar, ExtinctionMW +from observation_sim.mock_objects._util import tag_sed, getObservedSED, getABMAG, integrate_sed_bandpass, comoving_dist +from observation_sim.astrometry.Astrometry_util import on_orbit_obs_position + +# (TEST) +from astropy.cosmology import FlatLambdaCDM +from astropy import constants +from astropy import units as U +from astropy.coordinates import SkyCoord +from astropy.io import fits +import astropy.constants as atcons + +import ctypes + +try: + import importlib.resources as pkg_resources +except ImportError: + # Try backported to PY<37 'importlib_resources' + import importlib_resources as pkg_resources + +NSIDE = 128 + +pointing_file_list = ['pointing_C10_1000deg_lat80.dat', 'pointing_C10_1000deg_latm80_.dat', 'pointing_C10_1000deg_p180_m30.dat', 'pointing_C10_1000deg_p320_m40.dat'] +star_file_list = ['CSST_C10_1000sqd_1.hdf5', 'CSST_C10_1000sqd_2_Fornax.hdf5', 'CSST_C10_1000sqd_3.hdf5', 'CSST_C10_1000sqd_4.hdf5'] + + +def get_galaxy_qso_list(config): + cat_dir = config["catalog_options"]["input_path"]["cat_dir"] + with open(cat_dir+"galcat_C10/qsocat/gal_C10_file", 'r', encoding='utf-8') as fn1: + fn1_list = fn1.readlines() + bundle_file_list = [line.strip() for line in fn1_list] + with open(cat_dir+"galcat_C10/qsocat/qso_sed_C10_file", 'r', encoding='utf-8') as fn2: + fn2_list = fn2.readlines() + qsosed_file_list = [line.strip() for line in fn2_list] + return bundle_file_list, qsosed_file_list + + +class StarParm(ctypes.Structure): + _fields_ = [ + ('logte', ctypes.c_float), + ('logg', ctypes.c_float), + ('Mass', ctypes.c_float), + ('Av', ctypes.c_float), + ('mu0', ctypes.c_float), + ('Z', ctypes.c_float)] + + +def get_star_cat(config): + idx = pointing_file_list.index(os.path.basename(config['obs_setting']['pointing_file'])) + return_star_path = star_file_list[idx] + return return_star_path + + +def get_bundleIndex(healpixID_ring, bundleOrder=4, healpixOrder=7): + assert NSIDE == 2**healpixOrder + shift = healpixOrder - bundleOrder + shift = 2*shift + + nside_bundle = 2**bundleOrder + nside_healpix = 2**healpixOrder + + healpixID_nest = hp.ring2nest(nside_healpix, healpixID_ring) + bundleID_nest = (healpixID_nest >> shift) + bundleID_ring = hp.nest2ring(nside_bundle, bundleID_nest) + + return bundleID_ring + + +def get_agnsed_file(bundle_file_name, config): + bundle_file_list, qsosed_file_list = get_galaxy_qso_list(config) + return qsosed_file_list[bundle_file_list.index(bundle_file_name)] + + +class Catalog(CatalogBase): + def __init__(self, config, chip, pointing, chip_output, filt, **kwargs): + super().__init__() + self.cat_dir = config["catalog_options"]["input_path"]["cat_dir"] + + self.cosmo = FlatLambdaCDM(H0=67.66, Om0=0.3111) + + self.chip_output = chip_output + self.filt = filt + self.logger = chip_output.logger + + with pkg_resources.path('catalog.data', 'SLOAN_SDSS.g.fits') as filter_path: + self.normF_star = Table.read(str(filter_path)) + + self.config = config + self.chip = chip + self.pointing = pointing + + self.max_size = 0. + + # [TODO] Milky Way extinction + if "enable_mw_ext_gal" in config["catalog_options"] and config["catalog_options"]["enable_mw_ext_gal"]: + if "planck_ebv_map" not in config["catalog_options"]: + raise ValueError( + "Planck dust map must be given to enable Milky Way extinction calculation for galaxies.") + self.mw_ext = ExtinctionMW() + self.mw_ext.init_ext_model(model_name="odonnell") + self.mw_ext.load_Planck_ext( + file_path=config["catalog_options"]["planck_ebv_map"]) + + if "star_cat" in config["catalog_options"]["input_path"] and config["catalog_options"]["input_path"]["star_cat"] and not config["catalog_options"]["galaxy_only"]: + # Get the cloest star catalog file + star_file_name = get_star_cat(self.config) + star_path = os.path.join(config["catalog_options"]["input_path"]["star_cat"], star_file_name) + self.star_path = os.path.join(self.cat_dir, star_path) + self.star_SED_path = config["catalog_options"]["SED_templates_path"]["star_SED"] + self._load_SED_lib_star() + + if "galaxy_cat" in config["catalog_options"]["input_path"] and config["catalog_options"]["input_path"]["galaxy_cat"] and not config["catalog_options"]["star_only"]: + galaxy_dir = config["catalog_options"]["input_path"]["galaxy_cat"] + self.galaxy_path = os.path.join(self.cat_dir, galaxy_dir) + self.galaxy_SED_path = config["catalog_options"]["SED_templates_path"]["galaxy_SED"] + self._load_SED_lib_gals() + self.agn_seds = {} + + if "AGN_SED" in config["catalog_options"]["SED_templates_path"] and not config["catalog_options"]["star_only"]: + self.AGN_SED_path = config["catalog_options"]["SED_templates_path"]["AGN_SED"] + + if "rotateEll" in config["catalog_options"]: + self.rotation = np.radians( + float(config["catalog_options"]["rotateEll"])) + else: + self.rotation = 0. + + # Update output .cat header with catalog specific output columns + self._add_output_columns_header() + + self._get_healpix_list() + self._load() + + def _add_output_columns_header(self): + self.add_hdr = " av stellarmass dm teff logg feh" + self.add_hdr += " bulgemass diskmass detA e1 e2 kappa g1 g2 size galType veldisp " + + self.add_fmt = "%8.4f %8.4f %8.4f %8.4f %8.4f %8.4f" + self.add_fmt += " %8.4f %8.4f %8.4f %8.4f %8.4f %8.4f %8.4f %8.4f %8.4f %4d %8.4f " + self.chip_output.update_output_header( + additional_column_names=self.add_hdr) + + def _get_healpix_list(self): + self.sky_coverage = self.chip.getSkyCoverageEnlarged( + self.chip.img.wcs, margin=0.2) + ra_min, ra_max, dec_min, dec_max = self.sky_coverage.xmin, self.sky_coverage.xmax, self.sky_coverage.ymin, self.sky_coverage.ymax + ra = np.deg2rad(np.array([ra_min, ra_max, ra_max, ra_min])) + dec = np.deg2rad(np.array([dec_max, dec_max, dec_min, dec_min])) + self.pix_list = hp.query_polygon( + NSIDE, + hp.ang2vec(np.radians(90.) - dec, ra), + inclusive=True + ) + if self.logger is not None: + msg = str(("HEALPix List: ", self.pix_list)) + self.logger.info(msg) + else: + print("HEALPix List: ", self.pix_list) + + def load_norm_filt(self, obj): + if obj.type == "star": + return self.normF_star + elif obj.type == "galaxy" or obj.type == "quasar": + # return self.normF_galaxy + return None + else: + return None + + # def _load_SED_lib_star(self): + # self.tempSED_star = h5.File(self.star_SED_path,'r') + def _load_SED_lib_star(self): + # self.tempSED_star = h5.File(self.star_SED_path,'r') + with pkg_resources.path('catalog.data', 'starSpecInterp.so') as ddl_path: + self.starDDL = ctypes.CDLL(str(ddl_path)) + self.starDDL.loadSpecLibs.argtypes = [ctypes.c_char_p, ctypes.c_char_p] + self.starDDL.loadExts.argtypes = [ctypes.c_char_p] + nwv = self.starDDL.loadSpecLibs(str.encode(os.path.join( + self.star_SED_path, 'file_BT-Settl_CSST_wl1000-24000_R1000.par')), str.encode(self.star_SED_path)) + self.starDDL.loadExts(str.encode(os.path.join( + self.star_SED_path, "Ext_odonnell94_R3.1_CSST_wl1000-24000_R1000.fits"))) + self.star_spec_len = nwv + + def _interp_star_sed(self, obj): + spec = (ctypes.c_float*self.star_spec_len)() + wave = (ctypes.c_float*self.star_spec_len)() + self.starDDL.interpSingleStar.argtypes = [ + ctypes.Structure, ctypes.POINTER(ctypes.c_float)] + # s=Star(obj.param['teff'], obj.param['grav''], obj.paramstar['mwmsc_mass'], obj.param['AV'], obj.param['DM'], obj.param['z_met']) + s = StarParm(obj.param['teff'], obj.param['logg'], obj.param['stellarMass'], + obj.param['av'], obj.param['DM'], obj.param['feh']) + + self.starDDL.interpSingleStar(s, spec, wave) + + rv_c = obj.param['rv']/(atcons.c.value/1000.) + Doppler_factor = np.sqrt((1+rv_c)/(1-rv_c)) + wave_RV = wave*Doppler_factor + return wave_RV, np.power(10, spec[:]) + + def _load_SED_lib_gals(self): + pcs = h5.File(os.path.join(self.galaxy_SED_path, "pcs.h5"), "r") + lamb = h5.File(os.path.join(self.galaxy_SED_path, "lamb.h5"), "r") + self.lamb_gal = lamb['lamb'][()] + self.pcs = pcs['pcs'][()] + + def _load_gals(self, gals, pix_id=None, cat_id=0, agnsed_file=""): + ngals = len(gals['ra']) + + # Apply astrometric modeling + ra_arr = gals['ra'][:] + dec_arr = gals['dec'][:] + if self.config["obs_setting"]["enable_astrometric_model"]: + ra_list = ra_arr.tolist() + dec_list = dec_arr.tolist() + pmra_list = np.zeros(ngals).tolist() + pmdec_list = np.zeros(ngals).tolist() + rv_list = np.zeros(ngals).tolist() + parallax_list = [1e-9] * ngals + dt = datetime.utcfromtimestamp(self.pointing.timestamp) + date_str = dt.date().isoformat() + time_str = dt.time().isoformat() + ra_arr, dec_arr = on_orbit_obs_position( + input_ra_list=ra_list, + input_dec_list=dec_list, + input_pmra_list=pmra_list, + input_pmdec_list=pmdec_list, + input_rv_list=rv_list, + input_parallax_list=parallax_list, + input_nstars=ngals, + input_x=self.pointing.sat_x, + input_y=self.pointing.sat_y, + input_z=self.pointing.sat_z, + input_vx=self.pointing.sat_vx, + input_vy=self.pointing.sat_vy, + input_vz=self.pointing.sat_vz, + input_epoch="J2000", + input_date_str=date_str, + input_time_str=time_str + ) + + # [TODO] get Milky Way extinction AVs + if "enable_mw_ext_gal" in self.config["catalog_options"] and self.config["catalog_options"]["enable_mw_ext_gal"]: + MW_Av_arr = self.mw_ext.Av_from_Planck(ra=ra_arr, dec=dec_arr) + else: + MW_Av_arr = np.zeros(len(ra_arr)) + + for igals in range(ngals): + # # (TEST) + # if igals > 100: + # break + + param = self.initialize_param() + param['ra'] = ra_arr[igals] + param['dec'] = dec_arr[igals] + param['ra_orig'] = gals['ra'][igals] + param['dec_orig'] = gals['dec'][igals] + + # [TODO] get Milky Way extinction AVs + param['mw_Av'] = MW_Av_arr[igals] + + if not self.chip.isContainObj(ra_obj=param['ra'], dec_obj=param['dec'], margin=200): + continue + + # param['mag_use_normal'] = gals['mag_csst_%s'%(self.filt.filter_type)][igals] + # if self.filt.is_too_dim(mag=param['mag_use_normal'], margin=self.config["obs_setting"]["mag_lim_margin"]): + # continue + + param['z'] = gals['redshift'][igals] + param['model_tag'] = 'None' + param['g1'] = gals['shear'][igals][0] + param['g2'] = gals['shear'][igals][1] + param['kappa'] = gals['kappa'][igals] + param['e1'] = gals['ellipticity_true'][igals][0] + param['e2'] = gals['ellipticity_true'][igals][1] + + # For shape calculation + param['e1'], param['e2'], param['ell_total'] = self.rotate_ellipticity( + e1=gals['ellipticity_true'][igals][0], + e2=gals['ellipticity_true'][igals][1], + rotation=self.rotation, + unit='radians') + # param['ell_total'] = np.sqrt(param['e1']**2 + param['e2']**2) + if param['ell_total'] > 0.9: + continue + # phi_e = cmath.phase(complex(param['e1'], param['e2'])) + # param['e1'] = param['ell_total'] * np.cos(phi_e + 2*self.rotation) + # param['e2'] = param['ell_total'] * np.sin(phi_e + 2*self.rotation) + + param['e1_disk'] = param['e1'] + param['e2_disk'] = param['e2'] + param['e1_bulge'] = param['e1'] + param['e2_bulge'] = param['e2'] + + param['delta_ra'] = 0 + param['delta_dec'] = 0 + + # Masses + param['bulgemass'] = gals['bulgemass'][igals] + param['diskmass'] = gals['diskmass'][igals] + + param['size'] = gals['size'][igals] + if param['size'] > self.max_size: + self.max_size = param['size'] + + # Sersic index + param['disk_sersic_idx'] = 1. + param['bulge_sersic_idx'] = 4. + + # Sizes + param['bfrac'] = param['bulgemass'] / \ + (param['bulgemass'] + param['diskmass']) + if param['bfrac'] >= 0.6: + param['hlr_bulge'] = param['size'] + param['hlr_disk'] = param['size'] * (1. - param['bfrac']) + else: + param['hlr_disk'] = param['size'] + param['hlr_bulge'] = param['size'] * param['bfrac'] + + # SED coefficients + param['coeff'] = gals['coeff'][igals] + param['detA'] = gals['detA'][igals] + + # Others + param['galType'] = gals['type'][igals] + param['veldisp'] = gals['veldisp'][igals] + + # TEST no redening and no extinction + param['av'] = 0.0 + param['redden'] = 0 + + # TEMP + self.ids += 1 + param['id'] = '%06d' % (int(pix_id)) + \ + '%06d' % (cat_id) + '%08d' % (igals) + + # Is this an Quasar? + param['qsoindex'] = gals['qsoindex'][igals] + if param['qsoindex'] == -1: + param['star'] = 0 # Galaxy + param['agnsed_file'] = "" + obj = Galaxy(param, logger=self.logger) + else: + param_qso = copy.deepcopy(param) + param_qso['star'] = 2 # Quasar + param_qso['agnsed_file'] = agnsed_file + # First add QSO model + obj = Quasar(param_qso, logger=self.logger) + # Need to deal with additional output columns + obj.additional_output_str = self.add_fmt % (0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., + 0, 0.) + self.objs.append(obj) + # Then add host galaxy model + param['star'] = 0 # Galaxy + param['agnsed_file'] = "" + obj = Galaxy(param, logger=self.logger) + + # Need to deal with additional output columns for (host) galaxy + obj.additional_output_str = self.add_fmt % (0., 0., 0., 0., 0., 0., + param['bulgemass'], param['diskmass'], param['detA'], + param['e1'], param['e2'], param['kappa'], param['g1'], param['g2'], param['size'], + param['galType'], param['veldisp']) + + self.objs.append(obj) + + def _load_stars(self, stars, pix_id=None): + nstars = len(stars['RA']) + # Apply astrometric modeling + ra_arr = stars["RA"][:] + dec_arr = stars["DEC"][:] + pmra_arr = stars['pmra'][:] + pmdec_arr = stars['pmdec'][:] + rv_arr = stars['RV'][:] + parallax_arr = stars['parallax'][:] + if self.config["obs_setting"]["enable_astrometric_model"]: + ra_list = ra_arr.tolist() + dec_list = dec_arr.tolist() + pmra_list = pmra_arr.tolist() + pmdec_list = pmdec_arr.tolist() + rv_list = rv_arr.tolist() + parallax_list = parallax_arr.tolist() + dt = datetime.utcfromtimestamp(self.pointing.timestamp) + date_str = dt.date().isoformat() + time_str = dt.time().isoformat() + ra_arr, dec_arr = on_orbit_obs_position( + input_ra_list=ra_list, + input_dec_list=dec_list, + input_pmra_list=pmra_list, + input_pmdec_list=pmdec_list, + input_rv_list=rv_list, + input_parallax_list=parallax_list, + input_nstars=nstars, + input_x=self.pointing.sat_x, + input_y=self.pointing.sat_y, + input_z=self.pointing.sat_z, + input_vx=self.pointing.sat_vx, + input_vy=self.pointing.sat_vy, + input_vz=self.pointing.sat_vz, + input_epoch="J2000", + input_date_str=date_str, + input_time_str=time_str + ) + for istars in range(nstars): + # # (TEST) + # if istars > 100: + # break + + param = self.initialize_param() + param['ra'] = ra_arr[istars] + param['dec'] = dec_arr[istars] + param['ra_orig'] = stars["RA"][istars] + param['dec_orig'] = stars["DEC"][istars] + param['pmra'] = pmra_arr[istars] + param['pmdec'] = pmdec_arr[istars] + param['rv'] = rv_arr[istars] + param['parallax'] = parallax_arr[istars] + if not self.chip.isContainObj(ra_obj=param['ra'], dec_obj=param['dec'], margin=200): + continue + param['mag_use_normal'] = stars['app_SDSS_g'][istars] + self.ids += 1 + + param['id'] = '%06d' % (int(pix_id)) + '%08d' % (istars) + # param['sed_type'] = istars + # param['model_tag'] = '' + param['teff'] = stars['teff'][istars] + param['logg'] = stars['grav'][istars] + param['feh'] = stars['z_met'][istars] + param['stellarMass'] = stars['mass'][istars] + + param['av'] = stars['AV'][istars] + param['DM'] = stars['DM'][istars] + # param['z_met'] = stars['z_met'][istars] + + param['z'] = 0.0 + param['star'] = 1 # Star + + try: + obj = Star(param, logger=self.logger) + except Exception as e: + print(e) + + # Append additional output columns to the .cat file + obj.additional_output_str = self.add_fmt % (param["av"], param['stellarMass'], param['DM'], param['teff'], param['logg'], param['feh'], + 0., 0., 0., 0., 0., 0., 0., 0., 0., -1, 0.) + + self.objs.append(obj) + + def _load(self, **kwargs): + self.objs = [] + self.ids = 0 + + if "star_cat" in self.config["catalog_options"]["input_path"] and self.config["catalog_options"]["input_path"]["star_cat"] and not self.config["catalog_options"]["galaxy_only"]: + star_cat = h5.File(self.star_path, 'r')['star_catalog'] + for pix in self.pix_list: + try: + stars = star_cat[str(pix)] + self._load_stars(stars, pix_id=pix) + del stars + except Exception as e: + self.logger.error(str(e)) + # print(e) + + if "galaxy_cat" in self.config["catalog_options"]["input_path"] and self.config["catalog_options"]["input_path"]["galaxy_cat"] and not self.config["catalog_options"]["star_only"]: + for pix in self.pix_list: + try: + bundleID = get_bundleIndex(pix) + bundle_file = "galaxies_C10_bundle{:06}.h5".format(bundleID) + file_path = os.path.join(self.galaxy_path, bundle_file) + gals_cat = h5.File(file_path, 'r')['galaxies'] + gals = gals_cat[str(pix)] + + # Get corresponding AGN SED file + agnsed_file = get_agnsed_file(bundle_file, self.config) + agnsed_path = os.path.join(self.AGN_SED_path, agnsed_file) + self.agn_seds[agnsed_file] = fits.open(agnsed_path)[0].data + self._load_gals(gals, pix_id=pix, cat_id=bundleID, agnsed_file=agnsed_file) + del gals + except Exception as e: + traceback.print_exc() + self.logger.error(str(e)) + print(e) + + if self.logger is not None: + self.logger.info("maximum galaxy size: %.4f" % (self.max_size)) + self.logger.info("number of objects in catalog: %d" % + (len(self.objs))) + else: + print("number of objects in catalog: ", len(self.objs)) + + def load_sed(self, obj, **kwargs): + if obj.type == 'star': + # _, wave, flux = tag_sed( + # h5file=self.tempSED_star, + # model_tag=obj.param['model_tag'], + # teff=obj.param['teff'], + # logg=obj.param['logg'], + # feh=obj.param['feh'] + # ) + wave, flux = self._interp_star_sed(obj) + elif obj.type == 'galaxy' or obj.type == 'quasar': + factor = 10**(-.4 * self.cosmo.distmod(obj.z).value) + if obj.type == 'galaxy': + flux = np.matmul(self.pcs, obj.coeff) * factor + # if np.any(flux < 0): + # raise ValueError("Glaxy %s: negative SED fluxes"%obj.id) + flux[flux < 0] = 0. + sedcat = np.vstack((self.lamb_gal, flux)).T + sed_data = getObservedSED( + sedCat=sedcat, + redshift=obj.z, + av=obj.param["av"], + redden=obj.param["redden"] + ) + wave, flux = sed_data[0], sed_data[1] + elif obj.type == 'quasar': + flux = self.agn_seds[obj.agnsed_file][int( + obj.qsoindex)] * 1e-17 + flux[flux < 0] = 0. + wave = self.lamb_gal * (1.0 + obj.z) + else: + raise ValueError("Object type not known") + speci = interpolate.interp1d(wave, flux, fill_value=0., bounds_error=False) + lamb = np.arange(2000, 11001+0.5, 0.5) + y = speci(lamb) + + # [TODO] Apply Milky Way extinction + if obj.type != 'star' and ("enable_mw_ext_gal" in self.config["catalog_options"] and self.config["catalog_options"]["enable_mw_ext_gal"]): + y = self.mw_ext.apply_extinction(y, Av=obj.mw_Av) + + # erg/s/cm2/A --> photon/s/m2/A + all_sed = y * lamb / (cons.h.value * cons.c.value) * 1e-13 + sed = Table(np.array([lamb, all_sed]).T, names=('WAVELENGTH', 'FLUX')) + # if obj.type == 'quasar': + # # integrate to get the magnitudes + # sed_photon = np.array([sed['WAVELENGTH'], sed['FLUX']]).T + # sed_photon = galsim.LookupTable(x=np.array(sed_photon[:, 0]), f=np.array( + # sed_photon[:, 1]), interpolant='nearest') + # sed_photon = galsim.SED( + # sed_photon, wave_type='A', flux_type='1', fast=False) + # interFlux = integrate_sed_bandpass( + # sed=sed_photon, bandpass=self.filt.bandpass_full) + # obj.param['mag_use_normal'] = getABMAG( + # interFlux, self.filt.bandpass_full) + # # mag = getABMAG(interFlux, self.filt.bandpass_full) + # # print("mag diff = %.3f"%(mag - obj.param['mag_use_normal'])) + + # integrate to get the magnitudes + if obj.type == 'quasar' or obj.type == 'galaxy': + sed_photon = np.array([sed['WAVELENGTH'], sed['FLUX']]).T + sed_photon = galsim.LookupTable(x=np.array(sed_photon[:, 0]), f=np.array( + sed_photon[:, 1]), interpolant='nearest') + sed_photon = galsim.SED( + sed_photon, wave_type='A', flux_type='1', fast=False) + interFlux = integrate_sed_bandpass( + sed=sed_photon, bandpass=self.filt.bandpass_full) + obj.param['mag_use_normal'] = getABMAG( + interFlux, self.filt.bandpass_full) + # mag = getABMAG(interFlux, self.filt.bandpass_full) + # print("mag diff = %.3f"%(mag - obj.param['mag_use_normal'])) + del wave + del flux + return sed -- GitLab From de26bef08a1a4e3e700c408aa59f6941c44373af Mon Sep 17 00:00:00 2001 From: Chengliang Date: Tue, 26 Nov 2024 17:29:13 +0800 Subject: [PATCH 39/64] bug fixes: change galsim.drawImage method to no_pixel --- observation_sim/mock_objects/Galaxy.py | 2 +- observation_sim/mock_objects/Stamp.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/observation_sim/mock_objects/Galaxy.py b/observation_sim/mock_objects/Galaxy.py index 8d22344..6575035 100755 --- a/observation_sim/mock_objects/Galaxy.py +++ b/observation_sim/mock_objects/Galaxy.py @@ -201,7 +201,7 @@ class Galaxy(MockObject): # gal = self.bfrac * bulge + (1.0 - self.bfrac - kfrac) * disk + kfrac * knots # stamp = gal.drawImage(wcs=chip_wcs_local, method='phot', offset=offset, save_photons=True) - stamp = gal.drawImage(wcs=chip_wcs_local, offset=offset) + stamp = gal.drawImage(method='no_pixel', wcs=chip_wcs_local, offset=offset) if np.sum(np.isnan(stamp.array)) > 0: # ERROR happens return 2, pos_shear diff --git a/observation_sim/mock_objects/Stamp.py b/observation_sim/mock_objects/Stamp.py index d39ace7..c16c26f 100644 --- a/observation_sim/mock_objects/Stamp.py +++ b/observation_sim/mock_objects/Stamp.py @@ -92,7 +92,7 @@ class Stamp(MockObject): else: gal = gal + gal_temp - stamp = gal.drawImage(wcs=chip_wcs_local, offset=offset) + stamp = gal.drawImage(method='no_pixel', wcs=chip_wcs_local, offset=offset) if np.sum(np.isnan(stamp.array)) > 0: # ERROR happens return 2, pos_shear -- GitLab From 4ad7acd0c7618c77e82d86555e9f96e1dac3eb43 Mon Sep 17 00:00:00 2001 From: Chengliang Date: Tue, 26 Nov 2024 17:40:03 +0800 Subject: [PATCH 40/64] update codestyle-PEP8 --- observation_sim/psf/PSFInterp.py | 2 +- observation_sim/psf/_util.py | 19 ++++++++++--------- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/observation_sim/psf/PSFInterp.py b/observation_sim/psf/PSFInterp.py index 7c439bb..25f8c9a 100644 --- a/observation_sim/psf/PSFInterp.py +++ b/observation_sim/psf/PSFInterp.py @@ -360,7 +360,7 @@ class PSFInterp(PSFModel): hoc=self.hoc[twave], hoclist=self.hoclist[twave], PSFCentroidWgt=True) if extrapolate is True: - ccdList = [ 6, 7, 8, 9, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 22, 23, 24, 25] + ccdList = [6, 7, 8, 9, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 22, 23, 24, 25] rr_trim_list = [72, 64, 96, 88, 64, 72, 72, 76, 72, 72, 76, 72, 72, 64, 88, 96, 64, 72] imPSF = psf_extrapolate(imPSF, rr_trim=rr_trim_list[ccdList.index(chip.chipID)], ngg=ngg) diff --git a/observation_sim/psf/_util.py b/observation_sim/psf/_util.py index e57f969..45e1c02 100644 --- a/observation_sim/psf/_util.py +++ b/observation_sim/psf/_util.py @@ -1,6 +1,7 @@ import numpy as np from scipy.interpolate import interp1d + def binningPSF(img, ngg): imgX = img.reshape(ngg, img.shape[0]//ngg, ngg, img.shape[1]//ngg).mean(-1).mean(1) return imgX @@ -31,12 +32,12 @@ def psf_extrapolate(psf, rr_trim=64, ngg=256): # extrapolate PSF if True: xim = np.arange(256)-128 - xim,yim = np.meshgrid(xim, xim) - rim = np.sqrt(xim**2 +yim**2) + xim, yim = np.meshgrid(xim, xim) + rim = np.sqrt(xim**2 + yim**2) # rr_trim = 96 psf_temp = psf - psf_temp[rim > rr_trim] = 0 + psf_temp[rim > rr_trim] = 0 radii, means = radial_average_at_pixel(psf_temp, 128, 128, dr=4) radii_log = np.log(radii[1:]) @@ -47,18 +48,18 @@ def psf_extrapolate(psf, rr_trim=64, ngg=256): # ngg = 1024 xim = np.arange(ngg)-int(ngg/2) - xim,yim = np.meshgrid(xim, xim) - rim = np.sqrt(xim**2 +yim**2) - rim[int(ngg/2),int(ngg/2)] = np.finfo(float).eps # 1e-7 + xim, yim = np.meshgrid(xim, xim) + rim = np.sqrt(xim**2 + yim**2) + rim[int(ngg/2), int(ngg/2)] = np.finfo(float).eps # 1e-7 rim_log = np.log(rim) y_new = f_interp(rim_log) arr = np.zeros([ngg, ngg]) arr[int(ngg/2-128):int(ngg/2+128), int(ngg/2-128):int(ngg/2+128)] = np.log(psf_temp + np.finfo(float).eps) - arr[rim > rr_trim] = 0 - arr[arr==0] = y_new[arr==0] + arr[rim > rr_trim] = 0 + arr[arr == 0] = y_new[arr == 0] psf = np.exp(arr) - psf[rim > int(ngg/2)] = 0 + psf[rim > int(ngg/2)] = 0 imPSF = psf # binningPSF(psf, int(ngg/2)) imPSF = imPSF/np.nansum(imPSF) return imPSF -- GitLab From 2ac619d17cd8045f9d6ca9ed4e535d5ccc520a6e Mon Sep 17 00:00:00 2001 From: Chengliang Date: Wed, 27 Nov 2024 12:44:36 +0800 Subject: [PATCH 41/64] bug fixed --- observation_sim/psf/PSFInterp.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/observation_sim/psf/PSFInterp.py b/observation_sim/psf/PSFInterp.py index 25f8c9a..d21e75f 100644 --- a/observation_sim/psf/PSFInterp.py +++ b/observation_sim/psf/PSFInterp.py @@ -366,7 +366,8 @@ class PSFInterp(PSFModel): if galsimGSObject: if extrapolate is True: - imPSFt = imPSF + imPSFt = np.zeros([ngg+1, ngg+1]) + imPSFt[:-1, :-1] = imPSF else: imPSFt = np.zeros([257, 257]) imPSFt[0:256, 0:256] = imPSF -- GitLab From f4cf5529b8ee48904aafb965f0c822384cf1b203 Mon Sep 17 00:00:00 2001 From: Chengliang Date: Sat, 30 Nov 2024 18:21:31 +0800 Subject: [PATCH 42/64] Optimized memory in add_objects --- catalog/data/starSpecInterp.so | Bin 29304 -> 30184 bytes observation_sim/ObservationSim.py | 6 +++--- observation_sim/sim_steps/add_objects.py | 3 ++- 3 files changed, 5 insertions(+), 4 deletions(-) mode change 100755 => 100644 catalog/data/starSpecInterp.so diff --git a/catalog/data/starSpecInterp.so b/catalog/data/starSpecInterp.so old mode 100755 new mode 100644 index 150d42c5d743164a22eef536f846317e85aae387..11899b46080fb4434dc6b8a20c89a23fd80d94dd GIT binary patch literal 30184 zcmeHQ4SZD9mA{i@G$1g8f<>e{D%pbK5ENWKiYCg#M+J;P6c8AOWI{&sWisKzg2o+Y zm+@uVv}?B1pLXfiRkpj^(zWiQEhRxT!P**K?PA3m?b^;Xsf__^wA9)ExgT%dyv&fH z?(T1Y`{P08+;i?Z=brm@?$^w__iIZR=Q$iqJ^AcI(Qs_SF`poGn3=i&1b z_F2wbkct`>>K-dd3Np9ADGetDC2ofk=LtRqRXoY@^vXm$v%y8u7zM3z=Rl-;y^!m! zO^0*y1-@EBC6@;>$sLn&$E2Ksy|U;OEEH;w1M^*C*nO@d) zakwWfEg8cY#a)iS&*AT%LTlLW6T5aSn>oAn!Kr^=KIQSbzj@gCHw%B>{QU|49&7nY z$>`nZ-PN?BtZ?bpd)V^dUBB>xQ*S^l$C7vd#FS5`>S?EPs^#3#qKiHWEfA(iy7Cl#Gq5lC2GTHCS z!hcN`dQ%oXPiLXul10yoEc6-BhCHUsKFLEkRv z<&u9pIUhV_lKvxvNzXSYaWdPl3drZ%Tw7n~YYO=rLp~q#Em^h9R~cvwYz{Vs0*$Md z-BeRw7g*)rR1*+!nPYqv+x)(&V4c4vcyE9;1{!Mo6#>>1YQ%p6brlWU3DyMaSW`n| zur5?ZC{cZscE#Pkit4+4RsLWNTUp;23RITY1@CDNXf=V_KwYSbK_bxDFl!NOXbx3W z`x{wcTQJ0G>MQ)AKrj@no3$w9-voT~tYTtmV$0XE<#*hU!~zvH!A(t!CmLvMtS5Vr z!A4e9)!5KTI{cL@!L^jQs_GkHq0bj=s;`(g&sWt{;jgP=Rht9QSnIDrdfaS(2-3tF z3N%r$)?Zx-u=(z~y9iWlVHE-7q^hc-roM@%plvfVu`*b5?07@?GP-#yf|p@N6^m=Ty%$ zs^sy11oI_cz$tvTBPoi9WSl%Uk2$jbBQA=40&PqA^XAFHQ6&2V+1?yT?Rzqw_$LH| zn0XbjE=l_g$Mf0C5*PA$ro5UDss7p^+jEbc?MGGP-W4eV-HmRq~LRWP|ajPwK zG#vBUXrYfbsf<-y=+i9p1`GW>3w@h~j%k$nv{>k9kmj@7LLX;R8Edo9T^9Nt3w^wW zzSlyxj$ivMbh(t_Qu{4**_1i`fQ2qyKc{zC=yFKm^ll4X4r!d;W1&me&*{f3^ouw} zeDqrA7hC9Y3;ik!eZWGOL!Bk|Z18LeoLLE+a9#4T9_}yH4d=@~xRpppC@fcXUpL3!HgR%D$iIn`BSQX7oE#AHZ{p;5kbe^= zhlBi^I5`^R-^9tmApa&#js^KQadIfgzlqa8hy0s3ITqw!;i%0IFyD7wx`^@m1U_~{ zI_|XLf3)%2<$r67f7gb;X~SQ$;XkqA&)M*UHvB0Y{?9i2?``;_HoV=2$831ShVQiD z%{IK&h6il;dK+GD!{*SdTfcAuw+!G!b3-y*ou$9+m8MUD|@$ zXU|Fq{!yHNP9A~jpXkv6z4N^r^v3Y0@mf1tkv z{zH!*JcjnEN1y89puHQQQa1{UX!fB;wV_!Zy3x)fjfi0VnI7$m_i^?}oIv;>0p{9u zjART!yh?H(){PjKi$w;w%uh*tDU40$e14ac;z?eZ(iQ(J&eYD+a6nJG;!a&^jC~$% zG(v{!(U(gCd-rISatX5goi(@u$u3?Z+S>3Q0at93c@LU|LU zaNIFZJLzh@64bV~^{KiG_ZO2X{d#m~FDmg^v^?IW4N=W>X{QME&B~H0b9uG?dtLO| zJPOP-B=@g^NcJSw0^Q%aL3BHSk$eA<2xHg&?t{bpNA895$j#i zupj)Gs)-w!-MSO5wH=Upj-<%6_$o-54Jf{&>ky6E@o#*TOdjI#M-UG~E$uqozmduY zt$JqM!v!&gfph zf6%q=7$nw{M7P1ROI#vV?;A<=2frs9+<|>ijS+s@5g?S#hGRgU9YpGVlzHdVbI9uP z+7Pb{mNQNj;N=F2jt!Xp|+IZ zO3a8RVFiU5QJm%s(WiO=tW%-*td6e8G)x9)9n}>XLNo%<9^nG9Irm*d;$87up;?bc z=F*JBkYM8B+YlL>vrg~`A6|8mIGj%)%3$2TFG944`!C#se=Ecq zxR_qiqepx6&R)zT3FHZoPmGTfV-zzdXC>f(@zQHZ!QT2m`d;61GXWN5Z`l z?vrr8gglRWm)0S1s&!;U>yhx7guNUZ?bJ;57|*gU+W1?8yoeia&9R7MWd-R9zCj9< z%C7iJ?-LrM29F6el`SHR(U6uzyPxJ(M4vxYh(Npug4oI!Yw+HI7C3=K4bGg>z^F0P zW(Bp;^TClO^7ep5FxjPD-Aki3@tx%9%ppcrreG#GR(J zl`C!6NsSTV+IXXy3L(*`=5tG9g2Op`IhEbW?L7KIwCzPo--vL@n3}RW2bbldAvWb4 zJ^E7ok7QmnOjSEv)4ns&^rX<#n^Dt-Gtm?jn&KHXO*j)xmkLco88yAI^bE@Bwcqh_ z!l6uta%wpfO@`1^2u)oPH<|@+MTT<$S5i2VgX`9f-J-S*$~Hy)!DuHu_ zUnD$2*%i4f%hnW89&hS7*SRc@f8-LmlweDyOz_DupA>bYH}GAQQP@Rs?dlfAy)&+S;Kil zj>39uw_CJ|vAJ5TI>hnCxn&U@LO6Nnw;_>Zhafj0I>f?6rViobiH}@3=vy={oW4Vx zpSv=$%dU)kGm890E$0p)%j01#kyD4rl!=i##Dbg+%2-B**&zmT%8}#PmC;V>5Z~cC zM$W6zLhUhQhqyaOGctAv?->cxGJMQ)sB5a&6F243(B<^+lV73#MZ@H3yCPHNB!KeI zm5khAh4F)~E4#6u;A|XLCyau8`1D2ScGc-H!eDIwPOw{B_cT`<`^(q zxUm%jW<`kQ6qa=~Rb7FpYCBC;X?=|47MoBKkVp_U~?`VYM z1>yjJrn8uOJKMRITuP{gN=QwFA$ezxlA@$|%dfr+O@~&R@e6;cnhv1`Z$wc(Ax#|T z&BuA_2Fl*ZhRKQ`j}d_?s`XATIJ!Kkx#ut?FgOH*_5Lp z8MR>}$sqsh&Cw*)tcGN>`qS1y)nq(h2TelGs8kXQkWtw2`1QG!YSzr4v`FW$r4jd+ z8$FCw(bnW>v=irAV0~3cbk_e=q8;(~ddV5%XvT2NQbz<;zcu(7OiE`5a z^cERFuGt}mngx8sa<$%tqbk|T;H&tSl-Tr|4+(7d(K4KxPM9yCs05b48k_}i+|@d& zkK~=JxQWb=&fEEU;Cvo`E$7ya^>Li_PT{BEIO`ot%8m8u=VHY;5<6zyAjVmFm)1+E z>o}1T8!I)nm(gb))>49@7SfZLl4I z5^QXZHnd*I{_C5hQXAkRvGV^kH`NXzBE|M)&gRrfzd?(Y<-!IU281yD{<8ktR_L+v zxZU-Wr!!subCd_+`ai}IJ2uvJ=gD(T2TQK`9Yya+(di8GyHk`G?J=z`@0B~2JBcKZ z65C)@+Ch68B2)YHrFWFxURqwdiuUXGP*Fz@(grQ|>&pPF)zOWwE<};Sv#@F%tb(!F zD-Zw1fiui~2rh~Ktn?7CEegL{dXR_BbIJp5(vDM2?4z|0k?)M?51yXC*ur~ikJ z71Mve<>&~z9z}h0X)OfcSeH#jX5O5OaxnOKOb+(~a8WkEMIdnmA7Isp^tjcpy^FMfi#IE})B3XiMLwE^Rj?Sl=zms+&bphPIm;NXA6C zdVYR29&AD}0#U7{@BA?IA(6Ln$W90TyLUX%6;bB^eV;{Z-fy%Mj?qURixptSP81S5 zEW|jz;}sB|27#s!+OE@BW9%P57Qk)f!mS$zdckgJa4xYLG9}hd=NGi2eiswXr}O|g zFb>vr#FIa#s3Yzw*L@vP4gJwsluIhcez_~~;dMFW05;Kz*3c%vrjW3yA-hd?r`hz7 zI$vz^u!uMMaHq zF|txv_7+Z2N32<>6YJsO>Zo|6Wey}_0L(Tm99PJbH?^FfxqgQO&s&1aP|GtI{Slww$aJ`d= zN0nJ$vCV#WK^wjvptah_Y1#TU4zp?IMM`!YvM3{`*kP7d2B-MXR!MS-kI}I?ImMP- zoZ^;TxX;ij{s!fda*BIklRKAGOsDt`9fFUPgEMrBx2M_k$Z4EnWp1fw^<);Oc+sa+ zWpj!z6z5bfxj4o9Kcy<0Q!LI=T`o>>k8p~6$XoS}PjiY#>D+qchA~0`2&ednaEgym zGTTKmXXq4D-BLNl={ef>CptxIf@$94d)^$%<#bN5AvXnCouV`TH$B6Apw(Q9544ig za?yA78Rmk%&A4lU*5carH4IZUh|z5LF{S2olR_}#YhUz@FK0;cpUz(rKX`S;JA&@i zcftykr`c<9>P@zxfS1l1ZLip}v-o=?OM}N+oKLS^zn7ZoPsi~dfiJ+VL33T*Y49O~ z_S4n(qa&*^hF~FWF*Dj@DkZAQ)Q8z1L<(vQB1d7Ma9I-K{qu;L6Z>{wDA%WQq|E{4QrpuMGI!iw7F}`5_Y7hY4F1sxwRT8BSPvMH z<&sW%qiZgVYDGu^{jApOc{5kq#B#8E(qgbyL`>GIInWGpDZj{=cLTpNo zVnb4Fst|j3nrsy#{4>fb|3RY% z=&KTi+KUAHVWJ3j`R!Z&y*~4ok6h8&kFzCkwgk?Wz}XTwTLS+tOQ5K!sEIPB(VKea zdusjLg0;=Ho?xA)vbia=-GjIM)C4@!iYjLoRZjOb2K*J(fy&X$Q{=sNGuzr&U$+^& z^s1ox8h%4niW-fU=6(>2(RoB^r~P@U_Pj$+49oWOIEU~AYO4Kt%5AsV^urfQ|I3nXu7j_ z{;c&7tErqpAEQ|vCF0|mSy%)-mwR{xd&UY@i$RNXY6TLJ@{?hLM7@2%Uq zWkxz>>lP%qJ_Av`3`xmd&5f$`P(G_*1jWOg86IvPH;nS@3v3G^AGHBbu!(1#US@RX zoMK8t2Io=kgqC{)jrE>TJxbQIH4xlf9h%{}r#Tq9jEcYI23`qlK)|_QF1g~yua5cV zBV9Om-P=iVe^)v4wVypXr6hjc7yR=dFDU^Xe~dl+b$VXE;qpf>9J^%ajV0sW{j-T* z{P7z%I4;g#P=oj}_!~HwOzsBkIFwB82kZgt23&GDnd}Ap`m;C?!CbEVxnz>&boV@; zOqKv%hPn7gz_oxafYG;;$;SZm@U503fKTDKGXsG1;KxDyaooFtIkveS7mqo&unlqe z5*WilF53tjdWd(Nd-1qQUvQnbwXlWVFnRu!*G|2h1WA4o{t986n+WnD`Z@}O-XYT> zlyrvh=kH7=%ZRRxbN^-DO=Hi=zuAGLdHh2le+7Bu?*=pDpETpYkNB&PB$NCdXJ-5b zX8fy&pN=x&?*udBpD0lJPa^(lOj2>+no7TcVj1(`ZvyOk1@ZhHXG&fV=jUH?A!njI z%mvSzZzYrbJ!Og~zk%C;wFFy@`0G&aPg0?%__8nOf2knmY&|D@ZvMk=Qy0CX?I3=Y z!r#rNc=IRc3yUCs_BmSuXG`F037jo~vn6o01kRSg*%J6)F9G$wPW66HOxgJJH5pJi zy+f29h0{Aj>7n^Nf8-)N!AlS zfHMYqoC2_hb438Z@!(HczJQ}8{)V*gJc&<|P_i-BAP7<|+baVTB%f5zJ|ppIQjww; z%7m1i9+}=K$*=TKT5tx=^!co_Dsl`082B9Gi9DHO1cI+1_iX3%b38hU59@ zRqB2J)>wKEuzHVwIz8X)59#y*rusoT-D&ohbox0=wYzlsxlFa!bb29E?LM78imCpQ zPDdwE^<|03$1M<^jPx;VK$f$G9d9UxS2^EG5#fBiCtKY&VU5jaE~flXIvt6YSt&}- zc&6?zu*T*i(Y-6I6vcl5Q~t~vn~z-s<;T+L6IrJIlFu$=>b=M5{O~#rR*DGcvq?;~ zKWl70-fPb8u~HPj@~){ka#IEDeg1{h6jk`~ybR@uLw&TuactlMD>wFHBwdXgDi+_f zMQcvkBi$lf%<03+r&j7w+44)@m3N?iOI9IZdot<& zF?jMaw5yjvcVwuSUvT>HdjB;~Yj}J6Sn9FY<2lHHgGM1+d!Rj{JT|<4T@E_EKi>Xc z{9;MBzZai=pp>C&v1M84t3aps=-c1le@7Pn!FqSFZ`?Js=0^P&QF8yPF z7Jk|f%%uOVEcEw5Cp*W;epDcn`GE5ezklG9EP9;CZ>D#-o|CiCFUvyz9O#+Kr!))yO3*LQP@eUifA~EQ_h-@b*OK3UAH`#! zXBaXWt7r^0g_^6XycH~UO@uF0>%&zCb%7?_olsft+l<=`{58JHP<>;Q&)>X_Rn*ru z)C6#?gLiK6b+a-v(ftuYpTDuuzukw^na1t73IT@>zRKp>TDm5}g89H1N@K0{2XTo7 zzgdB5(Z-^}cFgv&6L=*>%Sy|Hwu@7BeOS8A(#t4eQNszD)HWxLJ6a_t0N^H5Tv zZfc-g8|1|ixT-?lYLOnzZ-+=H$*VNdiKn}>LtL_9<4?cdA{F`P{OXJpPBzjd8s_C2 z@GJ<^5kcYCB_XQyt(P^VJjnvE0-rOq$(NGI7YEJ?q%nlXNELZQ5Q-SEP6$FJQF_)zyar-pzH*-iAipY0?20j9q{~pefoj?Bt1F>RVM2#+0762Ak(9qS2xU-Bnqei^v#F_xdEtfVHkk}= z^NdNf-#}}23=8~G>nsI5lCFSS&nw)EfK^_t#}uUVMC+sG4T@HZ0A4Ri!!3W*K8AuD zC0)tc)4v7rwDq9m)%s3Bj})YR5ll(UeG|3+uo5&35vIJ_H&IaSlYoUkq{I5$35516 zRQhVYsNibJtn62O3RWYY_COS_)|Cowl=5Uh@!0df6*SVVattNK^+|7Md{>wE?2I|Pn|YCk|h z`u>6Sv8VqMB54gxeUKitZ_vG7;C6n6EBFT3T=-M+YJZ_8M|oOrQrlJXY9B(~OW7;! zSNp0eT~&|mkR=u+ul6er_&~&?3t)aKc?Aa$W0g18u^WZRkSQqwN>0I#K(@-O{g0uI z>HGpq^YXmQ`8=d{V=Q8unWQGj7 z`)vQnfthp8d*0i5&pGe8e3SFtt1VwT%w%FJWU;TZc#g4!vY_@Jg+Z{{EC=6{*p(bN zJ6<#()jmpqRLra*PcqDul=w>aGSI$;&h-^R1Ec z($%k8>ZfAW#<>u5BR-Sy`ErubE0F&ZK7>0OpGo+P#K#yeMMgF;y9#LwK3C&21)m%6 zxgH;-<8??+z-K%@q|P{euEd8z9zJCH%kjAkpKI{BkZ>`OZTO6kMAQycHx-n9hfBb< zGQLE{6A_P*X^ME?G~~w`(#c6`FVdZCMfDvrX2XYcdct=X zYdE)W&x)xt8z((J`%jOUADaJG&Cka+hu$CkYN+m|g~J<0Z1=8N^`}?g8=bR!=hxZF z_r5y+vi`S0nl>yzBT-ucnhzd8**wY?3W!G_&{eie3HY=G<>d21OEsNQrTg68vL8n!0%1N=jUnQOVjXKkp?~+d~En6 zhqY<&*8q{ma&mA1kgC4#0d5>eitaTIzk+p92SZTfu^4j4uq#-vge(8~L*QHrZ=;iw zKqvqnh12*De6w^MvpAG78XUwYoW$o-iT@pm|DhbnRu0GLr-UJtb32S=y>kB9NDd9* z4Sb0IX~|#de?Q=)PZK#Ugl4HH`LRpk8J8DwaO}%2`QKL{K-(q0gX526JET!3O8C^*KH3RxGZlay!>K zwpBPqS?Usdajkfid0b0}57dO}b9yOR=_oHjRCbShJ4MAiSh3Spfn;$-m6uD< zYGajH>vES>IM>3~%&`r1Wzes<)aCQKs`9;6`LiisNvT_SiAdeHeA%MK_UZZ4^Jg)Y zzLiZauc~xT-Cgc*m({x5Qyp$cah1EoF=HxNpnXl4LFgaFSu&=4HXsC3<&>g-*?4#Dj#i=F0GCsmDjJH1EO5aV(EU9*;pgFrbpNrOql`so zy=BLD?kRj*u3Cr`<;#h0q$`S$`wHdBbwxUO{siU8Wkp(e{s`sCRYeZ*{4HY-AH*W<-2%(4duzD zL^^o>cFL10iL~(iBFd8si5%kjxs)f@5jnu~(_&0Z%{on|18S&khz zYVwM7|NI6NGCgp{H&PGI_W>TZ!+zmi_&RRB2YJ($qeqFVJ6HrX{hK|ssMiC}hEWea z@MIT{9_*wj_#n>(>qXh?dY~$zTmm-WCASo2q3AZ5q>-V>qV2cwHcL|9XowJN#eytxo`@z%F_%$?{ zQu>%t=?LxblEp|a1N4^g9Lv$f!C0BBRw7SV40o&r*%M-S}nLIZXNio&w?ZCW2S zPWQBQ>Ra-)p4}GuuDJxr6**RL+ z61oo@MK)Lz#)uA?FPTeyxJ~roV}FUYRQIAZB3P;Ay%)||Hnx}QmcOAdcMI6OKS!`3 zmBV|%Ce{JMd!Blp9CP@MPohzpV_5jlC#? z4$xW%Z3OrPv~ahz2?N2e^`H;;%+uQUJffuc{GSLs-94HMtn4xQ_x7+|j|R2VH)>&2 z)4%tWspbkaSu-^lHRYjT(dmFSQUOZ>D`ln8flltW(Ra;6;DlC@?`t+v=X2_CYU-)l z$sH48BH>9yPdWstAMu7rDK&?N%t;!ZX=FabX;G;jIqp-oSd5KlifB{#H-lGG?P`IN zJC~$ubt?71fsuri^f4(rq-}cwR-nf!+HH+B{%K3&Y8v!=ttLx-HtfbNBU*yZIbzxO z4(f&ea~fm9d6EW27atVi?|mGNQuZisG?voVp!+lE!h}a(?w0UYLFRt@tYvfOS<9F$ z2e`nr^dEt~m+0vW^tQ~zMnTp`Wb_5H$VXgT_lpqQeilu6;H>5D*0Yw4E!|`+^OLtS zMx(SV@;K@XYcNZ_AE`uZ_)5}OR@nTUWpiu#3So*x2Txg7D=1H#gHA%9T%}L<1h}7C zoB+~1fAmA;V*;p;fA2w7GgFLht!u|6l;U-uuG)pKQSaV@1unYmom9nFkm1GM3qc8| z5<_d2XnBP8;~3fmpqXkeOD8}NZt0VAxxdF6*xT>l+s}NH^`N<89T|=Vi~0k6QS&I& zhC@UJUO`GO0M=q{G#)E4S{u>A0c#^fZCVE{quc6xXaU0;pq>|p#)W1QGH196Z1jNE z4s+r&?(kZaghshJ0xdO!yRZL%Rz>FTqcq6)Y_OJN$l|AXaZ$T2RzT0SlQih~Z-T6h zlj+4BdZ0sZ?aG43MKnxASU0wXpCrTp)>Gz9q(Hzbopz-2GGv2hjiA9C8mH;Fm>^xx z2JQroTX0_7UM>tZ4$b<-46duF=VRx1Jzrmwi8y~tHm!9-=G{gXKjJI~+TsTUZ>#S` z%kai%tM7{^nQEf8dRiSy1ZzAwKAyD2lX>xEK|DD-o?IAD>ha{NcydELxiy|Fk0-0+ z$=Z0bE}m?NC!6BQ{qf|1c=BL8c}OL(bf-Rxop59SEq2YnyK_+T(4>p> zz;D7?BsSphOv&bgh5n|2xy7Wqel2hGo{plDD9>PP`BK=tBR^w!^# zug8o?tDje}oamtC1btyS@yLHcOwe5XdD+s!19LI@#k~&L56p*nQ8~-mQ1kq;Gr&o z-gO6K%dyr-KgljPwdg_KvVp%)7x{hM<2T_D_=c7bre811pfL@Dsh=j-p!s{5km;cY z`q2l_%Q^ZW#*cOCxtU<2Qw#5F9s%@BIyDV!(WzgE4CvIy^$hHQ?m@2lJe~U94B3z_ z32ex9!cYq`qi>K^w{rAB?3zmJ!8-LXZu^|(2*x_K?{l-DPJIif9;9Z$I_h5oJM||^ zGthour#_N78ExQ4{tAsqjrJ{0cV1oPlIqYOF?s@i8?kDTsH_)Ek zJTs56vz86mmRm;^@bulSH0id8N%vO}b=GoIOF%mo)Q<5*qT7ZOtP<7V8WirhU4CM*y*>}&7d!QBd1+0)~3X$Qn;5J}|9O4}1 z;+L1d7?q0&l+5esW({1bu8``HWzyk>_uqxw+5>} z{>+3nC5F`>-+|LgK{NZe!pS0s-Wn&9WvN|(~ zbz~Bnd(r*h2I-sB&EEw5n9NluwdC>h=~mv!3$8&`F%oE>7JmCbX(V(~nvTe|aO7Wk ze=+}bQ3eKy)iA!r+Rf<(u?)O2xq)EOYhwMJrH3Y2Y1`EZb@TuRoOyaC@(1$4(MynA z=($2te-JfP59*^Hgk$9kUFfbPZTS|W3-)7?siL#*CjBEVEe;@473jNGlQV^8XqK8 zlR=`Ui>JCs;wd}>IW^-sYxSn zfX*9VMG4Lu_0WobJy_JKhqUm3qoIp|jfrfyIC!1#F0q6Oi6m6i7dsKMq9BfT_8l(S zOZ|c!v(MCUA+c8K1lY$a53?Xcn&Emyl^h(#&q)s7jvhleB~$w?+|cu zhP2UsnR;o5a&Pqbt?Mdb9g-0KjO$2MDe9Mv^h*NC2Wj$nx$tX+>kEqt*U>R^1ITd9 zTu!^@z>`~f)TIaTkT9Npt?*f%#_~u!d~UW< z5gyjzc;Goo(~}>jfBcbtPm5K*{+J%H%9is^TWW_a*eV88P2Wh_HPXjIk7D)vbMG^W&nMSDJ z;i%+m%aB6vOLua8a~`=xKKJow);5sLhcW08KDP0t>+IOa0&nAuaR7U_80!U)r?8RG)5o=5;VwbQmrdJ*oxgEZKP2 zd6=+&B(V?gc^kQZMvgBJ+Rvjw@K7(90((a$*m|(J3+O=&gELf1JuUR$9*S_Hx}Av@ zF67Rnl+KZc{f>%`Sxd3V4QLNQiZv4{!9#Kv`g?l3O$(g!)c`ut<|?R-g-+E%CtrG< z+^38>HAxd{&23r>YQ`dOU=%{pvdl!w(}$M${1>za>&YZ@j`)^?&sAT94_O#fLj3}v z)2sBDesFWhEpL)eWD==U@Qd&v3zJSirU8QeZ-%_W)NP8AbP{%|8G%Ni^}>n=x+h2{ zS@Zy{9fn;=Yll4So;II=tXF4$;req~7&9BSrtWb{Rujp3Xd>;-HXk`_xr;wIrDutC z(oHaCVOoQnlt9vLiDtqyvX^C zhvo2jMlAPi+85!I!z zp5WO&p{Lbftp0J&))4n>4J7L@eyMsPo=pxx<=M7msM`g5wwRo_XM2Bo26jm8*`CUb zG__|lhcA9L(Tl~DGkCEWEUxgv%%pa3e|mV&<5OvLG3Ud$EqK@*7KckS}J>6l7o)Ltj{rg^5%- zaywrTrj!CTVfl?MP;AtZOSxj0@5j_{06EIE@u))bVZygwro#klh;UE=ewuqfr`^yB zniXTg5XZcmDN|&_*Qi>QVgf%Q?eQ{6tKbxOoghTYmq_V@m?KRwr0{y6k$*UqEHz*m z5!-N*u;>`7>Rm6Bx|4*uLX$M?lNw_K7lBFReErDK82945L-ij!R2-iPJtiGGI5aMY za4y1IQT-aCo^NmCzy6gQpQrOLtgmcGLpJGwQ+mkRxv6k-;g-U?3+-Eu%HQCNKck>I zb0`d1V8{YP78tU?kOhV;Fl2!t3k+Fc$O1za7_z{S1^#L*kn7F$k}?`yvoqIL>8N#8 z)>PVDZd*x>*SE`tD|#xNw!GYusktTB+dNK3ak;Z(IJ4#E&nRO%Jyq^9;L<%mRTU1O ztIBOFt#Fi0W*(MX!t0n@Vk>c#mf|uZx6fAT^x;AtSFuYm_S&jSZFJv{4Y%J6XSt;| zXhXOA;JzIJFLhNo=K?yMtt{NIY%MEw;W{Fz6=+ExBip$)x1-kS-Bd7l+7^&il-xvL z!q!HP|&-{wQ)q9*%oi>-3SDkJm+BB9e!g$p;yGSzrFD4Mc*CyPmi|YN$P=CD)~Xl z)Zf1Tvq=lXx7_ZS`}o3zfaAm1BM(z}bHS9yE+4gQ@1ljH&s;n18!x`Sz;tESyv-;d zj!)OK(P%B=rst#41BjQlM5FZlc57=i+KG7l(P*>}v3@KXrL&ovUWi7&g4lt0Gvf95 zX+j<1mUlsqn8H{QG1Klf%v5VNT{-gNoFR-ZyOVsEe}3nIMAm-h=Wwssr(l zmH#YO{wToXk3^#d3FSBPavRDHWQWQO%2) zjbPyYDa!dhWr~Lm9^tVu9@hZp*LV`m?+#NqSx&A;9#||v`FPlt-(9B4SA9F{{_K#s z@go1lS(-%%BzZ$&$O1za7_z{S1%@mzWPu?I3|Zj+)dK1sO?7W3mU2AYD-$YDcX?7! zdAhrkf<;7(|LHH%BV}IQb4wSWQBe2N;ul#wsQWzeqd6Yb+8IA=<3Zi)IZ5VKdA7{s z`cNJ|{482U33Z=3UGzqw8NXwufWJNB;ZT-{X&*u1b*cXdk>z)UQ&OU_Fy|V(W}T^f z%+-EDvd0a*B5aV16nwT6r1Z8)d6!81@iNAvXD%r$3-GL$=VkR6{-B)a@0aEHVLZ<( zJtdpJx+r#EeUfI^(vPPRZjtd)8LyXdsf>5X_&ymwB;&_r{FIE3%lLH}|3Std$@n7t zlz_tJGQL*Ex5#*@jMvM!RK`1Ge4mUTlJVm*eoDq2)q?+RixGiLKbl-j{cRXVVY}2%l~aF9g@3ige>Vv~SHeyB-G?#EmT=`SR2gm+fN!{h zbxM24?#?!H_@zvZXNCVwBuG!?e-u2#@y9Ub9~ArvBvR@B9N@$!`5xqd_tgw4H{4$o@&p+e{me_k36h8eJ(1f=QDElb*SPmZ-^EV291K_Fd z9iPSF3M(GdIS1Vr-X-m?{N#c(_!Hn@Qr&}|?p}6h8a}%Kx5d?nr5;R!e=rUFNE-O7 zfTy|#{SA&k@V@r0G<^Oj@ssaO@8|G=_ofeneUiF9uiG|@46nM&^EfKQ3_)_7tX$H!!Ajl(E)D~FF{$@k*lmWKaEiJyG0|2=>w zxmqEp*yD5MSFvIoSQ~EIX8?PBHKnEb#VmfqzTH=8$F=cprx*9omsHuyDyp_QD(oe` zDv#IhsHtVeRh88hPF#_nUyvGuU)*nZcs!0>cAS)ZcCk_q4uI_?HIZ-+rOMnj`Q;98Im<8E}dNW3%Bm11Wt3XG4E4Wz^R6@o&=1~f8Z#<}ZPOU>|pND%A zs}z~quc^31(k0VNFn^B`ZLt)++Rv#tM+%~dR8jKPKI>+{h_|9w`$HA0{UA_ykkwIH zM$b=ZZ>H$geoV#dC8p9};i-5L%4x5s@@l`Q;#HEK^d}spzXY?@NT@P`sr{vjZE5VU z>c2_SlO7b*epSV4e@pt~PcUNg6}=NM5~23fvH4NXlcP~)46-?5psh$5>8+AZ#rzpt z3_Cvks%iM1B>EOPiK;l+UMjC*8U;rAYJa5SeNzp>kxbTqcM`oi&rq@2*DEf`^mUS6 zwSV$^Ptr0}0}#^jG`H z&aDE&CZgE4lB)o}MS}D%PyiV#`gKWg!lhu0le#D`FL3aPh2_B;o!_PMA2dFc?t(&m gk1rGP-y{_(xeAwtdlCvSdT6`Act;`1IGO%`0M7uX*Z=?k diff --git a/observation_sim/ObservationSim.py b/observation_sim/ObservationSim.py index 523406e..dbad1fb 100755 --- a/observation_sim/ObservationSim.py +++ b/observation_sim/ObservationSim.py @@ -154,13 +154,12 @@ class Observation(object): chip_output.Log_error(e) chip_output.Log_error("Failed simulation on step: %s" % (step)) break - - chip_output.Log_info("check running:1: pointing-%d chip-%d pid-%d memory-%6.2fGB" % (pointing.id, - chip.chipID, os.getpid(), (psutil.Process(os.getpid()).memory_info().rss / 1024 / 1024 / 1024))) del chip.img del chip.flat_img del chip.prnu_img del chip.shutter_img + chip_output.Log_info("check running:1: pointing-%d chip-%d pid-%d memory-%6.2fGB" % (pointing.id, + chip.chipID, os.getpid(), (psutil.Process(os.getpid()).memory_info().rss / 1024 / 1024 / 1024))) def runExposure_MPI_PointingList(self, pointing_list, chips=None): comm = MPI.COMM_WORLD @@ -239,5 +238,6 @@ class Observation(object): "finished running chip#%d..." % (chip.chipID)) for handler in chip_output.logger.handlers[:]: chip_output.logger.removeHandler(handler) + del chip_output gc.collect() process_counter += nchips_per_fp diff --git a/observation_sim/sim_steps/add_objects.py b/observation_sim/sim_steps/add_objects.py index 0d89b93..afca935 100644 --- a/observation_sim/sim_steps/add_objects.py +++ b/observation_sim/sim_steps/add_objects.py @@ -233,11 +233,12 @@ def add_objects(self, chip, filt, tel, pointing, catalog, obs_param): self.chip_output.Log_error("obj id: %s" % (obj.param['id'])) self.chip_output.Log_error(" e1: %.5f\n e2: %.5f\n size: %f\n bfrac: %f\n detA: %f\n g1: %.5f\n g2: %.5f\n" % ( obj.param['e1'], obj.param['e2'], obj.param['size'], obj.param['bfrac'], obj.param['detA'], obj.param['g1'], obj.param['g2'])) - # Unload SED: obj.unload_SED() del obj # gc.collect() + cat.starDDL.freeGlobeData() + del cat.starDDL if chip.survey_type == "spectroscopic" and not self.overall_config["run_option"]["out_cat_only"] and chip.slsPSFOptim: # from observation_sim.instruments.chip import chip_utils as chip_utils -- GitLab From 7465f1d84cb3e573d8acbc65fc98fddcbcd0577f Mon Sep 17 00:00:00 2001 From: fangyuedong Date: Sun, 1 Dec 2024 09:48:53 +0800 Subject: [PATCH 43/64] * Bug fixes: 1. bright objects were missing in some bands. 2. saturation cut magnitudes were different for the same objects in different bands * Now use exp_time for single exposure for saturation mag calculation. Use for depth exp_time for limiting mag calculation. --- observation_sim/instruments/Filter.py | 7 +++++-- observation_sim/instruments/chip/effects.py | 12 ++++++++++-- observation_sim/mock_objects/CatalogBase.py | 4 ++++ observation_sim/sim_steps/add_objects.py | 11 ++++++++--- 4 files changed, 27 insertions(+), 7 deletions(-) diff --git a/observation_sim/instruments/Filter.py b/observation_sim/instruments/Filter.py index 6a01ca9..a030d37 100755 --- a/observation_sim/instruments/Filter.py +++ b/observation_sim/instruments/Filter.py @@ -45,7 +45,6 @@ class Filter(object): def is_too_bright(self, mag, margin=-2.5): return mag <= self.mag_saturation + margin - # return mag <= 14.0 def is_too_dim(self, mag, margin=1.0): return mag >= self.mag_limiting + margin @@ -143,7 +142,7 @@ class Filter(object): del sl gc.collect() - def update_limit_saturation_mags(self, exptime=150., psf_fwhm=0.1969, skyFn='sky_emiss_hubble_50_50_A.dat', chip=None): + def update_limit_saturation_mags(self, exptime=150., psf_fwhm=0.1969, skyFn='sky_emiss_hubble_50_50_A.dat', chip=None, full_depth_exptime=None): if self.filter_type in _util.SPEC_FILTERS: return if chip is not None: @@ -160,6 +159,10 @@ class Filter(object): self.mag_limiting, self.mag_saturation = _util.calculateLimitMag( psf_fwhm=psf_fwhm, pixelSize=pix_scale, throughputFn=throughput_file, readout=5.0, skyFn=skyFn, darknoise=dark_noise, exTime=exptime, fw=full_well) + + if full_depth_exptime is not None: + self.mag_limiting, _ = _util.calculateLimitMag( + psf_fwhm=psf_fwhm, pixelSize=pix_scale, throughputFn=throughput_file, readout=5.0, skyFn=skyFn, darknoise=dark_noise, exTime=full_depth_exptime, fw=full_well) print("for filter %s: mag_limiting: %.3f, mag_saturation: %.3f" % (self.filter_type, self.mag_limiting, self.mag_saturation)) diff --git a/observation_sim/instruments/chip/effects.py b/observation_sim/instruments/chip/effects.py index bef8da0..7c4c7dc 100644 --- a/observation_sim/instruments/chip/effects.py +++ b/observation_sim/instruments/chip/effects.py @@ -308,15 +308,21 @@ def MakeTrail(imgarr, satuyxtuple, charge, fullwell=9e4, direction='up', trailcu if yi == 0 or yi == imgarr.shape[0]-1: imgarr[yi, xi] = fullwell break + if direction == 'up': if imgarr[yi-1, xi] >= fullwell: imgarr[yi, xi] = fullwell yi -= 1 + # [TEST] charge in the middle + if yi == (imgarr.shape[0] // 2 - 1): + break continue elif direction == 'down': if imgarr[yi+1, xi] >= fullwell: imgarr[yi, xi] = fullwell yi += 1 + if yi == (imgarr.shape[0] // 2): + break continue if aa <= 1: while imgarr[yi, xi] >= fullwell: @@ -325,13 +331,15 @@ def MakeTrail(imgarr, satuyxtuple, charge, fullwell=9e4, direction='up', trailcu imgarr[yi-1, xi] += charge charge = imgarr[yi-1, xi]-fullwell yi -= 1 - if yi < 0: + # if yi < 0: + if yi < 0 or yi == (imgarr.shape[0]//2 - 1): break elif direction == 'down': imgarr[yi+1, xi] += charge charge = imgarr[yi+1, xi]-fullwell yi += 1 - if yi > imgarr.shape[0]: + # if yi > imgarr.shape[0]: + if yi > imgarr.shape[0] or yi == (imgarr.shape[0]//2): break else: # calculate bleeding trail: diff --git a/observation_sim/mock_objects/CatalogBase.py b/observation_sim/mock_objects/CatalogBase.py index 77c9896..106e4e7 100644 --- a/observation_sim/mock_objects/CatalogBase.py +++ b/observation_sim/mock_objects/CatalogBase.py @@ -91,6 +91,10 @@ class CatalogBase(metaclass=ABCMeta): bandpass = target_filt.bandpass_full if norm_filt is not None: + if hasattr(norm_filt, 'bandpass_full'): + norm_filt = Table( + np.array(np.array([norm_filt.bandpass_full.wave_list*10.0, norm_filt.bandpass_full.func( + norm_filt.bandpass_full.wave_list)])).T, names=(['WAVELENGTH', 'SENSITIVITY'])) norm_thr_rang_ids = norm_filt['SENSITIVITY'] > 0.001 else: norm_filt = Table( diff --git a/observation_sim/sim_steps/add_objects.py b/observation_sim/sim_steps/add_objects.py index 0d89b93..9e6177c 100644 --- a/observation_sim/sim_steps/add_objects.py +++ b/observation_sim/sim_steps/add_objects.py @@ -75,7 +75,9 @@ def add_objects(self, chip, filt, tel, pointing, catalog, obs_param): for ifilt in range(len(self.all_filters)): temp_filter = self.all_filters[ifilt] temp_filter.update_limit_saturation_mags( - exptime=pointing.get_full_depth_exptime(temp_filter.filter_type), chip=chip) + exptime=pointing.exp_time, + full_depth_exptime=pointing.get_full_depth_exptime(temp_filter.filter_type), + chip=chip) if temp_filter.filter_type.lower() == self.overall_config["obs_setting"]["cut_in_band"].lower(): cut_filter = temp_filter @@ -109,6 +111,7 @@ def add_objects(self, chip, filt, tel, pointing, catalog, obs_param): try: sed_data = cat.load_sed(obj) norm_filt = cat.load_norm_filt(obj) + obj.sed, obj.param["mag_%s" % filt.filter_type.lower()], obj.param["flux_%s" % filt.filter_type.lower()] = cat.convert_sed( mag=obj.param["mag_use_normal"], sed=sed_data, @@ -116,11 +119,12 @@ def add_objects(self, chip, filt, tel, pointing, catalog, obs_param): norm_filt=norm_filt, mu=obj.mu ) + _, obj.param["mag_%s" % cut_filter.filter_type.lower()], obj.param["flux_%s" % cut_filter.filter_type.lower()] = cat.convert_sed( mag=obj.param["mag_use_normal"], sed=sed_data, target_filt=cut_filter, - norm_filt=norm_filt, + norm_filt=(norm_filt if norm_filt else filt), mu=obj.mu ) except Exception as e: @@ -129,6 +133,7 @@ def add_objects(self, chip, filt, tel, pointing, catalog, obs_param): continue # [TODO] Testing + # print(obj.param["mag_%s" % filt.filter_type.lower()], obj.param["mag_%s" % cut_filter.filter_type.lower()]) # self.chip_output.Log_info("mag_%s = %.3f"%(filt.filter_type.lower(), obj.param["mag_%s"%filt.filter_type.lower()])) # Exclude very bright/dim objects (for now) @@ -136,7 +141,7 @@ def add_objects(self, chip, filt, tel, pointing, catalog, obs_param): mag=obj.param["mag_%s" % self.overall_config["obs_setting"]["cut_in_band"].lower()], margin=self.overall_config["obs_setting"]["mag_sat_margin"]): - self.chip_output.Log_info("obj %s too birght!! mag_%s = %.3f" % ( + self.chip_output.Log_info("obj %s too bright!! mag_%s = %.3f" % ( obj.id, cut_filter.filter_type, obj.param["mag_%s" % self.overall_config["obs_setting"]["cut_in_band"].lower()])) bright_obj += 1 obj.unload_SED() -- GitLab From a3c2766cc55f99a234f2d1ec2f6146ccda3cb019 Mon Sep 17 00:00:00 2001 From: fangyuedong Date: Mon, 2 Dec 2024 16:24:19 +0800 Subject: [PATCH 44/64] * Restrict the saturation bleeding trails and bad columns. So they cannot go across channels. * Add free_mem method in CatalogBase.py. Thus class that inhrits this base class can then implement this function to free used memory. --- catalog/C9_Catalog.py | 4 ++++ observation_sim/instruments/chip/effects.py | 10 +++++++++- observation_sim/mock_objects/CatalogBase.py | 3 +++ observation_sim/sim_steps/add_objects.py | 6 +++--- 4 files changed, 19 insertions(+), 4 deletions(-) diff --git a/catalog/C9_Catalog.py b/catalog/C9_Catalog.py index 7081abc..8dc629f 100644 --- a/catalog/C9_Catalog.py +++ b/catalog/C9_Catalog.py @@ -468,6 +468,10 @@ class Catalog(CatalogBase): 0., 0., 0., 0., 0., 0., 0., 0., 0., -1, 0.) self.objs.append(obj) + + def free_mem(self, **kward): + self.starDDL.freeGlobeData() + del self.starDLL def _load(self, **kwargs): self.objs = [] diff --git a/observation_sim/instruments/chip/effects.py b/observation_sim/instruments/chip/effects.py index 7c4c7dc..0f835d2 100644 --- a/observation_sim/instruments/chip/effects.py +++ b/observation_sim/instruments/chip/effects.py @@ -84,7 +84,7 @@ def BadColumns(GSImage, seed=20240309, chipid=1, logger=None): rgdn = Generator(PCG64(int(seed*1.3))) nbadsecA, nbadsecD = rgn.integers(low=1, high=5, size=2) - collen = rgcollen.integers(low=int(ysize*0.1), high=int(ysize*0.7), size=(nbadsecA+nbadsecD)) + collen = rgcollen.integers(low=int(ysize*0.1), high=int(ysize*0.5), size=(nbadsecA+nbadsecD)) xposit = rgxpos.integers(low=int(xsize*0.05), high=int(xsize*0.95), size=(nbadsecA+nbadsecD)) if logger is not None: logger.info(xposit+1) @@ -350,8 +350,12 @@ def MakeTrail(imgarr, satuyxtuple, charge, fullwell=9e4, direction='up', trailcu imgarr[yi, xi] = fullwell if direction == 'up': yi -= 1 + if yi == (imgarr.shape[0]//2 - 1): + break elif direction == 'down': yi += 1 + if yi == (imgarr.shape[0]//2): + break yy += 1 else: if trail_frac < trailcutfrac: @@ -363,8 +367,12 @@ def MakeTrail(imgarr, satuyxtuple, charge, fullwell=9e4, direction='up', trailcu if direction == 'up': yi -= 1 + if yi == (imgarr.shape[0]//2 - 1): + break elif direction == 'down': yi += 1 + if yi == (imgarr.shape[0]//2): + break yy += 1 return imgarr diff --git a/observation_sim/mock_objects/CatalogBase.py b/observation_sim/mock_objects/CatalogBase.py index 106e4e7..ea94b77 100644 --- a/observation_sim/mock_objects/CatalogBase.py +++ b/observation_sim/mock_objects/CatalogBase.py @@ -12,6 +12,9 @@ class CatalogBase(metaclass=ABCMeta): def __init__(self): pass + def free_mem(self, **kward): + pass + @abstractmethod def load_sed(self, obj, **kward): pass diff --git a/observation_sim/sim_steps/add_objects.py b/observation_sim/sim_steps/add_objects.py index 81cb589..b35325b 100644 --- a/observation_sim/sim_steps/add_objects.py +++ b/observation_sim/sim_steps/add_objects.py @@ -102,6 +102,7 @@ def add_objects(self, chip, filt, tel, pointing, catalog, obs_param): # # [DEBUG] [TODO] # if j >= 10: # break + obj = cat.objs[j] if not self._is_obj_valid(obj): @@ -133,7 +134,6 @@ def add_objects(self, chip, filt, tel, pointing, catalog, obs_param): continue # [TODO] Testing - # print(obj.param["mag_%s" % filt.filter_type.lower()], obj.param["mag_%s" % cut_filter.filter_type.lower()]) # self.chip_output.Log_info("mag_%s = %.3f"%(filt.filter_type.lower(), obj.param["mag_%s"%filt.filter_type.lower()])) # Exclude very bright/dim objects (for now) @@ -242,8 +242,8 @@ def add_objects(self, chip, filt, tel, pointing, catalog, obs_param): obj.unload_SED() del obj # gc.collect() - cat.starDDL.freeGlobeData() - del cat.starDDL + cat.free_mem + del cat if chip.survey_type == "spectroscopic" and not self.overall_config["run_option"]["out_cat_only"] and chip.slsPSFOptim: # from observation_sim.instruments.chip import chip_utils as chip_utils -- GitLab From 6281c265ac46436129fe4c5cd17e824819310921 Mon Sep 17 00:00:00 2001 From: fangyuedong Date: Mon, 2 Dec 2024 16:35:16 +0800 Subject: [PATCH 45/64] add free_mem to C10_Catalog.py --- catalog/C10_Catalog.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/catalog/C10_Catalog.py b/catalog/C10_Catalog.py index 8bbebcb..029add6 100644 --- a/catalog/C10_Catalog.py +++ b/catalog/C10_Catalog.py @@ -499,6 +499,10 @@ class Catalog(CatalogBase): else: print("number of objects in catalog: ", len(self.objs)) + def free_mem(self, **kward): + self.starDDL.freeGlobeData() + del self.starDLL + def load_sed(self, obj, **kwargs): if obj.type == 'star': # _, wave, flux = tag_sed( -- GitLab From c0c380ab5e3b95787fb54031a93aae96d8fe0f32 Mon Sep 17 00:00:00 2001 From: Chengliang Date: Tue, 3 Dec 2024 09:44:21 +0800 Subject: [PATCH 46/64] update codestyle-PEP8 --- catalog/C10_Catalog.py | 8 ++++---- catalog/C9_Catalog.py | 2 +- observation_sim/instruments/Filter.py | 5 ++--- observation_sim/instruments/chip/effects.py | 2 +- observation_sim/mock_objects/CatalogBase.py | 4 +--- observation_sim/sim_steps/add_objects.py | 8 ++++---- 6 files changed, 13 insertions(+), 16 deletions(-) diff --git a/catalog/C10_Catalog.py b/catalog/C10_Catalog.py index 029add6..4648f9b 100644 --- a/catalog/C10_Catalog.py +++ b/catalog/C10_Catalog.py @@ -457,6 +457,10 @@ class Catalog(CatalogBase): self.objs.append(obj) + def free_mem(self, **kward): + self.starDDL.freeGlobeData() + del self.starDLL + def _load(self, **kwargs): self.objs = [] self.ids = 0 @@ -499,10 +503,6 @@ class Catalog(CatalogBase): else: print("number of objects in catalog: ", len(self.objs)) - def free_mem(self, **kward): - self.starDDL.freeGlobeData() - del self.starDLL - def load_sed(self, obj, **kwargs): if obj.type == 'star': # _, wave, flux = tag_sed( diff --git a/catalog/C9_Catalog.py b/catalog/C9_Catalog.py index 8dc629f..1de5392 100644 --- a/catalog/C9_Catalog.py +++ b/catalog/C9_Catalog.py @@ -468,7 +468,7 @@ class Catalog(CatalogBase): 0., 0., 0., 0., 0., 0., 0., 0., 0., -1, 0.) self.objs.append(obj) - + def free_mem(self, **kward): self.starDDL.freeGlobeData() del self.starDLL diff --git a/observation_sim/instruments/Filter.py b/observation_sim/instruments/Filter.py index a030d37..9e5083d 100755 --- a/observation_sim/instruments/Filter.py +++ b/observation_sim/instruments/Filter.py @@ -159,10 +159,9 @@ class Filter(object): self.mag_limiting, self.mag_saturation = _util.calculateLimitMag( psf_fwhm=psf_fwhm, pixelSize=pix_scale, throughputFn=throughput_file, readout=5.0, skyFn=skyFn, darknoise=dark_noise, exTime=exptime, fw=full_well) - + if full_depth_exptime is not None: - self.mag_limiting, _ = _util.calculateLimitMag( - psf_fwhm=psf_fwhm, pixelSize=pix_scale, throughputFn=throughput_file, readout=5.0, skyFn=skyFn, darknoise=dark_noise, exTime=full_depth_exptime, fw=full_well) + self.mag_limiting, _ = _util.calculateLimitMag(psf_fwhm=psf_fwhm, pixelSize=pix_scale, throughputFn=throughput_file, readout=5.0, skyFn=skyFn, darknoise=dark_noise, exTime=full_depth_exptime, fw=full_well) print("for filter %s: mag_limiting: %.3f, mag_saturation: %.3f" % (self.filter_type, self.mag_limiting, self.mag_saturation)) diff --git a/observation_sim/instruments/chip/effects.py b/observation_sim/instruments/chip/effects.py index 0f835d2..12f8ae3 100644 --- a/observation_sim/instruments/chip/effects.py +++ b/observation_sim/instruments/chip/effects.py @@ -339,7 +339,7 @@ def MakeTrail(imgarr, satuyxtuple, charge, fullwell=9e4, direction='up', trailcu charge = imgarr[yi+1, xi]-fullwell yi += 1 # if yi > imgarr.shape[0]: - if yi > imgarr.shape[0] or yi == (imgarr.shape[0]//2): + if yi > imgarr.shape[0] or yi == (imgarr.shape[0]//2): break else: # calculate bleeding trail: diff --git a/observation_sim/mock_objects/CatalogBase.py b/observation_sim/mock_objects/CatalogBase.py index ea94b77..e3896a0 100644 --- a/observation_sim/mock_objects/CatalogBase.py +++ b/observation_sim/mock_objects/CatalogBase.py @@ -95,9 +95,7 @@ class CatalogBase(metaclass=ABCMeta): if norm_filt is not None: if hasattr(norm_filt, 'bandpass_full'): - norm_filt = Table( - np.array(np.array([norm_filt.bandpass_full.wave_list*10.0, norm_filt.bandpass_full.func( - norm_filt.bandpass_full.wave_list)])).T, names=(['WAVELENGTH', 'SENSITIVITY'])) + norm_filt = Table(np.array(np.array([norm_filt.bandpass_full.wave_list*10.0, norm_filt.bandpass_full.func(norm_filt.bandpass_full.wave_list)])).T, names=(['WAVELENGTH', 'SENSITIVITY'])) norm_thr_rang_ids = norm_filt['SENSITIVITY'] > 0.001 else: norm_filt = Table( diff --git a/observation_sim/sim_steps/add_objects.py b/observation_sim/sim_steps/add_objects.py index b35325b..5b9375f 100644 --- a/observation_sim/sim_steps/add_objects.py +++ b/observation_sim/sim_steps/add_objects.py @@ -75,8 +75,8 @@ def add_objects(self, chip, filt, tel, pointing, catalog, obs_param): for ifilt in range(len(self.all_filters)): temp_filter = self.all_filters[ifilt] temp_filter.update_limit_saturation_mags( - exptime=pointing.exp_time, - full_depth_exptime=pointing.get_full_depth_exptime(temp_filter.filter_type), + exptime=pointing.exp_time, + full_depth_exptime=pointing.get_full_depth_exptime(temp_filter.filter_type), chip=chip) if temp_filter.filter_type.lower() == self.overall_config["obs_setting"]["cut_in_band"].lower(): cut_filter = temp_filter @@ -102,7 +102,7 @@ def add_objects(self, chip, filt, tel, pointing, catalog, obs_param): # # [DEBUG] [TODO] # if j >= 10: # break - + obj = cat.objs[j] if not self._is_obj_valid(obj): @@ -112,7 +112,7 @@ def add_objects(self, chip, filt, tel, pointing, catalog, obs_param): try: sed_data = cat.load_sed(obj) norm_filt = cat.load_norm_filt(obj) - + obj.sed, obj.param["mag_%s" % filt.filter_type.lower()], obj.param["flux_%s" % filt.filter_type.lower()] = cat.convert_sed( mag=obj.param["mag_use_normal"], sed=sed_data, -- GitLab From 291df31551770fce18c8b5e9f3341f728b41a668 Mon Sep 17 00:00:00 2001 From: Chengliang Date: Tue, 3 Dec 2024 09:49:38 +0800 Subject: [PATCH 47/64] reset drawImage-method to default --- observation_sim/mock_objects/Galaxy.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/observation_sim/mock_objects/Galaxy.py b/observation_sim/mock_objects/Galaxy.py index 6575035..8d22344 100755 --- a/observation_sim/mock_objects/Galaxy.py +++ b/observation_sim/mock_objects/Galaxy.py @@ -201,7 +201,7 @@ class Galaxy(MockObject): # gal = self.bfrac * bulge + (1.0 - self.bfrac - kfrac) * disk + kfrac * knots # stamp = gal.drawImage(wcs=chip_wcs_local, method='phot', offset=offset, save_photons=True) - stamp = gal.drawImage(method='no_pixel', wcs=chip_wcs_local, offset=offset) + stamp = gal.drawImage(wcs=chip_wcs_local, offset=offset) if np.sum(np.isnan(stamp.array)) > 0: # ERROR happens return 2, pos_shear -- GitLab From 13fa53066f42e86bd8b367c7652d005e52334a11 Mon Sep 17 00:00:00 2001 From: fangyuedong Date: Sat, 7 Dec 2024 04:30:22 +0800 Subject: [PATCH 48/64] pep8 reformat, replace the return of failed position retrivel to None --- observation_sim/mock_objects/MockObject.py | 2 ++ observation_sim/psf/FieldDistortion.py | 3 ++- observation_sim/sim_steps/add_objects.py | 9 ++++++--- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/observation_sim/mock_objects/MockObject.py b/observation_sim/mock_objects/MockObject.py index 8ef57be..d88b6f3 100755 --- a/observation_sim/mock_objects/MockObject.py +++ b/observation_sim/mock_objects/MockObject.py @@ -78,6 +78,8 @@ class MockObject(object): (self.posImg.x, self.posImg.y), flush=True) self.posImg, self.fd_shear = fdmodel.get_distorted( chip=chip, pos_img=self.posImg) + if self.posImg is None: + return None, None, None, None, None if verbose: print("After field distortion:\n") print("x = %.2f, y = %.2f\n" % diff --git a/observation_sim/psf/FieldDistortion.py b/observation_sim/psf/FieldDistortion.py index 506bbba..ff5faea 100644 --- a/observation_sim/psf/FieldDistortion.py +++ b/observation_sim/psf/FieldDistortion.py @@ -62,7 +62,8 @@ class FieldDistortion(object): the distored position. """ if not self.isContainObj_FD(chip=chip, pos_img=pos_img): - return galsim.PositionD(-1, -1), None + # return galsim.PositionD(-1, -1), None + return None, None if not img_rot: img_rot = np.radians(self.img_rot) else: diff --git a/observation_sim/sim_steps/add_objects.py b/observation_sim/sim_steps/add_objects.py index 5b9375f..b901c97 100644 --- a/observation_sim/sim_steps/add_objects.py +++ b/observation_sim/sim_steps/add_objects.py @@ -16,7 +16,8 @@ def _is_obj_valid(self, obj): # Currently there's no parameter checks for 'calib' type return True pos_keys = ['ra', 'dec'] - shape_keys = ['hlr_bulge', 'hlr_disk', 'e1_disk', 'e2_disk', 'e1_bulge', 'e2_bulge'] + shape_keys = ['hlr_bulge', 'hlr_disk', + 'e1_disk', 'e2_disk', 'e1_bulge', 'e2_bulge'] if any(obj.param[key] == -999. for key in pos_keys): msg = 'One or more positional information (ra, dec) is missing' self.chip_output.Log_error(msg) @@ -76,7 +77,8 @@ def add_objects(self, chip, filt, tel, pointing, catalog, obs_param): temp_filter = self.all_filters[ifilt] temp_filter.update_limit_saturation_mags( exptime=pointing.exp_time, - full_depth_exptime=pointing.get_full_depth_exptime(temp_filter.filter_type), + full_depth_exptime=pointing.get_full_depth_exptime( + temp_filter.filter_type), chip=chip) if temp_filter.filter_type.lower() == self.overall_config["obs_setting"]["cut_in_band"].lower(): cut_filter = temp_filter @@ -175,7 +177,8 @@ def add_objects(self, chip, filt, tel, pointing, catalog, obs_param): # [TODO] For now, only consider objects which their centers (after field distortion) are projected within the focal plane # Otherwise they will be considered missed objects # if pos_img.x == -1 or pos_img.y == -1 or (not chip.isContainObj(x_image=pos_img.x, y_image=pos_img.y, margin=0.)): - if pos_img.x == -1 or pos_img.y == -1: + # if pos_img.x == -1 or pos_img.y == -1: + if pos_img is None: self.chip_output.Log_info('obj_ra = %.6f, obj_dec = %.6f, obj_ra_orig = %.6f, obj_dec_orig = %.6f' % ( obj.ra, obj.dec, obj.ra_orig, obj.dec_orig)) self.chip_output.Log_error("Object missed: %s" % (obj.id)) -- GitLab From 31e95ea1f23c8eaf157860218bd14d28575f709a Mon Sep 17 00:00:00 2001 From: Chengliang Date: Wed, 11 Dec 2024 09:30:44 +0800 Subject: [PATCH 49/64] typo fixed --- observation_sim/sim_steps/add_objects.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/observation_sim/sim_steps/add_objects.py b/observation_sim/sim_steps/add_objects.py index b901c97..06bd712 100644 --- a/observation_sim/sim_steps/add_objects.py +++ b/observation_sim/sim_steps/add_objects.py @@ -245,7 +245,7 @@ def add_objects(self, chip, filt, tel, pointing, catalog, obs_param): obj.unload_SED() del obj # gc.collect() - cat.free_mem + cat.free_mem() del cat if chip.survey_type == "spectroscopic" and not self.overall_config["run_option"]["out_cat_only"] and chip.slsPSFOptim: -- GitLab From 4574f13f52ab372b4ecfda23ef0dadf8a932da33 Mon Sep 17 00:00:00 2001 From: Chengliang Date: Wed, 11 Dec 2024 19:19:07 +0800 Subject: [PATCH 50/64] typo fixed --- catalog/C10_Catalog.py | 2 +- catalog/C9_Catalog.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/catalog/C10_Catalog.py b/catalog/C10_Catalog.py index 4648f9b..3168b17 100644 --- a/catalog/C10_Catalog.py +++ b/catalog/C10_Catalog.py @@ -459,7 +459,7 @@ class Catalog(CatalogBase): def free_mem(self, **kward): self.starDDL.freeGlobeData() - del self.starDLL + del self.starDDL def _load(self, **kwargs): self.objs = [] diff --git a/catalog/C9_Catalog.py b/catalog/C9_Catalog.py index 1de5392..bcc15c9 100644 --- a/catalog/C9_Catalog.py +++ b/catalog/C9_Catalog.py @@ -471,7 +471,7 @@ class Catalog(CatalogBase): def free_mem(self, **kward): self.starDDL.freeGlobeData() - del self.starDLL + del self.starDDL def _load(self, **kwargs): self.objs = [] -- GitLab From 2fb27ea21e355377896966c94ceeb04ecf090dfc Mon Sep 17 00:00:00 2001 From: zhangxin Date: Mon, 30 Dec 2024 15:14:52 +0800 Subject: [PATCH 51/64] add led flat to image and sls; add brighter source psf for sls --- catalog/C9_Catalog.py | 5 +- observation_sim/ObservationSim.py | 2 + .../instruments/chip/chip_utils.py | 6 ++ observation_sim/mock_objects/FlatLED.py | 18 +++++- observation_sim/mock_objects/Galaxy.py | 11 ++-- observation_sim/mock_objects/MockObject.py | 17 ++++-- observation_sim/psf/PSFInterpSLS.py | 19 ++++++- observation_sim/psf/_util.py | 55 +++++++++++++++++++ 8 files changed, 117 insertions(+), 16 deletions(-) diff --git a/catalog/C9_Catalog.py b/catalog/C9_Catalog.py index bcc15c9..6f3a7f4 100644 --- a/catalog/C9_Catalog.py +++ b/catalog/C9_Catalog.py @@ -470,8 +470,9 @@ class Catalog(CatalogBase): self.objs.append(obj) def free_mem(self, **kward): - self.starDDL.freeGlobeData() - del self.starDDL + if not self.config["catalog_options"]["galaxy_only"]: + self.starDDL.freeGlobeData() + del self.starDDL def _load(self, **kwargs): self.objs = [] diff --git a/observation_sim/ObservationSim.py b/observation_sim/ObservationSim.py index dbad1fb..e3ca988 100755 --- a/observation_sim/ObservationSim.py +++ b/observation_sim/ObservationSim.py @@ -62,6 +62,8 @@ class Observation(object): # Get flat, shutter, and PRNU images chip.flat_img, _ = chip_utils.get_flat( img=chip.img, seed=int(self.config["random_seeds"]["seed_flat"])) + if chip.chipID <= 30: + chip.flat_img = chip.flat_img*chip_utils.get_innerflat(chip = chip) if chip.chipID > 30: chip.shutter_img = np.ones_like(chip.img.array) else: diff --git a/observation_sim/instruments/chip/chip_utils.py b/observation_sim/instruments/chip/chip_utils.py index 542ed12..1f476f2 100644 --- a/observation_sim/instruments/chip/chip_utils.py +++ b/observation_sim/instruments/chip/chip_utils.py @@ -172,6 +172,12 @@ def get_flat(img, seed): flat_normal = flat_img / np.mean(flat_img.array) return flat_img, flat_normal +def get_innerflat(chip = None, filt = None): + from observation_sim.mock_objects import FlatLED + led_obj = FlatLED(chip, filt) + flat_img = led_obj.getInnerFlat() + return flat_img + def add_cosmic_rays(img, chip, exptime=150, seed=0): cr_map, cr_event_num = effects.produceCR_Map( diff --git a/observation_sim/mock_objects/FlatLED.py b/observation_sim/mock_objects/FlatLED.py index a99e955..d2d2c6f 100755 --- a/observation_sim/mock_objects/FlatLED.py +++ b/observation_sim/mock_objects/FlatLED.py @@ -50,6 +50,8 @@ fluxLED = {'LED1': 15, 'LED2': 15, 'LED3': 12.5, 'LED4': 9, 'LED5': 9, # 'LED14': 10} mirro_eff = {'GU': 0.61, 'GV': 0.8, 'GI': 0.8} + +bandtoLed = {'NUV':['LED1','LED2'], 'u':['LED13','LED14'], 'g':['LED3','LED4','LED5'], 'r':['LED6','LED7'], 'i':['LED8'], 'z':['LED9','LED10'], 'y':['LED10'], 'GU':['LED1','LED2','LED13','LED14'], 'GV':['LED3','LED4','LED5','LED6'], 'GI':['LED7','LED8','LED9','LED10']} # mirro_eff = {'GU':1, 'GV':1, 'GI':1} @@ -69,10 +71,19 @@ class FlatLED(MockObject): with pkg_resources.path('observation_sim.mock_objects.data.led', "") as ledDir: self.flatDir = ledDir.as_posix() + + def getInnerFlat(self): + ledflats = bandtoLed[self.chip.filter_type] + iFlat = np.zeros([self.chip.npix_y, self.chip.npix_x]) + for nled in ledflats: + iFlat = iFlat + self.getLEDImage(led_type=nled, LED_Img_flag =False) + iFlat = iFlat / len(ledflats) + return iFlat + ### # return LED flat, e/s ### - def getLEDImage(self, led_type='LED1'): + def getLEDImage(self, led_type='LED1', LED_Img_flag =True): # cwave = cwaves[led_type] flat = fits.open(os.path.join(self.flatDir, 'model_' + cwaves_name[led_type] + 'nm.fits')) @@ -102,7 +113,10 @@ class FlatLED(MockObject): N[self.chip.npix_y * i:self.chip.npix_y * (i + 1), self.chip.npix_x * j:self.chip.npix_x * (j + 1)]), method='linear') U = U/np.mean(U) - flatImage = U*fluxLED[led_type]*1000 + + flatImage = U + if LED_Img_flag: + flatImage = flatImage*fluxLED[led_type]*1000 gc.collect() return flatImage diff --git a/observation_sim/mock_objects/Galaxy.py b/observation_sim/mock_objects/Galaxy.py index 8d22344..13ae922 100755 --- a/observation_sim/mock_objects/Galaxy.py +++ b/observation_sim/mock_objects/Galaxy.py @@ -335,18 +335,21 @@ class Galaxy(MockObject): pos_img_local[1] = pos_img.y - y_start nnx = 0 nny = 0 - for order in ["A", "B"]: + for order in ["B", "A"]: + EXTRA = False + if self.getMagFilter(filt) <= filt.mag_saturation-2.: + EXTRA = True psf, pos_shear = psf_model.get_PSF( - chip, pos_img_local=pos_img_local, bandNo=i+1, galsimGSObject=True, g_order=order, grating_split_pos=grating_split_pos) + chip, pos_img_local=pos_img_local, bandNo=i+1, galsimGSObject=True, g_order=order, grating_split_pos=grating_split_pos, extrapolate = EXTRA, ngg=3072) star_p = galsim.Convolve(psf, gal) if nnx == 0: galImg = star_p.drawImage( - wcs=chip_wcs_local, offset=offset) + wcs=chip_wcs_local, offset=offset, method='no_pixel') nnx = galImg.xmax - galImg.xmin + 1 nny = galImg.ymax - galImg.ymin + 1 else: galImg = star_p.drawImage( - nx=nnx, ny=nny, wcs=chip_wcs_local, offset=offset) + nx=nnx, ny=nny, wcs=chip_wcs_local, offset=offset, method='no_pixel') galImg.setOrigin(0, 0) # n1 = np.sum(np.isinf(galImg.array)) # n2 = np.sum(np.isnan(galImg.array)) diff --git a/observation_sim/mock_objects/MockObject.py b/observation_sim/mock_objects/MockObject.py index d88b6f3..2fb1455 100755 --- a/observation_sim/mock_objects/MockObject.py +++ b/observation_sim/mock_objects/MockObject.py @@ -386,7 +386,7 @@ class MockObject(object): sedNormFactor = 1. if self.getMagFilter(filt) <= 15: - folding_threshold = 5.e-4 + folding_threshold = 5.e-8 else: folding_threshold = 5.e-3 gsp = galsim.GSParams(folding_threshold=folding_threshold) @@ -445,19 +445,24 @@ class MockObject(object): pos_img_local[1] = pos_img.y - y_start nnx = 0 nny = 0 - for order in ["A", "B"]: + for order in ["B", "A"]: + EXTRA = False + if self.getMagFilter(filt) <= filt.mag_saturation-2.: + EXTRA = True + nnx = 2048 + nny = 2048 psf, pos_shear = psf_model.get_PSF( - chip, pos_img_local=pos_img_local, bandNo=i+1, galsimGSObject=True, g_order=order, grating_split_pos=grating_split_pos) + chip, pos_img_local=pos_img_local, bandNo=i+1, galsimGSObject=True, g_order=order, grating_split_pos=grating_split_pos, extrapolate=EXTRA, ngg=3072) # star_p = galsim.Convolve(psf, star) star_p = psf.withFlux(tel.pupil_area * exptime) if nnx == 0: starImg = star_p.drawImage( - wcs=chip_wcs_local, offset=offset) + wcs=chip_wcs_local, offset=offset, method='no_pixel') nnx = starImg.xmax - starImg.xmin + 1 nny = starImg.ymax - starImg.ymin + 1 else: starImg = star_p.drawImage( - nx=nnx, ny=nny, wcs=chip_wcs_local, offset=offset) + nx=nnx, ny=nny, wcs=chip_wcs_local, offset=offset, method='no_pixel') # n1 = np.sum(np.isinf(starImg.array)) # n2 = np.sum(np.isnan(starImg.array)) # if n1>0 or n2 > 0: @@ -470,7 +475,7 @@ class MockObject(object): psf, pos_shear = psf_model.get_PSF(chip=chip, pos_img=pos_img) # star_p = galsim.Convolve(psf, star) star_p = psf.withFlux(tel.pupil_area * exptime) - starImg = star_p.drawImage(wcs=chip_wcs_local, offset=offset) + starImg = star_p.drawImage(wcs=chip_wcs_local, offset=offset, method='no_pixel') starImg.setOrigin(0, 0) for order in ["A", "B", "C", "D", "E"]: starImg_List.append(starImg) diff --git a/observation_sim/psf/PSFInterpSLS.py b/observation_sim/psf/PSFInterpSLS.py index 1d1f4b5..7b45096 100644 --- a/observation_sim/psf/PSFInterpSLS.py +++ b/observation_sim/psf/PSFInterpSLS.py @@ -23,6 +23,9 @@ from astropy.modeling.models import Gaussian2D from scipy import signal, interpolate import datetime import gc +from astropy.io import fits + +from observation_sim.psf._util import psf_extrapolate, psf_extrapolate1 # from jax import numpy as jnp LOG_DEBUG = False # ***# @@ -354,7 +357,7 @@ class PSFInterpSLS(PSFModel): convImg = convImg/np.sum(convImg) return convImg - def get_PSF(self, chip, pos_img_local=[1000, 1000], bandNo=1, galsimGSObject=True, folding_threshold=5.e-3, g_order='A', grating_split_pos=3685): + def get_PSF(self, chip, pos_img_local=[1000, 1000], bandNo=1, galsimGSObject=True, folding_threshold=5.e-3, g_order='A', grating_split_pos=3685, extrapolate=False, ngg=2048): """ Get the PSF at a given image position @@ -435,6 +438,9 @@ class PSFInterpSLS(PSFModel): # PSF_int_trans[ids_szero] = 0 # print(PSF_int_trans[ids_szero].shape[0],PSF_int_trans.shape) PSF_int_trans = PSF_int_trans/np.sum(PSF_int_trans) + PSF_int_trans = PSF_int_trans-np.min(PSF_int_trans) + PSF_int_trans = PSF_int_trans/np.sum(PSF_int_trans) + # fits.writeto('/home/zhangxin/CSST_SIM/CSST_sim_develop/psf_test/psf.fits',PSF_int_trans) # DEBGU ids_szero = PSF_int_trans < 0 n01 = PSF_int_trans[ids_szero].shape[0] @@ -444,7 +450,16 @@ class PSFInterpSLS(PSFModel): if n1 > 0 or n2 > 0: print("DEBUG: PSFInterpSLS, inf:%d, nan:%d, 0 num:%d" % (n1, n2, n01)) - + if extrapolate is True: + # for rep_i in np.arange(0, 2, 1): + # PSF_int_trans[rep_i,:] = 1e9*pow(10,rep_i) + # PSF_int_trans[-1-rep_i,:] = 1e9*pow(10,rep_i) + # PSF_int_trans[:,rep_i] = 1e9*pow(10,rep_i) + # PSF_int_trans[:,-1-rep_i] = 1e9*pow(10,rep_i) + + PSF_int_trans = psf_extrapolate1(PSF_int_trans, ngg=ngg) + # fits.writeto('/home/zhangxin/CSST_SIM/CSST_sim_develop/psf_test/psf_large.fits',PSF_int_trans) + #### # from astropy.io import fits # fits.writeto(str(bandNo) + '_' + g_order+ '_psf_o.fits', PSF_int_trans) diff --git a/observation_sim/psf/_util.py b/observation_sim/psf/_util.py index 45e1c02..b9efcc1 100644 --- a/observation_sim/psf/_util.py +++ b/observation_sim/psf/_util.py @@ -63,3 +63,58 @@ def psf_extrapolate(psf, rr_trim=64, ngg=256): imPSF = psf # binningPSF(psf, int(ngg/2)) imPSF = imPSF/np.nansum(imPSF) return imPSF + +def psf_extrapolate1(psf, rr_trim=64, ngg=256): + # ngg = 256 + # extrapolate PSF + if True: + psf_enlar = np.zeros([ngg, ngg]) + psf_enlar[int(ngg/2-128):int(ngg/2+128), int(ngg/2-128):int(ngg/2+128)] = psf + xim = np.arange(ngg)-ngg/2 + xim, yim = np.meshgrid(xim, xim) + rim = np.sqrt(xim**2 + yim**2) + + psf_temp = psf_enlar + # psf_temp[rim >= rr_trim] = 0 + psf_temp[rim >= ngg/2-2] = np.finfo(float).eps + radii, means = radial_average_at_pixel(psf_temp, ngg/2, ngg/2, dr=2) + + radii_log = np.log(radii[1:]) + # radii_log = radii[1:] + means_log = np.log(means[1:]) + + + # xim = np.arange(256)-128 + # xim, yim = np.meshgrid(xim, xim) + # rim = np.sqrt(xim**2 + yim**2) + + # # rr_trim = 96 + # psf_temp = psf + # psf_temp[rim > rr_trim] = 0 + # radii, means = radial_average_at_pixel(psf_temp, 128, 128, dr=4) + + # radii_log = np.log10(radii[1:]) + # # radii_log = radii[1:] + # means_log = np.log10(means[1:]) + + finite_mask = np.isfinite(means_log) + f_interp = interp1d(radii_log[finite_mask][:-1], means_log[finite_mask][:-1], kind='linear', fill_value="extrapolate") + + # ngg = 1024 + # xim = np.arange(ngg)-int(ngg/2) + # xim, yim = np.meshgrid(xim, xim) + # rim = np.sqrt(xim**2 + yim**2) + # rim[int(ngg/2), int(ngg/2)] = np.finfo(float).eps # 1e-7 + rim_log = np.log(rim) + y_new = f_interp(rim_log) + + arr = np.zeros([ngg, ngg]) + arr[int(ngg/2-128):int(ngg/2+128), int(ngg/2-128):int(ngg/2+128)] = np.log(psf + np.finfo(float).eps) + arr[rim > 128-2] = 0 + arr[arr == 0] = y_new[arr == 0] + psf_n = np.exp(arr) + # psf_n[int(ngg/2-128):int(ngg/2+128), int(ngg/2-128):int(ngg/2+128)] = psf + # psf[rim > int(ngg/2)] = 0 + imPSF = psf_n # binningPSF(psf, int(ngg/2)) + # imPSF = imPSF/np.nansum(imPSF) + return imPSF -- GitLab From 95e6759c87e65b1a383b8163018f5dba136d34bf Mon Sep 17 00:00:00 2001 From: Chengliang Date: Wed, 8 Jan 2025 14:40:19 +0800 Subject: [PATCH 52/64] bug fixed --- observation_sim/sim_steps/add_pattern_noise.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/observation_sim/sim_steps/add_pattern_noise.py b/observation_sim/sim_steps/add_pattern_noise.py index dd487ce..aa8d61a 100644 --- a/observation_sim/sim_steps/add_pattern_noise.py +++ b/observation_sim/sim_steps/add_pattern_noise.py @@ -22,7 +22,7 @@ def add_poisson_and_dark(self, chip, filt, tel, pointing, catalog, obs_param): if obs_param["add_dark"] is True: chip.img, _ = chip_utils.add_poisson(img=chip.img, chip=chip, - exptime=pointing.exp_time, + exptime=exptime, poisson_noise=chip.poisson_noise, InputDark=None) else: -- GitLab From a4587b619fc212f0e94b1f4173222ef4796e481f Mon Sep 17 00:00:00 2001 From: Chengliang Date: Wed, 8 Jan 2025 14:53:33 +0800 Subject: [PATCH 53/64] update codestyle-PEP8 --- observation_sim/ObservationSim.py | 2 +- observation_sim/instruments/chip/chip_utils.py | 3 ++- observation_sim/mock_objects/FlatLED.py | 9 ++++----- observation_sim/mock_objects/Galaxy.py | 2 +- observation_sim/psf/PSFInterpSLS.py | 12 ++++++------ observation_sim/psf/_util.py | 2 +- 6 files changed, 15 insertions(+), 15 deletions(-) diff --git a/observation_sim/ObservationSim.py b/observation_sim/ObservationSim.py index e3ca988..7d35a66 100755 --- a/observation_sim/ObservationSim.py +++ b/observation_sim/ObservationSim.py @@ -63,7 +63,7 @@ class Observation(object): chip.flat_img, _ = chip_utils.get_flat( img=chip.img, seed=int(self.config["random_seeds"]["seed_flat"])) if chip.chipID <= 30: - chip.flat_img = chip.flat_img*chip_utils.get_innerflat(chip = chip) + chip.flat_img = chip.flat_img*chip_utils.get_innerflat(chip=chip) if chip.chipID > 30: chip.shutter_img = np.ones_like(chip.img.array) else: diff --git a/observation_sim/instruments/chip/chip_utils.py b/observation_sim/instruments/chip/chip_utils.py index 1f476f2..4225521 100644 --- a/observation_sim/instruments/chip/chip_utils.py +++ b/observation_sim/instruments/chip/chip_utils.py @@ -172,7 +172,8 @@ def get_flat(img, seed): flat_normal = flat_img / np.mean(flat_img.array) return flat_img, flat_normal -def get_innerflat(chip = None, filt = None): + +def get_innerflat(chip=None, filt=None): from observation_sim.mock_objects import FlatLED led_obj = FlatLED(chip, filt) flat_img = led_obj.getInnerFlat() diff --git a/observation_sim/mock_objects/FlatLED.py b/observation_sim/mock_objects/FlatLED.py index d2d2c6f..65fa988 100755 --- a/observation_sim/mock_objects/FlatLED.py +++ b/observation_sim/mock_objects/FlatLED.py @@ -51,7 +51,7 @@ fluxLED = {'LED1': 15, 'LED2': 15, 'LED3': 12.5, 'LED4': 9, 'LED5': 9, mirro_eff = {'GU': 0.61, 'GV': 0.8, 'GI': 0.8} -bandtoLed = {'NUV':['LED1','LED2'], 'u':['LED13','LED14'], 'g':['LED3','LED4','LED5'], 'r':['LED6','LED7'], 'i':['LED8'], 'z':['LED9','LED10'], 'y':['LED10'], 'GU':['LED1','LED2','LED13','LED14'], 'GV':['LED3','LED4','LED5','LED6'], 'GI':['LED7','LED8','LED9','LED10']} +bandtoLed = {'NUV': ['LED1', 'LED2'], 'u': ['LED13', 'LED14'], 'g': ['LED3', 'LED4', 'LED5'], 'r': ['LED6', 'LED7'], 'i': ['LED8'], 'z': ['LED9', 'LED10'], 'y': ['LED10'], 'GU': ['LED1', 'LED2', 'LED13', 'LED14'], 'GV': ['LED3', 'LED4', 'LED5', 'LED6'], 'GI': ['LED7', 'LED8', 'LED9', 'LED10']} # mirro_eff = {'GU':1, 'GV':1, 'GI':1} @@ -71,19 +71,18 @@ class FlatLED(MockObject): with pkg_resources.path('observation_sim.mock_objects.data.led', "") as ledDir: self.flatDir = ledDir.as_posix() - def getInnerFlat(self): ledflats = bandtoLed[self.chip.filter_type] iFlat = np.zeros([self.chip.npix_y, self.chip.npix_x]) for nled in ledflats: - iFlat = iFlat + self.getLEDImage(led_type=nled, LED_Img_flag =False) - iFlat = iFlat / len(ledflats) + iFlat = iFlat + self.getLEDImage(led_type=nled, LED_Img_flag=False) + iFlat = iFlat/len(ledflats) return iFlat ### # return LED flat, e/s ### - def getLEDImage(self, led_type='LED1', LED_Img_flag =True): + def getLEDImage(self, led_type='LED1', LED_Img_flag=True): # cwave = cwaves[led_type] flat = fits.open(os.path.join(self.flatDir, 'model_' + cwaves_name[led_type] + 'nm.fits')) diff --git a/observation_sim/mock_objects/Galaxy.py b/observation_sim/mock_objects/Galaxy.py index 13ae922..4fe034f 100755 --- a/observation_sim/mock_objects/Galaxy.py +++ b/observation_sim/mock_objects/Galaxy.py @@ -340,7 +340,7 @@ class Galaxy(MockObject): if self.getMagFilter(filt) <= filt.mag_saturation-2.: EXTRA = True psf, pos_shear = psf_model.get_PSF( - chip, pos_img_local=pos_img_local, bandNo=i+1, galsimGSObject=True, g_order=order, grating_split_pos=grating_split_pos, extrapolate = EXTRA, ngg=3072) + chip, pos_img_local=pos_img_local, bandNo=i+1, galsimGSObject=True, g_order=order, grating_split_pos=grating_split_pos, extrapolate=EXTRA, ngg=3072) star_p = galsim.Convolve(psf, gal) if nnx == 0: galImg = star_p.drawImage( diff --git a/observation_sim/psf/PSFInterpSLS.py b/observation_sim/psf/PSFInterpSLS.py index 7b45096..b62cfed 100644 --- a/observation_sim/psf/PSFInterpSLS.py +++ b/observation_sim/psf/PSFInterpSLS.py @@ -452,14 +452,14 @@ class PSFInterpSLS(PSFModel): (n1, n2, n01)) if extrapolate is True: # for rep_i in np.arange(0, 2, 1): - # PSF_int_trans[rep_i,:] = 1e9*pow(10,rep_i) - # PSF_int_trans[-1-rep_i,:] = 1e9*pow(10,rep_i) - # PSF_int_trans[:,rep_i] = 1e9*pow(10,rep_i) - # PSF_int_trans[:,-1-rep_i] = 1e9*pow(10,rep_i) + # PSF_int_trans[rep_i,:] = 1e9*pow(10,rep_i) + # PSF_int_trans[-1-rep_i,:] = 1e9*pow(10,rep_i) + # PSF_int_trans[:,rep_i] = 1e9*pow(10,rep_i) + # PSF_int_trans[:,-1-rep_i] = 1e9*pow(10,rep_i) PSF_int_trans = psf_extrapolate1(PSF_int_trans, ngg=ngg) - # fits.writeto('/home/zhangxin/CSST_SIM/CSST_sim_develop/psf_test/psf_large.fits',PSF_int_trans) - + # fits.writeto('/home/zhangxin/CSST_SIM/CSST_sim_develop/psf_test/psf_large.fits',PSF_int_trans) + #### # from astropy.io import fits # fits.writeto(str(bandNo) + '_' + g_order+ '_psf_o.fits', PSF_int_trans) diff --git a/observation_sim/psf/_util.py b/observation_sim/psf/_util.py index b9efcc1..1b7aa10 100644 --- a/observation_sim/psf/_util.py +++ b/observation_sim/psf/_util.py @@ -64,6 +64,7 @@ def psf_extrapolate(psf, rr_trim=64, ngg=256): imPSF = imPSF/np.nansum(imPSF) return imPSF + def psf_extrapolate1(psf, rr_trim=64, ngg=256): # ngg = 256 # extrapolate PSF @@ -83,7 +84,6 @@ def psf_extrapolate1(psf, rr_trim=64, ngg=256): # radii_log = radii[1:] means_log = np.log(means[1:]) - # xim = np.arange(256)-128 # xim, yim = np.meshgrid(xim, xim) # rim = np.sqrt(xim**2 + yim**2) -- GitLab From 7dcab00eaef4d0655ef5989b866897c7bbc1f306 Mon Sep 17 00:00:00 2001 From: zhangxin Date: Tue, 21 Jan 2025 13:19:02 +0800 Subject: [PATCH 54/64] fig bug: large mermory in the model FlatLED --- observation_sim/mock_objects/FlatLED.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/observation_sim/mock_objects/FlatLED.py b/observation_sim/mock_objects/FlatLED.py index 65fa988..f47967b 100755 --- a/observation_sim/mock_objects/FlatLED.py +++ b/observation_sim/mock_objects/FlatLED.py @@ -75,7 +75,7 @@ class FlatLED(MockObject): ledflats = bandtoLed[self.chip.filter_type] iFlat = np.zeros([self.chip.npix_y, self.chip.npix_x]) for nled in ledflats: - iFlat = iFlat + self.getLEDImage(led_type=nled, LED_Img_flag=False) + iFlat = iFlat + self.getLEDImage1(led_type=nled, LED_Img_flag=False) iFlat = iFlat/len(ledflats) return iFlat @@ -123,7 +123,7 @@ class FlatLED(MockObject): # return LED flat, e/s ### - def getLEDImage1(self, led_type='LED1'): + def getLEDImage1(self, led_type='LED1', LED_Img_flag =True): # cwave = cwaves[led_type] flat = fits.open(os.path.join(self.flatDir, 'model_' + cwaves_name[led_type] + 'nm.fits')) @@ -155,7 +155,9 @@ class FlatLED(MockObject): N[0:self.chip.npix_y, 0:self.chip.npix_x]), method='linear') U = U/np.mean(U) - flatImage = U*fluxLED[led_type]*1000 + flatImage = U + if LED_Img_flag: + flatImage = U*fluxLED[led_type]*1000 gc.collect() return flatImage -- GitLab From 31aa8b60e13d5f1ab9bd4791065397939f358e36 Mon Sep 17 00:00:00 2001 From: zhangxin Date: Tue, 21 Jan 2025 14:03:22 +0800 Subject: [PATCH 55/64] pep8 --- observation_sim/mock_objects/FlatLED.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/observation_sim/mock_objects/FlatLED.py b/observation_sim/mock_objects/FlatLED.py index f47967b..9560ab9 100755 --- a/observation_sim/mock_objects/FlatLED.py +++ b/observation_sim/mock_objects/FlatLED.py @@ -123,7 +123,7 @@ class FlatLED(MockObject): # return LED flat, e/s ### - def getLEDImage1(self, led_type='LED1', LED_Img_flag =True): + def getLEDImage1(self, led_type='LED1', LED_Img_flag=True): # cwave = cwaves[led_type] flat = fits.open(os.path.join(self.flatDir, 'model_' + cwaves_name[led_type] + 'nm.fits')) -- GitLab From d0440a4a6b4d888ea85de99886f66cecb4b8eeec Mon Sep 17 00:00:00 2001 From: zhangxin Date: Tue, 21 Jan 2025 16:17:01 +0800 Subject: [PATCH 56/64] griddata memery issue, use nearest replace linear --- observation_sim/mock_objects/FlatLED.py | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/observation_sim/mock_objects/FlatLED.py b/observation_sim/mock_objects/FlatLED.py index 9560ab9..e8a8952 100755 --- a/observation_sim/mock_objects/FlatLED.py +++ b/observation_sim/mock_objects/FlatLED.py @@ -129,31 +129,24 @@ class FlatLED(MockObject): cwaves_name[led_type] + 'nm.fits')) xlen = flat[0].header['NAXIS1'] ylen = 601 - i = self.chip.rowID - 1 j = self.chip.colID - 1 - x = np.linspace(0, self.chip.npix_x, int(xlen/6.)) y = np.linspace(0, self.chip.npix_y, int(ylen/5.)) xx, yy = np.meshgrid(x, y) - a1 = flat[0].data[int(ylen*i/5.):int(ylen*i/5.)+int(ylen/5.), int(xlen*j/6.):int(xlen*j/6.)+int(xlen/6.)] # z = np.sin((xx+yy+xx**2+yy**2)) - # fInterp = interp2d(xx, yy, z, kind='linear') - + # fInterp = interp2d(xx, yy, z, kind='linear') X_ = np.hstack((xx.flatten()[:, None], yy.flatten()[:, None])) Z_ = a1.flatten() - n_x = np.arange(0, self.chip.npix_x, 1) n_y = np.arange(0, self.chip.npix_y, 1) - - M, N = np.meshgrid(n_x, n_y) - + M, N = np.meshgrid(n_x, n_y) U = griddata(X_, Z_, ( M[0:self.chip.npix_y, 0:self.chip.npix_x], N[0:self.chip.npix_y, 0:self.chip.npix_x]), - method='linear') + method='nearest').astype(np.float32) U = U/np.mean(U) flatImage = U if LED_Img_flag: -- GitLab From b2d70812d9bcdc07ae35ae286ebadc4feb551939 Mon Sep 17 00:00:00 2001 From: zhangxin Date: Tue, 21 Jan 2025 16:22:10 +0800 Subject: [PATCH 57/64] pep8 --- observation_sim/mock_objects/FlatLED.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/observation_sim/mock_objects/FlatLED.py b/observation_sim/mock_objects/FlatLED.py index e8a8952..4eed6db 100755 --- a/observation_sim/mock_objects/FlatLED.py +++ b/observation_sim/mock_objects/FlatLED.py @@ -137,16 +137,16 @@ class FlatLED(MockObject): a1 = flat[0].data[int(ylen*i/5.):int(ylen*i/5.)+int(ylen/5.), int(xlen*j/6.):int(xlen*j/6.)+int(xlen/6.)] # z = np.sin((xx+yy+xx**2+yy**2)) - # fInterp = interp2d(xx, yy, z, kind='linear') + # fInterp = interp2d(xx, yy, z, kind='linear') X_ = np.hstack((xx.flatten()[:, None], yy.flatten()[:, None])) Z_ = a1.flatten() n_x = np.arange(0, self.chip.npix_x, 1) n_y = np.arange(0, self.chip.npix_y, 1) - M, N = np.meshgrid(n_x, n_y) + M, N = np.meshgrid(n_x, n_y) U = griddata(X_, Z_, ( M[0:self.chip.npix_y, 0:self.chip.npix_x], N[0:self.chip.npix_y, 0:self.chip.npix_x]), - method='nearest').astype(np.float32) + method='nearest').astype(np.float32) U = U/np.mean(U) flatImage = U if LED_Img_flag: -- GitLab From 0b7b3a2b2a64d6e2246e8f1fc438e2cdeac23f84 Mon Sep 17 00:00:00 2001 From: zhangxin Date: Tue, 21 Jan 2025 16:55:22 +0800 Subject: [PATCH 58/64] griddata memory issue --- observation_sim/mock_objects/FlatLED.py | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/observation_sim/mock_objects/FlatLED.py b/observation_sim/mock_objects/FlatLED.py index 4eed6db..2179b27 100755 --- a/observation_sim/mock_objects/FlatLED.py +++ b/observation_sim/mock_objects/FlatLED.py @@ -143,10 +143,21 @@ class FlatLED(MockObject): n_x = np.arange(0, self.chip.npix_x, 1) n_y = np.arange(0, self.chip.npix_y, 1) M, N = np.meshgrid(n_x, n_y) - U = griddata(X_, Z_, ( - M[0:self.chip.npix_y, 0:self.chip.npix_x], - N[0:self.chip.npix_y, 0:self.chip.npix_x]), - method='nearest').astype(np.float32) + x_seg_len = 4 + y_seg_len = 8 + x_seg = int(self.chip.npix_x/x_seg_len) + y_seg = int(self.chip.npix_y/y_seg_len) + U = np.zeros([self.chip.npix_y,self.chip.npix_x],dtype=np.float32) + for y_seg_i in np.arange(y_seg_len): + for x_seg_i in np.arange(x_seg_len): + U[y_seg_i*y_seg:(y_seg_i+1)*y_seg, x_seg_i*x_seg:(x_seg_i+1)*x_seg] = griddata(X_, Z_, ( + M[y_seg_i*y_seg:(y_seg_i+1)*y_seg, x_seg_i*x_seg:(x_seg_i+1)*x_seg], + N[y_seg_i*y_seg:(y_seg_i+1)*y_seg, x_seg_i*x_seg:(x_seg_i+1)*x_seg]), + method='linear') + # U = griddata(X_, Z_, ( + # M[0:self.chip.npix_y, 0:self.chip.npix_x], + # N[0:self.chip.npix_y, 0:self.chip.npix_x]), + # method='nearest').astype(np.float32) U = U/np.mean(U) flatImage = U if LED_Img_flag: -- GitLab From f02054bf21712294d379ae8c88e948cf673f1512 Mon Sep 17 00:00:00 2001 From: zhangxin Date: Tue, 21 Jan 2025 17:00:38 +0800 Subject: [PATCH 59/64] pep8 --- observation_sim/mock_objects/FlatLED.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/observation_sim/mock_objects/FlatLED.py b/observation_sim/mock_objects/FlatLED.py index 2179b27..bfa58ff 100755 --- a/observation_sim/mock_objects/FlatLED.py +++ b/observation_sim/mock_objects/FlatLED.py @@ -147,13 +147,13 @@ class FlatLED(MockObject): y_seg_len = 8 x_seg = int(self.chip.npix_x/x_seg_len) y_seg = int(self.chip.npix_y/y_seg_len) - U = np.zeros([self.chip.npix_y,self.chip.npix_x],dtype=np.float32) + U = np.zeros([self.chip.npix_y, self.chip.npix_x], dtype=np.float32) for y_seg_i in np.arange(y_seg_len): for x_seg_i in np.arange(x_seg_len): U[y_seg_i*y_seg:(y_seg_i+1)*y_seg, x_seg_i*x_seg:(x_seg_i+1)*x_seg] = griddata(X_, Z_, ( - M[y_seg_i*y_seg:(y_seg_i+1)*y_seg, x_seg_i*x_seg:(x_seg_i+1)*x_seg], - N[y_seg_i*y_seg:(y_seg_i+1)*y_seg, x_seg_i*x_seg:(x_seg_i+1)*x_seg]), - method='linear') + M[y_seg_i*y_seg:(y_seg_i+1)*y_seg, x_seg_i*x_seg:(x_seg_i+1)*x_seg], + N[y_seg_i*y_seg:(y_seg_i+1)*y_seg, x_seg_i*x_seg:(x_seg_i+1)*x_seg]), + method='linear') # U = griddata(X_, Z_, ( # M[0:self.chip.npix_y, 0:self.chip.npix_x], # N[0:self.chip.npix_y, 0:self.chip.npix_x]), -- GitLab From 111198f3d8870cd6eff6454c3ce5cc79d2370711 Mon Sep 17 00:00:00 2001 From: zhangxin Date: Tue, 21 Jan 2025 17:07:26 +0800 Subject: [PATCH 60/64] pep8 --- observation_sim/mock_objects/FlatLED.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/observation_sim/mock_objects/FlatLED.py b/observation_sim/mock_objects/FlatLED.py index bfa58ff..2674aa5 100755 --- a/observation_sim/mock_objects/FlatLED.py +++ b/observation_sim/mock_objects/FlatLED.py @@ -150,10 +150,7 @@ class FlatLED(MockObject): U = np.zeros([self.chip.npix_y, self.chip.npix_x], dtype=np.float32) for y_seg_i in np.arange(y_seg_len): for x_seg_i in np.arange(x_seg_len): - U[y_seg_i*y_seg:(y_seg_i+1)*y_seg, x_seg_i*x_seg:(x_seg_i+1)*x_seg] = griddata(X_, Z_, ( - M[y_seg_i*y_seg:(y_seg_i+1)*y_seg, x_seg_i*x_seg:(x_seg_i+1)*x_seg], - N[y_seg_i*y_seg:(y_seg_i+1)*y_seg, x_seg_i*x_seg:(x_seg_i+1)*x_seg]), - method='linear') + U[y_seg_i*y_seg:(y_seg_i+1)*y_seg, x_seg_i*x_seg:(x_seg_i+1)*x_seg] = griddata(X_, Z_, (M[y_seg_i*y_seg:(y_seg_i+1)*y_seg, x_seg_i*x_seg:(x_seg_i+1)*x_seg], N[y_seg_i*y_seg:(y_seg_i+1)*y_seg, x_seg_i*x_seg:(x_seg_i+1)*x_seg]), method='linear') # U = griddata(X_, Z_, ( # M[0:self.chip.npix_y, 0:self.chip.npix_x], # N[0:self.chip.npix_y, 0:self.chip.npix_x]), -- GitLab From 0f700d3128b2196f9c4a01bb5ace4ae86d5c908c Mon Sep 17 00:00:00 2001 From: zhangxin Date: Fri, 9 May 2025 09:33:59 +0800 Subject: [PATCH 61/64] delete file --- .../instruments/data/sls_conf/._CSST_GI1.conf | Bin 4096 -> 0 bytes .../instruments/data/sls_conf/._CSST_GV1.conf | Bin 4096 -> 0 bytes 2 files changed, 0 insertions(+), 0 deletions(-) delete mode 100755 observation_sim/instruments/data/sls_conf/._CSST_GI1.conf delete mode 100755 observation_sim/instruments/data/sls_conf/._CSST_GV1.conf diff --git a/observation_sim/instruments/data/sls_conf/._CSST_GI1.conf b/observation_sim/instruments/data/sls_conf/._CSST_GI1.conf deleted file mode 100755 index afe84e13b241509cf960068981c9e7033f876e86..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4096 zcmZQz6=P>$Vqox1Ojhs@R)|o50+1L3ClDJkFz{^v(m+1nBL)UWIUt(=a103v0xDsI z=wMg?WDB5a0m{L|rIPb=^%4sTa#Hnj5{pYpi&Ill5=&B*1A;+%_$zG^K(ypq8$%F1 z3PwXEOnfZB%IXRUIIjLzS3Q0MMdD+0eFjUu&rcnJ4_lgXI-2eXo D_Dd*N diff --git a/observation_sim/instruments/data/sls_conf/._CSST_GV1.conf b/observation_sim/instruments/data/sls_conf/._CSST_GV1.conf deleted file mode 100755 index 13acd34cf4136ed3b41e0ff98d97019deda0d631..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4096 zcmZQz6=P>$Vqox1Ojhs@R)|o50+1L3ClDJkFz{^v(m+1nBL)UWIUt(=a103v0xDsI z=wMg?WDB5a0m{L|rIPb=^%4sTa#Hnj5{pYpi&Ill5=&B*1A;+%tdEN)fanGBS%5ic*X7 zON)|I71HvHvK2D(N>cMmGV}8ib8;#ba#GVu6q0fh^Rj_`VW_SlO`-Z9?iCpZx&QwG DA$};W -- GitLab From 877d689f90464f4c88d2fe9e411851293d00db8a Mon Sep 17 00:00:00 2001 From: zhangxin Date: Fri, 9 May 2025 18:06:30 +0800 Subject: [PATCH 62/64] new formation msc-I0 data --- config/config_overall.yaml | 1 + observation_sim/_util.py | 7 ++++--- observation_sim/config/ChipOutput.py | 3 ++- observation_sim/config/Pointing.py | 16 +++++++++------- observation_sim/config/header/ImageHeader.py | 14 ++++++++------ .../config/header/csst_msc_l0_ms.fits | 2 +- observation_sim/sim_steps/prepare_headers.py | 4 +++- run_sim.py | 5 ++++- 8 files changed, 32 insertions(+), 20 deletions(-) diff --git a/config/config_overall.yaml b/config/config_overall.yaml index d22dc68..97ac2bc 100644 --- a/config/config_overall.yaml +++ b/config/config_overall.yaml @@ -12,6 +12,7 @@ # ok to pass either way or both, as long as they are consistent work_dir: "/public/home/fangyuedong/project/workplace/" run_name: "ext_on" +data_set: "csst-msc-c9-25sqdeg-v_test" # Project cycle and run counter are used to name the outputs project_cycle: 9 diff --git a/observation_sim/_util.py b/observation_sim/_util.py index 47c91ce..5735fca 100755 --- a/observation_sim/_util.py +++ b/observation_sim/_util.py @@ -26,7 +26,7 @@ def parse_args(): return parser.parse_args() -def generate_pointing_list(config, pointing_filename=None, data_dir=None): +def generate_pointing_list(config, pointing_filename=None, data_dir=None, dataset = ''): pointing_list = [] # Only valid when the pointing list does not contain time stamp column @@ -63,7 +63,7 @@ def generate_pointing_list(config, pointing_filename=None, data_dir=None): continue line = line.strip() columns = line.split() - pointing = Pointing(obs_config_file=obs_config_file) + pointing = Pointing(obs_config_file=obs_config_file, dataset=dataset) pointing.read_pointing_columns(columns=columns, id=ipoint) t += delta_t * 60. pointing_list.append(pointing) @@ -83,7 +83,8 @@ def generate_pointing_list(config, pointing_filename=None, data_dir=None): timestamp=t, exp_time=exp_time, pointing_type='SCI', - obs_config_file=obs_config_file + obs_config_file=obs_config_file, + dataset=dataset ) t += delta_t * 60. pointing_list.append(pointing) diff --git a/observation_sim/config/ChipOutput.py b/observation_sim/config/ChipOutput.py index 7db5e12..9d66359 100755 --- a/observation_sim/config/ChipOutput.py +++ b/observation_sim/config/ChipOutput.py @@ -28,7 +28,8 @@ class ChipOutput(object): sat_vel=[pointing.sat_vx, pointing.sat_vy, pointing.sat_vz], project_cycle=self.config["project_cycle"], run_counter=self.config["run_counter"], - chip_name=self.chip_label) + chip_name=self.chip_label, + dataset=pointing.dataset) obs_id = _util.get_obs_id(img_type=self.pointing_type, project_cycle=config["project_cycle"], run_counter=config[ "run_counter"], pointing_id=pointing.obs_id, pointing_type_code=pointing.pointing_type_code) diff --git a/observation_sim/config/Pointing.py b/observation_sim/config/Pointing.py index a7692ae..3015e72 100644 --- a/observation_sim/config/Pointing.py +++ b/observation_sim/config/Pointing.py @@ -10,7 +10,7 @@ import observation_sim.instruments._util as _util class Pointing(object): - def __init__(self, id=0, ra=0., dec=0., img_pa=0., timestamp=1621915200, sat_x=0., sat_y=0., sat_z=0., sun_x=0., sun_y=0., sun_z=0., sat_vx=0., sat_vy=0., sat_vz=0., exp_time=150., pointing_type='SCI', pointing_type_code='101', pointing_id='00000001', obs_config_file=None, t_shutter_open=1.3, t_shutter_close=1.3): + def __init__(self, id=0, ra=0., dec=0., img_pa=0., timestamp=1621915200, sat_x=0., sat_y=0., sat_z=0., sun_x=0., sun_y=0., sun_z=0., sat_vx=0., sat_vy=0., sat_vz=0., exp_time=150., pointing_type='SCI', pointing_type_code='101', pointing_id='00000001', obs_config_file=None, t_shutter_open=1.3, t_shutter_close=1.3, dataset = 'csst-msc-c9-25sqdeg-v3'): self.id = id self.ra = ra self.dec = dec @@ -41,6 +41,7 @@ class Pointing(object): self.pointing_type_code = self.obs_param["obs_type_code"] if self.obs_param["obs_id"]: self.obs_id = str(self.obs_param["obs_id"]) + self.dataset = dataset def get_full_depth_exptime(self, filter_type): if self.survey_field_type == 'WIDE': @@ -114,12 +115,13 @@ class Pointing(object): os.makedirs(run_dir, exist_ok=True) except OSError: pass - self.output_prefix = get_obs_id( - img_type=self.pointing_type, - project_cycle=overall_config["project_cycle"], - run_counter=overall_config["run_counter"], - pointing_id=self.obs_id, - pointing_type_code=self.pointing_type_code) + # self.output_prefix = get_obs_id( + # img_type=self.pointing_type, + # project_cycle=overall_config["project_cycle"], + # run_counter=overall_config["run_counter"], + # pointing_id=self.obs_id, + # pointing_type_code=self.pointing_type_code) + self.output_prefix = self.pointing_type_code+self.obs_id self.output_dir = os.path.join(run_dir, self.output_prefix) if not os.path.exists(self.output_dir): try: diff --git a/observation_sim/config/header/ImageHeader.py b/observation_sim/config/header/ImageHeader.py index 25a2867..f4d536f 100644 --- a/observation_sim/config/header/ImageHeader.py +++ b/observation_sim/config/header/ImageHeader.py @@ -355,7 +355,7 @@ def WCS_def(xlen=9216, ylen=9232, gapy=898.0, gapx1=534, gapx2=1309, ra_ref=60, # TODO project_cycle is temporary, is not in header defined, delete in future -def generatePrimaryHeader(xlen=9216, ylen=9232, pointing_id='00000001', pointing_type_code='101', ra=60, dec=-40, pixel_scale=0.074, time_pt=None, im_type='SCI', exptime=150., sat_pos=[0., 0., 0.], sat_vel=[0., 0., 0.], project_cycle=6, run_counter=0, chip_name="01"): +def generatePrimaryHeader(xlen=9216, ylen=9232, pointing_id='00000001', pointing_type_code='101', ra=60, dec=-40, pixel_scale=0.074, time_pt=None, im_type='SCI', exptime=150., sat_pos=[0., 0., 0.], sat_vel=[0., 0., 0.], project_cycle=6, run_counter=0, chip_name="01", obstype = 'WIDE', dataset='csst-msc-c9-25sqdeg-v3'): # array_size1, array_size2, flux, sigma = int(argv[1]), int(argv[2]), 1000.0, 5.0 @@ -416,8 +416,9 @@ def generatePrimaryHeader(xlen=9216, ylen=9232, pointing_id='00000001', pointing # # OBS_id = '1'+ obs_type[im_type] + str(int(project_cycle)) + pointNum.rjust(7,'0') # OBS_id = '1'+ obs_type[im_type] + str(int(project_cycle)) + str(int(run_counter)).rjust(2, '0') + pointNum.rjust(5,'0') - OBS_id = get_obs_id(img_type=im_type, project_cycle=project_cycle, run_counter=run_counter, - pointing_id=pointing_id, pointing_type_code=pointing_type_code) + # OBS_id = get_obs_id(img_type=im_type, project_cycle='project_cycle', run_counter=run_counter, + # pointing_id=pointing_id, pointing_type_code=pointing_type_code) + OBS_id = pointing_type_code+pointing_id # h_prim['OBJECT'] = str(int(project_cycle)) + pointNum.rjust(7, '0') h_prim['OBJECT'] = pointing_id @@ -429,8 +430,9 @@ def generatePrimaryHeader(xlen=9216, ylen=9232, pointing_id='00000001', pointing # file_type = {'SCI':'SCIE', 'BIAS':'BIAS', 'DARK':'DARK', 'FLAT':'FLAT', 'CRS':'CRS', 'CRD':'CRD','CALS':'CALS','CALF':'CALF'} # h_prim['FILETYPE'] = file_type[im_type] # h_prim['FILETYPE'] = get_file_type(img_type=im_type) - h_prim['FILETYPE'] = im_type - + # h_prim['FILETYPE'] = im_type + h_prim['OBSTYPE'] = obstype + h_prim['DATASET'] = dataset co = coord.SkyCoord(ra, dec, unit='deg') ra_hms = format(co.ra.hms.h, '02.0f') + format(co.ra.hms.m, @@ -469,7 +471,7 @@ def generatePrimaryHeader(xlen=9216, ylen=9232, pointing_id='00000001', pointing end_time_str[11:13] + end_time_str[14:16] + end_time_str[17:19] # h_prim['FILENAME'] = 'CSST_MSC_MS_' + im_type + '_' + file_start_time + '_' + file_end_time + '_' + OBS_id + '_' + CCDID[ # k - 1].rjust(2, '0') + '_L0_V01' - h_prim['FILENAME'] = 'CSST_MSC_MS_' + h_prim['FILETYPE'] + '_' + \ + h_prim['FILENAME'] = 'CSST_MSC_MS_' + im_type + '_' + \ file_start_time + '_' + file_end_time + \ '_' + OBS_id + '_' + chip_name + '_L0_V01' diff --git a/observation_sim/config/header/csst_msc_l0_ms.fits b/observation_sim/config/header/csst_msc_l0_ms.fits index 3866cdb..8c4eae9 100644 --- a/observation_sim/config/header/csst_msc_l0_ms.fits +++ b/observation_sim/config/header/csst_msc_l0_ms.fits @@ -1,4 +1,4 @@ -SIMPLE = T / conforms to FITS standard BITPIX = 8 / array data type NAXIS = 0 / number of array dimensions EXTEND = T NEXTEND = 1 / number of array dimensions DATE = '2024-08-17T06:05:12.0' / written date (yyyy-mm-ddThh:mm:ss.s) FILENAME= 'CSST_MSC_MS_SCI_20240817060512_20240817060742_10160100000_09_L0_V01' FILETYPE= 'SCI ' / observation type TELESCOP= 'CSST ' / telescope name INSTRUME= 'MSC ' / instrument name RADECSYS= 'ICRS ' / coordinate system of the object EQUINOX = 2000.0 FITSSWV = '2.1.0_20231208_wcl-5' / FITS creating software version COMMENT ========================================================================COMMENT OBJECT INFORMATION COMMENT ========================================================================OBJECT = '60000000' / object name TARGET = '161953.0+395345' / target name (hhmmss.s+ddmmss) OBSID = '10160100000' / observation ID RA_OBJ = 244.972773 / object RA (deg) DEC_OBJ = 39.895901 / object Dec (deg) COMMENT ========================================================================COMMENT TELESCOPE INFORMATION COMMENT ========================================================================REFFRAME= 'CSSTGSC-1.0' / guiding catalog version DATE-OBS= '2024-08-17T06:05:12.0' / observation date (yyyy-mm-ddThh:mm:ss.s) SATESWV = '0001 ' / satellite software version EXPSTART= 60539.25361 / exposure start time (MJD) CABSTART= 60539.25361 / first cabin time after exposure start (MJD) SUNANGL0= 50.0 / angle between the Sun and opt axis at CABSTART MOONANG0= 30.0 / angle between the Moon and opt axis at CABSTARTTEL_ALT0= 20.0 / angle between opt axis and Elimb at CABSTART POS_ANG0= 20.0 / angle between y axis and North Pole at CABSTARTPOSI0_X = -2218.3663 / orbital position in X at CABSTART (km) POSI0_Y = -5817.8559 / orbital position in Y at CABSTART (km) POSI0_Z = 2597.9467 / orbital position in Z at CABSTART (km) VELO0_X = 5.058199026407237 / orbital velocity in X at CABSTART (km/s) VELO0_Y = -3.85818799871231 / orbital velocity in Y at CABSTART (km/s) VELO0_Z = -4.322908628205369 / orbital velocity in Z at CABSTART (km/s) EULER0_1= 0.0 / Euler angle 1 at CABSTART (deg) EULER0_2= 0.0 / Euler angle 2 at CABSTART (deg) EULER0_3= 0.0 / Euler angle 3 at CABSTART (deg) RA_PNT0 = 244.972773 / pointing RA at CABSTART (deg) DEC_PNT0= 39.895901 / pointing Dec at CABSTART (deg) EXPEND = 60539.25535 / exposure end time (MJD) CABEND = 60539.25535 / first cabin time after exposure end (MJD) SUNANGL1= 50.0 / angle between the Sun and opt axis at CABEND MOONANG1= 30.0 / angle between the Moon and opt axis at CABEND TEL_ALT1= 20.0 / angle between opt axis and Elimb at CABEND POS_ANG1= 20.0 / angle between y axis and North Pole at CABEND POSI1_X = 0.0 / orbital position in X at CABEND (km) POSI1_Y = 0.0 / orbital position in Y at CABEND (km) POSI1_Z = 0.0 / orbital position in Z at CABEND (km) VELO1_X = 0.0 / orbital velocity in X at CABEND (km/s) VELO1_Y = 0.0 / orbital velocity in Y at CABEND (km/s) VELO1_Z = 0.0 / orbital velocity in Z at CABEND (km/s) EULER1_1= 0.0 / Euler angle 1 at CABEND (deg) EULER1_2= 0.0 / Euler angle 2 at CABEND (deg) EULER1_3= 0.0 / Euler angle 3 at CABEND (deg) RA_PNT1 = 244.972773 / pointing RA at CABEND (deg) DEC_PNT1= 39.895901 / pointing Dec at CABEND (deg) EPOCH = 2024.6 / equinox of pointing RA and Dec EXPTIME = 150.0 / exposure time (s) COMMENT ========================================================================COMMENT VERIFICATION INFORMATION COMMENT ========================================================================CHECKSUM= 'DhIlDgHkDgHkDgHk' / HDU checksum updated 2024-03-15T15:51:50 DATASUM = '0 ' / data unit checksum updated 2024-03-15T15:51:50 END XTENSION= 'IMAGE ' / image extension BITPIX = 16 / array data type NAXIS = 2 / number of array dimensions NAXIS1 = 20000 NAXIS2 = 4700 PCOUNT = 0 / number of parameters GCOUNT = 1 / number of groups BSCALE = 1 BZERO = 32768 EXTNAME = 'IMAGE ' / extension name EXTVER = 1 / extension version number BUNIT = 'ADU ' / physical unit of array values COMMENT ========================================================================COMMENT DETECTOR INFORMATION COMMENT ========================================================================CAMERA = 'MS' / camera of main survey DETSN = '12345678' / detector serial number DETNAME = 'CCD' / detector type DETTEMP1= 173.0 / detector temperature at EXPSTART (K) DETTEMP2= 173.0 / detector temperature at EXPEND (K) DETTEMP3= 173.0 / detector temperature at READT1 (K) DETSIZE = '9560x9264' / detector size DATASECT= '9216x9232' / data section PIXSCAL1= 0.074 / pixel scale for axis 1 (arcsec/pixel) PIXSCAL2= 0.074 / pixel scale for axis 2 (arcsec/pixel) PIXSIZE1= 10 / pixel size for axis 1 (micron) PIXSIZE2= 10 / pixel size for axis 2 (micron) CHIPID = '09 ' / chip ID CHIPLABL= 'r-1 ' / chip label FILTER = 'r ' / filter name NCHANNEL= 16 / number of readout channels PSCAN1 = 27 / horizontal prescan width, per readout channel PSCAN2 = 8 / vertical prescan width, per readout channel OSCAN1 = 16 / horizontal overscan width, per readout channel OSCAN2 = 16 / vertical overscan width, per readout channel COMMENT ========================================================================COMMENT WORLD COORDINATE SYSTEM INFORMATION COMMENT ========================================================================WCSAXES = 2 / number of WCS axes CRPIX1 = 4600.694649742984 / x-coordinate of reference pixel CRPIX2 = 4604.383757040574 / y-coordinate of reference pixel CRVAL1 = 244.5872723135913 / value of reference pixel on axis 1 CRVAL2 = 39.68195466168969 / value of reference pixel on axis 2 CTYPE1 = 'RA---TAN' / type of RA WCS projection CTYPE2 = 'DEC--TAN' / type of Dec WCS projection CD1_1 = -6.8096767434962E-06 / transformation matrix element (deg/pix) CD1_2 = -1.9394088718019E-05 / transformation matrix element (deg/pix) CD2_1 = -1.9394079613547E-05 / transformation matrix element (deg/pix) CD2_2 = 6.81009530128767E-06 / transformation matrix element (deg/pix) COMMENT ========================================================================COMMENT READOUT INFORMATION COMMENT ========================================================================GAINLVL = '01' / gain level GAIN01 = 1.089977689498424 / gain (e-/ADU, channel 01) GAIN02 = 1.099175619835018 / gain (e-/ADU, channel 02) GAIN03 = 1.107649165474623 / gain (e-/ADU, channel 03) GAIN04 = 1.121722214644728 / gain (e-/ADU, channel 04) GAIN05 = 1.081220797968546 / gain (e-/ADU, channel 05) GAIN06 = 1.09456272850753 / gain (e-/ADU, channel 06) GAIN07 = 1.111430472148367 / gain (e-/ADU, channel 07) GAIN08 = 1.105606424366627 / gain (e-/ADU, channel 08) GAIN09 = 1.101874970320761 / gain (e-/ADU, channel 09) GAIN10 = 1.085064046871988 / gain (e-/ADU, channel 10) GAIN11 = 1.12218772525153 / gain (e-/ADU, channel 11) GAIN12 = 1.114934178226512 / gain (e-/ADU, channel 12) GAIN13 = 1.119336504852553 / gain (e-/ADU, channel 13) GAIN14 = 1.093036190194986 / gain (e-/ADU, channel 14) GAIN15 = 1.084334798104931 / gain (e-/ADU, channel 15) GAIN16 = 1.090894538052644 / gain (e-/ADU, channel 16) RON01 = 5.0 / readout noise (e-, channel 01) RON02 = 5.0 / readout noise (e-, channel 02) RON03 = 5.0 / readout noise (e-, channel 03) RON04 = 5.0 / readout noise (e-, channel 04) RON05 = 5.0 / readout noise (e-, channel 05) RON06 = 5.0 / readout noise (e-, channel 06) RON07 = 5.0 / readout noise (e-, channel 07) RON08 = 5.0 / readout noise (e-, channel 08) RON09 = 5.0 / readout noise (e-, channel 09) RON10 = 5.0 / readout noise (e-, channel 10) RON11 = 5.0 / readout noise (e-, channel 11) RON12 = 5.0 / readout noise (e-, channel 12) RON13 = 5.0 / readout noise (e-, channel 13) RON14 = 5.0 / readout noise (e-, channel 14) RON15 = 5.0 / readout noise (e-, channel 15) RON16 = 5.0 / readout noise (e-, channel 16) ROTIME0 = '2024-08-17T06:07:42.1' / readout start time (UTC) ROTIME1 = '2024-08-17T06:08:22.1' / readout end time (UTC) ROSPEED = 10.0 / readout speed (MHz) EXPTIME = 150.0 / exposure time (s) DARKTIME= 152.0 / dark current time (s) COMMENT ========================================================================COMMENT SHUTTER INFORMATION COMMENT ========================================================================SHTSTAT = T / shutter status, T=open, F=close SHTOPEN0= '2024-08-17T06:07:42.1' / shutter open time (start, UTC) SHTOPEN1= '2024-08-17T06:07:42.1' / shutter open time (end, UTC) SHTCLOS0= '2024-08-17T06:07:42.1' / shutter close time (start, UTC) SHTCLOS1= '2024-08-17T06:07:42.1' / shutter close time (end, UTC) COMMENT ========================================================================COMMENT LED INFORMATION COMMENT ========================================================================LEDFLAG = 'main ' / main/backup LED LEDSTAT = '00000000000000' / LED status LEDT01 = 0.0 / LED01 flash time (ms) LEDT02 = 0.0 / LED02 flash time (ms) LEDT03 = 0.0 / LED03 flash time (ms) LEDT04 = 0.0 / LED04 flash time (ms) LEDT05 = 0.0 / LED05 flash time (ms) LEDT06 = 0.0 / LED06 flash time (ms) LEDT07 = 0.0 / LED07 flash time (ms) LEDT08 = 0.0 / LED08 flash time (ms) LEDT09 = 0.0 / LED09 flash time (ms) LEDT10 = 0.0 / LED10 flash time (ms) LEDT11 = 0.0 / LED11 flash time (ms) LEDT12 = 0.0 / LED12 flash time (ms) LEDT13 = 0.0 / LED13 flash time (ms) LEDT14 = 0.0 / LED14 flash time (ms) LEDTEMP = 173.0 / LED temperature (K) COMMENT ========================================================================COMMENT VERIFICATION INFORMATION COMMENT ========================================================================CHECKSUM= 'gWAehU4dgU9dgU9d' / HDU checksum updated 2024-03-15T15:51:51 DATASUM = '3747953988' / data unit checksum updated 2024-03-15T15:51:51 END ÅÄÅÍÍÁ¾È»ÅÇȾÃÁ¼ÃÇÈÃÇÌÁÃÂËÊÚÓÙéæêàéèæÞáÝêæáåå×ìÞäôÓæåâëÛàßÝäèÛîíàßáÝïâÓæ×äãßãæâæêàØÜêâêäéäâãëåééÜêãááßáÙáçÚãàëéÛãÛæêÞÚÓáéðíçëèêÝæçîÜòèççáèâáçîèàåßÚæäàëàÚâÜÞÛãèãßååÚêæíåÞ×ãæíäêçñèæÝãíæïìæåçâ×ÝæÛÕáâÜÒâëâàÕäâÚìîððíääííãçéàâêéßáðöäÜèàêéÞÝçäÙäæÞéáÞãÞàäÛé×âäÜäáØÝèâàÚãÞãîëâçèâäâîàòëßéÙêàèíæàåÞÙãââïåèæÚßçéÖæêÔÝçéçëêæßÕéäàÓäâãæëéæâ×ÖåæèäÝßéæãÐàáçßëÝëÝÚÞÞäæåÕíàÒÖààìéíäêôìðô‚ óìðôïåÑÝéß÷àÛÞÙßëçðïèëñàãÝèêîêÜãåçäáÕáëêÞçòâææêÜîòëØèåèáäáíäïåèäìèßàãßßåÚâñææìæèëääñõêêàÞóðÓÚéÙàÒÞéíæÞíãæââÜáèÝàÓèñáÔÙáàáççáÛáéããæáÜÜáçï×áãìâäàåæîëäÜéäÖÝáâÙáðéØêäèÜâãìííìÛÝÜïâßêæáçèêéäãâÖôáðééíñòîëñêìéñìéæááåÛîäåâßÞÝêàÝâåææÒÞèÛíÛÜèñæéßáßÜêØÜãêããææðéíÙæçâÚâßíðäàí×îÞäðØààÝçæßÞéããÕæâæÚáåÙéääæáÝØàßéåçâéÚÝéîÔæéìââÛÞèááÔâèØæçÙäêáçàâãæÚØâàåÞÚãÙâèå×àßâÝéàÛâÛéäàëàÝãàéâçßÚÛèäæÜçØõÚÞåæÓäçÙëäÝàààææßÝìêäïåâÙæ×ãáåèðßéâêãçæÙèçÞÜ×ÚÝðÜãàÞåâçÐíØÞèãÛçãÛçÕØæÕåðäîïââãæÜÜÞâãâåâÝðìÚßçèÛØÚêõêæëîÕëëÞââ÷ä䨂xåïÛÛåÚêìÙâáàâÞàëÚéîåáâÜôØìØÚÚåÝàÞëÚÕòåãëÚäôàßÝãäåéÝàáæêëâÞèÞâÛéàêâÝèæßâáßååäâòòáéäáéçáâàãØëÒëáèåßëèÞìéåæÔÞåäííçÞèæëâïáÛÞáèáì÷ãÝäààßèñíðã×çÞòèÝëæÞéßçÚߨßãÜÞãàÜàèêêìîèÝ×ðßèåÛãéçêæãÕîÝÛàÞèñÙáäééåäßêîíâØåéâÜÞìåãåéïÞáàñÓçïÏîØáëñçÞçåØçÝÚîãÓæáâçåèÛÝèÛÛÚíàÛäçÙêææåéäâèßçæÞØòèÚáîéïâæåäâéëßåÝæâããáëìåàáÞÚåéàÙóàãßéâæ×éãæßêçáàåæãâá×çéååØÃÂÂÅÁÄÇÄÃÅÌÁ½ÃÁÆËÆÄÊÇÅÄŽÁÅÞÅÇÉÆÉÌÁÈÆÉ½ÂÉÅÆÁÈÅÐÂÁÀËÄÈÂÄÈÄÂÊÆÈÅü¿ÅÆÂÈÄÉÇÉÁÍÁÐÍÇÇÍÊÄÊÇÅÊÉÑÉÊÐÌÄËÐàèèëãðààêèßñêðøâîõïÞæÚêñéëæìãêæïêûéüÞòïèñâÝûääñáïÕßæíîàçëíßìßêîñæëìßéæÞâìèçôîÞÜåÞéëîäíæîéíìíÝàãçÛÜëçèäèÞåæåãçàìèáåßëãçäëßå‚éèäæõèæûÙéäïáãëìßíÛèóôèêñèìæäâìëêÝèíêëàééïëéðîïàñèææâåãîä×éÔÚäêßãìïîãâàéèêêëçêéï‚‚‚ ‚ðæççãäêäéìèÞéðïäîãìîòäÛäéäæèýäàðêóëëíñáîæêÜäëãééæãêêÝÞæåãëðãÜìîàìðíçóóÖßãåìîíìïïáàççëìáóüæåàèïóÞÞêìêéÛêùæìêäïñöößçäáìììëëçéæáéâåÞåææçóéôìîçôçåàêìùæåìàØîâîèéõðìíëêãèïäùëèêìççßõåõêÞÞëêôíäáêæåëêêéêåëåæóåëåèéðççáÕçøëçßÚêéêïäÜßéõèÝæãêêãéæèæäëàãÝæãïíçàëáîåááñöõÞÞëàßßóÜçëéÞêîêæ÷ðèñáðîáøÝêäêçÙìäæâæáÜãêâæîãßçåÝòíñìñÝæÞèíàéÞâîéçéäÛêìèäïãæìîæîçÞìûèéííæàäêêæÜåââØêãìÝáã×ìèééßïçèäçãêâçíñÞìîíàçÝäáïêåèêçëÞíÔäéøæáðâäëêçàáäëàõõéãêìçæáçíçòâãâÜæëääñèíêæóÜåëåßæøãðèéäêæììæäåêñèå×ßÜòçèñéßïø÷ÜõïäèäîèæïßçâèîáÖäÞÜæìòâñåõÝéëåéëáÙããíçéìÞçåäîæíçéñâàîåæçÞðååÞçäåìêæçíèåçòøäíÝê×íì׿êÜçåëîÝîêÛéÛäèáñãåßéäìëêêåûççÛñ×ëéïæçîßßæöæîàåÜéôì‚‚$‚ôêîåÞáçâçÞàññãéãÝëâèêéøñãíéåçíåøæßäõæãæÞØëìßõáåäïëçîâßÞéÙáôæíñõåêèç×êéïãíÞíüîäòêäñÜÝõòëãäòñôáçìäàêäêåÜéèÚßòäâêñØáëßîëôúçðáíïðÚå÷‚cãÝêìäïáçèåçöóáêâëëìæîêÚðïåðåäåâëçñéåãäþâåæûîòèðäëãîáóíèæ÷ìæáîêäíáèßçïìÛëàâëêíãåëãææéÓäëìæîóëååãîáôðçãéîîèëããåöçæåæçñéíÙäÝçèäèêîáççòÞïäââëëü÷ÞæéåéèéâèãíéëáàÝèÜÛàáäíðçðîìöçåâåëëÞáçâóñðââÞæáãåçìÚïèëäëðåçêãèáôôÅѸÌÄÆÌÇÌÅÁÑÁËÒÍËÈËÉÈÏÈÄÈÑÂÉÉÎÌÂÔÊÊÊÌÊÈÈÄÅÈÁÏÁÊÈÅÉÂËÍÆÌÇËÆÆÇÆÉÊÏÆËÐÄËÊü¼¶½À¾¿µ¾½·¶½º½¸¸¿ºÀµ¾À¾¸Á»×ÙÕÓÚÉ×ÏÏÑÜàØÞÎÐÕÔÕÜÚÝÑßËØÜÛÞØÞÓßÓßßÕàÖÝÓÞÚÓÔÔÐÒÓéÒÜØÕÚÏØÖ×ÍÕãÐ×Ï×ÑÙÞÛÒÚ×ÕÜÏÕÐÔÜ×ÍÖÔÖßéÑÛÒÒÕÏÕÔÕÌËßÚÊÒßáÏÚÑÝáÝÙÓÌÝßàÜÞÛÖÝÝßÒØÖÖÚÑÜÛÖËãÏÍÔÔÚÏ×ÚÐéØÌæéÞÔÔÙߨ×רØÐÒ×Ý×ÖÝËâÐÑÑÔÚÖÔÛÊØÐ×áæäßßÚÎÙáÝáÞÑÙáÖÙÕÒÙØÚÔÙèÞÏÜÛÖÚåÞØÔäáÛÛÖâÏÖÖÞß×àÔÐäÞÚ×à×ÖàØÙáÜØàÕØÝÒÞÕÞØÜÙÐáÑÜáÑ×ßÖØÑÚäàÜÖÕÖÞÝÓÝÔàÆâÔÓÏÞÌÐÛ×ÕÛØÙØÙ×ÙÈËÏ×ÚÝÖÜÙ×ÐÔÖÞßÔâÝÑÎÔáäÛÛÜÙÓáÎàæÍÏãÚÜàÔÔâáÖÖØçÖÊÏÓÝÞÖàÑÝÔÓÏÔÔÐÚÓÔßÖÙÙÓàÕÝØÒÔßÍÑÝÒ×ÙØÛØÍÕÞÜÝÒâÝÔÔãàáØÕÛÏÌâÞÔÏÚÎÛÚÏ×ÖßåÛÉßäÜÇÝáÏçØÕàÕÙÑÔÙßãÑÕÜÞÔ×àÛàëÕÜØåäÔÙרÛßßÖÔ×ãÚÛÝßâÐæÙâÊÔÓáÜÞ×ÑÛÓÙÑÙØÒÕÝÙËÖÝêÝÖïÚàÒÒÞÔÕÙÙÝäÐÙÔ×çÔÔÖåÒØáÑÙßÖÑÖÖÔáãØÓÕÔÕÙÓØÙç×ÌÛìÖâßÞÚÜÏÛÛçÐÕÛÊÓÓ×ÕØÛÒÙØ×Ü×ÔÛÝÛÑÓËÞáÎáØÙÛÖÍãÚ×ÚÞÕÈÚÕÞäÕÜáàÚÔäàÔÜÜÎÛÔÏØÍÕßßáÚÕÏÕÌâÈÚÚàÙáÓÃÖÙ×ÔâÞÓߨÖàÓÒàáÜÕÛÜËÐÏÕÓ×ßÊÕåØÑ׿àÚÔÖØáÚØÞÑßÛÞÍÍÎÔãßÔßé×ÕÙÎÉÝØßââÒØÚÖã×ÔàÒ×ÌË×ÚÜÐÏÑÄÓÆÜÛÝÑßÙÚãÚÕÙÚáÑÝçâÖÝÜÙçÌìÓÛÏÚÑÕÔÞÏÖÝÔËÖÐÔÛÕÔÊÍÓØÑÔàåÛÛÖâÔÕÞÞÐÐÏÜØ×ÕÓ×ÚÞÔÚãØÐåÜÛÞâÔÞ×ÞØØÕ×ÕÝåÔÔÜÖÙæÞÞÐßÓÙÚÙÊÜÕÛÎÚÚÞÏÙÎÛÝÚàÏ×Ù×ÝÖÞàÞ×ÛÚØÞÚäÐÛØÚÚÛàâÑäÚÛ×áØÒÕÞÖÏÚÕÍ×ÓÄÛÏÓÜçàÛÓÝÕÛìÔÓÔÜÎÞ×ÚÔßËáäÏéßâÝÒËæâÞÚâÙÜãÑ×Ô×ËÕÓØÎÖÑרÛÎÏÓÛÓÚÝäãÓÙÝØÓÖÌ×ÓÍÚìàÖÛÙèåÏÜÖØÌÚÚÚÝÚØÑÌ×ÕÜ×ÜÝßËÞàÔÓÞÚÔߨ×ÝÖÛØà×ãÞÛÛàÉ×ãÜÚÜ×ÕéâÞÛÞ×ÛàßÞèÝÝàÓ×à×ÝÜÙèòÖö‚÷î÷âØÙÛØÓÚÙ×ÙÊÊàÞãÊÜÄÎäØÓÙÌÖßÓÞÔÒàÏÜÍÝÛÞÖáßáØÞÕÚÔÓÜåÛâ×ÔØÒÝÙÞÖÔ×äÛËߨܨÞíàÊÜÙÔÞ×ÕÙÝÒÛÙÓÙÝÜÚéÏÈÝÓÒÙÔÖÕÎÛ×ÕÙÎÖãÝæþ‚÷áíäÝÕĶľ¾Ã´»Ã¸¾¶º¼·¼À¿¹¸¹Ä¾»¿ÃÀ·»À¸³ºµ¹¾Âºµ±¶¶Ã»¹¶¹¹´¶·¶Å··¾¶½¿ÆÃÀÁ¸¹»º½¶¹´º¸®±¸·´·¹±¶¹»ºµ±º´·¸¶Âº¸°³¹½ÌÐÊÊÔÕÒÍÖÌÙØÔÑÊÓÚÔÔÎËËÙÓÐÖÒÓÕÛÞÒæÙØêÏÜËÖ××ÚÑÒÎÍÓÏÒÊÚÜÛËÖÏÓÕÐÒÓÍÌãÑÒÌÓßÒÞÚÏÓÑÐáÆÖÎÜÌØÔÐÍÒÚ×ÔÖÔáÍÓÚÚÏ×ÝÒÎÙÑØÏÐÛÑâÓÒÉÍÑÔÙ×ßÝÏÓÊÜæÖÞÏÓÜØÔÛÛÕÝÒÜÑÔÛÙÖÖÎÙÙ×ÚÒÑÓæ×ÔÖÐÔÌÛÝÞÎÜÈÙÚÓÍÖßÖÕØÕÖÞËÓÓÒÔ×ÓÛÚÓÊÑÍÉÉÔßãÊÝâÖàØÛÖÜÔßÔßÖÔÔ×ÉÖÙÔÌÜÐÏÔßÝ×ÕÑÕÖÕÔÏÔØÑÖÏÓÒÖÖÊÐÅÕÐÒ×ÔÒÕçÝßÑÜÚàÏÊÔÌÜÇÉÎÎÓÙÝÏÕÒØ××ÏÚÜÏÚרÑÏÒÙËÐÓÓÒâÝÎâÔÄØÒÔÚÑËÕÏÐÚÍÖÛÚáØØÔÓÍ×ÏÏËØÆÐÔÛÒÕÖÌÓÚÊÐÏÎÓרËÞÕÜÔÍÙàÛß××ÍÕÏÅÍÒÏÙáØÔÕâÙÌÜÓÓÕáÒÐÕßÐÒØÎ×ÒÒ×ÚÚèÌÜÞÞ×ÕÊÑÒØÛÏÜÁÕØßÎØÉÙÔãÓÝÑÌ×ÔËËË×ÏÔÕÏÆÝÄÓÏØÌ×Õâ×ÙÔÎÔÜÍåáÜÜÎ×ÖßÖÙÊÏÎÐÒØ×ØÕÙÝÖÕÐ×ÌÓÖÎßÐÖÕÔËÙÛÝÝÝÅÌÎÊÖÖÚÖÛÉÛÝËÙÔäÐÐÓäÐÚÒÖ×ÔØÉ×éÖØØÉÓË×ÔÝ×ãÙßÖèÐÙÑÓÖÕÔÚ××ÖÞäÉÎÒØÑÌ×ÎרÐÏÏÜÕÙÒÛÕÙÕÌáÕØÐÏÒÛÝÙÖâÚÕÍÓÉÓ××ÍÔØÖÑÛÒÏÎÞÖãÙÞàÛÑÒÐÌÚÍÚÓÓëØÕÝäÍÎÌØÓÖÚÜÎàÖÑÙÐÎ×ÓÚÔÎßâÉÇØÑÝÜØÏÑÍ×ÏÙÌÑÎÎÓÝßÚÛà×ÑÏÓÏÕÔÊÝÖÌÕ×ÚÒÕÞÓÓÐר×ÔÞÒÖÞÐÖÕÌÔÛÒÏ×ÕâÜÒÞØÛÛÑÒÓÑØÜÔÜÝ×ÏÔÉàÖÔãÍàÔÜÔÏÎÛÕßÐÚÔàØ×ÏרÓÕáØËâÀÕØéÌÓáßרÐ×ÙÐÑÔÖÒÍÖÏèÕÙØÑÎÓÌØÏÑÏÕÑÝ×ÝÚÖâÜÓÜÓáÐÞÖÎÓÕãÛÛÑ××ÌÖÖÒØÓÎÑÝÓÑÓÖØÖÌÐ×ÓÔÝÕÕÙÛÙÑÛÌÒÍØÏÝÊØÝÛÌØÖÖÛÜâÕØÄØÒÜÚàÕËÓÓÏÖÕÚÙÓÓÑÝÖØèÜáÞÙÕØÈÌØÍ×ÛÊßÔÐÖÚÍÖÕáßÍÛÏÙÛÞÔÎÇÔ×ÎÑÑÅÖÒÔÚÞÔÙÑä×ÔØËÒÕÓÝÐÎÐãÚÔ×ÖÐÖÓàØØÐÐÕ×ÛÚÐÓÏáÖÜÖÛÒØäÛÒÞÛÎâÕâÎÖËËÍæÖØÇÔÍÕÙÐÎÒÐÐÔÔßÖÕÓ×ÍÜ×ÒÓÛÓÜÖÔÒÏÉÝÜÅÛ×ÚÓËßËØÓÒÍÑÙÓÖÉÑÚàÚÙÐÕÔÔ×ÔÎ×ÌÏ×Ì×ÑÊØÚÖÕÝÑÒÛÏÙÙÑ××àÚØÙÐÈßÕÙçð‚ ìÐÐßÌØÒÛÓÕÎÖ×ÏÐ×ÔÕÎÒÜÉÖÒÖâÙ×ßÔÖÖ×ÚÖ×ÉØÔÙÑÔãÓÇÜÓÙÔÙàÜÚÚÛÍÔÞÛØÑÖÐÐØÕ×ÜÜÕÚÉÏÓÖÛÚÓÊÝÌÙÒÔÑÖµ²¹®º²µ²µÀ¸´º¿²µ´»¶¸¼³´·º·´¹º·¹Á·¹º¸¿±²µ±µ°¹»­Ã´¸¹º¸¾¼ºµµ®µ¼º¹µº´¿ºµµ¼ºÉÔÏÂÎÐËÎÎÆÊÈÌÉÈËÒÍÐÇÐÑÆÍÎÊÍàìåèãëêèêîàæàæèåíéöñìêéâïññÞõáïæíêìëåóøáç÷éñõáçììèéòüçëçëñíìíúåèêäßñåäìáëÜóèÜðíâáóíòçåáñáçãìíçãïÛÙåÜëãìéíßóââñöâßÜîìéñâçèìëõõåáåáõÝñíèßëçíããéâðîõéñðøôÝïïíêêæ÷éæíé÷êàèáñéçéâèôëæäçëàæêôæóèïíêêàóñëôòåâîóçùù÷Õðçðî÷êéòïàëêëëõçôæìäïàâòãñæääùéëðéæçîçåðéñèäëêììææòíòßÝðÝêõÛÛêèêïßäðìæÝãñêòðáäùêõíêçíôçõîÞêåèíçêóïíëáêåîúîîëôàäåçéçìãëêççêèïíéçíãããïæëóìåõõõàßæèíÜåàéòðìäîèøöëäêêñíùíìâðïðæìôêßãòäðëãïîôãâêîàêóùÙìéêúßìøæòèòðñãîáîÜäâðéäâéîëäãíéæìÜåèéùÝòÝéìàîèåíãã÷ãäññäáùåæõßíèëðééÝòêèÙèý÷áñçíäéæçðåÝæàøæðéàáåóçóñÞáæåçüíôïõãîîõíäôçèîãããáêáñãóéëçìîäïåãæìéææáèëóêãóãæêéßåèÛèßêãðäêâÞìîæñæöçôìñîñÞïïíêíìïâðìæàèëìòðóåèåñîïêåêéèéíæçíåèÞéëéëííøÞèþìîûøðçéèßãëãêëÚëèëèôåëóìñîíãïýóïàçéñéééãêäûäèâúäíïèÙßíççèêëãîëíèéÛäòãåèçåïíïèíèöåâíííãêìïëíêñ÷àçîãêðéÜðæçíãæãéîÜÞãäÛãáàêîìãëÝëÝææôëûæïîããßàñìïçòèëñëåõßéññèôëÜæÜåêñãçÞäóïîòÝêêõØéðó×ïèêèìçåðèíïäïçîèáäêßõêòæáõÖæãåéåóàåëêâÝïòõïééìêîïêáçâàñîåëéêèâÖðèÙéïïâå÷äïæâñëèäêóéãæææççñíããéâåèèßëìæìíæÝíðâêîðëðîùïåíÙöòáäâãæäâñâàéóïÞéïêáïïåèåáçééîæåëëè÷ääõäåçãïìáõéóäçéãåìäêéçíøõëíááææâÝáàÞïãçôãïîíïóìèáéòñáèæàëèîìøáùéòçñêêÜØéìñçøìïáöêáîùòãêúüîèæáðáøëëâóçõíòèìãçîîèéëéßæÚòèîëæáèßàéåêäæíééñòéîóîåäçêæððæòææìÞíôÜóæáíåééçíóöõðëøêèòúåàóìæêïßìòòôñëîËÅÈÍËÊÀÒÄÃÍÅÏÏËÊÔÌÉÊÏÎËÉÆÆÍÌÒÍÊÇÓÕÈÏÃÌÒÏÓËÆÊÏÆÌ¿ÌÄÇÆÒËÌÆÏÍÈÊËÏÆÂÌÃÉÂÈÑÉÏÈÍÍÈËÎÏÌÑÌÛÔÏÏÈÐÓÑÎÑÊÊÇÌÊÐðëóëã÷äûçíéõåíéíìñçÙàèò÷éîêëöñÞõñõóôëäïæîîéñëôëíúóñôåëèäíèæëùëìßóòèèòíõôèîçåâêòðëòöøêþâúë÷êñÝðçõãîíïîþéô‚òæäèãêçïêñõóãñÞñååîòæõñöðôïúíþèæïæíéíêéðéðäéøòãäìòåêæéëïðíéûì‚ó‚sðåìôäëññäñíîíñæö÷òòåàòëëôîòèöíäÝáòìõ÷èðîïííèêíêãóñóìøîñîôõäçöðììéûúñëñéïððìóùñýâûöëðäóòïöóããßîåæòéðíïñöæïêòëåèíëòóêèìðîèéúöâïåôïåèôñèöðëçñæíìòäåèêõêòå÷çíýèðòòçíè÷öóåóåöáîñëöçðóéíóôçïêìóõîîôäìòðïôéôíìïîïèïðíèâìæñãìêéëéííåìõûâóìñìïìõðôóíîöáæ÷óúóßäóûçîîûäÞíèöìèéíëñêìíìèëâäìõèíïñêêèâïåêãññ‚èßòùëâçíìôèîùóîðèøúïæéöíñîêïôçêëèîìæçáãóêðïçäîìóõ÷ïïïïñõïóëñìòèðíùóúóæöóçîãæðêùçúîøâüéíæôñïæ÷ëëêø÷èëñöðáìùúåëôöçóäëõóíéëéøèôæøìéþåüëæîîêìçîñäëåðíæñðýíïäãñîéêîäñìöèøïîôð÷æïøôçÿñôõëîîóúêéñíóíöñóîúèóñâéóíéíâææöîðíèóøãÿçèõðëñðæîâéëéèíïæóéïéäöéóäåîóñúòîéêðîììëòæßèääöáíííðâêéïæç÷óûäé÷øâòæñïí÷ïòßùëóâæéñóý÷ùñêæüñíéîøñéïöçùêìïìïéôñíäìçðéóóñóøéçê÷õåêüéêêïììæìæêëíúóæòîçðéðóôêòîòæîèôáïåõê‚ìúìçæ÷êäî÷óíî‚ñëãôôóò÷îàíôéèúäæáëêóãôêíéëèåñèøíäöòêóíëëåòôíòëðøõîééçèçâëçÞéîãêíòéôçìóæíîùàìðëñîìæîïïêïèëêï÷óûìòíñíðóðïÞóåøÝ‚íûçðêãîïâôçõñðëóçæíòòéïûêåëûëóîíîìïòßíõñïèïëêííèñæêêèçòîíñìñèòøéáóåéøçõéäêòåìéäñð‚êâæ÷èîïöõëäéêóæèéîðøæþîæìëìöãðôçèâæðñàëøðæñîðõñî÷íõèîèïíúâòëîÓòëîõæïìóë÷óóáëíèâæóòîîåîøôóæõïÚèéçèééäïæøèëñïóçóÒÎÖÆÊÔÏÎÓÅÍÇÏÈÑÐÔÒÐÔÓÕÏÌÍËÉÈÔÏÒÑËÖÒÕÈÑÍËÓÐÊÓÒÓÌËÎÐÚÑËÖÖÒÏÓÒÕÒÎÔÕÔÉÍÎ×ÊѶ»²¼¯¹·À½½´²·´½·¸µ·¸¹ºµº¸¹³àÙáÝ×ßßÜÞÞØßÖÝÌÝÜÐÖÒÖ×ÍÑÙáäÙÞÕ×ÈØßÕãÕÓÍÐÞ×ÜÝÔÍÐÐÜâÛÌßàÛÌáÕßÙØÌÓãæÕàÜÓáÛÑÇáÛÕÕÈÒÌÒÙÕÊÚØÔÕÝÙÞÝâáÝÚÞÆÜÚÙÓßÚÙÑäÕÜÍÒÝÙÚÓÔßÒÞÜÔâÚàÕÜרâÖäÔÙËÝÙÔÕÏÑÝßÙÜÏ×ÔÕÙÚÎÚÐÌÓàÜÜÞÝØà×ÜËÔÝÔÙ×ÓÑÖÚÖßÚÖÕâØÜÍÛÒÛÖÛÖÚÞÖÛÊÝÕÕáÜÓÙÕÔÓÞÓÙÖÙæàÍåÅàÛ×ßÌãÛÐ×ÕçæÖÐ×ÙËÛÓÚÕÞÒÙÙÖåáÞÓåãßÙØØÐÒÞÕÛáãÕÕÝâØÚÜÛÜÖÙ×ÙÕÒ×ÝÝÙÜÚàåÍÜÖÞÍÜÔÖÔÔÓÞÒÛáÖ×âÙÚçÛØ××àÙÛÎÖáÔ×àÑÌÓÓæÌÜÏÝØÔÍáØáÔØÙÐÔÙÝáÒÜÙâÞÐÖÝêÕÛ×ÕÞÝÚÚØÛáÙÞÒáÔÏØÚæÝ×ðÒÒÐÛÜÞÏÚÝçÔ×ÐÜØÐÖÑÛêÒÝÓÝÒßã×ÔØØÞØÜ×ÚÑÇÞÑÙØÍæåÝÐÓÛØØÖÞÜØÓáÕÖÛÉÍáÖØàêäÕÖçâÙÝÑÚÞØèÞäÛÒÛÍØÔÜàâÕÜæÚÑáÜàäÑÜ×ÙÚÞÛàÙÕÚÖàÛÕ×ÚÙÔÕÖÝÏÜÏÒèÖßÞÕÐÔçâáëÕÖÕÑãÊÖÓ×ÊÏÍÏÚØÕÍÑãÛÝÛÚÝâÖÐÛÑÓÊÓÔÌÔæÛÞ×ÔÐÛà×ÏÝÙÕÖ×áÔÞÖÍ×ÔÛââÓÛÝÔÜáâØÝÏßÕØÒÐÈßèÌÎÛÖÍ×áÝÙÚâÈàÒÝÐÖÐÚ×ÑÐáÝÔ×ÓÔÎÜÍâ׿ÕÔÛËÛÐÙËßÎÙáÜÞÙÚÞ×ßÜÎÚØëÜáÒ×ÜÒßÛÚÓÚÛÒß×ß×ÐÐ×äÙäÎØÖÚÙâÞØÞÙÚØÑÔÎÔãÏØÑÕÒÖËÐÆÓÛåÎÞåÛÝÑÞÕÚÙØÐÒÙ×ÕÝÙÞÑëÛÞÛÜâÔÓßÖÜÕÏåÏØÓÒÒÏÒÙÞÝäÝÚáÑÓÚËÔÓÝÓÎÑÙÝÑÛÎÚÔÞÕÐÙâÖäÞÒÚàÔÕÎâÚáÛÙÞØÝÝÒÝÛØÔáÛâÏë×Õ׿ÌÓçÊÛßáÛØÝÛ×ÎÕÊáÚçÜÞÔÐèÈÝ×ÕÐàÞÜÔßÚÓÙÚÛ×Û×ÍÚÖàÑâÜÍÚÜÓÔÚÒÏÓÕÖÚÔåÓá×ÑÓÕØÎØÖÓàÙÚÛØÓÏÖÝÜß×ÙÙÜÙèÙÝçßÔÐß×Û‚EÚæÈß×ÏÇÒØÝÌáÙäÔÞÏÏÜÛÜßÛáÜØ×ÛÜáÍÕÙÛÚáÕàÒÕàãØÛÑáÓÏØÐÛÏÝßÝØÙÝÖ×ÝÞãÜßÞÖÉÓâáÊÑÔÕßáÕÙÖáãÏâÜÒàÐàßàÉàÎÐÏÎÖÕÙØØâÐÕ×ÓãÞáãÑØÒÖÒÔØÛäÝÑÚâÑÜËÑÛÔëÖÙÝÕÚÍÑ×ÎÐÈÚßÔÐÔÕêÙ×ÖØÛÕÖÚÚÛàÓÚäÚÏÍÏÓÏÚÒÒÓÝÜßÕáÔ×ßÞßÜÔÙØÜØØàâàÓÛáãÕ×ÛØëØÑߨÚ×àÒÝäÖØÖÐÜÙÐæã×ÖÝÖÐãàÐàÞ×Ò×ÛÚÜØâÒÏáÕÖÎÛÑÓÕÖ×ÞÝÙÖàÕµ¾·»º¸¸¶ºÃ¼¿¿º¶¹¼¼µ¼»À¿¶À½·ºÃ¿¶·Á¸¾¾Â¿À·»º¸»¿´ÁÀ¶¸¹Âý¼Â»º¾¼¸»··»º¶Â½³¼ÊÅÂÆÀÌÈÈÀÉÅ¿ÃÆÅ¿ÐÈÄÄÀÆÆÉÇÉ»çåØåÛÞèëÝ×âÚëèââëáàäçêìØæðáÛíçåïçÝÝéñàÚáääñãå×ãìæãäØßÒßÝ×Ü×îæßåâÝïãàØæÛäéáåÜàòÞÞÝÚééÝåòúÚìîì×Üâß××ÞåëÜàéçÛàåìèÞâÙÝçèÜèàããÜâãççãÙÝââñÝìÚêÚçèæïèìäâãåÞÝäãßÞëðéÜáÖáßéçä×ÞôßããçðßáçæàÔèåÛåèçïÕæÝÜÞçÜíæáåäæÛÝãéÚìØéïáëߨãÜÓÞåÜÖëààÙëäáÛêÙâäéççÝäëëçâÞñÜÝÝáèâüÜÞÙØèèÛáæäáÞéãäßîäßêåêÞçàæÜàèâéßáäêñÝñìçÜîåßääàóíÝãßÝîéÙìÞÞêßÙÜÕßåçãÜâãåèâÚçìëÙïèÜåâ×ñæäãàãæÜÖóßàÚÖåÖîÕêââßÞßèêÜéáÙòììåèèàðçäãåÛÚãÍÝÖÜëåÜáéöãÛã×âäÜåçåìæäÙêäæåãåâïÚâßàäèÓëäêäââççììäÞíåàÛôéåÖâÛèìêÙëÙàáßæÜÛìÝÜçßéÙÞâéÓãêâàæïîàÜèíéÝÕîïããßåãâÝÜíèáÝèæãßÝëèëíãØãÞäíáÚàêßëçáçØÝÞßçéÜßÚèìäêëæÜáãääÞßÞÚçéçãÜæÜàèáàæàâÔæéåéßæÙéÛãäÜÑäÞßãñðæÞßâåêïâåéëæíìâÜãçÜñàõäçêæòêçâãåÜàãêâæáÚàò×ëãä×ãæéãÖëâæâÚìâàæçÛèèäßîãÞàÜÙáãÝäåÛåçÛôÙñêäÞéàåâààßßåÕæÞèÝâáàèêÞÛÝåãØãäÛØØááðæ×ßÞãëÕçåàãêÛçí×ïîÝáØê×ÚÛããëàðàÚØêØâëåçÛãêèð÷íÝåççäéÝÜçáéîßëåäàãìæãÙßëßÞ×èßìèÐÜãÛáÝÛåÜâææØàâÞãëåàâáÞãÞåäàááæÜåàéëêåæãÚñäæåßÜÚäæ×ß×àåÕßðæåÛààìåãÝçãâãäåãâçÛæçÞÜÕßáÜ×åèêã×ß×ÖåßìàóéåÙàÝöÝáÝðÞåäæàãéâáäìñáêáèìèëäÜÞÜÙçßããìåÜÛáçàâáßßåÛæàãÝìÛàçßÚÖæèããàÛØèäÜßåáðæêáÞáàñÞàãáêÖäââ×ÙâãçßåãæîßÞçÝáâéÓêÛÔÝíÜÞßÞàÙäáßÕßïçíÛßá×åìàåíáêãïáçæÝéìÙÝéÙêáðåÝêÞÞãñÜàÚâìàëëåÓïéà×îâìäàÜâÙÜæâáÜæáããåâØñëáÒêÝáßãÞÖÞæèßáåëáãÞãÛäßååàÞÝäèéæéÙàæÕÝèÖÙæíáêãìßÞÜáäëðáàßíðå×ãáêíÛÜäæãÝìäàëãéàèàéäßèà¿ÁÈÊÈË·ÇÂÆÁÆÁÂÏÅÄÃÁÇÄÆÂÉËÈÅÈÈÅÿÀÂŽÃÈÇÁÂÁÎÇÁ¾ÆÇÉÊÉÂÉËÅÊÃÁÃÂÄÇÂÈÂÆÊÊÃÊÄ»¾ÅÇÇÄÄÂÌÁ½Ç¾ÆÃÉÀÃÃÅÂÂÄÂÀ¾¼áÙÞÛÝæÛÜÞáÙæÜæÙÚâÙáäÜãÙæâäãáØáÓæãöÑÞÞÔáÜæáÞÍáäÜâØÝÝäÜÜÜæÝÞßà×ÜâäâéÜâéÙÖâ×àØÝæââêÙØëØáÞëáÚßçßçàäñäåÕÞãà×íéêÜÜÝÏéÝæÛÜÞÖåçãÝìæÛØäêèÓãÖÚÜèåñàÝçáàÝãÙâßÒáãßæàéßâàâäÜàÜèâÛíÚåÜÚâéàÝÚß×çåçÕæÙÝà×è×ëäçäÕåÞߨäØÛæÛÚÜàéÛâÞßÜâÚäßÞàæäæáâÝßäÖåÜê×ßÒÝ÷üÜìßÍåÚäàæçÝàÚÙÓÖçßàÛÝêÚáåÝØÖÚãáæÝäÞåéáÝÛÝàáâæØáéìçßÞêäÞäââæäÔéÛåÖéìÝäÖÛìèå×ßêëÞëèÕàÙòÕàÝßáàåàêãÜãïàÞäÝâÛîáßäâáßêáæáîãïâßÜàâçàäàÜëáëÞãÕíßãêåàâäéæÚØëÚÛêÝîÛðßäÙÙåÖÞêìéÞâáçêÛØÕßòÜØÞ×ÖàåäçåâåäÚäßâêÝÚééçßãêåâÜâãáÞàÙîÞêÞìÝáÕßáäÞÝéØßáçØÜâßåäØÛçåØ×ÞæÙáÝìðØèêëßäßèßëÓÝêÙÞçÕâðÞãâÎÕãÛåãÖÏ×çÚàìëåßðâèäàäìÞÔàÚéòïÓâçÔÓàÜãßãâêàåß×ÕæØäÙæàØÞÜéèæêàÕæâÖßâÝÚéåÙàÝàÓÖäâéäéÝçåï‚àÔÕâÞâãÜÞÛîàßåñÜàÒàÜߨãæáòëçßñßáæáÚÝÖêèÕÝãßÜÚàßéÝéÜÚàØÚéÞäáÞäààéãç×ÓßÝÚÜߨÜáàäåÞÕ×ÝæåðäÙÙßéÙéæååêââáåÞäÛßäÕäÔéÝßãóÚçãÜààãèåÛÓçèççãááÝÛæàÛÖÍäáåæáÞêàäáààäáßרâáåÛëáÙÙÛãÛçæäáíÙåØÔØßÝØÜÒÙÝâßçÙÝìåÞããÞÛäôæðûäßäãìäéÔïçØæÑèàäïãÜåßï×ååÙæÙÖçåÙáãæßçÝáÜàáÛéääàÜÝÝÚçÛáàÝÚãäÞãçßÙèãåæßâàÖèäÝïÚÛâÛãßáÔîêãäæåáåãææßáÛäãÛàÙåÝåæÞÛìæåÛØêÙçØßéäßãáéãçØêççÞßäâéìãêÙæäáèâßáéßÐÝèíáØÙÝïáõèÜäßßÝêæçéòáçêÏÝÜíëÚÞáèéÞéåáàåÙÚæÑéßßáÞÛèæëââèÞãâßãÛâÛåÛØæèÜÜÜÜßâéÜååâÕÔãäßåÞÛäæßãßååàÞàçÓáàèÞâÖòáÚÕÝäßÞÔßßàôßÜÜãØèææßßÛÚáëÜïçÜåàäâåØÚäÙÙØÝÞàÚÕÛåØÑÙåÝêßàãæéÒèÛâáÞåëëçÞâÕàçÝäåêèßÕâåàØäàãÜØàëÛêåçëÞáêâó‚ìÝÇ¿ÀÄËüÁÄÀÉÄÆ¼ÂÅÅȹÊÐÀ¼ÆÁÈÁÍÀÀÀÄÁÆÑƽÄÃÃÁÁȽ»ÀÆËÆÇÃÃÂÂÃÁÁÄÉÅ¿¿ÌɼįÇÄËÈÇÌÂÊÅÌË¿ÎÇÊÉÂÈÇËÈÆÆÑÉÒÐÄÏðêðãëæëæáääãçðïñæìçäðÝïîèôãóíèææäáìßÙòçìõöèàêåôòÜíåëèæíâóíèìðáñèçêæöêçáãæããìØæáâïèëçñçâÞûÛèâÞÜêáÝ×ßíãðóòæØÞéäòêèâÝðéëûêëíãêóäåíèêðãØêëæääóéîááâôèíäæîèæâäÞàåâçèêçæåàááßéíçæäïÝ÷ñäðâáéöéÝîîåáàíïçãíååñáúåòìëíôìîöæàèéãåëîáÛïçðëäóàéèôîçäõïíàíñãæàâéãäççãéõëìêðêôéæíïëîíàïëôìôíÜîÞëçíåõâèëæìæèâæÛÕßüêìêöæáîêêÖëãëßñåðÝíìÜèòõáèëãäæçìóíåáÜëêáÙêíÝèîóàèñýéÞííçäáèýêòîáóàáÞàäãèíßèìöèãéëïÛêßîäééæåñïäáéæíêÞäíèéáïçðæãïêãïïÝêåèóôäèêìèìîéÞíçëåëéâò÷æìëëìèëÝêîèîæìèàáàìßéìíìÞëáéîúõïçñõîòîãòãåßÞææéíëâáçìàíåìíâèòÛèëëëêðÞóúíÛÕéìíóãéëö×èêòàêæåñèðíòòõäïãñóéçæñãóêñçßÜáÞîéèèééæòöðèßïôìÛçíéôÕöóãëèøéíâãðìïôèçåØðôïéìõìçìí÷áïêçåæãåìóñíôååÝéÞÝðçîÛàåáñõïÞéæäâäãâáìíìëìäãùæÞæìëîæñìäÝâáëåÕÜçæêíëóåâêæåÚóéëßîêåéãìáæîôßãìãëèúâêåíåãçíðêâåïñâÙêÜàâðãâßíÙõãèæÛÚëáìåìãëîçÖâðíñêÙãÚåêçÙêöñíêæÞþåìäêïõåæçûåàêéèêâîâæòòîìèâõêâêëæçßßæäæçááøëÞîêçêÛëçéóíòòìâÞèÞæéâÿêïáåõîøèïéíâÙêìèçåí‚€ïãæåâàëéëëìïðåëåíîâñíèðâæÞßéç×éîèêïéâïßîÛãîäê÷ïêêâçêëõàïìñßáèææðÛáäéìåàóèÝäåäìîñçíÝíêèåæìñîëñëôäæåõéòâé×éêí×ÚäÞæëðæãòóíÝïäëåðâêàíùàçëäâìäîõêùòïã‚ãîòäòõÿñðò‚ï‚‚‚%‚E‚0‚‚‚,‚*‚)‚*‚‚*‚‚‚%‚1‚(‚‚‚‚ ‚‚ÿ‚ú‚‚‚‚ ù‚ñú‚þøðóïë÷áùíèêæïÞççôÞæñíèÞñÝíòãîìÖëííëæçäæëçíééãøìëâçìëÚâÛäíëçÜâìäñêèèáñîòïóìçóæóâÝæàôæåäðâãáüíåõïõÛöóâðíçßêçìãåëàèèäðßéãôéçÑÆÌÉÏÉÆÊËÓÎÅÊÔÆËÉÉØÎÒÉÍÉ¿ÏËÊÆËÄÐÀÊÉËËÇÈËÊÉÍÊÉÌÌÑÎÉÎÅÂÄÄÓËÇ¿ÍÎÑÃÅÐÍÌÃÆÎÀÂúżÁ·À¶º¿ÀºÁÁµº¶»ÁÆ¿À±ÓæàÜÖÚ×ââÍÕâÚÚÕåÖÒæÔÙÚÐØßÍÛØáÙãÚÚäØÔרÜèÓßäØßÍâ×ÝÖåÙÚÚÙÚÚÙæÜÚ×ÞÚØßÑâÓØÜØá×ÓÝáÙÞØÜÓáÒãÚÞêÔØßáÐÔÑÝÝÛáæÚÕÝàÛÜÚÔÎåÏÑÑÒÙãÝßÞÞáÈßææÞÖæàãÓÞÚÜâÝ×ÓÜÛ×ÚâíÝÜéÓÐááÜáÖÌ×ÕÙÒßáÔÕÜÙÔáÝèÖØÝÝõâÏ×ÛÛ×à×ßÜá×ÚÞêÐÛâÞÐÕÙËÞÒ×ÙèàÒßðÖߨàÐÔÝáÔÚר×ÙÛÕäÖÕÝÞÖÚãÖáèÄÞØÖÌØÒÙâÕÞÕÚÕàáàÖäÕØÞçäÔãØÒÜãÕÝÞÔäÚÞã×ÜÔäÒÔËãæáÛÕ×çÞßßÛÝÑäÌÜèãÑØÞáÔÙÞÏßÏäåÞÕÙÒÞÔÛàÛÓÞàÍØÞèÔàÕßÔÖÖÜÞàÒèÙØÚÑàåÛÝîÝóÕÛÕéØÚéáàÝÖÚËÙÕÞãâêÍÚæØÏÝÞèéÚßàÚÒÜáÝâ‚?ßÖÏÓØáÝÕÞÜØÔàÐÝàÑÏßÚàÜâÜÝÖÕÚÕÙêÛÚÓÎÞ×ÙåÝÝâߨ×ÜÝÛäØÙâÚÒâØÔßÎÕâßæåßáÜß×ÝÙáÕèàÒÝ×áÝÚÓèãÑÌßáëßÓ×ÝÖàáåÝÞ×àÌÚÜÓÞØáÔÖÚàØÛÑÖáÓçãÛßÜÛ×ÙÓáçÏÓÐÙÜ׿ÜÙÙãÞÝÛàãáÕÞÓ×ÔåâÞÌÚÖâà׿áââ×àÕÙÖÖÜÑÜèÛÔÕÞäÞߨØÝÓÕãÝäÍÞÕ×Ü×ÛÛÒÓÐàÜ×ÑÖáÛÚ×ÕÚãÏãàæØæÑÜàéÙÏÕâåÓèØÖïÛÛÝÙßßÕÐÙØÙÜÍÕæÙÞàåÙâÝêÛÖÍÚâÜÙ×ÕÙרÓÓÜÜãÞâÓߨñÚÔÒàÝÚÕÛÜçáçåéÓÕÔÛÝáÚÚÏÜàÕÛÛÙ×ÜÝ×ÕßÔÓÜÕââßâÓßßãÝÖ×ÝâÊçá×ãÚÞÙæË×ÛÜàà×ÔæåרààÐÚØÝçÖâÚÔáÓØÙרâÚÝßßÝÓ×ÜÐæßáâàÎåÍÖÇßÙã×ÕåÏáÔÔÝÜÓÚÓÞÌÕáØÝâÙÍÚÙÚÑÓäÜØÞÜÚÚÕ×åàÜ×ÓÜÜÛÝÑÞÙÜ×ߨÚÈÜàæÚÚÓÝßãâàåÖÚÏÓÜåÝÙÓèàÎÚ×ÙÕàâÖâÐæîÓàÜÑÞÛÙÕÐÛàÖØÛÛÖÚßߨÞÚàÔÛÞÛÏÛ×ÕÙÏÚÏèÜØÛßÓèáÕØíÛÜÕÙÙÚÖÖãäÖÕàÕêåרâÙÓâÎÖÒÙÕäÓÑÙÚàÕÚ×ÜâØÙÙÛßÜÙßÞßàÔÜÜÍÜÛßßÜâ××ÜÔÙÔèÚÜßÜ×ÜÜÜÓÜßÚÜÓÝØÖáÏåÝÕáÚáÞàÕÑÒßÛäßàËÖñßÞÙÞÙ×ÚÛÖÚÖàÔæßÛØåÚÞÛãæÞÞßÞÞÞÐÙÝääÝßÔÖÜÝÔÛÞÍÙÛÔãÏÚèÚÑÕÐÙÏãÙÜÖÝÕÙÙàäáåÕØÔ×ßåàÜáêãÝßÖãÑäÌÞÜÎÞÑÜÝÒæäíãàÕæÜÓåÜãÝØéßÞ×äÞÝââÚÜ×ÐÕÝíÛÓàÒÛÕéáàÌÞÙÚ½¿¾¾Àº»½»½ÀüÂÀ¿¹¼¸Ä»À¼ºµ¾º¸½Á¹º³¼»½¿Ã¾Å¾º¾ÃÀ¾Â»¼¼¼·¾¸¾¿À¼¹Ã¾Ã¾¼Åº½¾»¿ÀÁ»ÅÆÊ¾ÅÿÄÃÃÈÂÅÁĽ¾ÂÅÂÈÆÉÆâÜåëèÜçÛßÞîãÝêäÒÕØéëòàÛãàåìæëçæÜÙéáèØéßÝØÞâßêÛàëìØÕÝåØÜìèäâäÚê×åâæáÛæàßÞÜÞì×ãÝãÙíïçòåããÝéèáØèààãâçèçßàÝæÜÙïçÞ×äîâÚÙãçÖàÜæÚâáçâçâéèÝÔàáàÞ×ïââÝÛÝèìàîÙãßÜçßæÞçèââÙçéçààÛäßêáãàëââéîåäÜäâåâØ×ìÚèìÛÞëçàãäáâÛÞÝèÖÛáççØÝߨäëÛÝçåÝäáàááÚçÜêÞÞÝßÝèàÞâäÙØìÙßÚêåßìÞá×âëæÚÞêæêå×ßÑèãâÛæãââàáãÛãïéàêÚßæâ×íÜÚÛëçÙÙêâßáØëèãÔéãèëÚèåÜéêæåßÛÝáååÞÛåÝéàÞÙäãÜåÝáëÙââÞßîæßìãéäèÙèèáÙêìñáâëáèÝêÙâáâÛáçãäåàäêôÞçâÞÞáìâÙåßñäçäàãäâÜååôÜëáìáßÖÞÙÞæëãÛßÓßàâåÜìÝÕáâáëâÞßåÞÜâØÞÛÚæéÝåêæÚÞâàà×ääîîåÕÝæçÝÖäÙëàîÞÒâÙàÞâîåÚÚíéååÜãßßäØáÑßÞâæìÛÞãÞÛäëëçæõÛôçäÜñÞâèìåîÕæÙàÚÝÛÞé×íëÚÞéÕäçîëéÞæâÜâããßÛåáÝÝãóéù‚þäîÜçêåÞìÝÜøÝîçåÔÝéâëÚ×åéñÇÞÚäìçæãØäëÛéìáààãàääîèÙÛßçÛèëî×áÚÚàåãçéèêÛçèÛëèÝâÙØæÚØäçÜèéàçæâííßáâàèêÙÞãÞÙäØàØÚâççâáàáâàÕñçáäÞÓèÝéêéÛÞèåêçãÝïíåßçÝããæÖìèïßåáßãÙáôéÞìÝ×äÙäáåæÖâßÞâðçßßçä×âéãÙ××ßæÜéÚÝÜáÞâáãèßÛáÙéèßÛèíìâàÜäàáÜáàÞÝèçäèâêâÜÛîá×ãéãêáèàßàòëéçÛàßëèÞÞÛÚÝîæåÔäßìëáàúäéáøëÜßãÜÞãÜèãáòïãâååèèÛóÝÝéäÚåÐÝßâêäêêßãòáéÝäâØáÛêæç×ëåÞàÛååÝæßÛè×ÞåçãàäáÙêàÚäèæÔâîÚÞääæìäßãÝåçìÝääåÚàÞáæëäâñäè×ÙáâãÙáÙæÛåàèßÔߨ‚ìßáÜÝàÞãàâßèèàçßéàÛâãêßææàèáØòÞâÞÞïäáÝçãðäóäèßäãÛêàèæíìÝçäÞææçèÛåàáâçèóîý‚‚b‚è‚¥‚7‚ðôíäïéïçÞìàãØÚçæáçâÜååÜáÜßãóÜääááÜòàéÞÞåãáçÞåØâïëäåëäÚèáÛâàáÛÞäêèãìãîÖäÜåäêÚäéÜãæèæíæäÛèÚØáéàÞäãôéèàåöÝÝèççâàèêêéçÛëÜçÄɾÂÉÍÃǼÅÈÐÅÄÐÃÆÄÉ¾ÇÆ¿ÌÂĽÅ˾ÂÀ¿ÂÆÉľÁÁÅÅÆÁ¾ÍÃÈÁÁËÅÀ½Ê¿È¿ÈÊÁÃÀýÅÅź¿Ç¿¼É¿ÂÂÁÇÂÄþȿſ¿Â¸¿ÅÆÅĿŽãÜåæóæÚØèñâàââéÕäßãààëùäàéèÞÝÚßÛíåéäóØÛçÞØØãÝ×ÜàèÚßâäÚãÖæØàïäéëÙáÖÛÚÏðààÝåíÖØßäáäãàÜ×ãêäèãç×ÜÞã×ÞÙÞçÜÜäÜäÚߨçßÝãáÑÚåÕçßâãÜÞìÝå×îâØÛÞäãßÛßåÕãÚâàãßèçäáöçöåï×â×ååßßááïÝÖÔãÝÚØáèØÝÙìàÔóÖçßÐÛãèãØØÞæÚÛÝãàçÙ×äÙÙåÞäà×íã×ÞÜÞßßÙÜÙàãàåãÞáçÕíÖßÚÜááàÛáÜáÕéßÚÛÖéÞÖãàßÛáèèåäÜÒØÕÙÛØÖÚåÚÒÙçâÝççáÚâÙæÖÐãæåÝçëÜÏæãÝØßÕèÚïåÞÑÛâäÔÞâÛÞÙÕÞÚÛ×áÞÕÝÝåØàíàáéÚéÝÕâÜèëÜäæâÙßèÙÛÚÜÕëÜÒÔßÒáØáÎÓÝÚäÛÛáØÔãßàÞíîÝìÜâÔ×Öë×ËÓÖÝÚÖäÔÝäßÝÛéâåëÝÛáêàÍÜÙßãæßÕàÖæÝêãäâåÚÛÖåßÞââà×ààÛáâßëæàáãÐÚßÒÖãæÛÞÛÕåÜè×çîèáçÝåßéàãåæßÙÒàãØÛÞàäÑÛÛÛÙäàÒßÛÞæÛàßßäáàçèÜäáçÔÜÙÚ×âåääÛíîßÒÓÖàÜÒçäÜÎÚáãàßÚèÛÜÞåãÔåâÝÞåßÝâÛãØâÙááæäáÝÙÛàÚÞÜáÏÞØßááÛèÜÜßÝáàßàÞìÜäåÝßéáóèæÕØåÓßÚÞÞàïáÐéÛåÜÜçÙáÞæÜÛßÝÞÖåçÔÙ×Öáãéáç×ÞÝëæßÛí׿çæãØëÞÞæÜäáèàâçÝàáß×íßÖÚ×ãßäçÜÛìÝÞ×éãÖåîäàâÜá×ÚÜá×ÖìרÜÒãØØÕâÚÙÞæäÞÛâàæÞèàçæÚßéÒÚØÚÞíàäÚãèÑÙÜçÚÞàäÞäåÜçäÝÛâÝèàâÞååèÞêàçÖëÙßÙåáêããê‚-‚)áÖÜéÚÕë×ßÚßÔãââÛëÛãÙÖߨÙàìÛèÛâìÚÓÕâÝóÕêÚâÝááÙãÜíàäãáÔÙäçæÙàçãÞââÛÝÚÚÝ×àé×ß×å××ÜèÙéâÜæØÕÞäàèÞåÖæÝÞæåâéÓÚÜäÛÛíçÜÜÕâàâ‚QÒØÖÜàÙÜìæáÝàÝá×âàÛäåÙÌ×ÔäØåæãØéáÛæáÔãâïçÜØãÛÕÞáÞàÛäÙêÞÛ×ßæâÜàÚßÞÔãÝÝáæÕØáÙæÞÜáãæââåÛäÜÞÓÞÚØÙÙãÒèãØäÛáÕÓúØÝÒâïäÖßÜããÝèÏàãâæÖÝÏßÛÜâÎÝáåÛÜâØÏåãéÞÖÖãØ×æàÙáéãßÞçßÔÜáÞÏäÝÜìáÜãØçãí×èãßÒèÏÔÞÞßÜâãÞÒäÙèááÓîÜÝÜ×áÝæã×ÚÖêìáàáÛßàÞÒããÓèÚïâæÛèÛßãßÛÏÜÛÜàÔÞêÛêÕëèàÚßâߨÙã×ÔàÞÚÛ¾¼ÄÀººÅÀ»½Ã¿½È¼Ã½Â´ÀÆ¿ÂÃÅÄÃÁ·ÃÂÊÈŹÀ¿Ê¿ÄÀý¾Â¿¼ÄÁ½É¿»ÂÀÂÁ»Ï¹¿ÂȺ½ÅÀ¾ÄĽÒÈÒÍÌÐÓËÐÑÐÓËÒÏÐÏÇ×ÑÉÎÎÎÒÍÎóòíâæïèóëöñïóóúóëâÿôíçëìðîçñóôæõóòãôîôÜèõçóôçíçïìóëï÷ãêêøëñîöäÝæëëòçìóíðâòñçììéñåéìôçùñèîìñëøóêîéóò÷õíøðíîíüïõúüñêíçéóêýãôéïéúùçòëïóççòòãíÿïðïùåíõå‚ðìäöíç‚÷øéèéòøèëëàììèìå÷êíéïüñïñìðæîðïëåîéëñéëêïÝïèðüíúõñäêôñéêïæï‚çòëðãìæòôêæíßææþðõçúêðñðùïïòæâùëïðííöã÷ïóàúëîôïìîòùëôôíêìêñóîðøßîïèìôñîíé‚òöñëóîäâïèïéêóëíûîïíïçêëïðóéöóïâúðìõæóôõîÜôåð‚îíõ‚êïîóéóçííïëïçûàñïåèòëìñòúðîõíðìîáòîöñïìñöêßçéæêßïâðñíðãéóçòúòîð÷âñùôïòóéôøëþÞïòìçóöéééø÷îïçòòÚðíßä‚ðçóôòë÷åéòñèüýõîëåéøöãæòñêèåïäèìäëìïåæëêóóíùë÷åå÷êíò÷îëóîàìëðîíéðè÷èéñøéçüõëóîöÛèôããåðìèìöïìôìðòòæå÷÷òèììéñöíõúéêôñêíöéóíìöìðóïçåúõéïôçóûþõìíõìðëñôîóõïêïøîàééûðíéãìùïïæòðòíîå÷íïúèþåçïæôàëíðïôíéôíññòòêëÝïîúçîíåóêäæåñçíôïôëæâ÷îñðêóî÷ûäãïíñåæóðæßìñâééó÷êììâûìïìúèñåïôñóé÷ôäíûÞêððòìôîòôßîõõòåêåíìáãôñöêôìðêçãÿðëä‚ôêêõéëäòõíñáúëàðõéõ÷ôüù÷óðäóôöäèí÷íàëñïíöÞáïêñöëïæïòöçíëéôîõúêïóõòíçòäý÷ùðïåñúýêéìðöðöôôòôëù‚ñçëíëéâññøßîïúïðòòéõúìýêçîãìôïóòúóüíùñôóöòÖõóõòûúæîòóëï÷èìéùýïïúçöæîíöïçúäûòòíæ÷éûì÷ìâóðñøêñóäðãóôòäïîöåíïãïìïîðòêéëïòúéîõîïëûòêùæôë÷ùêôéòìñïîùöøâìî‚ +SIMPLE = T / conforms to FITS standard BITPIX = 8 / array data type NAXIS = 0 / number of array dimensions EXTEND = T NEXTEND = 1 / number of array dimensions DATE = '2024-08-17T06:05:12.0' / written date (yyyy-mm-ddThh:mm:ss.s) FILENAME= 'CSST_MSC_MS_WIDE_20240817060512_20240817060742_10160100000_09_L0_V01'TELESCOP= 'CSST ' / telescope name INSTRUME= 'MSC ' / instrument name OBSID = '10160100066' / observation ID OBSTYPE = 'WIDE ' / observation type DATASET = 'csst-msc-c9-25sqdeg-v3' / dataset RADECSYS= 'ICRS ' / coordinate system of the object EQUINOX = 2000.0 FITSSWV = '2.1.0_20231208_wcl-5' / FITS creating software version COMMENT ========================================================================COMMENT OBJECT INFORMATION COMMENT ========================================================================OBJECT = '60000000' / object name TARGET = '161953.0+395345' / target name (hhmmss.s+ddmmss) RA_OBJ = 244.972773 / object RA (deg) DEC_OBJ = 39.895901 / object Dec (deg) COMMENT ========================================================================COMMENT TELESCOPE INFORMATION COMMENT ========================================================================REFFRAME= 'CSSTGSC-1.0' / guiding catalog version DATE-OBS= '2024-08-17T06:05:12.0' / observation date (yyyy-mm-ddThh:mm:ss.s) SATESWV = '0001 ' / satellite software version EXPSTART= 60539.25361 / exposure start time (MJD) CABSTART= 60539.25361 / first cabin time after exposure start (MJD) SUNANGL0= 50.0 / angle between the Sun and opt axis at CABSTART MOONANG0= 30.0 / angle between the Moon and opt axis at CABSTARTTEL_ALT0= 20.0 / angle between opt axis and Elimb at CABSTART POS_ANG0= 20.0 / angle between y axis and North Pole at CABSTARTPOSI0_X = -2218.3663 / orbital position in X at CABSTART (km) POSI0_Y = -5817.8559 / orbital position in Y at CABSTART (km) POSI0_Z = 2597.9467 / orbital position in Z at CABSTART (km) VELO0_X = 5.058199026407237 / orbital velocity in X at CABSTART (km/s) VELO0_Y = -3.85818799871231 / orbital velocity in Y at CABSTART (km/s) VELO0_Z = -4.322908628205369 / orbital velocity in Z at CABSTART (km/s) EULER0_1= 0.0 / Euler angle 1 at CABSTART (deg) EULER0_2= 0.0 / Euler angle 2 at CABSTART (deg) EULER0_3= 0.0 / Euler angle 3 at CABSTART (deg) RA_PNT0 = 244.972773 / pointing RA at CABSTART (deg) DEC_PNT0= 39.895901 / pointing Dec at CABSTART (deg) EXPEND = 60539.25535 / exposure end time (MJD) CABEND = 60539.25535 / first cabin time after exposure end (MJD) SUNANGL1= 50.0 / angle between the Sun and opt axis at CABEND MOONANG1= 30.0 / angle between the Moon and opt axis at CABEND TEL_ALT1= 20.0 / angle between opt axis and Elimb at CABEND POS_ANG1= 20.0 / angle between y axis and North Pole at CABEND POSI1_X = 0.0 / orbital position in X at CABEND (km) POSI1_Y = 0.0 / orbital position in Y at CABEND (km) POSI1_Z = 0.0 / orbital position in Z at CABEND (km) VELO1_X = 0.0 / orbital velocity in X at CABEND (km/s) VELO1_Y = 0.0 / orbital velocity in Y at CABEND (km/s) VELO1_Z = 0.0 / orbital velocity in Z at CABEND (km/s) EULER1_1= 0.0 / Euler angle 1 at CABEND (deg) EULER1_2= 0.0 / Euler angle 2 at CABEND (deg) EULER1_3= 0.0 / Euler angle 3 at CABEND (deg) RA_PNT1 = 244.972773 / pointing RA at CABEND (deg) DEC_PNT1= 39.895901 / pointing Dec at CABEND (deg) EPOCH = 2024.6 / equinox of pointing RA and Dec EXPTIME = 150.0 / exposure time (s) COMMENT ========================================================================COMMENT VERIFICATION INFORMATION COMMENT ========================================================================CHECKSUM= 'GflkHfiiGfiiGfii' / HDU checksum updated 2025-04-30T14:18:49 DATASUM = '0 ' / data unit checksum updated 2025-04-30T14:18:49 END XTENSION= 'IMAGE ' / image extension BITPIX = 16 / array data type NAXIS = 2 / number of array dimensions NAXIS1 = 20000 NAXIS2 = 4700 PCOUNT = 0 / number of parameters GCOUNT = 1 / number of groups BSCALE = 1 BZERO = 32768 EXTNAME = 'IMAGE ' / extension name EXTVER = 1 / extension version number BUNIT = 'ADU ' / physical unit of array values COMMENT ========================================================================COMMENT DETECTOR INFORMATION COMMENT ========================================================================CAMERA = 'MS' / camera of main survey DETSN = '12345678' / detector serial number DETNAME = 'CCD' / detector type DETTEMP1= 173.0 / detector temperature at EXPSTART (K) DETTEMP2= 173.0 / detector temperature at EXPEND (K) DETTEMP3= 173.0 / detector temperature at READT1 (K) DETSIZE = '9560x9264' / detector size DATASECT= '9216x9232' / data section PIXSCAL1= 0.074 / pixel scale for axis 1 (arcsec/pixel) PIXSCAL2= 0.074 / pixel scale for axis 2 (arcsec/pixel) PIXSIZE1= 10 / pixel size for axis 1 (micron) PIXSIZE2= 10 / pixel size for axis 2 (micron) CHIPID = '09 ' / chip ID CHIPLABL= 'r-1 ' / chip label FILTER = 'r ' / filter name NCHANNEL= 16 / number of readout channels PSCAN1 = 27 / horizontal prescan width, per readout channel PSCAN2 = 8 / vertical prescan width, per readout channel OSCAN1 = 16 / horizontal overscan width, per readout channel OSCAN2 = 16 / vertical overscan width, per readout channel COMMENT ========================================================================COMMENT WORLD COORDINATE SYSTEM INFORMATION COMMENT ========================================================================WCSAXES = 2 / number of WCS axes CRPIX1 = 4600.694649742984 / x-coordinate of reference pixel CRPIX2 = 4604.383757040574 / y-coordinate of reference pixel CRVAL1 = 244.5872723135913 / value of reference pixel on axis 1 CRVAL2 = 39.68195466168969 / value of reference pixel on axis 2 CTYPE1 = 'RA---TAN' / type of RA WCS projection CTYPE2 = 'DEC--TAN' / type of Dec WCS projection CD1_1 = -6.8096767434962E-06 / transformation matrix element (deg/pix) CD1_2 = -1.9394088718019E-05 / transformation matrix element (deg/pix) CD2_1 = -1.9394079613547E-05 / transformation matrix element (deg/pix) CD2_2 = 6.81009530128767E-06 / transformation matrix element (deg/pix) COMMENT ========================================================================COMMENT READOUT INFORMATION COMMENT ========================================================================GAINLVL = '01' / gain level GAIN01 = 1.089977689498424 / gain (e-/ADU, channel 01) GAIN02 = 1.099175619835018 / gain (e-/ADU, channel 02) GAIN03 = 1.107649165474623 / gain (e-/ADU, channel 03) GAIN04 = 1.121722214644728 / gain (e-/ADU, channel 04) GAIN05 = 1.081220797968546 / gain (e-/ADU, channel 05) GAIN06 = 1.09456272850753 / gain (e-/ADU, channel 06) GAIN07 = 1.111430472148367 / gain (e-/ADU, channel 07) GAIN08 = 1.105606424366627 / gain (e-/ADU, channel 08) GAIN09 = 1.101874970320761 / gain (e-/ADU, channel 09) GAIN10 = 1.085064046871988 / gain (e-/ADU, channel 10) GAIN11 = 1.12218772525153 / gain (e-/ADU, channel 11) GAIN12 = 1.114934178226512 / gain (e-/ADU, channel 12) GAIN13 = 1.119336504852553 / gain (e-/ADU, channel 13) GAIN14 = 1.093036190194986 / gain (e-/ADU, channel 14) GAIN15 = 1.084334798104931 / gain (e-/ADU, channel 15) GAIN16 = 1.090894538052644 / gain (e-/ADU, channel 16) RON01 = 5.0 / readout noise (e-, channel 01) RON02 = 5.0 / readout noise (e-, channel 02) RON03 = 5.0 / readout noise (e-, channel 03) RON04 = 5.0 / readout noise (e-, channel 04) RON05 = 5.0 / readout noise (e-, channel 05) RON06 = 5.0 / readout noise (e-, channel 06) RON07 = 5.0 / readout noise (e-, channel 07) RON08 = 5.0 / readout noise (e-, channel 08) RON09 = 5.0 / readout noise (e-, channel 09) RON10 = 5.0 / readout noise (e-, channel 10) RON11 = 5.0 / readout noise (e-, channel 11) RON12 = 5.0 / readout noise (e-, channel 12) RON13 = 5.0 / readout noise (e-, channel 13) RON14 = 5.0 / readout noise (e-, channel 14) RON15 = 5.0 / readout noise (e-, channel 15) RON16 = 5.0 / readout noise (e-, channel 16) ROTIME0 = '2024-08-17T06:07:42.1' / readout start time (UTC) ROTIME1 = '2024-08-17T06:08:22.1' / readout end time (UTC) ROSPEED = 10.0 / readout speed (MHz) EXPTIME = 150.0 / exposure time (s) DARKTIME= 152.0 / dark current time (s) COMMENT ========================================================================COMMENT SHUTTER INFORMATION COMMENT ========================================================================SHTSTAT = T / shutter status, T=open, F=close SHTOPEN0= '2024-08-17T06:07:42.1' / shutter open time (start, UTC) SHTOPEN1= '2024-08-17T06:07:42.1' / shutter open time (end, UTC) SHTCLOS0= '2024-08-17T06:07:42.1' / shutter close time (start, UTC) SHTCLOS1= '2024-08-17T06:07:42.1' / shutter close time (end, UTC) COMMENT ========================================================================COMMENT LED INFORMATION COMMENT ========================================================================LEDFLAG = 'main ' / main/backup LED LEDSTAT = '00000000000000' / LED status LEDT01 = 0.0 / LED01 flash time (ms) LEDT02 = 0.0 / LED02 flash time (ms) LEDT03 = 0.0 / LED03 flash time (ms) LEDT04 = 0.0 / LED04 flash time (ms) LEDT05 = 0.0 / LED05 flash time (ms) LEDT06 = 0.0 / LED06 flash time (ms) LEDT07 = 0.0 / LED07 flash time (ms) LEDT08 = 0.0 / LED08 flash time (ms) LEDT09 = 0.0 / LED09 flash time (ms) LEDT10 = 0.0 / LED10 flash time (ms) LEDT11 = 0.0 / LED11 flash time (ms) LEDT12 = 0.0 / LED12 flash time (ms) LEDT13 = 0.0 / LED13 flash time (ms) LEDT14 = 0.0 / LED14 flash time (ms) LEDTEMP = 173.0 / LED temperature (K) COMMENT ========================================================================COMMENT VERIFICATION INFORMATION COMMENT ========================================================================CHECKSUM= 'fV9ghV9dfV9dfV9d' / HDU checksum updated 2025-04-30T14:18:51 DATASUM = '3747953988' / data unit checksum updated 2025-04-30T14:18:51 END ÅÄÅÍÍÁ¾È»ÅÇȾÃÁ¼ÃÇÈÃÇÌÁÃÂËÊÚÓÙéæêàéèæÞáÝêæáåå×ìÞäôÓæåâëÛàßÝäèÛîíàßáÝïâÓæ×äãßãæâæêàØÜêâêäéäâãëåééÜêãááßáÙáçÚãàëéÛãÛæêÞÚÓáéðíçëèêÝæçîÜòèççáèâáçîèàåßÚæäàëàÚâÜÞÛãèãßååÚêæíåÞ×ãæíäêçñèæÝãíæïìæåçâ×ÝæÛÕáâÜÒâëâàÕäâÚìîððíääííãçéàâêéßáðöäÜèàêéÞÝçäÙäæÞéáÞãÞàäÛé×âäÜäáØÝèâàÚãÞãîëâçèâäâîàòëßéÙêàèíæàåÞÙãââïåèæÚßçéÖæêÔÝçéçëêæßÕéäàÓäâãæëéæâ×ÖåæèäÝßéæãÐàáçßëÝëÝÚÞÞäæåÕíàÒÖààìéíäêôìðô‚ óìðôïåÑÝéß÷àÛÞÙßëçðïèëñàãÝèêîêÜãåçäáÕáëêÞçòâææêÜîòëØèåèáäáíäïåèäìèßàãßßåÚâñææìæèëääñõêêàÞóðÓÚéÙàÒÞéíæÞíãæââÜáèÝàÓèñáÔÙáàáççáÛáéããæáÜÜáçï×áãìâäàåæîëäÜéäÖÝáâÙáðéØêäèÜâãìííìÛÝÜïâßêæáçèêéäãâÖôáðééíñòîëñêìéñìéæááåÛîäåâßÞÝêàÝâåææÒÞèÛíÛÜèñæéßáßÜêØÜãêããææðéíÙæçâÚâßíðäàí×îÞäðØààÝçæßÞéããÕæâæÚáåÙéääæáÝØàßéåçâéÚÝéîÔæéìââÛÞèááÔâèØæçÙäêáçàâãæÚØâàåÞÚãÙâèå×àßâÝéàÛâÛéäàëàÝãàéâçßÚÛèäæÜçØõÚÞåæÓäçÙëäÝàààææßÝìêäïåâÙæ×ãáåèðßéâêãçæÙèçÞÜ×ÚÝðÜãàÞåâçÐíØÞèãÛçãÛçÕØæÕåðäîïââãæÜÜÞâãâåâÝðìÚßçèÛØÚêõêæëîÕëëÞââ÷ä䨂xåïÛÛåÚêìÙâáàâÞàëÚéîåáâÜôØìØÚÚåÝàÞëÚÕòåãëÚäôàßÝãäåéÝàáæêëâÞèÞâÛéàêâÝèæßâáßååäâòòáéäáéçáâàãØëÒëáèåßëèÞìéåæÔÞåäííçÞèæëâïáÛÞáèáì÷ãÝäààßèñíðã×çÞòèÝëæÞéßçÚߨßãÜÞãàÜàèêêìîèÝ×ðßèåÛãéçêæãÕîÝÛàÞèñÙáäééåäßêîíâØåéâÜÞìåãåéïÞáàñÓçïÏîØáëñçÞçåØçÝÚîãÓæáâçåèÛÝèÛÛÚíàÛäçÙêææåéäâèßçæÞØòèÚáîéïâæåäâéëßåÝæâããáëìåàáÞÚåéàÙóàãßéâæ×éãæßêçáàåæãâá×çéååØÃÂÂÅÁÄÇÄÃÅÌÁ½ÃÁÆËÆÄÊÇÅÄŽÁÅÞÅÇÉÆÉÌÁÈÆÉ½ÂÉÅÆÁÈÅÐÂÁÀËÄÈÂÄÈÄÂÊÆÈÅü¿ÅÆÂÈÄÉÇÉÁÍÁÐÍÇÇÍÊÄÊÇÅÊÉÑÉÊÐÌÄËÐàèèëãðààêèßñêðøâîõïÞæÚêñéëæìãêæïêûéüÞòïèñâÝûääñáïÕßæíîàçëíßìßêîñæëìßéæÞâìèçôîÞÜåÞéëîäíæîéíìíÝàãçÛÜëçèäèÞåæåãçàìèáåßëãçäëßå‚éèäæõèæûÙéäïáãëìßíÛèóôèêñèìæäâìëêÝèíêëàééïëéðîïàñèææâåãîä×éÔÚäêßãìïîãâàéèêêëçêéï‚‚‚ ‚ðæççãäêäéìèÞéðïäîãìîòäÛäéäæèýäàðêóëëíñáîæêÜäëãééæãêêÝÞæåãëðãÜìîàìðíçóóÖßãåìîíìïïáàççëìáóüæåàèïóÞÞêìêéÛêùæìêäïñöößçäáìììëëçéæáéâåÞåææçóéôìîçôçåàêìùæåìàØîâîèéõðìíëêãèïäùëèêìççßõåõêÞÞëêôíäáêæåëêêéêåëåæóåëåèéðççáÕçøëçßÚêéêïäÜßéõèÝæãêêãéæèæäëàãÝæãïíçàëáîåááñöõÞÞëàßßóÜçëéÞêîêæ÷ðèñáðîáøÝêäêçÙìäæâæáÜãêâæîãßçåÝòíñìñÝæÞèíàéÞâîéçéäÛêìèäïãæìîæîçÞìûèéííæàäêêæÜåââØêãìÝáã×ìèééßïçèäçãêâçíñÞìîíàçÝäáïêåèêçëÞíÔäéøæáðâäëêçàáäëàõõéãêìçæáçíçòâãâÜæëääñèíêæóÜåëåßæøãðèéäêæììæäåêñèå×ßÜòçèñéßïø÷ÜõïäèäîèæïßçâèîáÖäÞÜæìòâñåõÝéëåéëáÙããíçéìÞçåäîæíçéñâàîåæçÞðååÞçäåìêæçíèåçòøäíÝê×íì׿êÜçåëîÝîêÛéÛäèáñãåßéäìëêêåûççÛñ×ëéïæçîßßæöæîàåÜéôì‚‚$‚ôêîåÞáçâçÞàññãéãÝëâèêéøñãíéåçíåøæßäõæãæÞØëìßõáåäïëçîâßÞéÙáôæíñõåêèç×êéïãíÞíüîäòêäñÜÝõòëãäòñôáçìäàêäêåÜéèÚßòäâêñØáëßîëôúçðáíïðÚå÷‚cãÝêìäïáçèåçöóáêâëëìæîêÚðïåðåäåâëçñéåãäþâåæûîòèðäëãîáóíèæ÷ìæáîêäíáèßçïìÛëàâëêíãåëãææéÓäëìæîóëååãîáôðçãéîîèëããåöçæåæçñéíÙäÝçèäèêîáççòÞïäââëëü÷ÞæéåéèéâèãíéëáàÝèÜÛàáäíðçðîìöçåâåëëÞáçâóñðââÞæáãåçìÚïèëäëðåçêãèáôôÅѸÌÄÆÌÇÌÅÁÑÁËÒÍËÈËÉÈÏÈÄÈÑÂÉÉÎÌÂÔÊÊÊÌÊÈÈÄÅÈÁÏÁÊÈÅÉÂËÍÆÌÇËÆÆÇÆÉÊÏÆËÐÄËÊü¼¶½À¾¿µ¾½·¶½º½¸¸¿ºÀµ¾À¾¸Á»×ÙÕÓÚÉ×ÏÏÑÜàØÞÎÐÕÔÕÜÚÝÑßËØÜÛÞØÞÓßÓßßÕàÖÝÓÞÚÓÔÔÐÒÓéÒÜØÕÚÏØÖ×ÍÕãÐ×Ï×ÑÙÞÛÒÚ×ÕÜÏÕÐÔÜ×ÍÖÔÖßéÑÛÒÒÕÏÕÔÕÌËßÚÊÒßáÏÚÑÝáÝÙÓÌÝßàÜÞÛÖÝÝßÒØÖÖÚÑÜÛÖËãÏÍÔÔÚÏ×ÚÐéØÌæéÞÔÔÙߨ×רØÐÒ×Ý×ÖÝËâÐÑÑÔÚÖÔÛÊØÐ×áæäßßÚÎÙáÝáÞÑÙáÖÙÕÒÙØÚÔÙèÞÏÜÛÖÚåÞØÔäáÛÛÖâÏÖÖÞß×àÔÐäÞÚ×à×ÖàØÙáÜØàÕØÝÒÞÕÞØÜÙÐáÑÜáÑ×ßÖØÑÚäàÜÖÕÖÞÝÓÝÔàÆâÔÓÏÞÌÐÛ×ÕÛØÙØÙ×ÙÈËÏ×ÚÝÖÜÙ×ÐÔÖÞßÔâÝÑÎÔáäÛÛÜÙÓáÎàæÍÏãÚÜàÔÔâáÖÖØçÖÊÏÓÝÞÖàÑÝÔÓÏÔÔÐÚÓÔßÖÙÙÓàÕÝØÒÔßÍÑÝÒ×ÙØÛØÍÕÞÜÝÒâÝÔÔãàáØÕÛÏÌâÞÔÏÚÎÛÚÏ×ÖßåÛÉßäÜÇÝáÏçØÕàÕÙÑÔÙßãÑÕÜÞÔ×àÛàëÕÜØåäÔÙרÛßßÖÔ×ãÚÛÝßâÐæÙâÊÔÓáÜÞ×ÑÛÓÙÑÙØÒÕÝÙËÖÝêÝÖïÚàÒÒÞÔÕÙÙÝäÐÙÔ×çÔÔÖåÒØáÑÙßÖÑÖÖÔáãØÓÕÔÕÙÓØÙç×ÌÛìÖâßÞÚÜÏÛÛçÐÕÛÊÓÓ×ÕØÛÒÙØ×Ü×ÔÛÝÛÑÓËÞáÎáØÙÛÖÍãÚ×ÚÞÕÈÚÕÞäÕÜáàÚÔäàÔÜÜÎÛÔÏØÍÕßßáÚÕÏÕÌâÈÚÚàÙáÓÃÖÙ×ÔâÞÓߨÖàÓÒàáÜÕÛÜËÐÏÕÓ×ßÊÕåØÑ׿àÚÔÖØáÚØÞÑßÛÞÍÍÎÔãßÔßé×ÕÙÎÉÝØßââÒØÚÖã×ÔàÒ×ÌË×ÚÜÐÏÑÄÓÆÜÛÝÑßÙÚãÚÕÙÚáÑÝçâÖÝÜÙçÌìÓÛÏÚÑÕÔÞÏÖÝÔËÖÐÔÛÕÔÊÍÓØÑÔàåÛÛÖâÔÕÞÞÐÐÏÜØ×ÕÓ×ÚÞÔÚãØÐåÜÛÞâÔÞ×ÞØØÕ×ÕÝåÔÔÜÖÙæÞÞÐßÓÙÚÙÊÜÕÛÎÚÚÞÏÙÎÛÝÚàÏ×Ù×ÝÖÞàÞ×ÛÚØÞÚäÐÛØÚÚÛàâÑäÚÛ×áØÒÕÞÖÏÚÕÍ×ÓÄÛÏÓÜçàÛÓÝÕÛìÔÓÔÜÎÞ×ÚÔßËáäÏéßâÝÒËæâÞÚâÙÜãÑ×Ô×ËÕÓØÎÖÑרÛÎÏÓÛÓÚÝäãÓÙÝØÓÖÌ×ÓÍÚìàÖÛÙèåÏÜÖØÌÚÚÚÝÚØÑÌ×ÕÜ×ÜÝßËÞàÔÓÞÚÔߨ×ÝÖÛØà×ãÞÛÛàÉ×ãÜÚÜ×ÕéâÞÛÞ×ÛàßÞèÝÝàÓ×à×ÝÜÙèòÖö‚÷î÷âØÙÛØÓÚÙ×ÙÊÊàÞãÊÜÄÎäØÓÙÌÖßÓÞÔÒàÏÜÍÝÛÞÖáßáØÞÕÚÔÓÜåÛâ×ÔØÒÝÙÞÖÔ×äÛËߨܨÞíàÊÜÙÔÞ×ÕÙÝÒÛÙÓÙÝÜÚéÏÈÝÓÒÙÔÖÕÎÛ×ÕÙÎÖãÝæþ‚÷áíäÝÕĶľ¾Ã´»Ã¸¾¶º¼·¼À¿¹¸¹Ä¾»¿ÃÀ·»À¸³ºµ¹¾Âºµ±¶¶Ã»¹¶¹¹´¶·¶Å··¾¶½¿ÆÃÀÁ¸¹»º½¶¹´º¸®±¸·´·¹±¶¹»ºµ±º´·¸¶Âº¸°³¹½ÌÐÊÊÔÕÒÍÖÌÙØÔÑÊÓÚÔÔÎËËÙÓÐÖÒÓÕÛÞÒæÙØêÏÜËÖ××ÚÑÒÎÍÓÏÒÊÚÜÛËÖÏÓÕÐÒÓÍÌãÑÒÌÓßÒÞÚÏÓÑÐáÆÖÎÜÌØÔÐÍÒÚ×ÔÖÔáÍÓÚÚÏ×ÝÒÎÙÑØÏÐÛÑâÓÒÉÍÑÔÙ×ßÝÏÓÊÜæÖÞÏÓÜØÔÛÛÕÝÒÜÑÔÛÙÖÖÎÙÙ×ÚÒÑÓæ×ÔÖÐÔÌÛÝÞÎÜÈÙÚÓÍÖßÖÕØÕÖÞËÓÓÒÔ×ÓÛÚÓÊÑÍÉÉÔßãÊÝâÖàØÛÖÜÔßÔßÖÔÔ×ÉÖÙÔÌÜÐÏÔßÝ×ÕÑÕÖÕÔÏÔØÑÖÏÓÒÖÖÊÐÅÕÐÒ×ÔÒÕçÝßÑÜÚàÏÊÔÌÜÇÉÎÎÓÙÝÏÕÒØ××ÏÚÜÏÚרÑÏÒÙËÐÓÓÒâÝÎâÔÄØÒÔÚÑËÕÏÐÚÍÖÛÚáØØÔÓÍ×ÏÏËØÆÐÔÛÒÕÖÌÓÚÊÐÏÎÓרËÞÕÜÔÍÙàÛß××ÍÕÏÅÍÒÏÙáØÔÕâÙÌÜÓÓÕáÒÐÕßÐÒØÎ×ÒÒ×ÚÚèÌÜÞÞ×ÕÊÑÒØÛÏÜÁÕØßÎØÉÙÔãÓÝÑÌ×ÔËËË×ÏÔÕÏÆÝÄÓÏØÌ×Õâ×ÙÔÎÔÜÍåáÜÜÎ×ÖßÖÙÊÏÎÐÒØ×ØÕÙÝÖÕÐ×ÌÓÖÎßÐÖÕÔËÙÛÝÝÝÅÌÎÊÖÖÚÖÛÉÛÝËÙÔäÐÐÓäÐÚÒÖ×ÔØÉ×éÖØØÉÓË×ÔÝ×ãÙßÖèÐÙÑÓÖÕÔÚ××ÖÞäÉÎÒØÑÌ×ÎרÐÏÏÜÕÙÒÛÕÙÕÌáÕØÐÏÒÛÝÙÖâÚÕÍÓÉÓ××ÍÔØÖÑÛÒÏÎÞÖãÙÞàÛÑÒÐÌÚÍÚÓÓëØÕÝäÍÎÌØÓÖÚÜÎàÖÑÙÐÎ×ÓÚÔÎßâÉÇØÑÝÜØÏÑÍ×ÏÙÌÑÎÎÓÝßÚÛà×ÑÏÓÏÕÔÊÝÖÌÕ×ÚÒÕÞÓÓÐר×ÔÞÒÖÞÐÖÕÌÔÛÒÏ×ÕâÜÒÞØÛÛÑÒÓÑØÜÔÜÝ×ÏÔÉàÖÔãÍàÔÜÔÏÎÛÕßÐÚÔàØ×ÏרÓÕáØËâÀÕØéÌÓáßרÐ×ÙÐÑÔÖÒÍÖÏèÕÙØÑÎÓÌØÏÑÏÕÑÝ×ÝÚÖâÜÓÜÓáÐÞÖÎÓÕãÛÛÑ××ÌÖÖÒØÓÎÑÝÓÑÓÖØÖÌÐ×ÓÔÝÕÕÙÛÙÑÛÌÒÍØÏÝÊØÝÛÌØÖÖÛÜâÕØÄØÒÜÚàÕËÓÓÏÖÕÚÙÓÓÑÝÖØèÜáÞÙÕØÈÌØÍ×ÛÊßÔÐÖÚÍÖÕáßÍÛÏÙÛÞÔÎÇÔ×ÎÑÑÅÖÒÔÚÞÔÙÑä×ÔØËÒÕÓÝÐÎÐãÚÔ×ÖÐÖÓàØØÐÐÕ×ÛÚÐÓÏáÖÜÖÛÒØäÛÒÞÛÎâÕâÎÖËËÍæÖØÇÔÍÕÙÐÎÒÐÐÔÔßÖÕÓ×ÍÜ×ÒÓÛÓÜÖÔÒÏÉÝÜÅÛ×ÚÓËßËØÓÒÍÑÙÓÖÉÑÚàÚÙÐÕÔÔ×ÔÎ×ÌÏ×Ì×ÑÊØÚÖÕÝÑÒÛÏÙÙÑ××àÚØÙÐÈßÕÙçð‚ ìÐÐßÌØÒÛÓÕÎÖ×ÏÐ×ÔÕÎÒÜÉÖÒÖâÙ×ßÔÖÖ×ÚÖ×ÉØÔÙÑÔãÓÇÜÓÙÔÙàÜÚÚÛÍÔÞÛØÑÖÐÐØÕ×ÜÜÕÚÉÏÓÖÛÚÓÊÝÌÙÒÔÑÖµ²¹®º²µ²µÀ¸´º¿²µ´»¶¸¼³´·º·´¹º·¹Á·¹º¸¿±²µ±µ°¹»­Ã´¸¹º¸¾¼ºµµ®µ¼º¹µº´¿ºµµ¼ºÉÔÏÂÎÐËÎÎÆÊÈÌÉÈËÒÍÐÇÐÑÆÍÎÊÍàìåèãëêèêîàæàæèåíéöñìêéâïññÞõáïæíêìëåóøáç÷éñõáçììèéòüçëçëñíìíúåèêäßñåäìáëÜóèÜðíâáóíòçåáñáçãìíçãïÛÙåÜëãìéíßóââñöâßÜîìéñâçèìëõõåáåáõÝñíèßëçíããéâðîõéñðøôÝïïíêêæ÷éæíé÷êàèáñéçéâèôëæäçëàæêôæóèïíêêàóñëôòåâîóçùù÷Õðçðî÷êéòïàëêëëõçôæìäïàâòãñæääùéëðéæçîçåðéñèäëêììææòíòßÝðÝêõÛÛêèêïßäðìæÝãñêòðáäùêõíêçíôçõîÞêåèíçêóïíëáêåîúîîëôàäåçéçìãëêççêèïíéçíãããïæëóìåõõõàßæèíÜåàéòðìäîèøöëäêêñíùíìâðïðæìôêßãòäðëãïîôãâêîàêóùÙìéêúßìøæòèòðñãîáîÜäâðéäâéîëäãíéæìÜåèéùÝòÝéìàîèåíãã÷ãäññäáùåæõßíèëðééÝòêèÙèý÷áñçíäéæçðåÝæàøæðéàáåóçóñÞáæåçüíôïõãîîõíäôçèîãããáêáñãóéëçìîäïåãæìéææáèëóêãóãæêéßåèÛèßêãðäêâÞìîæñæöçôìñîñÞïïíêíìïâðìæàèëìòðóåèåñîïêåêéèéíæçíåèÞéëéëííøÞèþìîûøðçéèßãëãêëÚëèëèôåëóìñîíãïýóïàçéñéééãêäûäèâúäíïèÙßíççèêëãîëíèéÛäòãåèçåïíïèíèöåâíííãêìïëíêñ÷àçîãêðéÜðæçíãæãéîÜÞãäÛãáàêîìãëÝëÝææôëûæïîããßàñìïçòèëñëåõßéññèôëÜæÜåêñãçÞäóïîòÝêêõØéðó×ïèêèìçåðèíïäïçîèáäêßõêòæáõÖæãåéåóàåëêâÝïòõïééìêîïêáçâàñîåëéêèâÖðèÙéïïâå÷äïæâñëèäêóéãæææççñíããéâåèèßëìæìíæÝíðâêîðëðîùïåíÙöòáäâãæäâñâàéóïÞéïêáïïåèåáçééîæåëëè÷ääõäåçãïìáõéóäçéãåìäêéçíøõëíááææâÝáàÞïãçôãïîíïóìèáéòñáèæàëèîìøáùéòçñêêÜØéìñçøìïáöêáîùòãêúüîèæáðáøëëâóçõíòèìãçîîèéëéßæÚòèîëæáèßàéåêäæíééñòéîóîåäçêæððæòææìÞíôÜóæáíåééçíóöõðëøêèòúåàóìæêïßìòòôñëîËÅÈÍËÊÀÒÄÃÍÅÏÏËÊÔÌÉÊÏÎËÉÆÆÍÌÒÍÊÇÓÕÈÏÃÌÒÏÓËÆÊÏÆÌ¿ÌÄÇÆÒËÌÆÏÍÈÊËÏÆÂÌÃÉÂÈÑÉÏÈÍÍÈËÎÏÌÑÌÛÔÏÏÈÐÓÑÎÑÊÊÇÌÊÐðëóëã÷äûçíéõåíéíìñçÙàèò÷éîêëöñÞõñõóôëäïæîîéñëôëíúóñôåëèäíèæëùëìßóòèèòíõôèîçåâêòðëòöøêþâúë÷êñÝðçõãîíïîþéô‚òæäèãêçïêñõóãñÞñååîòæõñöðôïúíþèæïæíéíêéðéðäéøòãäìòåêæéëïðíéûì‚ó‚sðåìôäëññäñíîíñæö÷òòåàòëëôîòèöíäÝáòìõ÷èðîïííèêíêãóñóìøîñîôõäçöðììéûúñëñéïððìóùñýâûöëðäóòïöóããßîåæòéðíïñöæïêòëåèíëòóêèìðîèéúöâïåôïåèôñèöðëçñæíìòäåèêõêòå÷çíýèðòòçíè÷öóåóåöáîñëöçðóéíóôçïêìóõîîôäìòðïôéôíìïîïèïðíèâìæñãìêéëéííåìõûâóìñìïìõðôóíîöáæ÷óúóßäóûçîîûäÞíèöìèéíëñêìíìèëâäìõèíïñêêèâïåêãññ‚èßòùëâçíìôèîùóîðèøúïæéöíñîêïôçêëèîìæçáãóêðïçäîìóõ÷ïïïïñõïóëñìòèðíùóúóæöóçîãæðêùçúîøâüéíæôñïæ÷ëëêø÷èëñöðáìùúåëôöçóäëõóíéëéøèôæøìéþåüëæîîêìçîñäëåðíæñðýíïäãñîéêîäñìöèøïîôð÷æïøôçÿñôõëîîóúêéñíóíöñóîúèóñâéóíéíâææöîðíèóøãÿçèõðëñðæîâéëéèíïæóéïéäöéóäåîóñúòîéêðîììëòæßèääöáíííðâêéïæç÷óûäé÷øâòæñïí÷ïòßùëóâæéñóý÷ùñêæüñíéîøñéïöçùêìïìïéôñíäìçðéóóñóøéçê÷õåêüéêêïììæìæêëíúóæòîçðéðóôêòîòæîèôáïåõê‚ìúìçæ÷êäî÷óíî‚ñëãôôóò÷îàíôéèúäæáëêóãôêíéëèåñèøíäöòêóíëëåòôíòëðøõîééçèçâëçÞéîãêíòéôçìóæíîùàìðëñîìæîïïêïèëêï÷óûìòíñíðóðïÞóåøÝ‚íûçðêãîïâôçõñðëóçæíòòéïûêåëûëóîíîìïòßíõñïèïëêííèñæêêèçòîíñìñèòøéáóåéøçõéäêòåìéäñð‚êâæ÷èîïöõëäéêóæèéîðøæþîæìëìöãðôçèâæðñàëøðæñîðõñî÷íõèîèïíúâòëîÓòëîõæïìóë÷óóáëíèâæóòîîåîøôóæõïÚèéçèééäïæøèëñïóçóÒÎÖÆÊÔÏÎÓÅÍÇÏÈÑÐÔÒÐÔÓÕÏÌÍËÉÈÔÏÒÑËÖÒÕÈÑÍËÓÐÊÓÒÓÌËÎÐÚÑËÖÖÒÏÓÒÕÒÎÔÕÔÉÍÎ×ÊѶ»²¼¯¹·À½½´²·´½·¸µ·¸¹ºµº¸¹³àÙáÝ×ßßÜÞÞØßÖÝÌÝÜÐÖÒÖ×ÍÑÙáäÙÞÕ×ÈØßÕãÕÓÍÐÞ×ÜÝÔÍÐÐÜâÛÌßàÛÌáÕßÙØÌÓãæÕàÜÓáÛÑÇáÛÕÕÈÒÌÒÙÕÊÚØÔÕÝÙÞÝâáÝÚÞÆÜÚÙÓßÚÙÑäÕÜÍÒÝÙÚÓÔßÒÞÜÔâÚàÕÜרâÖäÔÙËÝÙÔÕÏÑÝßÙÜÏ×ÔÕÙÚÎÚÐÌÓàÜÜÞÝØà×ÜËÔÝÔÙ×ÓÑÖÚÖßÚÖÕâØÜÍÛÒÛÖÛÖÚÞÖÛÊÝÕÕáÜÓÙÕÔÓÞÓÙÖÙæàÍåÅàÛ×ßÌãÛÐ×ÕçæÖÐ×ÙËÛÓÚÕÞÒÙÙÖåáÞÓåãßÙØØÐÒÞÕÛáãÕÕÝâØÚÜÛÜÖÙ×ÙÕÒ×ÝÝÙÜÚàåÍÜÖÞÍÜÔÖÔÔÓÞÒÛáÖ×âÙÚçÛØ××àÙÛÎÖáÔ×àÑÌÓÓæÌÜÏÝØÔÍáØáÔØÙÐÔÙÝáÒÜÙâÞÐÖÝêÕÛ×ÕÞÝÚÚØÛáÙÞÒáÔÏØÚæÝ×ðÒÒÐÛÜÞÏÚÝçÔ×ÐÜØÐÖÑÛêÒÝÓÝÒßã×ÔØØÞØÜ×ÚÑÇÞÑÙØÍæåÝÐÓÛØØÖÞÜØÓáÕÖÛÉÍáÖØàêäÕÖçâÙÝÑÚÞØèÞäÛÒÛÍØÔÜàâÕÜæÚÑáÜàäÑÜ×ÙÚÞÛàÙÕÚÖàÛÕ×ÚÙÔÕÖÝÏÜÏÒèÖßÞÕÐÔçâáëÕÖÕÑãÊÖÓ×ÊÏÍÏÚØÕÍÑãÛÝÛÚÝâÖÐÛÑÓÊÓÔÌÔæÛÞ×ÔÐÛà×ÏÝÙÕÖ×áÔÞÖÍ×ÔÛââÓÛÝÔÜáâØÝÏßÕØÒÐÈßèÌÎÛÖÍ×áÝÙÚâÈàÒÝÐÖÐÚ×ÑÐáÝÔ×ÓÔÎÜÍâ׿ÕÔÛËÛÐÙËßÎÙáÜÞÙÚÞ×ßÜÎÚØëÜáÒ×ÜÒßÛÚÓÚÛÒß×ß×ÐÐ×äÙäÎØÖÚÙâÞØÞÙÚØÑÔÎÔãÏØÑÕÒÖËÐÆÓÛåÎÞåÛÝÑÞÕÚÙØÐÒÙ×ÕÝÙÞÑëÛÞÛÜâÔÓßÖÜÕÏåÏØÓÒÒÏÒÙÞÝäÝÚáÑÓÚËÔÓÝÓÎÑÙÝÑÛÎÚÔÞÕÐÙâÖäÞÒÚàÔÕÎâÚáÛÙÞØÝÝÒÝÛØÔáÛâÏë×Õ׿ÌÓçÊÛßáÛØÝÛ×ÎÕÊáÚçÜÞÔÐèÈÝ×ÕÐàÞÜÔßÚÓÙÚÛ×Û×ÍÚÖàÑâÜÍÚÜÓÔÚÒÏÓÕÖÚÔåÓá×ÑÓÕØÎØÖÓàÙÚÛØÓÏÖÝÜß×ÙÙÜÙèÙÝçßÔÐß×Û‚EÚæÈß×ÏÇÒØÝÌáÙäÔÞÏÏÜÛÜßÛáÜØ×ÛÜáÍÕÙÛÚáÕàÒÕàãØÛÑáÓÏØÐÛÏÝßÝØÙÝÖ×ÝÞãÜßÞÖÉÓâáÊÑÔÕßáÕÙÖáãÏâÜÒàÐàßàÉàÎÐÏÎÖÕÙØØâÐÕ×ÓãÞáãÑØÒÖÒÔØÛäÝÑÚâÑÜËÑÛÔëÖÙÝÕÚÍÑ×ÎÐÈÚßÔÐÔÕêÙ×ÖØÛÕÖÚÚÛàÓÚäÚÏÍÏÓÏÚÒÒÓÝÜßÕáÔ×ßÞßÜÔÙØÜØØàâàÓÛáãÕ×ÛØëØÑߨÚ×àÒÝäÖØÖÐÜÙÐæã×ÖÝÖÐãàÐàÞ×Ò×ÛÚÜØâÒÏáÕÖÎÛÑÓÕÖ×ÞÝÙÖàÕµ¾·»º¸¸¶ºÃ¼¿¿º¶¹¼¼µ¼»À¿¶À½·ºÃ¿¶·Á¸¾¾Â¿À·»º¸»¿´ÁÀ¶¸¹Âý¼Â»º¾¼¸»··»º¶Â½³¼ÊÅÂÆÀÌÈÈÀÉÅ¿ÃÆÅ¿ÐÈÄÄÀÆÆÉÇÉ»çåØåÛÞèëÝ×âÚëèââëáàäçêìØæðáÛíçåïçÝÝéñàÚáääñãå×ãìæãäØßÒßÝ×Ü×îæßåâÝïãàØæÛäéáåÜàòÞÞÝÚééÝåòúÚìîì×Üâß××ÞåëÜàéçÛàåìèÞâÙÝçèÜèàããÜâãççãÙÝââñÝìÚêÚçèæïèìäâãåÞÝäãßÞëðéÜáÖáßéçä×ÞôßããçðßáçæàÔèåÛåèçïÕæÝÜÞçÜíæáåäæÛÝãéÚìØéïáëߨãÜÓÞåÜÖëààÙëäáÛêÙâäéççÝäëëçâÞñÜÝÝáèâüÜÞÙØèèÛáæäáÞéãäßîäßêåêÞçàæÜàèâéßáäêñÝñìçÜîåßääàóíÝãßÝîéÙìÞÞêßÙÜÕßåçãÜâãåèâÚçìëÙïèÜåâ×ñæäãàãæÜÖóßàÚÖåÖîÕêââßÞßèêÜéáÙòììåèèàðçäãåÛÚãÍÝÖÜëåÜáéöãÛã×âäÜåçåìæäÙêäæåãåâïÚâßàäèÓëäêäââççììäÞíåàÛôéåÖâÛèìêÙëÙàáßæÜÛìÝÜçßéÙÞâéÓãêâàæïîàÜèíéÝÕîïããßåãâÝÜíèáÝèæãßÝëèëíãØãÞäíáÚàêßëçáçØÝÞßçéÜßÚèìäêëæÜáãääÞßÞÚçéçãÜæÜàèáàæàâÔæéåéßæÙéÛãäÜÑäÞßãñðæÞßâåêïâåéëæíìâÜãçÜñàõäçêæòêçâãåÜàãêâæáÚàò×ëãä×ãæéãÖëâæâÚìâàæçÛèèäßîãÞàÜÙáãÝäåÛåçÛôÙñêäÞéàåâààßßåÕæÞèÝâáàèêÞÛÝåãØãäÛØØááðæ×ßÞãëÕçåàãêÛçí×ïîÝáØê×ÚÛããëàðàÚØêØâëåçÛãêèð÷íÝåççäéÝÜçáéîßëåäàãìæãÙßëßÞ×èßìèÐÜãÛáÝÛåÜâææØàâÞãëåàâáÞãÞåäàááæÜåàéëêåæãÚñäæåßÜÚäæ×ß×àåÕßðæåÛààìåãÝçãâãäåãâçÛæçÞÜÕßáÜ×åèêã×ß×ÖåßìàóéåÙàÝöÝáÝðÞåäæàãéâáäìñáêáèìèëäÜÞÜÙçßããìåÜÛáçàâáßßåÛæàãÝìÛàçßÚÖæèããàÛØèäÜßåáðæêáÞáàñÞàãáêÖäââ×ÙâãçßåãæîßÞçÝáâéÓêÛÔÝíÜÞßÞàÙäáßÕßïçíÛßá×åìàåíáêãïáçæÝéìÙÝéÙêáðåÝêÞÞãñÜàÚâìàëëåÓïéà×îâìäàÜâÙÜæâáÜæáããåâØñëáÒêÝáßãÞÖÞæèßáåëáãÞãÛäßååàÞÝäèéæéÙàæÕÝèÖÙæíáêãìßÞÜáäëðáàßíðå×ãáêíÛÜäæãÝìäàëãéàèàéäßèà¿ÁÈÊÈË·ÇÂÆÁÆÁÂÏÅÄÃÁÇÄÆÂÉËÈÅÈÈÅÿÀÂŽÃÈÇÁÂÁÎÇÁ¾ÆÇÉÊÉÂÉËÅÊÃÁÃÂÄÇÂÈÂÆÊÊÃÊÄ»¾ÅÇÇÄÄÂÌÁ½Ç¾ÆÃÉÀÃÃÅÂÂÄÂÀ¾¼áÙÞÛÝæÛÜÞáÙæÜæÙÚâÙáäÜãÙæâäãáØáÓæãöÑÞÞÔáÜæáÞÍáäÜâØÝÝäÜÜÜæÝÞßà×ÜâäâéÜâéÙÖâ×àØÝæââêÙØëØáÞëáÚßçßçàäñäåÕÞãà×íéêÜÜÝÏéÝæÛÜÞÖåçãÝìæÛØäêèÓãÖÚÜèåñàÝçáàÝãÙâßÒáãßæàéßâàâäÜàÜèâÛíÚåÜÚâéàÝÚß×çåçÕæÙÝà×è×ëäçäÕåÞߨäØÛæÛÚÜàéÛâÞßÜâÚäßÞàæäæáâÝßäÖåÜê×ßÒÝ÷üÜìßÍåÚäàæçÝàÚÙÓÖçßàÛÝêÚáåÝØÖÚãáæÝäÞåéáÝÛÝàáâæØáéìçßÞêäÞäââæäÔéÛåÖéìÝäÖÛìèå×ßêëÞëèÕàÙòÕàÝßáàåàêãÜãïàÞäÝâÛîáßäâáßêáæáîãïâßÜàâçàäàÜëáëÞãÕíßãêåàâäéæÚØëÚÛêÝîÛðßäÙÙåÖÞêìéÞâáçêÛØÕßòÜØÞ×ÖàåäçåâåäÚäßâêÝÚééçßãêåâÜâãáÞàÙîÞêÞìÝáÕßáäÞÝéØßáçØÜâßåäØÛçåØ×ÞæÙáÝìðØèêëßäßèßëÓÝêÙÞçÕâðÞãâÎÕãÛåãÖÏ×çÚàìëåßðâèäàäìÞÔàÚéòïÓâçÔÓàÜãßãâêàåß×ÕæØäÙæàØÞÜéèæêàÕæâÖßâÝÚéåÙàÝàÓÖäâéäéÝçåï‚àÔÕâÞâãÜÞÛîàßåñÜàÒàÜߨãæáòëçßñßáæáÚÝÖêèÕÝãßÜÚàßéÝéÜÚàØÚéÞäáÞäààéãç×ÓßÝÚÜߨÜáàäåÞÕ×ÝæåðäÙÙßéÙéæååêââáåÞäÛßäÕäÔéÝßãóÚçãÜààãèåÛÓçèççãááÝÛæàÛÖÍäáåæáÞêàäáààäáßרâáåÛëáÙÙÛãÛçæäáíÙåØÔØßÝØÜÒÙÝâßçÙÝìåÞããÞÛäôæðûäßäãìäéÔïçØæÑèàäïãÜåßï×ååÙæÙÖçåÙáãæßçÝáÜàáÛéääàÜÝÝÚçÛáàÝÚãäÞãçßÙèãåæßâàÖèäÝïÚÛâÛãßáÔîêãäæåáåãææßáÛäãÛàÙåÝåæÞÛìæåÛØêÙçØßéäßãáéãçØêççÞßäâéìãêÙæäáèâßáéßÐÝèíáØÙÝïáõèÜäßßÝêæçéòáçêÏÝÜíëÚÞáèéÞéåáàåÙÚæÑéßßáÞÛèæëââèÞãâßãÛâÛåÛØæèÜÜÜÜßâéÜååâÕÔãäßåÞÛäæßãßååàÞàçÓáàèÞâÖòáÚÕÝäßÞÔßßàôßÜÜãØèææßßÛÚáëÜïçÜåàäâåØÚäÙÙØÝÞàÚÕÛåØÑÙåÝêßàãæéÒèÛâáÞåëëçÞâÕàçÝäåêèßÕâåàØäàãÜØàëÛêåçëÞáêâó‚ìÝÇ¿ÀÄËüÁÄÀÉÄÆ¼ÂÅÅȹÊÐÀ¼ÆÁÈÁÍÀÀÀÄÁÆÑƽÄÃÃÁÁȽ»ÀÆËÆÇÃÃÂÂÃÁÁÄÉÅ¿¿ÌɼįÇÄËÈÇÌÂÊÅÌË¿ÎÇÊÉÂÈÇËÈÆÆÑÉÒÐÄÏðêðãëæëæáääãçðïñæìçäðÝïîèôãóíèææäáìßÙòçìõöèàêåôòÜíåëèæíâóíèìðáñèçêæöêçáãæããìØæáâïèëçñçâÞûÛèâÞÜêáÝ×ßíãðóòæØÞéäòêèâÝðéëûêëíãêóäåíèêðãØêëæääóéîááâôèíäæîèæâäÞàåâçèêçæåàááßéíçæäïÝ÷ñäðâáéöéÝîîåáàíïçãíååñáúåòìëíôìîöæàèéãåëîáÛïçðëäóàéèôîçäõïíàíñãæàâéãäççãéõëìêðêôéæíïëîíàïëôìôíÜîÞëçíåõâèëæìæèâæÛÕßüêìêöæáîêêÖëãëßñåðÝíìÜèòõáèëãäæçìóíåáÜëêáÙêíÝèîóàèñýéÞííçäáèýêòîáóàáÞàäãèíßèìöèãéëïÛêßîäééæåñïäáéæíêÞäíèéáïçðæãïêãïïÝêåèóôäèêìèìîéÞíçëåëéâò÷æìëëìèëÝêîèîæìèàáàìßéìíìÞëáéîúõïçñõîòîãòãåßÞææéíëâáçìàíåìíâèòÛèëëëêðÞóúíÛÕéìíóãéëö×èêòàêæåñèðíòòõäïãñóéçæñãóêñçßÜáÞîéèèééæòöðèßïôìÛçíéôÕöóãëèøéíâãðìïôèçåØðôïéìõìçìí÷áïêçåæãåìóñíôååÝéÞÝðçîÛàåáñõïÞéæäâäãâáìíìëìäãùæÞæìëîæñìäÝâáëåÕÜçæêíëóåâêæåÚóéëßîêåéãìáæîôßãìãëèúâêåíåãçíðêâåïñâÙêÜàâðãâßíÙõãèæÛÚëáìåìãëîçÖâðíñêÙãÚåêçÙêöñíêæÞþåìäêïõåæçûåàêéèêâîâæòòîìèâõêâêëæçßßæäæçááøëÞîêçêÛëçéóíòòìâÞèÞæéâÿêïáåõîøèïéíâÙêìèçåí‚€ïãæåâàëéëëìïðåëåíîâñíèðâæÞßéç×éîèêïéâïßîÛãîäê÷ïêêâçêëõàïìñßáèææðÛáäéìåàóèÝäåäìîñçíÝíêèåæìñîëñëôäæåõéòâé×éêí×ÚäÞæëðæãòóíÝïäëåðâêàíùàçëäâìäîõêùòïã‚ãîòäòõÿñðò‚ï‚‚‚%‚E‚0‚‚‚,‚*‚)‚*‚‚*‚‚‚%‚1‚(‚‚‚‚ ‚‚ÿ‚ú‚‚‚‚ ù‚ñú‚þøðóïë÷áùíèêæïÞççôÞæñíèÞñÝíòãîìÖëííëæçäæëçíééãøìëâçìëÚâÛäíëçÜâìäñêèèáñîòïóìçóæóâÝæàôæåäðâãáüíåõïõÛöóâðíçßêçìãåëàèèäðßéãôéçÑÆÌÉÏÉÆÊËÓÎÅÊÔÆËÉÉØÎÒÉÍÉ¿ÏËÊÆËÄÐÀÊÉËËÇÈËÊÉÍÊÉÌÌÑÎÉÎÅÂÄÄÓËÇ¿ÍÎÑÃÅÐÍÌÃÆÎÀÂúżÁ·À¶º¿ÀºÁÁµº¶»ÁÆ¿À±ÓæàÜÖÚ×ââÍÕâÚÚÕåÖÒæÔÙÚÐØßÍÛØáÙãÚÚäØÔרÜèÓßäØßÍâ×ÝÖåÙÚÚÙÚÚÙæÜÚ×ÞÚØßÑâÓØÜØá×ÓÝáÙÞØÜÓáÒãÚÞêÔØßáÐÔÑÝÝÛáæÚÕÝàÛÜÚÔÎåÏÑÑÒÙãÝßÞÞáÈßææÞÖæàãÓÞÚÜâÝ×ÓÜÛ×ÚâíÝÜéÓÐááÜáÖÌ×ÕÙÒßáÔÕÜÙÔáÝèÖØÝÝõâÏ×ÛÛ×à×ßÜá×ÚÞêÐÛâÞÐÕÙËÞÒ×ÙèàÒßðÖߨàÐÔÝáÔÚר×ÙÛÕäÖÕÝÞÖÚãÖáèÄÞØÖÌØÒÙâÕÞÕÚÕàáàÖäÕØÞçäÔãØÒÜãÕÝÞÔäÚÞã×ÜÔäÒÔËãæáÛÕ×çÞßßÛÝÑäÌÜèãÑØÞáÔÙÞÏßÏäåÞÕÙÒÞÔÛàÛÓÞàÍØÞèÔàÕßÔÖÖÜÞàÒèÙØÚÑàåÛÝîÝóÕÛÕéØÚéáàÝÖÚËÙÕÞãâêÍÚæØÏÝÞèéÚßàÚÒÜáÝâ‚?ßÖÏÓØáÝÕÞÜØÔàÐÝàÑÏßÚàÜâÜÝÖÕÚÕÙêÛÚÓÎÞ×ÙåÝÝâߨ×ÜÝÛäØÙâÚÒâØÔßÎÕâßæåßáÜß×ÝÙáÕèàÒÝ×áÝÚÓèãÑÌßáëßÓ×ÝÖàáåÝÞ×àÌÚÜÓÞØáÔÖÚàØÛÑÖáÓçãÛßÜÛ×ÙÓáçÏÓÐÙÜ׿ÜÙÙãÞÝÛàãáÕÞÓ×ÔåâÞÌÚÖâà׿áââ×àÕÙÖÖÜÑÜèÛÔÕÞäÞߨØÝÓÕãÝäÍÞÕ×Ü×ÛÛÒÓÐàÜ×ÑÖáÛÚ×ÕÚãÏãàæØæÑÜàéÙÏÕâåÓèØÖïÛÛÝÙßßÕÐÙØÙÜÍÕæÙÞàåÙâÝêÛÖÍÚâÜÙ×ÕÙרÓÓÜÜãÞâÓߨñÚÔÒàÝÚÕÛÜçáçåéÓÕÔÛÝáÚÚÏÜàÕÛÛÙ×ÜÝ×ÕßÔÓÜÕââßâÓßßãÝÖ×ÝâÊçá×ãÚÞÙæË×ÛÜàà×ÔæåרààÐÚØÝçÖâÚÔáÓØÙרâÚÝßßÝÓ×ÜÐæßáâàÎåÍÖÇßÙã×ÕåÏáÔÔÝÜÓÚÓÞÌÕáØÝâÙÍÚÙÚÑÓäÜØÞÜÚÚÕ×åàÜ×ÓÜÜÛÝÑÞÙÜ×ߨÚÈÜàæÚÚÓÝßãâàåÖÚÏÓÜåÝÙÓèàÎÚ×ÙÕàâÖâÐæîÓàÜÑÞÛÙÕÐÛàÖØÛÛÖÚßߨÞÚàÔÛÞÛÏÛ×ÕÙÏÚÏèÜØÛßÓèáÕØíÛÜÕÙÙÚÖÖãäÖÕàÕêåרâÙÓâÎÖÒÙÕäÓÑÙÚàÕÚ×ÜâØÙÙÛßÜÙßÞßàÔÜÜÍÜÛßßÜâ××ÜÔÙÔèÚÜßÜ×ÜÜÜÓÜßÚÜÓÝØÖáÏåÝÕáÚáÞàÕÑÒßÛäßàËÖñßÞÙÞÙ×ÚÛÖÚÖàÔæßÛØåÚÞÛãæÞÞßÞÞÞÐÙÝääÝßÔÖÜÝÔÛÞÍÙÛÔãÏÚèÚÑÕÐÙÏãÙÜÖÝÕÙÙàäáåÕØÔ×ßåàÜáêãÝßÖãÑäÌÞÜÎÞÑÜÝÒæäíãàÕæÜÓåÜãÝØéßÞ×äÞÝââÚÜ×ÐÕÝíÛÓàÒÛÕéáàÌÞÙÚ½¿¾¾Àº»½»½ÀüÂÀ¿¹¼¸Ä»À¼ºµ¾º¸½Á¹º³¼»½¿Ã¾Å¾º¾ÃÀ¾Â»¼¼¼·¾¸¾¿À¼¹Ã¾Ã¾¼Åº½¾»¿ÀÁ»ÅÆÊ¾ÅÿÄÃÃÈÂÅÁĽ¾ÂÅÂÈÆÉÆâÜåëèÜçÛßÞîãÝêäÒÕØéëòàÛãàåìæëçæÜÙéáèØéßÝØÞâßêÛàëìØÕÝåØÜìèäâäÚê×åâæáÛæàßÞÜÞì×ãÝãÙíïçòåããÝéèáØèààãâçèçßàÝæÜÙïçÞ×äîâÚÙãçÖàÜæÚâáçâçâéèÝÔàáàÞ×ïââÝÛÝèìàîÙãßÜçßæÞçèââÙçéçààÛäßêáãàëââéîåäÜäâåâØ×ìÚèìÛÞëçàãäáâÛÞÝèÖÛáççØÝߨäëÛÝçåÝäáàááÚçÜêÞÞÝßÝèàÞâäÙØìÙßÚêåßìÞá×âëæÚÞêæêå×ßÑèãâÛæãââàáãÛãïéàêÚßæâ×íÜÚÛëçÙÙêâßáØëèãÔéãèëÚèåÜéêæåßÛÝáååÞÛåÝéàÞÙäãÜåÝáëÙââÞßîæßìãéäèÙèèáÙêìñáâëáèÝêÙâáâÛáçãäåàäêôÞçâÞÞáìâÙåßñäçäàãäâÜååôÜëáìáßÖÞÙÞæëãÛßÓßàâåÜìÝÕáâáëâÞßåÞÜâØÞÛÚæéÝåêæÚÞâàà×ääîîåÕÝæçÝÖäÙëàîÞÒâÙàÞâîåÚÚíéååÜãßßäØáÑßÞâæìÛÞãÞÛäëëçæõÛôçäÜñÞâèìåîÕæÙàÚÝÛÞé×íëÚÞéÕäçîëéÞæâÜâããßÛåáÝÝãóéù‚þäîÜçêåÞìÝÜøÝîçåÔÝéâëÚ×åéñÇÞÚäìçæãØäëÛéìáààãàääîèÙÛßçÛèëî×áÚÚàåãçéèêÛçèÛëèÝâÙØæÚØäçÜèéàçæâííßáâàèêÙÞãÞÙäØàØÚâççâáàáâàÕñçáäÞÓèÝéêéÛÞèåêçãÝïíåßçÝããæÖìèïßåáßãÙáôéÞìÝ×äÙäáåæÖâßÞâðçßßçä×âéãÙ××ßæÜéÚÝÜáÞâáãèßÛáÙéèßÛèíìâàÜäàáÜáàÞÝèçäèâêâÜÛîá×ãéãêáèàßàòëéçÛàßëèÞÞÛÚÝîæåÔäßìëáàúäéáøëÜßãÜÞãÜèãáòïãâååèèÛóÝÝéäÚåÐÝßâêäêêßãòáéÝäâØáÛêæç×ëåÞàÛååÝæßÛè×ÞåçãàäáÙêàÚäèæÔâîÚÞääæìäßãÝåçìÝääåÚàÞáæëäâñäè×ÙáâãÙáÙæÛåàèßÔߨ‚ìßáÜÝàÞãàâßèèàçßéàÛâãêßææàèáØòÞâÞÞïäáÝçãðäóäèßäãÛêàèæíìÝçäÞææçèÛåàáâçèóîý‚‚b‚è‚¥‚7‚ðôíäïéïçÞìàãØÚçæáçâÜååÜáÜßãóÜääááÜòàéÞÞåãáçÞåØâïëäåëäÚèáÛâàáÛÞäêèãìãîÖäÜåäêÚäéÜãæèæíæäÛèÚØáéàÞäãôéèàåöÝÝèççâàèêêéçÛëÜçÄɾÂÉÍÃǼÅÈÐÅÄÐÃÆÄÉ¾ÇÆ¿ÌÂĽÅ˾ÂÀ¿ÂÆÉľÁÁÅÅÆÁ¾ÍÃÈÁÁËÅÀ½Ê¿È¿ÈÊÁÃÀýÅÅź¿Ç¿¼É¿ÂÂÁÇÂÄþȿſ¿Â¸¿ÅÆÅĿŽãÜåæóæÚØèñâàââéÕäßãààëùäàéèÞÝÚßÛíåéäóØÛçÞØØãÝ×ÜàèÚßâäÚãÖæØàïäéëÙáÖÛÚÏðààÝåíÖØßäáäãàÜ×ãêäèãç×ÜÞã×ÞÙÞçÜÜäÜäÚߨçßÝãáÑÚåÕçßâãÜÞìÝå×îâØÛÞäãßÛßåÕãÚâàãßèçäáöçöåï×â×ååßßááïÝÖÔãÝÚØáèØÝÙìàÔóÖçßÐÛãèãØØÞæÚÛÝãàçÙ×äÙÙåÞäà×íã×ÞÜÞßßÙÜÙàãàåãÞáçÕíÖßÚÜááàÛáÜáÕéßÚÛÖéÞÖãàßÛáèèåäÜÒØÕÙÛØÖÚåÚÒÙçâÝççáÚâÙæÖÐãæåÝçëÜÏæãÝØßÕèÚïåÞÑÛâäÔÞâÛÞÙÕÞÚÛ×áÞÕÝÝåØàíàáéÚéÝÕâÜèëÜäæâÙßèÙÛÚÜÕëÜÒÔßÒáØáÎÓÝÚäÛÛáØÔãßàÞíîÝìÜâÔ×Öë×ËÓÖÝÚÖäÔÝäßÝÛéâåëÝÛáêàÍÜÙßãæßÕàÖæÝêãäâåÚÛÖåßÞââà×ààÛáâßëæàáãÐÚßÒÖãæÛÞÛÕåÜè×çîèáçÝåßéàãåæßÙÒàãØÛÞàäÑÛÛÛÙäàÒßÛÞæÛàßßäáàçèÜäáçÔÜÙÚ×âåääÛíîßÒÓÖàÜÒçäÜÎÚáãàßÚèÛÜÞåãÔåâÝÞåßÝâÛãØâÙááæäáÝÙÛàÚÞÜáÏÞØßááÛèÜÜßÝáàßàÞìÜäåÝßéáóèæÕØåÓßÚÞÞàïáÐéÛåÜÜçÙáÞæÜÛßÝÞÖåçÔÙ×Öáãéáç×ÞÝëæßÛí׿çæãØëÞÞæÜäáèàâçÝàáß×íßÖÚ×ãßäçÜÛìÝÞ×éãÖåîäàâÜá×ÚÜá×ÖìרÜÒãØØÕâÚÙÞæäÞÛâàæÞèàçæÚßéÒÚØÚÞíàäÚãèÑÙÜçÚÞàäÞäåÜçäÝÛâÝèàâÞååèÞêàçÖëÙßÙåáêããê‚-‚)áÖÜéÚÕë×ßÚßÔãââÛëÛãÙÖߨÙàìÛèÛâìÚÓÕâÝóÕêÚâÝááÙãÜíàäãáÔÙäçæÙàçãÞââÛÝÚÚÝ×àé×ß×å××ÜèÙéâÜæØÕÞäàèÞåÖæÝÞæåâéÓÚÜäÛÛíçÜÜÕâàâ‚QÒØÖÜàÙÜìæáÝàÝá×âàÛäåÙÌ×ÔäØåæãØéáÛæáÔãâïçÜØãÛÕÞáÞàÛäÙêÞÛ×ßæâÜàÚßÞÔãÝÝáæÕØáÙæÞÜáãæââåÛäÜÞÓÞÚØÙÙãÒèãØäÛáÕÓúØÝÒâïäÖßÜããÝèÏàãâæÖÝÏßÛÜâÎÝáåÛÜâØÏåãéÞÖÖãØ×æàÙáéãßÞçßÔÜáÞÏäÝÜìáÜãØçãí×èãßÒèÏÔÞÞßÜâãÞÒäÙèááÓîÜÝÜ×áÝæã×ÚÖêìáàáÛßàÞÒããÓèÚïâæÛèÛßãßÛÏÜÛÜàÔÞêÛêÕëèàÚßâߨÙã×ÔàÞÚÛ¾¼ÄÀººÅÀ»½Ã¿½È¼Ã½Â´ÀÆ¿ÂÃÅÄÃÁ·ÃÂÊÈŹÀ¿Ê¿ÄÀý¾Â¿¼ÄÁ½É¿»ÂÀÂÁ»Ï¹¿ÂȺ½ÅÀ¾ÄĽÒÈÒÍÌÐÓËÐÑÐÓËÒÏÐÏÇ×ÑÉÎÎÎÒÍÎóòíâæïèóëöñïóóúóëâÿôíçëìðîçñóôæõóòãôîôÜèõçóôçíçïìóëï÷ãêêøëñîöäÝæëëòçìóíðâòñçììéñåéìôçùñèîìñëøóêîéóò÷õíøðíîíüïõúüñêíçéóêýãôéïéúùçòëïóççòòãíÿïðïùåíõå‚ðìäöíç‚÷øéèéòøèëëàììèìå÷êíéïüñïñìðæîðïëåîéëñéëêïÝïèðüíúõñäêôñéêïæï‚çòëðãìæòôêæíßææþðõçúêðñðùïïòæâùëïðííöã÷ïóàúëîôïìîòùëôôíêìêñóîðøßîïèìôñîíé‚òöñëóîäâïèïéêóëíûîïíïçêëïðóéöóïâúðìõæóôõîÜôåð‚îíõ‚êïîóéóçííïëïçûàñïåèòëìñòúðîõíðìîáòîöñïìñöêßçéæêßïâðñíðãéóçòúòîð÷âñùôïòóéôøëþÞïòìçóöéééø÷îïçòòÚðíßä‚ðçóôòë÷åéòñèüýõîëåéøöãæòñêèåïäèìäëìïåæëêóóíùë÷åå÷êíò÷îëóîàìëðîíéðè÷èéñøéçüõëóîöÛèôããåðìèìöïìôìðòòæå÷÷òèììéñöíõúéêôñêíöéóíìöìðóïçåúõéïôçóûþõìíõìðëñôîóõïêïøîàééûðíéãìùïïæòðòíîå÷íïúèþåçïæôàëíðïôíéôíññòòêëÝïîúçîíåóêäæåñçíôïôëæâ÷îñðêóî÷ûäãïíñåæóðæßìñâééó÷êììâûìïìúèñåïôñóé÷ôäíûÞêððòìôîòôßîõõòåêåíìáãôñöêôìðêçãÿðëä‚ôêêõéëäòõíñáúëàðõéõ÷ôüù÷óðäóôöäèí÷íàëñïíöÞáïêñöëïæïòöçíëéôîõúêïóõòíçòäý÷ùðïåñúýêéìðöðöôôòôëù‚ñçëíëéâññøßîïúïðòòéõúìýêçîãìôïóòúóüíùñôóöòÖõóõòûúæîòóëï÷èìéùýïïúçöæîíöïçúäûòòíæ÷éûì÷ìâóðñøêñóäðãóôòäïîöåíïãïìïîðòêéëïòúéîõîïëûòêùæôë÷ùêôéòìñïîùöøâìî‚ éëüêí÷âøèééùìùâèêêîûõõíîêñúïùðøûïñíúõû÷þôîôñ÷ôöóóþýîóôöø÷öõ÷ù‚‚‚ÿ‚ ‚‚ñû‚‚‚ ‚‚‚‚ ‚ ‚‚‚‚‚‚‚‚‚‚‚‚!‚‚‚-‚‚!‚‚‚‚‚‚‚‚'‚1‚‚5‚*‚‚‚‚1‚#‚.‚&‚‚ ‚"‚‚‚‚!‚ ‚‚‚‚ diff --git a/observation_sim/sim_steps/prepare_headers.py b/observation_sim/sim_steps/prepare_headers.py index e8c4174..0a02595 100644 --- a/observation_sim/sim_steps/prepare_headers.py +++ b/observation_sim/sim_steps/prepare_headers.py @@ -17,7 +17,9 @@ def prepare_headers(self, chip, pointing): sat_vel=[pointing.sat_vx, pointing.sat_vy, pointing.sat_vz], project_cycle=self.overall_config["project_cycle"], run_counter=self.overall_config["run_counter"], - chip_name=str(chip.chipID).rjust(2, '0')) + chip_name=str(chip.chipID).rjust(2, '0'), + obstype=pointing.survey_field_type, + dataset=pointing.dataset) self.h_ext = generateExtensionHeader( chip=chip, xlen=chip.npix_x, diff --git a/run_sim.py b/run_sim.py index 5f14038..933ce33 100755 --- a/run_sim.py +++ b/run_sim.py @@ -62,6 +62,9 @@ def run_sim(): config["project_cycle"] = 6 if "run_counter" not in config: config["run_counter"] = 0 + + if "data_set" not in config: + config["data_set"] = "csst-msc" # Generate lists pointings based on the input pointing list (or default # pointing RA, DEC) and "config["obs_setting"]["run_pointings"]". @@ -72,7 +75,7 @@ def run_sim(): if "pointing_dir" in config['obs_setting']: pointing_dir = config['obs_setting']["pointing_dir"] pointing_list = generate_pointing_list( - config=config, pointing_filename=config['obs_setting']['pointing_file'], data_dir=pointing_dir) + config=config, pointing_filename=config['obs_setting']['pointing_file'], data_dir=pointing_dir, dataset = config["data_set"]) # Make the main output directories run_dir = make_run_dirs( -- GitLab From 4168b7486c2843f3effde6108bce00ff5be2cccc Mon Sep 17 00:00:00 2001 From: zhangxin Date: Wed, 21 May 2025 16:57:03 +0800 Subject: [PATCH 63/64] update header; fix sls bug: psf A and B error, modify the band bounders of sls --- observation_sim/config/header/ImageHeader.py | 4 +-- .../config/header/csst_msc_l0_ms.fits | 2 +- observation_sim/instruments/FilterParam.py | 6 ++--- observation_sim/mock_objects/Galaxy.py | 26 ++++++++++--------- observation_sim/mock_objects/MockObject.py | 2 +- 5 files changed, 21 insertions(+), 19 deletions(-) diff --git a/observation_sim/config/header/ImageHeader.py b/observation_sim/config/header/ImageHeader.py index f4d536f..2aed73f 100644 --- a/observation_sim/config/header/ImageHeader.py +++ b/observation_sim/config/header/ImageHeader.py @@ -533,8 +533,8 @@ def generateExtensionHeader(chip, xlen=9216, ylen=9232, ra=60, dec=-40, pa=-23.4 # h_ext['CCDCHIP'] = CCDID[k - 1].rjust(2, '0') # h_ext['CCDLABEL'] = filters[k-1] + '-' + filterID[k-1] # h_ext['FILTER'] = filters[k-1] - h_ext['CHIPID'] = str(chip.chipID).rjust(2, '0') - h_ext['CHIPLABL'] = chip.chip_name + h_ext['DETECTOR'] = str(chip.chipID).rjust(2, '0') + h_ext['DETLABEL'] = chip.chip_name h_ext['FILTER'] = chip.filter_type h_ext['NAXIS1'] = xlen h_ext['NAXIS2'] = ylen diff --git a/observation_sim/config/header/csst_msc_l0_ms.fits b/observation_sim/config/header/csst_msc_l0_ms.fits index 8c4eae9..7fd146c 100644 --- a/observation_sim/config/header/csst_msc_l0_ms.fits +++ b/observation_sim/config/header/csst_msc_l0_ms.fits @@ -1,4 +1,4 @@ -SIMPLE = T / conforms to FITS standard BITPIX = 8 / array data type NAXIS = 0 / number of array dimensions EXTEND = T NEXTEND = 1 / number of array dimensions DATE = '2024-08-17T06:05:12.0' / written date (yyyy-mm-ddThh:mm:ss.s) FILENAME= 'CSST_MSC_MS_WIDE_20240817060512_20240817060742_10160100000_09_L0_V01'TELESCOP= 'CSST ' / telescope name INSTRUME= 'MSC ' / instrument name OBSID = '10160100066' / observation ID OBSTYPE = 'WIDE ' / observation type DATASET = 'csst-msc-c9-25sqdeg-v3' / dataset RADECSYS= 'ICRS ' / coordinate system of the object EQUINOX = 2000.0 FITSSWV = '2.1.0_20231208_wcl-5' / FITS creating software version COMMENT ========================================================================COMMENT OBJECT INFORMATION COMMENT ========================================================================OBJECT = '60000000' / object name TARGET = '161953.0+395345' / target name (hhmmss.s+ddmmss) RA_OBJ = 244.972773 / object RA (deg) DEC_OBJ = 39.895901 / object Dec (deg) COMMENT ========================================================================COMMENT TELESCOPE INFORMATION COMMENT ========================================================================REFFRAME= 'CSSTGSC-1.0' / guiding catalog version DATE-OBS= '2024-08-17T06:05:12.0' / observation date (yyyy-mm-ddThh:mm:ss.s) SATESWV = '0001 ' / satellite software version EXPSTART= 60539.25361 / exposure start time (MJD) CABSTART= 60539.25361 / first cabin time after exposure start (MJD) SUNANGL0= 50.0 / angle between the Sun and opt axis at CABSTART MOONANG0= 30.0 / angle between the Moon and opt axis at CABSTARTTEL_ALT0= 20.0 / angle between opt axis and Elimb at CABSTART POS_ANG0= 20.0 / angle between y axis and North Pole at CABSTARTPOSI0_X = -2218.3663 / orbital position in X at CABSTART (km) POSI0_Y = -5817.8559 / orbital position in Y at CABSTART (km) POSI0_Z = 2597.9467 / orbital position in Z at CABSTART (km) VELO0_X = 5.058199026407237 / orbital velocity in X at CABSTART (km/s) VELO0_Y = -3.85818799871231 / orbital velocity in Y at CABSTART (km/s) VELO0_Z = -4.322908628205369 / orbital velocity in Z at CABSTART (km/s) EULER0_1= 0.0 / Euler angle 1 at CABSTART (deg) EULER0_2= 0.0 / Euler angle 2 at CABSTART (deg) EULER0_3= 0.0 / Euler angle 3 at CABSTART (deg) RA_PNT0 = 244.972773 / pointing RA at CABSTART (deg) DEC_PNT0= 39.895901 / pointing Dec at CABSTART (deg) EXPEND = 60539.25535 / exposure end time (MJD) CABEND = 60539.25535 / first cabin time after exposure end (MJD) SUNANGL1= 50.0 / angle between the Sun and opt axis at CABEND MOONANG1= 30.0 / angle between the Moon and opt axis at CABEND TEL_ALT1= 20.0 / angle between opt axis and Elimb at CABEND POS_ANG1= 20.0 / angle between y axis and North Pole at CABEND POSI1_X = 0.0 / orbital position in X at CABEND (km) POSI1_Y = 0.0 / orbital position in Y at CABEND (km) POSI1_Z = 0.0 / orbital position in Z at CABEND (km) VELO1_X = 0.0 / orbital velocity in X at CABEND (km/s) VELO1_Y = 0.0 / orbital velocity in Y at CABEND (km/s) VELO1_Z = 0.0 / orbital velocity in Z at CABEND (km/s) EULER1_1= 0.0 / Euler angle 1 at CABEND (deg) EULER1_2= 0.0 / Euler angle 2 at CABEND (deg) EULER1_3= 0.0 / Euler angle 3 at CABEND (deg) RA_PNT1 = 244.972773 / pointing RA at CABEND (deg) DEC_PNT1= 39.895901 / pointing Dec at CABEND (deg) EPOCH = 2024.6 / equinox of pointing RA and Dec EXPTIME = 150.0 / exposure time (s) COMMENT ========================================================================COMMENT VERIFICATION INFORMATION COMMENT ========================================================================CHECKSUM= 'GflkHfiiGfiiGfii' / HDU checksum updated 2025-04-30T14:18:49 DATASUM = '0 ' / data unit checksum updated 2025-04-30T14:18:49 END XTENSION= 'IMAGE ' / image extension BITPIX = 16 / array data type NAXIS = 2 / number of array dimensions NAXIS1 = 20000 NAXIS2 = 4700 PCOUNT = 0 / number of parameters GCOUNT = 1 / number of groups BSCALE = 1 BZERO = 32768 EXTNAME = 'IMAGE ' / extension name EXTVER = 1 / extension version number BUNIT = 'ADU ' / physical unit of array values COMMENT ========================================================================COMMENT DETECTOR INFORMATION COMMENT ========================================================================CAMERA = 'MS' / camera of main survey DETSN = '12345678' / detector serial number DETNAME = 'CCD' / detector type DETTEMP1= 173.0 / detector temperature at EXPSTART (K) DETTEMP2= 173.0 / detector temperature at EXPEND (K) DETTEMP3= 173.0 / detector temperature at READT1 (K) DETSIZE = '9560x9264' / detector size DATASECT= '9216x9232' / data section PIXSCAL1= 0.074 / pixel scale for axis 1 (arcsec/pixel) PIXSCAL2= 0.074 / pixel scale for axis 2 (arcsec/pixel) PIXSIZE1= 10 / pixel size for axis 1 (micron) PIXSIZE2= 10 / pixel size for axis 2 (micron) CHIPID = '09 ' / chip ID CHIPLABL= 'r-1 ' / chip label FILTER = 'r ' / filter name NCHANNEL= 16 / number of readout channels PSCAN1 = 27 / horizontal prescan width, per readout channel PSCAN2 = 8 / vertical prescan width, per readout channel OSCAN1 = 16 / horizontal overscan width, per readout channel OSCAN2 = 16 / vertical overscan width, per readout channel COMMENT ========================================================================COMMENT WORLD COORDINATE SYSTEM INFORMATION COMMENT ========================================================================WCSAXES = 2 / number of WCS axes CRPIX1 = 4600.694649742984 / x-coordinate of reference pixel CRPIX2 = 4604.383757040574 / y-coordinate of reference pixel CRVAL1 = 244.5872723135913 / value of reference pixel on axis 1 CRVAL2 = 39.68195466168969 / value of reference pixel on axis 2 CTYPE1 = 'RA---TAN' / type of RA WCS projection CTYPE2 = 'DEC--TAN' / type of Dec WCS projection CD1_1 = -6.8096767434962E-06 / transformation matrix element (deg/pix) CD1_2 = -1.9394088718019E-05 / transformation matrix element (deg/pix) CD2_1 = -1.9394079613547E-05 / transformation matrix element (deg/pix) CD2_2 = 6.81009530128767E-06 / transformation matrix element (deg/pix) COMMENT ========================================================================COMMENT READOUT INFORMATION COMMENT ========================================================================GAINLVL = '01' / gain level GAIN01 = 1.089977689498424 / gain (e-/ADU, channel 01) GAIN02 = 1.099175619835018 / gain (e-/ADU, channel 02) GAIN03 = 1.107649165474623 / gain (e-/ADU, channel 03) GAIN04 = 1.121722214644728 / gain (e-/ADU, channel 04) GAIN05 = 1.081220797968546 / gain (e-/ADU, channel 05) GAIN06 = 1.09456272850753 / gain (e-/ADU, channel 06) GAIN07 = 1.111430472148367 / gain (e-/ADU, channel 07) GAIN08 = 1.105606424366627 / gain (e-/ADU, channel 08) GAIN09 = 1.101874970320761 / gain (e-/ADU, channel 09) GAIN10 = 1.085064046871988 / gain (e-/ADU, channel 10) GAIN11 = 1.12218772525153 / gain (e-/ADU, channel 11) GAIN12 = 1.114934178226512 / gain (e-/ADU, channel 12) GAIN13 = 1.119336504852553 / gain (e-/ADU, channel 13) GAIN14 = 1.093036190194986 / gain (e-/ADU, channel 14) GAIN15 = 1.084334798104931 / gain (e-/ADU, channel 15) GAIN16 = 1.090894538052644 / gain (e-/ADU, channel 16) RON01 = 5.0 / readout noise (e-, channel 01) RON02 = 5.0 / readout noise (e-, channel 02) RON03 = 5.0 / readout noise (e-, channel 03) RON04 = 5.0 / readout noise (e-, channel 04) RON05 = 5.0 / readout noise (e-, channel 05) RON06 = 5.0 / readout noise (e-, channel 06) RON07 = 5.0 / readout noise (e-, channel 07) RON08 = 5.0 / readout noise (e-, channel 08) RON09 = 5.0 / readout noise (e-, channel 09) RON10 = 5.0 / readout noise (e-, channel 10) RON11 = 5.0 / readout noise (e-, channel 11) RON12 = 5.0 / readout noise (e-, channel 12) RON13 = 5.0 / readout noise (e-, channel 13) RON14 = 5.0 / readout noise (e-, channel 14) RON15 = 5.0 / readout noise (e-, channel 15) RON16 = 5.0 / readout noise (e-, channel 16) ROTIME0 = '2024-08-17T06:07:42.1' / readout start time (UTC) ROTIME1 = '2024-08-17T06:08:22.1' / readout end time (UTC) ROSPEED = 10.0 / readout speed (MHz) EXPTIME = 150.0 / exposure time (s) DARKTIME= 152.0 / dark current time (s) COMMENT ========================================================================COMMENT SHUTTER INFORMATION COMMENT ========================================================================SHTSTAT = T / shutter status, T=open, F=close SHTOPEN0= '2024-08-17T06:07:42.1' / shutter open time (start, UTC) SHTOPEN1= '2024-08-17T06:07:42.1' / shutter open time (end, UTC) SHTCLOS0= '2024-08-17T06:07:42.1' / shutter close time (start, UTC) SHTCLOS1= '2024-08-17T06:07:42.1' / shutter close time (end, UTC) COMMENT ========================================================================COMMENT LED INFORMATION COMMENT ========================================================================LEDFLAG = 'main ' / main/backup LED LEDSTAT = '00000000000000' / LED status LEDT01 = 0.0 / LED01 flash time (ms) LEDT02 = 0.0 / LED02 flash time (ms) LEDT03 = 0.0 / LED03 flash time (ms) LEDT04 = 0.0 / LED04 flash time (ms) LEDT05 = 0.0 / LED05 flash time (ms) LEDT06 = 0.0 / LED06 flash time (ms) LEDT07 = 0.0 / LED07 flash time (ms) LEDT08 = 0.0 / LED08 flash time (ms) LEDT09 = 0.0 / LED09 flash time (ms) LEDT10 = 0.0 / LED10 flash time (ms) LEDT11 = 0.0 / LED11 flash time (ms) LEDT12 = 0.0 / LED12 flash time (ms) LEDT13 = 0.0 / LED13 flash time (ms) LEDT14 = 0.0 / LED14 flash time (ms) LEDTEMP = 173.0 / LED temperature (K) COMMENT ========================================================================COMMENT VERIFICATION INFORMATION COMMENT ========================================================================CHECKSUM= 'fV9ghV9dfV9dfV9d' / HDU checksum updated 2025-04-30T14:18:51 DATASUM = '3747953988' / data unit checksum updated 2025-04-30T14:18:51 END ÅÄÅÍÍÁ¾È»ÅÇȾÃÁ¼ÃÇÈÃÇÌÁÃÂËÊÚÓÙéæêàéèæÞáÝêæáåå×ìÞäôÓæåâëÛàßÝäèÛîíàßáÝïâÓæ×äãßãæâæêàØÜêâêäéäâãëåééÜêãááßáÙáçÚãàëéÛãÛæêÞÚÓáéðíçëèêÝæçîÜòèççáèâáçîèàåßÚæäàëàÚâÜÞÛãèãßååÚêæíåÞ×ãæíäêçñèæÝãíæïìæåçâ×ÝæÛÕáâÜÒâëâàÕäâÚìîððíääííãçéàâêéßáðöäÜèàêéÞÝçäÙäæÞéáÞãÞàäÛé×âäÜäáØÝèâàÚãÞãîëâçèâäâîàòëßéÙêàèíæàåÞÙãââïåèæÚßçéÖæêÔÝçéçëêæßÕéäàÓäâãæëéæâ×ÖåæèäÝßéæãÐàáçßëÝëÝÚÞÞäæåÕíàÒÖààìéíäêôìðô‚ óìðôïåÑÝéß÷àÛÞÙßëçðïèëñàãÝèêîêÜãåçäáÕáëêÞçòâææêÜîòëØèåèáäáíäïåèäìèßàãßßåÚâñææìæèëääñõêêàÞóðÓÚéÙàÒÞéíæÞíãæââÜáèÝàÓèñáÔÙáàáççáÛáéããæáÜÜáçï×áãìâäàåæîëäÜéäÖÝáâÙáðéØêäèÜâãìííìÛÝÜïâßêæáçèêéäãâÖôáðééíñòîëñêìéñìéæááåÛîäåâßÞÝêàÝâåææÒÞèÛíÛÜèñæéßáßÜêØÜãêããææðéíÙæçâÚâßíðäàí×îÞäðØààÝçæßÞéããÕæâæÚáåÙéääæáÝØàßéåçâéÚÝéîÔæéìââÛÞèááÔâèØæçÙäêáçàâãæÚØâàåÞÚãÙâèå×àßâÝéàÛâÛéäàëàÝãàéâçßÚÛèäæÜçØõÚÞåæÓäçÙëäÝàààææßÝìêäïåâÙæ×ãáåèðßéâêãçæÙèçÞÜ×ÚÝðÜãàÞåâçÐíØÞèãÛçãÛçÕØæÕåðäîïââãæÜÜÞâãâåâÝðìÚßçèÛØÚêõêæëîÕëëÞââ÷ä䨂xåïÛÛåÚêìÙâáàâÞàëÚéîåáâÜôØìØÚÚåÝàÞëÚÕòåãëÚäôàßÝãäåéÝàáæêëâÞèÞâÛéàêâÝèæßâáßååäâòòáéäáéçáâàãØëÒëáèåßëèÞìéåæÔÞåäííçÞèæëâïáÛÞáèáì÷ãÝäààßèñíðã×çÞòèÝëæÞéßçÚߨßãÜÞãàÜàèêêìîèÝ×ðßèåÛãéçêæãÕîÝÛàÞèñÙáäééåäßêîíâØåéâÜÞìåãåéïÞáàñÓçïÏîØáëñçÞçåØçÝÚîãÓæáâçåèÛÝèÛÛÚíàÛäçÙêææåéäâèßçæÞØòèÚáîéïâæåäâéëßåÝæâããáëìåàáÞÚåéàÙóàãßéâæ×éãæßêçáàåæãâá×çéååØÃÂÂÅÁÄÇÄÃÅÌÁ½ÃÁÆËÆÄÊÇÅÄŽÁÅÞÅÇÉÆÉÌÁÈÆÉ½ÂÉÅÆÁÈÅÐÂÁÀËÄÈÂÄÈÄÂÊÆÈÅü¿ÅÆÂÈÄÉÇÉÁÍÁÐÍÇÇÍÊÄÊÇÅÊÉÑÉÊÐÌÄËÐàèèëãðààêèßñêðøâîõïÞæÚêñéëæìãêæïêûéüÞòïèñâÝûääñáïÕßæíîàçëíßìßêîñæëìßéæÞâìèçôîÞÜåÞéëîäíæîéíìíÝàãçÛÜëçèäèÞåæåãçàìèáåßëãçäëßå‚éèäæõèæûÙéäïáãëìßíÛèóôèêñèìæäâìëêÝèíêëàééïëéðîïàñèææâåãîä×éÔÚäêßãìïîãâàéèêêëçêéï‚‚‚ ‚ðæççãäêäéìèÞéðïäîãìîòäÛäéäæèýäàðêóëëíñáîæêÜäëãééæãêêÝÞæåãëðãÜìîàìðíçóóÖßãåìîíìïïáàççëìáóüæåàèïóÞÞêìêéÛêùæìêäïñöößçäáìììëëçéæáéâåÞåææçóéôìîçôçåàêìùæåìàØîâîèéõðìíëêãèïäùëèêìççßõåõêÞÞëêôíäáêæåëêêéêåëåæóåëåèéðççáÕçøëçßÚêéêïäÜßéõèÝæãêêãéæèæäëàãÝæãïíçàëáîåááñöõÞÞëàßßóÜçëéÞêîêæ÷ðèñáðîáøÝêäêçÙìäæâæáÜãêâæîãßçåÝòíñìñÝæÞèíàéÞâîéçéäÛêìèäïãæìîæîçÞìûèéííæàäêêæÜåââØêãìÝáã×ìèééßïçèäçãêâçíñÞìîíàçÝäáïêåèêçëÞíÔäéøæáðâäëêçàáäëàõõéãêìçæáçíçòâãâÜæëääñèíêæóÜåëåßæøãðèéäêæììæäåêñèå×ßÜòçèñéßïø÷ÜõïäèäîèæïßçâèîáÖäÞÜæìòâñåõÝéëåéëáÙããíçéìÞçåäîæíçéñâàîåæçÞðååÞçäåìêæçíèåçòøäíÝê×íì׿êÜçåëîÝîêÛéÛäèáñãåßéäìëêêåûççÛñ×ëéïæçîßßæöæîàåÜéôì‚‚$‚ôêîåÞáçâçÞàññãéãÝëâèêéøñãíéåçíåøæßäõæãæÞØëìßõáåäïëçîâßÞéÙáôæíñõåêèç×êéïãíÞíüîäòêäñÜÝõòëãäòñôáçìäàêäêåÜéèÚßòäâêñØáëßîëôúçðáíïðÚå÷‚cãÝêìäïáçèåçöóáêâëëìæîêÚðïåðåäåâëçñéåãäþâåæûîòèðäëãîáóíèæ÷ìæáîêäíáèßçïìÛëàâëêíãåëãææéÓäëìæîóëååãîáôðçãéîîèëããåöçæåæçñéíÙäÝçèäèêîáççòÞïäââëëü÷ÞæéåéèéâèãíéëáàÝèÜÛàáäíðçðîìöçåâåëëÞáçâóñðââÞæáãåçìÚïèëäëðåçêãèáôôÅѸÌÄÆÌÇÌÅÁÑÁËÒÍËÈËÉÈÏÈÄÈÑÂÉÉÎÌÂÔÊÊÊÌÊÈÈÄÅÈÁÏÁÊÈÅÉÂËÍÆÌÇËÆÆÇÆÉÊÏÆËÐÄËÊü¼¶½À¾¿µ¾½·¶½º½¸¸¿ºÀµ¾À¾¸Á»×ÙÕÓÚÉ×ÏÏÑÜàØÞÎÐÕÔÕÜÚÝÑßËØÜÛÞØÞÓßÓßßÕàÖÝÓÞÚÓÔÔÐÒÓéÒÜØÕÚÏØÖ×ÍÕãÐ×Ï×ÑÙÞÛÒÚ×ÕÜÏÕÐÔÜ×ÍÖÔÖßéÑÛÒÒÕÏÕÔÕÌËßÚÊÒßáÏÚÑÝáÝÙÓÌÝßàÜÞÛÖÝÝßÒØÖÖÚÑÜÛÖËãÏÍÔÔÚÏ×ÚÐéØÌæéÞÔÔÙߨ×רØÐÒ×Ý×ÖÝËâÐÑÑÔÚÖÔÛÊØÐ×áæäßßÚÎÙáÝáÞÑÙáÖÙÕÒÙØÚÔÙèÞÏÜÛÖÚåÞØÔäáÛÛÖâÏÖÖÞß×àÔÐäÞÚ×à×ÖàØÙáÜØàÕØÝÒÞÕÞØÜÙÐáÑÜáÑ×ßÖØÑÚäàÜÖÕÖÞÝÓÝÔàÆâÔÓÏÞÌÐÛ×ÕÛØÙØÙ×ÙÈËÏ×ÚÝÖÜÙ×ÐÔÖÞßÔâÝÑÎÔáäÛÛÜÙÓáÎàæÍÏãÚÜàÔÔâáÖÖØçÖÊÏÓÝÞÖàÑÝÔÓÏÔÔÐÚÓÔßÖÙÙÓàÕÝØÒÔßÍÑÝÒ×ÙØÛØÍÕÞÜÝÒâÝÔÔãàáØÕÛÏÌâÞÔÏÚÎÛÚÏ×ÖßåÛÉßäÜÇÝáÏçØÕàÕÙÑÔÙßãÑÕÜÞÔ×àÛàëÕÜØåäÔÙרÛßßÖÔ×ãÚÛÝßâÐæÙâÊÔÓáÜÞ×ÑÛÓÙÑÙØÒÕÝÙËÖÝêÝÖïÚàÒÒÞÔÕÙÙÝäÐÙÔ×çÔÔÖåÒØáÑÙßÖÑÖÖÔáãØÓÕÔÕÙÓØÙç×ÌÛìÖâßÞÚÜÏÛÛçÐÕÛÊÓÓ×ÕØÛÒÙØ×Ü×ÔÛÝÛÑÓËÞáÎáØÙÛÖÍãÚ×ÚÞÕÈÚÕÞäÕÜáàÚÔäàÔÜÜÎÛÔÏØÍÕßßáÚÕÏÕÌâÈÚÚàÙáÓÃÖÙ×ÔâÞÓߨÖàÓÒàáÜÕÛÜËÐÏÕÓ×ßÊÕåØÑ׿àÚÔÖØáÚØÞÑßÛÞÍÍÎÔãßÔßé×ÕÙÎÉÝØßââÒØÚÖã×ÔàÒ×ÌË×ÚÜÐÏÑÄÓÆÜÛÝÑßÙÚãÚÕÙÚáÑÝçâÖÝÜÙçÌìÓÛÏÚÑÕÔÞÏÖÝÔËÖÐÔÛÕÔÊÍÓØÑÔàåÛÛÖâÔÕÞÞÐÐÏÜØ×ÕÓ×ÚÞÔÚãØÐåÜÛÞâÔÞ×ÞØØÕ×ÕÝåÔÔÜÖÙæÞÞÐßÓÙÚÙÊÜÕÛÎÚÚÞÏÙÎÛÝÚàÏ×Ù×ÝÖÞàÞ×ÛÚØÞÚäÐÛØÚÚÛàâÑäÚÛ×áØÒÕÞÖÏÚÕÍ×ÓÄÛÏÓÜçàÛÓÝÕÛìÔÓÔÜÎÞ×ÚÔßËáäÏéßâÝÒËæâÞÚâÙÜãÑ×Ô×ËÕÓØÎÖÑרÛÎÏÓÛÓÚÝäãÓÙÝØÓÖÌ×ÓÍÚìàÖÛÙèåÏÜÖØÌÚÚÚÝÚØÑÌ×ÕÜ×ÜÝßËÞàÔÓÞÚÔߨ×ÝÖÛØà×ãÞÛÛàÉ×ãÜÚÜ×ÕéâÞÛÞ×ÛàßÞèÝÝàÓ×à×ÝÜÙèòÖö‚÷î÷âØÙÛØÓÚÙ×ÙÊÊàÞãÊÜÄÎäØÓÙÌÖßÓÞÔÒàÏÜÍÝÛÞÖáßáØÞÕÚÔÓÜåÛâ×ÔØÒÝÙÞÖÔ×äÛËߨܨÞíàÊÜÙÔÞ×ÕÙÝÒÛÙÓÙÝÜÚéÏÈÝÓÒÙÔÖÕÎÛ×ÕÙÎÖãÝæþ‚÷áíäÝÕĶľ¾Ã´»Ã¸¾¶º¼·¼À¿¹¸¹Ä¾»¿ÃÀ·»À¸³ºµ¹¾Âºµ±¶¶Ã»¹¶¹¹´¶·¶Å··¾¶½¿ÆÃÀÁ¸¹»º½¶¹´º¸®±¸·´·¹±¶¹»ºµ±º´·¸¶Âº¸°³¹½ÌÐÊÊÔÕÒÍÖÌÙØÔÑÊÓÚÔÔÎËËÙÓÐÖÒÓÕÛÞÒæÙØêÏÜËÖ××ÚÑÒÎÍÓÏÒÊÚÜÛËÖÏÓÕÐÒÓÍÌãÑÒÌÓßÒÞÚÏÓÑÐáÆÖÎÜÌØÔÐÍÒÚ×ÔÖÔáÍÓÚÚÏ×ÝÒÎÙÑØÏÐÛÑâÓÒÉÍÑÔÙ×ßÝÏÓÊÜæÖÞÏÓÜØÔÛÛÕÝÒÜÑÔÛÙÖÖÎÙÙ×ÚÒÑÓæ×ÔÖÐÔÌÛÝÞÎÜÈÙÚÓÍÖßÖÕØÕÖÞËÓÓÒÔ×ÓÛÚÓÊÑÍÉÉÔßãÊÝâÖàØÛÖÜÔßÔßÖÔÔ×ÉÖÙÔÌÜÐÏÔßÝ×ÕÑÕÖÕÔÏÔØÑÖÏÓÒÖÖÊÐÅÕÐÒ×ÔÒÕçÝßÑÜÚàÏÊÔÌÜÇÉÎÎÓÙÝÏÕÒØ××ÏÚÜÏÚרÑÏÒÙËÐÓÓÒâÝÎâÔÄØÒÔÚÑËÕÏÐÚÍÖÛÚáØØÔÓÍ×ÏÏËØÆÐÔÛÒÕÖÌÓÚÊÐÏÎÓרËÞÕÜÔÍÙàÛß××ÍÕÏÅÍÒÏÙáØÔÕâÙÌÜÓÓÕáÒÐÕßÐÒØÎ×ÒÒ×ÚÚèÌÜÞÞ×ÕÊÑÒØÛÏÜÁÕØßÎØÉÙÔãÓÝÑÌ×ÔËËË×ÏÔÕÏÆÝÄÓÏØÌ×Õâ×ÙÔÎÔÜÍåáÜÜÎ×ÖßÖÙÊÏÎÐÒØ×ØÕÙÝÖÕÐ×ÌÓÖÎßÐÖÕÔËÙÛÝÝÝÅÌÎÊÖÖÚÖÛÉÛÝËÙÔäÐÐÓäÐÚÒÖ×ÔØÉ×éÖØØÉÓË×ÔÝ×ãÙßÖèÐÙÑÓÖÕÔÚ××ÖÞäÉÎÒØÑÌ×ÎרÐÏÏÜÕÙÒÛÕÙÕÌáÕØÐÏÒÛÝÙÖâÚÕÍÓÉÓ××ÍÔØÖÑÛÒÏÎÞÖãÙÞàÛÑÒÐÌÚÍÚÓÓëØÕÝäÍÎÌØÓÖÚÜÎàÖÑÙÐÎ×ÓÚÔÎßâÉÇØÑÝÜØÏÑÍ×ÏÙÌÑÎÎÓÝßÚÛà×ÑÏÓÏÕÔÊÝÖÌÕ×ÚÒÕÞÓÓÐר×ÔÞÒÖÞÐÖÕÌÔÛÒÏ×ÕâÜÒÞØÛÛÑÒÓÑØÜÔÜÝ×ÏÔÉàÖÔãÍàÔÜÔÏÎÛÕßÐÚÔàØ×ÏרÓÕáØËâÀÕØéÌÓáßרÐ×ÙÐÑÔÖÒÍÖÏèÕÙØÑÎÓÌØÏÑÏÕÑÝ×ÝÚÖâÜÓÜÓáÐÞÖÎÓÕãÛÛÑ××ÌÖÖÒØÓÎÑÝÓÑÓÖØÖÌÐ×ÓÔÝÕÕÙÛÙÑÛÌÒÍØÏÝÊØÝÛÌØÖÖÛÜâÕØÄØÒÜÚàÕËÓÓÏÖÕÚÙÓÓÑÝÖØèÜáÞÙÕØÈÌØÍ×ÛÊßÔÐÖÚÍÖÕáßÍÛÏÙÛÞÔÎÇÔ×ÎÑÑÅÖÒÔÚÞÔÙÑä×ÔØËÒÕÓÝÐÎÐãÚÔ×ÖÐÖÓàØØÐÐÕ×ÛÚÐÓÏáÖÜÖÛÒØäÛÒÞÛÎâÕâÎÖËËÍæÖØÇÔÍÕÙÐÎÒÐÐÔÔßÖÕÓ×ÍÜ×ÒÓÛÓÜÖÔÒÏÉÝÜÅÛ×ÚÓËßËØÓÒÍÑÙÓÖÉÑÚàÚÙÐÕÔÔ×ÔÎ×ÌÏ×Ì×ÑÊØÚÖÕÝÑÒÛÏÙÙÑ××àÚØÙÐÈßÕÙçð‚ ìÐÐßÌØÒÛÓÕÎÖ×ÏÐ×ÔÕÎÒÜÉÖÒÖâÙ×ßÔÖÖ×ÚÖ×ÉØÔÙÑÔãÓÇÜÓÙÔÙàÜÚÚÛÍÔÞÛØÑÖÐÐØÕ×ÜÜÕÚÉÏÓÖÛÚÓÊÝÌÙÒÔÑÖµ²¹®º²µ²µÀ¸´º¿²µ´»¶¸¼³´·º·´¹º·¹Á·¹º¸¿±²µ±µ°¹»­Ã´¸¹º¸¾¼ºµµ®µ¼º¹µº´¿ºµµ¼ºÉÔÏÂÎÐËÎÎÆÊÈÌÉÈËÒÍÐÇÐÑÆÍÎÊÍàìåèãëêèêîàæàæèåíéöñìêéâïññÞõáïæíêìëåóøáç÷éñõáçììèéòüçëçëñíìíúåèêäßñåäìáëÜóèÜðíâáóíòçåáñáçãìíçãïÛÙåÜëãìéíßóââñöâßÜîìéñâçèìëõõåáåáõÝñíèßëçíããéâðîõéñðøôÝïïíêêæ÷éæíé÷êàèáñéçéâèôëæäçëàæêôæóèïíêêàóñëôòåâîóçùù÷Õðçðî÷êéòïàëêëëõçôæìäïàâòãñæääùéëðéæçîçåðéñèäëêììææòíòßÝðÝêõÛÛêèêïßäðìæÝãñêòðáäùêõíêçíôçõîÞêåèíçêóïíëáêåîúîîëôàäåçéçìãëêççêèïíéçíãããïæëóìåõõõàßæèíÜåàéòðìäîèøöëäêêñíùíìâðïðæìôêßãòäðëãïîôãâêîàêóùÙìéêúßìøæòèòðñãîáîÜäâðéäâéîëäãíéæìÜåèéùÝòÝéìàîèåíãã÷ãäññäáùåæõßíèëðééÝòêèÙèý÷áñçíäéæçðåÝæàøæðéàáåóçóñÞáæåçüíôïõãîîõíäôçèîãããáêáñãóéëçìîäïåãæìéææáèëóêãóãæêéßåèÛèßêãðäêâÞìîæñæöçôìñîñÞïïíêíìïâðìæàèëìòðóåèåñîïêåêéèéíæçíåèÞéëéëííøÞèþìîûøðçéèßãëãêëÚëèëèôåëóìñîíãïýóïàçéñéééãêäûäèâúäíïèÙßíççèêëãîëíèéÛäòãåèçåïíïèíèöåâíííãêìïëíêñ÷àçîãêðéÜðæçíãæãéîÜÞãäÛãáàêîìãëÝëÝææôëûæïîããßàñìïçòèëñëåõßéññèôëÜæÜåêñãçÞäóïîòÝêêõØéðó×ïèêèìçåðèíïäïçîèáäêßõêòæáõÖæãåéåóàåëêâÝïòõïééìêîïêáçâàñîåëéêèâÖðèÙéïïâå÷äïæâñëèäêóéãæææççñíããéâåèèßëìæìíæÝíðâêîðëðîùïåíÙöòáäâãæäâñâàéóïÞéïêáïïåèåáçééîæåëëè÷ääõäåçãïìáõéóäçéãåìäêéçíøõëíááææâÝáàÞïãçôãïîíïóìèáéòñáèæàëèîìøáùéòçñêêÜØéìñçøìïáöêáîùòãêúüîèæáðáøëëâóçõíòèìãçîîèéëéßæÚòèîëæáèßàéåêäæíééñòéîóîåäçêæððæòææìÞíôÜóæáíåééçíóöõðëøêèòúåàóìæêïßìòòôñëîËÅÈÍËÊÀÒÄÃÍÅÏÏËÊÔÌÉÊÏÎËÉÆÆÍÌÒÍÊÇÓÕÈÏÃÌÒÏÓËÆÊÏÆÌ¿ÌÄÇÆÒËÌÆÏÍÈÊËÏÆÂÌÃÉÂÈÑÉÏÈÍÍÈËÎÏÌÑÌÛÔÏÏÈÐÓÑÎÑÊÊÇÌÊÐðëóëã÷äûçíéõåíéíìñçÙàèò÷éîêëöñÞõñõóôëäïæîîéñëôëíúóñôåëèäíèæëùëìßóòèèòíõôèîçåâêòðëòöøêþâúë÷êñÝðçõãîíïîþéô‚òæäèãêçïêñõóãñÞñååîòæõñöðôïúíþèæïæíéíêéðéðäéøòãäìòåêæéëïðíéûì‚ó‚sðåìôäëññäñíîíñæö÷òòåàòëëôîòèöíäÝáòìõ÷èðîïííèêíêãóñóìøîñîôõäçöðììéûúñëñéïððìóùñýâûöëðäóòïöóããßîåæòéðíïñöæïêòëåèíëòóêèìðîèéúöâïåôïåèôñèöðëçñæíìòäåèêõêòå÷çíýèðòòçíè÷öóåóåöáîñëöçðóéíóôçïêìóõîîôäìòðïôéôíìïîïèïðíèâìæñãìêéëéííåìõûâóìñìïìõðôóíîöáæ÷óúóßäóûçîîûäÞíèöìèéíëñêìíìèëâäìõèíïñêêèâïåêãññ‚èßòùëâçíìôèîùóîðèøúïæéöíñîêïôçêëèîìæçáãóêðïçäîìóõ÷ïïïïñõïóëñìòèðíùóúóæöóçîãæðêùçúîøâüéíæôñïæ÷ëëêø÷èëñöðáìùúåëôöçóäëõóíéëéøèôæøìéþåüëæîîêìçîñäëåðíæñðýíïäãñîéêîäñìöèøïîôð÷æïøôçÿñôõëîîóúêéñíóíöñóîúèóñâéóíéíâææöîðíèóøãÿçèõðëñðæîâéëéèíïæóéïéäöéóäåîóñúòîéêðîììëòæßèääöáíííðâêéïæç÷óûäé÷øâòæñïí÷ïòßùëóâæéñóý÷ùñêæüñíéîøñéïöçùêìïìïéôñíäìçðéóóñóøéçê÷õåêüéêêïììæìæêëíúóæòîçðéðóôêòîòæîèôáïåõê‚ìúìçæ÷êäî÷óíî‚ñëãôôóò÷îàíôéèúäæáëêóãôêíéëèåñèøíäöòêóíëëåòôíòëðøõîééçèçâëçÞéîãêíòéôçìóæíîùàìðëñîìæîïïêïèëêï÷óûìòíñíðóðïÞóåøÝ‚íûçðêãîïâôçõñðëóçæíòòéïûêåëûëóîíîìïòßíõñïèïëêííèñæêêèçòîíñìñèòøéáóåéøçõéäêòåìéäñð‚êâæ÷èîïöõëäéêóæèéîðøæþîæìëìöãðôçèâæðñàëøðæñîðõñî÷íõèîèïíúâòëîÓòëîõæïìóë÷óóáëíèâæóòîîåîøôóæõïÚèéçèééäïæøèëñïóçóÒÎÖÆÊÔÏÎÓÅÍÇÏÈÑÐÔÒÐÔÓÕÏÌÍËÉÈÔÏÒÑËÖÒÕÈÑÍËÓÐÊÓÒÓÌËÎÐÚÑËÖÖÒÏÓÒÕÒÎÔÕÔÉÍÎ×ÊѶ»²¼¯¹·À½½´²·´½·¸µ·¸¹ºµº¸¹³àÙáÝ×ßßÜÞÞØßÖÝÌÝÜÐÖÒÖ×ÍÑÙáäÙÞÕ×ÈØßÕãÕÓÍÐÞ×ÜÝÔÍÐÐÜâÛÌßàÛÌáÕßÙØÌÓãæÕàÜÓáÛÑÇáÛÕÕÈÒÌÒÙÕÊÚØÔÕÝÙÞÝâáÝÚÞÆÜÚÙÓßÚÙÑäÕÜÍÒÝÙÚÓÔßÒÞÜÔâÚàÕÜרâÖäÔÙËÝÙÔÕÏÑÝßÙÜÏ×ÔÕÙÚÎÚÐÌÓàÜÜÞÝØà×ÜËÔÝÔÙ×ÓÑÖÚÖßÚÖÕâØÜÍÛÒÛÖÛÖÚÞÖÛÊÝÕÕáÜÓÙÕÔÓÞÓÙÖÙæàÍåÅàÛ×ßÌãÛÐ×ÕçæÖÐ×ÙËÛÓÚÕÞÒÙÙÖåáÞÓåãßÙØØÐÒÞÕÛáãÕÕÝâØÚÜÛÜÖÙ×ÙÕÒ×ÝÝÙÜÚàåÍÜÖÞÍÜÔÖÔÔÓÞÒÛáÖ×âÙÚçÛØ××àÙÛÎÖáÔ×àÑÌÓÓæÌÜÏÝØÔÍáØáÔØÙÐÔÙÝáÒÜÙâÞÐÖÝêÕÛ×ÕÞÝÚÚØÛáÙÞÒáÔÏØÚæÝ×ðÒÒÐÛÜÞÏÚÝçÔ×ÐÜØÐÖÑÛêÒÝÓÝÒßã×ÔØØÞØÜ×ÚÑÇÞÑÙØÍæåÝÐÓÛØØÖÞÜØÓáÕÖÛÉÍáÖØàêäÕÖçâÙÝÑÚÞØèÞäÛÒÛÍØÔÜàâÕÜæÚÑáÜàäÑÜ×ÙÚÞÛàÙÕÚÖàÛÕ×ÚÙÔÕÖÝÏÜÏÒèÖßÞÕÐÔçâáëÕÖÕÑãÊÖÓ×ÊÏÍÏÚØÕÍÑãÛÝÛÚÝâÖÐÛÑÓÊÓÔÌÔæÛÞ×ÔÐÛà×ÏÝÙÕÖ×áÔÞÖÍ×ÔÛââÓÛÝÔÜáâØÝÏßÕØÒÐÈßèÌÎÛÖÍ×áÝÙÚâÈàÒÝÐÖÐÚ×ÑÐáÝÔ×ÓÔÎÜÍâ׿ÕÔÛËÛÐÙËßÎÙáÜÞÙÚÞ×ßÜÎÚØëÜáÒ×ÜÒßÛÚÓÚÛÒß×ß×ÐÐ×äÙäÎØÖÚÙâÞØÞÙÚØÑÔÎÔãÏØÑÕÒÖËÐÆÓÛåÎÞåÛÝÑÞÕÚÙØÐÒÙ×ÕÝÙÞÑëÛÞÛÜâÔÓßÖÜÕÏåÏØÓÒÒÏÒÙÞÝäÝÚáÑÓÚËÔÓÝÓÎÑÙÝÑÛÎÚÔÞÕÐÙâÖäÞÒÚàÔÕÎâÚáÛÙÞØÝÝÒÝÛØÔáÛâÏë×Õ׿ÌÓçÊÛßáÛØÝÛ×ÎÕÊáÚçÜÞÔÐèÈÝ×ÕÐàÞÜÔßÚÓÙÚÛ×Û×ÍÚÖàÑâÜÍÚÜÓÔÚÒÏÓÕÖÚÔåÓá×ÑÓÕØÎØÖÓàÙÚÛØÓÏÖÝÜß×ÙÙÜÙèÙÝçßÔÐß×Û‚EÚæÈß×ÏÇÒØÝÌáÙäÔÞÏÏÜÛÜßÛáÜØ×ÛÜáÍÕÙÛÚáÕàÒÕàãØÛÑáÓÏØÐÛÏÝßÝØÙÝÖ×ÝÞãÜßÞÖÉÓâáÊÑÔÕßáÕÙÖáãÏâÜÒàÐàßàÉàÎÐÏÎÖÕÙØØâÐÕ×ÓãÞáãÑØÒÖÒÔØÛäÝÑÚâÑÜËÑÛÔëÖÙÝÕÚÍÑ×ÎÐÈÚßÔÐÔÕêÙ×ÖØÛÕÖÚÚÛàÓÚäÚÏÍÏÓÏÚÒÒÓÝÜßÕáÔ×ßÞßÜÔÙØÜØØàâàÓÛáãÕ×ÛØëØÑߨÚ×àÒÝäÖØÖÐÜÙÐæã×ÖÝÖÐãàÐàÞ×Ò×ÛÚÜØâÒÏáÕÖÎÛÑÓÕÖ×ÞÝÙÖàÕµ¾·»º¸¸¶ºÃ¼¿¿º¶¹¼¼µ¼»À¿¶À½·ºÃ¿¶·Á¸¾¾Â¿À·»º¸»¿´ÁÀ¶¸¹Âý¼Â»º¾¼¸»··»º¶Â½³¼ÊÅÂÆÀÌÈÈÀÉÅ¿ÃÆÅ¿ÐÈÄÄÀÆÆÉÇÉ»çåØåÛÞèëÝ×âÚëèââëáàäçêìØæðáÛíçåïçÝÝéñàÚáääñãå×ãìæãäØßÒßÝ×Ü×îæßåâÝïãàØæÛäéáåÜàòÞÞÝÚééÝåòúÚìîì×Üâß××ÞåëÜàéçÛàåìèÞâÙÝçèÜèàããÜâãççãÙÝââñÝìÚêÚçèæïèìäâãåÞÝäãßÞëðéÜáÖáßéçä×ÞôßããçðßáçæàÔèåÛåèçïÕæÝÜÞçÜíæáåäæÛÝãéÚìØéïáëߨãÜÓÞåÜÖëààÙëäáÛêÙâäéççÝäëëçâÞñÜÝÝáèâüÜÞÙØèèÛáæäáÞéãäßîäßêåêÞçàæÜàèâéßáäêñÝñìçÜîåßääàóíÝãßÝîéÙìÞÞêßÙÜÕßåçãÜâãåèâÚçìëÙïèÜåâ×ñæäãàãæÜÖóßàÚÖåÖîÕêââßÞßèêÜéáÙòììåèèàðçäãåÛÚãÍÝÖÜëåÜáéöãÛã×âäÜåçåìæäÙêäæåãåâïÚâßàäèÓëäêäââççììäÞíåàÛôéåÖâÛèìêÙëÙàáßæÜÛìÝÜçßéÙÞâéÓãêâàæïîàÜèíéÝÕîïããßåãâÝÜíèáÝèæãßÝëèëíãØãÞäíáÚàêßëçáçØÝÞßçéÜßÚèìäêëæÜáãääÞßÞÚçéçãÜæÜàèáàæàâÔæéåéßæÙéÛãäÜÑäÞßãñðæÞßâåêïâåéëæíìâÜãçÜñàõäçêæòêçâãåÜàãêâæáÚàò×ëãä×ãæéãÖëâæâÚìâàæçÛèèäßîãÞàÜÙáãÝäåÛåçÛôÙñêäÞéàåâààßßåÕæÞèÝâáàèêÞÛÝåãØãäÛØØááðæ×ßÞãëÕçåàãêÛçí×ïîÝáØê×ÚÛããëàðàÚØêØâëåçÛãêèð÷íÝåççäéÝÜçáéîßëåäàãìæãÙßëßÞ×èßìèÐÜãÛáÝÛåÜâææØàâÞãëåàâáÞãÞåäàááæÜåàéëêåæãÚñäæåßÜÚäæ×ß×àåÕßðæåÛààìåãÝçãâãäåãâçÛæçÞÜÕßáÜ×åèêã×ß×ÖåßìàóéåÙàÝöÝáÝðÞåäæàãéâáäìñáêáèìèëäÜÞÜÙçßããìåÜÛáçàâáßßåÛæàãÝìÛàçßÚÖæèããàÛØèäÜßåáðæêáÞáàñÞàãáêÖäââ×ÙâãçßåãæîßÞçÝáâéÓêÛÔÝíÜÞßÞàÙäáßÕßïçíÛßá×åìàåíáêãïáçæÝéìÙÝéÙêáðåÝêÞÞãñÜàÚâìàëëåÓïéà×îâìäàÜâÙÜæâáÜæáããåâØñëáÒêÝáßãÞÖÞæèßáåëáãÞãÛäßååàÞÝäèéæéÙàæÕÝèÖÙæíáêãìßÞÜáäëðáàßíðå×ãáêíÛÜäæãÝìäàëãéàèàéäßèà¿ÁÈÊÈË·ÇÂÆÁÆÁÂÏÅÄÃÁÇÄÆÂÉËÈÅÈÈÅÿÀÂŽÃÈÇÁÂÁÎÇÁ¾ÆÇÉÊÉÂÉËÅÊÃÁÃÂÄÇÂÈÂÆÊÊÃÊÄ»¾ÅÇÇÄÄÂÌÁ½Ç¾ÆÃÉÀÃÃÅÂÂÄÂÀ¾¼áÙÞÛÝæÛÜÞáÙæÜæÙÚâÙáäÜãÙæâäãáØáÓæãöÑÞÞÔáÜæáÞÍáäÜâØÝÝäÜÜÜæÝÞßà×ÜâäâéÜâéÙÖâ×àØÝæââêÙØëØáÞëáÚßçßçàäñäåÕÞãà×íéêÜÜÝÏéÝæÛÜÞÖåçãÝìæÛØäêèÓãÖÚÜèåñàÝçáàÝãÙâßÒáãßæàéßâàâäÜàÜèâÛíÚåÜÚâéàÝÚß×çåçÕæÙÝà×è×ëäçäÕåÞߨäØÛæÛÚÜàéÛâÞßÜâÚäßÞàæäæáâÝßäÖåÜê×ßÒÝ÷üÜìßÍåÚäàæçÝàÚÙÓÖçßàÛÝêÚáåÝØÖÚãáæÝäÞåéáÝÛÝàáâæØáéìçßÞêäÞäââæäÔéÛåÖéìÝäÖÛìèå×ßêëÞëèÕàÙòÕàÝßáàåàêãÜãïàÞäÝâÛîáßäâáßêáæáîãïâßÜàâçàäàÜëáëÞãÕíßãêåàâäéæÚØëÚÛêÝîÛðßäÙÙåÖÞêìéÞâáçêÛØÕßòÜØÞ×ÖàåäçåâåäÚäßâêÝÚééçßãêåâÜâãáÞàÙîÞêÞìÝáÕßáäÞÝéØßáçØÜâßåäØÛçåØ×ÞæÙáÝìðØèêëßäßèßëÓÝêÙÞçÕâðÞãâÎÕãÛåãÖÏ×çÚàìëåßðâèäàäìÞÔàÚéòïÓâçÔÓàÜãßãâêàåß×ÕæØäÙæàØÞÜéèæêàÕæâÖßâÝÚéåÙàÝàÓÖäâéäéÝçåï‚àÔÕâÞâãÜÞÛîàßåñÜàÒàÜߨãæáòëçßñßáæáÚÝÖêèÕÝãßÜÚàßéÝéÜÚàØÚéÞäáÞäààéãç×ÓßÝÚÜߨÜáàäåÞÕ×ÝæåðäÙÙßéÙéæååêââáåÞäÛßäÕäÔéÝßãóÚçãÜààãèåÛÓçèççãááÝÛæàÛÖÍäáåæáÞêàäáààäáßרâáåÛëáÙÙÛãÛçæäáíÙåØÔØßÝØÜÒÙÝâßçÙÝìåÞããÞÛäôæðûäßäãìäéÔïçØæÑèàäïãÜåßï×ååÙæÙÖçåÙáãæßçÝáÜàáÛéääàÜÝÝÚçÛáàÝÚãäÞãçßÙèãåæßâàÖèäÝïÚÛâÛãßáÔîêãäæåáåãææßáÛäãÛàÙåÝåæÞÛìæåÛØêÙçØßéäßãáéãçØêççÞßäâéìãêÙæäáèâßáéßÐÝèíáØÙÝïáõèÜäßßÝêæçéòáçêÏÝÜíëÚÞáèéÞéåáàåÙÚæÑéßßáÞÛèæëââèÞãâßãÛâÛåÛØæèÜÜÜÜßâéÜååâÕÔãäßåÞÛäæßãßååàÞàçÓáàèÞâÖòáÚÕÝäßÞÔßßàôßÜÜãØèææßßÛÚáëÜïçÜåàäâåØÚäÙÙØÝÞàÚÕÛåØÑÙåÝêßàãæéÒèÛâáÞåëëçÞâÕàçÝäåêèßÕâåàØäàãÜØàëÛêåçëÞáêâó‚ìÝÇ¿ÀÄËüÁÄÀÉÄÆ¼ÂÅÅȹÊÐÀ¼ÆÁÈÁÍÀÀÀÄÁÆÑƽÄÃÃÁÁȽ»ÀÆËÆÇÃÃÂÂÃÁÁÄÉÅ¿¿ÌɼįÇÄËÈÇÌÂÊÅÌË¿ÎÇÊÉÂÈÇËÈÆÆÑÉÒÐÄÏðêðãëæëæáääãçðïñæìçäðÝïîèôãóíèææäáìßÙòçìõöèàêåôòÜíåëèæíâóíèìðáñèçêæöêçáãæããìØæáâïèëçñçâÞûÛèâÞÜêáÝ×ßíãðóòæØÞéäòêèâÝðéëûêëíãêóäåíèêðãØêëæääóéîááâôèíäæîèæâäÞàåâçèêçæåàááßéíçæäïÝ÷ñäðâáéöéÝîîåáàíïçãíååñáúåòìëíôìîöæàèéãåëîáÛïçðëäóàéèôîçäõïíàíñãæàâéãäççãéõëìêðêôéæíïëîíàïëôìôíÜîÞëçíåõâèëæìæèâæÛÕßüêìêöæáîêêÖëãëßñåðÝíìÜèòõáèëãäæçìóíåáÜëêáÙêíÝèîóàèñýéÞííçäáèýêòîáóàáÞàäãèíßèìöèãéëïÛêßîäééæåñïäáéæíêÞäíèéáïçðæãïêãïïÝêåèóôäèêìèìîéÞíçëåëéâò÷æìëëìèëÝêîèîæìèàáàìßéìíìÞëáéîúõïçñõîòîãòãåßÞææéíëâáçìàíåìíâèòÛèëëëêðÞóúíÛÕéìíóãéëö×èêòàêæåñèðíòòõäïãñóéçæñãóêñçßÜáÞîéèèééæòöðèßïôìÛçíéôÕöóãëèøéíâãðìïôèçåØðôïéìõìçìí÷áïêçåæãåìóñíôååÝéÞÝðçîÛàåáñõïÞéæäâäãâáìíìëìäãùæÞæìëîæñìäÝâáëåÕÜçæêíëóåâêæåÚóéëßîêåéãìáæîôßãìãëèúâêåíåãçíðêâåïñâÙêÜàâðãâßíÙõãèæÛÚëáìåìãëîçÖâðíñêÙãÚåêçÙêöñíêæÞþåìäêïõåæçûåàêéèêâîâæòòîìèâõêâêëæçßßæäæçááøëÞîêçêÛëçéóíòòìâÞèÞæéâÿêïáåõîøèïéíâÙêìèçåí‚€ïãæåâàëéëëìïðåëåíîâñíèðâæÞßéç×éîèêïéâïßîÛãîäê÷ïêêâçêëõàïìñßáèææðÛáäéìåàóèÝäåäìîñçíÝíêèåæìñîëñëôäæåõéòâé×éêí×ÚäÞæëðæãòóíÝïäëåðâêàíùàçëäâìäîõêùòïã‚ãîòäòõÿñðò‚ï‚‚‚%‚E‚0‚‚‚,‚*‚)‚*‚‚*‚‚‚%‚1‚(‚‚‚‚ ‚‚ÿ‚ú‚‚‚‚ ù‚ñú‚þøðóïë÷áùíèêæïÞççôÞæñíèÞñÝíòãîìÖëííëæçäæëçíééãøìëâçìëÚâÛäíëçÜâìäñêèèáñîòïóìçóæóâÝæàôæåäðâãáüíåõïõÛöóâðíçßêçìãåëàèèäðßéãôéçÑÆÌÉÏÉÆÊËÓÎÅÊÔÆËÉÉØÎÒÉÍÉ¿ÏËÊÆËÄÐÀÊÉËËÇÈËÊÉÍÊÉÌÌÑÎÉÎÅÂÄÄÓËÇ¿ÍÎÑÃÅÐÍÌÃÆÎÀÂúżÁ·À¶º¿ÀºÁÁµº¶»ÁÆ¿À±ÓæàÜÖÚ×ââÍÕâÚÚÕåÖÒæÔÙÚÐØßÍÛØáÙãÚÚäØÔרÜèÓßäØßÍâ×ÝÖåÙÚÚÙÚÚÙæÜÚ×ÞÚØßÑâÓØÜØá×ÓÝáÙÞØÜÓáÒãÚÞêÔØßáÐÔÑÝÝÛáæÚÕÝàÛÜÚÔÎåÏÑÑÒÙãÝßÞÞáÈßææÞÖæàãÓÞÚÜâÝ×ÓÜÛ×ÚâíÝÜéÓÐááÜáÖÌ×ÕÙÒßáÔÕÜÙÔáÝèÖØÝÝõâÏ×ÛÛ×à×ßÜá×ÚÞêÐÛâÞÐÕÙËÞÒ×ÙèàÒßðÖߨàÐÔÝáÔÚר×ÙÛÕäÖÕÝÞÖÚãÖáèÄÞØÖÌØÒÙâÕÞÕÚÕàáàÖäÕØÞçäÔãØÒÜãÕÝÞÔäÚÞã×ÜÔäÒÔËãæáÛÕ×çÞßßÛÝÑäÌÜèãÑØÞáÔÙÞÏßÏäåÞÕÙÒÞÔÛàÛÓÞàÍØÞèÔàÕßÔÖÖÜÞàÒèÙØÚÑàåÛÝîÝóÕÛÕéØÚéáàÝÖÚËÙÕÞãâêÍÚæØÏÝÞèéÚßàÚÒÜáÝâ‚?ßÖÏÓØáÝÕÞÜØÔàÐÝàÑÏßÚàÜâÜÝÖÕÚÕÙêÛÚÓÎÞ×ÙåÝÝâߨ×ÜÝÛäØÙâÚÒâØÔßÎÕâßæåßáÜß×ÝÙáÕèàÒÝ×áÝÚÓèãÑÌßáëßÓ×ÝÖàáåÝÞ×àÌÚÜÓÞØáÔÖÚàØÛÑÖáÓçãÛßÜÛ×ÙÓáçÏÓÐÙÜ׿ÜÙÙãÞÝÛàãáÕÞÓ×ÔåâÞÌÚÖâà׿áââ×àÕÙÖÖÜÑÜèÛÔÕÞäÞߨØÝÓÕãÝäÍÞÕ×Ü×ÛÛÒÓÐàÜ×ÑÖáÛÚ×ÕÚãÏãàæØæÑÜàéÙÏÕâåÓèØÖïÛÛÝÙßßÕÐÙØÙÜÍÕæÙÞàåÙâÝêÛÖÍÚâÜÙ×ÕÙרÓÓÜÜãÞâÓߨñÚÔÒàÝÚÕÛÜçáçåéÓÕÔÛÝáÚÚÏÜàÕÛÛÙ×ÜÝ×ÕßÔÓÜÕââßâÓßßãÝÖ×ÝâÊçá×ãÚÞÙæË×ÛÜàà×ÔæåרààÐÚØÝçÖâÚÔáÓØÙרâÚÝßßÝÓ×ÜÐæßáâàÎåÍÖÇßÙã×ÕåÏáÔÔÝÜÓÚÓÞÌÕáØÝâÙÍÚÙÚÑÓäÜØÞÜÚÚÕ×åàÜ×ÓÜÜÛÝÑÞÙÜ×ߨÚÈÜàæÚÚÓÝßãâàåÖÚÏÓÜåÝÙÓèàÎÚ×ÙÕàâÖâÐæîÓàÜÑÞÛÙÕÐÛàÖØÛÛÖÚßߨÞÚàÔÛÞÛÏÛ×ÕÙÏÚÏèÜØÛßÓèáÕØíÛÜÕÙÙÚÖÖãäÖÕàÕêåרâÙÓâÎÖÒÙÕäÓÑÙÚàÕÚ×ÜâØÙÙÛßÜÙßÞßàÔÜÜÍÜÛßßÜâ××ÜÔÙÔèÚÜßÜ×ÜÜÜÓÜßÚÜÓÝØÖáÏåÝÕáÚáÞàÕÑÒßÛäßàËÖñßÞÙÞÙ×ÚÛÖÚÖàÔæßÛØåÚÞÛãæÞÞßÞÞÞÐÙÝääÝßÔÖÜÝÔÛÞÍÙÛÔãÏÚèÚÑÕÐÙÏãÙÜÖÝÕÙÙàäáåÕØÔ×ßåàÜáêãÝßÖãÑäÌÞÜÎÞÑÜÝÒæäíãàÕæÜÓåÜãÝØéßÞ×äÞÝââÚÜ×ÐÕÝíÛÓàÒÛÕéáàÌÞÙÚ½¿¾¾Àº»½»½ÀüÂÀ¿¹¼¸Ä»À¼ºµ¾º¸½Á¹º³¼»½¿Ã¾Å¾º¾ÃÀ¾Â»¼¼¼·¾¸¾¿À¼¹Ã¾Ã¾¼Åº½¾»¿ÀÁ»ÅÆÊ¾ÅÿÄÃÃÈÂÅÁĽ¾ÂÅÂÈÆÉÆâÜåëèÜçÛßÞîãÝêäÒÕØéëòàÛãàåìæëçæÜÙéáèØéßÝØÞâßêÛàëìØÕÝåØÜìèäâäÚê×åâæáÛæàßÞÜÞì×ãÝãÙíïçòåããÝéèáØèààãâçèçßàÝæÜÙïçÞ×äîâÚÙãçÖàÜæÚâáçâçâéèÝÔàáàÞ×ïââÝÛÝèìàîÙãßÜçßæÞçèââÙçéçààÛäßêáãàëââéîåäÜäâåâØ×ìÚèìÛÞëçàãäáâÛÞÝèÖÛáççØÝߨäëÛÝçåÝäáàááÚçÜêÞÞÝßÝèàÞâäÙØìÙßÚêåßìÞá×âëæÚÞêæêå×ßÑèãâÛæãââàáãÛãïéàêÚßæâ×íÜÚÛëçÙÙêâßáØëèãÔéãèëÚèåÜéêæåßÛÝáååÞÛåÝéàÞÙäãÜåÝáëÙââÞßîæßìãéäèÙèèáÙêìñáâëáèÝêÙâáâÛáçãäåàäêôÞçâÞÞáìâÙåßñäçäàãäâÜååôÜëáìáßÖÞÙÞæëãÛßÓßàâåÜìÝÕáâáëâÞßåÞÜâØÞÛÚæéÝåêæÚÞâàà×ääîîåÕÝæçÝÖäÙëàîÞÒâÙàÞâîåÚÚíéååÜãßßäØáÑßÞâæìÛÞãÞÛäëëçæõÛôçäÜñÞâèìåîÕæÙàÚÝÛÞé×íëÚÞéÕäçîëéÞæâÜâããßÛåáÝÝãóéù‚þäîÜçêåÞìÝÜøÝîçåÔÝéâëÚ×åéñÇÞÚäìçæãØäëÛéìáààãàääîèÙÛßçÛèëî×áÚÚàåãçéèêÛçèÛëèÝâÙØæÚØäçÜèéàçæâííßáâàèêÙÞãÞÙäØàØÚâççâáàáâàÕñçáäÞÓèÝéêéÛÞèåêçãÝïíåßçÝããæÖìèïßåáßãÙáôéÞìÝ×äÙäáåæÖâßÞâðçßßçä×âéãÙ××ßæÜéÚÝÜáÞâáãèßÛáÙéèßÛèíìâàÜäàáÜáàÞÝèçäèâêâÜÛîá×ãéãêáèàßàòëéçÛàßëèÞÞÛÚÝîæåÔäßìëáàúäéáøëÜßãÜÞãÜèãáòïãâååèèÛóÝÝéäÚåÐÝßâêäêêßãòáéÝäâØáÛêæç×ëåÞàÛååÝæßÛè×ÞåçãàäáÙêàÚäèæÔâîÚÞääæìäßãÝåçìÝääåÚàÞáæëäâñäè×ÙáâãÙáÙæÛåàèßÔߨ‚ìßáÜÝàÞãàâßèèàçßéàÛâãêßææàèáØòÞâÞÞïäáÝçãðäóäèßäãÛêàèæíìÝçäÞææçèÛåàáâçèóîý‚‚b‚è‚¥‚7‚ðôíäïéïçÞìàãØÚçæáçâÜååÜáÜßãóÜääááÜòàéÞÞåãáçÞåØâïëäåëäÚèáÛâàáÛÞäêèãìãîÖäÜåäêÚäéÜãæèæíæäÛèÚØáéàÞäãôéèàåöÝÝèççâàèêêéçÛëÜçÄɾÂÉÍÃǼÅÈÐÅÄÐÃÆÄÉ¾ÇÆ¿ÌÂĽÅ˾ÂÀ¿ÂÆÉľÁÁÅÅÆÁ¾ÍÃÈÁÁËÅÀ½Ê¿È¿ÈÊÁÃÀýÅÅź¿Ç¿¼É¿ÂÂÁÇÂÄþȿſ¿Â¸¿ÅÆÅĿŽãÜåæóæÚØèñâàââéÕäßãààëùäàéèÞÝÚßÛíåéäóØÛçÞØØãÝ×ÜàèÚßâäÚãÖæØàïäéëÙáÖÛÚÏðààÝåíÖØßäáäãàÜ×ãêäèãç×ÜÞã×ÞÙÞçÜÜäÜäÚߨçßÝãáÑÚåÕçßâãÜÞìÝå×îâØÛÞäãßÛßåÕãÚâàãßèçäáöçöåï×â×ååßßááïÝÖÔãÝÚØáèØÝÙìàÔóÖçßÐÛãèãØØÞæÚÛÝãàçÙ×äÙÙåÞäà×íã×ÞÜÞßßÙÜÙàãàåãÞáçÕíÖßÚÜááàÛáÜáÕéßÚÛÖéÞÖãàßÛáèèåäÜÒØÕÙÛØÖÚåÚÒÙçâÝççáÚâÙæÖÐãæåÝçëÜÏæãÝØßÕèÚïåÞÑÛâäÔÞâÛÞÙÕÞÚÛ×áÞÕÝÝåØàíàáéÚéÝÕâÜèëÜäæâÙßèÙÛÚÜÕëÜÒÔßÒáØáÎÓÝÚäÛÛáØÔãßàÞíîÝìÜâÔ×Öë×ËÓÖÝÚÖäÔÝäßÝÛéâåëÝÛáêàÍÜÙßãæßÕàÖæÝêãäâåÚÛÖåßÞââà×ààÛáâßëæàáãÐÚßÒÖãæÛÞÛÕåÜè×çîèáçÝåßéàãåæßÙÒàãØÛÞàäÑÛÛÛÙäàÒßÛÞæÛàßßäáàçèÜäáçÔÜÙÚ×âåääÛíîßÒÓÖàÜÒçäÜÎÚáãàßÚèÛÜÞåãÔåâÝÞåßÝâÛãØâÙááæäáÝÙÛàÚÞÜáÏÞØßááÛèÜÜßÝáàßàÞìÜäåÝßéáóèæÕØåÓßÚÞÞàïáÐéÛåÜÜçÙáÞæÜÛßÝÞÖåçÔÙ×Öáãéáç×ÞÝëæßÛí׿çæãØëÞÞæÜäáèàâçÝàáß×íßÖÚ×ãßäçÜÛìÝÞ×éãÖåîäàâÜá×ÚÜá×ÖìרÜÒãØØÕâÚÙÞæäÞÛâàæÞèàçæÚßéÒÚØÚÞíàäÚãèÑÙÜçÚÞàäÞäåÜçäÝÛâÝèàâÞååèÞêàçÖëÙßÙåáêããê‚-‚)áÖÜéÚÕë×ßÚßÔãââÛëÛãÙÖߨÙàìÛèÛâìÚÓÕâÝóÕêÚâÝááÙãÜíàäãáÔÙäçæÙàçãÞââÛÝÚÚÝ×àé×ß×å××ÜèÙéâÜæØÕÞäàèÞåÖæÝÞæåâéÓÚÜäÛÛíçÜÜÕâàâ‚QÒØÖÜàÙÜìæáÝàÝá×âàÛäåÙÌ×ÔäØåæãØéáÛæáÔãâïçÜØãÛÕÞáÞàÛäÙêÞÛ×ßæâÜàÚßÞÔãÝÝáæÕØáÙæÞÜáãæââåÛäÜÞÓÞÚØÙÙãÒèãØäÛáÕÓúØÝÒâïäÖßÜããÝèÏàãâæÖÝÏßÛÜâÎÝáåÛÜâØÏåãéÞÖÖãØ×æàÙáéãßÞçßÔÜáÞÏäÝÜìáÜãØçãí×èãßÒèÏÔÞÞßÜâãÞÒäÙèááÓîÜÝÜ×áÝæã×ÚÖêìáàáÛßàÞÒããÓèÚïâæÛèÛßãßÛÏÜÛÜàÔÞêÛêÕëèàÚßâߨÙã×ÔàÞÚÛ¾¼ÄÀººÅÀ»½Ã¿½È¼Ã½Â´ÀÆ¿ÂÃÅÄÃÁ·ÃÂÊÈŹÀ¿Ê¿ÄÀý¾Â¿¼ÄÁ½É¿»ÂÀÂÁ»Ï¹¿ÂȺ½ÅÀ¾ÄĽÒÈÒÍÌÐÓËÐÑÐÓËÒÏÐÏÇ×ÑÉÎÎÎÒÍÎóòíâæïèóëöñïóóúóëâÿôíçëìðîçñóôæõóòãôîôÜèõçóôçíçïìóëï÷ãêêøëñîöäÝæëëòçìóíðâòñçììéñåéìôçùñèîìñëøóêîéóò÷õíøðíîíüïõúüñêíçéóêýãôéïéúùçòëïóççòòãíÿïðïùåíõå‚ðìäöíç‚÷øéèéòøèëëàììèìå÷êíéïüñïñìðæîðïëåîéëñéëêïÝïèðüíúõñäêôñéêïæï‚çòëðãìæòôêæíßææþðõçúêðñðùïïòæâùëïðííöã÷ïóàúëîôïìîòùëôôíêìêñóîðøßîïèìôñîíé‚òöñëóîäâïèïéêóëíûîïíïçêëïðóéöóïâúðìõæóôõîÜôåð‚îíõ‚êïîóéóçííïëïçûàñïåèòëìñòúðîõíðìîáòîöñïìñöêßçéæêßïâðñíðãéóçòúòîð÷âñùôïòóéôøëþÞïòìçóöéééø÷îïçòòÚðíßä‚ðçóôòë÷åéòñèüýõîëåéøöãæòñêèåïäèìäëìïåæëêóóíùë÷åå÷êíò÷îëóîàìëðîíéðè÷èéñøéçüõëóîöÛèôããåðìèìöïìôìðòòæå÷÷òèììéñöíõúéêôñêíöéóíìöìðóïçåúõéïôçóûþõìíõìðëñôîóõïêïøîàééûðíéãìùïïæòðòíîå÷íïúèþåçïæôàëíðïôíéôíññòòêëÝïîúçîíåóêäæåñçíôïôëæâ÷îñðêóî÷ûäãïíñåæóðæßìñâééó÷êììâûìïìúèñåïôñóé÷ôäíûÞêððòìôîòôßîõõòåêåíìáãôñöêôìðêçãÿðëä‚ôêêõéëäòõíñáúëàðõéõ÷ôüù÷óðäóôöäèí÷íàëñïíöÞáïêñöëïæïòöçíëéôîõúêïóõòíçòäý÷ùðïåñúýêéìðöðöôôòôëù‚ñçëíëéâññøßîïúïðòòéõúìýêçîãìôïóòúóüíùñôóöòÖõóõòûúæîòóëï÷èìéùýïïúçöæîíöïçúäûòòíæ÷éûì÷ìâóðñøêñóäðãóôòäïîöåíïãïìïîðòêéëïòúéîõîïëûòêùæôë÷ùêôéòìñïîùöøâìî‚ +SIMPLE = T / conforms to FITS standard BITPIX = 8 / array data type NAXIS = 0 / number of array dimensions EXTEND = T NEXTEND = 1 / number of array dimensions DATE = '2024-08-17T06:05:12.0' / written date (yyyy-mm-ddThh:mm:ss.s) FILENAME= 'CSST_MSC_MS_WIDE_20240817060512_20240817060742_10160100000_09_L0_V01'TELESCOP= 'CSST ' / telescope name INSTRUME= 'MSC ' / instrument name OBSID = '10160100066' / observation ID OBSTYPE = 'WIDE ' / observation type DATASET = 'csst-msc-c9-25sqdeg-v3' / dataset RADECSYS= 'ICRS ' / coordinate system of the object EQUINOX = 2000.0 FITSSWV = '2.1.0_20231208_wcl-5' / FITS creating software version COMMENT ========================================================================COMMENT OBJECT INFORMATION COMMENT ========================================================================OBJECT = '60000000' / object name TARGET = '161953.0+395345' / target name (hhmmss.s+ddmmss) RA_OBJ = 244.972773 / object RA (deg) DEC_OBJ = 39.895901 / object Dec (deg) COMMENT ========================================================================COMMENT TELESCOPE INFORMATION COMMENT ========================================================================REFFRAME= 'CSSTGSC-1.0' / guiding catalog version DATE-OBS= '2024-08-17T06:05:12.0' / observation date (yyyy-mm-ddThh:mm:ss.s) SATESWV = '0001 ' / satellite software version EXPSTART= 60539.25361 / exposure start time (MJD) CABSTART= 60539.25361 / first cabin time after exposure start (MJD) SUNANGL0= 50.0 / angle between the Sun and opt axis at CABSTART MOONANG0= 30.0 / angle between the Moon and opt axis at CABSTARTTEL_ALT0= 20.0 / angle between opt axis and Elimb at CABSTART POS_ANG0= 20.0 / angle between y axis and North Pole at CABSTARTPOSI0_X = -2218.3663 / orbital position in X at CABSTART (km) POSI0_Y = -5817.8559 / orbital position in Y at CABSTART (km) POSI0_Z = 2597.9467 / orbital position in Z at CABSTART (km) VELO0_X = 5.058199026407237 / orbital velocity in X at CABSTART (km/s) VELO0_Y = -3.85818799871231 / orbital velocity in Y at CABSTART (km/s) VELO0_Z = -4.322908628205369 / orbital velocity in Z at CABSTART (km/s) EULER0_1= 0.0 / Euler angle 1 at CABSTART (deg) EULER0_2= 0.0 / Euler angle 2 at CABSTART (deg) EULER0_3= 0.0 / Euler angle 3 at CABSTART (deg) RA_PNT0 = 244.972773 / pointing RA at CABSTART (deg) DEC_PNT0= 39.895901 / pointing Dec at CABSTART (deg) EXPEND = 60539.25535 / exposure end time (MJD) CABEND = 60539.25535 / first cabin time after exposure end (MJD) SUNANGL1= 50.0 / angle between the Sun and opt axis at CABEND MOONANG1= 30.0 / angle between the Moon and opt axis at CABEND TEL_ALT1= 20.0 / angle between opt axis and Elimb at CABEND POS_ANG1= 20.0 / angle between y axis and North Pole at CABEND POSI1_X = 0.0 / orbital position in X at CABEND (km) POSI1_Y = 0.0 / orbital position in Y at CABEND (km) POSI1_Z = 0.0 / orbital position in Z at CABEND (km) VELO1_X = 0.0 / orbital velocity in X at CABEND (km/s) VELO1_Y = 0.0 / orbital velocity in Y at CABEND (km/s) VELO1_Z = 0.0 / orbital velocity in Z at CABEND (km/s) EULER1_1= 0.0 / Euler angle 1 at CABEND (deg) EULER1_2= 0.0 / Euler angle 2 at CABEND (deg) EULER1_3= 0.0 / Euler angle 3 at CABEND (deg) RA_PNT1 = 244.972773 / pointing RA at CABEND (deg) DEC_PNT1= 39.895901 / pointing Dec at CABEND (deg) EPOCH = 2024.6 / equinox of pointing RA and Dec EXPTIME = 150.0 / exposure time (s) COMMENT ========================================================================COMMENT VERIFICATION INFORMATION COMMENT ========================================================================CHECKSUM= 'EhhmGhhkEhhkEhhk' / HDU checksum updated 2025-05-15T14:39:50 DATASUM = '0 ' / data unit checksum updated 2025-05-15T14:39:50 END XTENSION= 'IMAGE ' / image extension BITPIX = 16 / array data type NAXIS = 2 / number of array dimensions NAXIS1 = 20000 NAXIS2 = 4700 PCOUNT = 0 / number of parameters GCOUNT = 1 / number of groups BSCALE = 1 BZERO = 32768 EXTNAME = 'IMAGE ' / extension name EXTVER = 1 / extension version number BUNIT = 'ADU ' / physical unit of array values COMMENT ========================================================================COMMENT DETECTOR INFORMATION COMMENT ========================================================================CAMERA = 'MS' / camera of main survey DETSN = '12345678' / detector serial number DETNAME = 'CCD' / detector type DETTEMP1= 173.0 / detector temperature at EXPSTART (K) DETTEMP2= 173.0 / detector temperature at EXPEND (K) DETTEMP3= 173.0 / detector temperature at READT1 (K) DETSIZE = '9560x9264' / detector size DATASECT= '9216x9232' / data section PIXSCAL1= 0.074 / pixel scale for axis 1 (arcsec/pixel) PIXSCAL2= 0.074 / pixel scale for axis 2 (arcsec/pixel) PIXSIZE1= 10 / pixel size for axis 1 (micron) PIXSIZE2= 10 / pixel size for axis 2 (micron) DETECTOR= '09 ' / detector ID DETLABEL= 'r-1 ' / detector label FILTER = 'r ' / filter name NCHANNEL= 16 / number of readout channels PSCAN1 = 27 / horizontal prescan width, per readout channel PSCAN2 = 8 / vertical prescan width, per readout channel OSCAN1 = 16 / horizontal overscan width, per readout channel OSCAN2 = 16 / vertical overscan width, per readout channel COMMENT ========================================================================COMMENT WORLD COORDINATE SYSTEM INFORMATION COMMENT ========================================================================WCSAXES = 2 / number of WCS axes CRPIX1 = 4600.694649742984 / x-coordinate of reference pixel CRPIX2 = 4604.383757040574 / y-coordinate of reference pixel CRVAL1 = 244.5872723135913 / value of reference pixel on axis 1 CRVAL2 = 39.68195466168969 / value of reference pixel on axis 2 CTYPE1 = 'RA---TAN' / type of RA WCS projection CTYPE2 = 'DEC--TAN' / type of Dec WCS projection CD1_1 = -6.8096767434962E-06 / transformation matrix element (deg/pix) CD1_2 = -1.9394088718019E-05 / transformation matrix element (deg/pix) CD2_1 = -1.9394079613547E-05 / transformation matrix element (deg/pix) CD2_2 = 6.81009530128767E-06 / transformation matrix element (deg/pix) COMMENT ========================================================================COMMENT READOUT INFORMATION COMMENT ========================================================================GAINLVL = '01' / gain level GAIN01 = 1.089977689498424 / gain (e-/ADU, channel 01) GAIN02 = 1.099175619835018 / gain (e-/ADU, channel 02) GAIN03 = 1.107649165474623 / gain (e-/ADU, channel 03) GAIN04 = 1.121722214644728 / gain (e-/ADU, channel 04) GAIN05 = 1.081220797968546 / gain (e-/ADU, channel 05) GAIN06 = 1.09456272850753 / gain (e-/ADU, channel 06) GAIN07 = 1.111430472148367 / gain (e-/ADU, channel 07) GAIN08 = 1.105606424366627 / gain (e-/ADU, channel 08) GAIN09 = 1.101874970320761 / gain (e-/ADU, channel 09) GAIN10 = 1.085064046871988 / gain (e-/ADU, channel 10) GAIN11 = 1.12218772525153 / gain (e-/ADU, channel 11) GAIN12 = 1.114934178226512 / gain (e-/ADU, channel 12) GAIN13 = 1.119336504852553 / gain (e-/ADU, channel 13) GAIN14 = 1.093036190194986 / gain (e-/ADU, channel 14) GAIN15 = 1.084334798104931 / gain (e-/ADU, channel 15) GAIN16 = 1.090894538052644 / gain (e-/ADU, channel 16) RON01 = 5.0 / readout noise (e-, channel 01) RON02 = 5.0 / readout noise (e-, channel 02) RON03 = 5.0 / readout noise (e-, channel 03) RON04 = 5.0 / readout noise (e-, channel 04) RON05 = 5.0 / readout noise (e-, channel 05) RON06 = 5.0 / readout noise (e-, channel 06) RON07 = 5.0 / readout noise (e-, channel 07) RON08 = 5.0 / readout noise (e-, channel 08) RON09 = 5.0 / readout noise (e-, channel 09) RON10 = 5.0 / readout noise (e-, channel 10) RON11 = 5.0 / readout noise (e-, channel 11) RON12 = 5.0 / readout noise (e-, channel 12) RON13 = 5.0 / readout noise (e-, channel 13) RON14 = 5.0 / readout noise (e-, channel 14) RON15 = 5.0 / readout noise (e-, channel 15) RON16 = 5.0 / readout noise (e-, channel 16) ROTIME0 = '2024-08-17T06:07:42.1' / readout start time (UTC) ROTIME1 = '2024-08-17T06:08:22.1' / readout end time (UTC) ROSPEED = 10.0 / readout speed (MHz) EXPTIME = 150.0 / exposure time (s) DARKTIME= 152.0 / dark current time (s) COMMENT ========================================================================COMMENT SHUTTER INFORMATION COMMENT ========================================================================SHTSTAT = T / shutter status, T=open, F=close SHTOPEN0= '2024-08-17T06:07:42.1' / shutter open time (start, UTC) SHTOPEN1= '2024-08-17T06:07:42.1' / shutter open time (end, UTC) SHTCLOS0= '2024-08-17T06:07:42.1' / shutter close time (start, UTC) SHTCLOS1= '2024-08-17T06:07:42.1' / shutter close time (end, UTC) COMMENT ========================================================================COMMENT LED INFORMATION COMMENT ========================================================================LEDFLAG = 'main ' / main/backup LED LEDSTAT = '00000000000000' / LED status LEDT01 = 0.0 / LED01 flash time (ms) LEDT02 = 0.0 / LED02 flash time (ms) LEDT03 = 0.0 / LED03 flash time (ms) LEDT04 = 0.0 / LED04 flash time (ms) LEDT05 = 0.0 / LED05 flash time (ms) LEDT06 = 0.0 / LED06 flash time (ms) LEDT07 = 0.0 / LED07 flash time (ms) LEDT08 = 0.0 / LED08 flash time (ms) LEDT09 = 0.0 / LED09 flash time (ms) LEDT10 = 0.0 / LED10 flash time (ms) LEDT11 = 0.0 / LED11 flash time (ms) LEDT12 = 0.0 / LED12 flash time (ms) LEDT13 = 0.0 / LED13 flash time (ms) LEDT14 = 0.0 / LED14 flash time (ms) LEDTEMP = 173.0 / LED temperature (K) COMMENT ========================================================================COMMENT VERIFICATION INFORMATION COMMENT ========================================================================CHECKSUM= 'o7Tkp5Rio5Rio5Ri' / HDU checksum updated 2025-05-15T14:39:52 DATASUM = '3747953988' / data unit checksum updated 2025-05-15T14:39:52 END ÅÄÅÍÍÁ¾È»ÅÇȾÃÁ¼ÃÇÈÃÇÌÁÃÂËÊÚÓÙéæêàéèæÞáÝêæáåå×ìÞäôÓæåâëÛàßÝäèÛîíàßáÝïâÓæ×äãßãæâæêàØÜêâêäéäâãëåééÜêãááßáÙáçÚãàëéÛãÛæêÞÚÓáéðíçëèêÝæçîÜòèççáèâáçîèàåßÚæäàëàÚâÜÞÛãèãßååÚêæíåÞ×ãæíäêçñèæÝãíæïìæåçâ×ÝæÛÕáâÜÒâëâàÕäâÚìîððíääííãçéàâêéßáðöäÜèàêéÞÝçäÙäæÞéáÞãÞàäÛé×âäÜäáØÝèâàÚãÞãîëâçèâäâîàòëßéÙêàèíæàåÞÙãââïåèæÚßçéÖæêÔÝçéçëêæßÕéäàÓäâãæëéæâ×ÖåæèäÝßéæãÐàáçßëÝëÝÚÞÞäæåÕíàÒÖààìéíäêôìðô‚ óìðôïåÑÝéß÷àÛÞÙßëçðïèëñàãÝèêîêÜãåçäáÕáëêÞçòâææêÜîòëØèåèáäáíäïåèäìèßàãßßåÚâñææìæèëääñõêêàÞóðÓÚéÙàÒÞéíæÞíãæââÜáèÝàÓèñáÔÙáàáççáÛáéããæáÜÜáçï×áãìâäàåæîëäÜéäÖÝáâÙáðéØêäèÜâãìííìÛÝÜïâßêæáçèêéäãâÖôáðééíñòîëñêìéñìéæááåÛîäåâßÞÝêàÝâåææÒÞèÛíÛÜèñæéßáßÜêØÜãêããææðéíÙæçâÚâßíðäàí×îÞäðØààÝçæßÞéããÕæâæÚáåÙéääæáÝØàßéåçâéÚÝéîÔæéìââÛÞèááÔâèØæçÙäêáçàâãæÚØâàåÞÚãÙâèå×àßâÝéàÛâÛéäàëàÝãàéâçßÚÛèäæÜçØõÚÞåæÓäçÙëäÝàààææßÝìêäïåâÙæ×ãáåèðßéâêãçæÙèçÞÜ×ÚÝðÜãàÞåâçÐíØÞèãÛçãÛçÕØæÕåðäîïââãæÜÜÞâãâåâÝðìÚßçèÛØÚêõêæëîÕëëÞââ÷ä䨂xåïÛÛåÚêìÙâáàâÞàëÚéîåáâÜôØìØÚÚåÝàÞëÚÕòåãëÚäôàßÝãäåéÝàáæêëâÞèÞâÛéàêâÝèæßâáßååäâòòáéäáéçáâàãØëÒëáèåßëèÞìéåæÔÞåäííçÞèæëâïáÛÞáèáì÷ãÝäààßèñíðã×çÞòèÝëæÞéßçÚߨßãÜÞãàÜàèêêìîèÝ×ðßèåÛãéçêæãÕîÝÛàÞèñÙáäééåäßêîíâØåéâÜÞìåãåéïÞáàñÓçïÏîØáëñçÞçåØçÝÚîãÓæáâçåèÛÝèÛÛÚíàÛäçÙêææåéäâèßçæÞØòèÚáîéïâæåäâéëßåÝæâããáëìåàáÞÚåéàÙóàãßéâæ×éãæßêçáàåæãâá×çéååØÃÂÂÅÁÄÇÄÃÅÌÁ½ÃÁÆËÆÄÊÇÅÄŽÁÅÞÅÇÉÆÉÌÁÈÆÉ½ÂÉÅÆÁÈÅÐÂÁÀËÄÈÂÄÈÄÂÊÆÈÅü¿ÅÆÂÈÄÉÇÉÁÍÁÐÍÇÇÍÊÄÊÇÅÊÉÑÉÊÐÌÄËÐàèèëãðààêèßñêðøâîõïÞæÚêñéëæìãêæïêûéüÞòïèñâÝûääñáïÕßæíîàçëíßìßêîñæëìßéæÞâìèçôîÞÜåÞéëîäíæîéíìíÝàãçÛÜëçèäèÞåæåãçàìèáåßëãçäëßå‚éèäæõèæûÙéäïáãëìßíÛèóôèêñèìæäâìëêÝèíêëàééïëéðîïàñèææâåãîä×éÔÚäêßãìïîãâàéèêêëçêéï‚‚‚ ‚ðæççãäêäéìèÞéðïäîãìîòäÛäéäæèýäàðêóëëíñáîæêÜäëãééæãêêÝÞæåãëðãÜìîàìðíçóóÖßãåìîíìïïáàççëìáóüæåàèïóÞÞêìêéÛêùæìêäïñöößçäáìììëëçéæáéâåÞåææçóéôìîçôçåàêìùæåìàØîâîèéõðìíëêãèïäùëèêìççßõåõêÞÞëêôíäáêæåëêêéêåëåæóåëåèéðççáÕçøëçßÚêéêïäÜßéõèÝæãêêãéæèæäëàãÝæãïíçàëáîåááñöõÞÞëàßßóÜçëéÞêîêæ÷ðèñáðîáøÝêäêçÙìäæâæáÜãêâæîãßçåÝòíñìñÝæÞèíàéÞâîéçéäÛêìèäïãæìîæîçÞìûèéííæàäêêæÜåââØêãìÝáã×ìèééßïçèäçãêâçíñÞìîíàçÝäáïêåèêçëÞíÔäéøæáðâäëêçàáäëàõõéãêìçæáçíçòâãâÜæëääñèíêæóÜåëåßæøãðèéäêæììæäåêñèå×ßÜòçèñéßïø÷ÜõïäèäîèæïßçâèîáÖäÞÜæìòâñåõÝéëåéëáÙããíçéìÞçåäîæíçéñâàîåæçÞðååÞçäåìêæçíèåçòøäíÝê×íì׿êÜçåëîÝîêÛéÛäèáñãåßéäìëêêåûççÛñ×ëéïæçîßßæöæîàåÜéôì‚‚$‚ôêîåÞáçâçÞàññãéãÝëâèêéøñãíéåçíåøæßäõæãæÞØëìßõáåäïëçîâßÞéÙáôæíñõåêèç×êéïãíÞíüîäòêäñÜÝõòëãäòñôáçìäàêäêåÜéèÚßòäâêñØáëßîëôúçðáíïðÚå÷‚cãÝêìäïáçèåçöóáêâëëìæîêÚðïåðåäåâëçñéåãäþâåæûîòèðäëãîáóíèæ÷ìæáîêäíáèßçïìÛëàâëêíãåëãææéÓäëìæîóëååãîáôðçãéîîèëããåöçæåæçñéíÙäÝçèäèêîáççòÞïäââëëü÷ÞæéåéèéâèãíéëáàÝèÜÛàáäíðçðîìöçåâåëëÞáçâóñðââÞæáãåçìÚïèëäëðåçêãèáôôÅѸÌÄÆÌÇÌÅÁÑÁËÒÍËÈËÉÈÏÈÄÈÑÂÉÉÎÌÂÔÊÊÊÌÊÈÈÄÅÈÁÏÁÊÈÅÉÂËÍÆÌÇËÆÆÇÆÉÊÏÆËÐÄËÊü¼¶½À¾¿µ¾½·¶½º½¸¸¿ºÀµ¾À¾¸Á»×ÙÕÓÚÉ×ÏÏÑÜàØÞÎÐÕÔÕÜÚÝÑßËØÜÛÞØÞÓßÓßßÕàÖÝÓÞÚÓÔÔÐÒÓéÒÜØÕÚÏØÖ×ÍÕãÐ×Ï×ÑÙÞÛÒÚ×ÕÜÏÕÐÔÜ×ÍÖÔÖßéÑÛÒÒÕÏÕÔÕÌËßÚÊÒßáÏÚÑÝáÝÙÓÌÝßàÜÞÛÖÝÝßÒØÖÖÚÑÜÛÖËãÏÍÔÔÚÏ×ÚÐéØÌæéÞÔÔÙߨ×רØÐÒ×Ý×ÖÝËâÐÑÑÔÚÖÔÛÊØÐ×áæäßßÚÎÙáÝáÞÑÙáÖÙÕÒÙØÚÔÙèÞÏÜÛÖÚåÞØÔäáÛÛÖâÏÖÖÞß×àÔÐäÞÚ×à×ÖàØÙáÜØàÕØÝÒÞÕÞØÜÙÐáÑÜáÑ×ßÖØÑÚäàÜÖÕÖÞÝÓÝÔàÆâÔÓÏÞÌÐÛ×ÕÛØÙØÙ×ÙÈËÏ×ÚÝÖÜÙ×ÐÔÖÞßÔâÝÑÎÔáäÛÛÜÙÓáÎàæÍÏãÚÜàÔÔâáÖÖØçÖÊÏÓÝÞÖàÑÝÔÓÏÔÔÐÚÓÔßÖÙÙÓàÕÝØÒÔßÍÑÝÒ×ÙØÛØÍÕÞÜÝÒâÝÔÔãàáØÕÛÏÌâÞÔÏÚÎÛÚÏ×ÖßåÛÉßäÜÇÝáÏçØÕàÕÙÑÔÙßãÑÕÜÞÔ×àÛàëÕÜØåäÔÙרÛßßÖÔ×ãÚÛÝßâÐæÙâÊÔÓáÜÞ×ÑÛÓÙÑÙØÒÕÝÙËÖÝêÝÖïÚàÒÒÞÔÕÙÙÝäÐÙÔ×çÔÔÖåÒØáÑÙßÖÑÖÖÔáãØÓÕÔÕÙÓØÙç×ÌÛìÖâßÞÚÜÏÛÛçÐÕÛÊÓÓ×ÕØÛÒÙØ×Ü×ÔÛÝÛÑÓËÞáÎáØÙÛÖÍãÚ×ÚÞÕÈÚÕÞäÕÜáàÚÔäàÔÜÜÎÛÔÏØÍÕßßáÚÕÏÕÌâÈÚÚàÙáÓÃÖÙ×ÔâÞÓߨÖàÓÒàáÜÕÛÜËÐÏÕÓ×ßÊÕåØÑ׿àÚÔÖØáÚØÞÑßÛÞÍÍÎÔãßÔßé×ÕÙÎÉÝØßââÒØÚÖã×ÔàÒ×ÌË×ÚÜÐÏÑÄÓÆÜÛÝÑßÙÚãÚÕÙÚáÑÝçâÖÝÜÙçÌìÓÛÏÚÑÕÔÞÏÖÝÔËÖÐÔÛÕÔÊÍÓØÑÔàåÛÛÖâÔÕÞÞÐÐÏÜØ×ÕÓ×ÚÞÔÚãØÐåÜÛÞâÔÞ×ÞØØÕ×ÕÝåÔÔÜÖÙæÞÞÐßÓÙÚÙÊÜÕÛÎÚÚÞÏÙÎÛÝÚàÏ×Ù×ÝÖÞàÞ×ÛÚØÞÚäÐÛØÚÚÛàâÑäÚÛ×áØÒÕÞÖÏÚÕÍ×ÓÄÛÏÓÜçàÛÓÝÕÛìÔÓÔÜÎÞ×ÚÔßËáäÏéßâÝÒËæâÞÚâÙÜãÑ×Ô×ËÕÓØÎÖÑרÛÎÏÓÛÓÚÝäãÓÙÝØÓÖÌ×ÓÍÚìàÖÛÙèåÏÜÖØÌÚÚÚÝÚØÑÌ×ÕÜ×ÜÝßËÞàÔÓÞÚÔߨ×ÝÖÛØà×ãÞÛÛàÉ×ãÜÚÜ×ÕéâÞÛÞ×ÛàßÞèÝÝàÓ×à×ÝÜÙèòÖö‚÷î÷âØÙÛØÓÚÙ×ÙÊÊàÞãÊÜÄÎäØÓÙÌÖßÓÞÔÒàÏÜÍÝÛÞÖáßáØÞÕÚÔÓÜåÛâ×ÔØÒÝÙÞÖÔ×äÛËߨܨÞíàÊÜÙÔÞ×ÕÙÝÒÛÙÓÙÝÜÚéÏÈÝÓÒÙÔÖÕÎÛ×ÕÙÎÖãÝæþ‚÷áíäÝÕĶľ¾Ã´»Ã¸¾¶º¼·¼À¿¹¸¹Ä¾»¿ÃÀ·»À¸³ºµ¹¾Âºµ±¶¶Ã»¹¶¹¹´¶·¶Å··¾¶½¿ÆÃÀÁ¸¹»º½¶¹´º¸®±¸·´·¹±¶¹»ºµ±º´·¸¶Âº¸°³¹½ÌÐÊÊÔÕÒÍÖÌÙØÔÑÊÓÚÔÔÎËËÙÓÐÖÒÓÕÛÞÒæÙØêÏÜËÖ××ÚÑÒÎÍÓÏÒÊÚÜÛËÖÏÓÕÐÒÓÍÌãÑÒÌÓßÒÞÚÏÓÑÐáÆÖÎÜÌØÔÐÍÒÚ×ÔÖÔáÍÓÚÚÏ×ÝÒÎÙÑØÏÐÛÑâÓÒÉÍÑÔÙ×ßÝÏÓÊÜæÖÞÏÓÜØÔÛÛÕÝÒÜÑÔÛÙÖÖÎÙÙ×ÚÒÑÓæ×ÔÖÐÔÌÛÝÞÎÜÈÙÚÓÍÖßÖÕØÕÖÞËÓÓÒÔ×ÓÛÚÓÊÑÍÉÉÔßãÊÝâÖàØÛÖÜÔßÔßÖÔÔ×ÉÖÙÔÌÜÐÏÔßÝ×ÕÑÕÖÕÔÏÔØÑÖÏÓÒÖÖÊÐÅÕÐÒ×ÔÒÕçÝßÑÜÚàÏÊÔÌÜÇÉÎÎÓÙÝÏÕÒØ××ÏÚÜÏÚרÑÏÒÙËÐÓÓÒâÝÎâÔÄØÒÔÚÑËÕÏÐÚÍÖÛÚáØØÔÓÍ×ÏÏËØÆÐÔÛÒÕÖÌÓÚÊÐÏÎÓרËÞÕÜÔÍÙàÛß××ÍÕÏÅÍÒÏÙáØÔÕâÙÌÜÓÓÕáÒÐÕßÐÒØÎ×ÒÒ×ÚÚèÌÜÞÞ×ÕÊÑÒØÛÏÜÁÕØßÎØÉÙÔãÓÝÑÌ×ÔËËË×ÏÔÕÏÆÝÄÓÏØÌ×Õâ×ÙÔÎÔÜÍåáÜÜÎ×ÖßÖÙÊÏÎÐÒØ×ØÕÙÝÖÕÐ×ÌÓÖÎßÐÖÕÔËÙÛÝÝÝÅÌÎÊÖÖÚÖÛÉÛÝËÙÔäÐÐÓäÐÚÒÖ×ÔØÉ×éÖØØÉÓË×ÔÝ×ãÙßÖèÐÙÑÓÖÕÔÚ××ÖÞäÉÎÒØÑÌ×ÎרÐÏÏÜÕÙÒÛÕÙÕÌáÕØÐÏÒÛÝÙÖâÚÕÍÓÉÓ××ÍÔØÖÑÛÒÏÎÞÖãÙÞàÛÑÒÐÌÚÍÚÓÓëØÕÝäÍÎÌØÓÖÚÜÎàÖÑÙÐÎ×ÓÚÔÎßâÉÇØÑÝÜØÏÑÍ×ÏÙÌÑÎÎÓÝßÚÛà×ÑÏÓÏÕÔÊÝÖÌÕ×ÚÒÕÞÓÓÐר×ÔÞÒÖÞÐÖÕÌÔÛÒÏ×ÕâÜÒÞØÛÛÑÒÓÑØÜÔÜÝ×ÏÔÉàÖÔãÍàÔÜÔÏÎÛÕßÐÚÔàØ×ÏרÓÕáØËâÀÕØéÌÓáßרÐ×ÙÐÑÔÖÒÍÖÏèÕÙØÑÎÓÌØÏÑÏÕÑÝ×ÝÚÖâÜÓÜÓáÐÞÖÎÓÕãÛÛÑ××ÌÖÖÒØÓÎÑÝÓÑÓÖØÖÌÐ×ÓÔÝÕÕÙÛÙÑÛÌÒÍØÏÝÊØÝÛÌØÖÖÛÜâÕØÄØÒÜÚàÕËÓÓÏÖÕÚÙÓÓÑÝÖØèÜáÞÙÕØÈÌØÍ×ÛÊßÔÐÖÚÍÖÕáßÍÛÏÙÛÞÔÎÇÔ×ÎÑÑÅÖÒÔÚÞÔÙÑä×ÔØËÒÕÓÝÐÎÐãÚÔ×ÖÐÖÓàØØÐÐÕ×ÛÚÐÓÏáÖÜÖÛÒØäÛÒÞÛÎâÕâÎÖËËÍæÖØÇÔÍÕÙÐÎÒÐÐÔÔßÖÕÓ×ÍÜ×ÒÓÛÓÜÖÔÒÏÉÝÜÅÛ×ÚÓËßËØÓÒÍÑÙÓÖÉÑÚàÚÙÐÕÔÔ×ÔÎ×ÌÏ×Ì×ÑÊØÚÖÕÝÑÒÛÏÙÙÑ××àÚØÙÐÈßÕÙçð‚ ìÐÐßÌØÒÛÓÕÎÖ×ÏÐ×ÔÕÎÒÜÉÖÒÖâÙ×ßÔÖÖ×ÚÖ×ÉØÔÙÑÔãÓÇÜÓÙÔÙàÜÚÚÛÍÔÞÛØÑÖÐÐØÕ×ÜÜÕÚÉÏÓÖÛÚÓÊÝÌÙÒÔÑÖµ²¹®º²µ²µÀ¸´º¿²µ´»¶¸¼³´·º·´¹º·¹Á·¹º¸¿±²µ±µ°¹»­Ã´¸¹º¸¾¼ºµµ®µ¼º¹µº´¿ºµµ¼ºÉÔÏÂÎÐËÎÎÆÊÈÌÉÈËÒÍÐÇÐÑÆÍÎÊÍàìåèãëêèêîàæàæèåíéöñìêéâïññÞõáïæíêìëåóøáç÷éñõáçììèéòüçëçëñíìíúåèêäßñåäìáëÜóèÜðíâáóíòçåáñáçãìíçãïÛÙåÜëãìéíßóââñöâßÜîìéñâçèìëõõåáåáõÝñíèßëçíããéâðîõéñðøôÝïïíêêæ÷éæíé÷êàèáñéçéâèôëæäçëàæêôæóèïíêêàóñëôòåâîóçùù÷Õðçðî÷êéòïàëêëëõçôæìäïàâòãñæääùéëðéæçîçåðéñèäëêììææòíòßÝðÝêõÛÛêèêïßäðìæÝãñêòðáäùêõíêçíôçõîÞêåèíçêóïíëáêåîúîîëôàäåçéçìãëêççêèïíéçíãããïæëóìåõõõàßæèíÜåàéòðìäîèøöëäêêñíùíìâðïðæìôêßãòäðëãïîôãâêîàêóùÙìéêúßìøæòèòðñãîáîÜäâðéäâéîëäãíéæìÜåèéùÝòÝéìàîèåíãã÷ãäññäáùåæõßíèëðééÝòêèÙèý÷áñçíäéæçðåÝæàøæðéàáåóçóñÞáæåçüíôïõãîîõíäôçèîãããáêáñãóéëçìîäïåãæìéææáèëóêãóãæêéßåèÛèßêãðäêâÞìîæñæöçôìñîñÞïïíêíìïâðìæàèëìòðóåèåñîïêåêéèéíæçíåèÞéëéëííøÞèþìîûøðçéèßãëãêëÚëèëèôåëóìñîíãïýóïàçéñéééãêäûäèâúäíïèÙßíççèêëãîëíèéÛäòãåèçåïíïèíèöåâíííãêìïëíêñ÷àçîãêðéÜðæçíãæãéîÜÞãäÛãáàêîìãëÝëÝææôëûæïîããßàñìïçòèëñëåõßéññèôëÜæÜåêñãçÞäóïîòÝêêõØéðó×ïèêèìçåðèíïäïçîèáäêßõêòæáõÖæãåéåóàåëêâÝïòõïééìêîïêáçâàñîåëéêèâÖðèÙéïïâå÷äïæâñëèäêóéãæææççñíããéâåèèßëìæìíæÝíðâêîðëðîùïåíÙöòáäâãæäâñâàéóïÞéïêáïïåèåáçééîæåëëè÷ääõäåçãïìáõéóäçéãåìäêéçíøõëíááææâÝáàÞïãçôãïîíïóìèáéòñáèæàëèîìøáùéòçñêêÜØéìñçøìïáöêáîùòãêúüîèæáðáøëëâóçõíòèìãçîîèéëéßæÚòèîëæáèßàéåêäæíééñòéîóîåäçêæððæòææìÞíôÜóæáíåééçíóöõðëøêèòúåàóìæêïßìòòôñëîËÅÈÍËÊÀÒÄÃÍÅÏÏËÊÔÌÉÊÏÎËÉÆÆÍÌÒÍÊÇÓÕÈÏÃÌÒÏÓËÆÊÏÆÌ¿ÌÄÇÆÒËÌÆÏÍÈÊËÏÆÂÌÃÉÂÈÑÉÏÈÍÍÈËÎÏÌÑÌÛÔÏÏÈÐÓÑÎÑÊÊÇÌÊÐðëóëã÷äûçíéõåíéíìñçÙàèò÷éîêëöñÞõñõóôëäïæîîéñëôëíúóñôåëèäíèæëùëìßóòèèòíõôèîçåâêòðëòöøêþâúë÷êñÝðçõãîíïîþéô‚òæäèãêçïêñõóãñÞñååîòæõñöðôïúíþèæïæíéíêéðéðäéøòãäìòåêæéëïðíéûì‚ó‚sðåìôäëññäñíîíñæö÷òòåàòëëôîòèöíäÝáòìõ÷èðîïííèêíêãóñóìøîñîôõäçöðììéûúñëñéïððìóùñýâûöëðäóòïöóããßîåæòéðíïñöæïêòëåèíëòóêèìðîèéúöâïåôïåèôñèöðëçñæíìòäåèêõêòå÷çíýèðòòçíè÷öóåóåöáîñëöçðóéíóôçïêìóõîîôäìòðïôéôíìïîïèïðíèâìæñãìêéëéííåìõûâóìñìïìõðôóíîöáæ÷óúóßäóûçîîûäÞíèöìèéíëñêìíìèëâäìõèíïñêêèâïåêãññ‚èßòùëâçíìôèîùóîðèøúïæéöíñîêïôçêëèîìæçáãóêðïçäîìóõ÷ïïïïñõïóëñìòèðíùóúóæöóçîãæðêùçúîøâüéíæôñïæ÷ëëêø÷èëñöðáìùúåëôöçóäëõóíéëéøèôæøìéþåüëæîîêìçîñäëåðíæñðýíïäãñîéêîäñìöèøïîôð÷æïøôçÿñôõëîîóúêéñíóíöñóîúèóñâéóíéíâææöîðíèóøãÿçèõðëñðæîâéëéèíïæóéïéäöéóäåîóñúòîéêðîììëòæßèääöáíííðâêéïæç÷óûäé÷øâòæñïí÷ïòßùëóâæéñóý÷ùñêæüñíéîøñéïöçùêìïìïéôñíäìçðéóóñóøéçê÷õåêüéêêïììæìæêëíúóæòîçðéðóôêòîòæîèôáïåõê‚ìúìçæ÷êäî÷óíî‚ñëãôôóò÷îàíôéèúäæáëêóãôêíéëèåñèøíäöòêóíëëåòôíòëðøõîééçèçâëçÞéîãêíòéôçìóæíîùàìðëñîìæîïïêïèëêï÷óûìòíñíðóðïÞóåøÝ‚íûçðêãîïâôçõñðëóçæíòòéïûêåëûëóîíîìïòßíõñïèïëêííèñæêêèçòîíñìñèòøéáóåéøçõéäêòåìéäñð‚êâæ÷èîïöõëäéêóæèéîðøæþîæìëìöãðôçèâæðñàëøðæñîðõñî÷íõèîèïíúâòëîÓòëîõæïìóë÷óóáëíèâæóòîîåîøôóæõïÚèéçèééäïæøèëñïóçóÒÎÖÆÊÔÏÎÓÅÍÇÏÈÑÐÔÒÐÔÓÕÏÌÍËÉÈÔÏÒÑËÖÒÕÈÑÍËÓÐÊÓÒÓÌËÎÐÚÑËÖÖÒÏÓÒÕÒÎÔÕÔÉÍÎ×ÊѶ»²¼¯¹·À½½´²·´½·¸µ·¸¹ºµº¸¹³àÙáÝ×ßßÜÞÞØßÖÝÌÝÜÐÖÒÖ×ÍÑÙáäÙÞÕ×ÈØßÕãÕÓÍÐÞ×ÜÝÔÍÐÐÜâÛÌßàÛÌáÕßÙØÌÓãæÕàÜÓáÛÑÇáÛÕÕÈÒÌÒÙÕÊÚØÔÕÝÙÞÝâáÝÚÞÆÜÚÙÓßÚÙÑäÕÜÍÒÝÙÚÓÔßÒÞÜÔâÚàÕÜרâÖäÔÙËÝÙÔÕÏÑÝßÙÜÏ×ÔÕÙÚÎÚÐÌÓàÜÜÞÝØà×ÜËÔÝÔÙ×ÓÑÖÚÖßÚÖÕâØÜÍÛÒÛÖÛÖÚÞÖÛÊÝÕÕáÜÓÙÕÔÓÞÓÙÖÙæàÍåÅàÛ×ßÌãÛÐ×ÕçæÖÐ×ÙËÛÓÚÕÞÒÙÙÖåáÞÓåãßÙØØÐÒÞÕÛáãÕÕÝâØÚÜÛÜÖÙ×ÙÕÒ×ÝÝÙÜÚàåÍÜÖÞÍÜÔÖÔÔÓÞÒÛáÖ×âÙÚçÛØ××àÙÛÎÖáÔ×àÑÌÓÓæÌÜÏÝØÔÍáØáÔØÙÐÔÙÝáÒÜÙâÞÐÖÝêÕÛ×ÕÞÝÚÚØÛáÙÞÒáÔÏØÚæÝ×ðÒÒÐÛÜÞÏÚÝçÔ×ÐÜØÐÖÑÛêÒÝÓÝÒßã×ÔØØÞØÜ×ÚÑÇÞÑÙØÍæåÝÐÓÛØØÖÞÜØÓáÕÖÛÉÍáÖØàêäÕÖçâÙÝÑÚÞØèÞäÛÒÛÍØÔÜàâÕÜæÚÑáÜàäÑÜ×ÙÚÞÛàÙÕÚÖàÛÕ×ÚÙÔÕÖÝÏÜÏÒèÖßÞÕÐÔçâáëÕÖÕÑãÊÖÓ×ÊÏÍÏÚØÕÍÑãÛÝÛÚÝâÖÐÛÑÓÊÓÔÌÔæÛÞ×ÔÐÛà×ÏÝÙÕÖ×áÔÞÖÍ×ÔÛââÓÛÝÔÜáâØÝÏßÕØÒÐÈßèÌÎÛÖÍ×áÝÙÚâÈàÒÝÐÖÐÚ×ÑÐáÝÔ×ÓÔÎÜÍâ׿ÕÔÛËÛÐÙËßÎÙáÜÞÙÚÞ×ßÜÎÚØëÜáÒ×ÜÒßÛÚÓÚÛÒß×ß×ÐÐ×äÙäÎØÖÚÙâÞØÞÙÚØÑÔÎÔãÏØÑÕÒÖËÐÆÓÛåÎÞåÛÝÑÞÕÚÙØÐÒÙ×ÕÝÙÞÑëÛÞÛÜâÔÓßÖÜÕÏåÏØÓÒÒÏÒÙÞÝäÝÚáÑÓÚËÔÓÝÓÎÑÙÝÑÛÎÚÔÞÕÐÙâÖäÞÒÚàÔÕÎâÚáÛÙÞØÝÝÒÝÛØÔáÛâÏë×Õ׿ÌÓçÊÛßáÛØÝÛ×ÎÕÊáÚçÜÞÔÐèÈÝ×ÕÐàÞÜÔßÚÓÙÚÛ×Û×ÍÚÖàÑâÜÍÚÜÓÔÚÒÏÓÕÖÚÔåÓá×ÑÓÕØÎØÖÓàÙÚÛØÓÏÖÝÜß×ÙÙÜÙèÙÝçßÔÐß×Û‚EÚæÈß×ÏÇÒØÝÌáÙäÔÞÏÏÜÛÜßÛáÜØ×ÛÜáÍÕÙÛÚáÕàÒÕàãØÛÑáÓÏØÐÛÏÝßÝØÙÝÖ×ÝÞãÜßÞÖÉÓâáÊÑÔÕßáÕÙÖáãÏâÜÒàÐàßàÉàÎÐÏÎÖÕÙØØâÐÕ×ÓãÞáãÑØÒÖÒÔØÛäÝÑÚâÑÜËÑÛÔëÖÙÝÕÚÍÑ×ÎÐÈÚßÔÐÔÕêÙ×ÖØÛÕÖÚÚÛàÓÚäÚÏÍÏÓÏÚÒÒÓÝÜßÕáÔ×ßÞßÜÔÙØÜØØàâàÓÛáãÕ×ÛØëØÑߨÚ×àÒÝäÖØÖÐÜÙÐæã×ÖÝÖÐãàÐàÞ×Ò×ÛÚÜØâÒÏáÕÖÎÛÑÓÕÖ×ÞÝÙÖàÕµ¾·»º¸¸¶ºÃ¼¿¿º¶¹¼¼µ¼»À¿¶À½·ºÃ¿¶·Á¸¾¾Â¿À·»º¸»¿´ÁÀ¶¸¹Âý¼Â»º¾¼¸»··»º¶Â½³¼ÊÅÂÆÀÌÈÈÀÉÅ¿ÃÆÅ¿ÐÈÄÄÀÆÆÉÇÉ»çåØåÛÞèëÝ×âÚëèââëáàäçêìØæðáÛíçåïçÝÝéñàÚáääñãå×ãìæãäØßÒßÝ×Ü×îæßåâÝïãàØæÛäéáåÜàòÞÞÝÚééÝåòúÚìîì×Üâß××ÞåëÜàéçÛàåìèÞâÙÝçèÜèàããÜâãççãÙÝââñÝìÚêÚçèæïèìäâãåÞÝäãßÞëðéÜáÖáßéçä×ÞôßããçðßáçæàÔèåÛåèçïÕæÝÜÞçÜíæáåäæÛÝãéÚìØéïáëߨãÜÓÞåÜÖëààÙëäáÛêÙâäéççÝäëëçâÞñÜÝÝáèâüÜÞÙØèèÛáæäáÞéãäßîäßêåêÞçàæÜàèâéßáäêñÝñìçÜîåßääàóíÝãßÝîéÙìÞÞêßÙÜÕßåçãÜâãåèâÚçìëÙïèÜåâ×ñæäãàãæÜÖóßàÚÖåÖîÕêââßÞßèêÜéáÙòììåèèàðçäãåÛÚãÍÝÖÜëåÜáéöãÛã×âäÜåçåìæäÙêäæåãåâïÚâßàäèÓëäêäââççììäÞíåàÛôéåÖâÛèìêÙëÙàáßæÜÛìÝÜçßéÙÞâéÓãêâàæïîàÜèíéÝÕîïããßåãâÝÜíèáÝèæãßÝëèëíãØãÞäíáÚàêßëçáçØÝÞßçéÜßÚèìäêëæÜáãääÞßÞÚçéçãÜæÜàèáàæàâÔæéåéßæÙéÛãäÜÑäÞßãñðæÞßâåêïâåéëæíìâÜãçÜñàõäçêæòêçâãåÜàãêâæáÚàò×ëãä×ãæéãÖëâæâÚìâàæçÛèèäßîãÞàÜÙáãÝäåÛåçÛôÙñêäÞéàåâààßßåÕæÞèÝâáàèêÞÛÝåãØãäÛØØááðæ×ßÞãëÕçåàãêÛçí×ïîÝáØê×ÚÛããëàðàÚØêØâëåçÛãêèð÷íÝåççäéÝÜçáéîßëåäàãìæãÙßëßÞ×èßìèÐÜãÛáÝÛåÜâææØàâÞãëåàâáÞãÞåäàááæÜåàéëêåæãÚñäæåßÜÚäæ×ß×àåÕßðæåÛààìåãÝçãâãäåãâçÛæçÞÜÕßáÜ×åèêã×ß×ÖåßìàóéåÙàÝöÝáÝðÞåäæàãéâáäìñáêáèìèëäÜÞÜÙçßããìåÜÛáçàâáßßåÛæàãÝìÛàçßÚÖæèããàÛØèäÜßåáðæêáÞáàñÞàãáêÖäââ×ÙâãçßåãæîßÞçÝáâéÓêÛÔÝíÜÞßÞàÙäáßÕßïçíÛßá×åìàåíáêãïáçæÝéìÙÝéÙêáðåÝêÞÞãñÜàÚâìàëëåÓïéà×îâìäàÜâÙÜæâáÜæáããåâØñëáÒêÝáßãÞÖÞæèßáåëáãÞãÛäßååàÞÝäèéæéÙàæÕÝèÖÙæíáêãìßÞÜáäëðáàßíðå×ãáêíÛÜäæãÝìäàëãéàèàéäßèà¿ÁÈÊÈË·ÇÂÆÁÆÁÂÏÅÄÃÁÇÄÆÂÉËÈÅÈÈÅÿÀÂŽÃÈÇÁÂÁÎÇÁ¾ÆÇÉÊÉÂÉËÅÊÃÁÃÂÄÇÂÈÂÆÊÊÃÊÄ»¾ÅÇÇÄÄÂÌÁ½Ç¾ÆÃÉÀÃÃÅÂÂÄÂÀ¾¼áÙÞÛÝæÛÜÞáÙæÜæÙÚâÙáäÜãÙæâäãáØáÓæãöÑÞÞÔáÜæáÞÍáäÜâØÝÝäÜÜÜæÝÞßà×ÜâäâéÜâéÙÖâ×àØÝæââêÙØëØáÞëáÚßçßçàäñäåÕÞãà×íéêÜÜÝÏéÝæÛÜÞÖåçãÝìæÛØäêèÓãÖÚÜèåñàÝçáàÝãÙâßÒáãßæàéßâàâäÜàÜèâÛíÚåÜÚâéàÝÚß×çåçÕæÙÝà×è×ëäçäÕåÞߨäØÛæÛÚÜàéÛâÞßÜâÚäßÞàæäæáâÝßäÖåÜê×ßÒÝ÷üÜìßÍåÚäàæçÝàÚÙÓÖçßàÛÝêÚáåÝØÖÚãáæÝäÞåéáÝÛÝàáâæØáéìçßÞêäÞäââæäÔéÛåÖéìÝäÖÛìèå×ßêëÞëèÕàÙòÕàÝßáàåàêãÜãïàÞäÝâÛîáßäâáßêáæáîãïâßÜàâçàäàÜëáëÞãÕíßãêåàâäéæÚØëÚÛêÝîÛðßäÙÙåÖÞêìéÞâáçêÛØÕßòÜØÞ×ÖàåäçåâåäÚäßâêÝÚééçßãêåâÜâãáÞàÙîÞêÞìÝáÕßáäÞÝéØßáçØÜâßåäØÛçåØ×ÞæÙáÝìðØèêëßäßèßëÓÝêÙÞçÕâðÞãâÎÕãÛåãÖÏ×çÚàìëåßðâèäàäìÞÔàÚéòïÓâçÔÓàÜãßãâêàåß×ÕæØäÙæàØÞÜéèæêàÕæâÖßâÝÚéåÙàÝàÓÖäâéäéÝçåï‚àÔÕâÞâãÜÞÛîàßåñÜàÒàÜߨãæáòëçßñßáæáÚÝÖêèÕÝãßÜÚàßéÝéÜÚàØÚéÞäáÞäààéãç×ÓßÝÚÜߨÜáàäåÞÕ×ÝæåðäÙÙßéÙéæååêââáåÞäÛßäÕäÔéÝßãóÚçãÜààãèåÛÓçèççãááÝÛæàÛÖÍäáåæáÞêàäáààäáßרâáåÛëáÙÙÛãÛçæäáíÙåØÔØßÝØÜÒÙÝâßçÙÝìåÞããÞÛäôæðûäßäãìäéÔïçØæÑèàäïãÜåßï×ååÙæÙÖçåÙáãæßçÝáÜàáÛéääàÜÝÝÚçÛáàÝÚãäÞãçßÙèãåæßâàÖèäÝïÚÛâÛãßáÔîêãäæåáåãææßáÛäãÛàÙåÝåæÞÛìæåÛØêÙçØßéäßãáéãçØêççÞßäâéìãêÙæäáèâßáéßÐÝèíáØÙÝïáõèÜäßßÝêæçéòáçêÏÝÜíëÚÞáèéÞéåáàåÙÚæÑéßßáÞÛèæëââèÞãâßãÛâÛåÛØæèÜÜÜÜßâéÜååâÕÔãäßåÞÛäæßãßååàÞàçÓáàèÞâÖòáÚÕÝäßÞÔßßàôßÜÜãØèææßßÛÚáëÜïçÜåàäâåØÚäÙÙØÝÞàÚÕÛåØÑÙåÝêßàãæéÒèÛâáÞåëëçÞâÕàçÝäåêèßÕâåàØäàãÜØàëÛêåçëÞáêâó‚ìÝÇ¿ÀÄËüÁÄÀÉÄÆ¼ÂÅÅȹÊÐÀ¼ÆÁÈÁÍÀÀÀÄÁÆÑƽÄÃÃÁÁȽ»ÀÆËÆÇÃÃÂÂÃÁÁÄÉÅ¿¿ÌɼįÇÄËÈÇÌÂÊÅÌË¿ÎÇÊÉÂÈÇËÈÆÆÑÉÒÐÄÏðêðãëæëæáääãçðïñæìçäðÝïîèôãóíèææäáìßÙòçìõöèàêåôòÜíåëèæíâóíèìðáñèçêæöêçáãæããìØæáâïèëçñçâÞûÛèâÞÜêáÝ×ßíãðóòæØÞéäòêèâÝðéëûêëíãêóäåíèêðãØêëæääóéîááâôèíäæîèæâäÞàåâçèêçæåàááßéíçæäïÝ÷ñäðâáéöéÝîîåáàíïçãíååñáúåòìëíôìîöæàèéãåëîáÛïçðëäóàéèôîçäõïíàíñãæàâéãäççãéõëìêðêôéæíïëîíàïëôìôíÜîÞëçíåõâèëæìæèâæÛÕßüêìêöæáîêêÖëãëßñåðÝíìÜèòõáèëãäæçìóíåáÜëêáÙêíÝèîóàèñýéÞííçäáèýêòîáóàáÞàäãèíßèìöèãéëïÛêßîäééæåñïäáéæíêÞäíèéáïçðæãïêãïïÝêåèóôäèêìèìîéÞíçëåëéâò÷æìëëìèëÝêîèîæìèàáàìßéìíìÞëáéîúõïçñõîòîãòãåßÞææéíëâáçìàíåìíâèòÛèëëëêðÞóúíÛÕéìíóãéëö×èêòàêæåñèðíòòõäïãñóéçæñãóêñçßÜáÞîéèèééæòöðèßïôìÛçíéôÕöóãëèøéíâãðìïôèçåØðôïéìõìçìí÷áïêçåæãåìóñíôååÝéÞÝðçîÛàåáñõïÞéæäâäãâáìíìëìäãùæÞæìëîæñìäÝâáëåÕÜçæêíëóåâêæåÚóéëßîêåéãìáæîôßãìãëèúâêåíåãçíðêâåïñâÙêÜàâðãâßíÙõãèæÛÚëáìåìãëîçÖâðíñêÙãÚåêçÙêöñíêæÞþåìäêïõåæçûåàêéèêâîâæòòîìèâõêâêëæçßßæäæçááøëÞîêçêÛëçéóíòòìâÞèÞæéâÿêïáåõîøèïéíâÙêìèçåí‚€ïãæåâàëéëëìïðåëåíîâñíèðâæÞßéç×éîèêïéâïßîÛãîäê÷ïêêâçêëõàïìñßáèææðÛáäéìåàóèÝäåäìîñçíÝíêèåæìñîëñëôäæåõéòâé×éêí×ÚäÞæëðæãòóíÝïäëåðâêàíùàçëäâìäîõêùòïã‚ãîòäòõÿñðò‚ï‚‚‚%‚E‚0‚‚‚,‚*‚)‚*‚‚*‚‚‚%‚1‚(‚‚‚‚ ‚‚ÿ‚ú‚‚‚‚ ù‚ñú‚þøðóïë÷áùíèêæïÞççôÞæñíèÞñÝíòãîìÖëííëæçäæëçíééãøìëâçìëÚâÛäíëçÜâìäñêèèáñîòïóìçóæóâÝæàôæåäðâãáüíåõïõÛöóâðíçßêçìãåëàèèäðßéãôéçÑÆÌÉÏÉÆÊËÓÎÅÊÔÆËÉÉØÎÒÉÍÉ¿ÏËÊÆËÄÐÀÊÉËËÇÈËÊÉÍÊÉÌÌÑÎÉÎÅÂÄÄÓËÇ¿ÍÎÑÃÅÐÍÌÃÆÎÀÂúżÁ·À¶º¿ÀºÁÁµº¶»ÁÆ¿À±ÓæàÜÖÚ×ââÍÕâÚÚÕåÖÒæÔÙÚÐØßÍÛØáÙãÚÚäØÔרÜèÓßäØßÍâ×ÝÖåÙÚÚÙÚÚÙæÜÚ×ÞÚØßÑâÓØÜØá×ÓÝáÙÞØÜÓáÒãÚÞêÔØßáÐÔÑÝÝÛáæÚÕÝàÛÜÚÔÎåÏÑÑÒÙãÝßÞÞáÈßææÞÖæàãÓÞÚÜâÝ×ÓÜÛ×ÚâíÝÜéÓÐááÜáÖÌ×ÕÙÒßáÔÕÜÙÔáÝèÖØÝÝõâÏ×ÛÛ×à×ßÜá×ÚÞêÐÛâÞÐÕÙËÞÒ×ÙèàÒßðÖߨàÐÔÝáÔÚר×ÙÛÕäÖÕÝÞÖÚãÖáèÄÞØÖÌØÒÙâÕÞÕÚÕàáàÖäÕØÞçäÔãØÒÜãÕÝÞÔäÚÞã×ÜÔäÒÔËãæáÛÕ×çÞßßÛÝÑäÌÜèãÑØÞáÔÙÞÏßÏäåÞÕÙÒÞÔÛàÛÓÞàÍØÞèÔàÕßÔÖÖÜÞàÒèÙØÚÑàåÛÝîÝóÕÛÕéØÚéáàÝÖÚËÙÕÞãâêÍÚæØÏÝÞèéÚßàÚÒÜáÝâ‚?ßÖÏÓØáÝÕÞÜØÔàÐÝàÑÏßÚàÜâÜÝÖÕÚÕÙêÛÚÓÎÞ×ÙåÝÝâߨ×ÜÝÛäØÙâÚÒâØÔßÎÕâßæåßáÜß×ÝÙáÕèàÒÝ×áÝÚÓèãÑÌßáëßÓ×ÝÖàáåÝÞ×àÌÚÜÓÞØáÔÖÚàØÛÑÖáÓçãÛßÜÛ×ÙÓáçÏÓÐÙÜ׿ÜÙÙãÞÝÛàãáÕÞÓ×ÔåâÞÌÚÖâà׿áââ×àÕÙÖÖÜÑÜèÛÔÕÞäÞߨØÝÓÕãÝäÍÞÕ×Ü×ÛÛÒÓÐàÜ×ÑÖáÛÚ×ÕÚãÏãàæØæÑÜàéÙÏÕâåÓèØÖïÛÛÝÙßßÕÐÙØÙÜÍÕæÙÞàåÙâÝêÛÖÍÚâÜÙ×ÕÙרÓÓÜÜãÞâÓߨñÚÔÒàÝÚÕÛÜçáçåéÓÕÔÛÝáÚÚÏÜàÕÛÛÙ×ÜÝ×ÕßÔÓÜÕââßâÓßßãÝÖ×ÝâÊçá×ãÚÞÙæË×ÛÜàà×ÔæåרààÐÚØÝçÖâÚÔáÓØÙרâÚÝßßÝÓ×ÜÐæßáâàÎåÍÖÇßÙã×ÕåÏáÔÔÝÜÓÚÓÞÌÕáØÝâÙÍÚÙÚÑÓäÜØÞÜÚÚÕ×åàÜ×ÓÜÜÛÝÑÞÙÜ×ߨÚÈÜàæÚÚÓÝßãâàåÖÚÏÓÜåÝÙÓèàÎÚ×ÙÕàâÖâÐæîÓàÜÑÞÛÙÕÐÛàÖØÛÛÖÚßߨÞÚàÔÛÞÛÏÛ×ÕÙÏÚÏèÜØÛßÓèáÕØíÛÜÕÙÙÚÖÖãäÖÕàÕêåרâÙÓâÎÖÒÙÕäÓÑÙÚàÕÚ×ÜâØÙÙÛßÜÙßÞßàÔÜÜÍÜÛßßÜâ××ÜÔÙÔèÚÜßÜ×ÜÜÜÓÜßÚÜÓÝØÖáÏåÝÕáÚáÞàÕÑÒßÛäßàËÖñßÞÙÞÙ×ÚÛÖÚÖàÔæßÛØåÚÞÛãæÞÞßÞÞÞÐÙÝääÝßÔÖÜÝÔÛÞÍÙÛÔãÏÚèÚÑÕÐÙÏãÙÜÖÝÕÙÙàäáåÕØÔ×ßåàÜáêãÝßÖãÑäÌÞÜÎÞÑÜÝÒæäíãàÕæÜÓåÜãÝØéßÞ×äÞÝââÚÜ×ÐÕÝíÛÓàÒÛÕéáàÌÞÙÚ½¿¾¾Àº»½»½ÀüÂÀ¿¹¼¸Ä»À¼ºµ¾º¸½Á¹º³¼»½¿Ã¾Å¾º¾ÃÀ¾Â»¼¼¼·¾¸¾¿À¼¹Ã¾Ã¾¼Åº½¾»¿ÀÁ»ÅÆÊ¾ÅÿÄÃÃÈÂÅÁĽ¾ÂÅÂÈÆÉÆâÜåëèÜçÛßÞîãÝêäÒÕØéëòàÛãàåìæëçæÜÙéáèØéßÝØÞâßêÛàëìØÕÝåØÜìèäâäÚê×åâæáÛæàßÞÜÞì×ãÝãÙíïçòåããÝéèáØèààãâçèçßàÝæÜÙïçÞ×äîâÚÙãçÖàÜæÚâáçâçâéèÝÔàáàÞ×ïââÝÛÝèìàîÙãßÜçßæÞçèââÙçéçààÛäßêáãàëââéîåäÜäâåâØ×ìÚèìÛÞëçàãäáâÛÞÝèÖÛáççØÝߨäëÛÝçåÝäáàááÚçÜêÞÞÝßÝèàÞâäÙØìÙßÚêåßìÞá×âëæÚÞêæêå×ßÑèãâÛæãââàáãÛãïéàêÚßæâ×íÜÚÛëçÙÙêâßáØëèãÔéãèëÚèåÜéêæåßÛÝáååÞÛåÝéàÞÙäãÜåÝáëÙââÞßîæßìãéäèÙèèáÙêìñáâëáèÝêÙâáâÛáçãäåàäêôÞçâÞÞáìâÙåßñäçäàãäâÜååôÜëáìáßÖÞÙÞæëãÛßÓßàâåÜìÝÕáâáëâÞßåÞÜâØÞÛÚæéÝåêæÚÞâàà×ääîîåÕÝæçÝÖäÙëàîÞÒâÙàÞâîåÚÚíéååÜãßßäØáÑßÞâæìÛÞãÞÛäëëçæõÛôçäÜñÞâèìåîÕæÙàÚÝÛÞé×íëÚÞéÕäçîëéÞæâÜâããßÛåáÝÝãóéù‚þäîÜçêåÞìÝÜøÝîçåÔÝéâëÚ×åéñÇÞÚäìçæãØäëÛéìáààãàääîèÙÛßçÛèëî×áÚÚàåãçéèêÛçèÛëèÝâÙØæÚØäçÜèéàçæâííßáâàèêÙÞãÞÙäØàØÚâççâáàáâàÕñçáäÞÓèÝéêéÛÞèåêçãÝïíåßçÝããæÖìèïßåáßãÙáôéÞìÝ×äÙäáåæÖâßÞâðçßßçä×âéãÙ××ßæÜéÚÝÜáÞâáãèßÛáÙéèßÛèíìâàÜäàáÜáàÞÝèçäèâêâÜÛîá×ãéãêáèàßàòëéçÛàßëèÞÞÛÚÝîæåÔäßìëáàúäéáøëÜßãÜÞãÜèãáòïãâååèèÛóÝÝéäÚåÐÝßâêäêêßãòáéÝäâØáÛêæç×ëåÞàÛååÝæßÛè×ÞåçãàäáÙêàÚäèæÔâîÚÞääæìäßãÝåçìÝääåÚàÞáæëäâñäè×ÙáâãÙáÙæÛåàèßÔߨ‚ìßáÜÝàÞãàâßèèàçßéàÛâãêßææàèáØòÞâÞÞïäáÝçãðäóäèßäãÛêàèæíìÝçäÞææçèÛåàáâçèóîý‚‚b‚è‚¥‚7‚ðôíäïéïçÞìàãØÚçæáçâÜååÜáÜßãóÜääááÜòàéÞÞåãáçÞåØâïëäåëäÚèáÛâàáÛÞäêèãìãîÖäÜåäêÚäéÜãæèæíæäÛèÚØáéàÞäãôéèàåöÝÝèççâàèêêéçÛëÜçÄɾÂÉÍÃǼÅÈÐÅÄÐÃÆÄÉ¾ÇÆ¿ÌÂĽÅ˾ÂÀ¿ÂÆÉľÁÁÅÅÆÁ¾ÍÃÈÁÁËÅÀ½Ê¿È¿ÈÊÁÃÀýÅÅź¿Ç¿¼É¿ÂÂÁÇÂÄþȿſ¿Â¸¿ÅÆÅĿŽãÜåæóæÚØèñâàââéÕäßãààëùäàéèÞÝÚßÛíåéäóØÛçÞØØãÝ×ÜàèÚßâäÚãÖæØàïäéëÙáÖÛÚÏðààÝåíÖØßäáäãàÜ×ãêäèãç×ÜÞã×ÞÙÞçÜÜäÜäÚߨçßÝãáÑÚåÕçßâãÜÞìÝå×îâØÛÞäãßÛßåÕãÚâàãßèçäáöçöåï×â×ååßßááïÝÖÔãÝÚØáèØÝÙìàÔóÖçßÐÛãèãØØÞæÚÛÝãàçÙ×äÙÙåÞäà×íã×ÞÜÞßßÙÜÙàãàåãÞáçÕíÖßÚÜááàÛáÜáÕéßÚÛÖéÞÖãàßÛáèèåäÜÒØÕÙÛØÖÚåÚÒÙçâÝççáÚâÙæÖÐãæåÝçëÜÏæãÝØßÕèÚïåÞÑÛâäÔÞâÛÞÙÕÞÚÛ×áÞÕÝÝåØàíàáéÚéÝÕâÜèëÜäæâÙßèÙÛÚÜÕëÜÒÔßÒáØáÎÓÝÚäÛÛáØÔãßàÞíîÝìÜâÔ×Öë×ËÓÖÝÚÖäÔÝäßÝÛéâåëÝÛáêàÍÜÙßãæßÕàÖæÝêãäâåÚÛÖåßÞââà×ààÛáâßëæàáãÐÚßÒÖãæÛÞÛÕåÜè×çîèáçÝåßéàãåæßÙÒàãØÛÞàäÑÛÛÛÙäàÒßÛÞæÛàßßäáàçèÜäáçÔÜÙÚ×âåääÛíîßÒÓÖàÜÒçäÜÎÚáãàßÚèÛÜÞåãÔåâÝÞåßÝâÛãØâÙááæäáÝÙÛàÚÞÜáÏÞØßááÛèÜÜßÝáàßàÞìÜäåÝßéáóèæÕØåÓßÚÞÞàïáÐéÛåÜÜçÙáÞæÜÛßÝÞÖåçÔÙ×Öáãéáç×ÞÝëæßÛí׿çæãØëÞÞæÜäáèàâçÝàáß×íßÖÚ×ãßäçÜÛìÝÞ×éãÖåîäàâÜá×ÚÜá×ÖìרÜÒãØØÕâÚÙÞæäÞÛâàæÞèàçæÚßéÒÚØÚÞíàäÚãèÑÙÜçÚÞàäÞäåÜçäÝÛâÝèàâÞååèÞêàçÖëÙßÙåáêããê‚-‚)áÖÜéÚÕë×ßÚßÔãââÛëÛãÙÖߨÙàìÛèÛâìÚÓÕâÝóÕêÚâÝááÙãÜíàäãáÔÙäçæÙàçãÞââÛÝÚÚÝ×àé×ß×å××ÜèÙéâÜæØÕÞäàèÞåÖæÝÞæåâéÓÚÜäÛÛíçÜÜÕâàâ‚QÒØÖÜàÙÜìæáÝàÝá×âàÛäåÙÌ×ÔäØåæãØéáÛæáÔãâïçÜØãÛÕÞáÞàÛäÙêÞÛ×ßæâÜàÚßÞÔãÝÝáæÕØáÙæÞÜáãæââåÛäÜÞÓÞÚØÙÙãÒèãØäÛáÕÓúØÝÒâïäÖßÜããÝèÏàãâæÖÝÏßÛÜâÎÝáåÛÜâØÏåãéÞÖÖãØ×æàÙáéãßÞçßÔÜáÞÏäÝÜìáÜãØçãí×èãßÒèÏÔÞÞßÜâãÞÒäÙèááÓîÜÝÜ×áÝæã×ÚÖêìáàáÛßàÞÒããÓèÚïâæÛèÛßãßÛÏÜÛÜàÔÞêÛêÕëèàÚßâߨÙã×ÔàÞÚÛ¾¼ÄÀººÅÀ»½Ã¿½È¼Ã½Â´ÀÆ¿ÂÃÅÄÃÁ·ÃÂÊÈŹÀ¿Ê¿ÄÀý¾Â¿¼ÄÁ½É¿»ÂÀÂÁ»Ï¹¿ÂȺ½ÅÀ¾ÄĽÒÈÒÍÌÐÓËÐÑÐÓËÒÏÐÏÇ×ÑÉÎÎÎÒÍÎóòíâæïèóëöñïóóúóëâÿôíçëìðîçñóôæõóòãôîôÜèõçóôçíçïìóëï÷ãêêøëñîöäÝæëëòçìóíðâòñçììéñåéìôçùñèîìñëøóêîéóò÷õíøðíîíüïõúüñêíçéóêýãôéïéúùçòëïóççòòãíÿïðïùåíõå‚ðìäöíç‚÷øéèéòøèëëàììèìå÷êíéïüñïñìðæîðïëåîéëñéëêïÝïèðüíúõñäêôñéêïæï‚çòëðãìæòôêæíßææþðõçúêðñðùïïòæâùëïðííöã÷ïóàúëîôïìîòùëôôíêìêñóîðøßîïèìôñîíé‚òöñëóîäâïèïéêóëíûîïíïçêëïðóéöóïâúðìõæóôõîÜôåð‚îíõ‚êïîóéóçííïëïçûàñïåèòëìñòúðîõíðìîáòîöñïìñöêßçéæêßïâðñíðãéóçòúòîð÷âñùôïòóéôøëþÞïòìçóöéééø÷îïçòòÚðíßä‚ðçóôòë÷åéòñèüýõîëåéøöãæòñêèåïäèìäëìïåæëêóóíùë÷åå÷êíò÷îëóîàìëðîíéðè÷èéñøéçüõëóîöÛèôããåðìèìöïìôìðòòæå÷÷òèììéñöíõúéêôñêíöéóíìöìðóïçåúõéïôçóûþõìíõìðëñôîóõïêïøîàééûðíéãìùïïæòðòíîå÷íïúèþåçïæôàëíðïôíéôíññòòêëÝïîúçîíåóêäæåñçíôïôëæâ÷îñðêóî÷ûäãïíñåæóðæßìñâééó÷êììâûìïìúèñåïôñóé÷ôäíûÞêððòìôîòôßîõõòåêåíìáãôñöêôìðêçãÿðëä‚ôêêõéëäòõíñáúëàðõéõ÷ôüù÷óðäóôöäèí÷íàëñïíöÞáïêñöëïæïòöçíëéôîõúêïóõòíçòäý÷ùðïåñúýêéìðöðöôôòôëù‚ñçëíëéâññøßîïúïðòòéõúìýêçîãìôïóòúóüíùñôóöòÖõóõòûúæîòóëï÷èìéùýïïúçöæîíöïçúäûòòíæ÷éûì÷ìâóðñøêñóäðãóôòäïîöåíïãïìïîðòêéëïòúéîõîïëûòêùæôë÷ùêôéòìñïîùöøâìî‚ éëüêí÷âøèééùìùâèêêîûõõíîêñúïùðøûïñíúõû÷þôîôñ÷ôöóóþýîóôöø÷öõ÷ù‚‚‚ÿ‚ ‚‚ñû‚‚‚ ‚‚‚‚ ‚ ‚‚‚‚‚‚‚‚‚‚‚‚!‚‚‚-‚‚!‚‚‚‚‚‚‚‚'‚1‚‚5‚*‚‚‚‚1‚#‚.‚&‚‚ ‚"‚‚‚‚!‚ ‚‚‚‚ diff --git a/observation_sim/instruments/FilterParam.py b/observation_sim/instruments/FilterParam.py index 6235eb3..ac433f3 100755 --- a/observation_sim/instruments/FilterParam.py +++ b/observation_sim/instruments/FilterParam.py @@ -37,9 +37,9 @@ class FilterParam(object): # [TODO] "FGS": [5000.0, 8000.0, 3000.0, 11000.0, 0.6500, 0.164, 0., 30.], - "GU": [0.0, 0.0, 2550.0, 4200.0, 1.0, 0.037, 14.0, 26.0], - "GV": [0.0, 0.0, 4000.0, 6500.0, 1.0, 0.037, 14.0, 26.0], - "GI": [0.0, 0.0, 6200.0, 10000.0, 1.0, 0.037, 14.0, 26.0], + "GU": [0.0, 0.0, 2550.0, 10000.0, 1.0, 0.037, 14.0, 26.0], + "GV": [0.0, 0.0, 3500.0, 6500.0, 1.0, 0.037, 14.0, 26.0], + "GI": [0.0, 0.0, 5000.0, 10000.0, 1.0, 0.037, 14.0, 26.0], } else: filtP = filter_param diff --git a/observation_sim/mock_objects/Galaxy.py b/observation_sim/mock_objects/Galaxy.py index 4fe034f..fd7ecba 100755 --- a/observation_sim/mock_objects/Galaxy.py +++ b/observation_sim/mock_objects/Galaxy.py @@ -285,7 +285,7 @@ class Galaxy(MockObject): for i in range(len(bandpass_list)): branges[i, 0] = bandpass_list[i].blue_limit * 10 branges[i, 1] = bandpass_list[i].red_limit * 10 - + for i in range(len(bandpass_list)): # bandpass = bandpass_list[i] brange = branges[i] @@ -335,7 +335,7 @@ class Galaxy(MockObject): pos_img_local[1] = pos_img.y - y_start nnx = 0 nny = 0 - for order in ["B", "A"]: + for order in ["A", "B"]: EXTRA = False if self.getMagFilter(filt) <= filt.mag_saturation-2.: EXTRA = True @@ -362,16 +362,18 @@ class Galaxy(MockObject): for order in ["C", "D", "E"]: galImg_List.append(galImg) except: - psf, pos_shear = psf_model.get_PSF(chip=chip, pos_img=pos_img) - star_p = galsim.Convolve(psf, gal) - galImg = star_p.drawImage(wcs=chip_wcs_local, offset=offset) - galImg.setOrigin(0, 0) - if np.sum(np.isnan(galImg.array)) > 0: - # ERROR happens - return 2, pos_shear - for order in ["A", "B", "C", "D", "E"]: - galImg_List.append(galImg) - + try: + psf, pos_shear = psf_model.get_PSF(chip=chip, pos_img=pos_img) + star_p = galsim.Convolve(psf, gal) + galImg = star_p.drawImage(wcs=chip_wcs_local, offset=offset) + galImg.setOrigin(0, 0) + if np.sum(np.isnan(galImg.array)) > 0: + # ERROR happens + return 2, pos_shear + for order in ["A", "B", "C", "D", "E"]: + galImg_List.append(galImg) + except Exception as e: + continue # starImg = gal.drawImage( # wcs=chip_wcs_local, offset=offset, method='real_space') diff --git a/observation_sim/mock_objects/MockObject.py b/observation_sim/mock_objects/MockObject.py index 2fb1455..6ccbe54 100755 --- a/observation_sim/mock_objects/MockObject.py +++ b/observation_sim/mock_objects/MockObject.py @@ -445,7 +445,7 @@ class MockObject(object): pos_img_local[1] = pos_img.y - y_start nnx = 0 nny = 0 - for order in ["B", "A"]: + for order in ["A", "B"]: EXTRA = False if self.getMagFilter(filt) <= filt.mag_saturation-2.: EXTRA = True -- GitLab From 428f2c1eeb55c3995887a225cd75076e3f9c6deb Mon Sep 17 00:00:00 2001 From: Zhang Xin Date: Wed, 21 May 2025 19:11:07 +0800 Subject: [PATCH 64/64] pep8 --- observation_sim/_util.py | 7 ++++--- observation_sim/config/Pointing.py | 2 +- observation_sim/config/header/ImageHeader.py | 4 ++-- observation_sim/mock_objects/Galaxy.py | 8 +++++--- run_sim.py | 4 ++-- 5 files changed, 14 insertions(+), 11 deletions(-) diff --git a/observation_sim/_util.py b/observation_sim/_util.py index 5735fca..7c23127 100755 --- a/observation_sim/_util.py +++ b/observation_sim/_util.py @@ -26,7 +26,7 @@ def parse_args(): return parser.parse_args() -def generate_pointing_list(config, pointing_filename=None, data_dir=None, dataset = ''): +def generate_pointing_list(config, pointing_filename=None, data_dir=None, dataset=''): pointing_list = [] # Only valid when the pointing list does not contain time stamp column @@ -63,7 +63,8 @@ def generate_pointing_list(config, pointing_filename=None, data_dir=None, datase continue line = line.strip() columns = line.split() - pointing = Pointing(obs_config_file=obs_config_file, dataset=dataset) + pointing = Pointing( + obs_config_file=obs_config_file, dataset=dataset) pointing.read_pointing_columns(columns=columns, id=ipoint) t += delta_t * 60. pointing_list.append(pointing) @@ -83,7 +84,7 @@ def generate_pointing_list(config, pointing_filename=None, data_dir=None, datase timestamp=t, exp_time=exp_time, pointing_type='SCI', - obs_config_file=obs_config_file, + obs_config_file=obs_config_file, dataset=dataset ) t += delta_t * 60. diff --git a/observation_sim/config/Pointing.py b/observation_sim/config/Pointing.py index 3015e72..36766a1 100644 --- a/observation_sim/config/Pointing.py +++ b/observation_sim/config/Pointing.py @@ -10,7 +10,7 @@ import observation_sim.instruments._util as _util class Pointing(object): - def __init__(self, id=0, ra=0., dec=0., img_pa=0., timestamp=1621915200, sat_x=0., sat_y=0., sat_z=0., sun_x=0., sun_y=0., sun_z=0., sat_vx=0., sat_vy=0., sat_vz=0., exp_time=150., pointing_type='SCI', pointing_type_code='101', pointing_id='00000001', obs_config_file=None, t_shutter_open=1.3, t_shutter_close=1.3, dataset = 'csst-msc-c9-25sqdeg-v3'): + def __init__(self, id=0, ra=0., dec=0., img_pa=0., timestamp=1621915200, sat_x=0., sat_y=0., sat_z=0., sun_x=0., sun_y=0., sun_z=0., sat_vx=0., sat_vy=0., sat_vz=0., exp_time=150., pointing_type='SCI', pointing_type_code='101', pointing_id='00000001', obs_config_file=None, t_shutter_open=1.3, t_shutter_close=1.3, dataset='csst-msc-c9-25sqdeg-v3'): self.id = id self.ra = ra self.dec = dec diff --git a/observation_sim/config/header/ImageHeader.py b/observation_sim/config/header/ImageHeader.py index 2aed73f..ef57c86 100644 --- a/observation_sim/config/header/ImageHeader.py +++ b/observation_sim/config/header/ImageHeader.py @@ -355,7 +355,7 @@ def WCS_def(xlen=9216, ylen=9232, gapy=898.0, gapx1=534, gapx2=1309, ra_ref=60, # TODO project_cycle is temporary, is not in header defined, delete in future -def generatePrimaryHeader(xlen=9216, ylen=9232, pointing_id='00000001', pointing_type_code='101', ra=60, dec=-40, pixel_scale=0.074, time_pt=None, im_type='SCI', exptime=150., sat_pos=[0., 0., 0.], sat_vel=[0., 0., 0.], project_cycle=6, run_counter=0, chip_name="01", obstype = 'WIDE', dataset='csst-msc-c9-25sqdeg-v3'): +def generatePrimaryHeader(xlen=9216, ylen=9232, pointing_id='00000001', pointing_type_code='101', ra=60, dec=-40, pixel_scale=0.074, time_pt=None, im_type='SCI', exptime=150., sat_pos=[0., 0., 0.], sat_vel=[0., 0., 0.], project_cycle=6, run_counter=0, chip_name="01", obstype='WIDE', dataset='csst-msc-c9-25sqdeg-v3'): # array_size1, array_size2, flux, sigma = int(argv[1]), int(argv[2]), 1000.0, 5.0 @@ -432,7 +432,7 @@ def generatePrimaryHeader(xlen=9216, ylen=9232, pointing_id='00000001', pointing # h_prim['FILETYPE'] = get_file_type(img_type=im_type) # h_prim['FILETYPE'] = im_type h_prim['OBSTYPE'] = obstype - h_prim['DATASET'] = dataset + h_prim['DATASET'] = dataset co = coord.SkyCoord(ra, dec, unit='deg') ra_hms = format(co.ra.hms.h, '02.0f') + format(co.ra.hms.m, diff --git a/observation_sim/mock_objects/Galaxy.py b/observation_sim/mock_objects/Galaxy.py index fd7ecba..97df60c 100755 --- a/observation_sim/mock_objects/Galaxy.py +++ b/observation_sim/mock_objects/Galaxy.py @@ -285,7 +285,7 @@ class Galaxy(MockObject): for i in range(len(bandpass_list)): branges[i, 0] = bandpass_list[i].blue_limit * 10 branges[i, 1] = bandpass_list[i].red_limit * 10 - + for i in range(len(bandpass_list)): # bandpass = bandpass_list[i] brange = branges[i] @@ -363,9 +363,11 @@ class Galaxy(MockObject): galImg_List.append(galImg) except: try: - psf, pos_shear = psf_model.get_PSF(chip=chip, pos_img=pos_img) + psf, pos_shear = psf_model.get_PSF( + chip=chip, pos_img=pos_img) star_p = galsim.Convolve(psf, gal) - galImg = star_p.drawImage(wcs=chip_wcs_local, offset=offset) + galImg = star_p.drawImage( + wcs=chip_wcs_local, offset=offset) galImg.setOrigin(0, 0) if np.sum(np.isnan(galImg.array)) > 0: # ERROR happens diff --git a/run_sim.py b/run_sim.py index 933ce33..416cb29 100755 --- a/run_sim.py +++ b/run_sim.py @@ -62,7 +62,7 @@ def run_sim(): config["project_cycle"] = 6 if "run_counter" not in config: config["run_counter"] = 0 - + if "data_set" not in config: config["data_set"] = "csst-msc" @@ -75,7 +75,7 @@ def run_sim(): if "pointing_dir" in config['obs_setting']: pointing_dir = config['obs_setting']["pointing_dir"] pointing_list = generate_pointing_list( - config=config, pointing_filename=config['obs_setting']['pointing_file'], data_dir=pointing_dir, dataset = config["data_set"]) + config=config, pointing_filename=config['obs_setting']['pointing_file'], data_dir=pointing_dir, dataset=config["data_set"]) # Make the main output directories run_dir = make_run_dirs( -- GitLab