;+ ; NAME: ; jpl_init ; PURPOSE: ; Initialize a new ephemeris file ; CATEGORY: ; smei/gen/idl/ephem ; CALLING SEQUENCE: FUNCTION jpl_init, ET, JPL_PNTR, loud=loud, test=test ; INPUTS: ; ET(2) double ephemeris time ; JPL_PNTR pointer to structure with info for current ; ephemeris file ; OPTIONAL INPUT PARAMETERS: ; /loud if set some parameters read from the ephemeris file ; are printed (used by href=jpl_test=). ; OUTPUTS: ; OK =1: ephemeris file ready for next jpl_state call ; =0: usually means ET is outside the range of the ephemeris ; (currently 1950-2050) ; JPL_PNTR update pointer ; INCLUDE: @compile_opt.pro ; On error, return to caller ; COMMON BLOCKS: common JPL_BUF, BUF_MAP ; File handle for assoc read ; CALLS: ; InitVar, who_am_i ; PROCEDURE: ; > IDL implementation of the JPL Lunar and Planetary Ephemeris package ; > Ephemeris data files are searched for in the subdirectory 'jpl' of the directory ; where this file is located. ; > jpl_init opens the appropriate ephemeris file for time ET and reads ; the correct record in the pointer JPL_PNTR ; > The ephemeris file is accessed using BUF_MAP, an 1018-element ; double precesion array associated with a record in the ephemeris file. ; MODIFICATION HISTORY: ; AUG-1999, Paul Hick (UCSD/CASS) ; FEB-2005, Paul Hick (UCSD/CASS; pphick@ucsd.edu) ;- InitVar, loud, /key InitVar, test, /key next_file = 0 ; JPL_PNTR is created the first time the JPL ephemeris is accessed. ; It exists until it is explicitly destroyed by a call to jpl_close(/kill). ; (note that a call to jpl_close without the /kill keyword will only ; close the open ephemeris file; the current ephemeris data remain in ; memory). CASE ptr_valid(JPL_PNTR) OF 0: BEGIN ; Create the JPL_PNTR structure ; Pick up list of ephemeris files and create the JPL_PNTR structure. tmp = filepath(root=who_am_i(/dir),subdir='jpl','unxp*.405') cFile = file_search(tmp,count=nFile) IF nFile EQ 0 THEN BEGIN message, /info, 'no ephemeris files found: '+tmp RETURN, 0 ENDIF ; Make chronologically ordered list of ephemeris files cFile = cFile[sort(cFile)] ; Probably redundant ; Set up the structure. Only entries nFile and cFile are filled with ; useful data. NCOEFFS = 1018 ; # double precision numbers on one record JPL_PNTR = ptr_new( {JPL_STRUCT, $ nFile : nFile , $ ; # ephemeris files cFile : cFile , $ ; Names of ephemeris files ; Filled every time a new ephemeris file is opened. iFile : -1L , $ ; Index of current ephemeris file iU : -1L , $ ; Needed for jpl_close NRMAX : -1L , $ ; # ephemeris records in file ;NCON : 0L , $ ; not used ;NUMDE : 0L , $ ; not used AU : 0d0 , $ EMRAT : 0d0 , $ IPT : lonarr(3,14,/nozero) , $ ; pointer info for accessing ephemeris file SS : dblarr(3, /nozero) , $ ; Filled by jpl_state when new record is read: NRL : -1L , $ ; current record in memory; -1 forces new read NCOEFFS : NCOEFFS , $ ; # double precision numbers on one record BUF : dblarr(NCOEFFS) }) ; Block of ephemeris data ;CVAL : dblarr(400, /nozero), $ ; printed locally ;CNAM : replicate('123456',400),$ ; printed locally ;TTL :replicate('123456',14,3) }) ; not used END 1: BEGIN NRL = (*JPL_PNTR).NRL SS = (*JPL_PNTR).SS IF NRL NE -1 THEN BEGIN ; There still is a block of ephemeris data in memory (even if the ; ephemeris file has been close already by a call to jpl_close. Since ; jpl_state will not have to read a new record this is OK. NR = jpl_inside(ET, SS) IF NR EQ NRL THEN RETURN, 1 ; Data in memory are OK ENDIF IF (*JPL_PNTR).iU NE -1 THEN BEGIN ; The ephemeris file is still open. If the record required for et2 is in ; this file than jpl_state will read it if necessary. NR = jpl_inside(ET, SS) IF NR NE -1 THEN $ ; Open ephemeris file is correct file RETURN, jpl_read(NR, JPL_PNTR, BUF_MAP) ; Read record NR and return ; Open ephemeris file is the wrong file. Check whether the requested ; time is later or earlier than the range covered in the file. CASE 1 OF ET[0]+ET[1] LT SS[0]: next_file = 1 ; Epoch too early ET[0]+ET[1] GT SS[1]: next_file = 2 ; Epoch too late ENDCASE ENDIF END ENDCASE ; next_file = 0: run through all ephemeris files 0,..,nFile-1 ; next_file = 1: requested time is later: process iFile+1,..,nFile-1 ; next_file = 2; requested time is earlier; process iFile-1,..,0 iFile = (*JPL_PNTR).iFile nFile = (*JPL_PNTR).nFile frst = ([0,iFile-1,iFile+1])[next_file] last = ([nFile-1,0,nFile-1])[next_file] IF frst GE nFile OR frst LT 0 THEN RETURN, 0 step = 2*(last GT frst)-1 ; 1st record: 14*3*6+400*6+3*8+4+8+8+3*12*4+4+3*4 = 2856 ; 8*1018-2856= 5288 TTL = replicate('123456',14,3) ; Define variables to read 1st record CNAM = replicate('123456',400) SS = dblarr(3,/nozero) NCON = 0L AU = 0.0d0 EMRAT = 0.0d0 IPT1 = lonarr(3,12) NUMDE = 0L IPT2 = lonarr(3) PAD = bytarr(5288) CVAL = dblarr(400,/nozero) ; Define variable to read 2nd record FOR iFile=frst,last,step DO BEGIN openr, iU, /get_lun, ((*JPL_PNTR).cFile)[iFile] readu, iU, TTL,CNAM,SS,NCON,AU,EMRAT,IPT1,NUMDE,IPT2,PAD readu, iU, CVAL ; The pointers for the Sun are moved to position 0 ; 1,..,10 become the planets and the Moon ; 11 and 12 become nutations and librations respectively. IPT = [[IPT1[*,10]],[IPT1[*,0:9]],[IPT1[*,11]],[IPT2]] byteorder, SS , /xdrtod, /swap_if_little_endian byteorder, NCON , /lswap , /swap_if_little_endian byteorder, AU , /xdrtod, /swap_if_little_endian byteorder, EMRAT, /xdrtod, /swap_if_little_endian byteorder, NUMDE, /lswap , /swap_if_little_endian byteorder, IPT , /lswap , /swap_if_little_endian byteorder, CVAL , /xdrtod, /swap_if_little_endian NR = jpl_inside(ET, SS) IF NR NE -1 THEN BEGIN ; Found correct ephemeris file IF loud THEN BEGIN message, /info, 'ephemeris file '+((*JPL_PNTR).cFile)[iFile] IF test THEN BEGIN print, format='(/,3F14.2,/)', SS FOR I=0,NCON-1,2 DO print, format='(2(A8,E24.16))', CNAM[I],CVAL[I], CNAM[I+1],CVAL[I+1] print print, ' line -- jed -- t# c# x# --- jpl value --- --- user value -- -- difference --' ENDIF ENDIF ; Close open ephemeris file if (*JPL_PNTR).iU NE -1 THEN free_lun, (*JPL_PNTR).iU NCOEFFS = (*JPL_PNTR).NCOEFFS I = ([8*NCOEFFS,1])[!version.os_family EQ 'vms'] BUF_MAP = assoc(iU, dblarr(NCOEFFS),2*I) (*JPL_PNTR).iFile = iFile (*JPL_PNTR).iU = iU ;(*JPL_PNTR).NCON = NCON ;(*JPL_PNTR).NUMDE = NUMDE (*JPL_PNTR).NRMAX = (fstat(iU)).size/(8*NCOEFFS)-2 (*JPL_PNTR).AU = AU (*JPL_PNTR).EMRAT = EMRAT (*JPL_PNTR).IPT = IPT (*JPL_PNTR).SS = SS (*JPL_PNTR).NRL = -1 ;(*JPL_PNTR).CVAL = CVAL ;(*JPL_PNTR).CNAM = CNAM ;(*JPL_PNTR).TTL = TTL RETURN, jpl_read(NR, JPL_PNTR, BUF_MAP) ENDIF free_lun, iU ENDFOR RETURN, 0 & END