;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; DIGS_GETSPICE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; DIGS_GETSPICE_IAUHACK pro digs_getspice_iauhack, fithdr, pfxs, sfx, argnewcomment $ , coeffs=argcoeffs $ , modulo=argmod $ , newsfx=argnewsfx $ , debug=debug dodebug = keyword_set(debug) if n_elements(argcoeffs) lt 2L then coeffs = [0d0,1d0] $ else coeffs = argcoeffs if n_elements(argnewsfx) eq 1L then newsfx = argnewsfx[0] else newsfx=sfx if n_elements(argmod) eq 1L then modulo = argmod else modulo = 0d0 for iPfx=0L,n_elements(pfxs)-1L do begin kwd = strupcase(pfxs[iPfx] + sfx) newkwd = strupcase(pfxs[iPfx] + newsfx) val = sxpar(fithdr,kwd,comment=comment,count=count) if n_elements(argnewcomment) eq 1L then comment=argnewcomment[0] if count ne 1L then continue ;;; ;;; if value is bad i.e. -999 and MODULO is 360, assume this is an ;;; angle that would normally be converted but will remain as ;;; -999 in this case ;;; if val ne -999d0 or modulo ne 360d0 then begin valout = poly(val,coeffs) if modulo ne 0d0 then valout = valout mod modulo endif else begin valout = val endelse if dodebug then print,kwd+'>'+newkwd,[val,coeffs,valout] if kwd eq newkwd then begin sxaddpar,fithdr,newkwd,valout,comment endif else begin sxaddpar,fithdr,newkwd,valout,comment,after=kwd sxdelpar,fithdr,kwd endelse endfor return end ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; DIGS_GETSPICE ;;; - Deep Impact wrapper for BTCGENERAL_GETSPICE ;;; - call with four or five inputs: ;;; ;;; 1) PARTITION: SPICE partition to precede SCLK from IMGH094 to 097+098 ;;; - if string, will be prepended as it ;;; - else with be prepended with a '/' between it and SCLK ;;; ;;; 2) SPICELISTFILES: vector of two SPICELIST files giving location of ;;; SPICE kernels ;;; - first SPICELIST file leads to nominal predicted kernels ;;; - second SPICELIST file leads to reconstructed kernels ;;; - Intent is as stated, may be any two sets of kernels, but ;;; this routine assumes geometry calculated from the second ;;; set is better than that from the first ;;; ;;; 3) FITHDR: FITS header into which to put the DI FITS keywords ;;; - if not an vector of strings, then DI FITS keywords will not be added ;;; ;;; 4) IMGHDR: structure containing values from DI raw 100-byte header ;;; - generated by interpret_scu_headercu.pro ;;; - members are structures containing raw header values in .val ;;; - e.g. imghdr.IMGH020.val is a byte indicating the instrument ;;; - e.g. imghdr.IMGH094.val through imghdr.IMGH098.val are the ;;; 5 bytes of the SCLK (nnnnnnnnnn.yyy) ;;; ;;; 5) SPICEVECTOR: vector of at least two structures of SPICE information ;;; - normally an output returned by btcgeneral_getspice() ;;; - may be an input, see keyword /USESPICEVECTOR below ;;; - on output ;;; - the first structure gets the 'NOM' prefix ;;; - the second structure gets the 'REC' prefix ;;; - on input, it is assumed the better structures are later in the vector ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; Keywords ;;; ;;; 6) /USESPICEVECTOR: don't do SPICE calculations, use SPICEVECTOR as input ;;; - typically used to update FITS header ;;; - N.B. SPICEVECTOR must be an input vector of structures of the kind ;;; output by BTCGENERAL_GETSPICE, and would normally be output ;;; from a previous run of this routine ;;; - the better "quality" structures will be later in the vector ;;; - the purpose of doing this is to call this routine once to ;;; have BTCGENERAL_GETSPICE() just determine the clock values ;;; without updating the FITS header (argument FITHDR), and ;;; then calling this routine later with the previously-returned ;;; SPICEVECTOR to add the SPICE information later in the FITS ;;; header. ;;; ;;; 7) /SKIPADD2FITHDR: don't add SPICEVECTOR or DI SPICE FITS bits to FITHDR ;;; - see discussion in ;;; ;;; 8) MODETBL=MODETBL: use di_scu_getmodeinfo(...,/getinttime) for exposure ;;; ;;; N.B. the following call does nothing ;;; ;;; DIGS_GETSPICE, partition, fithdr, spicelistfile $ ;;; , imghdr, spicevector $ ;;; , /USESPICEVECTOR,/SKIPADD2FITHDR ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; pro digs_getspice, partition, spicelistfiles, fithdr, imghdr, spicevector $ , besttarget $ , usespicevector=usespicevector $ , skipadd2fithdr=skipadd2fithdr $ , modeTbl=modeTbl $ , nocatch=nocatch $ , mylog=mylog $ , debug=debug ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; Perform spice calculations if not keyword_set(USESPICEVECTOR) then begin ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; Instrument/Frame name in SPICE from DI IMGH020 & IMGH021 ;;; e.g. 'DIF_MRI', 'DIF_HRI_VIS', 'DIF_HRI_IR', 'DII_ITS' ;;; case imghdr.IMGH020.val of 1: platform_instr = 'DII_ITS' 2: platform_instr = 'DIF_MRI' 3: begin platform_instr = 'DIF_HRI' $ + ((imghdr.IMGH021.val eq 0) ? '_VIS' : '_IR') end else: platform_instr = 'UNKNOWN_UNKNOWN' endcase ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; SCLK string, PARTITION + SCLK, at end of exposure ;;; e.g. '1/158769404.152' ;;; ;;; - convert partition to a string ;;; if n_elements(partition) ne 1 then begin partn = '1/' endif else if size(partition[0],/type) eq size('',/type) then begin partn = partition[0] endif else begin partn = strtrim(partition[0],2) + '/' endelse ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; Old incorrect method for calculating SPICE SCLK model subticks ;;; assumed 20-bit counter modulus was 1,048,576 (2^20) instead of ;;; 1,000,000. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; BTCarcich 20050204 ;;; - Fixed this to be IMGH098 instead of IMGH097 ;;; - Added optional round up dependent on IMGH099 subticks = ulong(imghdr.IMGH098.val) ;;; 0 <= IMGH099 <= 127: round down i.e. leave subticks as is ;;; 128 <= IMGH099 <= 255: round up i.e. increment subticks with rollover if imghdr.IMGH099.val gt 127 then begin if subticks lt 255 then begin ;;; Handle sub-tick rollover subticks = subticks + 1L endif else begin subticks = 0L ticks = ticks + 1L endelse endif ;;; - get ticks and sub-ticks from raw image header values ;;; - IMGH094 to IMGH097 is 4-byte MSByte-first integer (approx. seconds) ;;; - IMGH098 is 0-255 byte of subticks i.e. fractional seconds ;;; - IMGH098 & IMGH099 are actually bits [19:12] and [11:4], ;;; respectively, of a microsecond clock, but the SPICE SCLK-Kernel ;;; only uses this IMGH098 ticks = ulong(imghdr.IMGH097.val) $ + 256UL * ( ulong(imghdr.IMGH096.val) $ + 256UL * ( ulong(imghdr.IMGH095.val) $ + 256UL * ( ulong(imghdr.IMGH094.val) $ ))) ;;if getenv('E;POXI_CORRECT_SCLK') eq 'YES' then begin if getenv('DO_NOT_CORRECT_DI_SCLK') eq '' then begin badSclk0 = '1/' + string(ticks,FORMAT='(I10.10)') + '.' + string(subticks,FORMAT='(I3.3)') ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; Bits [19:12] and [11:4] in IMGH098 and IMGH099, respectively, ;;; roll over at 62,500 (= 1,000,000 >> 4). Add 0.5 before ;;; rounding. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; subticks = round( ( (256d0 * ulong(imghdr.IMGH098.val)) $ + ulong(imghdr.IMGH099.val) $ + 0.5d0 $ ) $ * (256d0/625d2) $ ) if subticks eq 256L then begin subticks = 0L ticks = ticks + 1L endif endif else begin ptr_free,ptr_new(badSclk0,/no_copy) endelse partn_sclkch = partn + string(ticks,FORMAT='(I10.10)') + '.' + string(subticks,FORMAT='(I3.3)') ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; Exposure, in milliseconds, for ARG_DELET ;;; - For all VIS modes, and HRIIR modes 1,2,3,7 ;;; - SCLK is end of exposure => ARG_DELET is negative ;;; - For d HRIIR modes 4,5 (ALTFF,DIAG) ;;; - SCLK is start of exposure => ARG_DELET is positive ;;; - This could be done better, see DI_SCU_MODETABLE routines ;;; imgmode = imghdr.IMGH030.val ;;; if n_elements(modeTbl) eq 0L then begin exposure_ms = 3.5d0 $ + total( (256d0^[2d0,1,0]) $ * [imghdr.IMGH033.val,imghdr.IMGH034.val,imghdr.IMGH035.val]) $ + imghdr.IMGH031.val ;;; endif else begin ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; DI exposure algorithm: ;;; ;;; Need mission subphase, instrument, ;;; image mode, min exp, cmd exp, delay time ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; msnsubph = 'N/A' ;;; anything but TVn will work here ;;; ;;; Instrument: ITSVIS or MRIVIS or HRIIR or HRIVIS ;;; instrume = strmid( platform_instr, 4, 3) ;;; if instrume eq 'HRI' and imghdr.IMGH021.val eq 1 then begin instrume = instrume + 'IR' endif else begin instrume = instrume + 'VIS' endelse ;;; minexptm = $ di_scu_getmodeinfo(modeTbl, 'XXX', instrume, imgmode, /getminexptime) ;;; cmdexptm = imghdr.IMGH035.val $ + ( 256d0 * ( imghdr.IMGH034.val + (256d0 * imghdr.IMGH033.val))) ;;; delaytm = imghdr.IMGH031.val ;;; exposure_ms = $ di_scu_getmodeinfo( modeTbl, MSNSUBPH, INSTRUME, IMGMODE $ , MINEXPTM, CMDEXPTM, DELAYTM, /getinttime) endelse ;;; Set DELET negative unless HRIIR mode ALTFF or DIAG delet = - exposure_ms $ / ( (imghdr.IMGH021.val ne 1 or imgmode lt 5L or imgmode gt 6) ? 2d3 : -2d3) targets = $ [ ((ticks lt 174570000) ? 'tempel' : 'hartley 2') $ , 'moon' $ , 'mars' $ , 'earth' $ , 'jupiter' $ , 'PRETEND I CAR HD 90589' $ , 'BET HYI HD 2151' $ , 'NGC3114' $ , 'CANOPUS HD 45348' $ , 'ACHERNAR HD 10144' $ , 'NGC7027' $ , '16 CYG A HD 186408' $ , 'HD 60753' $ , 'VEGA HD 172167' $ , '47 TUC NGC104' $ , 'SIRIUS HD 48915' $ , 'I CAR HD 79447' $ , 'NGC3532' $ , 'M11' $ , 'HD 92044' $ , 'OMI VEL CLUSTER IC2391' $ , 'GJ436' $ , 'HAT-P-1' $ , 'HAT-P-2' $ , 'HAT-P-3' $ , 'HAT-P-4' $ , 'HAT-P-7' $ , 'TRES-1' $ , 'TRES-2' $ , 'TRES-3' $ , 'TRES-4' $ , 'WASP-1' $ , 'WASP-2' $ , 'WASP-3' $ , 'XO-1' $ , 'XO-2' $ , 'XO-3' $ , 'HD 80607' $ , 'MOA-2009-BLG-266' $ , 'C/2012 S1 (ISON)' $ , 'C/2009 P1 GARRADD' $ ] ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; Allow for CK Time Offset for ITSVIS ;;; - look for attitude up to 16s earlier than mid-observation time ;;; - Used for nominal predict geometry only ;;; - Use default ckitermax of 15 if platform_instr eq 'DII_ITS' then begin ckto = [-16d0] endif else begin ckto = 0b tmpvar = temporary(ckto) ;;; Ensure CKTO variable is undefined endelse ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; BTC20081203 Reversed order so more forgiving NOMINAL SPICE kernel ;;; set will remain loaded after the calls ;;; BTC20081206 /noMsgNoFrameConnect => Inhibit message,/cont for REC ;;; in btcgeneral_getspice.pro ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; Get reconstructed geometry if available arec = btcgeneral_getspice( $ spicelistfiles[1] $ , 'REC' $ , platform_instr $ , targets $ , arg_partition_sclkch=partn_sclkch $ , arg_delet=delet $ , /noMsgNoFrameConnect $ , nocatch=nocatch $ , badSclk0=badSclk0 $ , debug=debug $ , mylog=mylog $ ) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; Get nominal predict geometry if available if arec.stat.val eq 'OK' then begin anom = arec anom.qual.val = 'NOM' endif else begin anom = btcgeneral_getspice( $ spicelistfiles[0] $ , 'NOM' $ , platform_instr $ , targets $ , arg_partition_sclkch=partn_sclkch $ , arg_delet=delet $ , cktimeoffsets=ckto $ , nocatch=nocatch $ , badSclk0=badSclk0 $ , debug=debug $ , mylog=mylog $ ) endelse ;;; Fix pixel size comment regardless of binning arec.pxlsz.comment = '[radians] Pixel size, binned if IR' anom.pxlsz.comment = arec.pxlsz.comment spicevector = [anom, arec] endif ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; DI-specific FITS keywords, derived from best element SPICEVECTOR ;;; - return without updating FITHDR if SKIPADD2FITHDR is set ;;; or if FITHDR is not a vector of strings ;;; if keyword_set(skipadd2fithdr) then return sz = size(fithdr) if sz[0] ne 1L then return if size(fithdr,/type) ne size('',/type) then return ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; select best element of SPICEVECTOR ;;; - i.e. highest-index element where .qual.val = 'OK' abest = spicevector[ max( [where(spicevector.stat.val eq 'OK'), 0L]) ] sxaddhist, [ string(make_array(70,val=byte('*'))) $ , ' *** Derived geometry values' $ , string(make_array(70,val=byte('*'))) $ ], fithdr, /comment case abest.qual.val of 'NOM': spicetype = 'PREDICTED' 'REC': spicetype = 'RECONSTRUCTED' else: spicetype = abest.qual.val endcase besttarget = abest.trgnm.val sxaddpar, fithdr, 'GEOMQUAL', spicetype $ , ' Type of geometry (SPICE kernels)' sxaddpar, fithdr, 'GEOMPROV', abest.qual.val $ , ' Provenance: (NOMinal or REConstructed)' sxaddpar, fithdr, 'GEOMSTAT', abest.stat.val, ' ' + abest.stat.comment sxaddpar, fithdr, 'range', abest.scrng.val $ , ' [km] Instrument range to target surface', format='(f20.3)' sxaddpar, fithdr, 'CTRDIST', abest.scrng.val $ , ' [km] Instrument range to target center of mass', format='(f20.3)' sxaddpar, fithdr, 'RANGECEN', abest.scrng.val $ , ' [km] Spacecraft range to center of target', format='(f20.3)' ;;; Pixel scale, m/pxl = (range, km) * (microradians km/km) * (1d3 m/km), ;;; and Phase angle if abest.stat.val eq 'OK' then begin pxlscale =abest.scrng.val * abest.pxlsz.val * 1d3 phangle = cspice_vsep( [abest.scx.val, abest.scy.val, abest.scz.val] $ , [abest.sox.val, abest.soy.val, abest.soz.val]) $ * 180d0 / !DPI endif else begin pxlscale = -999.0 phangle = -999.0 endelse sxaddpar, fithdr, 'PXLSCALE', pxlscale $ , ' [m/pixel] Pixel scale, binned if IR', format='(f20.3)' sxaddpar, fithdr, 'PHANGLE', phangle $ , ' [deg] Phase angle (Sun-Target-S/C)' sxaddpar, fithdr, 'INANGLE', -999.0 $ , ' [deg] Incidence angle' sxaddpar, fithdr, 'EMANGLE', -999.0 $ , ' [deg] Emission angle' sxaddpar, fithdr, 'ADCFRAME', 'EMEJ2000' $ , ' inertial reference frame to target' sxaddpar, fithdr, 'ADCTIME', abest.sclk.val $ , ' [SCLK] Spacecraft time stamp' sxaddpar, fithdr, 'ADCQA', abest.scqa.val $ , ' Instrument quaternion (qa, SPICE)' sxaddpar, fithdr, 'ADCQX', abest.scqx.val $ , ' Instrument quaternion (qx)' sxaddpar, fithdr, 'ADCQY', abest.scqy.val $ , ' Instrument quaternion (qy)' sxaddpar, fithdr, 'ADCQZ', abest.scqz.val $ , ' Instrument quaternion (qz)' sxaddpar, fithdr, 'ADCVX', abest.scvqx.val $ , ' [radians/sec] Velocity wrt J2000 frame (x)' sxaddpar, fithdr, 'ADCVY', abest.scvqy.val $ , ' [radians/sec] Velocity wrt J2000 frame (y)' sxaddpar, fithdr, 'ADCVZ', abest.scvqz.val $ , ' [radians/sec] Velocity wrt J2000 frame (z)' sxaddpar, fithdr, 'TARSCRX', abest.scx.val $ , ' [km] Target to S/C range, EME J2000 X', format='(f20.3)' sxaddpar, fithdr, 'TARSCRY', abest.scy.val $ , ' [km] Target to S/C range, EME J2000 Y', format='(f20.3)' sxaddpar, fithdr, 'TARSCRZ', abest.scz.val $ , ' [km] Target to S/C range, EME J2000 Z', format='(f20.3)' sxaddpar, fithdr, 'TARSCVX', abest.scvx.val $ , ' [km/s] Target to S/C vel, EME J2000 X' sxaddpar, fithdr, 'TARSCVY', abest.scvy.val $ , ' [km/s] Target to S/C vel, EME J2000 Y' sxaddpar, fithdr, 'TARSCVZ', abest.scvz.val $ , ' [km/s] Target to S/C vel, EME J2000 Z' sxaddpar, fithdr, 'TARSCR', abest.scrng.val $ , ' [km] Range from Target to S/C' sxaddpar, fithdr, 'TARSUNRX', abest.sox.val $ , ' [km] Target to Sun range, EME J2000 X', format='(f20.3)' sxaddpar, fithdr, 'TARSUNRY', abest.soy.val $ , ' [km] Target to Sun range, EME J2000 Y', format='(f20.3)' sxaddpar, fithdr, 'TARSUNRZ', abest.soz.val $ , ' [km] Target to Sun range, EME J2000 Z', format='(f20.3)' sxaddpar, fithdr, 'TARSUNVX', abest.sovx.val $ , ' [km/s] Target to Sun vel, EME J2000 X' sxaddpar, fithdr, 'TARSUNVY', abest.sovy.val $ , ' [km/s] Target to Sun vel, EME J2000 Y' sxaddpar, fithdr, 'TARSUNVZ', abest.sovz.val $ , ' [km/s] Target to Sun vel, EME J2000 Z' sxaddpar, fithdr, 'TARSUNR', abest.sorng.val $ , ' [km] Range from Target to Sun' sxaddpar, fithdr, 'EARTARRX', abest.eox.val $ , ' [km] Earth to Target range, EME J2000 X' sxaddpar, fithdr, 'EARTARRY', abest.eoy.val $ , ' [km] Earth to Target range, EME J2000 Y' sxaddpar, fithdr, 'EARTARRZ', abest.eoz.val $ , ' [km] Earth to Target range, EME J2000 Z' sxaddpar, fithdr, 'EARTARVX', abest.eovx.val $ , ' [km/s] Earth to Target vel, EME J2000 X' sxaddpar, fithdr, 'EARTARVY', abest.eovy.val $ , ' [km/s] Earth to Target vel, EME J2000 Y' sxaddpar, fithdr, 'EARTARVZ', abest.eovz.val $ , ' [km/s] Earth to Target vel, EME J2000 Z' sxaddpar, fithdr, 'EARTARR', abest.eorng.val $ , ' [km] Range from Earth to Target' sc2so = [ abest.sox.val - abest.scx.val $ , abest.soy.val - abest.scy.val $ , abest.soz.val - abest.scz.val ] sxaddpar, fithdr, 'SCSUNRX', sc2so[0] $ , ' [km] S/C to Sun range, EME J2000 X', format='(f20.3)' sxaddpar, fithdr, 'SCSUNRY', sc2so[1] $ , ' [km] S/C to Sun range, EME J2000 Y', format='(f20.3)' sxaddpar, fithdr, 'SCSUNRZ', sc2so[2] $ , ' [km] S/C to Sun range, EME J2000 Z', format='(f20.3)' sxaddpar, fithdr, 'SCSUNR', cspice_vnorm(sc2so) $ , ' [km] Range from S/C to Sun', format='(f20.3)' sxaddpar, fithdr, 'SCEARRX', abest.ex.val $ , ' [km] S/C to Earth range, EME J2000 X', format='(f20.3)' sxaddpar, fithdr, 'SCEARRY', abest.ey.val $ , ' [km] S/C to Earth range, EME J2000 Y', format='(f20.3)' sxaddpar, fithdr, 'SCEARRZ', abest.ez.val $ , ' [km] S/C to Earth range, EME J2000 Z', format='(f20.3)' sxaddpar, fithdr, 'SCEARR', abest.erng.val $ , ' [km] Range from S/C to Earth', format='(f20.3)' sxaddpar, fithdr, 'CELESTN', abest.emen.val $ , ' [deg] Celestial North Clock Angle in image' sxaddpar, fithdr, 'ECLN', abest.ecln.val $ , ' [deg] Ecliptic North Clock Angle in image' sxaddpar, fithdr, 'BORERA', abest.scra.val $ , '[deg] RA of instrument boresight, EMEJ2000' sxaddpar, fithdr, 'BOREDEC', abest.scdec.val $ , '[deg] DEC of instrument boresight, EMEJ2000' sxaddpar, fithdr, 'SOLARCLK', abest.solcl.val $ , '[deg] Clock Angle to Sun from boresight' sxaddpar, fithdr, 'SOLARELO', abest.solel.val $ , '[deg] Sun-S/C-Boresight solar elongation' btcgeneral_getspice_struct2fithdr, fithdr, spicevector ;;; IAU hack pfxs = [ 'NOM', 'REC' ] ;;; Latitudes digs_getspice_iauhack, fithdr, pfxs $ , 'sclat', '[deg] Sub-spacecraft IAU latitude' $ , debug=debug digs_getspice_iauhack, fithdr, pfxs $ , 'solat', '[deg] Sub-solar IAU latitude' $ , debug=debug digs_getspice_iauhack, fithdr, pfxs $ , 'eolat', '[deg] Sub-earth-observer IAU latitude' $ , debug=debug ;;; Longitudes digs_getspice_iauhack, fithdr, pfxs $ , 'sclon', '[deg] Sub-spacecraft IAU longitude' $ , coeffs = [360d0,-1d0], modulo=360d0 $ , debug=debug digs_getspice_iauhack, fithdr, pfxs $ , 'solon', '[deg] Sub-solar IAU longitude' $ , coeffs = [360d0,-1d0], modulo=360d0 $ , debug=debug digs_getspice_iauhack, fithdr, pfxs $ , 'eolon', '[deg] Sub-earth-observer IAU longitude' $ , coeffs = [360d0,-1d0], modulo=360d0 $ , debug=debug ;;; Pole digs_getspice_iauhack, fithdr, pfxs $ , 'noraz', '[deg] Body IAU +Pole azimuth, CW from up' $ , newsfx='ppaz' $ , debug=debug digs_getspice_iauhack, fithdr, pfxs $ , 'nrthx', '[N/A] Body IAU +Pole in FOV, Xinstr' $ , newsfx='ppolx' $ , debug=debug digs_getspice_iauhack, fithdr, pfxs $ , 'nrthy', '[N/A] Body IAU +Pole in FOV, Yinstr' $ , newsfx='ppoly' $ , debug=debug digs_getspice_iauhack, fithdr, pfxs $ , 'nrthz', '[N/A] Body IAU +Pole in FOV, Zinstr' $ , newsfx='ppolz' $ , debug=debug end ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;