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

fixed photometry/bad column issue, modify detector effects order

parent ef8c4609
Loading
Loading
Loading
Loading
+2 −0
Original line number Original line Diff line number Diff line
@@ -37,8 +37,10 @@ class ChipOutput(object):
        fmt5 = "%10s %8.4f %8.4f %8.4f\n"
        fmt5 = "%10s %8.4f %8.4f %8.4f\n"
        self.hdr = hdr1 + hdr2 + hdr3 + hdr4 + hdr5
        self.hdr = hdr1 + hdr2 + hdr3 + hdr4 + hdr5
        self.fmt = fmt1 + fmt2 + fmt3 + fmt4 + fmt5
        self.fmt = fmt1 + fmt2 + fmt3 + fmt4 + fmt5
        print("pointing_type = %s\n"%(pointing_type))
        if pointing_type == 'MS':
        if pointing_type == 'MS':
            self.cat = open(os.path.join(self.subdir, self.cat_name), "w")
            self.cat = open(os.path.join(self.subdir, self.cat_name), "w")
            print("Creating catalog file %s ...\n"%(os.path.join(self.subdir, self.cat_name)))
            self.cat.write(self.hdr)
            self.cat.write(self.hdr)


    def updateHDR(self, hdr):
    def updateHDR(self, hdr):
+143 −136
Original line number Original line Diff line number Diff line
@@ -30,16 +30,13 @@ class Chip(FocalPlane):
        self.read_noise = 5.0   # e/pix
        self.read_noise = 5.0   # e/pix
        self.dark_noise = 0.02  # e/pix/s
        self.dark_noise = 0.02  # e/pix/s
        self.pix_scale  = 0.074 # pixel scale
        self.pix_scale  = 0.074 # pixel scale
        # self.gain       = 1.0
        # self.bias_level = 1000  # e-/pix
        self.gain = float(config["gain"])
        self.gain = float(config["gain"])
        self.bias_level = float(config["bias_level"])
        self.bias_level = float(config["bias_level"])
        self.overscan   = 1000
        self.overscan   = 1000
        self.exptime    = 150   # second
        self.exptime    = float(config["exp_time"])   # second
        # self.dark_exptime = 300  # second
        # self.flat_exptime = 150  # second
        self.dark_exptime = float(config['dark_exptime'])
        self.dark_exptime = float(config['dark_exptime'])
        self.flat_exptime = float(config['flat_exptime'])
        self.flat_exptime = float(config['flat_exptime'])
        self.readout_time = float(config['readout_time'])


        # A chip ID must be assigned
        # A chip ID must be assigned
        self.chipID = int(chipID)
        self.chipID = int(chipID)
