1
0
forked from xmm/arches
This commit is contained in:
2025-10-23 13:20:50 +03:00
parent 2dee828098
commit 22c164cd41
20 changed files with 2240 additions and 256 deletions

View File

@@ -15,7 +15,7 @@ print("Arches root path: {}".format(root_path))
archive_dir=root_path+'/data/archive'
events_dir=root_path+'/data/processed-oot'
products_dir=root_path+'/products'
#products_dir=root_path+'/products'
create_folder(events_dir)
@@ -62,11 +62,14 @@ for obsid in files:
w('sasver', []).run() # print info
search_str=f'{work_dir}/????_{obsid}_EPN_S???_ImagingEvts_OOT.ds'
search_str=f'{work_dir}/????_{obsid}_EPN_S???_ImagingEvts.ds'
epfiles = glob.glob(search_str)
if not (epfiles):
print('Running epproc')
w('epproc', ['withoutoftime=true',]).run()
print('*** Running epproc')
w('epproc', ['withoutoftime=true',]).run()
else:
print('*** Skipping epproc')

View File

@@ -15,7 +15,7 @@ print("Arches root path: {}".format(root_path))
archive_dir=root_path+'/data/archive'
events_dir=root_path+'/data/processed'
products_dir=root_path+'/products'
#products_dir=root_path+'/products'
create_folder(events_dir)

View File

@@ -26,10 +26,10 @@ print("Arches root path: {}".format(root_path))
archive_dir=root_path+'/data/archive'
events_dir=root_path+'/data/processed'
products_dir=root_path+'/products'
products_dir=root_path+'/products/sas'
ds9reg_dir=root_path+'/data/ds9reg'
imos=2
imos=1
create_folder(products_dir)
@@ -42,8 +42,10 @@ files = glob.glob(archive_dir+'/*')
for obsid in files:
obsid = os.path.basename(obsid)
if(obsid in skip):
continue
work_dir = init_work_dir(obsid)
work_dir = init_work_dir(obsid, products_dir=products_dir)
os.chdir(work_dir)

View File

@@ -26,7 +26,7 @@ print("Arches root path: {}".format(root_path))
archive_dir=root_path+'/data/archive'
events_dir=root_path+'/data/processed'
products_dir=root_path+'/products'
products_dir=root_path+'/products/sas'
ds9reg_dir=root_path+'/data/ds9reg'
create_folder(products_dir)
@@ -39,8 +39,10 @@ files = glob.glob(archive_dir+'/0862*')
for obsid in files:
obsid = os.path.basename(obsid)
if(obsid in skip):
continue
work_dir = init_work_dir(obsid)
work_dir = init_work_dir(obsid, products_dir=products_dir)
os.chdir(work_dir)
@@ -147,7 +149,7 @@ for obsid in files:
pn_pi_max = 12000. # High energy range eV
pn_threshold = 0.75 # cts/sec (only used here for display purposes)
out_LCFile = work_dir+'/EPIC_pn_FlareBKGRate.fit' # Name of the output BKG lightcurve
out_LCFile = work_dir+'/EPIC_PN_FlareBKGRate.fit' # Name of the output BKG lightcurve
# SAS Command
cmd = "evselect" # SAS task to be executed
@@ -241,9 +243,9 @@ for obsid in files:
# Define the input and output file names
in_LCFile = work_dir+'/EPIC_pn_FlareBKGRate.fit' # Name of the input BKG lightcurve
out_gti_set = work_dir+'/EPIC_pn_gti.fit' # Name of the output file containing GTI intervals
out_clean_evtFile = work_dir+'/EPIC_pn_gtiFilteredEvts.ds' # Name of the output Event file filtered by GTI
in_LCFile = work_dir+'/EPIC_PN_FlareBKGRate.fit' # Name of the input BKG lightcurve
out_gti_set = work_dir+'/EPIC_PN_gti.fit' # Name of the output file containing GTI intervals
out_clean_evtFile = work_dir+'/EPIC_PN_gtiFilteredEvts.ds' # Name of the output Event file filtered by GTI
# SAS Command
cmd = "tabgtigen"

View File

@@ -26,10 +26,10 @@ print("Arches root path: {}".format(root_path))
archive_dir=root_path+'/data/archive'
events_dir=root_path+'/data/processed'
products_dir=root_path+'/products'
products_dir=root_path+'/products/sas'
ds9reg_dir=root_path+'/data/ds9reg'
imos=1
imos=2
create_folder(products_dir)
@@ -41,8 +41,11 @@ files = glob.glob(archive_dir+'/*')
for obsid in files:
obsid = os.path.basename(obsid)
if(obsid in skip):
continue
work_dir = init_work_dir(obsid, products_dir=products_dir)
work_dir = init_work_dir(obsid)
os.chdir(work_dir)
# EPIC_pn_gtiFilteredEvts.ds EPIC_MOS2_Image_0862470501.fit
@@ -50,7 +53,7 @@ for obsid in files:
print(search_str)
epfiles = glob.glob(search_str)
if not (epfiles):
print("*** run 02_filter_flares_pn.py ***")
print("*** run 02_sas_flares_pn.py ***")
sys.exit()
out_IMFile = epfiles[0]

View File

@@ -26,7 +26,7 @@ print("Arches root path: {}".format(root_path))
archive_dir=root_path+'/data/archive'
events_dir=root_path+'/data/processed'
products_dir=root_path+'/products'
products_dir=root_path+'/products/sas'
ds9reg_dir=root_path+'/data/ds9reg'
create_folder(products_dir)
@@ -39,8 +39,10 @@ files = glob.glob(archive_dir+'/*')
for obsid in files:
obsid = os.path.basename(obsid)
if(obsid in skip):
continue
work_dir = init_work_dir(obsid)
work_dir = init_work_dir(obsid, products_dir=products_dir)
os.chdir(work_dir)
# EPIC_pn_gtiFilteredEvts.ds
@@ -48,7 +50,7 @@ for obsid in files:
print(search_str)
epfiles = glob.glob(search_str)
if not (epfiles):
print("*** run 02_filter_flares_pn.py ***")
print("*** run 02_sas_flares_pn.py ***")
sys.exit()
out_IMFile = epfiles[0]

View File

@@ -54,18 +54,29 @@ for obsid in files:
key='mos1S001'
run_mosspectra(key,'T T F T T F T',elow=elow,ehigh=ehigh)
run_mosback( key,'T T F T T F T')
run_bkgimsky( key,elow=elow,ehigh=ehigh)
run_mosback (key,'T T F T T F T')
run_bkgimsky (key,elow=elow,ehigh=ehigh)
run_mossave (key,elow=elow,ehigh=ehigh)
key='mos2S002'
run_mosspectra(key,'T T T T T T T',elow=elow,ehigh=ehigh)
run_mosback( key,'T T T T T T T')
run_bkgimsky( key,elow=elow,ehigh=ehigh)
run_mosback (key,'T T T T T T T')
run_bkgimsky (key,elow=elow,ehigh=ehigh)
run_mossave (key,elow=elow,ehigh=ehigh)
key='pnS003'
run_pnspectra(key,'T T T T',elow=elow,ehigh=ehigh)
run_pnback( key,'T T T T')
run_bkgimsky( key,elow=elow,ehigh=ehigh)
pattern=0
run_pnspectra(key,'T T T T',elow=elow,ehigh=ehigh,pattern=pattern)
run_pnback (key,'T T T T')
run_bkgimsky (key,elow=elow,ehigh=ehigh)
run_pnsave (key,elow=elow,ehigh=ehigh,pattern=pattern)
pattern=4
run_pnspectra(key,'T T T T',elow=elow,ehigh=ehigh,pattern=pattern)
run_pnback (key,'T T T T')
run_bkgimsky (key,elow=elow,ehigh=ehigh)
run_pnsave (key,elow=elow,ehigh=ehigh,pattern=pattern)
#sys.exit()

View File

