def make_synthetic_observation(srcmodel_file, expmap_file, bgmap_file, maskmap_file, outfile, targ_cts=2000): """ Take a synthetic sb model and turn it into a "observation" by applying an exposure map, bg image and mask. 'srcmodel' - model of the source poissonized in units [cts], normed to required total cts 'expmap' - exposure map 'bgmap' - background map (smooth, units cts) 'maskmap' - mask """ POISSONIZE_IMAGE = True # load images expmap, hdr = load_fits_im(expmap_file) bgmap, hdr = load_fits_im(bgmap_file) maskmap, hdr = load_fits_im(maskmap_file, 1) # mask is in ext1 srcmodel, hdr = load_fits_im(srcmodel_file) # trim sizes if necessary (should be needed only in case of manual # testing) and works only in the (most typical) case of # 1row/column difference if srcmodel.shape[0] == expmap.shape[0]-2: expmap = trim_fftconvolve(expmap) if srcmodel.shape[0] == bgmap.shape[0]-2: bgmap = trim_fftconvolve(bgmap) if srcmodel.shape[0] == maskmap.shape[0]-2: maskmap = trim_fftconvolve(maskmap) # prepare the transforms output_im = srcmodel bgmap_poi = bgmap * maskmap # get rid of artifacts output_im_poi = srcmodel * expmap # model should be in cts/s/pix, this # way you get cts/pix as in # obsercvations print 'Number of total cts :: ', sum(output_im_poi) try: # would be better to limit to r500 print 'Norming to expected total cts :: ', targ_cts output_im_poi = targ_cts * output_im_poi / sum(output_im_poi) except Exception, e: print 'source image is empty!' raise e
def v06_psf_2d_lmfit_profile(pars,distmatrix,bgrid,r500,instrument, theta, energy, xcen_obj,ycen_obj,data_profile=None, data_profile_err=None): """ Fits the surface brightness profile by creating a 2D model of the image - v06 model (without the central beta model) x psf No bg. Also allows to return directly residuals. """ USE_ERROR=True # debug option # make first a 2D image model_image = make_2d_v06_psf(pars, distmatrix, bgrid, r500, instrument, theta, energy) # FIXME: is this necessary for each step? # trim distmatrix size to image post convolution distmatrix = roll(roll(distmatrix,2,axis=0),2,axis=1) distmatrix = trim_fftconvolve(distmatrix) # profile extraction r_length = r500 # factor out r500 r = arange(1.0, r_length+1, 1.0) (profile, geometric_area) = extract_profile_fast2(model_image, distmatrix, bgrid) model_profile = profile[0:r_length] / geometric_area[0:r_length] # trim the corners # print '*'*30 # print len(r), len(model_profile) # print len(profile[0:r_length]), r_length # # print len(data_profile[0:r_length]), len(model_profile), r500, r_length # print '*'*30 if data_profile == None: # return (r, model_profile, geometric_area) return (r, model_profile) else: residuals = data_profile - model_profile # is this biasing? if USE_ERROR: residuals = residuals / data_profile_err print "full resid :: ", sum(residuals) # return residuals return residuals
def make_2d_beta_psf(pars, imsize, xsize_obj, ysize_obj, instrument, im_psf, APPLY_PSF, DO_ZERO_PAD): """ Creates a 2D image of a beta model convolved with psf Arguments: """ # FIXME: the _object coordinates are not needed anymore # hdr = pyfits.getheader('pn-test.fits') # FIXME: would be better to create a fits header from scratch xcen = pars['xcen'].value ycen = pars['ycen'].value norm = pars['norm_'+instrument].value rcore = pars['rcore'].value beta = pars['beta'].value im_beta = make_2d_beta(imsize, xcen, ycen, norm, rcore, beta) # hdu = pyfits.PrimaryHDU(im_beta, hdr) # extension - array, header # hdulist = pyfits.HDUList([hdu]) # list all extensions here # hdulist.writeto('tmpa.fits', clobber=True) # if DO_ZERO_PAD: im_beta = zero_pad_image(im_beta, xsize_obj) # hdu = pyfits.PrimaryHDU(im_beta, hdr) # extension - array, header # hdulist = pyfits.HDUList([hdu]) # list all extensions here # hdulist.writeto('tmp0.fits', clobber=True) im_output = im_beta if APPLY_PSF: # create PSF # im_psf = make_2d_king_old(imsize, xcen, ycen, instrument, theta, energy) # im_psf = psf[instrument] # convolve im_output = fftconvolve(im_beta.astype(float), im_psf.astype(float), mode = 'same') im_output = trim_fftconvolve(im_output) return im_output
def make_2d_v06_psf(pars, distmatrix, bgrid, r500, instrument, im_psf): """ Creates a 2D image of a vikhlinin et al. 2006 model convolved with psf. """ # APPLY_PSF = True rc = pars['rc'].value rs = pars['rs'].value n0 = pars['n0_'+instrument].value alpha = pars['alpha'].value beta = pars['beta'].value gamma = pars['gamma'].value epsilon = pars['epsilon'].value im_output = make_2d_v06(distmatrix, bgrid, r500, rc, rs, n0, alpha, beta, gamma, epsilon) # convolve im_output = fftconvolve(im_output.astype(float), im_psf.astype(float), mode = 'same') im_output = trim_fftconvolve(im_output) return im_output
def v06_psf_2d_lmfit_profile_joint(pars,distmatrix,bgrid, rfit, instruments, psf_dict, xcen_obj,ycen_obj, data_r=None, data_profile=None, data_profile_err=None): """ Fits the surface brightness profile by creating a 2D model of the image - v06 model (without the central beta model) x psf for a combinaiton of instruments No bg. Also allows to return directly residuals. """ USE_ERROR=True # debug option # setup dictionaries model_image = {} profile = {} geometric_area = {} model_profile = {} # profile extraction r = arange(1.0, rfit+1, 1.0) # make first a 2D image for instrument in instruments: model_image[instrument] = make_2d_v06_psf(pars, distmatrix, bgrid, rfit, instrument, psf_dict[instrument]) # FIXME: is this necessary for each step? - would require to # have 2 distance matrices! trim distmatrix size to image # post convolution distmatrix = roll(roll(distmatrix,2,axis=0),2,axis=1) distmatrix = trim_fftconvolve(distmatrix) (profile[instrument], geometric_area[instrument]) = \ extract_profile_fast2(model_image[instrument], distmatrix, bgrid) # trim the corners model_profile[instrument] = profile[instrument][0:rfit] / geometric_area[instrument][0:rfit] # FIXME: bin here if data_profile == None: # return (r, model_profile, geometric_area) return (r, model_profile) else: # combine the likelihoods residuals = 0.0 for instrument in instruments: residuals_inst = abs(data_profile[instrument] - model_profile[instrument]) # is this biasing? if USE_ERROR: residuals_inst = residuals_inst / data_profile_err[instrument] print instrument, "resid :: ", sum(residuals_inst) residuals = residuals + residuals_inst print pars['n0_'+instruments[0]].value, pars['alpha'].value, pars['beta'].value, pars['epsilon'].value, pars['rc'].value, pars['rs'].value print "full resid :: ", sum(residuals), "Chisqr :: ", sum(residuals**2) print '='*35 return residuals