@@ -234,60 +231,6 @@ class Chip(FocalPlane):
        noise = self.dark_noise * exptime + self.read_noise**2
        noise = self.dark_noise * exptime + self.read_noise**2
        return noise
        return noise



    def addNoise_phot(self, img, exptime=150.0, sky_noise=0., seed=31415):
        rng = galsim.BaseDeviate(seed)
        dark_noise = galsim.DeviateNoise(galsim.PoissonDeviate(rng, self.dark_noise*exptime))
        img.addNoise(dark_noise)
        ccd_noise = galsim.CCDNoise(rng, sky_level=sky_noise, gain=self.gain, read_noise=self.read_noise)
        img.addNoise(ccd_noise)
        return img

    def addNoise_spec(self, config, tel, img, sky_map, exptime=150.0, seed=31415):
        if img.array.shape != sky_map.shape:
            raise ValueError("The shape img and sky_map must be equal.")

        # n_img_arrar = (img.array + sky_map) * tel.pupil_area * exptime
        # Should be the following?
        rng = galsim.BaseDeviate(seed)
        noise_img = galsim.Image(img, copy=True)
        dark_noise = galsim.DeviateNoise(galsim.PoissonDeviate(rng, self.dark_noise*exptime))
        img.addNoise(dark_noise)
        if config["abs_back"].lower() == "y":
            img += (sky_map * tel.pupil_area * exptime)
        ccd_noise = galsim.CCDNoise(rng, gain=self.gain, read_noise=self.read_noise)
        img.addNoise(ccd_noise)
        return img
        # pNoise = self.dark_noise * exptime
        # noise_img = galsim.Image(n_img_arrar, copy=True)
        # dNose = galsim.PoissonNoise(rng=rng, sky_level=pNoise)
        # noise_img.addNoise(dNose)
        # rdNoise = galsim.GaussianNoise(rng=rng, sigma=self.read_noise)
        # noise_img.addNoise(rdNoise)
        # return noise_img

    def addNoise(self, config, tel, filt, img, sky_map=None, exptime=150.0):
        if self.survey_type == "photometric":
            sky_level = filt.getSkyNoise(exptime=exptime, gain=self.gain)
            img = self.addNoise_phot(
                img=img, 
                exptime=exptime, 
                sky_noise=filt.getSkyNoise(exptime=exptime, gain=self.gain), 
                seed=int(config["seed_skynoise"]))
            if config["abs_back"].lower() == "y":
                img += sky_level
        elif self.survey_type == "spectroscopic":
            if sky_map is None:
                raise ValueError("Must provide sky_map for spectroscopic chip")
            img = self.addNoise_spec(
                config=config, 
                tel=tel, 
                img=img, 
                sky_map=sky_map, 
                exptime=exptime, 
                seed=int(config["seed_skynoise"]))
        return img

    def getChipSLSConf(self):
    def getChipSLSConf(self):
        confFile = ''
        confFile = ''
        if self.chipID == 1: confFile = ['CSST_GI2.conf', 'CSST_GI1.conf']
        if self.chipID == 1: confFile = ['CSST_GI2.conf', 'CSST_GI1.conf']
@@ -351,7 +294,7 @@ class Chip(FocalPlane):
        fname = os.path.join(output_dir, h_prim['FILENAME']+'.fits')
        fname = os.path.join(output_dir, h_prim['FILENAME']+'.fits')
        hdu1.writeto(fname, output_verify='ignore', overwrite=True)
        hdu1.writeto(fname, output_verify='ignore', overwrite=True)


    def addEffects(self, config, img, chip_output, filt, ra_cen, dec_cen, img_rot, exptime=150., pointing_ID=0, timestamp_obs=1621915200, pointing_type='MS'):
    def addEffects(self, config, img, chip_output, filt, ra_cen, dec_cen, img_rot, exptime=150., pointing_ID=0, timestamp_obs=1621915200, pointing_type='MS', sky_map=None, tel=None):
        SeedGainNonuni=int(config["seed_gainNonUniform"])
        SeedGainNonuni=int(config["seed_gainNonUniform"])
        SeedBiasNonuni=int(config["seed_biasNonUniform"])
        SeedBiasNonuni=int(config["seed_biasNonUniform"])
        SeedRnNonuni = int(config["seed_rnNonUniform"])
        SeedRnNonuni = int(config["seed_rnNonUniform"])
@@ -368,6 +311,17 @@ class Chip(FocalPlane):
        else:
        else:
            BoolDeadPix = False
            BoolDeadPix = False


        # Add sky background
        if sky_map == None:
            sky_map = filt.getSkyNoise(exptime=self.exptime)
        elif img.array.shape != sky_map.shape:
            raise ValueError("The shape img and sky_map must be equal.")
        elif tel is not None: # If sky_map is given in flux
            sky_map = sky_map * tel.pupil_area * self.exptime
        if config["add_back"].lower() == "y":
            img += sky_map
        del sky_map

        # Apply flat-field large scale structure for one chip
        # Apply flat-field large scale structure for one chip
        if config["flat_fielding"].lower() == "y":
        if config["flat_fielding"].lower() == "y":
            print("  Creating and applying Flat-Fielding", flush=True)
            print("  Creating and applying Flat-Fielding", flush=True)