@@ -27,10 +27,15 @@ print("Arches root path: {}".format(root_path))
archive_dir=root_path+'/data/archive'
events_dir=root_path+'/data/processed'
products_dir=root_path+'/products'
products_dir=root_path+'/products/sas'
ds9reg_dir=root_path+'/data/ds9reg'
imos=2
if len(sys.argv) > 1:
print(f"The first command-line argument is: {sys.argv[1]}")
imos=sys.argv[1]
else:
print("No command-line arguments provided. Use MOS1.")
imos=1
create_folder(products_dir)
@@ -42,91 +47,32 @@ files = glob.glob(archive_dir+'/*')
for obsid in files:
obsid = os.path.basename(obsid)
if(obsid in skip):
continue
work_dir = init_work_dir(obsid)
work_dir = init_work_dir(obsid, products_dir=products_dir)
os.chdir(work_dir)
eventfile=f'{products_dir}/{obsid}/EPIC_MOS{imos}_gtiFilteredEvts.ds'
if(os.path.isfile(eventfile)==False):
print("*** run 02_filter_flares_mos.py ***")
print("*** run 02_sas_flares_mos.py ***")
sys.exit()
# EPIC_pn_gtiFilteredEvts.ds
search_str = f'{products_dir}/{obsid}/EPIC_MOS{imos}_Image_{obsid}.fit'
print(search_str)
emfiles = glob.glob(search_str)
if not (emfiles):
print("*** run 02_filter_flares_mos.py ***")
print("*** run 02_sas_flares_mos.py ***")
sys.exit()
out_IMFile = emfiles[0]
# Visualize the image with ds9
d = pyds9.DS9()
d.set("file "+out_IMFile)
d.set('cmap bb')
d.set('scale log')
#d.set(f"region {ds9reg_dir}/arches.reg")
src_fn=f'{ds9reg_dir}/{obsid}/src.reg'
if(os.path.isfile(src_fn)==True):
d.set(f"region {src_fn}")
bkg_fn=f'{ds9reg_dir}/{obsid}/bkg.reg'
if(os.path.isfile(bkg_fn)==True):
d.set(f"region {bkg_fn}")
reply = input(f"{obsid}: Proceed to make spectrum/lightcurve? [y/[n]] ")
if reply!='y':
continue
print(d.get("regions"))
# Extract the relevant information from the ds9 regions.
region1=(re.split("circle|annulus",d.get("regions").partition("physical")[2]))[1].replace('(','').replace(')','').replace('#',',')
region2=(re.split("circle|annulus",d.get("regions").partition("physical")[2]))[2].replace('(','').replace(')','').replace('#',',')
print("Identified first region: ", region1)
print("Identified second region: ", region2)
#print("region1 "+region1.partition("color")[2].replace('=','').replace('\n',''))
#print("region2 "+region2.partition("color")[2].replace('=','').replace('\n',''))
# Identify source and background regions using the 'white' color.
c1=region1.partition("color")[2].replace('=','').replace('\n','')
print("Region1 color: "+c1)
if(c1=='white'):
regionsrc = region1
regionbkg = region2
else:
regionsrc = region2
regionbkg = region1
# Save and print selected region coordinates.
x_source = regionsrc.split(",")[0].replace('\n','')
y_source = regionsrc.split(",")[1].replace('\n','')
r_source = regionsrc.split(",")[2].replace('\n','')
print("The coordinates of the selected source region are: \n")
print(" x_source = ", x_source, "(physical)")
print(" y_source = ", y_source, "(physical)")
print(" r_source = ", r_source, "(physical) \n")
x_bkg = regionbkg.split(",")[0].replace('\n','')
y_bkg = regionbkg.split(",")[1].replace('\n','')
r_bkg = regionbkg.split(",")[2].replace('\n','')
print("The coordinates of the selected background region are: \n")
print(" x_bkg = ", x_bkg, "(physical)")
print(" y_bkg = ", y_bkg, "(physical)")
print(" r_bkg = ", r_bkg, "(physical) \n")
# If the background is an annulus, save and print R2.
if "annulus" in str(d.get("regions")):
r2_bkg = regionbkg.split(",")[3].replace('\n','')
print(" r2_bkg = ", r2_bkg, "(physical)")
x_source,y_source,r_source,x_bkg,y_bkg,r_bkg,r2_bkg = get_ds9_regions(out_IMFile, src_fn, bkg_fn)
#########################################
# Extract the source region light curve #
@@ -143,28 +89,20 @@ for obsid in files:
# Define the output ligthcurve file name
in_LCSRCFile = work_dir+f'/EPIC_MOS{imos}_source_lightcurve.lc' # Name of the output source light curve
# SAS Command
cmd = "evselect" # SAS task to be executed
# Arguments of SAS Command
expression = f'{q_flag}&&(PATTERN<={n_pattern})&&((X,Y) IN circle({x_source},{y_source},{r_source}))&&(PI in [{mos_pi_min}:{mos_pi_max}])' # event filter expression
expression = f'{q_flag}&&(PATTERN<={n_pattern})&&((X,Y) IN circle({x_source},{y_source},{r_source}))&&(PI in [{mos_pi_min}:{mos_pi_max}])'
inargs = [f'table={eventfile}','energycolumn=PI','withrateset=yes',f'rateset={in_LCSRCFile}',
f'timebinsize={lc_bin}','maketimecolumn=yes','makeratecolumn=yes',f'expression={expression}']
print(" Filter expression to use: "+expression+" \n")
print(" SAS command to be executed: "+cmd+", with arguments; \n")
# Execute the SAS task with the parameters to produce the source region light curve
w(cmd, inargs).run()
w("evselect", inargs).run()
# Inspect light curve
plt.figure(figsize=(20,8)) # Size of figure
plotLC(plt,mos_threshold[imos-1],in_LCSRCFile) # Plot source region light curve
plt.legend()
plt.show()
#plt.figure(figsize=(20,8)) # Size of figure
#plotLC(plt,mos_threshold[imos-1],in_LCSRCFile) # Plot source region light curve
#plt.legend()
#plt.show()
######################################
# Extract the source region spectrum #
@@ -177,49 +115,45 @@ for obsid in files:
# Define the output ligthcurve file name
in_SPSRCFile = work_dir+f'/EPIC_MOS{imos}_source_spectrum.fits' # Name of the output source spectrum
# SAS Command
cmd = "evselect" # SAS task to be executed
# Arguments of SAS Command
expression = f'{q_flag}&&(PATTERN<={n_pattern})&&((X,Y) IN circle({x_source},{y_source},{r_source}))' # event filter expression
inargs = [f'table={eventfile}','withspectrumset=yes',f'spectrumset={in_SPSRCFile}',
'energycolumn=PI','spectralbinsize=5','withspecranges=yes','specchannelmin=0',
'specchannelmax=11999',f'expression={expression}']
print(" Filter expression to use: "+expression+" \n")
print(" SAS command to be executed: "+cmd+", with arguments; \n")
w(cmd, inargs).run()
w("evselect", inargs).run()
# Extract the background region spectrum with the same criteria
# Define the output ligthcurve file name
in_SPBKGFile = work_dir+f'/EPIC_MOS{imos}_background_spectrum.fits' # Name of the output background spectrum
# SAS Command
cmd = "evselect" # SAS task to be executed
# Arguments of SAS Command
if(r2_bkg==None):
expression = f'{q_flag}&&(PATTERN<={n_pattern})&&((X,Y) IN circle({x_bkg},{y_bkg},{r_bkg}))'
else:
expression = f'{q_flag}&&(PATTERN<={n_pattern})&&((X,Y) IN annulus({x_bkg},{y_bkg},{r_bkg},{r2_bkg}))'
expression = f'{q_flag}&&(PATTERN<={n_pattern})&&((X,Y) IN circle({x_bkg},{y_bkg},{r_bkg}))' # event filter expression
inargs = [f'table={eventfile}','withspectrumset=yes',f'spectrumset={in_SPBKGFile}',
'energycolumn=PI','spectralbinsize=5','withspecranges=yes','specchannelmin=0',
'specchannelmax=11999',f'expression={expression}']
print(" Filter expression to use: "+expression+" \n")
print(" SAS command to be executed: "+cmd+", with arguments; \n")
w(cmd, inargs).run()
w("evselect", inargs).run()
w("backscale", [f'spectrumset={in_SPSRCFile}',f'badpixlocation={eventfile}']).run()
w("backscale", [f'spectrumset={in_SPBKGFile}',f'badpixlocation={eventfile}']).run()
# https://www.cosmos.esa.int/web/xmm-newton/sas-thread-epic-merging
MAXENERGY=12
NBINS=1190
in_RESPFile = work_dir+f'/EPIC_MOS{imos}.rmf' # Name of the output redistribution
w("rmfgen", [f'spectrumset={in_SPSRCFile}',f'rmfset={in_RESPFile}']).run()
w("rmfgen", [f'spectrumset={in_SPSRCFile}',f'rmfset={in_RESPFile}',
'withenergybins=yes', 'energymin=0.1',
f'energymax={MAXENERGY}', f'nenergybins={NBINS}',]).run()
in_ARFFile = work_dir+f'/EPIC_MOS{imos}.arf' # Name of the output ancillary
cmd = "arfgen" # SAS task to be executed
print(" Checking for Response File ..... \n")
# Check if RESP file is available.
@@ -232,7 +166,7 @@ for obsid in files:
# Arguments of SAS Command
inargs = [f'spectrumset={in_SPSRCFile}',f'arfset={in_ARFFile}',
'withrmfset=yes',f'rmfset={in_RESPFile}',f'badpixlocation={eventfile}','detmaptype=psf']
w(cmd, inargs).run()
w("arfgen", inargs).run()
# rebin the spectra and link associated files
in_GRPFile = work_dir+f'/EPIC_MOS{imos}_spectrum_grp.fits' # Name of the output specgruop

