def integrate_map(band,skypos,tranges,skyrange,width=False,height=False, verbose=0,memlight=False,hdu=False,retries=20,response=False, detsize=1.1): """ Integrate an image over some number of time ranges. Use a reduced memory optimization (at the expense of more web queries) if requested. """ imsz = gxt.deg2pix(skypos,skyrange) img = np.zeros(imsz) for trange in tranges: # If memlight is requested, break the integration into # smaller chunks. # FIXME: memlight gives slightly wrong answers right now # This is probably due to a quirk of SQL, per issue #140. # Deprecating memlight until this can be resolved. step = memlight if memlight else trange[1]-trange[0] for i in np.arange(trange[0],trange[1],step): t0,t1=i,i+step if verbose: mc.print_inline('Coadding '+str(t0)+' to '+str(t1)) img += makemap(band,skypos,[t0,t1],skyrange,response=response, verbose=verbose,detsize=detsize) if response: # This is an intensity map. img /= dbt.compute_exptime(band,trange,skypos=skypos, verbose=verbose) return img
def fits_header(band,skypos,tranges,skyrange,width=False,height=False, verbose=0,tscale=1000.,hdu=False,retries=20): """Populate a FITS header.""" if verbose: print_inline('Populating FITS header.') hdu = hdu if hdu else pyfits.PrimaryHDU() wcs = define_wcs(skypos,skyrange,width=width,height=height) hdu.header['CDELT1'],hdu.header['CDELT2'] = wcs.wcs.cdelt hdu.header['CTYPE1'],hdu.header['CTYPE2'] = wcs.wcs.ctype hdu.header['CRPIX1'],hdu.header['CRPIX2'] = wcs.wcs.crpix hdu.header['CRVAL1'],hdu.header['CRVAL2'] = wcs.wcs.crval #hdu.header['RA_CENT'],hdu.header['DEC_CENT'] = wcs.wcs.crval # Dupe. hdu.header['EQUINOX'],hdu.header['EPOCH'] = 2000., 2000. hdu.header['BAND'] = 1 if band=='NUV' else 2 # Do we want to set the following? #hdu.header['OW'] = 1 #hdu.header['DIRECT'] = 1 #hdu.header['GRISM'] = 0 #hdu.header['OPAQUE'] = 0 # Put the total exposure time into the primary header hdu.header['EXPTIME'] = 0. for trange in tranges: hdu.header['EXPTIME'] += dbt.compute_exptime(band,trange, verbose=verbose,retries=retries) if len(tranges)==1: # Put the time range into the primary header for a single frame image hdu.header['EXPSTART'],hdu.header['EXPEND'] = tranges[0] # These are the proper keywords for this: hdu.header['TIME-OBS'],hdu.header['TIME-END'] = tranges[0] return hdu
def netdead(band,t0,t1,tstep=1.,refrate=79.,verbose=0): print 'Time range: ['+str(t0)+', '+str(t1)+']' refrate = 79. # counts per second, nominal stim rate feeclkratio = 0.966 # not sure what detector property this adjusts for tec2fdead = 5.52e-6 # TEC to deadtime correction (Method 2) stimcount = gQuery.getValue(gQuery.stimcount(band,t0,t1)) totcount = (gQuery.getValue(gQuery.deadtime1(band,t0,t1)) + gQuery.getValue(gQuery.deadtime2(band,t0,t1))) exptime = t1-t0 # Method 0 # Empirical formula dead0 = tec2fdead*(totcount/exptime)/feeclkratio minrate,maxrate = refrate*.4,refrate+2. # Method 2 # Direct measurement of stims bins = np.linspace(0.,exptime-exptime%tstep,exptime//tstep+1)+t0 h = np.zeros(len(bins)) for i,t in enumerate(bins): print_inline(t1-t) h[i] = gQuery.getValue(gQuery.stimcount(band,t,t+tstep-0.0001)) #h,xh = np.histogram(stimt-trange[0],bins=bins) ix = ((h<=maxrate) & (h>=minrate)).nonzero()[0] dead2 = (1.-((h[ix]/tstep)/feeclkratio)/refrate).mean() # Method 1 # Empirical formula except with counts binned into 1s h = np.zeros(len(bins)) for i,t in enumerate(bins): print_inline(t1-t) h[i] = gQuery.getValue(gQuery.deadtime1(band,t,t+tstep-0.0001)) + gQuery.getValue(gQuery.deadtime2(band,t,t+tstep-0.0001)) dead1 = (tec2fdead*(h/tstep)/feeclkratio).mean() expt = compute_exptime(band,[t0,t1]) print dead0,dead1,dead2 return [t0, t1, dead0, dead1, dead2, expt, stimcount, totcount]
def movie_tbl(band,tranges,verbose=0,framesz=0,retries=20): """Initialize a FITS table to contain movie frame information.""" if verbose: print_inline('Populating exposure time table.') tstarts,tstops,exptimes=[],[],[] for trange in tranges: stepsz = framesz if framesz else trange[1]-trange[0] steps = np.ceil((trange[1]-trange[0])/stepsz) for i,t0 in enumerate(np.arange(trange[0],trange[1],stepsz)): t1 = trange[1] if i==steps else t0+stepsz tstarts.append(t0) tstops.append(t1) exptimes.append(dbt.compute_exptime(band,[t0,t1], verbose=verbose,retries=retries)) col1 = pyfits.Column(name='tstart',format='E',array=np.array(tstarts)) col2 = pyfits.Column(name='tstop',format='E',array=np.array(tstops)) col3 = pyfits.Column(name='exptime',format='E',array=np.array(exptimes)) cols = pyfits.ColDefs([col1,col2,col3]) tbl = pyfits.new_table(cols) return tbl
def netdead(band, t0, t1, tstep=1., refrate=79., verbose=0): print 'Time range: [' + str(t0) + ', ' + str(t1) + ']' refrate = 79. # counts per second, nominal stim rate feeclkratio = 0.966 # not sure what detector property this adjusts for tec2fdead = 5.52e-6 # TEC to deadtime correction (Method 2) stimcount = gQuery.getValue(gQuery.stimcount(band, t0, t1)) totcount = (gQuery.getValue(gQuery.deadtime1(band, t0, t1)) + gQuery.getValue(gQuery.deadtime2(band, t0, t1))) exptime = t1 - t0 # Method 0 # Empirical formula dead0 = tec2fdead * (totcount / exptime) / feeclkratio minrate, maxrate = refrate * .4, refrate + 2. # Method 2 # Direct measurement of stims bins = np.linspace(0., exptime - exptime % tstep, exptime // tstep + 1) + t0 h = np.zeros(len(bins)) for i, t in enumerate(bins): print_inline(t1 - t) h[i] = gQuery.getValue(gQuery.stimcount(band, t, t + tstep - 0.0001)) #h,xh = np.histogram(stimt-trange[0],bins=bins) ix = ((h <= maxrate) & (h >= minrate)).nonzero()[0] dead2 = (1. - ((h[ix] / tstep) / feeclkratio) / refrate).mean() # Method 1 # Empirical formula except with counts binned into 1s h = np.zeros(len(bins)) for i, t in enumerate(bins): print_inline(t1 - t) h[i] = gQuery.getValue(gQuery.deadtime1( band, t, t + tstep - 0.0001)) + gQuery.getValue( gQuery.deadtime2(band, t, t + tstep - 0.0001)) dead1 = (tec2fdead * (h / tstep) / feeclkratio).mean() expt = compute_exptime(band, [t0, t1]) print dead0, dead1, dead2 return [t0, t1, dead0, dead1, dead2, expt, stimcount, totcount]
def rrhr(band,skypos,tranges,skyrange,width=False,height=False,stepsz=1., verbose=0,calpath='../cal/',tscale=1000.,response=True,hdu=False, retries=20): """Generate a high resolution relative response (rrhr) map.""" imsz = gxt.deg2pix(skypos,skyrange) # TODO the if width / height flat = get_fits_data(flat_filename(band,calpath),verbose=verbose) flatinfo = get_fits_header(flat_filename(band,calpath)) npixx,npixy = flat.shape fltsz = flat.shape pixsz = flatinfo['CDELT2'] detsize = 1.25 # Rotate the flat into the correct orientation to start. flat = np.flipud(np.rot90(flat)) # NOTE: This upsample interpolation is done _last_ in the canonical # pipeline as part of the poissonbg.c routine. # The interpolation function is "congrid" in the same file. # TODO: Should this be first order interpolation? (i.e. bilinear) hrflat = scipy.ndimage.interpolation.zoom(flat,4.,order=0,prefilter=False) img = np.zeros(hrflat.shape)[ hrflat.shape[0]/2.-imsz[0]/2.:hrflat.shape[0]/2.+imsz[0]/2., hrflat.shape[1]/2.-imsz[1]/2.:hrflat.shape[1]/2+imsz[1]/2.] for trange in tranges: t0,t1=trange entries = gQuery.getArray(gQuery.aspect(t0,t1),retries=retries) n = len(entries) asptime = np.float64(np.array(entries)[:,2])/tscale aspra = np.float32(np.array(entries)[:,3]) aspdec = np.float32(np.array(entries)[:,4]) asptwist= np.float32(np.array(entries)[:,5]) aspflags= np.float32(np.array(entries)[:,6]) asptwist= np.float32(np.array(entries)[:,9]) aspra0 = np.zeros(n)+skypos[0] aspdec0 = np.zeros(n)+skypos[1] xi_vec, eta_vec = gnomonic.gnomfwd_simple( aspra,aspdec,aspra0,aspdec0,-asptwist,1.0/36000.,0.) col = 4.*( ((( xi_vec/36000.)/(detsize/2.)*(detsize/(fltsz[0]*pixsz)) + 1.)/2. * fltsz[0]) - (fltsz[0]/2.) ) row = 4.*( (((eta_vec/36000.)/(detsize/2.)*(detsize/(fltsz[1]*pixsz)) + 1.)/2. * fltsz[1]) - (fltsz[1]/2.) ) vectors = rotvec(np.array([col,row]),-asptwist) for i in range(n): if verbose>1: print_inline('Stamping '+str(asptime[i])) # FIXME: Clean this mess up a little just for clarity. img += scipy.ndimage.interpolation.shift(scipy.ndimage.interpolation.rotate(hrflat,-asptwist[i],reshape=False,order=0,prefilter=False),[vectors[1,i],vectors[0,i]],order=0,prefilter=False)[hrflat.shape[0]/2.-imsz[0]/2.:hrflat.shape[0]/2.+imsz[0]/2.,hrflat.shape[1]/2.-imsz[1]/2.:hrflat.shape[1]/2+imsz[1]/2.]*dbt.compute_exptime(band,[asptime[i],asptime[i]+1],verbose=verbose,retries=retries)*gxt.compute_flat_scale(asptime[i]+0.5,band,verbose=0) return img
def quickmag(band, ra0, dec0, tranges, radius, annulus=None, data={}, stepsz=None, verbose=0, maskdepth=20.0, maskradius=1.5,detsize=1.25,coadd=False, photonfile=None): if verbose: mc.print_inline("Retrieving all of the target events.") trange = [np.array(tranges).min(),np.array(tranges).max()] try: searchradius = annulus[1] except TypeError: searchradius = radius data = pullphotons(band, ra0, dec0, tranges, searchradius, verbose=verbose, photonfile=photonfile) if verbose: mc.print_inline("Isolating source from background.") angSep = mc.angularSeparation(ra0, dec0, data['ra'], data['dec']) if verbose: mc.print_inline("Binning data according to requested depth.") # Multiple ways of defining bins if coadd: bins = np.array(trange) elif stepsz: bins = np.append(np.arange(min(trange), max(trange), stepsz), max(trange)) else: bins = np.unique(np.array(tranges).flatten()) # This is equivalent in function to np.digitize(data['t'],bins) except # that it's much, much faster. See numpy issue #2656. ix = np.searchsorted(bins,data['t'],"right") # Initialize histogrammed arrays # FIXME: allocate these from a dict of constructors lcurve_cols = ['counts', 'sources', 'bg_counts','responses', 'detxs', 'detys', 't0_data', 't1_data', 't_mean', 'racent', 'deccent'] lcurve = {'params':gphot_params(band,[ra0,dec0],radius,annulus=annulus, verbose=verbose, detsize=detsize,stepsz=stepsz, trange=trange,maskdepth=maskdepth, maskradius=maskradius)} for col in lcurve_cols: lcurve[col] = np.zeros(len(bins)-1) # FIXME: Bottleneck. There's probably a way to do this without looping. # Don't bother looping through anything with no data. lcurve['bg'] = {'simple':np.zeros(len(bins)-1), 'cheese':np.zeros(len(bins)-1)} if annulus is not None: lcurve['bg']['sources'] = bg_sources(band,ra0,dec0,annulus[1], maskdepth=maskdepth) lcurve['bg']['eff_area'] = cheese_bg_area(band,ra0,dec0,annulus, lcurve['bg']['sources']) else: lcurve['bg']['sources'] = None lcurve['bg']['eff_area'] = 0. if verbose: mc.print_inline("Populating histograms.") for cnt,i in enumerate(np.unique(ix)): # Exclude data outside of the bins in searchsorted. if i-1<0 or i==len(bins): continue if verbose: mc.print_inline('Binning {i} of {l}.'.format( i=cnt,l=len(np.unique(ix)))) t_ix = np.where(ix==i) # TODO: Optionally limit data to specific parts of detector. rad_ix = np.where((angSep <= radius) & (ix == i)) # NOTE: This checks for the dim edge case where you have photons in # the annulus but not in the aperture. if not len(rad_ix[0]): continue lcurve['t0_data'][i-1] = data['t'][rad_ix].min() lcurve['t1_data'][i-1] = data['t'][rad_ix].max() lcurve['t_mean'][i-1] = data['t'][rad_ix].mean() lcurve['counts'][i-1] = len(rad_ix[0]) lcurve['sources'][i-1] = (1./data['response'][rad_ix]).sum() lcurve['responses'][i-1] = data['response'][rad_ix].mean() lcurve['detxs'][i-1] = data['col'][rad_ix].mean() lcurve['detys'][i-1] = data['row'][rad_ix].mean() lcurve['racent'][i-1] = data['ra'][rad_ix].mean() lcurve['deccent'][i-1] = data['dec'][rad_ix].mean() if annulus is not None: ann_ix = np.where((angSep > annulus[0]) & (angSep <= annulus[1]) & (ix == i)) lcurve['bg_counts'][i-1] = len(ann_ix[0]) # Background is reported as counts within the aperture lcurve['bg']['simple'][i-1] = (mc.area(radius) * (1./data['response'][ann_ix]).sum() / (mc.area(annulus[1])-mc.area(annulus[0]))) lcurve['bg']['cheese'][i-1] = cheese_bg(band, ra0, dec0, radius, annulus, data['ra'][t_ix], data['dec'][t_ix], data['response'][t_ix], maskdepth=maskdepth, eff_area=lcurve['bg']['eff_area'], sources=lcurve['bg']['sources']) else: lcurve['bg_counts'][i-1]=0. lcurve['bg']['simple'][i-1]=0. lcurve['bg']['cheese'][i-1]=0. # Only return bins that contain data. ix = np.where((np.isfinite(lcurve['sources'])) & (np.array(lcurve['sources']) > 0)) lcurve['t0'] = bins[ix] lcurve['t1'] = bins[ix[0]+1] for col in lcurve_cols: lcurve[col] = lcurve[col][ix] if annulus is not None: lcurve['bg']['simple']=lcurve['bg']['simple'][ix] lcurve['bg']['cheese']=lcurve['bg']['cheese'][ix] else: lcurve['bg']['simple']=0. lcurve['bg']['cheese']=0. lcurve['exptime'] = np.array( [dbt.compute_exptime(band,trange,skypos=[ra0,dec0], verbose=verbose,coadd=coadd) for trange in zip(lcurve['t0_data'],lcurve['t1_data'])]) if verbose: mc.print_inline("Returning curve data.") lcurve['photons'] = data return lcurve