36
36
# following https://statmorph.readthedocs.io/en/latest/notebooks/tutorial.html
37
37
## to learn it
38
38
39
+ # import sys # <-comment out to see the output
40
+ # tmp = sys.stdout # <-comment out to see the output
41
+
42
+ # output_file = '/home/robbler/research/statmorph_output/log_statmorph_output.txt'
43
+ # sys.stdout = open(output_file, "w") # <-comment out to see the output
44
+
39
45
40
46
def run_in_jades (filter = 'f277w' ,output_name = 'JADES_statmorph_measurements' ,use_grizli = False ):
41
47
###############################
@@ -160,20 +166,21 @@ def run_in_jades(filter='f277w',output_name='JADES_statmorph_measurements',use_g
160
166
### only values to change under this change are SN and parameteric values like sersic
161
167
162
168
163
- ### importing fits files for GS
169
+ ### importing fits files for GS ##############
164
170
165
- # starting with f444 because it should have the clearest source (maybe not clear detail though)
166
- #hdul = fits.open('JADES_Fits_Maps/hlsp_jades_jwst_nircam_goods-s-deep_f444w_v2.0_drz.fits')
167
171
hdul = None
168
172
gs_whtmap = None
169
173
gs_jades_seg = None
170
-
174
+ full_jades_seg = None # for testing with grizli so that we use thE JADES SEGMAP
175
+ gs_jades_wcs = None # ^^^^^^^^^^^
171
176
### try to use the grizli data reduction otherwise use jades
172
177
if (use_grizli ):
173
178
grizli_hdul = fits .open (f'/home/robbler/research/grizli-reductions/gds-grizli-v7.2-{ filter } -clear_drc_sci.fits' )
174
179
hdul = grizli_hdul
175
180
gs_whtmap = fits .open (f'/home/robbler/research/grizli-reductions/gds-grizli-v7.2-{ filter } -clear_drc_wht.fits' )[0 ].data
176
- gs_jades_seg = fits .getdata ('/home/robbler/research/grizli-reductions/gds-grizli-v7.2-ir_seg.fits' )
181
+ # gs_jades_seg = fits.getdata('/home/robbler/research/grizli-reductions/gds-grizli-v7.2-ir_seg.fits')
182
+ gs_jades_seg = fits .getdata ('/home/robbler/research/JADES_Fits_Maps/GS/hlsp_jades_jwst_nircam_goods-s-deep_segmentation_v2.0_drz.fits' )
183
+ full_jades_seg = fits .open ('/home/robbler/research/JADES_Fits_Maps/GS/hlsp_jades_jwst_nircam_goods-s-deep_segmentation_v2.0_drz.fits' )
177
184
else :
178
185
hdul = fits .open (f'/home/robbler/research/JADES_Fits_Maps/GS/hlsp_jades_jwst_nircam_goods-s-deep_{ filter } _v2.0_drz.fits' )
179
186
# segmentation map
@@ -182,7 +189,7 @@ def run_in_jades(filter='f277w',output_name='JADES_statmorph_measurements',use_g
182
189
183
190
184
191
# catalog file
185
- tmp = fits .open ('research/JADES catalog/hlsp_jades_jwst_nircam_goods-s-deep_photometry_v2.0_catalog.fits' )
192
+ tmp = fits .open ('/home/robbler/ research/JADES catalog/hlsp_jades_jwst_nircam_goods-s-deep_photometry_v2.0_catalog.fits' )
186
193
187
194
# generate PSF for current filter
188
195
# nc = webbpsf.NIRCam()
@@ -195,33 +202,37 @@ def run_in_jades(filter='f277w',output_name='JADES_statmorph_measurements',use_g
195
202
if (use_grizli ):
196
203
gs_sci = hdul [0 ].data
197
204
gs_wcs_coords = WCS (hdul [0 ].header )
205
+ ###### for testing with grizli sources so that we use the JADES SEGMAP instead
206
+ gs_jades_wcs = WCS (full_jades_seg [0 ].header )
207
+ # gn_wcs_coords = WCS(hdul[0].header)
208
+ full_jades_seg .close ()
198
209
else :
199
210
gs_sci = hdul [1 ].data # for getting the science image
200
211
gs_wcs_coords = WCS (hdul [1 ].header ) # getting wcs from header
201
- #print(f'wcs_header_info: {hdul[1].header}')
202
212
hdul .close ()
203
213
204
214
# catalog file
205
215
gs_jades_catalog = Table (tmp ['FLAG' ].data ) # extension #2 "FLAG" data
206
216
tmp .close ()
207
217
208
-
209
- gn_whtmap = fits .open (f'/home/robbler/research/grizli-reductions/gdn-grizli-v7.3-{ filter } -clear_drc_wht.fits' )
210
218
# print(gn_whtmap[0].header['FLAGS_WEIGHT'])
211
219
# exit()
212
220
213
- ##### open goods north files ... #######
221
+ #################### open goods north files ... ############################################################################ #######
214
222
# starting with f444 because it should have the clearest source (maybe not clear detail though)
215
223
#hdul = fits.open('JADES_Fits_Maps/hlsp_jades_jwst_nircam_goods-s-deep_f444w_v2.0_drz.fits')
216
224
217
225
### try to use the grizli data reduction otherwise use jades
218
226
gn_whtmap = None
219
227
gn_jades_seg = None
228
+ gn_jades_wcs = None
220
229
if (use_grizli ):
221
230
grizli_hdul = fits .open (f'/home/robbler/research/grizli-reductions/gdn-grizli-v7.3-{ filter } -clear_drc_sci.fits' )
222
231
hdul = grizli_hdul
223
232
gn_whtmap = fits .open (f'/home/robbler/research/grizli-reductions/gdn-grizli-v7.3-{ filter } -clear_drc_wht.fits' )[0 ].data
224
- gn_jades_seg = fits .getdata ('/home/robbler/research/grizli-reductions/gdn-grizli-v7.3-ir_seg.fits' )
233
+ # gn_jades_seg = fits.getdata('/home/robbler/research/grizli-reductions/gdn-grizli-v7.3-ir_seg.fits')
234
+ gn_jades_seg = fits .getdata ('research/JADES_Fits_Maps/GN/hlsp_jades_jwst_nircam_goods-n_segmentation_v1.0_drz.fits' )
235
+ full_jades_seg = fits .open ('research/JADES_Fits_Maps/GN/hlsp_jades_jwst_nircam_goods-n_segmentation_v1.0_drz.fits' )
225
236
else :
226
237
hdul = fits .open (f'research/JADES_Fits_Maps/GN/hlsp_jades_jwst_nircam_goods-n_{ filter } _v1.0_drz.fits' )
227
238
# segmentation map
@@ -241,15 +252,19 @@ def run_in_jades(filter='f277w',output_name='JADES_statmorph_measurements',use_g
241
252
if (use_grizli ):
242
253
gn_sci = hdul [0 ].data
243
254
gn_wcs_coords = WCS (hdul [0 ].header )
255
+ ###### for testing with grizli sources so that we use the JADES SEGMAP instead
256
+ gn_jades_wcs = WCS (full_jades_seg [0 ].header )
257
+ # gn_wcs_coords = WCS(hdul[0].header)
258
+ full_jades_seg .close ()
244
259
else :
245
260
gn_sci = hdul [1 ].data # for getting the science image
246
261
gn_wcs_coords = WCS (hdul [1 ].header ) # getting wcs from header
247
262
hdul .close ()
248
-
249
263
# catalog file
250
264
gn_jades_catalog = Table (tmp ['FLAG' ].data ) # extension #2 "FLAG" data
251
265
tmp .close ()
252
266
267
+
253
268
# maybe this is the weight value we're looking for for statmorph (one value for each entry, so how would I convert this to an image to be used with statmorph though?)
254
269
#print(jades_catalog[3]['F444W_WHT'])
255
270
@@ -272,7 +287,12 @@ def run_in_jades(filter='f277w',output_name='JADES_statmorph_measurements',use_g
272
287
# detection radius ~ 1" for Kirkpatrick data, so we want anything within a ~3" box
273
288
# maybe change this later to reflect the light distribution (20%, 80% radii)
274
289
275
- size = 6 # cutout size in arcsec, might need to tweak depending on the source size
290
+ if (use_grizli ):
291
+ size = 8 # cutout size in arcsec, might need to tweak depending on the source size
292
+ # this was a size of 6 for JADES sources (scaling ratio is ~.75)
293
+ else :
294
+ size = 6 # ~0.75 the grizli one (equates to 200x200) sized cutouts
295
+
276
296
277
297
# jades_id = jades_names[ind]
278
298
# get jades id counterpart coordinates
@@ -312,26 +332,41 @@ def run_in_jades(filter='f277w',output_name='JADES_statmorph_measurements',use_g
312
332
# search_one_id = np.array([kirk_id])
313
333
search_ids = sources ['ID' ]
314
334
full_output = sources
335
+ # search_ids = ['GN_IRS33^e','GS_IRS12','GS_IRS34','GS_IRS37','GS_IRS62','GS_IRS9'] # trouble sources with grizli
336
+ # search_ids = ['GS_IRS2'] # for testing with a high S/N source
337
+ # search_ids = ['GS_IRS34']
338
+
315
339
cols = ['Filter' ,'Flag' ,'Concentration (C)' ,'Asymmetry (A)' ,'Outer Asymmetry (Ao)' ,'Smoothness (S)' ,'Gini' ,'M20' ,'Gini-M20-Merger' ,'Multimode (M)' ,'Intensity (I)' ,'Deviation (D)' ,'S/N' ,'Cutout Size (pix)' ]
316
- # for id in search_one_id:
340
+
341
+
342
+ ###############################
343
+ #### searching for the ID #####
344
+ ###############################
317
345
for id in search_ids :
318
346
row = []
319
- # data_source = sources[(sources['ID'].str.contains(id))]
347
+ if (id == 'GS_IRS34' ):
348
+ size = 10 # change the size of the cutout for the biggest source
349
+ else :
350
+ size = 8
351
+ # this way it's properly fitting it and not returning flag 2
352
+
320
353
data_source = sources [(sources ['ID' ].str .contains (id ,regex = False ))].iloc [0 ]
321
354
search_id = id
322
- jades_catalog ,sci ,jades_seg ,wcs_coords ,whtmap = (None for i in range (5 ))
355
+ jades_catalog ,sci ,jades_seg ,wcs_coords ,jades_wcs_coords , whtmap = (None for i in range (6 ))
323
356
324
357
if (id .startswith ('GN' )):
325
358
jades_catalog = gn_jades_catalog
326
359
sci = gn_sci
327
360
jades_seg = gn_jades_seg
328
361
wcs_coords = gn_wcs_coords
362
+ jades_wcs_coords = gn_jades_wcs
329
363
whtmap = gn_whtmap
330
364
if (id .startswith ('GS' )):
331
365
jades_catalog = gs_jades_catalog
332
366
sci = gs_sci
333
367
jades_seg = gs_jades_seg
334
368
wcs_coords = gs_wcs_coords
369
+ jades_wcs_coords = gs_jades_wcs
335
370
whtmap = gs_whtmap
336
371
337
372
jades_id_raw = data_source ['JADES ID' ]
@@ -343,48 +378,100 @@ def run_in_jades(filter='f277w',output_name='JADES_statmorph_measurements',use_g
343
378
344
379
source = jades_catalog [jades_catalog ['ID' ]== jades_id ] # make sure jades_id is an integer, otherwise it just returns the first item NOT AN ERROR??
345
380
position = SkyCoord (source ['RA' ],source ['DEC' ],unit = 'deg' )
381
+
382
+
383
+ ###################
384
+ # try to get the cutout, print error and continue if it fails #
385
+ # usually fails if the wcs coordinates aren't set right
386
+ ###################
346
387
try :
347
388
img = Cutout2D (sci ,position ,size * units .arcsec ,wcs = wcs_coords ,copy = True ).data
348
389
wht = None
349
390
if (use_grizli ):
350
391
wht = Cutout2D (whtmap ,position ,size * units .arcsec ,wcs = wcs_coords ,copy = True ).data
351
- # get the segmap for the specific source
352
- seg = Cutout2D (jades_seg ,position ,size * units .arcsec ,wcs = wcs_coords ,copy = True ).data
392
+ #### testing with different size to use the jades segmap instead so we can get accurate measurement for S/N
393
+ seg = Cutout2D (jades_seg ,position ,.75 * size * units .arcsec ,wcs = jades_wcs_coords ,copy = True ).data
394
+ else :
395
+ # get the segmap for the specific source
396
+ seg = Cutout2D (jades_seg ,position ,size * units .arcsec ,wcs = wcs_coords ,copy = True ).data
353
397
seg_img = SegmentationImage (seg )
398
+ # plt.imshow(seg_img)
399
+ # plt.show()
400
+ # plt.imshow(img)
401
+ # plt.show()
354
402
except :
355
403
print (f'[!!!] ERROR with IMG for { search_id } ' )
356
404
continue
405
+ ############ TESTING SNR #################################
406
+ # sn_testing = img/(1/wht)
407
+
408
+ ## testing with something of a similar size to the gini segmap
409
+ # gini_cut = Cutout2D(sci,position,size/7*units.arcsec,wcs=wcs_coords,copy=True).data
410
+ # gini_wht = Cutout2D(whtmap,position,size/7*units.arcsec,wcs=wcs_coords,copy=True).data
411
+ # new_sn = gini_cut/(1/gini_wht)
412
+ # plt.imshow(new_sn,origin='lower')
413
+ # plt.colorbar()
414
+ # plt.show()
415
+ # # print(np.mean(sn_testing))
416
+ # print(np.mean(new_sn))
417
+
418
+ # full_sn = img/(1/wht)
419
+ # plt.imshow(full_sn,origin='lower')
420
+ # plt.colorbar()
421
+ # plt.show()
422
+ # print(np.mean(full_sn))
423
+ # exit()
424
+ # # noise = np.std(1/wht)
357
425
426
+ # print(img.shape)
427
+ # noise_cut = img[100:150,0:50]
428
+ # plt.imshow(noise_cut,origin='lower')
429
+ # plt.colorbar()
430
+ # plt.show()
358
431
432
+ # plt.imshow(img,origin='lower')
433
+ # plt.colorbar()
434
+ # plt.show()
435
+ # noise_new = np.std(noise_cut)
436
+
437
+ # print(np.max(img)/noise_new)
438
+ # sn_test = img/noise
439
+ # print(np.max(img)/noise)
440
+ # # print(sn_test)
441
+ # # print(sn_testing)
442
+ # plt.imshow(sn_test,origin='lower')
443
+ # plt.show()
444
+ # exit()
445
+ #############################################
359
446
# seg_img_id = np.where(seg_img.labels==jades_id)[0][0] # for running statmorph on only the jades ID we want
360
447
# m = np.mean(img)
361
448
# s = np.std(img)
362
- sigma = 2.0 # detection threshold =1.5*sigma
363
- fwhm = fwhms [filter .upper ()]
449
+ # sigma = 2.0 # detection threshold =1.5*sigma
450
+ # fwhm = fwhms[filter.upper()]
364
451
365
452
# making a 2d gaussian kernel with fwhm 3 pixels (Ren paper uses 0.2 Petrosian Radius)
366
453
# then getting a sample of the background and using that as the threshold for detection
367
454
# instead of just sigma ##################
368
- npix = 60 # min pixels for connection
455
+ # npix = 60 # min pixels for connection
369
456
# from astropy.stats import SigmaClip
370
- sigma_clip = SigmaClip (sigma = 4.0 ,maxiters = 10 )
457
+ # sigma_clip = SigmaClip(sigma=4.0,maxiters=10)
371
458
# sigma_clip = SigmaClip(sigma=sigma+2.0)
372
459
# bkg_estimator = MedianBackground(sigma_clip=sigma_clip)
373
460
# bkg = Background2D(img, (9,9), filter_size=(13,13), bkg_estimator=bkg_estimator)
374
461
# bkg = Background2D(img,(25,25),filter_size=(9,9),sigma_clip=sigma_clip,bkg_estimator=bkg_estimator)
375
462
# img -= bkg.background # subtract the background
376
- kernel = make_2dgaussian_kernel (fwhm , size = 5 )
377
- convolved_data = convolve (img , kernel )
463
+ # kernel = make_2dgaussian_kernel(fwhm, size=5)
464
+ # convolved_data = convolve(img, kernel)
378
465
# convolved_image = convolve(img,psf[0:100][0:100])
379
466
# convolved_image = convolve(img,psf)
380
467
#threshold = detect_threshold(convolved_data,sigma)
381
- threshold = detect_threshold (convolved_data ,sigma ,sigma_clip = sigma_clip )
468
+ # threshold = detect_threshold(convolved_data,sigma,sigma_clip=sigma_clip)
382
469
#mean,_,std = sigma_clipped_stats(img)
383
470
#threshold = sigma*std
384
471
# make the segmentation map using the bg subtracted image, threshold, & number of required connected pixels
385
- segmap = detect_sources (convolved_data ,threshold ,npix )
472
+ # segmap = detect_sources(convolved_data,threshold,npix)
386
473
# then separate connected segmentation sources by deblending them
387
- deblended_segmap = deblend_sources (convolved_data ,segmap ,npixels = npix ,nlevels = 32 ,contrast = 0.5 ) # nlevel=32 & contrast=0.01
474
+ # deblended_segmap = deblend_sources(convolved_data,segmap,npixels=npix,nlevels=32,contrast=0.5) # nlevel=32 & contrast=0.01
388
475
389
476
# segmap_final = convolve(deblended_segmap,seg)
390
477
# deblended_segmap = seg # testing with no deblending
@@ -401,12 +488,12 @@ def run_in_jades(filter='f277w',output_name='JADES_statmorph_measurements',use_g
401
488
# plt.show()
402
489
403
490
## attempt to find the biggest segmap part, and fit that within the cutout
404
- areas = np .zeros ([len (seg_img .labels )])
405
- v = 0
406
- areas = seg_img .get_areas (seg_img .labels )
407
- # for i in seg_img.labels:
408
- # v+=1
409
- seg_id = seg_img .labels [np .where (areas == np .max (areas ))[0 ][0 ]]
491
+ # areas = np.zeros([len(seg_img.labels)])
492
+ # v=0
493
+ # areas = seg_img.get_areas(seg_img.labels)
494
+ # # for i in seg_img.labels:
495
+ # # v+=1
496
+ # seg_id = seg_img.labels[np.where(areas==np.max(areas))[0][0]]
410
497
#################################################
411
498
412
499
source_gain = source [f'{ filter .upper ()} _WHT' ] # this seems wrong, need to figure out weightmap issue
@@ -416,29 +503,14 @@ def run_in_jades(filter='f277w',output_name='JADES_statmorph_measurements',use_g
416
503
### ^^^^ maybe useful later for all nircam data gain map
417
504
### https://jwst-pipeline.readthedocs.io/en/latest/jwst/gain_scale/description.html
418
505
## the value of gain=source_gain might not be right, need to check with Alex or Sam to see if that's what I should be doing here...
506
+ print (f'----------------' )
419
507
morph = None
420
508
if (use_grizli ):
421
- morph = statmorph .SourceMorphology (img ,seg_img ,seg_id ,weightmap = (1 / wht ),skybox_size = 64 ,verbose = False ) # weight map some auto generated by SExtractor will give it as 1/RMS
509
+ morph = statmorph .SourceMorphology (img ,seg_img ,jades_id ,weightmap = (1 / wht ),skybox_size = 32 ,verbose = True ) # weight map some auto generated by SExtractor will give it as 1/RMS
510
+ # maybe label id should be seg_id (but it's only getting the max value here)
422
511
else :
423
- morph = statmorph .SourceMorphology (img ,seg_img ,jades_id ,gain = source_gain ,skybox_size = 64 ,verbose = False ) # maybe cutout_extent=1?
512
+ morph = statmorph .SourceMorphology (img ,seg_img ,jades_id ,gain = source_gain ,skybox_size = 32 ,verbose = True ) # maybe cutout_extent=1?
424
513
425
- '''
426
- stat_rows[c,0] = id #id
427
- stat_rows[c,1] = position # position (skycoord)
428
- stat_rows[c,2] = morph.flag # flag (error, 0=great, 1=ok, 2=bad)
429
- stat_rows[c,3] = morph.concentration # concentration
430
- stat_rows[c,4] = morph.asymmetry # asymmetry
431
- stat_rows[c,5] = morph.outer_asymmetry # outer asymmetry
432
- stat_rows[c,6] = morph.deviation # deviation (not sure if this is total or just outer?)
433
- stat_rows[c,7] = morph.smoothness # smoothness (clumpiness)
434
- stat_rows[c,8] = morph.gini # gini
435
- stat_rows[c,9] = morph.m20 # m20
436
- stat_rows[c,10] = morph.gini_m20_merger # gini/m20 for mergers
437
- stat_rows[c,11] = morph.sn_per_pixel # s/n ratio (per pixel?)
438
- stat_rows[c,12] = (f'({morph.xmax_stamp-morph.xmin_stamp},{morph.ymax_stamp-morph.ymin_stamp})') # size of cutout
439
- c+=1
440
- '''
441
- print (f'----------------' )
442
514
print (f'[---] Searching for Kirk ID: { search_id } ' )
443
515
print (f'[---] Searching for JADES ID: { jades_id } ' )
444
516
print (f'[---] Found JADES ID: { source ["ID" ][0 ]} ' )
@@ -479,11 +551,11 @@ def run_in_jades(filter='f277w',output_name='JADES_statmorph_measurements',use_g
479
551
savepath = (f'research/statmorph_output/{ filter } /{ size } _{ search_id } ' )
480
552
if (use_grizli ):
481
553
savepath = (f'research/statmorph_output/grizli/{ filter } /{ size } _{ search_id } ' )
482
- # plt.savefig(savepath,dpi=100)
483
- plt .show ()
554
+ plt .savefig (savepath ,dpi = 100 )
555
+ # plt.show()
484
556
plt .close ()
485
557
486
- full_output .to_csv (f'research/statmorph_output/{ filter } _{ size } _{ output_name } .tsv' ,'\t ' )
558
+ full_output .to_csv (f'research/statmorph_output/grizli/ { filter } _{ size } _{ output_name } .tsv' ,'\t ' )
487
559
print ('[!!!] Finished statmorph measurements -- outputing table...' )
488
560
print (full_output )
489
561
disclaimer ()
@@ -678,10 +750,11 @@ def test_in_ceers():
678
750
679
751
# test_in_ceers()
680
752
681
- grizli_filters = ['f277w' ,'f356w' ,'f444w' ]
682
- jades_filters = ['f277w' ,'f356w' ,'f444w' ]
683
- for i in jades_filters :
684
- run_in_jades (filter = i ,use_grizli = False ,output_name = 'testing-gain-values-jades' )
753
+ grizli_filters = ['f115w' ,'f150w' ,'f200w' ,'f277w' ,'f356w' ,'f444w' ]
754
+ grizli_filters = ['f277w' ,'f356w' ,'f444w' ] # testing with these bc others are giving errors?
755
+ jades_filters = ['f115w' ,'f150w' ,'f200w' ,'f277w' ,'f356w' ,'f444w' ]
756
+ for i in grizli_filters :
757
+ run_in_jades (filter = i ,use_grizli = True ,output_name = 'grizli_1_over_wht' )
685
758
686
759
687
760
@@ -701,3 +774,7 @@ def make_circles(table,radius):
701
774
dec = i ['dec' ]
702
775
print (f'circle({ ra } , { dec } , { radius } ") # text={{{ label } }}' )
703
776
c += 1
777
+
778
+
779
+ # save all output to "all, err, out" files
780
+ # command 2> >(tee /research/statmorph_output/err) 1> >(tee /research/statmorph_output/out) | tee >/research/statmorph_output/all.txt
0 commit comments