View File

@@ -27,7 +27,7 @@ print("Arches root path: {}".format(root_path))
archive_dir=root_path+'/data/archive'
events_dir=root_path+'/data/processed'
products_dir=root_path+'/products'
products_dir=root_path+'/products/sas'
ds9reg_dir=root_path+'/data/ds9reg'
create_folder(products_dir)
@@ -40,8 +40,10 @@ files = glob.glob(archive_dir+'/*')
for obsid in files:
obsid = os.path.basename(obsid)
if(obsid in skip):
continue
work_dir = init_work_dir(obsid)
work_dir = init_work_dir(obsid, products_dir=products_dir)
os.chdir(work_dir)
@@ -50,7 +52,6 @@ for obsid in files:
print("*** run 02_filter_flares_pn.py ***")
sys.exit()
# EPIC_pn_gtiFilteredEvts.ds
search_str = f'{products_dir}/{obsid}/EPIC_PN_Image_{obsid}.fit'
print(search_str)
@@ -62,69 +63,9 @@ for obsid in files:
out_IMFile = epfiles[0]
# Visualize the image with ds9
d = pyds9.DS9()
d.set("file "+out_IMFile)
d.set('cmap bb')
d.set('scale log')
#d.set(f"region {ds9reg_dir}/arches.reg")
src_fn=f'{ds9reg_dir}/{obsid}/src.reg'
if(os.path.isfile(src_fn)==True):
d.set(f"region {src_fn}")
bkg_fn=f'{ds9reg_dir}/{obsid}/bkg.reg'
if(os.path.isfile(bkg_fn)==True):
d.set(f"region {bkg_fn}")
reply = input(f"{obsid}: Proceed to make spectrum/lightcurve? [y/[n]] ")
if reply!='y':
continue
print(d.get("regions"))
# Extract the relevant information from the ds9 regions.
region1=(re.split("circle|annulus",d.get("regions").partition("physical")[2]))[1].replace('(','').replace(')','').replace('#',',')
region2=(re.split("circle|annulus",d.get("regions").partition("physical")[2]))[2].replace('(','').replace(')','').replace('#',',')
print("Identified first region: ", region1)
print("Identified second region: ", region2)
#print("region1 "+region1.partition("color")[2].replace('=','').replace('\n',''))
#print("region2 "+region2.partition("color")[2].replace('=','').replace('\n',''))
# Identify source and background regions using the 'white' color.
c1=region1.partition("color")[2].replace('=','').replace('\n','')
print("Region1 color: "+c1)
if(c1=='white'):
regionsrc = region1
regionbkg = region2
else:
regionsrc = region2
regionbkg = region1
# Save and print selected region coordinates.
x_source = regionsrc.split(",")[0].replace('\n','')
y_source = regionsrc.split(",")[1].replace('\n','')
r_source = regionsrc.split(",")[2].replace('\n','')
print("The coordinates of the selected source region are: \n")
print(" x_source = ", x_source, "(physical)")
print(" y_source = ", y_source, "(physical)")
print(" r_source = ", r_source, "(physical) \n")
x_bkg = regionbkg.split(",")[0].replace('\n','')
y_bkg = regionbkg.split(",")[1].replace('\n','')
r_bkg = regionbkg.split(",")[2].replace('\n','')
print("The coordinates of the selected background region are: \n")
print(" x_bkg = ", x_bkg, "(physical)")
print(" y_bkg = ", y_bkg, "(physical)")
print(" r_bkg = ", r_bkg, "(physical) \n")
# If the background is an annulus, save and print R2.
if "annulus" in str(d.get("regions")):
r2_bkg = regionbkg.split(",")[3].replace('\n','')
print(" r2_bkg = ", r2_bkg, "(physical)")
x_source,y_source,r_source,x_bkg,y_bkg,r_bkg,r2_bkg = get_ds9_regions(out_IMFile, src_fn, bkg_fn)
#########################################
# Extract the source region light curve #
@@ -156,13 +97,10 @@ for obsid in files:
w(cmd, inargs).run()
# Inspect light curve
plt.figure(figsize=(20,8)) # Size of figure
plotLC(plt,pn_threshold,in_LCSRCFile) # Plot source region light curve
plt.legend()
plt.show()
#plt.figure(figsize=(20,8)) # Size of figure
#plotLC(plt,pn_threshold,in_LCSRCFile) # Plot source region light curve
#plt.legend()
#plt.show()
######################################
# Extract the source region spectrum #
@@ -179,8 +117,7 @@ for obsid in files:
cmd = "evselect" # SAS task to be executed
# Arguments of SAS Command
expression = f'{q_flag}&&(PATTERN<={n_pattern})&&((X,Y) IN circle({x_source},{y_source},{r_source}))' # event filter expression
expression = f'{q_flag}&&(PATTERN<={n_pattern})&&((X,Y) IN circle({x_source},{y_source},{r_source}))'
inargs = [f'table={eventfile}','withspectrumset=yes',f'spectrumset={in_SPSRCFile}',
'energycolumn=PI','spectralbinsize=5','withspecranges=yes','specchannelmin=0',
'specchannelmax=20479',f'expression={expression}']
@@ -199,10 +136,13 @@ for obsid in files:
cmd = "evselect" # SAS task to be executed
# Arguments of SAS Command
expression = f'{q_flag}&&(PATTERN<={n_pattern})&&((X,Y) IN circle({x_bkg},{y_bkg},{r_bkg}))' # event filter expression
if(r2_bkg==None):
expression = f'{q_flag}&&(PATTERN<={n_pattern})&&((X,Y) IN circle({x_bkg},{y_bkg},{r_bkg}))'
else:
expression = f'{q_flag}&&(PATTERN<={n_pattern})&&((X,Y) IN annulus({x_bkg},{y_bkg},{r_bkg},{r2_bkg}))'
inargs = [f'table={eventfile}','withspectrumset=yes',f'spectrumset={in_SPBKGFile}',
'energycolumn=PI','spectralbinsize=5','withspecranges=yes','specchannelmin=0',
'energycolumn=PI','spectralbinsize=5','specchannelmin=0',#'withspecranges=yes',
'specchannelmax=20479',f'expression={expression}']
print(" Filter expression to use: "+expression+" \n")
@@ -213,8 +153,13 @@ for obsid in files:
w("backscale", [f'spectrumset={in_SPSRCFile}',f'badpixlocation={eventfile}']).run()
w("backscale", [f'spectrumset={in_SPBKGFile}',f'badpixlocation={eventfile}']).run()
# https://www.cosmos.esa.int/web/xmm-newton/sas-thread-epic-merging
MAXENERGY=15
NBINS=1490
in_RESPFile = work_dir+'/EPIC_PN.rmf' # Name of the output redistribution
w("rmfgen", [f'spectrumset={in_SPSRCFile}',f'rmfset={in_RESPFile}']).run()
w("rmfgen", [f'spectrumset={in_SPSRCFile}',f'rmfset={in_RESPFile}',
'withenergybins=yes', 'energymin=0.1',
f'energymax={MAXENERGY}', f'nenergybins={NBINS}',]).run()
in_ARFFile = work_dir+'/EPIC_PN.arf' # Name of the output ancillary
cmd = "arfgen" # SAS task to be executed

