Commit 4afd1181 authored by Fang Yuedong's avatar Fang Yuedong
Browse files

add renamed files

parent 4c9c940a
import os
import galsim
import ctypes
import numpy as np
from astropy.io import fits
from datetime import datetime
from observation_sim.instruments.chip import effects
from observation_sim.config.header import generatePrimaryHeader, generateExtensionHeader
try:
import importlib.resources as pkg_resources
except ImportError:
# Try backported to PY<37 'importlib_resources'
import importlib_resources as pkg_resources
def log_info(msg, logger=None):
if logger:
logger.info(msg)
else:
print(msg, flush=True)
def getChipSLSGratingID(chipID):
gratingID = ['', '']
if chipID == 1:
gratingID = ['GI2', 'GI1']
if chipID == 2:
gratingID = ['GV4', 'GV3']
if chipID == 3:
gratingID = ['GU2', 'GU1']
if chipID == 4:
gratingID = ['GU4', 'GU3']
if chipID == 5:
gratingID = ['GV2', 'GV1']
if chipID == 10:
gratingID = ['GI4', 'GI3']
if chipID == 21:
gratingID = ['GI6', 'GI5']
if chipID == 26:
gratingID = ['GV8', 'GV7']
if chipID == 27:
gratingID = ['GU6', 'GU5']
if chipID == 28:
gratingID = ['GU8', 'GU7']
if chipID == 29:
gratingID = ['GV6', 'GV5']
if chipID == 30:
gratingID = ['GI8', 'GI7']
return gratingID
def getChipSLSConf(chipID):
confFile = ''
if chipID == 1:
confFile = ['CSST_GI2.conf', 'CSST_GI1.conf']
if chipID == 2:
confFile = ['CSST_GV4.conf', 'CSST_GV3.conf']
if chipID == 3:
confFile = ['CSST_GU2.conf', 'CSST_GU1.conf']
if chipID == 4:
confFile = ['CSST_GU4.conf', 'CSST_GU3.conf']
if chipID == 5:
confFile = ['CSST_GV2.conf', 'CSST_GV1.conf']
if chipID == 10:
confFile = ['CSST_GI4.conf', 'CSST_GI3.conf']
if chipID == 21:
confFile = ['CSST_GI6.conf', 'CSST_GI5.conf']
if chipID == 26:
confFile = ['CSST_GV8.conf', 'CSST_GV7.conf']
if chipID == 27:
confFile = ['CSST_GU6.conf', 'CSST_GU5.conf']
if chipID == 28:
confFile = ['CSST_GU8.conf', 'CSST_GU7.conf']
if chipID == 29:
confFile = ['CSST_GV6.conf', 'CSST_GV5.conf']
if chipID == 30:
confFile = ['CSST_GI8.conf', 'CSST_GI7.conf']
return confFile
def generateHeader(chip, pointing, img_type=None, img_type_code=None, project_cycle='9', run_counter='1'):
if (img_type is None) or (img_type_code is None):
img_type = pointing.pointing_type
img_type_code = pointing.pointing_type_code
h_prim = generatePrimaryHeader(
xlen=chip.npix_x,
ylen=chip.npix_y,
pointing_id=pointing.obs_id,
pointing_type_code=img_type_code,
ra=pointing.ra,
dec=pointing.dec,
pixel_scale=chip.pix_scale,
time_pt=pointing.timestamp,
exptime=pointing.exp_time,
im_type=img_type,
sat_pos=[pointing.sat_x, pointing.sat_y, pointing.sat_z],
sat_vel=[pointing.sat_vx, pointing.sat_vy, pointing.sat_vz],
project_cycle=project_cycle,
run_counter=run_counter,
chip_name=str(chip.chipID).rjust(2, '0'))
h_ext = generateExtensionHeader(
chip=chip,
xlen=chip.npix_x,
ylen=chip.npix_y,
ra=pointing.ra,
dec=pointing.dec,
pa=pointing.img_pa.deg,
gain=chip.gain,
readout=chip.read_noise,
dark=chip.dark_noise,
saturation=90000,
pixel_scale=chip.pix_scale,
pixel_size=chip.pix_size,
xcen=chip.x_cen,
ycen=chip.y_cen,
extName=img_type,
timestamp=pointing.timestamp,
exptime=pointing.exp_time,
readoutTime=chip.readout_time,
t_shutter_open=pointing.t_shutter_open,
t_shutter_close=pointing.t_shutter_close)
return h_prim, h_ext
def output_fits_image(chip, pointing, img, output_dir, img_type=None, img_type_code=None, project_cycle='9', run_counter='1'):
h_prim, h_ext = generateHeader(
chip=chip,
pointing=pointing,
img_type=img_type,
img_type_code=img_type_code,
project_cycle=project_cycle,
run_counter=run_counter)
hdu1 = fits.PrimaryHDU(header=h_prim)
hdu1.add_checksum()
hdu1.header.comments['CHECKSUM'] = 'HDU checksum'
hdu1.header.comments['DATASUM'] = 'data unit checksum'
hdu2 = fits.ImageHDU(img.array, header=h_ext)
hdu2.add_checksum()
hdu2.header.comments['XTENSION'] = 'extension type'
hdu2.header.comments['CHECKSUM'] = 'HDU checksum'
hdu2.header.comments['DATASUM'] = 'data unit checksum'
hdu1 = fits.HDUList([hdu1, hdu2])
fname = os.path.join(output_dir, h_prim['FILENAME']+'.fits')
hdu1.writeto(fname, output_verify='ignore', overwrite=True)
def add_sky_background(img, filt, exptime, sky_map=None, tel=None):
# Add sky background
if sky_map is None:
sky_map = filt.getSkyNoise(exptime=exptime)
sky_map = sky_map * np.ones_like(img.array)
sky_map = galsim.Image(array=sky_map)
# Apply Poisson noise to the sky map
# # (NOTE): only for photometric chips if it utilizes the photon shooting to draw stamps
# if self.survey_type == "photometric":
# sky_map.addNoise(poisson_noise)
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 * exptime
img += sky_map
return img, sky_map
def get_flat(img, seed):
flat_img = effects.MakeFlatSmooth(
GSBounds=img.bounds,
seed=seed)
flat_normal = flat_img / np.mean(flat_img.array)
return flat_img, flat_normal
def add_cosmic_rays(img, chip, exptime=150, seed=0):
cr_map, cr_event_num = effects.produceCR_Map(
xLen=chip.npix_x, yLen=chip.npix_y,
exTime=exptime+0.5*chip.readout_time,
cr_pixelRatio=0.003*(exptime+0.5*chip.readout_time)/600.,
gain=chip.gain,
attachedSizes=chip.attachedSizes,
seed=seed) # seed: obj-imaging:+0; bias:+1; dark:+2; flat:+3;
img += cr_map
cr_map[cr_map > 65535] = 65535
cr_map[cr_map < 0] = 0
crmap_gsimg = galsim.Image(cr_map, dtype=np.uint16)
del cr_map
return img, crmap_gsimg, cr_event_num
def add_PRNU(img, chip, seed=0):
prnu_img = effects.PRNU_Img(
xsize=chip.npix_x,
ysize=chip.npix_y,
sigma=0.01,
seed=seed)
img *= prnu_img
return img, prnu_img
def get_poisson(seed=0, sky_level=0.):
rng_poisson = galsim.BaseDeviate(seed)
poisson_noise = galsim.PoissonNoise(rng_poisson, sky_level=sky_level)
return rng_poisson, poisson_noise
def get_base_img(img, chip, read_noise, readout_time, dark_noise, exptime=150., InputDark=None):
if InputDark == 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)
base_img1 = base_level * np.ones_like(img.array)
else:
base_img1 = np.zeros_like(img.array)
ny = int(chip.npix_y/2)
nx = chip.npix_x
arr = np.arange(ny).reshape(ny, 1)
arr = np.broadcast_to(arr, (ny, nx))
base_img2 = np.zeros_like(img.array)
base_img2[:ny, :] = arr
base_img2[ny:, :] = arr[::-1, :]
base_img2[:, :] = base_img2[:, :]*(readout_time/ny)*dark_noise
return base_img1+base_img2
def add_poisson(img, chip, exptime=150., seed=0, sky_level=0., poisson_noise=None, dark_noise=None, InputDark=None):
if poisson_noise is None:
_, poisson_noise = get_poisson(seed=seed, sky_level=sky_level)
read_noise = chip.read_noise
if dark_noise is None:
dark_noise = chip.dark_noise
base_img = get_base_img(img=img, chip=chip, read_noise=read_noise, readout_time=chip.readout_time,
dark_noise=dark_noise, exptime=exptime, InputDark=InputDark)
img += base_img
img.addNoise(poisson_noise)
# img -= read_noise**2
if InputDark != None:
# "Instrument/data/dark/dark_1000s_example_0.fits"
hdu = fits.open(InputDark)
img += hdu[0].data/hdu[0].header['exptime']*exptime
hdu.close()
return img, base_img
def add_brighter_fatter(img):
# Inital dynamic lib
try:
with pkg_resources.files('observation_sim.instruments.chip.libBF').joinpath("libmoduleBF.so") as lib_path:
lib_bf = ctypes.CDLL(lib_path)
except AttributeError:
with pkg_resources.path('observation_sim.instruments.chip.libBF', "libmoduleBF.so") as lib_path:
lib_bf = ctypes.CDLL(lib_path)
lib_bf.addEffects.argtypes = [ctypes.c_int, ctypes.c_int, ctypes.POINTER(
ctypes.c_float), ctypes.POINTER(ctypes.c_float), ctypes.c_int]
# Set bit flag
bit_flag = 1
bit_flag = bit_flag | (1 << 2)
nx, ny = img.array.shape
nn = nx * ny
arr_ima = (ctypes.c_float*nn)()
arr_imc = (ctypes.c_float*nn)()
arr_ima[:] = img.array.reshape(nn)
arr_imc[:] = np.zeros(nn)
lib_bf.addEffects(nx, ny, arr_ima, arr_imc, bit_flag)
img.array[:, :] = np.reshape(arr_imc, [nx, ny])
del arr_ima, arr_imc
return img
"""
def add_inputdark(img, chip, exptime):
fname = "/share/home/weichengliang/CSST_git/test_new_sim/csst-simulation/ObservationSim/Instrument/data/dark/dark_1000s_example_0.fits"
hdu = fits.open(fname)
#ny, nx = img.array.shape
#inputdark = np.zeros([ny, nx])
img.array[:, :] += hdu[0].data/hdu[0].header['exptime']*exptime
hdu.close()
del inputdark
return img
"""
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)])
for iy in range(nsecy):
for ix in range(nsecx):
if iy % 2 == 0:
tx = ix
else:
tx = (nsecx-1)-ix
ty = iy
# 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)
imgtemp = np.zeros(
[int(ny/nsecy+pre2+over2), int(nx/nsecx+pre1+over1)])
if int(chunkidx/4) == 0:
imgtemp[pre2:pre2+dy, pre1:pre1 +
dx] = img[iy*dy:(iy+1)*dy, ix*dx:(ix+1)*dx]
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]
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]
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, :]
# hstack chunk(1,2)-[1,2,3,4,5,6,7,8]
imgtx1 = np.hstack(imgt[:nsecx:, :, :])
# hstack chunk(4,3)-[16,15,14,13,12,11,,10,9]
imgtx2 = np.hstack(imgt[:(nsecx-1):-1, :, :])
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.wcs = GSImage.wcs
return newimg
def AddPreScanFO(GSImage, pre1=27, pre2=4, over1=71, over2=80, nsecy=1, nsecx=16):
img = GSImage.array
ny, nx = img.shape
dx = int(nx/nsecx)
dy = int(ny/nsecy)
newimg = galsim.Image(int(nx+(pre1+over1)*nsecx),
int(ny+(pre2+over2)*nsecy), init_value=0)
for ix in range(nsecx):
newimg.array[pre2:pre2+dy, pre1+ix *
(dx+pre1+over1):pre1+dx+ix*(dx+pre1+over1)] = img[0:dy, 0+ix*dx:dx+ix*dx]
newimg.wcs = GSImage.wcs
return newimg
def formatOutput(GSImage, nsecy=2, nsecx=8):
img = GSImage.array
ny, nx = img.shape
dx = int(nx/nsecx)
dy = int(ny/nsecy)
imgt = np.zeros([int(nsecx*nsecy), dy, dx])
for iy in range(nsecy):
for ix in range(nsecx):
if iy % 2 == 0:
tx = ix
else:
tx = (nsecx-1)-ix
ty = iy
chunkidx = int(tx+ty*nsecx)
if int(chunkidx/4) == 0:
imgt[chunkidx, :, :] = img[iy*dy:(iy+1)*dy, ix*dx:(ix+1)*dx]
if int(chunkidx/4) == 1:
imgt[chunkidx, :, :] = img[iy*dy:(iy+1)*dy, ix*dx:(ix+1)*dx]
if int(chunkidx/4) == 2:
imgt[chunkidx, :, :] = img[iy*dy:(iy+1)*dy, ix*dx:(ix+1)*dx]
if int(chunkidx/4) == 3:
imgt[chunkidx, :, :] = img[iy*dy:(iy+1)*dy, ix*dx:(ix+1)*dx]
imgttx0 = np.hstack(imgt[0:4:, :, :])
imgttx1 = np.hstack(imgt[4:8:, :, ::-1])
imgttx2 = np.hstack(imgt[8:12:, ::-1, ::-1])
imgttx3 = np.hstack(imgt[12:16:, ::-1, :])
newimg = galsim.Image(int(dx*nsecx*nsecy), dy, init_value=0)
newimg.array[:, :] = np.hstack([imgttx0, imgttx1, imgttx2, imgttx3])
return newimg
def formatRevert(GSImage, nsecy=1, nsecx=16):
img = GSImage.array
ny, nx = img.shape
dx = int(nx/nsecx)
dy = int(ny/nsecy)
newimg = galsim.Image(int(dx*8), int(dy*2), init_value=0)
for ix in range(0, 4):
tx = ix
newimg.array[0:dy, 0+tx*dx:dx+tx*dx] = img[:, 0+ix*dx:dx+ix*dx]
for ix in range(4, 8):
tx = ix
newimg.array[0:dy, 0+tx*dx:dx+tx *
dx] = img[:, 0+ix*dx:dx+ix*dx][:, ::-1]
for ix in range(8, 12):
tx = 7-(ix-8)
newimg.array[0+dy:dy+dy, 0+tx*dx:dx+tx *
dx] = img[:, 0+ix*dx:dx+ix*dx][::-1, ::-1]
for ix in range(12, 16):
tx = 7-(ix-8)
newimg.array[0+dy:dy+dy, 0+tx*dx:dx+tx *
dx] = img[:, 0+ix*dx:dx+ix*dx][::-1, :]
return newimg
import galsim
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
from numba import jit
from astropy import stats
def AddOverscan(GSImage, overscan=1000, gain=1, widthl=27, widthr=27, widtht=8, widthb=8, read_noise=5):
"""
Add overscan/gain; gain=e-/ADU
widthl: left pre-scan width
widthr: right pre-scan width
widtht: top over-scan width (the top of nd-array with small row-index)
widthb: bottom over-scan width (the bottom of nd-array with large row-index)
"""
imgshape = GSImage.array.shape
newimg = galsim.Image(imgshape[1]+widthl+widthr, imgshape[0]+widtht+widthb, init_value=0)
rng = galsim.UniformDeviate()
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.wcs = GSImage.wcs
# if GSImage.wcs is not None:
# newwcs = GSImage.wcs.withOrigin(galsim.PositionD(widthl,widtht))
# newimg.wcs = newwcs
# else:
# pass
return newimg
def DefectivePixels(GSImage, IfHotPix=True, IfDeadPix=True, fraction=1E-4, seed=20210304, biaslevel=0):
# Also called bad pixels, including hot pixels and dead pixels
# Hot Pixel > 20e-/s
# Dead Pixel < 70%*Mean
rgf = Generator(PCG64(int(seed*1.1)))
if IfHotPix==True and IfDeadPix==True:
HotFraction = rgf.random() # fraction in total bad pixels
elif IfHotPix==False and IfDeadPix==False:
return GSImage
elif IfHotPix==True:
HotFraction = 1
else:
HotFraction = 0
NPix = GSImage.array.size
NPixBad = int(NPix*fraction)
NPixHot = int(NPix*fraction*HotFraction)
NPixDead = NPixBad-NPixHot
NPix_y,NPix_x = GSImage.array.shape
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)
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
return GSImage
def BadColumns(GSImage, seed=20240309, chipid=1, logger=None):
# Set bad column values
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)
stdimg = np.std(subarr)
seed += chipid
rgn = Generator(PCG64(int(seed)))
rgcollen = Generator(PCG64(int(seed*1.1)))
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))
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)
else:
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
# 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])
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])
return GSImage
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:
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)
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]
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)
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)
BiasCombImg = BiasSngImg*ncombine
rng = galsim.UniformDeviate()
NoiseBias = galsim.GaussianNoise(rng=rng, sigma=read_noise*ncombine**0.5)
BiasCombImg.addNoise(NoiseBias)
if ncombine == 1:
BiasTag = 'Single'
pass
elif ncombine >1:
BiasCombImg /= ncombine
BiasTag = 'Combine'
# BiasCombImg.replaceNegative(replace_value=0)
# BiasCombImg.quantize()
return BiasCombImg, BiasTag
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
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)
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]
return GSImage, gain_array
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
if logger is not None:
msg = str(seed-20210202, "Gains of 16 channels: " + str(Gain16))
logger.info(msg)
else:
print(seed-20210202, "Gains of 16 channels:\n", 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]
# return GSImage
return Gain16
def MakeFlatSmooth(GSBounds, seed):
rg = Generator(PCG64(int(seed)))
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()
Flty, Fltx = np.mgrid[ymin:(ymax+1), xmin:(xmax+1)]
rg = Generator(PCG64(int(seed)))
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)
FlatCombImg = flat_single_image*ncombine
rng = galsim.UniformDeviate()
NoiseFlatPoi = galsim.PoissonNoise(rng=rng, sky_level=0)
FlatCombImg.addNoise(NoiseFlatPoi)
NoiseFlatReadN = galsim.GaussianNoise(rng=rng, sigma=read_noise*ncombine**0.5)
FlatCombImg.addNoise(NoiseFlatReadN)
# 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,
seed=seed_bias,
logger=logger)
if ncombine == 1:
FlatTag = 'Single'
pass
elif ncombine >1:
FlatCombImg /= ncombine
FlatTag = 'Combine'
# FlatCombImg.replaceNegative(replace_value=0)
# FlatCombImg.quantize()
return FlatCombImg, FlatTag
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)
darkpix = darkpsec*exptime
DarkSngImg = galsim.Image(npix_x, npix_y, init_value=darkpix)
rng = galsim.UniformDeviate()
NoiseDarkPoi = galsim.PoissonNoise(rng=rng, sky_level=0)
NoiseReadN = galsim.GaussianNoise(rng=rng, sigma=read_noise*ncombine**0.5)
DarkCombImg = DarkSngImg*ncombine
DarkCombImg.addNoise(NoiseDarkPoi)
DarkCombImg.addNoise(NoiseReadN)
for i in range(ncombine):
DarkCombImg = AddBiasNonUniform16(
DarkCombImg,
bias_level=bias_level,
nsecy = 2, nsecx=8,
seed=int(seed_bias),
logger=logger)
if ncombine == 1:
DarkTag = 'Single'
pass
elif ncombine >1:
DarkCombImg /= ncombine
DarkTag = 'Combine'
# DarkCombImg.replaceNegative(replace_value=0)
# DarkCombImg.quantize()
return DarkCombImg, DarkTag
def PRNU_Img(xsize, ysize, sigma=0.01, seed=202101):
rg = Generator(PCG64(int(seed)))
prnuarr = rg.normal(1, sigma, (ysize,xsize))
prnuimg = galsim.ImageF(prnuarr)
return prnuimg
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
GSImage.applyNonlinearity(NonLinear_f, beta1, beta2)
return GSImage
######################################## Saturation & Bleeding Start ###############################
def BleedingTrail(aa, yy):
if aa<0.2:
aa=0.2
else:
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)
trail_frac = 1-0.1*(fy-1)/(faa-1)
except Exception as e:
print(e)
trail_frac = 1
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
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:
break
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
continue
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:
break
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)
# put charge upwards
if trail_frac>=0.99:
imgarr[yi,xi] = fullwell
if direction=='up':
yi-=1
elif direction=='down':
yi+=1
yy += 1
else:
if trail_frac<trailcutfrac:
break
charge = fullwell*trail_frac
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)
if satupos_y.shape[0]==0:
# make no change for the image array
return imgarr
elif satupos_y.shape[0]/imgarr.size > 0.5:
imgarr.fill(fullwell)
return imgarr
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)])
satcharge = chargedict[yxidx]
chargeup = ((np.random.random()-0.5)*0.05+0.5)*satcharge
chargedn = satcharge - chargeup
try:
# Charge Clump moves up
if 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))
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.
Work together with chargeflow() function.
Parameters:
GSImage: a GalSim Image of a chip;
nsect_x: number of sections divided along x direction;
nsect_y: number of sections divided along y direction.
Return: a saturated image array with the same size of input.
"""
imgarr = GSImage.array
size_y, size_x = imgarr.shape
subsize_y = int(size_y/nsect_y)
subsize_x = int(size_x/nsect_x)
for i in range(nsect_y):
for j in range(nsect_x):
subimg = imgarr[subsize_y*i:subsize_y*(i+1), subsize_x*j:subsize_x*(j+1)]
subimg = ChargeFlow(subimg, fullwell=fullwell)
imgarr[subsize_y*i:subsize_y*(i+1), subsize_x*j:subsize_x*(j+1)] = subimg
return GSImage
################################# Saturation & Bleeding End ####################################
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.
# 00 01
# 10 11
# 20 21
# ...
# return: GS Image Object
npix_y,npix_x = GSImage.array.shape
subheight = int(8+npix_y/2+8)
subwidth = int(16+npix_x/8+27)
OutputSubimg = galsim.ImageUS(subwidth, subheight, init_value=overscan_value)
if rowi<4 and coli==0:
subbounds = galsim.BoundsI(1, int(npix_x/2), int(npix_y/8*rowi+1), int(npix_y/8*(rowi+1)))
subbounds = subbounds.shift(galsim.PositionI(GSImage.bounds.getXMin()-1, GSImage.bounds.getYMin()-1))
subimg = GSImage[subbounds]
OutputSubimg.array[27:int(npix_y/8)+27,8:int(npix_x/2)+8] = subimg.array
elif rowi<4 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[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:
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
else:
print("\n\033[31mError: "+"Wrong rowi or coli assignment. Permitted: 0<=rowi<=7, 0<=coli<=1."+"\033[0m\n")
return OutputSubimg
return OutputSubimg
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_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)
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)
return GSImage
@jit()
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_b = -2.671933068990729
sh1 = img.shape[0]
sh2 = img.shape[1]
n_img = img*0
idx = np.where(img<threshold)
if len(idx[0]) == 0:
pass
elif len(idx[0])>0:
n_img[idx] = img[idx]
yidx,xidx = np.where(img>=threshold)
if len(yidx) == 0:
pass
elif len(yidx)>0:
# print(index)
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)
# 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
# t_pow = 0
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:
t_pow = 0
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):
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:
break
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:
break
n_img[i,x_pos] = n_img[i,x_pos] + all_trail[m]
return n_img
#---------- For Cosmic-Ray Simulation ------------
#---------- Zhang Xin ----------------------------
def getYValue(collection, x):
index = 0;
if (collection.shape[1] == 2):
while(x>collection[index,0] and index < collection.shape[0]):
index= index + 1;
if (index == collection.shape[0] or index == 0):
return 0;
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;
def selectCosmicRayCollection(attachedSizes, xLen, yLen,cr_pixelRatio,CR_max_size):
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;
maxValue = max(attachedSizes[:,1])
maxValue += 0.1;
cr_event_num = 0;
CRs = np.zeros(pixelNum);
while (CRPixelNum < pixelNum):
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);
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);
return CRs[0:cr_event_num];
def defineEnergyForCR(cr_event_size,seed = 12345):
import random
sigma = 0.6 / 2.355;
mean = 3.3;
random.seed(seed)
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);
return energys;
def convCR(CRmap=None, addPSF=None, sp_n = 4):
sh = CRmap.shape
# sp_n = 4
subCRmap = np.zeros(np.array(sh)*sp_n)
pix_v0 = 1/(sp_n*sp_n)
for i in np.arange(sh[0]):
i_st = sp_n*i
for j in np.arange(sh[1]):
if CRmap[i,j] ==0:
continue
j_st = sp_n*j
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
m_size = addPSF.shape[0]
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:
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
for i in np.arange(sh_n[0]):
i_st = sp_n*i
for j in np.arange(sh_n[1]):
p_v = 0
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]
CRmap_n[i,j] = p_v
return CRmap_n
def produceCR_Map(xLen, yLen, exTime, cr_pixelRatio, gain, attachedSizes, seed=20210317):
# 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_event_size = cr_size.shape[0];
cr_energys = defineEnergyForCR(cr_event_size,seed = seed);
CRmap = np.zeros([yLen, xLen]);
## produce conv kernel
from astropy.modeling.models import Gaussian2D
o_size = 4
sp_n = 8
m_size = o_size*sp_n+1
m_cen = o_size*sp_n/2
sigma_psf = 0.2*sp_n
addPSF_ = Gaussian2D(1, m_cen, m_cen, sigma_psf, sigma_psf)
yp, xp = np.mgrid[0:m_size, 0:m_size]
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();
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);
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:
continue;
crMatrix[y_n,x_n] = pix_energy;
crMatrix_n = convCR(crMatrix, convKernel, sp_n)
# crMatrix_n = crMatrix
xpix = np.arange(crMatrix_n.shape[0]) + int(xPos)
ypix = np.arange(crMatrix_n.shape[1]) + int(yPos)
sh = CRmap.shape
okx = (xpix >= 0) & (xpix < sh[1])
oky = (ypix >= 0) & (ypix < sh[0])
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]
return CRmap.astype(np.int32), cr_event_size
def ShutterEffectArr(GSImage, t_exp=150, t_shutter=1.3, dist_bearing=735, dt=1E-3):
# Generate Shutter-Effect normalized image
# t_shutter: time of shutter movement
# dist_bearing: distance between two bearings of shutter leaves
# dt: delta_t of sampling
from scipy import interpolate
SampleNumb = int(t_shutter/dt+1)
DistHalf = dist_bearing/2
t = np.arange(SampleNumb)*dt
a_arr = 5.84*np.sin(2*math.pi/t_shutter*t)
v = np.zeros(SampleNumb)
theta = np.zeros(SampleNumb)
x = np.arange(SampleNumb)/(SampleNumb-1)*dist_bearing
s = np.zeros(SampleNumb)
s1 = np.zeros(SampleNumb)
s2 = np.zeros(SampleNumb)
brt = np.zeros(SampleNumb)
idx = np.arange(SampleNumb)
sidx = np.zeros(SampleNumb)
s1idx = np.zeros(SampleNumb)
s2idx = np.zeros(SampleNumb)
v[0] = 0
theta[0] = 0
for i in range(SampleNumb-1):
v[i+1] = v[i]+a_arr[i]*dt
theta[i+1] = theta[i]+v[i]*dt
s1[i] = DistHalf*np.cos(theta[i])
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<s2idx[i])] += dt
if t_exp>t_shutter*2:
brt = brt*2+(t_exp-t_shutter*2)
else:
brt = brt*2
x = (x-dist_bearing/2)*100
intp = interpolate.splrep(x, brt, s=0)
xmin = GSImage.bounds.getXMin()
xmax = GSImage.bounds.getXMax()
ymin = GSImage.bounds.getYMin()
ymax = GSImage.bounds.getYMax()
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:
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 /= np.max(expeffect)
exparrnormal = np.tile(expeffect, (sizey,1))
# GSImage *= exparrnormal
return exparrnormal
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "nrutil.h"
#define ISSETBITFLAG(x,b) ((x) & (1 << (b)))
#define ADD_DIFFUSION 1
#define ADD_BF_FILTER 2
float linearInterp(float xp, float x0, float y0, float x1, float y1);
void addEffects(int ngx_ima, int ngy_ima, float *arr_ima, float *arr_imc, int bit_flag)
{
int nx, ny, i,j,k,ks;
int it,jt,itt,jtt;
int diffuidx[26][2],diffuN,ilow,ih,im,dim[3];
float diffua[5][5],cdiffu[26],**bfa;
double mvar,mcov,tmp,ma,mb,mc;
char fname[100];
nx = ngx_ima; //input-image size
ny = ngy_ima;
//0. init. original image with an input array (arr_ima)
//1. Adding diffusion effect.
if(ISSETBITFLAG(bit_flag, ADD_DIFFUSION))
{
printf("adding diffusion.....\n");
printf("ERR: no diffusion filter ...");
exit(0);
}
//2. Adding BF effect
if(ISSETBITFLAG(bit_flag, ADD_BF_FILTER))
{
printf("Adding BF effect...\n");
//setup BF correlation fliter
float neX;
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;
float bfaP2[9]={0.9945288, 0.0003041936, 0.0007539311, 0.0002424675, 0.0001226098, 0.00009308617, 0.00008027447, 0.00006309676, 0.00006400052};
bfa=matrix(-2,2,-2,2);
// smooth with the BF filter
for(i=0;i<nx;i++)for(j=0;j<ny;j++) arr_imc[j+i*ny]=0;
for(i=0;i<nx;i++)
{
for(j=0;j<ny;j++)
{
//rescale BF filter with the local pix value
neX = arr_ima[j+i*ny];
if(neX >= 10000)
{
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;
}
else
{
neX=10000;
bfa[0][0]=0;
bfa[0][1]=bfa[0][-1]=bfaP2[1];
bfa[-1][0]=bfa[1][0]=bfaP2[2];
bfa[-1][-1]=bfa[1][1]=bfa[-1][1]=bfa[1][-1]=bfaP2[3];
bfa[0][-2]=bfa[0][2]=bfaP2[4];
bfa[-2][0]=bfa[2][0]=bfaP2[5];
bfa[-2][-1]=bfa[-2][1]=bfa[2][1]=bfa[2][-1]=bfaP2[6];
bfa[-1][-2]=bfa[1][2]=bfa[-1][2]=bfa[1][-2]=bfaP2[7];
bfa[-2][-2]=bfa[-2][2]=bfa[2][-2]=bfa[2][2]=bfaP2[8];
}
tmp = 0;
for(it=-2;it<=2;it++)
for(jt=-2;jt<=2;jt++)
{
bfa[it][jt] = bfa[it][jt]/neX*arr_ima[j+i*ny];
tmp += bfa[it][jt];
}
bfa[0][0]=1.-tmp;
// assign electrons according to the BF filter bfat
for(it=-2;it<=2;it++)
{
for(jt=-2;jt<=2;jt++)
{
itt=i+it;
jtt=j+jt;
if(itt>=0 && jtt>=0 && itt<nx && jtt<ny)
//c0[itt][jtt]+=bfa[it][jt]*b[i][j];
arr_imc[jtt+itt*ny] += bfa[it][jt]*arr_ima[j+i*ny];
}
}
}
}
free_matrix(bfa,-2,2,-2,2);
}
else
{
for(i=0;i<nx;i++) for(j=0;j<ny;j++) arr_imc[j+i*ny]=arr_ima[j+i*ny]; ////for ADD_BF False
}
}
float linearInterp(float xp, float x0, float y0, float x1, float y1)
{
float yp;
yp = y0 + ((y1-y0)/(x1-x0)) * (xp - x0);
return yp;
}
#if defined(__STDC__) || defined(ANSI) || defined(NRANSI) /* ANSI */
#include <stdio.h>
#include <stddef.h>
#include <stdlib.h>
#define NR_END 1
#define FREE_ARG char*
void nrerror(char error_text[])
/* Numerical Recipes standard error handler */
{
fprintf(stderr,"Numerical Recipes run-time error...\n");
fprintf(stderr,"%s\n",error_text);
fprintf(stderr,"...now exiting to system...\n");
exit(1);
}
float *vector(long nl, long nh)
/* allocate a float vector with subscript range v[nl..nh] */
{
float *v;
v=(float *)malloc((size_t) ((nh-nl+1+NR_END)*sizeof(float)));
if (!v) nrerror("allocation failure in vector()");
return v-nl+NR_END;
}
int *ivector(long nl, long nh)
/* allocate an int vector with subscript range v[nl..nh] */
{
int *v;
v=(int *)malloc((size_t) ((nh-nl+1+NR_END)*sizeof(int)));
if (!v) nrerror("allocation failure in ivector()");
return v-nl+NR_END;
}
unsigned char *cvector(long nl, long nh)
/* allocate an unsigned char vector with subscript range v[nl..nh] */
{
unsigned char *v;
v=(unsigned char *)malloc((size_t) ((nh-nl+1+NR_END)*sizeof(unsigned char)));
if (!v) nrerror("allocation failure in cvector()");
return v-nl+NR_END;
}
long *lvector(long nl, long nh)
/* allocate an long vector with subscript range v[nl..nh] */
{
long *v;
v=(long *)malloc((size_t) ((nh-nl+1+NR_END)*sizeof(long)));
if (!v) nrerror("allocation failure in lvector()");
return v-nl+NR_END;
}
double *dvector(long nl, long nh)
/* allocate a double vector with subscript range v[nl..nh] */
{
double *v;
v=(double *)malloc((size_t) ((nh-nl+1+NR_END)*sizeof(double)));
if (!v) nrerror("allocation failure in dvector()");
return v-nl+NR_END;
}
float **matrix(long nrl, long nrh, long ncl, long nch)
/* allocate a float matrix with subscript range m[nrl..nrh][ncl..nch] */
{
long i, nrow=nrh-nrl+1,ncol=nch-ncl+1;
float **m;
/* allocate pointers to rows */
m=(float **) malloc((size_t)((nrow+NR_END)*sizeof(float*)));
if (!m) nrerror("allocation failure 1 in matrix()");
m += NR_END;
m -= nrl;
/* allocate rows and set pointers to them */
m[nrl]=(float *) malloc((size_t)((nrow*ncol+NR_END)*sizeof(float)));
if (!m[nrl]) nrerror("allocation failure 2 in matrix()");
m[nrl] += NR_END;
m[nrl] -= ncl;
for(i=nrl+1;i<=nrh;i++) m[i]=m[i-1]+ncol;
/* return pointer to array of pointers to rows */
return m;
}
double **dmatrix(long nrl, long nrh, long ncl, long nch)
/* allocate a double matrix with subscript range m[nrl..nrh][ncl..nch] */
{
long i, nrow=nrh-nrl+1,ncol=nch-ncl+1;
double **m;
/* allocate pointers to rows */
m=(double **) malloc((size_t)((nrow+NR_END)*sizeof(double*)));
if (!m) nrerror("allocation failure 1 in matrix()");
m += NR_END;
m -= nrl;
/* allocate rows and set pointers to them */
m[nrl]=(double *) malloc((size_t)((nrow*ncol+NR_END)*sizeof(double)));
if (!m[nrl]) nrerror("allocation failure 2 in matrix()");
m[nrl] += NR_END;
m[nrl] -= ncl;
for(i=nrl+1;i<=nrh;i++) m[i]=m[i-1]+ncol;
/* return pointer to array of pointers to rows */
return m;
}
int **imatrix(long nrl, long nrh, long ncl, long nch)
/* allocate a int matrix with subscript range m[nrl..nrh][ncl..nch] */
{
long i, nrow=nrh-nrl+1,ncol=nch-ncl+1;
int **m;
/* allocate pointers to rows */
m=(int **) malloc((size_t)((nrow+NR_END)*sizeof(int*)));
if (!m) nrerror("allocation failure 1 in matrix()");
m += NR_END;
m -= nrl;
/* allocate rows and set pointers to them */
m[nrl]=(int *) malloc((size_t)((nrow*ncol+NR_END)*sizeof(int)));
if (!m[nrl]) nrerror("allocation failure 2 in matrix()");
m[nrl] += NR_END;
m[nrl] -= ncl;
for(i=nrl+1;i<=nrh;i++) m[i]=m[i-1]+ncol;
/* return pointer to array of pointers to rows */
return m;
}
float **submatrix(float **a, long oldrl, long oldrh, long oldcl, long oldch,
long newrl, long newcl)
/* point a submatrix [newrl..][newcl..] to a[oldrl..oldrh][oldcl..oldch] */
{
long i,j,nrow=oldrh-oldrl+1,ncol=oldcl-newcl;
float **m;
/* allocate array of pointers to rows */
m=(float **) malloc((size_t) ((nrow+NR_END)*sizeof(float*)));
if (!m) nrerror("allocation failure in submatrix()");
m += NR_END;
m -= newrl;
/* set pointers to rows */
for(i=oldrl,j=newrl;i<=oldrh;i++,j++) m[j]=a[i]+ncol;
/* return pointer to array of pointers to rows */
return m;
}
float **convert_matrix(float *a, long nrl, long nrh, long ncl, long nch)
/* allocate a float matrix m[nrl..nrh][ncl..nch] that points to the matrix
declared in the standard C manner as a[nrow][ncol], where nrow=nrh-nrl+1
and ncol=nch-ncl+1. The routine should be called with the address
&a[0][0] as the first argument. */
{
long i,j,nrow=nrh-nrl+1,ncol=nch-ncl+1;
float **m;
/* allocate pointers to rows */
m=(float **) malloc((size_t) ((nrow+NR_END)*sizeof(float*)));
if (!m) nrerror("allocation failure in convert_matrix()");
m += NR_END;
m -= nrl;
/* set pointers to rows */
m[nrl]=a-ncl;
for(i=1,j=nrl+1;i<nrow;i++,j++) m[j]=m[j-1]+ncol;
/* return pointer to array of pointers to rows */
return m;
}
float ***f3tensor(long nrl, long nrh, long ncl, long nch, long ndl, long ndh)
/* allocate a float 3tensor with range t[nrl..nrh][ncl..nch][ndl..ndh] */
{
long i,j,nrow=nrh-nrl+1,ncol=nch-ncl+1,ndep=ndh-ndl+1;
float ***t;
/* allocate pointers to pointers to rows */
t=(float ***) malloc((size_t)((nrow+NR_END)*sizeof(float**)));
if (!t) nrerror("allocation failure 1 in f3tensor()");
t += NR_END;
t -= nrl;
/* allocate pointers to rows and set pointers to them */
t[nrl]=(float **) malloc((size_t)((nrow*ncol+NR_END)*sizeof(float*)));
if (!t[nrl]) nrerror("allocation failure 2 in f3tensor()");
t[nrl] += NR_END;
t[nrl] -= ncl;
/* allocate rows and set pointers to them */
t[nrl][ncl]=(float *) malloc((size_t)((nrow*ncol*ndep+NR_END)*sizeof(float)));
if (!t[nrl][ncl]) nrerror("allocation failure 3 in f3tensor()");
t[nrl][ncl] += NR_END;
t[nrl][ncl] -= ndl;
for(j=ncl+1;j<=nch;j++) t[nrl][j]=t[nrl][j-1]+ndep;
for(i=nrl+1;i<=nrh;i++) {
t[i]=t[i-1]+ncol;
t[i][ncl]=t[i-1][ncl]+ncol*ndep;
for(j=ncl+1;j<=nch;j++) t[i][j]=t[i][j-1]+ndep;
}
/* return pointer to array of pointers to rows */
return t;
}
double ***d3tensor(long nrl, long nrh, long ncl, long nch, long ndl, long ndh)
/* allocate a double 3tensor with range t[nrl..nrh][ncl..nch][ndl..ndh] */
{
long i,j,nrow=nrh-nrl+1,ncol=nch-ncl+1,ndep=ndh-ndl+1;
double ***t;
/* allocate pointers to pointers to rows */
t=(double ***) malloc((size_t)((nrow+NR_END)*sizeof(double**)));
if (!t) nrerror("allocation failure 1 in f3tensor()");
t += NR_END;
t -= nrl;
/* allocate pointers to rows and set pointers to them */
t[nrl]=(double **) malloc((size_t)((nrow*ncol+NR_END)*sizeof(double*)));
if (!t[nrl]) nrerror("allocation failure 2 in f3tensor()");
t[nrl] += NR_END;
t[nrl] -= ncl;
/* allocate rows and set pointers to them */
t[nrl][ncl]=(double *) malloc((size_t)((nrow*ncol*ndep+NR_END)*sizeof(double)));
if (!t[nrl][ncl]) nrerror("allocation failure 3 in f3tensor()");
t[nrl][ncl] += NR_END;
t[nrl][ncl] -= ndl;
for(j=ncl+1;j<=nch;j++) t[nrl][j]=t[nrl][j-1]+ndep;
for(i=nrl+1;i<=nrh;i++) {
t[i]=t[i-1]+ncol;
t[i][ncl]=t[i-1][ncl]+ncol*ndep;
for(j=ncl+1;j<=nch;j++) t[i][j]=t[i][j-1]+ndep;
}
/* return pointer to array of pointers to rows */
return t;
}
char **cmatrix(long nrl, long nrh, long ncl, long nch)
/* allocate a int matrix with subscript range m[nrl..nrh][ncl..nch] */
{
long i, nrow=nrh-nrl+1,ncol=nch-ncl+1;
char **m;
/* allocate pointers to rows */
m=(char **) malloc((size_t)((nrow+NR_END)*sizeof(char*)));
if (!m) nrerror("allocation failure 1 in matrix()");
m += NR_END;
m -= nrl;
/* allocate rows and set pointers to them */
m[nrl]=(char *) malloc((size_t)((nrow*ncol+NR_END)*sizeof(char)));
if (!m[nrl]) nrerror("allocation failure 2 in matrix()");
m[nrl] += NR_END;
m[nrl] -= ncl;
for(i=nrl+1;i<=nrh;i++) m[i]=m[i-1]+ncol;
/* return pointer to array of pointers to rows */
return m;
}
void free_vector(float *v, long nl, long nh)
/* free a float vector allocated with vector() */
{
free((FREE_ARG) (v+nl-NR_END));
}
void free_ivector(int *v, long nl, long nh)
/* free an int vector allocated with ivector() */
{
free((FREE_ARG) (v+nl-NR_END));
}
void free_cvector(unsigned char *v, long nl, long nh)
/* free an unsigned char vector allocated with cvector() */
{
free((FREE_ARG) (v+nl-NR_END));
}
void free_lvector(long *v, long nl, long nh)
/* free an long vector allocated with lvector() */
{
free((FREE_ARG) (v+nl-NR_END));
}
void free_dvector(double *v, long nl, long nh)
/* free a double vector allocated with dvector() */
{
free((FREE_ARG) (v+nl-NR_END));
}
void free_matrix(float **m, long nrl, long nrh, long ncl, long nch)
/* free a float matrix allocated by matrix() */
{
free((FREE_ARG) (m[nrl]+ncl-NR_END));
free((FREE_ARG) (m+nrl-NR_END));
}
void free_dmatrix(double **m, long nrl, long nrh, long ncl, long nch)
/* free a double matrix allocated by dmatrix() */
{
free((FREE_ARG) (m[nrl]+ncl-NR_END));
free((FREE_ARG) (m+nrl-NR_END));
}
void free_imatrix(int **m, long nrl, long nrh, long ncl, long nch)
/* free an int matrix allocated by imatrix() */
{
free((FREE_ARG) (m[nrl]+ncl-NR_END));
free((FREE_ARG) (m+nrl-NR_END));
}
void free_submatrix(float **b, long nrl, long nrh, long ncl, long nch)
/* free a submatrix allocated by submatrix() */
{
free((FREE_ARG) (b+nrl-NR_END));
}
void free_convert_matrix(float **b, long nrl, long nrh, long ncl, long nch)
/* free a matrix allocated by convert_matrix() */
{
free((FREE_ARG) (b+nrl-NR_END));
}
void free_f3tensor(float ***t, long nrl, long nrh, long ncl, long nch,
long ndl, long ndh)
/* free a float f3tensor allocated by f3tensor() */
{
free((FREE_ARG) (t[nrl][ncl]+ndl-NR_END));
free((FREE_ARG) (t[nrl]+ncl-NR_END));
free((FREE_ARG) (t+nrl-NR_END));
}
void free_d3tensor(double ***t, long nrl, long nrh, long ncl, long nch,
long ndl, long ndh)
/* free a double f3tensor allocated by f3tensor() */
{
free((FREE_ARG) (t[nrl][ncl]+ndl-NR_END));
free((FREE_ARG) (t[nrl]+ncl-NR_END));
free((FREE_ARG) (t+nrl-NR_END));
}
void free_cmatrix(char **m, long nrl, long nrh, long ncl, long nch)
/* free a character matrix allocated by matrix() */
{
free((FREE_ARG) (m[nrl]+ncl-NR_END));
free((FREE_ARG) (m+nrl-NR_END));
}
#else /* ANSI */
/* traditional - K&R */
#include <stdio.h>
#define NR_END 1
#define FREE_ARG char*
void nrerror(error_text)
char error_text[];
/* Numerical Recipes standard error handler */
{
void exit();
fprintf(stderr,"Numerical Recipes run-time error...\n");
fprintf(stderr,"%s\n",error_text);
fprintf(stderr,"...now exiting to system...\n");
exit(1);
}
float *vector(nl,nh)
long nh,nl;
/* allocate a float vector with subscript range v[nl..nh] */
{
float *v;
v=(float *)malloc((unsigned int) ((nh-nl+1+NR_END)*sizeof(float)));
if (!v) nrerror("allocation failure in vector()");
return v-nl+NR_END;
}
int *ivector(nl,nh)
long nh,nl;
/* allocate an int vector with subscript range v[nl..nh] */
{
int *v;
v=(int *)malloc((unsigned int) ((nh-nl+1+NR_END)*sizeof(int)));
if (!v) nrerror("allocation failure in ivector()");
return v-nl+NR_END;
}
unsigned char *cvector(nl,nh)
long nh,nl;
/* allocate an unsigned char vector with subscript range v[nl..nh] */
{
unsigned char *v;
v=(unsigned char *)malloc((unsigned int) ((nh-nl+1+NR_END)*sizeof(unsigned char)));
if (!v) nrerror("allocation failure in cvector()");
return v-nl+NR_END;
}
long *lvector(nl,nh)
long nh,nl;
/* allocate an unsigned long vector with subscript range v[nl..nh] */
{
long *v;
v=(long *)malloc((int) ((nh-nl+1+NR_END)*sizeof(long)));
if (!v) nrerror("allocation failure in lvector()");
return v-nl+NR_END;
}
double *dvector(nl,nh)
long nh,nl;
/* allocate a double vector with subscript range v[nl..nh] */
{
double *v;
v=(double *)malloc((unsigned int) ((nh-nl+1+NR_END)*sizeof(double)));
if (!v) nrerror("allocation failure in dvector()");
return v-nl+NR_END;
}
float **matrix(nrl,nrh,ncl,nch)
long nch,ncl,nrh,nrl;
/* allocate a float matrix with subscript range m[nrl..nrh][ncl..nch] */
{
long i, nrow=nrh-nrl+1,ncol=nch-ncl+1;
float **m;
/* allocate pointers to rows */
m=(float **) malloc((unsigned int)((nrow+NR_END)*sizeof(float*)));
if (!m) nrerror("allocation failure 1 in matrix()");
m += NR_END;
m -= nrl;
/* allocate rows and set pointers to them */
m[nrl]=(float *) malloc((unsigned int)((nrow*ncol+NR_END)*sizeof(float)));
if (!m[nrl]) nrerror("allocation failure 2 in matrix()");
m[nrl] += NR_END;
m[nrl] -= ncl;
for(i=nrl+1;i<=nrh;i++) m[i]=m[i-1]+ncol;
/* return pointer to array of pointers to rows */
return m;
}
double **dmatrix(nrl,nrh,ncl,nch)
long nch,ncl,nrh,nrl;
/* allocate a double matrix with subscript range m[nrl..nrh][ncl..nch] */
{
long i, nrow=nrh-nrl+1,ncol=nch-ncl+1;
double **m;
/* allocate pointers to rows */
m=(double **) malloc((unsigned int)((nrow+NR_END)*sizeof(double*)));
if (!m) nrerror("allocation failure 1 in matrix()");
m += NR_END;
m -= nrl;
/* allocate rows and set pointers to them */
m[nrl]=(double *) malloc((unsigned int)((nrow*ncol+NR_END)*sizeof(double)));
if (!m[nrl]) nrerror("allocation failure 2 in matrix()");
m[nrl] += NR_END;
m[nrl] -= ncl;
for(i=nrl+1;i<=nrh;i++) m[i]=m[i-1]+ncol;
/* return pointer to array of pointers to rows */
return m;
}
int **imatrix(nrl,nrh,ncl,nch)
long nch,ncl,nrh,nrl;
/* allocate a int matrix with subscript range m[nrl..nrh][ncl..nch] */
{
long i, nrow=nrh-nrl+1,ncol=nch-ncl+1;
int **m;
/* allocate pointers to rows */
m=(int **) malloc((unsigned int)((nrow+NR_END)*sizeof(int*)));
if (!m) nrerror("allocation failure 1 in matrix()");
m += NR_END;
m -= nrl;
/* allocate rows and set pointers to them */
m[nrl]=(int *) malloc((unsigned int)((nrow*ncol+NR_END)*sizeof(int)));
if (!m[nrl]) nrerror("allocation failure 2 in matrix()");
m[nrl] += NR_END;
m[nrl] -= ncl;
for(i=nrl+1;i<=nrh;i++) m[i]=m[i-1]+ncol;
/* return pointer to array of pointers to rows */
return m;
}
float **submatrix(a,oldrl,oldrh,oldcl,oldch,newrl,newcl)
float **a;
long newcl,newrl,oldch,oldcl,oldrh,oldrl;
/* point a submatrix [newrl..][newcl..] to a[oldrl..oldrh][oldcl..oldch] */
{
long i,j,nrow=oldrh-oldrl+1,ncol=oldcl-newcl;
float **m;
/* allocate array of pointers to rows */
m=(float **) malloc((unsigned int) ((nrow+NR_END)*sizeof(float*)));
if (!m) nrerror("allocation failure in submatrix()");
m += NR_END;
m -= newrl;
/* set pointers to rows */
for(i=oldrl,j=newrl;i<=oldrh;i++,j++) m[j]=a[i]+ncol;
/* return pointer to array of pointers to rows */
return m;
}
float **convert_matrix(a,nrl,nrh,ncl,nch)
float *a;
long nch,ncl,nrh,nrl;
/* allocate a float matrix m[nrl..nrh][ncl..nch] that points to the matrix
declared in the standard C manner as a[nrow][ncol], where nrow=nrh-nrl+1
and ncol=nch-ncl+1. The routine should be called with the address
&a[0][0] as the first argument. */
{
long i,j,nrow=nrh-nrl+1,ncol=nch-ncl+1;
float **m;
/* allocate pointers to rows */
m=(float **) malloc((unsigned int) ((nrow+NR_END)*sizeof(float*)));
if (!m) nrerror("allocation failure in convert_matrix()");
m += NR_END;
m -= nrl;
/* set pointers to rows */
m[nrl]=a-ncl;
for(i=1,j=nrl+1;i<nrow;i++,j++) m[j]=m[j-1]+ncol;
/* return pointer to array of pointers to rows */
return m;
}
double ***d3tensor(nrl,nrh,ncl,nch,ndl,ndh)
long nch,ncl,ndh,ndl,nrh,nrl;
/* allocate a float 3tensor with range t[nrl..nrh][ncl..nch][ndl..ndh] */
{
long i,j,nrow=nrh-nrl+1,ncol=nch-ncl+1,ndep=ndh-ndl+1;
double ***t;
/* allocate pointers to pointers to rows */
t=(double ***) malloc((unsigned int)((nrow+NR_END)*sizeof(double**)));
if (!t) nrerror("allocation failure 1 in f3tensor()");
t += NR_END;
t -= nrl;
/* allocate pointers to rows and set pointers to them */
t[nrl]=(double **) malloc((unsigned int)((nrow*ncol+NR_END)*sizeof(double*)));
if (!t[nrl]) nrerror("allocation failure 2 in f3tensor()");
t[nrl] += NR_END;
t[nrl] -= ncl;
/* allocate rows and set pointers to them */
t[nrl][ncl]=(double *) malloc((unsigned int)((nrow*ncol*ndep+NR_END)*sizeof(double)));
if (!t[nrl][ncl]) nrerror("allocation failure 3 in f3tensor()");
t[nrl][ncl] += NR_END;
t[nrl][ncl] -= ndl;
for(j=ncl+1;j<=nch;j++) t[nrl][j]=t[nrl][j-1]+ndep;
for(i=nrl+1;i<=nrh;i++) {
t[i]=t[i-1]+ncol;
t[i][ncl]=t[i-1][ncl]+ncol*ndep;
for(j=ncl+1;j<=nch;j++) t[i][j]=t[i][j-1]+ndep;
}
/* return pointer to array of pointers to rows */
return t;
}
float ***f3tensor(nrl,nrh,ncl,nch,ndl,ndh)
long nch,ncl,ndh,ndl,nrh,nrl;
/* allocate a float 3tensor with range t[nrl..nrh][ncl..nch][ndl..ndh] */
{
long i,j,nrow=nrh-nrl+1,ncol=nch-ncl+1,ndep=ndh-ndl+1;
float ***t;
/* allocate pointers to pointers to rows */
t=(float ***) malloc((unsigned int)((nrow+NR_END)*sizeof(float**)));
if (!t) nrerror("allocation failure 1 in f3tensor()");
t += NR_END;
t -= nrl;
/* allocate pointers to rows and set pointers to them */
t[nrl]=(float **) malloc((unsigned int)((nrow*ncol+NR_END)*sizeof(float*)));
if (!t[nrl]) nrerror("allocation failure 2 in f3tensor()");
t[nrl] += NR_END;
t[nrl] -= ncl;
/* allocate rows and set pointers to them */
t[nrl][ncl]=(float *) malloc((unsigned int)((nrow*ncol*ndep+NR_END)*sizeof(float)));
if (!t[nrl][ncl]) nrerror("allocation failure 3 in f3tensor()");
t[nrl][ncl] += NR_END;
t[nrl][ncl] -= ndl;
for(j=ncl+1;j<=nch;j++) t[nrl][j]=t[nrl][j-1]+ndep;
for(i=nrl+1;i<=nrh;i++) {
t[i]=t[i-1]+ncol;
t[i][ncl]=t[i-1][ncl]+ncol*ndep;
for(j=ncl+1;j<=nch;j++) t[i][j]=t[i][j-1]+ndep;
}
/* return pointer to array of pointers to rows */
return t;
}
char **cmatrix(nrl,nrh,ncl,nch)
long nch,ncl,nrh,nrl;
/* allocate a int matrix with subscript range m[nrl..nrh][ncl..nch] */
{
long i, nrow=nrh-nrl+1,ncol=nch-ncl+1;
char **m;
/* allocate pointers to rows */
m=(char **) malloc((unsigned int)((nrow+NR_END)*sizeof(char*)));
if (!m) nrerror("allocation failure 1 in matrix()");
m += NR_END;
m -= nrl;
/* allocate rows and set pointers to them */
m[nrl]=(char *) malloc((unsigned int)((nrow*ncol+NR_END)*sizeof(char)));
if (!m[nrl]) nrerror("allocation failure 2 in matrix()");
m[nrl] += NR_END;
m[nrl] -= ncl;
for(i=nrl+1;i<=nrh;i++) m[i]=m[i-1]+ncol;
/* return pointer to array of pointers to rows */
return m;
}
void free_vector(v,nl,nh)
float *v;
long nh,nl;
/* free a float vector allocated with vector() */
{
free((FREE_ARG) (v+nl-NR_END));
}
void free_ivector(v,nl,nh)
int *v;
long nh,nl;
/* free an int vector allocated with ivector() */
{
free((FREE_ARG) (v+nl-NR_END));
}
void free_cvector(v,nl,nh)
long nh,nl;
unsigned char *v;
/* free an unsigned char vector allocated with cvector() */
{
free((FREE_ARG) (v+nl-NR_END));
}
void free_lvector(v,nl,nh)
long nh,nl;
long *v;
/* free an long vector allocated with lvector() */
{
free((FREE_ARG) (v+nl-NR_END));
}
void free_dvector(v,nl,nh)
double *v;
long nh,nl;
/* free a double vector allocated with dvector() */
{
free((FREE_ARG) (v+nl-NR_END));
}
void free_matrix(m,nrl,nrh,ncl,nch)
float **m;
long nch,ncl,nrh,nrl;
/* free a float matrix allocated by matrix() */
{
free((FREE_ARG) (m[nrl]+ncl-NR_END));
free((FREE_ARG) (m+nrl-NR_END));
}
void free_dmatrix(m,nrl,nrh,ncl,nch)
double **m;
long nch,ncl,nrh,nrl;
/* free a double matrix allocated by dmatrix() */
{
free((FREE_ARG) (m[nrl]+ncl-NR_END));
free((FREE_ARG) (m+nrl-NR_END));
}
void free_imatrix(m,nrl,nrh,ncl,nch)
int **m;
long nch,ncl,nrh,nrl;
/* free an int matrix allocated by imatrix() */
{
free((FREE_ARG) (m[nrl]+ncl-NR_END));
free((FREE_ARG) (m+nrl-NR_END));
}
void free_submatrix(b,nrl,nrh,ncl,nch)
float **b;
long nch,ncl,nrh,nrl;
/* free a submatrix allocated by submatrix() */
{
free((FREE_ARG) (b+nrl-NR_END));
}
void free_convert_matrix(b,nrl,nrh,ncl,nch)
float **b;
long nch,ncl,nrh,nrl;
/* free a matrix allocated by convert_matrix() */
{
free((FREE_ARG) (b+nrl-NR_END));
}
void free_f3tensor(t,nrl,nrh,ncl,nch,ndl,ndh)
float ***t;
long nch,ncl,ndh,ndl,nrh,nrl;
/* free a float f3tensor allocated by f3tensor() */
{
free((FREE_ARG) (t[nrl][ncl]+ndl-NR_END));
free((FREE_ARG) (t[nrl]+ncl-NR_END));
free((FREE_ARG) (t+nrl-NR_END));
}
void free_d3tensor(t,nrl,nrh,ncl,nch,ndl,ndh)
double ***t;
long nch,ncl,ndh,ndl,nrh,nrl;
/* free a float f3tensor allocated by f3tensor() */
{
free((FREE_ARG) (t[nrl][ncl]+ndl-NR_END));
free((FREE_ARG) (t[nrl]+ncl-NR_END));
free((FREE_ARG) (t+nrl-NR_END));
}
void free_cmatrix(m,nrl,nrh,ncl,nch)
char **m;
long nch,ncl,nrh,nrl;
/* free a double matrix allocated by dmatrix() */
{
free((FREE_ARG) (m[nrl]+ncl-NR_END));
free((FREE_ARG) (m+nrl-NR_END));
}
#endif /* ANSI */
/* CAUTION: This is the ANSI C (only) version of the Numerical Recipes
utility file nrutil.h. Do not confuse this file with the same-named
file nrutil.h that may be supplied in a 'misc' subdirectory.
*That* file is the one from the book, and contains both ANSI and
traditional K&R versions, along with #ifdef macros to select the
correct version. *This* file contains only ANSI C. */
#ifndef _NR_UTILS_H_
#define _NR_UTILS_H_
static float sqrarg;
#define SQR(a) ((sqrarg=(a)) == 0.0 ? 0.0 : sqrarg*sqrarg)
static double dsqrarg;
#define DSQR(a) ((dsqrarg=(a)) == 0.0 ? 0.0 : dsqrarg*dsqrarg)
static double dmaxarg1,dmaxarg2;
#define DMAX(a,b) (dmaxarg1=(a),dmaxarg2=(b),(dmaxarg1) > (dmaxarg2) ?\
(dmaxarg1) : (dmaxarg2))
static double dminarg1,dminarg2;
#define DMIN(a,b) (dminarg1=(a),dminarg2=(b),(dminarg1) < (dminarg2) ?\
(dminarg1) : (dminarg2))
static float maxarg1,maxarg2;
#define FMAX(a,b) (maxarg1=(a),maxarg2=(b),(maxarg1) > (maxarg2) ?\
(maxarg1) : (maxarg2))
static float minarg1,minarg2;
#define FMIN(a,b) (minarg1=(a),minarg2=(b),(minarg1) < (minarg2) ?\
(minarg1) : (minarg2))
static long lmaxarg1,lmaxarg2;
#define LMAX(a,b) (lmaxarg1=(a),lmaxarg2=(b),(lmaxarg1) > (lmaxarg2) ?\
(lmaxarg1) : (lmaxarg2))
static long lminarg1,lminarg2;
#define LMIN(a,b) (lminarg1=(a),lminarg2=(b),(lminarg1) < (lminarg2) ?\
(lminarg1) : (lminarg2))
static int imaxarg1,imaxarg2;
#define IMAX(a,b) (imaxarg1=(a),imaxarg2=(b),(imaxarg1) > (imaxarg2) ?\
(imaxarg1) : (imaxarg2))
static int iminarg1,iminarg2;
#define IMIN(a,b) (iminarg1=(a),iminarg2=(b),(iminarg1) < (iminarg2) ?\
(iminarg1) : (iminarg2))
#define SIGN(a,b) ((b) >= 0.0 ? fabs(a) : -fabs(a))
void nrerror(char error_text[]);
float *vector(long nl, long nh);
int *ivector(long nl, long nh);
unsigned char *cvector(long nl, long nh);
long *lvector(long nl, long nh);
double *dvector(long nl, long nh);
float **matrix(long nrl, long nrh, long ncl, long nch);
double **dmatrix(long nrl, long nrh, long ncl, long nch);
int **imatrix(long nrl, long nrh, long ncl, long nch);
float **submatrix(float **a, long oldrl, long oldrh, long oldcl, long oldch,
long newrl, long newcl);
float **convert_matrix(float *a, long nrl, long nrh, long ncl, long nch);
float ***f3tensor(long nrl, long nrh, long ncl, long nch, long ndl, long ndh);
void free_vector(float *v, long nl, long nh);
void free_ivector(int *v, long nl, long nh);
void free_cvector(unsigned char *v, long nl, long nh);
void free_lvector(long *v, long nl, long nh);
void free_dvector(double *v, long nl, long nh);
void free_matrix(float **m, long nrl, long nrh, long ncl, long nch);
void free_dmatrix(double **m, long nrl, long nrh, long ncl, long nch);
void free_imatrix(int **m, long nrl, long nrh, long ncl, long nch);
void free_submatrix(float **b, long nrl, long nrh, long ncl, long nch);
void free_convert_matrix(float **b, long nrl, long nrh, long ncl, long nch);
void free_f3tensor(float ***t, long nrl, long nrh, long ncl, long nch,
long ndl, long ndh);
int ***i3tensor(long nrl, long nrh, long ncl, long nch, long ndl, long ndh);
void free_i3tensor(int ***t, long nrl, long nrh, long ncl, long nch,
long ndl, long ndh);
unsigned char ***b3tensor(long nrl, long nrh, long ncl, long nch, long ndl, long ndh);
void free_b3tensor(unsigned char ***t, long nrl, long nrh, long ncl, long nch,
long ndl, long ndh);
double ***d3tensor(long nrl, long nrh, long ncl, long nch, long ndl, long ndh);
void free_d3tensor(double ***t, long nrl, long nrh, long ncl, long nch,
long ndl, long ndh);
char **cmatrix(long nrl, long nrh, long ncl, long nch);
void free_cmatrix(char **m, long nrl, long nrh, long ncl, long nch);
#endif /* _NR_UTILS_H_ */
from ctypes import CDLL, POINTER, c_int, c_double, c_float, c_long, c_char_p
from numpy.ctypeslib import ndpointer
import numpy.ctypeslib as clb
import numpy as np
from astropy.io import fits
from scipy.stats import randint
from glob import glob
from datetime import datetime
import os
lib_path = os.path.dirname(os.path.realpath(__file__))
# lib_path += "/add_CTI.so"
lib_path += "/libmoduleCTI.so"
lib = CDLL(lib_path)
CTI_simul = lib.__getattr__('CTI_simul')
CTI_simul.argtypes = [POINTER(POINTER(c_int)), c_int, c_int, c_int, c_int, POINTER(c_float), POINTER(c_float),
c_float, c_float, c_float, c_int, POINTER(c_int), c_int, POINTER(POINTER(c_int))]
'''
get_trap_h = lib.__getattr__('save_trap_map')
get_trap_h.argtypes = [POINTER(c_int), c_int, c_int, c_int, c_int, POINTER(c_float), c_float, c_float, c_char_p]
def get_trap_map(seeds,nx,ny,nmax,rho_trap,beta,c,out_dir):
hsp_result = np.zeros(ny*nx*nmax)
nsp = len(rho_trap)
seeds1 = seeds.astype(np.int32)
seeds_p = np.ctypeslib.as_ctypes(seeds1)
rho_trap1 = rho_trap.astype(np.float32)
rho_trap_p = np.ctypeslib.as_ctypes(rho_trap1)
filename = (out_dir+"/trap.bin").encode('utf-8')
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)
for i in range(nsp):
print("transfering trap type "+str(i+1))
datai = data[i]
ntrap = datai[0,:,:]
for j in range(nmax-1):
h = datai[j+1,:,:]
h[np.where(ntrap<j+1)] = 0
datai[j+1,:,:] = h
fits.writeto(fits_dir+"/trap_"+str(i+1)+".fits",datai,overwrite=True)
'''
def numpy_matrix_to_int_pointer(arr):
int_pointer_array = (POINTER(c_int)*arr.shape[0])()
for i in range(arr.shape[0]):
arr1 = np.array(arr[i].copy().tolist(), dtype=np.int32)
int_pointer_array[i] = np.ctypeslib.as_ctypes(arr1)
return int_pointer_array
def pointer_to_numpy_matrix(arr_pointer, row, col):
arr = np.zeros((row, col))
for i in range(row):
for j in range(col):
arr[i, j] = arr_pointer[i][j]
return arr
def CTI_sim(im, nx, ny, noverscan, nsp, nmax, beta, w, c, t, rho_trap, trap_seeds, release_seed=0):
image = im.T
nx_c, ny_c, noverscan_c, nsp_c, nmax_c = c_int(nx), c_int(
ny), c_int(noverscan), c_int(nsp), c_int(nmax)
ntotal = ny+noverscan
beta_c, w_c, c_c = c_float(beta), c_float(w), c_float(c)
t_p = np.ctypeslib.as_ctypes(t)
rho_trap_p = np.ctypeslib.as_ctypes(rho_trap)
image_p = numpy_matrix_to_int_pointer(image)
trap_seeds1 = trap_seeds.astype(np.int32)
trap_seeds_p = np.ctypeslib.as_ctypes(trap_seeds1)
release_seed_c = c_int(release_seed)
image_cti = np.zeros((nx, ntotal))
image_cti = image_cti.astype(np.int32)
image_cti_p = numpy_matrix_to_int_pointer(image_cti)
print(datetime.now())
CTI_simul(image_p, nx, ny, noverscan, nsp, rho_trap_p, t_p, beta,
w, c, nmax, trap_seeds_p, release_seed_c, image_cti_p)
print(datetime.now())
image_cti_result = np.zeros((nx, ntotal))
for i in range(nx):
for j in range(ntotal):
image_cti_result[i, j] = image_cti_p[i][j]
return image_cti_result.T
"""
if __name__ =='__main__':
nx,ny,noverscan,nsp,nmax = 4608,4616,84,3,10
ntotal = 4700
beta,w,c = 0.478,84700,0
t = np.array([0.74,7.7,37],dtype=np.float32)
rho_trap = np.array([0.6,1.6,1.4],dtype=np.float32)
trap_seeds = np.array([0,100,1000],dtype=np.int32)
release_seed = 500
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)
fits.writeto("output/image_CTI.fits",data=image_cti,overwrite=True)
"""
#include objects here:
objects = src/add_CTI1.o src/nrutil.o src/ran1.o src/ran2.o src/poidev.o src/gammln.o src/gasdev.o src/sort.o src/creattraps.o
add_CTI.so: $(objects)
gcc -shared -fPIC -std=c99 -o $@ $(objects) -lm
# general compilation rules
.SUFFIXES: .c .o
.c.o:
cc -c $< -O3 -shared -fPIC -std=c99 -o $@
.PHONY : clean
clean:
rm -f src/*.o add_CTI.so
CTI_lgl_v0.3/
add_CTIfinal.c >> add_CTI.c
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "nrutil.h"
#include <time.h>
float poidev(float x, long *idum);
void creattraps(long *seed,int ntrap,int ny,int nmax,float c,float beta,float **sp);
void addCTI(int *a0,int ny,int noverscan,int nsp,float beta,float w, float c,float *t, float ***ntrap, int *acti, int release_seed,float *randv);
//int read_fits_2D(const char *argv,float *galaxy,int imagesize);
//int write_fits_2D(const char *argv,float **stars,int *dim);
float ran1(long *idum);
void CTI_simul(int **image, int nx, int ny, int noverscan, int nsp, float *rho_trap, float *t, float beta, float w, float c, int nmax, long *trap_seeds, int release_seed,int **imagecti){
int ntotal;
printf("image parameters: nx=%i ny=%i noverscan=%i\n",nx,ny,noverscan);
printf("input image: image[0][0]=%i image[50][60]=%i image[1000][20]=%i image[20][1000]=%i\n",image[0][0],image[50][60],image[1000][20],image[20][1000]);
printf("rho_trap rho1=%f rho2=%f rho3=%f\n",rho_trap[0],rho_trap[1],rho_trap[2]);
printf("t t1=%f t2=%f t3=%f\n",t[0],t[1],t[2]);
printf("volume parameter beta=%f,w=%f,c=%f\n",beta,w,c);
printf("nsp=%i,nmax=%i\n",nsp,nmax);
//printf("trap_seeds = %i,%i,%i\n",trap_seeds[0],trap_seeds[1],trap_seeds[2]);
printf("release_seed = %i\n",release_seed);
printf("begin CTI simulation\n");
float ***ntrap;
float *randv;
float tmp;
int ntrap_tmp,nrandv=100000;
int *a0,*acti,dim[2];
int i,j,k,l;
long iseed=-1;
ntotal=ny+noverscan;
ntrap = f3tensor(0,nsp-1,0,ny,0,nmax+1);
a0=ivector(0,ny);
acti=ivector(0,ntotal);
randv=vector(0,nrandv);
for(i=0;i<nrandv;i++)randv[i]=ran1(&iseed);
printf("column k/%i, k=", nx);
for(k=0;k<nx;k++){
if(k % 8 == 0) fprintf(stdout, "%i ",k); fflush(stdout);
for(l=0;l<nsp;l++){
tmp = rho_trap[l]*ny;
ntrap_tmp = poidev(tmp,&trap_seeds[l]);
creattraps(&trap_seeds[l],ntrap_tmp,ny,nmax,c,beta,ntrap[l]);
}
for(i=0;i<ny;i++){a0[i]=image[k][i];}
//for(i=0;i<ntotal;i++)acti[i]=0;
addCTI(a0,ny,noverscan,nsp,beta,w,c,t,ntrap,acti,release_seed,randv);
for(i=0;i<ntotal;i++){
imagecti[k][i]=acti[i];
}
}
printf("\nCTI simulation finished!\n");
free_ivector(a0,0,ny);
free_ivector(acti,0,ntotal);
free_f3tensor(ntrap,0,nsp-1,0,ny,0,nmax+1);
free_vector(randv,0,nrandv);
return;
}
void addCTI(int *a0,int ny,int noverscan, int nsp, float beta,float w, float c,float *t, float ***ntrap, int *acti, int release_seed,float *randv)
{
void trap_release(int *flow, int *traped,int ntraped,float *randv,int *ncumran,float f);
//float ran1(long *idum);
float *tmpntrap,*f,tmph[50];
float height,wre;
int flowt,ntraptot,ntraped,topoftrap,nrelease,ntraped0,tmptrapedt,ntrapsum;
int ntotal,i,j,k,nmove,isum,ntmp,isp,*tmptraped,**traped,*flow;
int ncumran,ncumran0,jc,*jcindx;
long hotseed=-1;
wre=1/w;
ntotal=ny+noverscan;
f=vector(0,nsp-1);
traped = imatrix(0,nsp-1,0,ntotal);
flow=ivector(0,ntotal);
jcindx=ivector(0,ntotal);
for(i=0;i<nsp;i++){f[i]=1-exp(-1./t[i]);}
for(i=ny;i<ntotal;i++)flow[i]=0;
for(i=0;i<nsp;i++){for(j=ny;j<ntotal;j++){traped[i][j] = 0;}}
//initialize
for(i=0;i<ny;i++){
flow[i]=a0[i];
for(j=0;j<nsp;j++){
ntraptot = ntrap[j][i][0];
height=flow[i]*wre;
if(ntraptot>0){
ntraped=0;
tmpntrap=ntrap[j][i];
while(tmpntrap[ntraped+1]<=height){ntraped++;}
if(flow[i]<ntraped)ntraped=flow[i];
flow[i]-=ntraped;
traped[j][i]=ntraped;
}
else{traped[j][i]=0;}
}
}
// rearrange trapes
jc=-1;
for(i=0;i<ny;i++){
ntrapsum=ntrap[0][i][0]+ntrap[1][i][0]+ntrap[2][i][0];
//if((ntrapsum!=0 || hotpixflag){ if there is none-zero trap or it is a hot pix
if(ntrapsum!=0){
jc++;
for(j=0;j<nsp;j++){
traped[j][jc]=traped[j][i];
ntraptot=ntrap[j][i][0];
for(k=0;k<=ntraptot+1;k++)ntrap[j][jc][k]=ntrap[j][i][k];
}
}
jcindx[i+1]=jc;
}
for(i=ny;i<ntotal;i++)jcindx[i]=jc;
// add CTI effects
acti[0]=flow[0];
for(i=1;i<ntotal;i++){
nmove=jcindx[i];
for(j=nmove;j>=0;j--){
//flow[i]+=poidev(0.01, &hotseed);
ncumran=randv[j+i]*10000;
height=flow[i]*wre;
isp=0;
tmpntrap=ntrap[isp][j];
ntraped=0;
tmptraped=traped[isp];
while(tmpntrap[ntraped+1]<=height){ntraped++;}
topoftrap=tmptraped[j]-ntraped;
if(topoftrap!=0){trap_release(&flow[i], &tmptraped[j],topoftrap,randv,&ncumran,f[isp]);}
isp=1;
tmpntrap=ntrap[isp][j];
ntraped=0;
//height=flow[j]*wre; ;
tmptraped=traped[isp];
while(tmpntrap[ntraped+1]<=height){ntraped++;}
topoftrap=tmptraped[j]-ntraped;
if(topoftrap!=0){trap_release(&flow[i], &tmptraped[j],topoftrap,randv,&ncumran,f[isp]);}
isp=2;
tmpntrap=ntrap[isp][j];
ntraped=0;
//height=flow[j]*wre;
tmptraped=traped[isp];
while(tmpntrap[ntraped+1]<=height){ntraped++;}
topoftrap=tmptraped[j]-ntraped;
if(topoftrap!=0){trap_release(&flow[i], &tmptraped[j],topoftrap,randv,&ncumran,f[isp]);}
//isp=3...
}
acti[i]=flow[i];
}
free_ivector(flow,0,ntotal);
free_ivector(jcindx,0,ntotal);
free_imatrix(traped,0,nsp-1,0,ntotal);
free_vector(f,0,nsp-1);
return;
}
void trap_release(int *flow, int *traped,int topoftrap,float *randv,int *ncumran,float f){
int ntmp,k;
if (topoftrap>0){ // release
for(k=0;k<topoftrap;k++){
*ncumran+=1;
if(randv[*ncumran]<f){
*flow+=1;
*traped-=1;
}
}
return;
}
else{ //trap
ntmp = -topoftrap;
if(*flow<ntmp)ntmp=*flow;
*flow-=ntmp;
*traped += ntmp;
}
return;
}
/*int main(){
int read_fits_2D(const char *argv,float *galaxy,int imagesize);
int write_fits_2D(const char *argv,float **stars,int *dim);
int **image,nimg,kct,i,j;
float *image1,**imagecti;
int nx=4608,ny=4616,noverscan=84,nmax=12,nsp=3;
int ntotal;
float beta=0.478,w=84700,c=0;
float t[3] = {0.74,7.7,37};
float rho_trap[3] = {0.6,1.6,1.4};
char fname1[300];
int dim[2];
long trap_seeds[3] = {1,100,1000};
int release_seed = 10000;
clock_t start, end;
ntotal=ny+noverscan;
nimg=nx*ny;
image=imatrix(0,nx,0,ny);
image1=vector(0,nimg);
imagecti=matrix(0,nx,0,ntotal);
strcpy(fname1,"inputdata/image.fits");
read_fits_2D(fname1,image1,nimg);kct=0;
for (j=0; j<ny; j++){
for(i=0;i<nx;i++){
image[i][j]=image1[kct];
kct++;
}}
free_vector(image1,0,nimg);
start = clock();
CTI_simul(image, nx, ny, noverscan, nsp, rho_trap, t, beta, w, c, nmax, trap_seeds, release_seed, imagecti);
end = clock();
float time;
time = (end-start)/CLOCKS_PER_SEC;
printf("running time %f ms\n",time);
// output final image
strcpy(fname1,"output/image_CTIfinal.fits");
dim[0]=nx;dim[1]=ntotal;
write_fits_2D(fname1,imagecti,dim);
free_matrix(imagecti,0,nx,0,ntotal);
free_imatrix(image,0,nx,0,ny);
return 0;
}*/
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "nrutil.h"
void creattraps(long *seed,int ntrap,int ny,int nmax,float c,float beta,float **sp)
{
//creat ntrap traps along one column
//sp[i][0] the number of trap in the ith pixle;
//sp[i][j] (c,1+c) the height of the jth trap in the ith pixle;
float ran1(long *idum);
void sort(unsigned long n, float arr[]);
float tmp,betare,height;
int i,nyt,ntmp,j;
float *tmpv;
tmpv = vector(1,100);
if(nmax>50){printf(" the upper limite of trap in each pixe is too large, nmax=%d\n",nmax); getchar();}
betare=1./beta;
for(i=0;i<ny;i++)sp[i][0]=0;
for(i=0;i<ntrap;i++){
nyt=ran1(seed)*ny;
sp[nyt][0]++;
}
for(i=0;i<ny;i++){
ntmp=sp[i][0];
if(ntmp==1){
height=ran1(seed)-c;
if(height<=0){sp[i][1]=0;}
else{
sp[i][1]=pow(height,betare);
}
}
if(ntmp>1){
if(ntmp>nmax)sp[i][0]=ntmp=nmax; // upper limite of trap in each pixel is nmax
for(j=1;j<=ntmp;j++)tmpv[j]=ran1(seed)-c;
sort(ntmp, tmpv);
for(j=1;j<=ntmp;j++){
height=tmpv[j];
if(height<=0){sp[i][j]=0;}
else{sp[i][j]=pow(height,betare);}
}
}
sp[i][ntmp+1]=999999;
}
free_vector(tmpv,1,100);
}
#include <math.h>
float gammln(float xx)
{
double x,y,tmp,ser;
static double cof[6]={76.18009172947146,-86.50532032941677,
24.01409824083091,-1.231739572450155,
0.1208650973866179e-2,-0.5395239384953e-5};
int j;
y=x=xx;
tmp=x+5.5;
tmp -= (x+0.5)*log(tmp);
ser=1.000000000190015;
for (j=0;j<=5;j++) ser += cof[j]/++y;
return -tmp+log(2.5066282746310005*ser/x);
}
/* (C) Copr. 1986-92 Numerical Recipes Software )1!. */
#include <math.h>
float gasdev(long *idum)
{
float ran1(long *idum);
static int iset=0;
static float gset;
float fac,rsq,v1,v2;
if (iset == 0) {
do {
v1=2.0*ran1(idum)-1.0;
v2=2.0*ran1(idum)-1.0;
rsq=v1*v1+v2*v2;
} while (rsq >= 1.0 || rsq == 0.0);
fac=sqrt(-2.0*log(rsq)/rsq);
gset=v1*fac;
iset=1;
return v2*fac;
} else {
iset=0;
return gset;
}
}
/* (C) Copr. 1986-92 Numerical Recipes Software )1!. */
#if defined(__STDC__) || defined(ANSI) || defined(NRANSI) /* ANSI */
#include <stdio.h>
#include <stddef.h>
#include <stdlib.h>
#define NR_END 1
#define FREE_ARG char*
void nrerror(char error_text[])
/* Numerical Recipes standard error handler */
{
fprintf(stderr,"Numerical Recipes run-time error...\n");
fprintf(stderr,"%s\n",error_text);
fprintf(stderr,"...now exiting to system...\n");
exit(1);
}
float *vector(long nl, long nh)
/* allocate a float vector with subscript range v[nl..nh] */
{
float *v;
v=(float *)malloc((size_t) ((nh-nl+1+NR_END)*sizeof(float)));
if (!v) nrerror("allocation failure in vector()");
return v-nl+NR_END;
}
int *ivector(long nl, long nh)
/* allocate an int vector with subscript range v[nl..nh] */
{
int *v;
v=(int *)malloc((size_t) ((nh-nl+1+NR_END)*sizeof(int)));
if (!v) nrerror("allocation failure in ivector()");
return v-nl+NR_END;
}
unsigned char *cvector(long nl, long nh)
/* allocate an unsigned char vector with subscript range v[nl..nh] */
{
unsigned char *v;
v=(unsigned char *)malloc((size_t) ((nh-nl+1+NR_END)*sizeof(unsigned char)));
if (!v) nrerror("allocation failure in cvector()");
return v-nl+NR_END;
}
long *lvector(long nl, long nh)
/* allocate an long vector with subscript range v[nl..nh] */
{
long *v;
v=(long *)malloc((size_t) ((nh-nl+1+NR_END)*sizeof(long)));
if (!v) nrerror("allocation failure in lvector()");
return v-nl+NR_END;
}
double *dvector(long nl, long nh)
/* allocate a double vector with subscript range v[nl..nh] */
{
double *v;
v=(double *)malloc((size_t) ((nh-nl+1+NR_END)*sizeof(double)));
if (!v) nrerror("allocation failure in dvector()");
return v-nl+NR_END;
}
float **matrix(long nrl, long nrh, long ncl, long nch)
/* allocate a float matrix with subscript range m[nrl..nrh][ncl..nch] */
{
long i, nrow=nrh-nrl+1,ncol=nch-ncl+1;
float **m;
/* allocate pointers to rows */
m=(float **) malloc((size_t)((nrow+NR_END)*sizeof(float*)));
if (!m) nrerror("allocation failure 1 in matrix()");
m += NR_END;
m -= nrl;
/* allocate rows and set pointers to them */
m[nrl]=(float *) malloc((size_t)((nrow*ncol+NR_END)*sizeof(float)));
if (!m[nrl]) nrerror("allocation failure 2 in matrix()");
m[nrl] += NR_END;
m[nrl] -= ncl;
for(i=nrl+1;i<=nrh;i++) m[i]=m[i-1]+ncol;
/* return pointer to array of pointers to rows */
return m;
}
double **dmatrix(long nrl, long nrh, long ncl, long nch)
/* allocate a double matrix with subscript range m[nrl..nrh][ncl..nch] */
{
long i, nrow=nrh-nrl+1,ncol=nch-ncl+1;
double **m;
/* allocate pointers to rows */
m=(double **) malloc((size_t)((nrow+NR_END)*sizeof(double*)));
if (!m) nrerror("allocation failure 1 in matrix()");
m += NR_END;
m -= nrl;
/* allocate rows and set pointers to them */
m[nrl]=(double *) malloc((size_t)((nrow*ncol+NR_END)*sizeof(double)));
if (!m[nrl]) nrerror("allocation failure 2 in matrix()");
m[nrl] += NR_END;
m[nrl] -= ncl;
for(i=nrl+1;i<=nrh;i++) m[i]=m[i-1]+ncol;
/* return pointer to array of pointers to rows */
return m;
}
int **imatrix(long nrl, long nrh, long ncl, long nch)
/* allocate a int matrix with subscript range m[nrl..nrh][ncl..nch] */
{
long i, nrow=nrh-nrl+1,ncol=nch-ncl+1;
int **m;
/* allocate pointers to rows */
m=(int **) malloc((size_t)((nrow+NR_END)*sizeof(int*)));
if (!m) nrerror("allocation failure 1 in matrix()");
m += NR_END;
m -= nrl;
/* allocate rows and set pointers to them */
m[nrl]=(int *) malloc((size_t)((nrow*ncol+NR_END)*sizeof(int)));
if (!m[nrl]) nrerror("allocation failure 2 in matrix()");
m[nrl] += NR_END;
m[nrl] -= ncl;
for(i=nrl+1;i<=nrh;i++) m[i]=m[i-1]+ncol;
/* return pointer to array of pointers to rows */
return m;
}
float **submatrix(float **a, long oldrl, long oldrh, long oldcl, long oldch,
long newrl, long newcl)
/* point a submatrix [newrl..][newcl..] to a[oldrl..oldrh][oldcl..oldch] */
{
long i,j,nrow=oldrh-oldrl+1,ncol=oldcl-newcl;
float **m;
/* allocate array of pointers to rows */
m=(float **) malloc((size_t) ((nrow+NR_END)*sizeof(float*)));
if (!m) nrerror("allocation failure in submatrix()");
m += NR_END;
m -= newrl;
/* set pointers to rows */
for(i=oldrl,j=newrl;i<=oldrh;i++,j++) m[j]=a[i]+ncol;
/* return pointer to array of pointers to rows */
return m;
}
float **convert_matrix(float *a, long nrl, long nrh, long ncl, long nch)
/* allocate a float matrix m[nrl..nrh][ncl..nch] that points to the matrix
declared in the standard C manner as a[nrow][ncol], where nrow=nrh-nrl+1
and ncol=nch-ncl+1. The routine should be called with the address
&a[0][0] as the first argument. */
{
long i,j,nrow=nrh-nrl+1,ncol=nch-ncl+1;
float **m;
/* allocate pointers to rows */
m=(float **) malloc((size_t) ((nrow+NR_END)*sizeof(float*)));
if (!m) nrerror("allocation failure in convert_matrix()");
m += NR_END;
m -= nrl;
/* set pointers to rows */
m[nrl]=a-ncl;
for(i=1,j=nrl+1;i<nrow;i++,j++) m[j]=m[j-1]+ncol;
/* return pointer to array of pointers to rows */
return m;
}
float ***f3tensor(long nrl, long nrh, long ncl, long nch, long ndl, long ndh)
/* allocate a float 3tensor with range t[nrl..nrh][ncl..nch][ndl..ndh] */
{
long i,j,nrow=nrh-nrl+1,ncol=nch-ncl+1,ndep=ndh-ndl+1;
float ***t;
/* allocate pointers to pointers to rows */
t=(float ***) malloc((size_t)((nrow+NR_END)*sizeof(float**)));
if (!t) nrerror("allocation failure 1 in f3tensor()");
t += NR_END;
t -= nrl;
/* allocate pointers to rows and set pointers to them */
t[nrl]=(float **) malloc((size_t)((nrow*ncol+NR_END)*sizeof(float*)));
if (!t[nrl]) nrerror("allocation failure 2 in f3tensor()");
t[nrl] += NR_END;
t[nrl] -= ncl;
/* allocate rows and set pointers to them */
t[nrl][ncl]=(float *) malloc((size_t)((nrow*ncol*ndep+NR_END)*sizeof(float)));
if (!t[nrl][ncl]) nrerror("allocation failure 3 in f3tensor()");
t[nrl][ncl] += NR_END;
t[nrl][ncl] -= ndl;
for(j=ncl+1;j<=nch;j++) t[nrl][j]=t[nrl][j-1]+ndep;
for(i=nrl+1;i<=nrh;i++) {
t[i]=t[i-1]+ncol;
t[i][ncl]=t[i-1][ncl]+ncol*ndep;
for(j=ncl+1;j<=nch;j++) t[i][j]=t[i][j-1]+ndep;
}
/* return pointer to array of pointers to rows */
return t;
}
double ***d3tensor(long nrl, long nrh, long ncl, long nch, long ndl, long ndh)
/* allocate a double 3tensor with range t[nrl..nrh][ncl..nch][ndl..ndh] */
{
long i,j,nrow=nrh-nrl+1,ncol=nch-ncl+1,ndep=ndh-ndl+1;
double ***t;
/* allocate pointers to pointers to rows */
t=(double ***) malloc((size_t)((nrow+NR_END)*sizeof(double**)));
if (!t) nrerror("allocation failure 1 in f3tensor()");
t += NR_END;
t -= nrl;
/* allocate pointers to rows and set pointers to them */
t[nrl]=(double **) malloc((size_t)((nrow*ncol+NR_END)*sizeof(double*)));
if (!t[nrl]) nrerror("allocation failure 2 in f3tensor()");
t[nrl] += NR_END;
t[nrl] -= ncl;
/* allocate rows and set pointers to them */
t[nrl][ncl]=(double *) malloc((size_t)((nrow*ncol*ndep+NR_END)*sizeof(double)));
if (!t[nrl][ncl]) nrerror("allocation failure 3 in f3tensor()");
t[nrl][ncl] += NR_END;
t[nrl][ncl] -= ndl;
for(j=ncl+1;j<=nch;j++) t[nrl][j]=t[nrl][j-1]+ndep;
for(i=nrl+1;i<=nrh;i++) {
t[i]=t[i-1]+ncol;
t[i][ncl]=t[i-1][ncl]+ncol*ndep;
for(j=ncl+1;j<=nch;j++) t[i][j]=t[i][j-1]+ndep;
}
/* return pointer to array of pointers to rows */
return t;
}
char **cmatrix(long nrl, long nrh, long ncl, long nch)
/* allocate a int matrix with subscript range m[nrl..nrh][ncl..nch] */
{
long i, nrow=nrh-nrl+1,ncol=nch-ncl+1;
char **m;
/* allocate pointers to rows */
m=(char **) malloc((size_t)((nrow+NR_END)*sizeof(char*)));
if (!m) nrerror("allocation failure 1 in matrix()");
m += NR_END;
m -= nrl;
/* allocate rows and set pointers to them */
m[nrl]=(char *) malloc((size_t)((nrow*ncol+NR_END)*sizeof(char)));
if (!m[nrl]) nrerror("allocation failure 2 in matrix()");
m[nrl] += NR_END;
m[nrl] -= ncl;
for(i=nrl+1;i<=nrh;i++) m[i]=m[i-1]+ncol;
/* return pointer to array of pointers to rows */
return m;
}
void free_vector(float *v, long nl, long nh)
/* free a float vector allocated with vector() */
{
free((FREE_ARG) (v+nl-NR_END));
}
void free_ivector(int *v, long nl, long nh)
/* free an int vector allocated with ivector() */
{
free((FREE_ARG) (v+nl-NR_END));
}
void free_cvector(unsigned char *v, long nl, long nh)
/* free an unsigned char vector allocated with cvector() */
{
free((FREE_ARG) (v+nl-NR_END));
}
void free_lvector(long *v, long nl, long nh)
/* free an long vector allocated with lvector() */
{
free((FREE_ARG) (v+nl-NR_END));
}
void free_dvector(double *v, long nl, long nh)
/* free a double vector allocated with dvector() */
{
free((FREE_ARG) (v+nl-NR_END));
}
void free_matrix(float **m, long nrl, long nrh, long ncl, long nch)
/* free a float matrix allocated by matrix() */
{
free((FREE_ARG) (m[nrl]+ncl-NR_END));
free((FREE_ARG) (m+nrl-NR_END));
}
void free_dmatrix(double **m, long nrl, long nrh, long ncl, long nch)
/* free a double matrix allocated by dmatrix() */
{
free((FREE_ARG) (m[nrl]+ncl-NR_END));
free((FREE_ARG) (m+nrl-NR_END));
}
void free_imatrix(int **m, long nrl, long nrh, long ncl, long nch)
/* free an int matrix allocated by imatrix() */
{
free((FREE_ARG) (m[nrl]+ncl-NR_END));
free((FREE_ARG) (m+nrl-NR_END));
}
void free_submatrix(float **b, long nrl, long nrh, long ncl, long nch)
/* free a submatrix allocated by submatrix() */
{
free((FREE_ARG) (b+nrl-NR_END));
}
void free_convert_matrix(float **b, long nrl, long nrh, long ncl, long nch)
/* free a matrix allocated by convert_matrix() */
{
free((FREE_ARG) (b+nrl-NR_END));
}
void free_f3tensor(float ***t, long nrl, long nrh, long ncl, long nch,
long ndl, long ndh)
/* free a float f3tensor allocated by f3tensor() */
{
free((FREE_ARG) (t[nrl][ncl]+ndl-NR_END));
free((FREE_ARG) (t[nrl]+ncl-NR_END));
free((FREE_ARG) (t+nrl-NR_END));
}
void free_d3tensor(double ***t, long nrl, long nrh, long ncl, long nch,
long ndl, long ndh)
/* free a double f3tensor allocated by f3tensor() */
{
free((FREE_ARG) (t[nrl][ncl]+ndl-NR_END));
free((FREE_ARG) (t[nrl]+ncl-NR_END));
free((FREE_ARG) (t+nrl-NR_END));
}
void free_cmatrix(char **m, long nrl, long nrh, long ncl, long nch)
/* free a character matrix allocated by matrix() */
{
free((FREE_ARG) (m[nrl]+ncl-NR_END));
free((FREE_ARG) (m+nrl-NR_END));
}
#else /* ANSI */
/* traditional - K&R */
#include <stdio.h>
#define NR_END 1
#define FREE_ARG char*
void nrerror(error_text)
char error_text[];
/* Numerical Recipes standard error handler */
{
void exit();
fprintf(stderr,"Numerical Recipes run-time error...\n");
fprintf(stderr,"%s\n",error_text);
fprintf(stderr,"...now exiting to system...\n");
exit(1);
}
float *vector(nl,nh)
long nh,nl;
/* allocate a float vector with subscript range v[nl..nh] */
{
float *v;
v=(float *)malloc((unsigned int) ((nh-nl+1+NR_END)*sizeof(float)));
if (!v) nrerror("allocation failure in vector()");
return v-nl+NR_END;
}
int *ivector(nl,nh)
long nh,nl;
/* allocate an int vector with subscript range v[nl..nh] */
{
int *v;
v=(int *)malloc((unsigned int) ((nh-nl+1+NR_END)*sizeof(int)));
if (!v) nrerror("allocation failure in ivector()");
return v-nl+NR_END;
}
unsigned char *cvector(nl,nh)
long nh,nl;
/* allocate an unsigned char vector with subscript range v[nl..nh] */
{
unsigned char *v;
v=(unsigned char *)malloc((unsigned int) ((nh-nl+1+NR_END)*sizeof(unsigned char)));
if (!v) nrerror("allocation failure in cvector()");
return v-nl+NR_END;
}
long *lvector(nl,nh)
long nh,nl;
/* allocate an unsigned long vector with subscript range v[nl..nh] */
{
long *v;
v=(long *)malloc((int) ((nh-nl+1+NR_END)*sizeof(long)));
if (!v) nrerror("allocation failure in lvector()");
return v-nl+NR_END;
}
double *dvector(nl,nh)
long nh,nl;
/* allocate a double vector with subscript range v[nl..nh] */
{
double *v;
v=(double *)malloc((unsigned int) ((nh-nl+1+NR_END)*sizeof(double)));
if (!v) nrerror("allocation failure in dvector()");
return v-nl+NR_END;
}
float **matrix(nrl,nrh,ncl,nch)
long nch,ncl,nrh,nrl;
/* allocate a float matrix with subscript range m[nrl..nrh][ncl..nch] */
{
long i, nrow=nrh-nrl+1,ncol=nch-ncl+1;
float **m;
/* allocate pointers to rows */
m=(float **) malloc((unsigned int)((nrow+NR_END)*sizeof(float*)));
if (!m) nrerror("allocation failure 1 in matrix()");
m += NR_END;
m -= nrl;
/* allocate rows and set pointers to them */
m[nrl]=(float *) malloc((unsigned int)((nrow*ncol+NR_END)*sizeof(float)));
if (!m[nrl]) nrerror("allocation failure 2 in matrix()");
m[nrl] += NR_END;
m[nrl] -= ncl;
for(i=nrl+1;i<=nrh;i++) m[i]=m[i-1]+ncol;
/* return pointer to array of pointers to rows */
return m;
}
double **dmatrix(nrl,nrh,ncl,nch)
long nch,ncl,nrh,nrl;
/* allocate a double matrix with subscript range m[nrl..nrh][ncl..nch] */
{
long i, nrow=nrh-nrl+1,ncol=nch-ncl+1;
double **m;
/* allocate pointers to rows */
m=(double **) malloc((unsigned int)((nrow+NR_END)*sizeof(double*)));
if (!m) nrerror("allocation failure 1 in matrix()");
m += NR_END;
m -= nrl;
/* allocate rows and set pointers to them */
m[nrl]=(double *) malloc((unsigned int)((nrow*ncol+NR_END)*sizeof(double)));
if (!m[nrl]) nrerror("allocation failure 2 in matrix()");
m[nrl] += NR_END;
m[nrl] -= ncl;
for(i=nrl+1;i<=nrh;i++) m[i]=m[i-1]+ncol;
/* return pointer to array of pointers to rows */
return m;
}
int **imatrix(nrl,nrh,ncl,nch)
long nch,ncl,nrh,nrl;
/* allocate a int matrix with subscript range m[nrl..nrh][ncl..nch] */
{
long i, nrow=nrh-nrl+1,ncol=nch-ncl+1;
int **m;
/* allocate pointers to rows */
m=(int **) malloc((unsigned int)((nrow+NR_END)*sizeof(int*)));
if (!m) nrerror("allocation failure 1 in matrix()");
m += NR_END;
m -= nrl;
/* allocate rows and set pointers to them */
m[nrl]=(int *) malloc((unsigned int)((nrow*ncol+NR_END)*sizeof(int)));
if (!m[nrl]) nrerror("allocation failure 2 in matrix()");
m[nrl] += NR_END;
m[nrl] -= ncl;
for(i=nrl+1;i<=nrh;i++) m[i]=m[i-1]+ncol;
/* return pointer to array of pointers to rows */
return m;
}
float **submatrix(a,oldrl,oldrh,oldcl,oldch,newrl,newcl)
float **a;
long newcl,newrl,oldch,oldcl,oldrh,oldrl;
/* point a submatrix [newrl..][newcl..] to a[oldrl..oldrh][oldcl..oldch] */
{
long i,j,nrow=oldrh-oldrl+1,ncol=oldcl-newcl;
float **m;
/* allocate array of pointers to rows */
m=(float **) malloc((unsigned int) ((nrow+NR_END)*sizeof(float*)));
if (!m) nrerror("allocation failure in submatrix()");
m += NR_END;
m -= newrl;
/* set pointers to rows */
for(i=oldrl,j=newrl;i<=oldrh;i++,j++) m[j]=a[i]+ncol;
/* return pointer to array of pointers to rows */
return m;
}
float **convert_matrix(a,nrl,nrh,ncl,nch)
float *a;
long nch,ncl,nrh,nrl;
/* allocate a float matrix m[nrl..nrh][ncl..nch] that points to the matrix
declared in the standard C manner as a[nrow][ncol], where nrow=nrh-nrl+1
and ncol=nch-ncl+1. The routine should be called with the address
&a[0][0] as the first argument. */
{
long i,j,nrow=nrh-nrl+1,ncol=nch-ncl+1;
float **m;
/* allocate pointers to rows */
m=(float **) malloc((unsigned int) ((nrow+NR_END)*sizeof(float*)));
if (!m) nrerror("allocation failure in convert_matrix()");
m += NR_END;
m -= nrl;
/* set pointers to rows */
m[nrl]=a-ncl;
for(i=1,j=nrl+1;i<nrow;i++,j++) m[j]=m[j-1]+ncol;
/* return pointer to array of pointers to rows */
return m;
}
double ***d3tensor(nrl,nrh,ncl,nch,ndl,ndh)
long nch,ncl,ndh,ndl,nrh,nrl;
/* allocate a float 3tensor with range t[nrl..nrh][ncl..nch][ndl..ndh] */
{
long i,j,nrow=nrh-nrl+1,ncol=nch-ncl+1,ndep=ndh-ndl+1;
double ***t;
/* allocate pointers to pointers to rows */
t=(double ***) malloc((unsigned int)((nrow+NR_END)*sizeof(double**)));
if (!t) nrerror("allocation failure 1 in f3tensor()");
t += NR_END;
t -= nrl;
/* allocate pointers to rows and set pointers to them */
t[nrl]=(double **) malloc((unsigned int)((nrow*ncol+NR_END)*sizeof(double*)));
if (!t[nrl]) nrerror("allocation failure 2 in f3tensor()");
t[nrl] += NR_END;
t[nrl] -= ncl;
/* allocate rows and set pointers to them */
t[nrl][ncl]=(double *) malloc((unsigned int)((nrow*ncol*ndep+NR_END)*sizeof(double)));
if (!t[nrl][ncl]) nrerror("allocation failure 3 in f3tensor()");
t[nrl][ncl] += NR_END;
t[nrl][ncl] -= ndl;
for(j=ncl+1;j<=nch;j++) t[nrl][j]=t[nrl][j-1]+ndep;
for(i=nrl+1;i<=nrh;i++) {
t[i]=t[i-1]+ncol;
t[i][ncl]=t[i-1][ncl]+ncol*ndep;
for(j=ncl+1;j<=nch;j++) t[i][j]=t[i][j-1]+ndep;
}
/* return pointer to array of pointers to rows */
return t;
}
float ***f3tensor(nrl,nrh,ncl,nch,ndl,ndh)
long nch,ncl,ndh,ndl,nrh,nrl;
/* allocate a float 3tensor with range t[nrl..nrh][ncl..nch][ndl..ndh] */
{
long i,j,nrow=nrh-nrl+1,ncol=nch-ncl+1,ndep=ndh-ndl+1;
float ***t;
/* allocate pointers to pointers to rows */
t=(float ***) malloc((unsigned int)((nrow+NR_END)*sizeof(float**)));
if (!t) nrerror("allocation failure 1 in f3tensor()");
t += NR_END;
t -= nrl;
/* allocate pointers to rows and set pointers to them */
t[nrl]=(float **) malloc((unsigned int)((nrow*ncol+NR_END)*sizeof(float*)));
if (!t[nrl]) nrerror("allocation failure 2 in f3tensor()");
t[nrl] += NR_END;
t[nrl] -= ncl;
/* allocate rows and set pointers to them */
t[nrl][ncl]=(float *) malloc((unsigned int)((nrow*ncol*ndep+NR_END)*sizeof(float)));
if (!t[nrl][ncl]) nrerror("allocation failure 3 in f3tensor()");
t[nrl][ncl] += NR_END;
t[nrl][ncl] -= ndl;
for(j=ncl+1;j<=nch;j++) t[nrl][j]=t[nrl][j-1]+ndep;
for(i=nrl+1;i<=nrh;i++) {
t[i]=t[i-1]+ncol;
t[i][ncl]=t[i-1][ncl]+ncol*ndep;
for(j=ncl+1;j<=nch;j++) t[i][j]=t[i][j-1]+ndep;
}
/* return pointer to array of pointers to rows */
return t;
}
char **cmatrix(nrl,nrh,ncl,nch)
long nch,ncl,nrh,nrl;
/* allocate a int matrix with subscript range m[nrl..nrh][ncl..nch] */
{
long i, nrow=nrh-nrl+1,ncol=nch-ncl+1;
char **m;
/* allocate pointers to rows */
m=(char **) malloc((unsigned int)((nrow+NR_END)*sizeof(char*)));
if (!m) nrerror("allocation failure 1 in matrix()");
m += NR_END;
m -= nrl;
/* allocate rows and set pointers to them */
m[nrl]=(char *) malloc((unsigned int)((nrow*ncol+NR_END)*sizeof(char)));
if (!m[nrl]) nrerror("allocation failure 2 in matrix()");
m[nrl] += NR_END;
m[nrl] -= ncl;
for(i=nrl+1;i<=nrh;i++) m[i]=m[i-1]+ncol;
/* return pointer to array of pointers to rows */
return m;
}
void free_vector(v,nl,nh)
float *v;
long nh,nl;
/* free a float vector allocated with vector() */
{
free((FREE_ARG) (v+nl-NR_END));
}
void free_ivector(v,nl,nh)
int *v;
long nh,nl;
/* free an int vector allocated with ivector() */
{
free((FREE_ARG) (v+nl-NR_END));
}
void free_cvector(v,nl,nh)
long nh,nl;
unsigned char *v;
/* free an unsigned char vector allocated with cvector() */
{
free((FREE_ARG) (v+nl-NR_END));
}
void free_lvector(v,nl,nh)
long nh,nl;
long *v;
/* free an long vector allocated with lvector() */
{
free((FREE_ARG) (v+nl-NR_END));
}
void free_dvector(v,nl,nh)
double *v;
long nh,nl;
/* free a double vector allocated with dvector() */
{
free((FREE_ARG) (v+nl-NR_END));
}
void free_matrix(m,nrl,nrh,ncl,nch)
float **m;
long nch,ncl,nrh,nrl;
/* free a float matrix allocated by matrix() */
{
free((FREE_ARG) (m[nrl]+ncl-NR_END));
free((FREE_ARG) (m+nrl-NR_END));
}
void free_dmatrix(m,nrl,nrh,ncl,nch)
double **m;
long nch,ncl,nrh,nrl;
/* free a double matrix allocated by dmatrix() */
{
free((FREE_ARG) (m[nrl]+ncl-NR_END));
free((FREE_ARG) (m+nrl-NR_END));
}
void free_imatrix(m,nrl,nrh,ncl,nch)
int **m;
long nch,ncl,nrh,nrl;
/* free an int matrix allocated by imatrix() */
{
free((FREE_ARG) (m[nrl]+ncl-NR_END));
free((FREE_ARG) (m+nrl-NR_END));
}
void free_submatrix(b,nrl,nrh,ncl,nch)
float **b;
long nch,ncl,nrh,nrl;
/* free a submatrix allocated by submatrix() */
{
free((FREE_ARG) (b+nrl-NR_END));
}
void free_convert_matrix(b,nrl,nrh,ncl,nch)
float **b;
long nch,ncl,nrh,nrl;
/* free a matrix allocated by convert_matrix() */
{
free((FREE_ARG) (b+nrl-NR_END));
}
void free_f3tensor(t,nrl,nrh,ncl,nch,ndl,ndh)
float ***t;
long nch,ncl,ndh,ndl,nrh,nrl;
/* free a float f3tensor allocated by f3tensor() */
{
free((FREE_ARG) (t[nrl][ncl]+ndl-NR_END));
free((FREE_ARG) (t[nrl]+ncl-NR_END));
free((FREE_ARG) (t+nrl-NR_END));
}
void free_d3tensor(t,nrl,nrh,ncl,nch,ndl,ndh)
double ***t;
long nch,ncl,ndh,ndl,nrh,nrl;
/* free a float f3tensor allocated by f3tensor() */
{
free((FREE_ARG) (t[nrl][ncl]+ndl-NR_END));
free((FREE_ARG) (t[nrl]+ncl-NR_END));
free((FREE_ARG) (t+nrl-NR_END));
}
void free_cmatrix(m,nrl,nrh,ncl,nch)
char **m;
long nch,ncl,nrh,nrl;
/* free a double matrix allocated by dmatrix() */
{
free((FREE_ARG) (m[nrl]+ncl-NR_END));
free((FREE_ARG) (m+nrl-NR_END));
}
#endif /* ANSI */
/* CAUTION: This is the ANSI C (only) version of the Numerical Recipes
utility file nrutil.h. Do not confuse this file with the same-named
file nrutil.h that may be supplied in a 'misc' subdirectory.
*That* file is the one from the book, and contains both ANSI and
traditional K&R versions, along with #ifdef macros to select the
correct version. *This* file contains only ANSI C. */
#ifndef _NR_UTILS_H_
#define _NR_UTILS_H_
static float sqrarg;
#define SQR(a) ((sqrarg=(a)) == 0.0 ? 0.0 : sqrarg*sqrarg)
static double dsqrarg;
#define DSQR(a) ((dsqrarg=(a)) == 0.0 ? 0.0 : dsqrarg*dsqrarg)
static double dmaxarg1,dmaxarg2;
#define DMAX(a,b) (dmaxarg1=(a),dmaxarg2=(b),(dmaxarg1) > (dmaxarg2) ?\
(dmaxarg1) : (dmaxarg2))
static double dminarg1,dminarg2;
#define DMIN(a,b) (dminarg1=(a),dminarg2=(b),(dminarg1) < (dminarg2) ?\
(dminarg1) : (dminarg2))
static float maxarg1,maxarg2;
#define FMAX(a,b) (maxarg1=(a),maxarg2=(b),(maxarg1) > (maxarg2) ?\
(maxarg1) : (maxarg2))
static float minarg1,minarg2;
#define FMIN(a,b) (minarg1=(a),minarg2=(b),(minarg1) < (minarg2) ?\
(minarg1) : (minarg2))
static long lmaxarg1,lmaxarg2;
#define LMAX(a,b) (lmaxarg1=(a),lmaxarg2=(b),(lmaxarg1) > (lmaxarg2) ?\
(lmaxarg1) : (lmaxarg2))
static long lminarg1,lminarg2;
#define LMIN(a,b) (lminarg1=(a),lminarg2=(b),(lminarg1) < (lminarg2) ?\
(lminarg1) : (lminarg2))
static int imaxarg1,imaxarg2;
#define IMAX(a,b) (imaxarg1=(a),imaxarg2=(b),(imaxarg1) > (imaxarg2) ?\
(imaxarg1) : (imaxarg2))
static int iminarg1,iminarg2;
#define IMIN(a,b) (iminarg1=(a),iminarg2=(b),(iminarg1) < (iminarg2) ?\
(iminarg1) : (iminarg2))
#define SIGN(a,b) ((b) >= 0.0 ? fabs(a) : -fabs(a))
void nrerror(char error_text[]);
float *vector(long nl, long nh);
int *ivector(long nl, long nh);
unsigned char *cvector(long nl, long nh);
long *lvector(long nl, long nh);
double *dvector(long nl, long nh);
float **matrix(long nrl, long nrh, long ncl, long nch);
double **dmatrix(long nrl, long nrh, long ncl, long nch);
int **imatrix(long nrl, long nrh, long ncl, long nch);
float **submatrix(float **a, long oldrl, long oldrh, long oldcl, long oldch,
long newrl, long newcl);
float **convert_matrix(float *a, long nrl, long nrh, long ncl, long nch);
float ***f3tensor(long nrl, long nrh, long ncl, long nch, long ndl, long ndh);
void free_vector(float *v, long nl, long nh);
void free_ivector(int *v, long nl, long nh);
void free_cvector(unsigned char *v, long nl, long nh);
void free_lvector(long *v, long nl, long nh);
void free_dvector(double *v, long nl, long nh);
void free_matrix(float **m, long nrl, long nrh, long ncl, long nch);
void free_dmatrix(double **m, long nrl, long nrh, long ncl, long nch);
void free_imatrix(int **m, long nrl, long nrh, long ncl, long nch);
void free_submatrix(float **b, long nrl, long nrh, long ncl, long nch);
void free_convert_matrix(float **b, long nrl, long nrh, long ncl, long nch);
void free_f3tensor(float ***t, long nrl, long nrh, long ncl, long nch,
long ndl, long ndh);
int ***i3tensor(long nrl, long nrh, long ncl, long nch, long ndl, long ndh);
void free_i3tensor(int ***t, long nrl, long nrh, long ncl, long nch,
long ndl, long ndh);
unsigned char ***b3tensor(long nrl, long nrh, long ncl, long nch, long ndl, long ndh);
void free_b3tensor(unsigned char ***t, long nrl, long nrh, long ncl, long nch,
long ndl, long ndh);
double ***d3tensor(long nrl, long nrh, long ncl, long nch, long ndl, long ndh);
void free_d3tensor(double ***t, long nrl, long nrh, long ncl, long nch,
long ndl, long ndh);
char **cmatrix(long nrl, long nrh, long ncl, long nch);
void free_cmatrix(char **m, long nrl, long nrh, long ncl, long nch);
#endif /* _NR_UTILS_H_ */
#include <math.h>
#define PI 3.141592654
float poidev(float xm, int *idum)
{
float gammln(float xx);
float ran1(int *idum);
static float sq,alxm,g,oldm=(-1.0);
float em,t,y;
if (xm < 12.0) {
if (xm != oldm) {
oldm=xm;
g=exp(-xm);
}
em = -1;
t=1.0;
do {
++em;
t *= ran1(idum);
} while (t > g);
} else {
if (xm != oldm) {
oldm=xm;
sq=sqrt(2.0*xm);
alxm=log(xm);
g=xm*alxm-gammln(xm+1.0);
}
do {
do {
y=tan(PI*ran1(idum));
em=sq*y+xm;
} while (em < 0.0);
em=floor(em);
t=0.9*(1.0+y*y)*exp(em*alxm-gammln(em+1.0)-g);
} while (ran1(idum) > t);
}
return em;
}
float poidev_copy(float xm, int *idum)
{
float gammln(float xx);
float ran1_copy(int *idum);
static float sq1,alxm1,g1,oldm1=(-1.0);
float em,t,y;
if (xm < 12.0) {
if (xm != oldm1) {
oldm1=xm;
g1=exp(-xm);
}
em = -1;
t=1.0;
do {
++em;
t *= ran1_copy(idum);
} while (t > g1);
} else {
if (xm != oldm1) {
oldm1=xm;
sq1=sqrt(2.0*xm);
alxm1=log(xm);
g1=xm*alxm1-gammln(xm+1.0);
}
do {
do {
y=tan(PI*ran1_copy(idum));
em=sq1*y+xm;
} while (em < 0.0);
em=floor(em);
t=0.9*(1.0+y*y)*exp(em*alxm1-gammln(em+1.0)-g1);
} while (ran1_copy(idum) > t);
}
return em;
}
#undef PI
/* (C) Copr. 1986-92 Numerical Recipes Software )1!. */
#define IA 16807
#define IM 2147483647
#define AM (1.0/IM)
#define IQ 127773
#define IR 2836
#define NTAB 32
#define NDIV (1+(IM-1)/NTAB)
#define EPS 1.2e-7
#define RNMX (1.0-EPS)
float ran1(int *idum)
{
int j;
int k;
//static
static int iy=0;
static int iv[NTAB];
float temp;
if (*idum <= 0 || !iy) {
if (-(*idum) < 1) *idum=1;
else *idum = -(*idum);
for (j=NTAB+7;j>=0;j--) {
k=(*idum)/IQ;
*idum=IA*(*idum-k*IQ)-IR*k;
if (*idum < 0) *idum += IM;
if (j < NTAB) iv[j] = *idum;
}
iy=iv[0];
}
k=(*idum)/IQ;
*idum=IA*(*idum-k*IQ)-IR*k;
if (*idum < 0) *idum += IM;
j=iy/NDIV;
iy=iv[j];
iv[j] = *idum;
if ((temp=AM*iy) > RNMX) return RNMX;
else return temp;
}
float ran1_copy(int *idum)
{
int j;
int k;
//static
static int iy1=0;
static int iv1[NTAB];
float temp;
if (*idum <= 0 || !iy1) {
if (-(*idum) < 1) *idum=1;
else *idum = -(*idum);
for (j=NTAB+7;j>=0;j--) {
k=(*idum)/IQ;
*idum=IA*(*idum-k*IQ)-IR*k;
if (*idum < 0) *idum += IM;
if (j < NTAB) iv1[j] = *idum;
}
iy1=iv1[0];
}
k=(*idum)/IQ;
*idum=IA*(*idum-k*IQ)-IR*k;
if (*idum < 0) *idum += IM;
j=iy1/NDIV;
iy1=iv1[j];
iv1[j] = *idum;
if ((temp=AM*iy1) > RNMX) return RNMX;
else return temp;
}
#undef IA
#undef IM
#undef AM
#undef IQ
#undef IR
#undef NTAB
#undef NDIV
#undef EPS
#undef RNMX
/* (C) Copr. 1986-92 Numerical Recipes Software )1!. */
#define IM1 2147483563
#define IM2 2147483399
#define AM (1.0/IM1)
#define IMM1 (IM1-1)
#define IA1 40014
#define IA2 40692
#define IQ1 53668
#define IQ2 52774
#define IR1 12211
#define IR2 3791
#define NTAB 32
#define NDIV (1+IMM1/NTAB)
#define EPS 1.2e-7
#define RNMX (1.0-EPS)
float ran2(long *idum)
{
int j;
long k;
static long idum2=123456789;
static long iy=0;
static long iv[NTAB];
float temp;
if (*idum <= 0) {
if (-(*idum) < 1) *idum=1;
else *idum = -(*idum);
idum2=(*idum);
for (j=NTAB+7;j>=0;j--) {
k=(*idum)/IQ1;
*idum=IA1*(*idum-k*IQ1)-k*IR1;
if (*idum < 0) *idum += IM1;
if (j < NTAB) iv[j] = *idum;
}
iy=iv[0];
}
k=(*idum)/IQ1;
*idum=IA1*(*idum-k*IQ1)-k*IR1;
if (*idum < 0) *idum += IM1;
k=idum2/IQ2;
idum2=IA2*(idum2-k*IQ2)-k*IR2;
if (idum2 < 0) idum2 += IM2;
j=iy/NDIV;
iy=iv[j]-idum2;
iv[j] = *idum;
if (iy < 1) iy += IMM1;
if ((temp=AM*iy) > RNMX) return RNMX;
else return temp;
}
#undef IM1
#undef IM2
#undef AM
#undef IMM1
#undef IA1
#undef IA2
#undef IQ1
#undef IQ2
#undef IR1
#undef IR2
#undef NTAB
#undef NDIV
#undef EPS
#undef RNMX
/* (C) Copr. 1986-92 Numerical Recipes Software )1!. */
#define NRANSI
#include "nrutil.h"
#define SWAP(a,b) temp=(a);(a)=(b);(b)=temp;
#define M 7
#define NSTACK 50
void sort(unsigned long n, float arr[])
{
unsigned long i,ir=n,j,k,l=1;
int jstack=0,*istack;
float a,temp;
istack=ivector(1,NSTACK);
for (;;) {
if (ir-l < M) {
for (j=l+1;j<=ir;j++) {
a=arr[j];
for (i=j-1;i>=1;i--) {
if (arr[i] <= a) break;
arr[i+1]=arr[i];
}
arr[i+1]=a;
}
if (jstack == 0) break;
ir=istack[jstack--];
l=istack[jstack--];
} else {
k=(l+ir) >> 1;
SWAP(arr[k],arr[l+1])
if (arr[l+1] > arr[ir]) {
SWAP(arr[l+1],arr[ir])
}
if (arr[l] > arr[ir]) {
SWAP(arr[l],arr[ir])
}
if (arr[l+1] > arr[l]) {
SWAP(arr[l+1],arr[l])
}
i=l+1;
j=ir;
a=arr[l];
for (;;) {
do i++; while (arr[i] < a);
do j--; while (arr[j] > a);
if (j < i) break;
SWAP(arr[i],arr[j]);
}
arr[l]=arr[j];
arr[j]=a;
jstack += 2;
if (jstack > NSTACK) nrerror("NSTACK too small in sort.");
if (ir-i+1 >= j-l) {
istack[jstack]=ir;
istack[jstack-1]=i;
ir=j-1;
} else {
istack[jstack]=j-1;
istack[jstack-1]=l;
l=i;
}
}
}
free_ivector(istack,1,NSTACK);
}
#undef M
#undef NSTACK
#undef SWAP
#undef NRANSI
/* (C) Copr. 1986-92 Numerical Recipes Software )1!. */
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment