示例#1
0
def _make_xselect_commands(infile, outfile, elow, ehigh, usrgti=False):
    '''
    Helper script to generate the xselect commands to make an image in a given NuSTAR range
    '''

    xsel = open("xsel.xco", "w")
    xsel.write("session1\n")
    xsel.write("read events \n")
    evdir = os.path.dirname(infile)
    xsel.write(f'{evdir} \n ')
    evfile = os.path.basename(infile)
    xsel.write(f'{evfile} \n ')
    xsel.write('yes \n')
    pi_low = energy_to_chan(elow)
    pi_high = energy_to_chan(ehigh)
    if usrgti is not False:
        xsel.write(f'filter time \n')
        xsel.write('file \n')
        xsel.write(f'{usrgti}\n')
        xsel.write('extract events\n')
    xsel.write('filter pha_cutoff {} {} \n'.format(pi_low, pi_high))

    xsel.write('set xybinsize 1\n')
    xsel.write("extract image\n")
    xsel.write("save image\n")
    xsel.write("%s \n" % outfile)
    xsel.write('exit\n')
    xsel.write('n \n')
    xsel.close()
    return 'xsel.xco'
示例#2
0
def _make_xselect_commands_det1(infile, outfile, elow, ehigh):
    '''
    Helper script to generate the xselect commands to make an image in a
    given NuSTAR energy range
    '''

    import glob
    for oldfile in glob.glob("session1*"):
        os.system(f"rm {oldfile}")

    xsel = open("xsel.xco", "w")
    xsel.write("session1\n")
    xsel.write("read events \n")
    evdir = os.path.dirname(infile)
    xsel.write(f'{evdir} \n ')
    evfile = os.path.basename(infile)
    xsel.write(f'{evfile} \n ')
    xsel.write('yes \n')
    xsel.write('set xyname\n')
    xsel.write('DET1X\n')
    xsel.write('DET1Y\n')
    pi_low = energy_to_chan(elow)
    pi_high = energy_to_chan(ehigh)
    xsel.write('filter pha_cutoff {} {} \n'.format(pi_low, pi_high))
    xsel.write('set xybinsize 1\n')
    xsel.write("extract image\n")
    xsel.write("save image\n")
    xsel.write("%s \n" % outfile)
    xsel.write('exit\n')
    xsel.write('n \n')
    xsel.close()
    return 'xsel.xco'