View File

@@ -47,11 +47,20 @@ for obsid in files:
work_dir = init_work_dir(obsid, products_dir=products_dir)
print(f"\n*** jump to {work_dir} ***\n")
os.chdir(work_dir)
group_spectrum(key='mos1S001')
group_spectrum(key='mos2S002')
group_spectrum(key='pnS003')
group_spectrum(key='pnS003',oot=True)
dd='ffov_spectrum'
create_folder(dd)
group_spectrum(key='mos1S001',chdir='ffov_mos1S001',cpdir=dd)
group_spectrum(key='mos2S002',chdir='ffov_mos2S002',cpdir=dd)
pattern=0
group_spectrum(key='pnS003',oot=True,chdir=f'ffov_pnS003_{pattern}',cpdir=dd,pattern=pattern)
group_spectrum(key='pnS003',oot=False,chdir=f'ffov_pnS003_{pattern}',cpdir=dd,pattern=pattern)
pattern=4
group_spectrum(key='pnS003',oot=True,chdir=f'ffov_pnS003_{pattern}',cpdir=dd,pattern=pattern)
group_spectrum(key='pnS003',oot=False,chdir=f'ffov_pnS003_{pattern}',cpdir=dd,pattern=pattern)

132
scripts/05_sas_spectrum_merge.py Executable file
View File

