test_effect_unit.py 9.02 KB
Newer Older
1
2
3
4
5
6
7
8
import unittest
import numpy as np
from ObservationSim.Instrument.Chip import Effects
import galsim
import matplotlib.pyplot as plt
import os,sys,math,copy
from numpy.random import Generator, PCG64
import warnings
Zhang Xin's avatar
Zhang Xin committed
9
from astropy.io import fits
10
11
12
13
14
15
16

warnings.filterwarnings("ignore", '.*Numba.*',)

width = 9216
height = 9232

class DetTest(unittest.TestCase):
Zhang Xin's avatar
Zhang Xin committed
17
18
19

    def __init__(self, methodName='runTest'):
        super(DetTest,self).__init__(methodName)
Zhang Xin's avatar
Zhang Xin committed
20
        self.filePath('csst_msc_sim/test_sls_and_straylight')
Zhang Xin's avatar
Zhang Xin committed
21
22
23
24
25
26
27
28
29
30

    def filePath(self, file_name):
        self.datafn = os.path.join(os.getenv('UNIT_TEST_DATA_ROOT'), file_name)
        self.outDataFn = os.path.join(self.datafn,'output')
        if os.path.isdir(self.outDataFn):
            pass
        else:
            os.mkdir(self.outDataFn)
        

31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
    def test_prnu(self):
        '''
        Unit test for PRNU. Expected result: a randomized GS image contains PRNU with sigma=0.01, mean=1.
        '''
        print('PRNU Test:')
        sigma = 0.01
        seed = 20210911
        prnuimg = Effects.PRNU_Img(width, height, sigma=sigma, seed=seed)
        meanval, stdval = np.mean(prnuimg.array), np.std(prnuimg.array)
        print('  Mean & STDDEV of PRNU image are %6.4f & %6.4f.' % (meanval, stdval))
        print('  PRNU Image Array:')
        print('  ',prnuimg.array)
        self.assertTrue(np.abs(meanval-1)<1e-6)
        self.assertTrue(np.abs(stdval-sigma)<0.002)
        print('\nUnit test for PRNU has been passed.')
        del prnuimg

    def test_dark(self):
        '''
        Test add dark current to image. Expected result: an image with dark current 3.4 e- and noise=1.844 e-.
        '''
        rng_poisson = galsim.BaseDeviate(20210911)
        dark_noise = galsim.DeviateNoise(galsim.PoissonDeviate(rng_poisson, 0.02*(150+0.5*40)))
        img = galsim.Image(200,200,dtype=np.float32, init_value=0)
        print('Initial Mean & STD = %6.3f & %6.3f' % (np.mean(img.array), np.std(img.array)))
        img.addNoise(dark_noise)
        meanval = np.mean(img.array)
        stdval = np.std(img.array)
        print('Dark added Mean & STD = %6.3f & %6.3f' % (meanval, stdval))
        self.assertTrue(np.abs(meanval-3.4)<0.05)
        self.assertTrue(np.abs(stdval-1.844)<0.02)
        print('\nUnit test for dark current has been passed.')
        del img

    def test_satu(self):
        '''
        Test saturation and bleeding. Expected result: an image with bleeding effect.
        '''
        img = galsim.Image(500,500,dtype=np.float32)
        star = galsim.Gaussian(flux=60e5,fwhm=3)
        img = star.drawImage(image=img,center=(150,200))
        # gal = galsim.Sersic(n=1, half_light_radius=3,flux=50e5)
        # img = gal.drawImage(image=img,center=(350,300))
        img.addNoise(galsim.GaussianNoise(sigma=7))
        # plt.imshow(img.array)
        # plt.show()
Zhang Xin's avatar
Zhang Xin committed
77
        filename1 = os.path.join(self.outDataFn,'test_satu_initimg.fits')
78
79
80
81
        img.write(filename1)
        newimg = Effects.SaturBloom(img, fullwell=9e4)
        # plt.imshow(newimg.array)
        # plt.show()
Zhang Xin's avatar
Zhang Xin committed
82
        filename2 = os.path.join(self.outDataFn,'test_satu_bleedimg.fits')
