22
22
from desispec .io import shorten_filename
23
23
from desiutil .log import get_logger
24
24
from desispec .util import parse_int_args
25
- from desispec .trace_shifts import write_traces_in_psf ,compute_dx_from_cross_dispersion_profiles ,compute_dy_from_spectral_cross_correlation ,monomials ,polynomial_fit ,compute_dy_using_boxcar_extraction ,compute_dx_dy_using_psf ,shift_ycoef_using_external_spectrum ,recompute_legendre_coefficients ,recompute_legendre_coefficients_for_x ,recompute_legendre_coefficients_for_y ,list_of_expected_spot_positions
25
+ from desispec .trace_shifts import write_traces_in_psf ,compute_dx_from_cross_dispersion_profiles ,compute_dy_from_spectral_cross_correlation ,monomials ,polynomial_fit ,compute_dy_using_boxcar_extraction ,compute_dx_dy_using_psf ,shift_ycoef_using_external_spectrum ,recompute_legendre_coefficients ,recompute_legendre_coefficients_for_x ,recompute_legendre_coefficients_for_y ,list_of_expected_spot_positions , compute_x_offset_from_central_band_cross_dispersion_profile
26
26
from desispec .large_trace_shifts import detect_spots_in_image ,match_same_system
27
27
28
28
def parse (options = None ):
@@ -60,7 +60,7 @@ def parse(options=None):
60
60
parser .add_argument ('--degyy' , type = int , default = 0 , required = False ,
61
61
help = 'polynomial degree for y shifts along y' )
62
62
parser .add_argument ('--continuum' , action = 'store_true' ,
63
- help = 'only fit shifts along x for continuum input image' )
63
+ help = 'only fit shifts along x for continuum or LED input image' )
64
64
parser .add_argument ('--auto' , action = 'store_true' ,
65
65
help = 'choose best method (sky,continuum or just internal calib) from the FLAVOR keyword in the input image header' )
66
66
@@ -72,7 +72,8 @@ def parse(options=None):
72
72
help = "width of cross-dispersion profile" )
73
73
parser .add_argument ('--ccd-rows-rebin' , type = int , default = 4 , required = False ,
74
74
help = "rebinning of CCD rows to run faster" )
75
-
75
+ parser .add_argument ('--no-large-shift-scan' , action = "store_true" ,
76
+ help = "do not perform a large shift scan for arc lamp or continuum exposures" )
76
77
args = parser .parse_args (options )
77
78
78
79
return args
@@ -459,15 +460,21 @@ def fit_trace_shifts(image, args):
459
460
args .sky = True
460
461
log .info ("wavelength calib, internal={}, sky={} , arc_lamps={}" .format (internal_wavelength_calib ,args .sky ,args .arc_lamps ))
461
462
462
- if args .arc_lamps :
463
+ cfinder = CalibFinder ([image .meta ])
464
+ fibers = np .arange (tset .nspec )
465
+ if cfinder .haskey ("BROKENFIBERS" ) :
466
+ brokenfibers = parse_int_args (cfinder .value ("BROKENFIBERS" ))% 500
467
+ log .debug (f"brokenfibers={ brokenfibers } " )
468
+ fibers = fibers [np .isin (fibers , brokenfibers , invert = True )]
469
+
470
+ # for arc lamp images, we can predict where we expect to see spots on the CCD image
471
+ # given an input traceset (variable tset), and use the comparison between the prediction
472
+ # and actual spots locations to derive a first correction to the coordinates saved in the traceset
473
+ # this is disabled by the option --no-large-shift-scan
474
+ if args .arc_lamps and (not args .no_large_shift_scan ) :
463
475
464
476
log .info ("for arc lamps, find a first solution by comparing expected spots positions with detections over the whole CCD" )
465
- cfinder = CalibFinder ([image .meta ])
466
- fibers = np .arange (tset .nspec )
467
- if cfinder .haskey ("BROKENFIBERS" ) :
468
- brokenfibers = parse_int_args (cfinder .value ("BROKENFIBERS" ))% 500
469
- log .debug (f"brokenfibers={ brokenfibers } " )
470
- fibers = fibers [np .isin (fibers , brokenfibers , invert = True )]
477
+
471
478
xref ,yref = list_of_expected_spot_positions (tset ,fibers )
472
479
xin ,yin = detect_spots_in_image (image )
473
480
@@ -510,6 +517,16 @@ def fit_trace_shifts(image, args):
510
517
xcoef [:,0 ] += delta_xref
511
518
ycoef [:,0 ] += delta_yref
512
519
520
+ # for continuum images, we can predict where we expect to see spectral traces on the CCD image
521
+ # given an input traceset (variable tset), and use the comparison between the prediction
522
+ # and actual spectral traces to derive a first correction to the X coordinates saved in the traceset
523
+ # this is disabled by the option --no-large-shift-scan
524
+ if args .continuum and (not args .no_large_shift_scan ) :
525
+ log .info ("for continuum or LED exposures, find a first solution on delta_X by comparing a wide cross-dispersion profile with expectations" )
526
+ delta_xref = compute_x_offset_from_central_band_cross_dispersion_profile (tset , image , fibers = fibers )
527
+ log .info (f"apply best shift delta x = { delta_xref } to traceset" )
528
+ xcoef [:,0 ] += delta_xref
529
+
513
530
spectrum_filename = args .spectrum
514
531
continuum_subtract = False
515
532
if args .sky :
@@ -557,6 +574,7 @@ def fit_trace_shifts(image, args):
557
574
558
575
else :
559
576
577
+
560
578
# internal calibration method that does not use the psf
561
579
# nor a prior set of lines. this method is much faster
562
580
0 commit comments