@@ -0,0 +1,132 @@
#!/usr/bin/env python
from pysas.wrapper import Wrapper as w
import os, sys
from os.path import dirname
import inspect
import glob
import os.path
from os import path
import subprocess
import numpy as np
import matplotlib.pyplot as plt
from astropy.io import fits
from astropy.table import Table
from matplotlib.colors import LogNorm
import re
import pyds9
import arches
from arches.utils import *
from arches.config import *
root_path=dirname(dirname(dirname(inspect.getfile(arches))))
print("Arches root path: {}".format(root_path))
archive_dir=root_path+'/data/archive'
events_dir=root_path+'/data/processed'
products_dir=root_path+'/products/sas'
ds9reg_dir=root_path+'/data/ds9reg'
create_folder(products_dir)
inargs = ['--version']
t = w('sasver', inargs)
t.run()
files = glob.glob(archive_dir+'/*')
for obsid in files:
obsid = os.path.basename(obsid)
if(obsid in skip):
continue
work_dir = init_work_dir(obsid, products_dir=products_dir)
os.chdir(work_dir)
#
# Combine MOS1+2
#
spec=[]
bkg=[]
resp=[]
arf=[]
for imos in [1,2]:
in_SPSRCFile = work_dir+f'/EPIC_MOS{imos}_source_spectrum.fits' # Name of the output source spectrum
in_SPBKGFile = work_dir+f'/EPIC_MOS{imos}_background_spectrum.fits' # Name of the output background spectrum
in_RESPFile = work_dir+f'/EPIC_MOS{imos}.rmf' # Name of the output redistribution
in_ARFFile = work_dir+f'/EPIC_MOS{imos}.arf' # Name of the output ancillary
spec.append(in_SPSRCFile)
bkg.append(in_SPBKGFile)
resp.append(in_RESPFile)
arf.append(in_ARFFile)
in_spec=" ".join(spec)
in_bkg=" ".join(bkg)
in_resp=" ".join(resp)
in_arf=" ".join(arf)
out_SPSRCFile = work_dir+f'/EPIC_MOS_merged_source_spectrum.fits' # Name of the output source spectrum
out_SPBKGFile = work_dir+f'/EPIC_MOS_merged_background_spectrum.fits' # Name of the output background spectrum
out_RESPFile = work_dir+f'/EPIC_MOS_merged.rmf' # Name of the output redistribution
out_ARFFile = work_dir+f'/EPIC_MOS_merged.arf' # Name of the output ancillary
inargs = [f'pha=\"{in_spec}\"',f'bkg={in_bkg}',
f'rmf=\"{in_resp}\"',f'arf=\"{in_arf}\"',
f'allowHEdiff=yes',
f'filepha={out_SPSRCFile}',
f'filebkg={out_SPBKGFile}',
f'filersp={out_RESPFile}']
w("epicspeccombine", inargs).run()
# rebin the spectra and link associated files
in_GRPFile = work_dir+f'/EPIC_MOS_merged_spectrum_grp.fits' # Name of the output specgruop
inargs = [f'spectrumset={out_SPSRCFile}','mincounts=30','oversample=3',
f'rmfset={out_RESPFile}',
f'backgndset={out_SPBKGFile}',f'groupedset={in_GRPFile}']
w("specgroup", inargs).run()
#
# Combine MOS1,2+PN
#
in_SPSRCFile = work_dir+f'/EPIC_PN_source_spectrum.fits' # Name of the output source spectrum
in_SPBKGFile = work_dir+f'/EPIC_PN_background_spectrum.fits' # Name of the output background spectrum
in_RESPFile = work_dir+f'/EPIC_PN.rmf' # Name of the output redistribution
in_ARFFile = work_dir+f'/EPIC_PN.arf' # Name of the output ancillary
spec.append(work_dir+f'/EPIC_PN_source_spectrum.fits')
bkg.append(work_dir+f'/EPIC_PN_background_spectrum.fits')
resp.append(work_dir+f'/EPIC_PN.rmf')
arf.append(work_dir+f'/EPIC_PN.arf')
in_spec=" ".join(spec)
in_bkg=" ".join(bkg)
in_resp=" ".join(resp)
in_arf=" ".join(arf)
out_SPSRCFile = work_dir+f'/EPIC_merged_source_spectrum.fits' # Name of the output source spectrum
out_SPBKGFile = work_dir+f'/EPIC_merged_background_spectrum.fits' # Name of the output background spectrum
out_RESPFile = work_dir+f'/EPIC_merged.rmf' # Name of the output redistribution
out_ARFFile = work_dir+f'/EPIC_merged.arf' # Name of the output ancillary
inargs = [f'pha=\"{in_spec}\"',f'bkg={in_bkg}',
f'rmf=\"{in_resp}\"',f'arf=\"{in_arf}\"',
f'allowHEdiff=yes',
f'filepha={out_SPSRCFile}',
f'filebkg={out_SPBKGFile}',
f'filersp={out_RESPFile}']
w("epicspeccombine", inargs).run()
# rebin the spectra and link associated files
in_GRPFile = work_dir+f'/EPIC_merged_spectrum_grp.fits' # Name of the output specgruop
inargs = [f'spectrumset={out_SPSRCFile}','mincounts=30','oversample=3',
f'rmfset={out_RESPFile}',
f'backgndset={out_SPBKGFile}',f'groupedset={in_GRPFile}']
w("specgroup", inargs).run()

88
scripts/06_esas_protonscale.py Executable file
View File

