def sim_evlist(flux=.1, obstime=.5, arf=None, rmf=None, extra=None, output_filename_base=None, write_pha=False, do_graphical_output=True, loglevel='INFO') : # Time it! t_1 = time.clock() # Configure logging numeric_level = getattr(logging, loglevel.upper(), None) if not isinstance(numeric_level, int): raise ValueError('Invalid log level: %s' % loglevel) logging.basicConfig(level=numeric_level, format='%(asctime)s - %(levelname)s - %(message)s', datefmt='%Y-%m-%d %H:%M:%S') # Welcome user, print out basic information on package versions logging.info('This is {0} (pyfact v{1})'.format(os.path.split(__file__)[1], pf.__version__)) logging.info('We are running with numpy v{0}, scipy v{1}, and pyfits v{2}'.format( np.__version__, scipy.__version__, pyfits.__version__ )) #--------------------------------------------------------------------------- logging.info('Exposure: {0} h'.format(obstime)) obstime *= 3600. #observation time in seconds obj_ra, obj_dec = 0., .5 pnt_ra, pnt_dec = 0., 0. t_min = 24600. objcosdec = np.cos(obj_dec * np.pi / 180.) #--------------------------------------------------------------------------- # Read ARF, RMF, and extra file logging.info('ARF: {0}'.format(arf)) ea, ea_erange = pf.arf_to_np(pyfits.open(arf)[1]) # DEBUG #ea /= irf_data[:,4] rm, rm_erange, rm_ebounds, rm_minprob = None, ea_erange, None, None if rmf : logging.info('RMF: {0}'.format(rmf)) rm, rm_erange, rm_ebounds, rm_minprob = pf.rmf_to_np(pyfits.open(rmf)) if extra : logging.info('Extra file: {0}'.format(extra)) extraf = pyfits.open(extra) logging.info('Using effective area with 80% containment from extra file') ea = extraf['EA80'].data.field('VAL') / .8 # 100% effective area ea_erange = 10. ** np.hstack([extraf['EA80'].data.field('BIN_LO'), extraf['EA80'].data.field('BIN_HI')[-1]]) else : logging.info('Assuming energy independent 80% cut efficiency for ARF file.') ea /= .80 #--------------------------------------------------------------------------- # Signal #log_e_cen = (irf_data[:,0] + irf_data[:,1]) / 2. e_cen = 10. ** ((np.log10(ea_erange[1:]*ea_erange[:-1])) / 2.) ea_loge_step_mean = np.log10(ea_erange[1:]/ea_erange[:-1]).mean().round(4) D('ea_loge_step_mean = {0}', ea_loge_step_mean) # DEBUG #ea_s, e_cen_s = ea, e_cen # Resample effective area to increase precision if ea_loge_step_mean > .1 : elog10step = .05 logging.info('Resampling effective area in log10(EA) vs log10(E) (elog10step = {0})'.format(elog10step)) ea_spl = scipy.interpolate.UnivariateSpline(e_cen, np.log10(ea), s=0, k=1) e_cen = 10. ** np.arange(np.log10(e_cen[0]), np.log10(e_cen[-1]), step=elog10step) ea = 10. ** ea_spl(e_cen) # DEBUG plot #plt.loglog(e_cen_s, ea_s, ) #plt.loglog(e_cen, ea, '+') #plt.show() func_pl = lambda x, p: p[0] * x ** (-p[1]) flux_f = lambda x : func_pl(x, (3.45E-11 * flux, 2.63)) f_test = scipy.interpolate.UnivariateSpline(e_cen, ea * flux_f(e_cen) * 1E4, s=0, k=1) # m^2 > cm^2 log_e_steps = np.log10(rm_erange) # Calculate event numbers for the RMF bins def get_int_rate(emin, emax) : if emin < e_cen[0] or emax > e_cen[-1] : return 0. else : return f_test.integral(emin, emax) int_rate = np.array([get_int_rate(10. ** el, 10. ** eh) for (el, eh) in zip(log_e_steps[:-1], log_e_steps[1:])]) # Sanity int_rate[int_rate < 0.] = 0. # DEBUG #int_rate_s = int_rate if rmf : D('Photon rate before RM = {0}', np.sum(int_rate)) # Apply energy distribution matrix int_rate = np.dot(int_rate, rm) D('Photon rate after RM = {0}', np.sum(int_rate)) # DEBUG plots #plt.figure(1) #plt.semilogy(log_e_steps[:-1], int_rate_s, 'o', label='PRE RMF') ##plt.plot(log_e_steps[:-1], int_rate_s, 'o', label='PRE RMF') #if rmf : # plt.semilogy(np.log10(rm_ebounds[:-1]), int_rate, '+', label='POST RMF') #plt.ylim(1E-6,1.) #plt.legend() #plt.show() ##sys.exit(0) # Calculate cumulative event numbers int_all = np.sum(int_rate) int_rate = np.cumsum(int_rate) if rmf : #log_e_steps = (np.log10(rm_ebounds[1:]) + np.log10(rm_ebounds[:-1])) / 2. log_e_steps = np.log10(rm_ebounds) # Filter out low and high values to avoid spline problems at the edges istart = np.sum(int_rate == 0.) - 1 if istart < 0 : istart = 0 istop = np.sum(int_rate / int_all > 1. - 1e-4) # This value dictates the dynamic range at the high energy end D('istart = {0}, istop = {1}', istart, istop) # DEBUG plots #plt.plot(int_rate[istart:-istop] / int_all, log_e_steps[istart + 1:-istop], '+') #plt.show() # DEBUG plots #plt.hist(int_rate[istart:-istop] / int_all) #plt.show() ev_gen_f = scipy.interpolate.UnivariateSpline( int_rate[istart:-istop] / int_all, log_e_steps[istart + 1:-istop], s=0, k=1 ) ## DEBUG plot #plt.plot(np.linspace(0.,1.,100), ev_gen_f(np.linspace(0.,1.,100)), 'o') #plt.show() # Test event generator function n_a_t = 100. a_t = ev_gen_f(np.linspace(0.,1., n_a_t)) D('Test ev_gen_f, (v = 0 / #v) = {0}, (v = NaN / #v) = {1}', np.sum(a_t == 0.) / n_a_t, np.sum(np.isnan(a_t)) / n_a_t) if (np.sum(a_t == 0.) / n_a_t > 0.05) or (np.sum(np.isnan(a_t)) / n_a_t > .05) : raise Exception('Could not generate event generator function for photons. Try to decrease the upper cut-off value in the code.') # Calculate total number of photon events n_events = int_all * obstime logging.debug('Number of photons : {0}'.format(n_events)) # Generate energy event list evlist_e = ev_gen_f(np.random.rand(n_events)) # Sanity D('Number of photons with E = NaN : {0}', np.sum(np.isnan(evlist_e))) evlist_e[np.isnan(evlist_e)] = 0. ## DEBUG plot #plt.figure(1) #plt.hist(evlist_e, range=[-2.,2.], bins=20) ##plt.show() #sys.exit(0) #------------------------------------------------------ # Apply PSF # Broken power law fit function, normalized at break energy bpl = lambda p,x : np.where(x < p[0], p[1] * (x / p[0]) ** -p[2], p[1] * (x / p[0]) ** -p[3]) evlist_psf = None if extra : d = extraf['ANGRES68'].data g = scipy.interpolate.UnivariateSpline((d.field('BIN_LO') + d.field('BIN_HI')) / 2., d.field('VAL'), s=0, k=1) evlist_psf = g(evlist_e) else : psf_p1 = [1.1, 5.5E-2, .42, .19] # Fit from SubarrayE_IFAE_50hours_20101102 evlist_psf = bpl(psf_p1, 10. ** evlist_e) logging.warning('Using dummy PSF extracted from SubarrayE_IFAE_50hours_20101102') evlist_dec = obj_dec + np.random.randn(n_events) * evlist_psf evlist_ra = obj_ra + np.random.randn(n_events) * evlist_psf / objcosdec evlist_t = t_min + obstime * np.random.rand(n_events) / 86400. #--------------------------------------------------------------------------- # Background #plt.figure(1) p_rate_area, log_e_cen = None, None if extra : d = extraf['BGRATED'].data p_rate_area = d.field('VAL') log_e_cen = (d.field('BIN_LO') + d.field('BIN_HI')) / 2 #g = scipy.interpolate.UnivariateSpline((d.field('BIN_LO') + d.field('BIN_HI')) / 2., d.field('VAL'), s=0, k=1) else : logging.warning('Using dummy background rate extracted from SubarrayE_IFAE_50hours_20101102') bgrate_p1 = [9., 5.E-4, 1.44, .49] # Fit from SubarrayE_IFAE_50hours_20101102 log_e_cen = np.linspace(-1.5, 2., 35.) p_rate_area = bpl(bgrate_p1, 10. ** log_e_cen) p_rate_area[log_e_cen < -1.] = .4 # DEBUG plot plt.semilogy(log_e_cen, p_rate_area) plt.show() p_rate_total = np.sum(p_rate_area) ev_gen_f = scipy.interpolate.UnivariateSpline( np.cumsum(p_rate_area) / np.sum(p_rate_area), log_e_cen, s=0, k=1 ) cam_acc = lambda p, x: p[0] * x ** 0. * (1. + (x / p[1]) ** p[2]) ** ((0. + p[3]) / p[2]) cam_acc_par = (1.,1.7, 6., -5.5) r_steps = np.linspace(0.001, 4., 150) int_cam_acc = np.zeros(150) for i, r in enumerate(r_steps) : int_cam_acc[i] = scipy.integrate.quad(lambda x: cam_acc(cam_acc_par, x) * x * 2. * np.pi, 0., r)[0] n_events_bg = int(p_rate_total * obstime * int_cam_acc[-1]) logging.debug('Number of protons : {0}'.format(n_events_bg)) tplt_multi = 5 evlist_bg_e = ev_gen_f(np.random.rand(n_events_bg * (tplt_multi + 1))) ev_gen_f2 = scipy.interpolate.UnivariateSpline( int_cam_acc / scipy.integrate.quad(lambda x: cam_acc(cam_acc_par, x) * 2. * x * np.pi, 0., 4.)[0], r_steps, s=0, k=1 ) evlist_bg_r = ev_gen_f2(np.random.rand(n_events_bg * (tplt_multi + 1))) r_max = 4. #evlist_bg_r = np.sqrt(np.random.rand(n_events_bg * (tplt_multi + 1))) * r_max rnd = np.random.rand(n_events_bg * (1 + tplt_multi)) evlist_bg_rx = np.sqrt(rnd) * evlist_bg_r * np.where(np.random.randint(2, size=(n_events_bg * (tplt_multi + 1))) == 0, -1., 1.) evlist_bg_ry = np.sqrt(1. - rnd) * evlist_bg_r * np.where(np.random.randint(2, size=(n_events_bg * (tplt_multi + 1))) == 0, -1., 1.) #evlist_bg_sky_r = np.sqrt(np.random.rand(n_events_bg * (tplt_multi + 1))) * r_max #evlist_bg_sky_r = ev_gen_f2(np.random.rand(n_events_bg * (tplt_multi + 1))) rnd = np.random.rand(n_events_bg * (tplt_multi + 1)) evlist_bg_ra = np.sin(2. * np.pi * rnd) * evlist_bg_r / objcosdec evlist_bg_dec = np.cos(2. * np.pi * rnd) * evlist_bg_r #plt.hist(evlist_bg_rx ** 2. + evlist_bg_ry**2., bins=50) #print float(n_events_bg * (tplt_multi + 1)) / np.sum(p_rate_area) / 86400. evlist_bg_t = t_min + obstime * np.random.rand(n_events_bg * (tplt_multi + 1)) / 86400. #--------------------------------------------------------------------------- # Plots & debug plt.figure(3) objra, objdec = 0., 0. H, xedges, yedges = np.histogram2d( np.append(evlist_bg_dec, evlist_dec), np.append(evlist_bg_ra, evlist_ra), bins=[100, 100], range=[[objra - 3., objra + 3.], [objdec - 3., objdec + 3.]] ) extent = [yedges[0], yedges[-1], xedges[-1], xedges[0]] plt.imshow(H, extent=extent, interpolation='nearest') cb = plt.colorbar() cb.set_label('Number of events') plt.xlabel('RA (deg)') plt.ylabel('Dec (deg)') test_r = np.sqrt(evlist_bg_ra ** 2. + evlist_bg_dec ** 2.) logging.debug('Number of BG events in a circle of area 1 deg^2 = {0}'.format(np.sum(test_r[0:n_events_bg] < np.sqrt(1. / np.pi)))) logging.debug('Expected number of BG event per area 1 deg^2 = {0}'.format(p_rate_total * obstime)) obj_r = np.sqrt(((obj_ra - evlist_ra) / objcosdec) ** 2. + (obj_dec - evlist_dec) ** 2.) thetamax_on, thetamax_off = .1, .22 non = np.sum(obj_r < thetamax_on) + np.sum(test_r[0:n_events_bg] < thetamax_on) noff = np.sum(test_r[0:n_events_bg] < thetamax_off) alpha = thetamax_on ** 2. / thetamax_off ** 2. logging.info('N_ON = {0}, N_OFF = {1}, ALPHA = {2}, SIGN = {3}'.format( non, noff, alpha, pf.get_li_ma_sign(non, noff, alpha))) plt.figure(2) plt.hist(obj_r ** 2., bins=30) #--------------------------------------------------------------------------- # Output to file if output_filename_base: logging.info('Writing eventlist to file {0}.eventlist.fits'.format(output_filename_base)) newtable = pyfits.new_table( pyfits.ColDefs([ pyfits.Column(name='TIME', format='1E', unit='deg', array=np.append(evlist_t, evlist_bg_t)), pyfits.Column(name='RA', format='1E', unit='deg', array=np.append(evlist_ra, evlist_bg_ra)), pyfits.Column(name='DEC', format='1E', unit='deg', array=np.append( evlist_dec, evlist_bg_dec)), pyfits.Column(name='DETX', format='1E', unit='deg', array=np.append(np.zeros(n_events), evlist_bg_rx)), pyfits.Column(name='DETY', format='1E', unit='deg', array=np.append(np.ones(n_events) * .5, evlist_bg_ry)), pyfits.Column(name='ENERGY', format='1E', unit='tev', array=10. ** np.append(evlist_e,evlist_bg_e)), pyfits.Column(name='HIL_MSW', format='1E', array=np.append(np.zeros(n_events + n_events_bg), 5. * np.ones(n_events_bg * tplt_multi))), pyfits.Column(name='HIL_MSL', format='1E', array=np.append(np.zeros(n_events + n_events_bg), 5. * np.ones(n_events_bg * tplt_multi))) ]) ) #newtable = pyfits.new_table(coldefs_new) dstart = datetime.datetime(2011, 1, 1, 0, 0) # date/time of start of the first observation dstop = dstart + datetime.timedelta(seconds=obstime) # date/time of end of the last observation dbase = datetime.datetime(2011, 1, 1) hdr = newtable.header hdr.update('RA_OBJ' , obj_ra, 'Target position RA [deg]') hdr.update('DEC_OBJ', obj_dec, 'Target position dec [deg]') hdr.update('RA_PNT', pnt_ra, 'Observation position RA [deg]') hdr.update('DEC_PNT', pnt_dec, 'Observation position dec [deg]') hdr.update('EQUINOX ', 2000.0, 'Equinox of the object') hdr.update('RADECSYS', 'FK5', 'Co-ordinate frame used for equinox') hdr.update('CREATOR', 'pfsim v{0}'.format(pf.__version__) , 'Program') hdr.update('DATE', datetime.datetime.today().strftime('%Y-%m-%d'), 'FITS file creation date (yyyy-mm-dd)') hdr.update('TELESCOP', 'CTASIM', 'Instrument name') hdr.update('EXTNAME', 'EVENTS' , 'HESARC standard') hdr.update('DATE_OBS', dstart.strftime('%Y-%m-%d'), 'Obs. start date (yy-mm-dd)') hdr.update('TIME_OBS', dstart.strftime('%H:%M:%S'), 'Obs. start time (hh:mm::ss)') hdr.update('DATE_END', dstop.strftime('%Y-%m-%d'), 'Obs. stop date (yy-mm-dd)') hdr.update('TIME_END', dstop.strftime('%H:%M:%S'), 'Obs. stop time (hh:mm::ss)') hdr.update('TSTART', 0., 'Mission time of start of obs [s]') hdr.update('TSTOP', obstime, 'Mission time of end of obs [s]') hdr.update('MJDREFI', int(pf.date_to_mjd(dstart)), 'Integer part of start MJD [s] ') hdr.update('MJDREFF', pf.date_to_mjd(dstart) - int(pf.date_to_mjd(dstart)), 'Fractional part of start MJD') hdr.update('TIMEUNIT', 'days' , 'Time unit of MJD') hdr.update('TIMESYS', 'TT', 'Terrestrial Time') hdr.update('TIMEREF', 'local', '') hdr.update('TELAPSE', obstime, 'Diff of start and end times') hdr.update('ONTIME', obstime, 'Tot good time (incl deadtime)') # No deadtime assumed hdr.update('LIVETIME', obstime, 'Deadtime=ONTIME/LIVETIME') # No deadtime assumed hdr.update('DEADC', 1., 'Deadtime fraction') # No deadtime assumed hdr.update('TIMEDEL', 1., 'Time resolution') hdr.update('EUNIT', 'TeV', 'Energy unit') hdr.update('EVTVER', 'v1.0.0', 'Event-list version number') #hdr.update('', , '') # Write eventlist to file newtable.writeto('{0}.eventlist.fits'.format(output_filename_base)) if write_pha : logging.info('Writing PHA to file {0}.pha.fits'.format(output_filename_base)) # Prepare data dat, t = np.histogram(10. ** evlist_e, bins=rm_ebounds) dat = np.array(dat, dtype=float) dat_err = np.sqrt(dat) chan = np.arange(len(dat)) # Data to PHA tbhdu = pf.np_to_pha(counts=dat, stat_err=dat_err, channel=chan, exposure=obstime, obj_ra=obj_ra, obj_dec=obj_dec, quality=np.where((dat == 0), 1, 0), dstart=dstart, dstop=dstop, dbase=dbase, creator='pfsim', version=pf.__version__, telescope='CTASIM') tbhdu.header.update('ANCRFILE', os.path.basename(arf), 'Ancillary response file (ARF)') if rmf : tbhdu.header.update('RESPFILE', os.path.basename(rmf), 'Redistribution matrix file (RMF)') # Write PHA to file tbhdu.writeto('{0}.pha.fits'.format(output_filename_base)) #---------------------------------------- # Time it! t_2 = time.clock() logging.info('Execution took {0}'.format(pf.get_nice_time(t_2 - t_1))) logging.info('Thank you for choosing {0}. Have a great day!'.format(os.path.split(__file__)[1])) #---------------------------------------- if do_graphical_output: plt.show()
def create_sky_map(input_file_name, skymap_size=5., skymap_bin_size=0.05, r_overs=.125, ring_bg_radii=None, template_background=None, skymap_center=None, write_output=False, fov_acceptance=False, do_graphical_output=True, loglevel='INFO') : # Time it! t_1 = time.clock() # Configure logging numeric_level = getattr(logging, loglevel.upper(), None) if not isinstance(numeric_level, int): raise ValueError('Invalid log level: %s' % loglevel) logging.basicConfig(level=numeric_level, format='%(asctime)s - %(levelname)s - %(message)s', datefmt='%Y-%m-%d %H:%M:%S') # Welcome user, print out basic information on package versions logging.info('This is {0} (pyfact v{1})'.format(os.path.split(__file__)[1], pf.__version__)) logging.info('We are running with numpy v{0}, scipy v{1}, and pyfits v{2}'.format( np.__version__, scipy.__version__, pyfits.__version__ )) #--------------------------------------------------------------------------- # Loop over the file list, calculate quantities, & fill histograms # Skymap definition #skymap_size, skymap_bin_size = 6., 0.05 rexdeg = .3 # Intialize some variables skycenra, skycendec, pntra, pntdec = None, None, None, None if skymap_center : skycenra, skycendec = eval(skymap_center) logging.info('Skymap center: RA {0}, Dec {1}'.format(skycenra, skycendec)) ring_bg_r_min, ring_bg_r_max = .3, .7 if ring_bg_radii : ring_bg_r_min, ring_bg_r_max = eval(ring_bg_radii) if r_overs > ring_bg_r_min : logging.warning('Oversampling radius is larger than the inner radius chosen for the ring BG: {0} > {1}'.format(r_overs, ring_bg_r_min)) logging.info('Skymap size : {0} deg'.format(skymap_size)) logging.info('Skymap bin size : {0} deg'.format(skymap_bin_size)) logging.info('Oversampling radius : {0} deg'.format(r_overs)) logging.info('Ring BG radius : {0} - {1} deg'.format(ring_bg_r_min, ring_bg_r_max)) skymap_nbins, sky_dec_min, sky_dec_max, objcosdec, sky_ra_min, sky_ra_max = 0, 0., 0., 0., 0., 0. sky_hist, acc_hist, extent = None, None, None tpl_had_hist, tpl_acc_hist = None, None sky_ex_reg, sky_ex_reg_map = None, None telescope, object_ = 'NONE', 'NONE' firstloop = True exposure = 0. # Read in input file, can be individual fits or bankfile logging.info('Opening input file ..') def get_filelist(input_file_name) : # Check if we are dealing with a single file or a bankfile # and create/read in the file list accordingly try : f = pyfits.open(input_file_name) f.close() file_list = [input_file_name] except : # We are dealing with a bankfile logging.info('Reading files from bankfile {0}'.format(input_file_name)) file_list = np.loadtxt(input_file_name, dtype='S', usecols=[0]) return file_list file_list = get_filelist(input_file_name) tpl_file_list = None # Read in template files if template_background : tpl_file_list = get_filelist(template_background) if len(file_list) != len(tpl_file_list) : logging.warning('Different number of signal and template background files. Switching off template background analysis.') template_background = None # Main loop over input files for i, file_name in enumerate(file_list) : logging.info('Processing file {0}'.format(file_name)) def get_evl(file_name) : # Open fits file hdulist = pyfits.open(file_name) # Access header of second extension hdr = hdulist['EVENTS'].header # Access data of first extension tbdata = hdulist['EVENTS'].data # Calculate some useful quantities and add them to the table # Distance from the camera (FOV) center camdist = np.sqrt(tbdata.field('DETX') ** 2. + tbdata.field('DETY') ** 2.) camdist_col = pyfits.Column(name='XCAMDIST', format='1E', unit='deg', array=camdist) # Add new columns to the table coldefs_new = pyfits.ColDefs([camdist_col]) #coldefs_new = pyfits.ColDefs([camdist_col, detx_col, dety_col]) newtable = pyfits.new_table(hdulist[1].columns + coldefs_new) # New table data return hdulist, hdr, newtable.data hdulist, ex1hdr, tbdata = get_evl(file_name) # Read in eventlist for template background tpl_hdulist, tpl_tbdata = None, None if template_background : tpl_hdulist, tpl_hdr, tpl_tbdata = get_evl(tpl_file_list[i]) #--------------------------------------------------------------------------- # Intialize & GTI objra, objdec = ex1hdr['RA_OBJ'], ex1hdr['DEC_OBJ'] if firstloop : # If skymap center is not set, set it to the object position of the first run if skycenra == None or skycendec == None : skycenra, skycendec = objra, objdec logging.debug('Setting skymap center to skycenra, skycendec = {0}, {1}'.format(skycenra, skycendec)) if 'TELESCOP' in ex1hdr : telescope = ex1hdr['TELESCOP'] logging.debug('Setting TELESCOP to {0}'.format(telescope)) if 'OBJECT' in ex1hdr : object_ = ex1hdr['OBJECT'] logging.debug('Setting OBJECT to {0}'.format(object_)) mgit, tpl_mgit = np.ones(len(tbdata), dtype=np.bool), None if template_background : tpl_mgit = np.ones(len(tpl_tbdata), dtype=np.bool) try : # Note: according to the eventlist format document v1.0.0 Section 10 # "The times are expressed in the same units as in the EVENTS # table (seconds since mission start in terresterial time)." for gti in hdulist['GTI'].data : mgit *= (tbdata.field('TIME') >= gti[0]) * (tbdata.field('TIME') <= gti[1]) if template_background : tpl_mgit *= (tpl_tbdata.field('TIME') >= gti[0]) * (tpl_tbdata.field('TIME') <= gti[1]) except : logging.warning('File does not contain a GTI extension') #--------------------------------------------------------------------------- # Handle exclusion region # If no exclusion regions are given, use the object position from the first run if sky_ex_reg == None : sky_ex_reg = [pf.SkyCircle(pf.SkyCoord(objra, objdec), rexdeg)] logging.info('Setting exclusion region to object position (ra={0}, dec={1}, r={2}'.format(objra, objdec, rexdeg)) pntra, pntdec = ex1hdr['RA_PNT'], ex1hdr['DEC_PNT'] obj_cam_dist = pf.SkyCoord(skycenra, skycendec).dist(pf.SkyCoord(pntra, pntdec)) exposure_run = ex1hdr['LIVETIME'] exposure += exposure_run logging.info('RUN Start date/time : {0} {1}'.format(ex1hdr['DATE_OBS'], ex1hdr['TIME_OBS'])) logging.info('RUN Stop date/time : {0} {1}'.format(ex1hdr['DATE_END'], ex1hdr['TIME_END'])) logging.info('RUN Exposure : {0:.2f} [s]'.format(exposure_run)) logging.info('RUN Pointing pos. : RA {0:.4f} [deg], Dec {1:.4f} [deg]'.format(pntra, pntdec)) logging.info('RUN Obj. cam. dist. : {0:.4f} [deg]'.format(obj_cam_dist)) # Cut out source region for acceptance fitting exmask = None for sc in sky_ex_reg : if exmask : exmask *= sc.c.dist(pf.SkyCoord(tbdata.field('RA'), tbdata.field('DEC'))) < sc.r else : exmask = sc.c.dist(pf.SkyCoord(tbdata.field('RA'), tbdata.field('DEC'))) < sc.r exmask = np.invert(exmask) photbdata = tbdata[exmask * mgit] if len(photbdata) < 10 : logging.warning('Less then 10 events found in file {0} after exclusion region cuts'.format(file_name)) hadtbdata = None if template_background : exmask = None for sc in sky_ex_reg : if exmask : exmask *= sc.c.dist(pf.SkyCoord(tpl_tbdata.field('RA'), tpl_tbdata.field('DEC'))) < sc.r else : exmask = sc.c.dist(pf.SkyCoord(tpl_tbdata.field('RA'), tpl_tbdata.field('DEC'))) < sc.r exmask = np.invert(exmask) hadtbdata = tpl_tbdata[exmask * tpl_mgit] #--------------------------------------------------------------------------- # Calculate camera acceptance n, bins, nerr, r, r_a, ex_a, fitter = pf.get_cam_acc( photbdata.field('XCAMDIST'), exreg=[(sc.r, sc.c.dist(pf.SkyCoord(pntra, pntdec))) for sc in sky_ex_reg], fit=True, ) # DEBUG if logging.root.level is logging.DEBUG : fitter.print_results() # DEBUG plot plt.errorbar(r, n / r_a / (1. - ex_a), nerr / r_a / (1. - ex_a)) plt.plot(r, fitter.fitfunc(fitter.results[0], r)) plt.show() had_acc, had_n, had_fit = None, None, None if template_background : had_acc = pf.get_cam_acc( hadtbdata.field('XCAMDIST'), exreg=[(sc.r, sc.c.dist(pf.SkyCoord(pntra, pntdec))) for sc in sky_ex_reg], fit=True ) had_n, had_fit = had_acc[0], had_acc[6] logging.debug('Camera acceptance hadrons fit probability: {0}'.format(had_fit.prob)) # !!! All photons including the exclusion regions photbdata = tbdata[mgit] if template_background : hadtbdata = tpl_tbdata[tpl_mgit] if len(photbdata) < 10 : logging.warning('Less then 10 events found in file {0} after GTI cut.'.format(file_name)) tpl_acc_cor_use_interp = True tpl_acc_f, tpl_acc = None, None if template_background : if tpl_acc_cor_use_interp : tpl_acc_f = scipy.interpolate.UnivariateSpline(r, n.astype(float) / had_n.astype(float), s=0, k=1) else : tpl_acc_f = lambda r: fitter.fitfunc(p1, r) / had_fit.fitfunc(had_fit.results[0], r) tpl_acc = tpl_acc_f(hadtbdata.field('XCAMDIST')) m = hadtbdata.field('XCAMDIST') > r[-1] tpl_acc[m] = tpl_acc_f(r[-1]) m = hadtbdata.field('XCAMDIST') < r[0] tpl_acc[m] = tpl_acc_f(r[0]) #--------------------------------------------------------------------------- # Skymap - definitions/calculation # Object position in the sky if firstloop : #skycenra, objdec, skymap_size = ex1hdr['RA_OBJ'], ex1hdr['DEC_OBJ'], 6. #if skycenra == None or objdec == None : # skycenra, objdec = ex1hdr['RA_OBJ'], ex1hdr['DEC_OBJ'] # Calculate skymap limits skymap_nbins = int(skymap_size / skymap_bin_size) sky_dec_min, sky_dec_max = skycendec - skymap_size / 2., skycendec + skymap_size / 2. objcosdec = np.cos(skycendec * np.pi / 180.) sky_ra_min, sky_ra_max = skycenra - skymap_size / 2. / objcosdec, skycenra + skymap_size / 2. / objcosdec logging.debug('skymap_nbins = {0}'.format(skymap_nbins)) logging.debug('sky_dec_min, sky_dec_max = {0}, {1}'.format(sky_dec_min, sky_dec_max)) logging.debug('sky_ra_min, sky_ra_max = {0}, {1}'.format(sky_ra_min, sky_ra_max)) # Create sky map (i.e. bin events) # NOTE: In histogram2d the first axes is the vertical (y, DEC) the 2nd the horizontal axes (x, RA) sky = np.histogram2d(x=photbdata.field('DEC '), y=photbdata.field('RA '), bins=[skymap_nbins, skymap_nbins], range=[[sky_dec_min, sky_dec_max], [sky_ra_min, sky_ra_max]]) if firstloop : # Just used to have the x-min/max, y-min/max saved H, xedges, yedges = sky # NOTE: The zero point of the histogram 2d is at the lower left corner while # the pyplot routine imshow takes [0,0] at the upper left corner (i.e. # we have to invert the 1st axis before plotting, see below). # Also, imshow uses the traditional 1st axes = x = RA, 2nd axes = y = DEC # notation for the extend keyword #extent = [yedges[0], yedges[-1], xedges[-1], xedges[0]] extent = [yedges[0], yedges[-1], xedges[0], xedges[-1]] sky_hist = sky[0] sky_ex_reg_map = pf.get_exclusion_region_map(sky_hist, (sky_ra_min, sky_ra_max), (sky_dec_min, sky_dec_max), sky_ex_reg) else : sky_hist += sky[0] # Calculate camera acceptance dec_a = np.linspace(sky_dec_min, sky_dec_max, skymap_nbins + 1) ra_a = np.linspace(sky_ra_min, sky_ra_max, skymap_nbins + 1) xx, yy = np.meshgrid((ra_a[:-1] + ra_a[1:]) / 2. - pntra, (dec_a[:-1] + dec_a[1:]) / 2. - pntdec) rr = np.sqrt(xx ** 2. + yy ** 2.) p1 = fitter.results[0] acc = fitter.fitfunc(p1, rr) / fitter.fitfunc(p1, .01) m = rr > 4. acc[m] = fitter.fitfunc(p1, 4.) / fitter.fitfunc(p1, .01) if not fov_acceptance : logging.debug('Do _not_ apply FoV acceptance correction') acc = acc * 0. + 1. # DEBUG plot #plt.imshow(acc[::-1], extent=extent, interpolation='nearest') #plt.colorbar() #plt.title('acc_bg_overs') #plt.show() if firstloop : acc_hist = acc * exposure_run # acc[0] before else : acc_hist += acc * exposure_run # acc[0] before if template_background : # Create hadron event like map for template background tpl_had = np.histogram2d(x=hadtbdata.field('DEC '), y=hadtbdata.field('RA '), bins=[skymap_nbins, skymap_nbins], #weights=1./accept, range=[[sky_dec_min, sky_dec_max], [sky_ra_min, sky_ra_max]]) if firstloop : tpl_had_hist = tpl_had[0] else : tpl_had_hist += tpl_had[0] # Create acceptance map for template background tpl_acc = np.histogram2d(x=hadtbdata.field('DEC '), y=hadtbdata.field('RA '), bins=[skymap_nbins, skymap_nbins], weights=tpl_acc, range=[[sky_dec_min, sky_dec_max], [sky_ra_min, sky_ra_max]]) if firstloop : tpl_acc_hist = tpl_acc[0] else : tpl_acc_hist += tpl_acc[0] # Close fits file hdulist.close() if tpl_hdulist : tpl_hdulist.close() # Clean up memory newtable = None gc.collect() firstloop = False #--------------------------------------------------------------------------- # Calculate final skymaps logging.info('Processing final sky maps') # Calculate oversampled skymap, ring background, excess, and significances sc = pf.get_sky_mask_circle(r_overs, skymap_bin_size) sr = pf.get_sky_mask_ring(ring_bg_r_min, ring_bg_r_max, skymap_bin_size) acc_hist /= exposure logging.info('Calculating oversampled event map ..') sky_overs, sky_overs_alpha = pf.oversample_sky_map(sky_hist, sc) logging.info('Calculating oversampled ring background map ..') sky_bg_ring, sky_bg_ring_alpha = pf.oversample_sky_map(sky_hist, sr, sky_ex_reg_map) logging.info('Calculating oversampled event acceptance map ..') acc_overs, acc_overs_alpha = pf.oversample_sky_map(acc_hist, sc) logging.info('Calculating oversampled ring background acceptance map ..') acc_bg_overs, acc_bg_overs_alpha = pf.oversample_sky_map(acc_hist, sr, sky_ex_reg_map) rng_alpha = acc_hist / acc_bg_overs # camera acceptance rng_exc = sky_hist - sky_bg_ring * rng_alpha rng_sig = pf.get_li_ma_sign(sky_hist, sky_bg_ring, rng_alpha) rng_alpha_overs = acc_overs / acc_bg_overs # camera acceptance rng_exc_overs = sky_overs - sky_bg_ring * rng_alpha_overs rng_sig_overs = pf.get_li_ma_sign(sky_overs, sky_bg_ring, rng_alpha_overs) tpl_had_overs, tpl_sig_overs, tpl_exc_overs, tpl_alpha_overs = None, None, None, None if template_background : logging.info('Calculating oversampled template background map ..') tpl_had_overs, tpl_had_overs_alpha = pf.oversample_sky_map(tpl_had_hist, sc) logging.info('Calculating oversampled template acceptance map ..') tpl_acc_overs, tpl_acc_overs_alpha = pf.oversample_sky_map(tpl_acc_hist, sc) tpl_exc_overs = sky_overs - tpl_acc_overs tpl_alpha_overs = tpl_acc_overs / tpl_had_overs tpl_sig_overs = pf.get_li_ma_sign(sky_overs, tpl_had_overs, tpl_alpha_overs) #--------------------------------------------------------------------------- # Write results to file if write_output : logging.info('Writing result to file ..') rarange, decrange = (sky_ra_min, sky_ra_max), (sky_dec_min, sky_dec_max) outfile_base_name = 'skymap_ring' outfile_data = { '_ev.fits': sky_hist, '_ac.fits': acc_hist, '_ev_overs.fits': sky_overs, '_bg_overs.fits': sky_bg_ring, '_si_overs.fits': rng_sig_overs, '_ex_overs.fits': rng_exc_overs, '_al_overs.fits': rng_alpha_overs, '_si.fits': rng_sig, '_ex.fits': rng_exc, '_al.fits': rng_alpha } outfile_base_name = pf.unique_base_file_name(outfile_base_name, outfile_data.keys()) for ext, data in outfile_data.iteritems() : pf.map_to_primaryhdu(data, rarange, decrange, author='PyFACT pfmap', object_=object_, telescope=telescope).writeto(outfile_base_name + ext) if template_background : outfile_base_name = 'skymap_template' outfile_data = { '_bg.fits': tpl_had_hist, '_ac.fits': tpl_acc_hist, '_bg_overs.fits': tpl_had_overs, '_si_overs.fits': tpl_sig_overs, '_ex_overs.fits': tpl_exc_overs, '_al_overs.fits': tpl_alpha_overs, #'_si.fits': rng_sig, #'_ex.fits': rng_exc, #'_al.fits': rng_alpha } outfile_base_name = pf.unique_base_file_name(outfile_base_name, outfile_data.keys()) for ext, data in outfile_data.iteritems() : pf.map_to_primaryhdu(data, rarange, decrange, author='PyFACT pfmap', object_=object_, telescope=telescope).writeto(outfile_base_name + ext) logging.info('The output files can be found in {0}'.format(os.getcwd())) #--------------------------------------------------------------------------- # Plot results if has_matplotlib and do_graphical_output : import matplotlib logging.info('Plotting results (matplotlib v{0})'.format(matplotlib.__version__)) plot_skymap(sky_overs, rng_exc_overs, rng_sig_overs, sky_bg_ring, rng_alpha_overs, 'Ring BG overs.', sky_ra_min, sky_ra_max, sky_dec_min, sky_dec_max, objcosdec, r_overs, extent, skycenra, skycendec, ring_bg_r_min, ring_bg_r_max, sign_hist_r_max = 2.) if template_background : plot_skymap(sky_overs, tpl_exc_overs, tpl_sig_overs, tpl_had_overs, tpl_alpha_overs, 'Template BG overs.', sky_ra_min, sky_ra_max, sky_dec_min, sky_dec_max, objcosdec, r_overs, extent, skycenra, skycendec, sign_hist_r_max = 2.) #---------------------------------------- # Time it! t_2 = time.clock() logging.info('Execution took {0}'.format(pf.get_nice_time(t_2 - t_1))) logging.info('Thank you for choosing {0}. Have a great day!'.format(os.path.split(__file__)[1])) #---------------------------------------- plt.show()