示例#3
0
def make_det1_lightcurve(infile,
                         mod,
                         obs,
                         time_bin=100 * u.s,
                         mode='01',
                         elow=3,
                         ehigh=20,
                         stemout=False,
                         gtifile=False):
    '''
    Generate a script to run nuproducts to make a lightcurve using the whole
    FoV and turning off all vignetting and PSF effects. Assumes that infile 
    has already been filtered using extract_det1_events().
    
    Parameters
    ----------
    
    infile: str
        Full path to the input event file. This should be pre-filtered by
        by extract_det1_events
    
    mod: str
        'A' or 'B'
        
    obs: nustar_gen.info.Observation
        Observation meta data
    
    
    Other Parameters
    -------------------
        
    elow: float, optional, default = 3 keV
        Low-energy bound
    
    ehigh: float, optional, default is 20 keV
        High-energy bound
            
    mode: str, optional, default is '01'
        Optional. Used to specify stemout if you're doing mode06 analysis and want
        to specify output names that are more complicated.
        
    gtifile: str
        Path to a GTI file. If this is set, then this is passed to nuproducts.
    
    stemout: str, optional
        Use the specified stemout string when calling nuproducts. Otherwise
        uses the default value.

    '''

    from astropy.io.fits import getheader

    # Make sure environment is set up properly
    _check_environment()

    # Check to see that all files exist:
    assert os.path.isfile(
        infile), 'make_det1_lightcurve: infile does not exist!'

    #    evdir = os.path.dirname(infile)
    evdir = obs.evdir
    seqid = obs.seqid
    #    seqid = os.path.basename(os.path.dirname(evdir))
    outdir = obs.out_path

    #     if outpath is None:
    #         outdir = evdir
    #     else:
    #         outdir = outpath

    hdr = getheader(infile)
    ra = hdr['RA_OBJ']
    dec = hdr['DEC_OBJ']

    time_bin = int((time_bin.to(u.s)).value)
    if stemout is False:
        stemout = f'nu{seqid}{mod}{mode}_full_FoV_{elow}to{ehigh}_{time_bin}s'

    lc_script = f'{outdir}/rundet1lc_{stemout}.sh'

    pi_low = energy_to_chan(elow)
    pi_high = energy_to_chan(ehigh)

    with open(lc_script, 'w') as f:
        f.write('nuproducts phafile=NONE bkgphafile=NONE imagefile=NONE ')
        f.write(f'infile={infile} ')
        f.write('runmkarf=no runmkrmf=no ')
        f.write(f'indir={evdir} outdir={outdir} instrument=FPM{mod} ')
        f.write(f'steminputs=nu{seqid} stemout={stemout} ')
        f.write(f'pilow={pi_low} pihigh={pi_high} ')
        f.write(f'bkgextract=no ')
        f.write(f'binsize={time_bin} ')
        f.write(
            f'srcra={ra} srcdec={dec} srcregionfile=DEFAULT srcradius=299 ')

        # Turn off all of the time-dependent corrections for the pointing here
        f.write(f'lcpsfflag=no lcexpoflag=no lcvignflag=no ')

        if (gtifile != False):
            f.write(f'usrgtifile={gtifile} ')
        f.write('clobber=yes')

    os.chmod(lc_script, stat.S_IRWXG + stat.S_IRWXU)

    return lc_script
示例#4
0
def make_lightcurve(infile,
                    mod,
                    src_reg,
                    barycorr=False,
                    time_bin=100 * u.s,
                    mode='01',
                    bgd_reg='None',
                    outpath='None',
                    elow=3,
                    ehigh=20):
    '''
    Generate a script to run nuproducts
    
    Parameters
    ----------
    
    infile: str
        Full path to the input event file.
    
    mod: str
        'A' or 'B'
        
    src_reg: str
        Full path to source region.
    
    
    Other Parameters
    -------------------

    bgd_reg: str
        If not 'None', then must be the full path to the background region file

    barycorr: bool 
        Default is 'False'. If 'True', then queries the infile for the OBJ J2000
        coordinates and uses these for the barycenter correction.
        
    elow: float
        Low-eneryg bound. Default is 3 keV.
    
    ehigh: float
        High-energy bound. Default is 20 keV.
    
    outpath: str
        Optional. Default is to put the lightcurves in the same location as infile
        
    mode: str
        Optional. Used primarily if you're doing mode06 analysis and need to specify
        output names that are more complicated.

    '''

    from astropy.io.fits import getheader

    # Make sure environment is set up properly
    _check_environment()

    # Check to see that all files exist:
    assert os.path.isfile(infile), 'make_lightcurve: infile does not exist!'
    assert os.path.isfile(src_reg), 'make_lightcurve: src_reg does not exist!'

    if bgd_reg != 'None':
        assert os.path.isfile(
            bgd_reg), 'make_lightcurve: bgd_reg does not exist!'
        bkgextract = 'yes'
    else:
        bkgextract = 'no'

    reg_base = os.path.basename(src_reg)
    reg_base = os.path.splitext(reg_base)[0]

    evdir = os.path.dirname(infile)

    seqid = os.path.basename(os.path.dirname(evdir))

    if outpath == 'None':
        outdir = evdir
    else:
        outdir = outpath
        try:
            os.makedirs(outdir)
        except FileExistsError:
            # directory already exists
            pass
    time_bin = (time_bin.to(u.s)).value
    stemout = f'nu{seqid}{mod}{mode}_{reg_base}_{elow}to{ehigh}_{time_bin:3.4}s'
    lc_script = outdir + f'/runlc_{stemout}.sh'

    pi_low = energy_to_chan(elow)
    pi_high = energy_to_chan(ehigh)

    with open(lc_script, 'w') as f:
        f.write('nuproducts phafile=NONE bkgphafile=NONE imagefile=NONE ')
        f.write(f'runmkarf=no runmkrmf=no pilow={pi_low} pihigh={pi_high} ')
        f.write(f'indir={evdir} outdir={outdir} instrument=FPM{mod} ')
        f.write(f'steminputs=nu{seqid} stemout={stemout} ')
        f.write(f'srcregionfile={src_reg} ')

        if bkgextract == 'no':
            f.write(f'bkgextract=no ')
        else:
            f.write(f'bkgextract=yes bkgregionfile={bgd_reg} ')
        f.write(f'binsize={time_bin} ')

        if barycorr:
            attorb = evdir + f'/nu{seqid}{mod}.attorb'
            hdr = getheader(infile)
            ra = hdr['RA_OBJ']
            dec = hdr['DEC_OBJ']
            f.write(f'barycorr=yes srcra_barycorr={ra} srcdec_barycorr={dec} ')
            f.write(f'orbitfile={attorb} ')

        f.write('clobber=yes')

    os.chmod(lc_script, stat.S_IRWXG + stat.S_IRWXU)
    return lc_script