@@ -392,30 +346,19 @@ class Chip(FocalPlane):
                del shutt_gsimg
                del shutt_gsimg
            del shuttimg
            del shuttimg


        # Apply PRNU effect and output PRNU flat file:
        # Add Poisson noise
        if config["prnu_effect"].lower() == "y":
        seed = int(config["seed_poisson"]) + pointing_ID*30 + self.chipID
            print("  Applying PRNU effect", flush=True)
        rng_poisson = galsim.BaseDeviate(seed)
            prnu_img = effects.PRNU_Img(
        poisson_noise = galsim.PoissonNoise(rng_poisson, sky_level=0.)
                xsize=self.npix_x, 
        img.addNoise(poisson_noise)
                ysize=self.npix_y, 
                sigma=0.01, 
                seed=int(config["seed_prnu"]+self.chipID))
            img *= prnu_img
            if config["prnu_output"].lower() == "y":
                prnu_img.write("%s/FlatImg_PRNU_%s.fits" % (chip_output.subdir,self.chipID))
            if config["flat_output"].lower() == "n":
                del prnu_img

        # Add dark current
        img += self.dark_noise*exptime


        # Add cosmic-rays
        # Add cosmic-rays
        if config["cosmic_ray"].lower() == "y" and pointing_type=='MS':
        if config["cosmic_ray"].lower() == "y" and pointing_type=='MS':
            print("  Adding Cosmic-Ray", flush=True)
            print("  Adding Cosmic-Ray", flush=True)
            cr_map = effects.produceCR_Map(
            cr_map = effects.produceCR_Map(
                xLen=self.npix_x, yLen=self.npix_y, 
                xLen=self.npix_x, yLen=self.npix_y, 
                exTime=exptime, 
                exTime=self.exptime+0.5*self.readout_time, 
                cr_pixelRatio=0.003, 
                cr_pixelRatio=0.003*(1+0.5*self.readout_time/self.exptime), 
                gain=self.gain, 
                gain=self.gain, 
                attachedSizes=self.attachedSizes,
                attachedSizes=self.attachedSizes,
                seed=SeedCosmicRay+pointing_ID*30+self.chipID)   # seed: obj-imaging:+0; bias:+1; dark:+2; flat:+3;
                seed=SeedCosmicRay+pointing_ID*30+self.chipID)   # seed: obj-imaging:+0; bias:+1; dark:+2; flat:+3;
