@@ -69,9 +69,8 @@ def __init__(
6969 bgr_background_name = "off" ,
7070 process_bgr_like_science = False ,
7171 jwst_parameters = None ,
72- do_drizzle = None ,
72+ do_drizzle = False ,
7373 do_blot = False ,
74- blot_ref_index = 0 ,
7574 blot_fillval = np .nan ,
7675 overwrite = False ,
7776 ):
@@ -123,17 +122,12 @@ def __init__(
123122 do_drizzle: If True, drizzle individual frames
124123 to the i2d mosaic WCS after the main
125124 pipeline run. Note: creates a lot of files.
126- If not set (None) and do_blot is True,
127- do_drizzle is automatically enabled. If
128- explicitly set to False while do_blot is
129- True, a ValueError is raised. Defaults to
130- None.
131- do_blot: If True, blot each resampled exposure
132- back to a reference detector frame (requires
133- drizzling). Defaults to False.
134- blot_ref_index: Index into the alphabetically sorted CRF file list of
135- the reference exposure whose detector frame
136- is used for blotting. Defaults to 0.
125+ Defaults to False.
126+ do_blot: If True, blot the final i2d mosaic to
127+ the detector frame of each exposure,
128+ producing one ``*_i2d_blot.fits`` file per
129+ exposure. Independent of do_drizzle.
130+ Defaults to False.
137131 blot_fillval: Fill value for pixels outside the
138132 blotted footprint. Defaults to np.nan
139133 overwrite: Whether to overwrite or not. Defaults
@@ -175,18 +169,9 @@ def __init__(
175169 self .bgr_background_name = bgr_background_name
176170 self .process_bgr_like_science = process_bgr_like_science
177171 self .jwst_parameters = jwst_parameters
178- if do_drizzle is False and do_blot :
179- raise ValueError (
180- "do_drizzle was explicitly set to False, but do_blot "
181- "was set to True. Either set (do_drizzle, do_blot) to "
182- "(True, True) or (True, False), or (None, True)."
183- )
184- if do_drizzle is None :
185- do_drizzle = bool (do_blot )
186172 self .do_drizzle = do_drizzle
187173 self .do_blot = do_blot
188- self .blot_ref_index = blot_ref_index
189- self .blot_fillval = blot_fillval
174+ self .blot_fillval = float (blot_fillval )
190175 self .overwrite = overwrite
191176
192177 self .band_type = get_band_type (self .band )
@@ -696,88 +681,85 @@ def run_step(
696681 # - Can't have suffix ending in _i2d.fits, messes with anchoring pattern matching.
697682 for f in glob .glob (os .path .join (self .out_dir , "*_outlier_resamplestep.fits" )):
698683 os .rename (f , f .replace ("_outlier_resamplestep.fits" , "_i2d_single.fits" ))
699-
700- if self .do_blot :
701- self ._blot_to_detector_frame (
702- crf_files = crf_files ,
703- ref_index = self .blot_ref_index ,
704- )
705684 else :
706685 log .warning ("do_drizzle is set but no i2d/crf files found" )
707686
687+ if self .do_blot :
688+ i2d_files = glob .glob (os .path .join (self .out_dir , "*_i2d.fits" ))
689+ crf_files = sorted (glob .glob (os .path .join (self .out_dir , "*_crf.fits" )))
690+ if i2d_files and crf_files :
691+ self ._blot_to_detector_frame (crf_files = crf_files )
692+ else :
693+ log .warning ("do_blot is set but no i2d/crf files found" )
694+
708695 return True
709696
710697 def _blot_to_detector_frame (
711698 self ,
712699 crf_files ,
713- ref_index = 0 ,
714700 ):
715- """Blot resampled single-exposure images back to a detector frame.
701+ """Blot the final i2d mosaic to each exposure's detector frame.
716702
717- Each ``*_i2d_single.fits`` file (one per exposure, on the common
718- i2d WCS grid) is blotted onto the detector frame of the chosen
719- reference exposure. The output files are written as
720- ``*_blot_det.fits`` alongside the other lv3 products.
703+ The ``*_i2d.fits`` mosaic is blotted onto the detector frame of
704+ every CRF exposure, producing one ``*_i2d_blot.fits`` file per
705+ exposure alongside the other lv3 products.
721706
722707 Args:
723708 crf_files: Sorted list of CRF file paths (one per exposure).
724- Used to obtain the detector-frame GWCS and shape.
725- ref_index: Index into *crf_files* of the reference exposure
726- whose detector frame will be adopted. Defaults to 0
727- (the first exposure).
709+ Each CRF provides the detector-frame GWCS and shape that
710+ the mosaic is blotted onto.
728711 """
729712
730- single_files = sorted (
731- glob .glob (os .path .join (self .out_dir , "*_i2d_single.fits" ))
732- )
733- if not single_files :
734- log .warning ("_blot_to_detector_frame: no *_i2d_single.fits files found" )
713+ i2d_files = glob .glob (os .path .join (self .out_dir , "*_i2d.fits" ))
714+ if not i2d_files :
715+ log .warning ("_blot_to_detector_frame: no *_i2d.fits mosaic found" )
735716 return
736717
737- if ref_index >= len (crf_files ) :
718+ if len (i2d_files ) > 1 :
738719 log .warning (
739- "_blot_to_detector_frame: ref_index %d out of range (%d exposures) " ,
740- ref_index , len ( crf_files ),
720+ "_blot_to_detector_frame: found %d i2d files, using %s " ,
721+ len ( i2d_files ), os . path . basename ( i2d_files [ 0 ] ),
741722 )
742- return
743723
744724 log .info (
745- "Blotting %d resampled exposures to detector frame of %s " ,
746- len (single_files ), os . path . basename ( crf_files [ ref_index ] ),
725+ "Blotting i2d mosaic to %d exposure detector frames " ,
726+ len (crf_files ),
747727 )
748728
749- with datamodels .open (crf_files [ ref_index ]) as ref_model :
750- blot_wcs = ref_model . meta . wcs
751- blot_shape = ref_model . data . shape
729+ with datamodels .open (i2d_files [ 0 ]) as i2d_model :
730+ mosaic_data = i2d_model . data . astype ( np . float32 )
731+ mosaic_wcs = i2d_model . meta . wcs
752732
753- ref_pixflux_area = ref_model .meta .photometry .pixelarea_steradians
754- blot_wcs .array_shape = blot_shape
755- ref_pixel_area = compute_image_pixel_area (blot_wcs )
756- pix_ratio = np .sqrt (ref_pixflux_area / ref_pixel_area )
733+ for crf_file in crf_files :
734+ with datamodels .open (crf_file ) as crf_model :
735+ blot_wcs = crf_model .meta .wcs
736+ blot_shape = crf_model .data .shape
737+
738+ pixflux_area = crf_model .meta .photometry .pixelarea_steradians
739+ blot_wcs .array_shape = blot_shape
740+ pixel_area = compute_image_pixel_area (blot_wcs )
741+ pix_ratio = np .sqrt (pixflux_area / pixel_area )
757742
758- for single_file in single_files :
759- with datamodels .open (single_file ) as single_model :
760743 blotted = gwcs_blot (
761- median_data = single_model . data . astype ( np . float32 ) ,
762- median_wcs = single_model . meta . wcs ,
744+ median_data = mosaic_data ,
745+ median_wcs = mosaic_wcs ,
763746 blot_shape = blot_shape ,
764747 blot_wcs = blot_wcs ,
765748 pix_ratio = pix_ratio ,
766749 fillval = self .blot_fillval ,
767750 )
768751
769- out_name = single_file .replace ("_i2d_single.fits" , "_blot_det.fits" )
770- blot_model = datamodels .ImageModel (data = blotted )
771- blot_model .update (ref_model )
772- blot_model .meta .wcs = copy .deepcopy (blot_wcs )
773- save_file (blot_model , out_name = out_name , dr_version = self .dr_version )
774- blot_model .close ()
775-
776- log .info (
777- " %s -> %s" ,
778- os .path .basename (single_file ),
779- os .path .basename (out_name ),
780- )
752+ out_name = crf_file .replace ("_crf.fits" , "_i2d_blot.fits" )
753+ blot_model = datamodels .ImageModel (data = blotted )
754+ blot_model .update (crf_model )
755+ blot_model .meta .wcs = copy .deepcopy (blot_wcs )
756+ save_file (blot_model , out_name = out_name , dr_version = self .dr_version )
757+ blot_model .close ()
758+
759+ log .info (
760+ " mosaic -> %s" ,
761+ os .path .basename (out_name ),
762+ )
781763
782764 gc .collect ()
783765
0 commit comments