@@ -0,0 +1,88 @@
#!/usr/bin/env python
from pysas.wrapper import Wrapper as w
import os, sys
from os.path import dirname
import inspect
import glob
import os.path
from os import path
import subprocess
import numpy as np
import matplotlib.pyplot as plt
from astropy.io import fits
from astropy.table import Table
from matplotlib.colors import LogNorm
import pyds9
import arches
from arches.utils import *
from arches.config import *
root_path=dirname(dirname(dirname(inspect.getfile(arches))))
print("Root path: {}".format(root_path))
archive_dir=root_path+'/data/archive'
events_dir=root_path+'/data/processed'
events_oot_dir=root_path+'/data/processed-oot'
products_dir=root_path+'/products/esas'
ds9reg_dir=root_path+'/data/ds9reg'
create_folder(products_dir)
inargs = ['--version']
t = w('sasver', inargs)
t.run()
files = glob.glob(archive_dir+'/*')
for obsid in files:
obsid = os.path.basename(obsid)
if(obsid in skip):
continue
work_dir = init_work_dir(obsid, products_dir=products_dir)
print(f"\n*** jump to {work_dir} ***\n")
os.chdir(work_dir)
key="mos1S001"
os.chdir(f'ffov_{key}')
inargs = [f'maskfile={key}-fovimspdet.fits',
f'specfile={key}-fovt.pi',
'mode=1',]
w('protonscale', inargs).run()
os.chdir('../')
key="mos2S002"
os.chdir(f'ffov_{key}')
inargs = [f'maskfile={key}-fovimspdet.fits',
f'specfile={key}-fovt.pi',
'mode=1',]
w('protonscale', inargs).run()
os.chdir('../')
key="pnS003"
os.chdir(f'ffov_{key}_0')
inargs = [f'maskfile={key}-fovimspdet.fits',
f'specfile={key}-fovt.pi',
'mode=1',]
w('protonscale', inargs).run()
os.chdir('../')
key="pnS003"
os.chdir(f'ffov_{key}_4')
inargs = [f'maskfile={key}-fovimspdet.fits',
f'specfile={key}-fovt.pi',
'mode=1',]
w('protonscale', inargs).run()
os.chdir('../')

191
scripts/06_sas_QPB.py Executable file
View File