83
84
85
86
87
88
89
90
91
        newimg.write(filename2)
        del img,newimg, star

    def test_nonlinear(self):
        '''
        Test non-linear effect. Expected result: an image with non-linearity effect.
        '''
        imgarr = np.arange(1,9e4,4).reshape((150,150))
        img = galsim.Image(copy.deepcopy(imgarr))
Zhang Xin's avatar
Zhang Xin committed
92
        filename1 = os.path.join(self.outDataFn,'test_nonlinear_initimg.fits')
93
94
        img.write(filename1)
        newimg = Effects.NonLinearity(img, beta1=5E-7, beta2=0)
Zhang Xin's avatar
Zhang Xin committed
95
        filename2 = os.path.join(self.outDataFn,'test_nonlinear_finalimg.fits')
96
97
98
99
100
        newimg.write(filename2)
        plt.scatter(imgarr.flatten(), newimg.array.flatten(), s=2, alpha=0.5)
        plt.plot([-1e3,9e4],[-1e3,9e4],color='black', lw=1, ls='--')
        plt.xlabel('input (e-)')
        plt.ylabel('output (e-)')
Zhang Xin's avatar
Zhang Xin committed
101
        plt.savefig(os.path.join(self.outDataFn,'test_nonlinearity.png'), dpi=200)
102
103
104
105
106
107
108
109
        plt.show()
        del img,newimg,imgarr

    def test_badpixel_HtrDtr(self):
        img = galsim.Image(500,500,init_value=1000)
        rgbadpix = Generator(PCG64(20210911))
        badfraction = 5E-5*(rgbadpix.random()*0.5+0.7)
        img = Effects.DefectivePixels(img, IfHotPix=True, IfDeadPix=True, fraction=badfraction, seed=20210911, biaslevel=0)
Zhang Xin's avatar
Zhang Xin committed
110
        img.write(os.path.join(self.outDataFn,'test_badpixel_HtrDtr.fits'))
111
112
113
114
115
116
        del img
    def test_badpixel_HfsDtr(self):
        img = galsim.Image(500,500,init_value=1000)
        rgbadpix = Generator(PCG64(20210911))
        badfraction = 5E-5*(rgbadpix.random()*0.5+0.7)
        img = Effects.DefectivePixels(img, IfHotPix=False, IfDeadPix=True, fraction=badfraction, seed=20210911, biaslevel=0)
Zhang Xin's avatar
Zhang Xin committed
117
        img.write(os.path.join(self.outDataFn,'test_badpixel_HfsDtr.fits'))
118
119
120
121
122
123
        del img
    def test_badpixel_HtrDfs(self):
        img = galsim.Image(500,500,init_value=1000)
        rgbadpix = Generator(PCG64(20210911))
        badfraction = 5E-5*(rgbadpix.random()*0.5+0.7)
        img = Effects.DefectivePixels(img, IfHotPix=True, IfDeadPix=False, fraction=badfraction, seed=20210911, biaslevel=0)
Zhang Xin's avatar
Zhang Xin committed
124
        img.write(os.path.join(self.outDataFn,'test_badpixel_HtrDfs.fits'))
125
126
127
128
129
130
        del img
    def test_badpixel_HfsDfs(self):
        img = galsim.Image(500,500,init_value=1000)
        rgbadpix = Generator(PCG64(20210911))
        badfraction = 5E-5*(rgbadpix.random()*0.5+0.7)
        img = Effects.DefectivePixels(img, IfHotPix=False, IfDeadPix=False, fraction=badfraction, seed=20210911, biaslevel=0)
Zhang Xin's avatar
Zhang Xin committed
131
        img.write(os.path.join(self.outDataFn,'test_badpixel_HfsDfs.fits'))
132
133
134
135
136
137
        del img

    def test_badlines(self):
        img = galsim.Image(500,500,init_value=-1000)
        img.addNoise(galsim.GaussianNoise(sigma=7))
        newimg = Effects.BadColumns(copy.deepcopy(img), seed=20210911)
Zhang Xin's avatar
Zhang Xin committed
138
        newimg.write(os.path.join(self.outDataFn,'test_badlines.fits'))
139
140
        del newimg,img

