det_effect_unit_test.py 8.33 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
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
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
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

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

width = 9216
height = 9232

if os.path.isdir('./output/'):
    pass
else:
    os.mkdir('./output/')

class DetTest(unittest.TestCase):
    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()
        filename1 = os.path.join('output','test_satu_initimg.fits')
        img.write(filename1)
        newimg = Effects.SaturBloom(img, fullwell=9e4)
        # plt.imshow(newimg.array)
        # plt.show()
        filename2 = os.path.join('output','test_satu_bleedimg.fits')
        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))
        filename1 = os.path.join('output','test_nonlinear_initimg.fits')
        img.write(filename1)
        newimg = Effects.NonLinearity(img, beta1=5E-7, beta2=0)
        filename2 = os.path.join('output','test_nonlinear_finalimg.fits')
        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-)')
        plt.savefig('./output/test_nonlinearity.png', dpi=200)
        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)
        img.write('./output/test_badpixel_HtrDtr.fits')
        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)
        img.write('./output/test_badpixel_HfsDtr.fits')
        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)
        img.write('./output/test_badpixel_HtrDfs.fits')
        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)
        img.write('./output/test_badpixel_HfsDfs.fits')
        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)
        newimg.write('./output/test_badlines.fits')
        del newimg,img

    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('./output/test_ctecol.fits')
        newimgrow.write('./output/test_cterow.fits')
        del img,newimgcol,newimgrow

    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)
        img.write('./output/test_readnoise.fits')
        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)
        img = Effects.ApplyGainNonUniform16(img, gain=1.5, nsecy=2, nsecx=8, seed=202102)
        img.write("./output/test_apply16gains.fits")
        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):
        attachedSizes = np.loadtxt('../ObservationSim/Instrument/Chip/wfc-cr-attachpixel.dat')
        cr_map = Effects.produceCR_Map(
                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)
        crimg.write('./output/test_cosmicray.fits')
        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
        img.write('./output/test_shutter.fits')
        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)
        flat_normal.write('./output/test_vignette.fits')
        del flat_img,img,flat_normal



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