def xpobssim(**kwargs): """Run the ximpol fast simulator. """ assert (kwargs['configfile'].endswith('.py')) if kwargs['outfile'] is None: outfile = os.path.basename(kwargs['configfile']).replace( '.py', '.fits') mkdir(XIMPOL_DATA) kwargs['outfile'] = os.path.join(XIMPOL_DATA, outfile) logger.info('Setting output file path to %s...' % kwargs['outfile']) if os.path.exists(kwargs['outfile']) and not kwargs['clobber']: logger.info('Output file %s already exists.' % kwargs['outfile']) logger.info('Remove the file or set "clobber = True" to overwite it.') return kwargs['outfile'] chrono = xChrono() logger.info('Setting the random seed to %d...' % kwargs['seed']) numpy.random.seed(kwargs['seed']) logger.info('Loading the instrument response functions...') aeff, psf, modf, edisp = load_irfs(kwargs['irfname']) logger.info('Done %s.' % chrono) logger.info('Setting up the source model...') module_name = os.path.basename(kwargs['configfile']).replace('.py', '') ROI_MODEL = imp.load_source(module_name, kwargs['configfile']).ROI_MODEL logger.info(ROI_MODEL) if kwargs['tstart'] < ROI_MODEL.min_validity_time(): kwargs['tstart'] = ROI_MODEL.min_validity_time() logger.info('Simulation start time set to %s...' % kwargs['tstart']) tstop = kwargs['tstart'] + kwargs['duration'] if tstop > ROI_MODEL.max_validity_time(): tstop = ROI_MODEL.max_validity_time() logger.info('Simulation stop time set to %s...' % tstop) gti_list = [(kwargs['tstart'], tstop)] kwargs['tstop'] = tstop event_list = ROI_MODEL.rvs_event_list(aeff, psf, modf, edisp, **kwargs) logger.info('Done %s.' % chrono) simulation_info = xSimulationInfo() simulation_info.gti_list = gti_list simulation_info.roi_model = ROI_MODEL simulation_info.irf_name = kwargs['irfname'] simulation_info.aeff = aeff simulation_info.psf = psf simulation_info.modf = modf simulation_info.edisp = edisp event_list.write_fits(kwargs['outfile'], simulation_info) logger.info('All done %s!' % chrono) return kwargs['outfile']
def xpobssim(**kwargs): """Run the ximpol fast simulator. """ assert(kwargs['configfile'].endswith('.py')) if kwargs['outfile'] is None: outfile = os.path.basename(kwargs['configfile']).replace('.py', '.fits') mkdir(XIMPOL_DATA) kwargs['outfile'] = os.path.join(XIMPOL_DATA, outfile) logger.info('Setting output file path to %s...' % kwargs['outfile']) if os.path.exists(kwargs['outfile']) and not kwargs['clobber']: logger.info('Output file %s already exists.' % kwargs['outfile']) logger.info('Remove the file or set "clobber = True" to overwite it.') return kwargs['outfile'] chrono = xChrono() logger.info('Setting the random seed to %d...' % kwargs['seed']) numpy.random.seed(kwargs['seed']) logger.info('Loading the instrument response functions...') aeff, psf, modf, edisp = load_irfs(kwargs['irfname']) logger.info('Done %s.' % chrono) logger.info('Setting up the source model...') module_name = os.path.basename(kwargs['configfile']).replace('.py', '') ROI_MODEL = imp.load_source(module_name, kwargs['configfile']).ROI_MODEL logger.info(ROI_MODEL) if kwargs['tstart'] < ROI_MODEL.min_validity_time(): kwargs['tstart'] = ROI_MODEL.min_validity_time() logger.info('Simulation start time set to %s...' % kwargs['tstart']) tstop = kwargs['tstart'] + kwargs['duration'] if tstop > ROI_MODEL.max_validity_time(): tstop = ROI_MODEL.max_validity_time() logger.info('Simulation stop time set to %s...' % tstop) gti_list = [(kwargs['tstart'], tstop)] kwargs['tstop'] = tstop event_list = ROI_MODEL.rvs_event_list(aeff, psf, modf, edisp, **kwargs) logger.info('Done %s.' % chrono) simulation_info = xSimulationInfo() simulation_info.gti_list = gti_list simulation_info.roi_model = ROI_MODEL simulation_info.irf_name = kwargs['irfname'] simulation_info.aeff = aeff simulation_info.psf = psf simulation_info.modf = modf simulation_info.edisp = edisp event_list.write_fits(kwargs['outfile'], simulation_info) logger.info('All done %s!' % chrono) return kwargs['outfile']
def chandra2ximpol(file_path, **kwargs): """Make the conversion from Chandra to ximpol. """ assert(file_path.endswith('.fits')) if kwargs['outfile'] is None: outfile = os.path.basename(file_path).replace('.fits','_xipe.fits') mkdir(XIMPOL_DATA) kwargs['outfile'] = os.path.join(XIMPOL_DATA, outfile) logger.info('Setting output file path to %s...' % kwargs['outfile']) if os.path.exists(kwargs['outfile']) and not kwargs['clobber']: logger.info('Output file %s already exists.' % kwargs['outfile']) logger.info('Remove the file or set "clobber = True" to overwite it.') return kwargs['outfile'] chrono = xChrono() logger.info('Setting the random seed to %d...' % kwargs['seed']) numpy.random.seed(kwargs['seed']) logger.info('Loading the instrument response functions...') aeff, psf, modf, edisp = load_irfs(kwargs['irfname']) c_aeff_name = 'chandra_acis_%s.arf' % kwargs['acis'] c_aeff_file = os.path.join(XIMPOL_IRF, 'fits', c_aeff_name) logger.info('Reading Chandra effective area data from %s...' % c_aeff_file) c_aeff = load_chandra_arf(c_aeff_file) _x = aeff.x _y = aeff.y/c_aeff(_x) aeff_ratio = xInterpolatedUnivariateSplineLinear(_x, _y) logger.info('Loading the input FITS event file...') hdu_list = fits.open(file_path) # If configuration file is not provided we assume a non-polarized source if kwargs['configfile'] is None: logger.info('Configuration file not provided.') logger.info('Setting polarization angle and degree to zero...') polarization_degree = constant(0.) polarization_angle = constant(0.) else: logger.info('Setting up the polarization source model...') module_name = os.path.basename(kwargs['configfile']).replace('.py', '') polarization_degree = imp.load_source(module_name, kwargs['configfile']).POLARIZATION_DEGREE polarization_angle = imp.load_source(module_name, kwargs['configfile']).POLARIZATION_ANGLE logger.info('Done %s.' % chrono) hdr = hdu_list[1].header tbdata = hdu_list[1].data tstart = hdr['TSTART'] tstop = hdr['TSTOP'] obs_time = tstop - tstart logger.info('Chandra observation time: %i s.' %obs_time) ra_pnt = hdr['RA_PNT'] dec_pnt = hdr['DEC_PNT'] ROI_MODEL = xROIModel(ra_pnt, dec_pnt) logger.info('Reading Chandra data...') col_mc_energy = tbdata['energy']*0.001 # eV -> keV rnd_ratio = numpy.random.random(len(col_mc_energy)) # The condition col_mc_energy < 10. is needed to avoid to take the bunch of # events with energy > 10 keV included into the Chandra photon list (we # actually don't know the reason). _mask = (rnd_ratio < aeff_ratio(col_mc_energy))*(col_mc_energy<10.) # This is needed for over-sample the events in case of effective area ratio # greater than 1. _mask_ratio = (rnd_ratio < (aeff_ratio(col_mc_energy)-1.))*\ (col_mc_energy<10.) col_mc_energy = numpy.append(col_mc_energy[_mask], col_mc_energy[_mask_ratio]) col_time = numpy.append(tbdata['time'][_mask],tbdata['time'][_mask_ratio]) col_mc_ra, col_mc_dec = _get_radec(hdr, tbdata) col_mc_ra = numpy.append(col_mc_ra[_mask], col_mc_ra[_mask_ratio]) col_mc_dec = numpy.append(col_mc_dec[_mask], col_mc_dec[_mask_ratio]) duration = kwargs['duration'] if not numpy.isnan(duration): logger.info('Setting the observation time to %d s...' % duration) scale = numpy.modf(duration/obs_time) tstop = tstart + duration logger.info('Scaling counts according to observation time...') col_mc_energy, col_time, col_mc_ra, col_mc_dec = time_scaling(scale, col_mc_energy, col_time, col_mc_ra, col_mc_dec) logger.info('Converting from Chandra to ximpol...') gti_list = [(tstart, tstop)] event_list = xMonteCarloEventList() event_list.set_column('TIME', col_time) event_list.set_column('MC_ENERGY', col_mc_energy) col_pha = edisp.matrix.rvs(col_mc_energy) event_list.set_column('PHA', col_pha) col_energy = edisp.ebounds(col_pha) event_list.set_column('ENERGY',col_energy) event_list.set_column('MC_RA', col_mc_ra) event_list.set_column('MC_DEC', col_mc_dec) col_ra, col_dec = psf.smear(col_mc_ra, col_mc_dec) event_list.set_column('RA', col_ra) event_list.set_column('DEC', col_dec) pol_degree = polarization_degree(col_mc_energy, col_time, col_mc_ra, col_mc_dec) pol_angle = polarization_angle(col_mc_energy, col_time, col_mc_ra, col_mc_dec) col_pe_angle = modf.rvs_phi(col_mc_energy, pol_degree, pol_angle) event_list.set_column('PE_ANGLE', col_pe_angle) # Set the phase to rnd [0-1] for all non-periodic sources. phase=numpy.random.uniform(0,1,len(col_dec)) event_list.set_column('PHASE', phase) event_list.set_column('MC_SRC_ID', numpy.zeros(len(col_dec))) logger.info('Done %s.' % chrono) simulation_info = xSimulationInfo() simulation_info.gti_list = gti_list simulation_info.roi_model = ROI_MODEL simulation_info.irf_name = kwargs['irfname'] simulation_info.aeff = aeff simulation_info.psf = psf simulation_info.modf = modf simulation_info.edisp = edisp event_list.sort() event_list.write_fits(kwargs['outfile'], simulation_info) logger.info('All done %s!' % chrono) return kwargs['outfile']
def chandra2ximpol(file_path, **kwargs): """Make the conversion from Chandra to ximpol. """ assert file_path.endswith(".fits") if kwargs["outfile"] is None: outfile = os.path.basename(file_path).replace(".fits", "_xipe.fits") mkdir(XIMPOL_DATA) kwargs["outfile"] = os.path.join(XIMPOL_DATA, outfile) logger.info("Setting output file path to %s..." % kwargs["outfile"]) if os.path.exists(kwargs["outfile"]) and not kwargs["clobber"]: logger.info("Output file %s already exists." % kwargs["outfile"]) logger.info('Remove the file or set "clobber = True" to overwite it.') return kwargs["outfile"] chrono = xChrono() logger.info("Setting the random seed to %d..." % kwargs["seed"]) numpy.random.seed(kwargs["seed"]) logger.info("Loading the instrument response functions...") aeff, psf, modf, edisp = load_irfs(kwargs["irfname"]) c_aeff_name = "chandra_acis_%s.arf" % kwargs["acis"] c_aeff_file = os.path.join(XIMPOL_IRF, "fits", c_aeff_name) logger.info("Reading Chandra effective area data from %s..." % c_aeff_file) c_aeff = _load_chandra_arf(c_aeff_file) c_vign_name = "chandra_vignet.fits" c_vign_file = os.path.join(XIMPOL_IRF, "fits", c_vign_name) logger.info("Reading Chandra vignetiing data from %s..." % c_vign_file) c_vign = _load_chandra_vign(c_vign_file) aeff_ratio = _make_aeff_ratio(aeff, c_aeff, c_vign) logger.info("Done %s." % chrono) logger.info("Loading the input FITS event file...") hdu_list = fits.open(file_path) hdr = hdu_list[1].header tbdata = hdu_list[1].data tstart = hdr["TSTART"] tstop = hdr["TSTOP"] obs_time = tstop - tstart logger.info("Chandra observation time: %i s." % obs_time) ra_pnt = hdr["RA_PNT"] dec_pnt = hdr["DEC_PNT"] ROI_MODEL = xROIModel(ra_pnt, dec_pnt) logger.info("Reading Chandra data...") col_mc_energy = tbdata["energy"] * 0.001 # eV -> keV col_mc_ra, col_mc_dec = _get_radec(hdr, tbdata) ref_skyccord = SkyCoord(ra_pnt, dec_pnt, unit="deg") evt_skycoord = SkyCoord(col_mc_ra, col_mc_dec, unit="deg") separation = evt_skycoord.separation(ref_skyccord).arcmin logger.info("Converting from Chandra to ximpol...") rnd_ratio = numpy.random.random(len(col_mc_energy)) # The condition col_mc_energy < 10. is needed to avoid to take the bunch of # events with energy > 10 keV included into the Chandra photon list (we # actually don't know the reason). _mask = (rnd_ratio < aeff_ratio(col_mc_energy, separation)) * (col_mc_energy < 10.0) # This is needed for over-sample the events in case of effective area ratio # greater than 1. _mask_ratio = (rnd_ratio < (aeff_ratio(col_mc_energy, separation) - 1.0)) * (col_mc_energy < 10.0) col_mc_energy = numpy.append(col_mc_energy[_mask], col_mc_energy[_mask_ratio]) col_mc_ra = numpy.append(col_mc_ra[_mask], col_mc_ra[_mask_ratio]) col_mc_dec = numpy.append(col_mc_dec[_mask], col_mc_dec[_mask_ratio]) col_time = numpy.append(tbdata["time"][_mask], tbdata["time"][_mask_ratio]) # If duration parameter is provided the counts are down- or oversampled. duration = kwargs["duration"] if not numpy.isnan(duration): logger.info("Setting the observation time to %d s..." % duration) scale = numpy.modf(duration / obs_time) tstop = tstart + duration logger.info("Scaling counts according to observation time...") col_mc_energy, col_time, col_mc_ra, col_mc_dec = _time_scaling( scale, col_mc_energy, col_time, col_mc_ra, col_mc_dec ) # The Ra Dec coordinates are calculated here because they are needed in # source id definition (in case of kwargs['chandra']==False) col_ra, col_dec = psf.smear(col_mc_ra, col_mc_dec) # The default source id in case of no regfile and for regions not selected # is zero. For regions selected in the regfile the source id is determined # by the order of definition (starting with 1). logger.info("Defining source id...") src_id = numpy.zeros(len(col_mc_dec)) n_reg = -1 if kwargs["regfile"] is not None: regions = pyregion.open(kwargs["regfile"]) for n_reg, region in enumerate(regions): if kwargs["mc"] is True: mask = filter_region(region, col_mc_ra, col_mc_dec) else: mask = filter_region(region, col_ra, col_dec) src_id[mask] = n_reg + 1 # If configuration file is not provided we assume a non-polarized source. # In case of configfile with polarization model defined in different # regions the photoelectron distribution is generated according to them. if kwargs["configfile"] is None: logger.info("Configuration file not provided.") logger.info("Setting polarization angle and degree to zero...") polarization_degree = constant(0.0) polarization_angle = constant(0.0) pol_dict = {0: [polarization_degree, polarization_angle]} for k in range(1, n_reg + 2): pol_dict[k] = [polarization_degree, polarization_angle] else: logger.info("Setting up the polarization source model...") module_name = os.path.basename(kwargs["configfile"]).replace(".py", "") pol_dict = imp.load_source(module_name, kwargs["configfile"]).POLARIZATION_DICT logger.info("Generating photoelectron azimuthal distribution...") col_pe_angle = numpy.empty(len(col_mc_dec)) for key, pol_list in pol_dict.items(): _mask_src = src_id == key pol_degree = pol_list[0]( col_mc_energy[_mask_src], col_time[_mask_src], col_mc_ra[_mask_src], col_mc_dec[_mask_src] ) pol_angle = pol_list[1]( col_mc_energy[_mask_src], col_time[_mask_src], col_mc_ra[_mask_src], col_mc_dec[_mask_src] ) col_pe_angle[_mask_src] = modf.rvs_phi(col_mc_energy[_mask_src], pol_degree, pol_angle) gti_list = [(tstart, tstop)] event_list = xMonteCarloEventList() event_list.set_column("TIME", col_time) event_list.set_column("MC_ENERGY", col_mc_energy) col_pha = edisp.matrix.rvs(col_mc_energy) event_list.set_column("PHA", col_pha) col_energy = edisp.ebounds(col_pha) event_list.set_column("ENERGY", col_energy) event_list.set_column("MC_RA", col_mc_ra) event_list.set_column("MC_DEC", col_mc_dec) event_list.set_column("RA", col_ra) event_list.set_column("DEC", col_dec) event_list.set_column("MC_SRC_ID", src_id) event_list.set_column("PE_ANGLE", col_pe_angle) # Set the phase to rnd [0-1] for all non-periodic sources. phase = numpy.random.uniform(0, 1, len(col_dec)) event_list.set_column("PHASE", phase) logger.info("Done %s." % chrono) simulation_info = xSimulationInfo() simulation_info.gti_list = gti_list simulation_info.roi_model = ROI_MODEL simulation_info.irf_name = kwargs["irfname"] simulation_info.aeff = aeff simulation_info.psf = psf simulation_info.modf = modf simulation_info.edisp = edisp event_list.sort() event_list.write_fits(kwargs["outfile"], simulation_info) logger.info("All done %s!" % chrono) return kwargs["outfile"]