Zhang Xin's avatar
Zhang Xin committed
141
142
143
144
145
146
147
148
149
    # def test_cte(self):
    #     img = galsim.Image(200,200,init_value=1000)
    #     img.array[50,80] = 1e4
    #     img.array[150,150] = 3e4
    #     newimgcol = Effects.CTE_Effect(copy.deepcopy(img),direction='column')
    #     newimgrow = Effects.CTE_Effect(copy.deepcopy(img),direction='row')
    #     newimgcol.write(os.path.join(self.outDataFn,'test_ctecol.fits'))
    #     newimgrow.write(os.path.join(self.outDataFn,'test_cterow.fits'))
    #     del img,newimgcol,newimgrow
150
151
152
153
154
155
156

    def test_readnoise(self):
        img = galsim.Image(200,200,init_value=1000)
        seed = 20210911
        rng_readout = galsim.BaseDeviate(seed)
        readout_noise = galsim.GaussianNoise(rng=rng_readout, sigma=5)
        img.addNoise(readout_noise)
Zhang Xin's avatar
Zhang Xin committed
157
        img.write(os.path.join(self.outDataFn,'test_readnoise.fits'))
158
159
160
161
162
163
164
165
166
167
168
169
170
        stdval = np.std(img.array)
        self.assertTrue(np.abs(stdval-5)<0.01*5)
        print('\nUnit test for readout noise has been passed.')
        del img

    def test_addbias(self):
        img = galsim.Image(200,200,init_value=0)
        img = Effects.AddBiasNonUniform16(img,bias_level=500, nsecy = 2, nsecx=8,seed=20210911)
        img.write('./output/test_addbias.fits')
        del img

    def test_apply16gains(self):
        img = galsim.Image(500,500,init_value=100)
Zhang Xin's avatar
Zhang Xin committed
171
172
        img,_ = Effects.ApplyGainNonUniform16(img, gain=1.5, nsecy=2, nsecx=8, seed=202102)
        img.write(os.path.join(self.outDataFn,'test_apply16gains.fits'))
173
174
175
176
177
178
179
180
181
182
183
184
        rightedge = int(500/8)*8
        print('gain=%6.2f' % 1.5)
        meanimg = np.mean(img.array[:,:rightedge])
        sigmaimg = np.std(img.array[:,:rightedge])
        print('mean, sigma = %6.2f, %6.2f' % (meanimg,sigmaimg))
        self.assertTrue(np.abs(meanimg-100/1.5)<1)
        self.assertTrue(np.abs(sigmaimg/meanimg-0.01)<0.001)
        print('\nUnit test for applying 16 channel gains has been passed.')
        del img


    def test_cosmicray(self):
Zhang Xin's avatar
Zhang Xin committed
185
186
        attachedSizes = np.loadtxt(os.path.join(self.datafn,'wfc-cr-attachpixel.dat'))
        cr_map,_ = Effects.produceCR_Map(
187
188
189
190
                xLen=500, yLen=500, exTime=150+0.5*40, 
                cr_pixelRatio=0.003*(1+0.5*40/150), 
                gain=1, attachedSizes=attachedSizes, seed=20210911)
        crimg = galsim.Image(cr_map)
Zhang Xin's avatar
Zhang Xin committed
191
        crimg.write(os.path.join(self.outDataFn,'test_cosmicray.fits'))
192
193
194
195
196
197
        del cr_map,crimg

    def test_shutter(self):
        img = galsim.Image(5000,5000,init_value=1000)
        shuttimg = Effects.ShutterEffectArr(img, t_exp=150, t_shutter=1.3, dist_bearing=735, dt=1E-3)    # shutter effect normalized image for this chip
        img *= shuttimg
Zhang Xin's avatar
Zhang Xin committed
198
        img.write(os.path.join(self.outDataFn,'test_shutter.fits'))
199
200
201
202
203
204
205
206
207
        del img

    def test_vignette(self):
        img = galsim.Image(2000,2000,init_value=1000)
        print(img.bounds)
        # # img.bounds = galsim.BoundsI(1, width, 1, height)
        img.setOrigin(10000,10000)
        flat_img = Effects.MakeFlatSmooth(img.bounds,20210911)
        flat_normal = flat_img / np.mean(flat_img.array)
Zhang Xin's avatar
Zhang Xin committed
208
        flat_normal.write(os.path.join(self.outDataFn,'test_vignette.fits'))
209
210
211
212
213
214
        del flat_img,img,flat_normal



if __name__ == '__main__':
    unittest.main()