@@ -442,15 +385,78 @@ class Chip(FocalPlane):
                exptime=150.)
                exptime=150.)
            del crmap_gsimg
            del crmap_gsimg


        # Apply PRNU effect and output PRNU flat file:
        if config["prnu_effect"].lower() == "y":
            print("  Applying PRNU effect", flush=True)
            prnu_img = effects.PRNU_Img(
                xsize=self.npix_x, 
                ysize=self.npix_y, 
                sigma=0.01, 
                seed=int(config["seed_prnu"]+self.chipID))
            img *= prnu_img
            if config["prnu_output"].lower() == "y":
                prnu_img.write("%s/FlatImg_PRNU_%s.fits" % (chip_output.subdir,self.chipID))
            if config["flat_output"].lower() == "n":
                del prnu_img

        # Add dark current
        if config["add_dark"].lower() == "y":
            dark_noise = galsim.DeviateNoise(galsim.PoissonDeviate(rng_poisson, self.dark_noise*(self.exptime+0.5*self.readout_time)))
            img.addNoise(dark_noise)

        # Add Hot Pixels or/and Dead Pixels
        rgbadpix = Generator(PCG64(int(SeedDefective+self.chipID)))
        badfraction = 5E-5*(rgbadpix.random()*0.5+0.7)
        img = effects.DefectivePixels(img, IfHotPix=BoolHotPix, IfDeadPix=BoolDeadPix, fraction=badfraction, seed=SeedDefective+self.chipID, biaslevel=0)

        # Apply Bad lines 
        if config["add_badcolumns"].lower() == "y":
            img = effects.BadColumns(img, seed=SeedBadColumns, chipid=self.chipID)

        # Add Bias level
        # Add Bias level
        if config["add_bias"].lower() == "y":
        if config["add_bias"].lower() == "y":
            print("  Adding Bias level and 16-channel non-uniformity")
            print("  Adding Bias level and 16-channel non-uniformity")
            # img += float(config["bias_level"])
            img = effects.AddBiasNonUniform16(img, 
            img = effects.AddBiasNonUniform16(img, 
                bias_level=float(config["bias_level"]), 
                bias_level=float(config["bias_level"]), 
                nsecy = 2, nsecx=8, 
                nsecy = 2, nsecx=8, 
                seed=SeedBiasNonuni+self.chipID)
                seed=SeedBiasNonuni+self.chipID)


        # Apply Nonlinearity on the chip image
        if config["non_linear"].lower() == "y":
            print("  Applying Non-Linearity on the chip image", flush=True)
            img = effects.NonLinearity(GSImage=img, beta1=5.e-7, beta2=0)

        # Apply CCD Saturation & Blooming
        if config["saturbloom"].lower() == "y":
            print("  Applying CCD Saturation & Blooming")
            img = effects.SaturBloom(GSImage=img, nsect_x=1, nsect_y=1, fullwell=fullwell)

        # Apply CTE Effect
        if config["cte_trail"].lower() == "y":
            print("  Apply CTE Effect")
            img = effects.CTE_Effect(GSImage=img, threshold=27)

        # Add Read-out Noise
        if config["add_readout"].lower() == "y":
            seed = int(config["seed_readout"]) + pointing_ID*30 + self.chipID
            rng_readout = galsim.BaseDeviate(seed)
            readout_noise = galsim.GaussianNoise(rng=rng_readout, sigma=self.read_noise)
            img.addNoise(readout_noise)


        # Apply Gain & Quantization
        print("  Applying Gain (and 16 channel non-uniformity) & Quantization", flush=True)
        img = effects.ApplyGainNonUniform16(
            img, gain=self.gain, 
            nsecy = 2, nsecx=8, 
            seed=SeedGainNonuni+self.chipID)
        img.array[img.array > 65535] = 65535
        img.replaceNegative(replace_value=0)
        img.quantize()

        ######################################################################################
        # Output images for calibration pointing
        ######################################################################################
        # Bias output
        # Bias output
        if config["bias_output"].lower() == "y" and pointing_type=='CAL':
        if config["bias_output"].lower() == "y" and pointing_type=='CAL':
            print("  Output N frame Bias files", flush=True)
            print("  Output N frame Bias files", flush=True)
@@ -466,7 +472,7 @@ class Chip(FocalPlane):
                        cr_map = effects.produceCR_Map(
                        cr_map = effects.produceCR_Map(
                            xLen=self.npix_x, yLen=self.npix_y, 
                            xLen=self.npix_x, yLen=self.npix_y, 
                            exTime=0.01, 
                            exTime=0.01, 
                            cr_pixelRatio=0.003*0.01/self.exptime, 
                            cr_pixelRatio=0.003*(0.01+0.5*self.readout_time)/(self.exptime+0.5*self.readout_time), 
                            gain=self.gain, 
                            gain=self.gain, 
                            attachedSizes=self.attachedSizes,
                            attachedSizes=self.attachedSizes,
                            seed=SeedCosmicRay+pointing_ID*30+self.chipID+1)
                            seed=SeedCosmicRay+pointing_ID*30+self.chipID+1)