示例#5
0
def make_det1_lightcurve(infile,
                         mod,
                         barycorr=False,
                         time_bin=100 * u.s,
                         mode='01',
                         outpath=None,
                         elow=3,
                         ehigh=20):
    '''
    Generate a script to run nuproducts to make a lightcurve using the whole
    FoV and turning off all vignetting and PSF effects. Assumes that infile 
    has already been filtered using extract_det1_events().
    
    Parameters
    ----------
    
    infile: str
        Full path to the input event file.
    
    mod: str
        'A' or 'B'
        
    
    
    Optional Parameters
    -------------------
    
    bgd_reg: str
        If not 'None', then must be the full path to the background region file

    barycorr: bool 
        Default is 'False'. If 'True', then queries the infile for the OBJ J2000
        coordinates and uses these for the barycenter correction.
        
    elow: float
        Low-eneryg bound. Default is 3 keV.
    
    ehigh: float
        High-energy bound. Default is 20 keV.
    
    outpath: str
        Optional. Default is to put the lightcurves in the same location as infile
        
    mode: str
        Optional. Used primarily if you're doing mode06 analysis and need to specify
        output names that are more complicated.

    '''

    from astropy.io.fits import getheader

    # Make sure environment is set up properly
    _check_environment()

    # Check to see that all files exist:
    assert os.path.isfile(
        infile), 'make_det1_lightcurve: infile does not exist!'

    evdir = os.path.dirname(infile)

    seqid = os.path.basename(os.path.dirname(evdir))

    if outpath is None:
        outdir = evdir
    else:
        outdir = outpath

    hdr = getheader(infile)
    ra = hdr['RA_OBJ']
    dec = hdr['DEC_OBJ']

    time_bin = int((time_bin.to(u.s)).value)
    stemout = f'nu{seqid}{mod}{mode}_full_FoV_{elow}to{ehigh}_{time_bin}s'
    lc_script = f'{outdir}/rundet1lc_{stemout}.sh'

    pi_low = energy_to_chan(elow)
    pi_high = energy_to_chan(ehigh)

    with open(lc_script, 'w') as f:
        f.write('nuproducts phafile=NONE bkgphafile=NONE imagefile=NONE ')
        f.write(f'infile={infile} ')
        f.write('runmkarf=no runmkrmf=no ')
        f.write(f'indir={evdir} outdir={outdir} instrument=FPM{mod} ')
        f.write(f'steminputs=nu{seqid} stemout={stemout} ')
        f.write(f'pilow={pi_low} pihigh={pi_high} ')
        f.write(f'bkgextract=no ')
        f.write(f'binsize={time_bin} ')
        f.write(
            f'srcra={ra} srcdec={dec} srcregionfile=DEFAULT srcradius=299 ')

        # Turn off all of the time-dependent corrections for the pointing here
        f.write(f'lcpsfflag=no lcexpoflag=no lcvignflag=no ')

        if barycorr:
            attorb = evdir + f'/nu{seqid}{mod}.attorb'
            f.write(f'barycorr=yes srcra_barycorr={ra} srcdec_barycorr={dec} ')
            f.write(f'orbitfile={attorb} ')

        f.write('clobber=yes')

    os.chmod(lc_script, stat.S_IRWXG + stat.S_IRWXU)

    return lc_script
