Example #1
0
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']
Example #2
0
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']
Example #3
0
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']
Example #4
0
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"]