@@ -477,7 +483,11 @@ class Chip(FocalPlane):
                # Non-Linearity for Bias
                # Non-Linearity for Bias
                if config["non_linear"].lower() == "y":
                if config["non_linear"].lower() == "y":
                    print("  Applying Non-Linearity on the Bias image", flush=True)
                    print("  Applying Non-Linearity on the Bias image", flush=True)
                    BiasCombImg = effects.NonLinearity(GSImage=BiasCombImg, beta1=1.e-7, beta2=1.e-10)
                    BiasCombImg = effects.NonLinearity(GSImage=BiasCombImg, beta1=5.e-7, beta2=0)

                # Apply Bad lines 
                if config["add_badcolumns"].lower() == "y":
                    BiasCombImg = effects.BadColumns(BiasCombImg-float(config["bias_level"])+5, seed=SeedBadColumns, chipid=self.chipID) + float(config["bias_level"])-5


                BiasCombImg = effects.ApplyGainNonUniform16(BiasCombImg, gain=self.gain, 
                BiasCombImg = effects.ApplyGainNonUniform16(BiasCombImg, gain=self.gain, 
                    nsecy = 2, nsecx=8, 
                    nsecy = 2, nsecx=8, 
@@ -493,7 +503,7 @@ class Chip(FocalPlane):
                datetime_obs = datetime.fromtimestamp(timestamp_obs)
                datetime_obs = datetime.fromtimestamp(timestamp_obs)
                date_obs = datetime_obs.strftime("%y%m%d")
                date_obs = datetime_obs.strftime("%y%m%d")
                time_obs = datetime_obs.strftime("%H%M%S")
                time_obs = datetime_obs.strftime("%H%M%S")
                timestamp_obs += 5 * 60
                timestamp_obs += 10 * 60
                self.outputCal(
                self.outputCal(
                    img=BiasCombImg,
                    img=BiasCombImg,
                    ra_cen=ra_cen,
                    ra_cen=ra_cen,
@@ -517,7 +527,7 @@ class Chip(FocalPlane):
            elif config["add_bias"].lower() == "n":
            elif config["add_bias"].lower() == "n":
                biaslevel = 0
                biaslevel = 0
                overscan = 0
                overscan = 0
            darklevel = self.dark_noise*self.flat_exptime
            darklevel = self.dark_noise*(self.flat_exptime+0.5*self.readout_time)
            for i in range(NFlat):
            for i in range(NFlat):
                FlatSingle = flat_img * prnu_img + darklevel
                FlatSingle = flat_img * prnu_img + darklevel
                FlatCombImg, FlatTag = effects.MakeFlatNcomb(
                FlatCombImg, FlatTag = effects.MakeFlatNcomb(
@@ -526,15 +536,15 @@ class Chip(FocalPlane):
                    read_noise=self.read_noise,
                    read_noise=self.read_noise,
                    gain=1, 
                    gain=1, 
                    overscan=overscan, 
                    overscan=overscan, 
                    biaslevel=biaslevel,
                    biaslevel=0,
                    seed_bias=SeedDefective+self.chipID
                    seed_bias=SeedDefective+self.chipID
                    )
                    )
                if config["cosmic_ray"].lower() == "y":
                if config["cosmic_ray"].lower() == "y":
                    if config["cray_differ"].lower() == "y":
                    if config["cray_differ"].lower() == "y":
                        cr_map = effects.produceCR_Map(
                        cr_map = effects.produceCR_Map(
                            xLen=self.npix_x, yLen=self.npix_y, 
                            xLen=self.npix_x, yLen=self.npix_y, 
                            exTime=self.flat_exptime, 
                            exTime=self.flat_exptime+0.5*self.readout_time, 
                            cr_pixelRatio=0.003*self.flat_exptime/self.exptime, 
                            cr_pixelRatio=0.003*(self.flat_exptime+0.5*self.readout_time)/(self.exptime+0.5*self.readout_time), 
                            gain=self.gain, 
                            gain=self.gain, 
                            attachedSizes=self.attachedSizes,
                            attachedSizes=self.attachedSizes,
                            seed=SeedCosmicRay+pointing_ID*30+self.chipID+3)
                            seed=SeedCosmicRay+pointing_ID*30+self.chipID+3)
@@ -544,19 +554,35 @@ class Chip(FocalPlane):


                if config["non_linear"].lower() == "y":
                if config["non_linear"].lower() == "y":
                    print("  Applying Non-Linearity on the Flat image", flush=True)
                    print("  Applying Non-Linearity on the Flat image", flush=True)
                    FlatCombImg = effects.NonLinearity(GSImage=FlatCombImg, beta1=1.e-7, beta2=1.e-10)
                    FlatCombImg = effects.NonLinearity(GSImage=FlatCombImg, beta1=5.e-7, beta2=0)


                if config["cte_trail"].lower() == "y":
                if config["cte_trail"].lower() == "y":
                    FlatCombImg = effects.CTE_Effect(GSImage=FlatCombImg, threshold=3)
                    FlatCombImg = effects.CTE_Effect(GSImage=FlatCombImg, threshold=3)


                # Add Hot Pixels or/and Dead Pixels
                rgbadpix = Generator(PCG64(int(SeedDefective+self.chipID)))
                badfraction = 5E-5*(rgbadpix.random()*0.5+0.7)
                FlatCombImg = effects.DefectivePixels(FlatCombImg, IfHotPix=BoolHotPix, IfDeadPix=BoolDeadPix, fraction=badfraction, seed=SeedDefective+self.chipID, biaslevel=0)

                # Apply Bad lines 
                # Apply Bad lines 
                if config["add_badcolumns"].lower() == "y":
                if config["add_badcolumns"].lower() == "y":
                    FlatCombImg = effects.BadColumns(FlatCombImg, seed=SeedBadColumns, chipid=self.chipID)
                    FlatCombImg = effects.BadColumns(FlatCombImg, seed=SeedBadColumns, chipid=self.chipID)


                # Add Hot Pixels or/and Dead Pixels
                # Add Bias level
                rgbadpix = Generator(PCG64(int(SeedDefective+self.chipID)))
                if config["add_bias"].lower() == "y":
                badfraction = 5E-5*(rgbadpix.random()*0.5+0.7)
                    print("  Adding Bias level and 16-channel non-uniformity")
                FlatCombImg = effects.DefectivePixels(FlatCombImg, IfHotPix=BoolHotPix, IfDeadPix=BoolDeadPix, fraction=badfraction, seed=SeedDefective+self.chipID, biaslevel=self.bias_level)
                    # img += float(config["bias_level"])
                    FlatCombImg = effects.AddBiasNonUniform16(FlatCombImg, 
                        bias_level=biaslevel, 
                        nsecy = 2, nsecx=8, 
                        seed=SeedBiasNonuni+self.chipID)
                
                # Add Read-out Noise
                if config["add_readout"].lower() == "y":
                    seed = int(config["seed_readout"]) + pointing_ID*30 + self.chipID
                    rng_readout = galsim.BaseDeviate(seed)
                    readout_noise = galsim.GaussianNoise(rng=rng_readout, sigma=self.read_noise)
                    FlatCombImg.addNoise(readout_noise)


                FlatCombImg = effects.ApplyGainNonUniform16(FlatCombImg, gain=self.gain, 
                FlatCombImg = effects.ApplyGainNonUniform16(FlatCombImg, gain=self.gain, 
                    nsecy = 2, nsecx=8, 
                    nsecy = 2, nsecx=8, 
@@ -569,7 +595,7 @@ class Chip(FocalPlane):
                datetime_obs = datetime.fromtimestamp(timestamp_obs)
                datetime_obs = datetime.fromtimestamp(timestamp_obs)
                date_obs = datetime_obs.strftime("%y%m%d")
                date_obs = datetime_obs.strftime("%y%m%d")
                time_obs = datetime_obs.strftime("%H%M%S")
                time_obs = datetime_obs.strftime("%H%M%S")
                timestamp_obs += 5 * 60
                timestamp_obs += 10 * 60
                self.outputCal(
                self.outputCal(
                    img=FlatCombImg,
                    img=FlatCombImg,
                    ra_cen=ra_cen,
                    ra_cen=ra_cen,
@@ -601,15 +627,15 @@ class Chip(FocalPlane):
            for i in range(NDark):
            for i in range(NDark):
                DarkCombImg, DarkTag = effects.MakeDarkNcomb(
                DarkCombImg, DarkTag = effects.MakeDarkNcomb(
                    self.npix_x, self.npix_y, 
                    self.npix_x, self.npix_y, 
                    overscan=overscan, bias_level=biaslevel, darkpsec=0.02, exptime=self.dark_exptime,
                    overscan=overscan, bias_level=0, darkpsec=0.02, exptime=self.dark_exptime+0.5*self.readout_time,
                    ncombine=1, read_noise=self.read_noise, 
                    ncombine=1, read_noise=self.read_noise, 
                    gain=1, seed_bias=SeedBiasNonuni+self.chipID)
                    gain=1, seed_bias=SeedBiasNonuni+self.chipID)
                if config["cosmic_ray"].lower() == "y":
                if config["cosmic_ray"].lower() == "y":
                    if config["cray_differ"].lower() == "y":
                    if config["cray_differ"].lower() == "y":
                        cr_map = effects.produceCR_Map(
                        cr_map = effects.produceCR_Map(
                            xLen=self.npix_x, yLen=self.npix_y, 
                            xLen=self.npix_x, yLen=self.npix_y, 
                            exTime=self.dark_exptime, 
                            exTime=self.dark_exptime+0.5*self.readout_time, 
                            cr_pixelRatio=0.003*self.dark_exptime/self.exptime, 
                            cr_pixelRatio=0.003*(self.dark_exptime+0.5*self.readout_time)/(self.exptime+0.5*self.readout_time), 
                            gain=self.gain, 
                            gain=self.gain, 
                            attachedSizes=self.attachedSizes,
                            attachedSizes=self.attachedSizes,
                            seed=SeedCosmicRay+pointing_ID*30+self.chipID+2)
                            seed=SeedCosmicRay+pointing_ID*30+self.chipID+2)
@@ -638,19 +664,35 @@ class Chip(FocalPlane):
                # Non-Linearity for Dark
                # Non-Linearity for Dark
                if config["non_linear"].lower() == "y":
                if config["non_linear"].lower() == "y":
                    print("  Applying Non-Linearity on the Dark image", flush=True)
                    print("  Applying Non-Linearity on the Dark image", flush=True)
                    DarkCombImg = effects.NonLinearity(GSImage=DarkCombImg, beta1=1.e-7, beta2=1.e-10)
                    DarkCombImg = effects.NonLinearity(GSImage=DarkCombImg, beta1=5.e-7, beta2=0)


                if config["cte_trail"].lower() == "y":
                if config["cte_trail"].lower() == "y":
                    DarkCombImg = effects.CTE_Effect(GSImage=DarkCombImg, threshold=3)
                    DarkCombImg = effects.CTE_Effect(GSImage=DarkCombImg, threshold=3)


                # Add Hot Pixels or/and Dead Pixels
                rgbadpix = Generator(PCG64(int(SeedDefective+self.chipID)))
                badfraction = 5E-5*(rgbadpix.random()*0.5+0.7)
                DarkCombImg = effects.DefectivePixels(DarkCombImg, IfHotPix=BoolHotPix, IfDeadPix=BoolDeadPix, fraction=badfraction, seed=SeedDefective+self.chipID, biaslevel=0)

                # Apply Bad lines 
                # Apply Bad lines 
                if config["add_badcolumns"].lower() == "y":
                if config["add_badcolumns"].lower() == "y":
                    DarkCombImg = effects.BadColumns(DarkCombImg, seed=SeedBadColumns, chipid=self.chipID)
                    DarkCombImg = effects.BadColumns(DarkCombImg, seed=SeedBadColumns, chipid=self.chipID)


                # Add Hot Pixels or/and Dead Pixels
                # Add Bias level
                rgbadpix = Generator(PCG64(int(SeedDefective+self.chipID)))
                if config["add_bias"].lower() == "y":
                badfraction = 5E-5*(rgbadpix.random()*0.5+0.7)
                    print("  Adding Bias level and 16-channel non-uniformity")
                DarkCombImg = effects.DefectivePixels(DarkCombImg, IfHotPix=BoolHotPix, IfDeadPix=BoolDeadPix, fraction=badfraction, seed=SeedDefective+self.chipID, biaslevel=self.bias_level)
                    # img += float(config["bias_level"])
                    DarkCombImg = effects.AddBiasNonUniform16(DarkCombImg, 
                        bias_level=biaslevel, 
                        nsecy = 2, nsecx=8, 
                        seed=SeedBiasNonuni+self.chipID)

                # Add Read-out Noise
                if config["add_readout"].lower() == "y":
                    seed = int(config["seed_readout"]) + pointing_ID*30 + self.chipID
                    rng_readout = galsim.BaseDeviate(seed)
                    readout_noise = galsim.GaussianNoise(rng=rng_readout, sigma=self.read_noise)
                    DarkCombImg.addNoise(readout_noise)


                DarkCombImg = effects.ApplyGainNonUniform16(
                DarkCombImg = effects.ApplyGainNonUniform16(
                    DarkCombImg, gain=self.gain, 
                    DarkCombImg, gain=self.gain, 
@@ -667,7 +709,7 @@ class Chip(FocalPlane):
                datetime_obs = datetime.fromtimestamp(timestamp_obs)
                datetime_obs = datetime.fromtimestamp(timestamp_obs)
                date_obs = datetime_obs.strftime("%y%m%d")
                date_obs = datetime_obs.strftime("%y%m%d")
                time_obs = datetime_obs.strftime("%H%M%S")
                time_obs = datetime_obs.strftime("%H%M%S")
                timestamp_obs += 5 * 60
                timestamp_obs += 10 * 60
                self.outputCal(
                self.outputCal(
                    img=DarkCombImg,
                    img=DarkCombImg,
                    ra_cen=ra_cen,
                    ra_cen=ra_cen,
@@ -680,41 +722,6 @@ class Chip(FocalPlane):
                    output_dir=chip_output.subdir,
                    output_dir=chip_output.subdir,
                    exptime=self.dark_exptime)
                    exptime=self.dark_exptime)
            del DarkCombImg
            del DarkCombImg

        # Apply Nonlinearity on the chip image
        if config["non_linear"].lower() == "y":
            print("  Applying Non-Linearity on the chip image", flush=True)
            img = effects.NonLinearity(GSImage=img, beta1=1.e-7, beta2=1.e-10)

        # Apply CCD Saturation & Blooming
        if config["saturbloom"].lower() == "y":
            print("  Applying CCD Saturation & Blooming")
            img = effects.SaturBloom(GSImage=img, nsect_x=1, nsect_y=1, fullwell=fullwell)

        # Apply CTE Effect
        if config["cte_trail"].lower() == "y":
            print("  Apply CTE Effect")
            img = effects.CTE_Effect(GSImage=img, threshold=27)

        # Apply Bad lines 
        if config["add_badcolumns"].lower() == "y":
            img = effects.BadColumns(img, seed=SeedBadColumns, chipid=self.chipID)

        # Add Hot Pixels or/and Dead Pixels
        rgbadpix = Generator(PCG64(int(SeedDefective+self.chipID)))
        badfraction = 5E-5*(rgbadpix.random()*0.5+0.7)
        img = effects.DefectivePixels(img, IfHotPix=BoolHotPix, IfDeadPix=BoolDeadPix, fraction=badfraction, seed=SeedDefective+self.chipID, biaslevel=self.bias_level)
        

        # Apply Gain & Quantization
        print("  Applying Gain (and 16 channel non-uniformity) & Quantization", flush=True)
        img = effects.ApplyGainNonUniform16(
            img, gain=self.gain, 
            nsecy = 2, nsecx=8, 
            seed=SeedGainNonuni+self.chipID)
        img.array[img.array > 65535] = 65535
        img.replaceNegative(replace_value=0)
        img.quantize()
        # img = galsim.ImageUS(img)
        # img = galsim.ImageUS(img)


        # # 16 output channel, with each a single image file
        # # 16 output channel, with each a single image file
Loading