示例#6
0
def make_straylight_arf(det1im, regfile, filt_file, mod, obs):
    '''
    Produces an ARF for a given observation. Currently uses counts-weighting to
        determine the contribution of the detabs parameters for each detector.
        SHOULD PROBABLY BE MOVED TO WRAPPERS OR SOMETHING?
        
    Parameters
    ----------
    det1im : str
        Full path to the DET1 exposure image file.
        
    regfil : str
        Full path to the region file, assumed to be a ds9 region file in "IMAGE"
        coordinates
    
    filt_file : str
        Full path to the DET1 screened event file (i.e. output of
        nustar_gen.wrappers.extract_det1_events() ). This used to scale the ARF by
        the number of 3--10 keV counts on each detector.

    mod : str
        'A' or 'B'
        
    obs: nustar_gen.info.Observation
        Observation meta data


    Returns
    -------
    out_arf: string
        Full path to the new arf file
    
    '''   
    
    from astropy.io import fits
    import glob
    from nustar_gen import io
    from nustar_gen.utils import energy_to_chan
    
    
        # Check to see that all files exist:
    assert os.path.isfile(det1im), \
        f'straylight_area: DET1 exposure map not found: {det1im}'
    assert os.path.isfile(regfile), \
        f'straylight_area: Region file not found: {regfile}'
    assert os.path.isfile(filt_file), \
        f'straylight_area: Event file not found: {evf}'

    outdir = obs.out_path
    
    out_arf = outdir+'/'+os.path.splitext(os.path.basename(filt_file))[0]+'.arf'

    # Get the effective are target:
    area = straylight_area(det1im, regfile, filt_file)
    
    # Use counts relative scaling to blend the ARFs:
    ev_hdu = fits.open(filt_file)
    evts = ev_hdu[1].data
    scale_evts = evts[ (evts['PI']>energy_to_chan(3.)) & (evts['PI'] < energy_to_chan(10.) )]
    dethist, detedges = np.histogram(scale_evts['DET_ID'], range=[0, 3],bins = 4)
    totcts = dethist.sum()
    scale = [ float(x) / totcts for x in dethist]
    ev_hdu.close()

    # Load the base ARF file:
    arf_file = io.find_arf_template()
    arf_hdu = fits.open(arf_file)
    arf = arf_hdu[1].data
    arf_header = arf_hdu[1].header
    # Trim header
    arf_hdu[1].header = arf_header[0:26]

    # Mock up an ARF that's flat with just the detector area
    arf['SPECRESP'] = [area.value for x in arf['SPECRESP']]


    caldb = os.environ['CALDB']
    detabs_files = glob.glob(caldb+f'/**/nu{mod}detabs*', recursive=True)
    use = len(detabs_files)-1

    detabs_hdu = fits.open(detabs_files[use])

    for detind, isc in enumerate(scale):
        detabs = detabs_hdu[detind+1].data
        if detind == 0:
            arfabs = detabs['DETABS'] * isc
        else:
            arfabs += detabs['DETABS'] * isc
    arf['SPECRESP'] *= arfabs
    detabs_hdu.close()

    be_file = io.find_be_arf()
    be_arf = fits.getdata(be_file, 1)

    arf['SPECRESP'] *= be_arf['SPECRESP']

    arf_hdu.writeto(out_arf, overwrite=True)
    arf_hdu.close()
    
    return out_arf