@@ -0,0 +1,191 @@
#!/usr/bin/env python
from pysas.wrapper import Wrapper as w
import os, sys
from os.path import dirname
import inspect
import glob
import os.path
from os import path
import subprocess
import numpy as np
import matplotlib.pyplot as plt
from astropy.io import fits
from astropy.table import Table
from matplotlib.colors import LogNorm
import re
import pyds9
import arches
from arches.utils import *
from arches.config import *
root_path=dirname(dirname(dirname(inspect.getfile(arches))))
print("Arches root path: {}".format(root_path))
archive_dir=root_path+'/data/archive'
events_dir=root_path+'/data/processed'
products_dir=root_path+'/products/sas'
ds9reg_dir=root_path+'/data/ds9reg'
create_folder(products_dir)
inargs = ['--version']
t = w('sasver', inargs)
t.run()
files = glob.glob(archive_dir+'/*')
for obsid in files:
obsid = os.path.basename(obsid)
if(obsid in skip):
continue
work_dir = init_work_dir(obsid, products_dir=products_dir)
os.chdir(work_dir)
#
# Create QPB
# https://www.cosmos.esa.int/web/xmm-newton/sas-thread-background
#
attfiles = glob.glob(events_dir+f'/{obsid}/*{obsid}_AttHk.ds')
if(attfiles):
print(f"*** {attfiles} ***")
else:
print("AttHk?")
sys.exit()
attfile = attfiles[0]
if not os.path.isfile(attfile):
print ("File "+attfile+" does not exist, please check. \n")
sys.exit()
spec=[]
bkg=[]
resp=[]
arf=[]
#for imos in [1,2]:
for key in ['MOS1','MOS2','PN']:
evtfile = get_first_file(events_dir+f'/{obsid}/*{obsid}_E{key}*_ImagingEvts.ds')
# Run the SAS task evqpb over each one of these event files.
evqpb_outset=work_dir+f'/EPIC_{key}_QPB.fits' # Name of the output file
inargs = [f'table={evtfile}', f'attfile={attfile}',
f'outset={evqpb_outset}',
f'exposurefactor=2.0',]
w("evqpb", inargs).run()
gti=f'EPIC_{key}_gti.fit'
expression=f'gti({gti},TIME)'
# filter the EPIC event files to create cleaned and filtered for
# flaring particle background event files for your observation
sci_clean=work_dir+f'/EPIC_{key}_filtered.fits' # Name of the output file
inargs = [f'table={evtfile}', 'withfilteredset=yes',
f'filteredset={sci_clean}',
'destruct=yes','keepfilteroutput=true',
f'expression={expression}']
w("evselect", inargs).run()
# Use the same expression to filter the FWC event files:
qpb_clean=work_dir+f'/EPIC_{key}_QPB_clean.fits' # Name of the output file
inargs = [f'table={evqpb_outset}', 'withfilteredset=yes',
f'filteredset={qpb_clean}',
'destruct=yes','keepfilteroutput=true',
f'expression={expression}']
w("evselect", inargs).run()
if(key=='PN'):
expression='(#XMMEA_EP)&&(PATTERN<=4)&&(PI>=200)&&(PI<=12000)'
else:
expression='(#XMMEA_EM)&&(PATTERN<=12)&&(PI>=200)&&(PI<=12000)'
sci_image=work_dir+f'/EPIC_{key}_sci_image.fits' # Name of the output file
# Extract an image for the science exposure
inargs = [f'table={sci_clean}', f'expression={expression}',
'imagebinning=binSize', f'imageset={sci_image}',
'withimageset=yes','xcolumn=X', 'ycolumn=Y',
'ximagebinsize=80', 'yimagebinsize=80',
]
w("evselect", inargs).run()
qpb_image=work_dir+f'/EPIC_{key}_qpb_image.fits' # Name of the output file
# Extract an image for the FWC exposure
inargs = [f'table={qpb_clean}', f'expression={expression}',
'imagebinning=binSize', f'imageset={qpb_image}',
'withimageset=yes','xcolumn=X', 'ycolumn=Y',
'ximagebinsize=80', 'yimagebinsize=80','zcolumn=EWEIGHT',
]
w("evselect", inargs).run()
# Subtract background
cor_image=work_dir+f'/EPIC_{key}_cor_image.fits' # Name of the output file
cmd = ['farith', f'{sci_image}', f'{qpb_image}', f'{cor_image}', 'SUB',
'copyprime=yes',
'clobber=yes']
result = subprocess.run(cmd, capture_output=True, text=True, check=True)
continue
#
# How to use the FWC event files for spectra generation
#
src_fn=f'{ds9reg_dir}/{obsid}/src.reg'
bkg_fn=f'{ds9reg_dir}/{obsid}/bkg.reg'
x_source,y_source,r_source,x_bkg,y_bkg,r_bkg,r2_bkg = get_ds9_regions(sci_image, src_fn, bkg_fn)
######################################
# Extract the source region spectrum #
######################################
# Define some parameters for filtering the event file
q_flag = "#XMMEA_EP" if (key=='PN') else "#XMMEA_EM" # Quality flag for EPIC pn
n_pattern = 4 if (key=='PN') else 12 # Pattern selection
# for the source region of the science exposure
sci_spec_file = work_dir+f'/EPIC_{key}_source_spectrum.fits' # Name of the output source spectrum
expression = f'{q_flag}&&(PATTERN<={n_pattern})&&((X,Y) IN circle({x_source},{y_source},{r_source}))'
inargs = [f'table={sci_clean}','withspectrumset=yes',f'spectrumset={sci_spec_file}',
'energycolumn=PI','spectralbinsize=5','withspecranges=yes','specchannelmin=0',
'specchannelmax=11999',f'expression={expression}']
w("evselect", inargs).run()
# for the background region of the science exposure
sci_bkg_file = work_dir+f'/EPIC_{key}_background_spectrum.fits'
if(r2_bkg==None):
expression = f'{q_flag}&&(PATTERN<={n_pattern})&&((X,Y) IN circle({x_bkg},{y_bkg},{r_bkg}))'
else:
expression = f'{q_flag}&&(PATTERN<={n_pattern})&&((X,Y) IN annulus({x_bkg},{y_bkg},{r_bkg},{r2_bkg}))'
inargs = [f'table={sci_clean}','withspectrumset=yes',f'spectrumset={sci_bkg_file}',
'energycolumn=PI','spectralbinsize=5','withspecranges=yes','specchannelmin=0',
'specchannelmax=11999',f'expression={expression}']
w("evselect", inargs).run()
# for the source region of the science exposure
qpb_spec_file = work_dir+f'/EPIC_{key}_qpb_source_spectrum.fits' # Name of the output source spectrum
expression = f'{q_flag}&&(PATTERN<={n_pattern})&&((X,Y) IN circle({x_source},{y_source},{r_source}))'
inargs = [f'table={qpb_clean}','withspectrumset=yes',f'spectrumset={qpb_spec_file}',
'energycolumn=PI','spectralbinsize=5','withspecranges=yes','specchannelmin=0',
'specchannelmax=11999',f'expression={expression}', 'zcolumn=EWEIGHT',]
w("evselect", inargs).run()
# for the source region of the science exposure
qpb_bkg_file = work_dir+f'/EPIC_{key}_qpb_background_spectrum.fits' # Name of the output source spectrum
if(r2_bkg==None):
expression = f'{q_flag}&&(PATTERN<={n_pattern})&&((X,Y) IN circle({x_bkg},{y_bkg},{r_bkg}))'
else:
expression = f'{q_flag}&&(PATTERN<={n_pattern})&&((X,Y) IN annulus({x_bkg},{y_bkg},{r_bkg},{r2_bkg}))'
inargs = [f'table={qpb_clean}','withspectrumset=yes',f'spectrumset={qpb_bkg_file}',
'energycolumn=PI','spectralbinsize=5','withspecranges=yes','specchannelmin=0',
'specchannelmax=11999',f'expression={expression}', 'zcolumn=EWEIGHT',]
w("evselect", inargs).run()
"""
By using the zcolumn parameter in the generation of the spectra for the FWC exposure,
we ensure that the produced FWC spectra are correctly scaled for the ratio of exposure times
between science and FWC exposures. By doing so, the FWC spectra are ready to be
subtracted from the science spectra.
"""
#sys.exit()