; docformat = 'rst' ; ; NAME: ; ssoddGetDens ; PURPOSE: ; Return the density estimates or their average value from the Solar ; System Objects Density Database for a specific target or ; simply dump the database ; ;+ ; :Description: ; Return the density estimates or their average value from the Solar ; System Objects Density Database for a specific target or ; simply dump the database ; ; :Categories: ; Database, SSODD, Asteroid, Density ; ; :Params: ; ID: in, required, type=integer/string ; Target identifyer ('*', Name, Provisional designation, Number) ; ; :Returns: A structure with the density estimates and their average ; values, or code for success (-1: target not found, -2: SSODD file ; not found, -3: No target specified). Structure fields are:: ; .ALL: Weighted average of all estimates:: ; .val: Value in g/cc ; .unc: Standard deviation in g/cc ; .VAL: Weighted average of valid estimates (flag!=2):: ; .val: Value in g/cc ; .unc: Standard deviation in g/cc ; .ALL: Weighted average of selected estimates (flag=1):: ; .val: Value in g/cc ; .unc: Standard deviation in g/cc ; .IND: An array of structure for each density estimate:: ; .val: Density estimates, in g/cc ; .unc: Density uncertainty, in g/cc ; .dev: Deviation to average, in sigma, for:: ; .ALL: All estimates ; .VAL: Valid estimates ; .ALL: Selected estimates ; .method: Description of the method used to determine the dens ; .select: A flag for selection (sel=0, val=0|1, all=0|1|2) ; .src: The source of density estimate (e.g., article bibcode) ; ; :Keywords: ; SSODD: in, optional, type=string ; Path to the SSODD density file ; CONFIG: in, optional, type=string ; Path to the configuration file for catalogs, at the ; minimum this file should contain the 2 following lines to be used ; by current routine:: ; [Solar System Objects Density Database] ; dens = PATH_TO_YOUR_SSODD_DENS_FILE ; DUMP: in, optional, type=boolean, default=0 ; Set this keyword to return the whole SSODD file ; VERBOSE: in, optional, type=boolean, default=0 ; Trigger dialog with user ; ; :Examples: ; Search SSODD for Ceres and Pallas:: ; IDL> print, ssoddGetDens(1) ; IDL> print, ssoddGetDens('Pallas') ; ; :Uses: ; initIDL, readfmt, astNameFormat, designation, meanWithUnc ; ; :Author: ; B.Carry (IMCCE) ; ; :History: ; Change History:: ; Written in June 2014, B. Carry (IMCCE) ; 2014 Sep - B. Carry (IMCCE) - Bug on selection (num=0) corrected ; 2017 Dec - B. Carry (OCA) - Changed input format to CSV ; 2018 Apr - B. Carry (OCA) - Changed tags dev -> unc ;- function ssoddGetDens, id, SSODD=SSODD, config=config, dump=dump, verbose=verbose COMPILE_OPT hidden, idl2 ;-----------------------------------------------------------------------------------------------; ;-----------------------------------------------------------------------------------------------; ;--- TAG --- I -- Initialization And Input Verification -----------------------; ;-----------------------------------------------------------------------------------------------; ;-----------------------------------------------------------------------------------------------; ;--I.1-- Set IDL to Local Working Environment ------------------------------------------------ if not keyword_set(SSODD) then begin if not keyword_set(CONFIG) then begin config = initidl(/CATALOG) endif SSODD = config.ssodd.dens endif ;--I.2-- Output Structure Definition -------------------------------------------- empty={num:0L, name:'', val:0., unc:0., dev:{all:0.,val:0.,sel:0.}, method:'', select:0, src:''} ;--I.3-- Dump mode Exception ---------------------------------------------------- if keyword_set(DUMP) then ID='*' ;--I.4-- Exceptions ------------------------------------------------------------ ;--I.4.1-- Neither ID nor DUMP Specified if not keyword_set(ID) then begin if keyword_set(VERBOSE) then message, /IOERROR, 'No target identifier specified: dens=ssoddGetDens([ID,/DUMP,...])' return, -3 endif ;--I.4.2-- SSODD Density File Not Found if not file_test (ssodd,/read) then begin if keyword_set(VERBOSE) then message, /INFO, 'SSODD File Not Found: '+strtrim(ssodd,2) return, -2 endif ;-----------------------------------------------------------------------------------------------; ;-----------------------------------------------------------------------------------------------; ;--- TAG --- II -- Read the Whole SSODD file -----------------------; ;-----------------------------------------------------------------------------------------------; ;-----------------------------------------------------------------------------------------------; readcol, ssodd, delimiter=',', /Silent, format='(L,A,F,F,A,I,A)', $ ssoddNum, ssoddName, ssoddVal, ssoddUnc, ssoddMeth, ssoddSel, ssoddSrc nbSSODD = n_elements(ssoddNum) ssoddName= strtrim(ssoddName,2) ssoddMeth= strtrim(ssoddMeth,2) ssoddSrc = strtrim(ssoddSrc ,2) ;-----------------------------------------------------------------------------------------------; ;-----------------------------------------------------------------------------------------------; ;--- TAG --- III -- Asteroid Designation Interpretation -----------------------; ;-----------------------------------------------------------------------------------------------; ;-----------------------------------------------------------------------------------------------; ;--III.1-- Identify Input Type --------------------------------------------------- trash = astNameFormat(ID, TYPE=idType ) ;--III.2-- Set Asteroid IAU Number ----------------------------------------------- if idType eq 1 then begin num = round(float(ID)) des = designation(ID) endif else begin num = designation(ID) des = strtrim(ID,2) endelse ;--III.3-- Line Selection -------------------------------------------------------- ;--III.3.1-- Complete Dump of the SSODD catalog if keyword_set(dump) or strcmp(ID,'*',1) then begin sel=indgen(nbSSODD) nbSel=nbSSODD ;--III.3.2-- Only a Specified Target endif else begin if num ne 0 then sel=where( num eq ssoddNum or strcmp(des, ssoddName,/FOLD), nbSel ) $ else sel=where( strcmp(des, ssoddName,/FOLD), nbSel ) endelse ;--III.4-- Target not Found Exception ------------------------------------------- if nbSel eq 0 then begin if keyword_set(VERBOSE) then message, /INFO, 'Target not found: '+strtrim(string(ID,format='(A)'),2) return, -1 endif ;-----------------------------------------------------------------------------------------------; ;-----------------------------------------------------------------------------------------------; ;--- TAG --- IV -- Result Concatenation and Averaging -----------------------; ;-----------------------------------------------------------------------------------------------; ;-----------------------------------------------------------------------------------------------; ;--IV.1-- Create the Output Structure -------------------------------------------- if nbSel gt 1 then result = replicate(empty,nbSel) $ else result = empty ;--IV.2-- Fill the Structure ----------------------------------------------------- for kSel=0, nbSel-1 do begin result[kSel].num = ssoddNum[sel[kSel]] result[kSel].name = ssoddName[sel[kSel]] result[kSel].val = ssoddVal[sel[kSel]] result[kSel].unc = ssoddUnc[sel[kSel]] result[kSel].method = ssoddMeth[sel[kSel]] result[kSel].select = ssoddSel[sel[kSel]] result[kSel].src = ssoddSrc[sel[kSel]] endfor ;--IV.3-- Compute the Average Estimate ------------------------------------------- if not keyword_set(dump) then begin ;--IV.3.1-- Average of All Values avgAll = meanWithUnc( result.val, result.unc ) ;--IV.3.2-- Average of Valid Values Only valid = where( result.select ne 2, nbValid ) case nbValid of 0: avgVal=avgAll 1: avgVal=[result[valid].val, result[valid].unc] else: avgVal = meanWithUnc( result[valid].val, result[valid].unc ) endcase ;--IV.3.3-- Average of Selected Values Only valid = where( result.select eq 1, nbValid ) case nbValid of 0: avgSel=avgAll 1: avgSel=[result[valid].val, result[valid].unc] else: avgSel = meanWithUnc( result[valid].val, result[valid].unc ) endcase ;--IV.3.4-- Compute Estimate Deviation from Average for kSel=0, nbSel-1 do begin result[kSel].dev.all = (result[kSel].val-avgAll[0])/avgAll[1] result[kSel].dev.val = (result[kSel].val-avgVal[0])/avgVal[1] result[kSel].dev.sel = (result[kSel].val-avgSel[0])/avgSel[1] endfor ;--IV.3.5-- Export Structure of Estimates and Averages export={num:result[0].num, $ name:result[0].name, $ all:{val:avgAll[0], unc:avgAll[1]}, $ val:{val:avgVal[0], unc:avgVal[1]}, $ sel:{val:avgSel[0], unc:avgSel[1]}, $ ind:result} ;--IV.3.6-- GUI: Display Estimates and Averages if keyword_set(verbose) then begin print, '---------------------------------------------------------------' print, ' Density estimates Deviation from average' print, ' Value Uncertainty All Valid Select Technique Reference' forprint, result.val, result.unc, $ result.dev.all, result.dev.val, result.dev.sel, $ result.method, result.select, result.src, textout=2, $ format='(2x,F8.3,3x,F8.3,3x,3(F7.3,2x),2x,A-5,4x,I1,4x,A-30)' print, '---------------------------------------------------------------' print, avgAll[0], avgAll[1], 'Average all', format='(2x,E8.2,3x,E8.2,4x,A-25)' print, avgVal[0], avgVal[1], 'Average valid', format='(2x,E8.2,3x,E8.2,4x,A-25)' print, avgSel[0], avgSel[1], 'Average selected', format='(2x,E8.2,3x,E8.2,4x,A-25)' endif endif else begin export=result endelse ;--IV.4-- Return Individual Estimates and Averages ------------------------------- return, export end