; docformat = 'rst' ; ; NAME: ; astClass ; PURPOSE: ; Determine an asteroid dynamical class from its osculating orbital ; elements or its name or number. ; ;+ ; :Description: ; Determine an asteroid dynamical class from its osculating orbital ; elements or its name or number. ; ; ; :Categories: ; Database, Asteroid, Orbits ; ; :Params: ; DESIGN: in, required, type=[string] ; Array of target identifyers (designations, number) ; a: in, optional, type=[double] ; Array of target semi-major axes ; e: in, optional, type=[float] ; Array of target eccentricity ; ; :Returns: A structure with the dynamical classes, or a code for ; success (-1: designation not found). Structure fields are:: ; .NUM: Asteroid IAU Number ; .NAME: Asteroid Name or Provisional Designation ; .TYPE: Dynamical class ; .A: Semi-major axis (au) ; .E: Eccentricity ; ; :Keywords: ; ASTORB: in, optional, type=integer/string ; The path to a local version of AstOrb (Lowell Obs) ; ; :Examples: ; Find dynamical classes of Ceres, Makemake, Haumea, and Eros:: ; IDL> print, astClass(['Ceres','Makemake','Eros']) ; ; :Uses: ; initIDL, astElements ; ; :Author: ; B.Carry (OCA) ; ; :History: ; Change History:: ; Written in September 2014, B. Carry (IMCCE) ; 2016 June - B. Carry (OCA) - Compile option idl2 added ; 2016 June - B. Carry (OCA) - Outer Solar System follow Gladman 2008 ;- function astClass, design, a, e, astOrb=astOrb ;-----------------------------------------------------------------------------------------------; ;-----------------------------------------------------------------------------------------------; ;--- TAG --- I -- Initialization And Input Verification -----------------------; ;-----------------------------------------------------------------------------------------------; ;-----------------------------------------------------------------------------------------------; COMPILE_OPT hidden, idl2 ;--I.1-- Search Orbital Elements ------------------------------------------------------ if N_PARAMS() lt 3 then begin ;--I.1.1-- Set AstOrb File if keyword_set(astorb) then begin astorb = strtrim(astorb,2) endif else begin confAstroIM= initIDL() confCatalog= initIDL(confAstroIM.soft.catalog, /CATALOG) astorb = confCatalog.astorb endelse ;--I.1.2-- File Check Out if not file_test(astorb,/READ) then begin message, /IOERROR, 'AstOrb file not found: '+astOrb return, -1 endif ;--I.2-- Elements Variable Size ------------------------------------------------------- endif else begin nbA = n_elements(a) nbE = n_elements(e) if nbA ne nbE then begin message, /IOERROR, 'Orbital elements array have different lengths' return, -2 endif endelse ;--I.3-- List of Targets & Output Structure ------------------------------------------- nbSSO = n_elements(design) empty = {num:0L, name:'', type:'', subtype:'', a:0.D, e:0., i:0.} if nbSSO eq 1 then result = empty $ else result= replicate(empty,nbSSO) ;--I.4-- Constants -------------------------------------------------------------------- qMars = 1.666 aNeptune = 30.1 distRes = 0.35 ;-----------------------------------------------------------------------------------------------; ;-----------------------------------------------------------------------------------------------; ;--- TAG --- II -- Extract Orbital Elements from AstOrb (optional) -----------------------; ;-----------------------------------------------------------------------------------------------; ;-----------------------------------------------------------------------------------------------; if N_PARAMS() lt 3 then begin ;--II.1-- Orbital Elements Array ------------------------------------------------------------- a=dblarr(nbSSO) e=fltarr(nbSSO) ;--II.2-- Parse AstOrb for Requested Targets -------------------------------------------------- for kSSO=0, nbSSO-1 do begin osc = astElements( design[kSSO] ) a[kSSO] = osc.a e[kSSO] = osc.e endfor endif ;--II.3-- Keep Orbital Elements --------------------------------------------------------------- result.a = a result.e = e ;-----------------------------------------------------------------------------------------------; ;-----------------------------------------------------------------------------------------------; ;--- TAG --- III -- Define Dynamical Class from Orbital Elements -----------------------; ;-----------------------------------------------------------------------------------------------; ;-----------------------------------------------------------------------------------------------; for kSSO=0, nbSSO-1 do begin ;--III.1-- Target ID -------------------------------------------------------------------- result[kSSO].name = design[kSSO] p = a[kSSO]*(1.-e[kSSO]) q = a[kSSO]*(1.+e[kSSO]) ;-----------------------------------------------------------------------------------------------; ;-----------------------------------------------------------------------------------------------; ;--- TAG --- IV -- Inner Solar System -----------------------; ;-----------------------------------------------------------------------------------------------; ;-----------------------------------------------------------------------------------------------; if a[kSSO] lt 5.5 then begin ;---------------------------------------------------------------------------------------- ;--IV.1-- Non Planet-Crossers: MB, Hungaria, Trojans, ... ------------------------------ if p gt qMars then begin ;--IV.1.1-- Jupiter Trojans -------------------------------------------------------------- if a[kSSO] ge 4.6 then begin result[kSSO].type = 'Trojan' ;--IV.1.2-- Main-Belt Asteroid ----------------------------------------------------------- endif else begin result[kSSO].type = 'MB' ;--IV.1.2/A-- Hungarias if a[kSSO] lt 2.0 then begin result[kSSO].type = 'Hungaria' endif else begin ;--IV.1.2/B-- Inner Belt if a[kSSO] lt 2.5 then begin result[kSSO].subtype = 'IMB' endif else begin ;--IV.1.2/C-- Middle Belt if a[kSSO] lt 2.82 then begin result[kSSO].subtype = 'MMB' endif else begin ;--IV.1.2/D-- Outer Belt if a[kSSO] lt 3.27 then begin result[kSSO].subtype = 'OMB' endif else begin ;--IV.1.2/E-- Cybeles if a[kSSO] lt 3.7 then begin result[kSSO].subtype = 'Cybele' ;--IV.1.2/F-- Hildas endif else begin result[kSSO].subtype = 'Hilda' endelse ;--IV.1.2/E endelse ;--IV.1.2/D endelse ;--IV.1.2/C endelse ;--IV.1.2/B endelse ;--IV.1.2/A endelse ;--IV.1.2 ;---------------------------------------------------------------------------------------- ;--IV.2-- Planet-Crossers: MCs and NEAs ------------------------------------------------ endif else begin ;--IV.2.1-- Mars-Crossers ---------------------------------------------------------------- if p ge 1.3 then begin result[kSSO].type = 'MC' ;--IV.2.2-- Near-Earth Asteroids --------------------------------------------------------- endif else begin result[kSSO].type = 'NEA' ;--IV.2.2/A-- Apollos (~62%) if a[kSSO] ge 1.0 and p lt 1.017 then begin result[kSSO].subtype = 'Apollo' endif else begin ;--IV.2.2/B-- Amors (~32%) if a[kSSO] ge 1.0 and p ge 1.017 and p lt 1.3 then begin result[kSSO].subtype = 'Amor' endif else begin ;--IV.2.2/C-- Atens (~6%) if a[kSSO] lt 1.0 and q ge 0.983 then begin result[kSSO].subtype = 'Aten' endif else begin ;--IV.2.2/D-- Atiras (Handful known) if a[kSSO] lt 1.0 and q lt 0.983 then begin result[kSSO].subtype = 'Atira' endif else begin ;--IV.2.2/E-- Vulcanoids (yet to be discovered) if a[kSSO] ge 0.08 and a[kSSO] lt 0.21 then begin result[kSSO].subtype = 'Vulcanoid' endif endelse ;--IV.2.2/D endelse ;--IV.2.2/C endelse ;--IV.2.2/B endelse ;--IV.2.2/A endelse ;--IV.2.2 endelse ;--IV.2 ;-----------------------------------------------------------------------------------------------; ;-----------------------------------------------------------------------------------------------; ;--- TAG --- V -- Outer Solar System -----------------------; ;-----------------------------------------------------------------------------------------------; ;-----------------------------------------------------------------------------------------------; endif else begin ;---------------------------------------------------------------------------------------- ;--V.1-- Planet-Crossers: Centaurs ----------------------------------------------------- if a[kSSO] lt aNeptune then begin result[kSSO].type = 'Centaur' ;---------------------------------------------------------------------------------------- ;--V.2-- Non Planet-Crossers: Oort Cloud ----------------------------------------------- endif else if a[kSSO] gt 2000. then begin result[kSSO].type = 'IOC' endif else begin ;---------------------------------------------------------------------------------------- ;--V.3-- Non Planet-Crossers: Kuiper Belt ---------------------------------------------- result[kSSO].type = 'KBO' ;--V.3.1-- Scattered-Disk Objects ------------------------------------------------------ if p le (aNeptune * 2.^(2./3) * (1.0-0.24)) then begin result[kSSO].subtype = 'SDO' ;--V.3.2-- Classical & Detached -------------------------------------------------------- endif else begin result[kSSO].subtype = 'Classical' ;--V.3.2/A-- Detached Object if e[kSSO] ge 0.24 then begin result[kSSO].subtype = 'Detached' ;--V.3.2/B-- Classical Belt endif else begin if a[kSSO] lt 39.4028 then begin ;-MMR result[kSSO].subtype = 'Inner Classical Belt' endif else begin if a[kSSO] gt 47.8 then begin result[kSSO].subtype = 'Outer Classical Belt' endif else result[kSSO].subtype='Main Classical Belt' endelse endelse endelse ;--V.3.3-- Resonant Objects ------------------------------------------------------------ listMMR = ['5:4','4:3','11:8','3:2','5:3','7:4','9:5','11:6','2:1','19:9','9:4','7:3','12:5','5:2','8:3','3:1','7:2','11:3','11:2','27:4'] nbMMR = n_elements(listMMR) for kMMR=0, nbMMR-1 do begin pqMMR = float(strSplit(listMMR[kMMR],':',/Extract)) aRes = aNeptune * (pqMMR[0]/pqMMR[1])^(2./3.) if abs( a[kSSO] - aRes ) le distRes then begin result[kSSO].subtype = 'Resonant '+listMMR[kMMR] kMMR = nbMMR endif endfor endelse ;--V.2 endelse ;--V endfor ;--V.3-- Export Results --------------------------------------------------------------- return, result end