; docformat = 'rst' ; ; NAME: ; ssoddGetMass ; PURPOSE: ; Return the mass estimates or their average value from the Solar ; System Objects Density Database for a specific target or ; simply dump the database ; ;+ ; :Description: ; Return the mass 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, Mass ; ; :Params: ; ID: in, required, type=integer/string ; Target identifyer ('*', Name, Provisional designation, Number) ; ; :Returns: A structure with the mass 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:: ; .NUM: Target Number ; .NAME: Target Name ; .ALL: Weighted average of all estimates:: ; .val: Value in kg ; .unc: Standard deviation in kg ; .VAL: Weighted average of valid estimates (flag!=2):: ; .val: Value in kg ; .unc: Standard deviation in kg ; .ALL: Weighted average of selected estimates (flag=1):: ; .val: Value in kg ; .unc: Standard deviation in kg ; .IND: An array of structure for each mass estimate:: ; .val: Mass estimates, in kg ; .unc: Mass uncertainty, in kg ; .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 mass ; .select: A flag for selection (sel=0, val=0|1, all=0|1|2) ; .src: The source of mass estimate (e.g., article bibcode) ; ; :Keywords: ; SSODD: in, optional, type=string/structure ; The SSODD mass structure or a path to the SSODD mass 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] ; mass = PATH_TO_YOUR_SSODD_MASS_FILE ; dump: in, optional, type=boolean, default=0 ; Set this keyword to return the whole SSODD file ; noWeight: in, optional, type=boolean, default=0 ; Set this keyword to compute average mass without weights ; verbose: in, optional, type=boolean, default=0 ; Trigger dialog with user ; ; :Examples: ; Search SSODD for Ceres and Pallas:: ; IDL> print, ssoddGetMass(1) ; IDL> print, ssoddGetMass('Pallas') ; ; :Uses: ; initIDL, readfmt, astNameFormat, designation, meanWithUnc ; ; :Author: ; B.Carry (OCA) ; ; :History: ; Change History:: ; Written in June 2014, B. Carry (IMCCE) ; 2014 Sep - B. Carry (IMCCE) - Bug on selection (num=0) corrected ; 2017 Apr - B. Carry (OCA) - Added idl2, added noWeight ; 2017 Dec - B. Carry (OCA) - Changed input format to CSV ; 2018 Mar - B. Carry (OCA) - SSODD keyword accept structure to avoid reading the file on disk ; 2018 Apr - B. Carry (OCA) - Changed tags dev -> unc ;- function ssoddGetMass, id, SSODD=SSODD, config=config, dump=dump, $ verbose=verbose, noWeight=noWeight 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.mass 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: mass=ssoddGetMass([ID,/DUMP,...])' return, -3 endif ;--I.4.2-- SSODD Mass File Not Found if size(ssodd,/Type) eq 7 then if ~file_test(ssodd,/read) then begin if keyword_set(VERBOSE) then message, /ioError, 'SSODD File Not Found: '+strtrim(ssodd,2) return, -2 endif ;-----------------------------------------------------------------------------------------------; ;-----------------------------------------------------------------------------------------------; ;--- TAG --- II -- Read the Whole SSODD file -----------------------; ;-----------------------------------------------------------------------------------------------; ;-----------------------------------------------------------------------------------------------; ;--II.1-- Read SSODD Mass File ---------------------------------------------------------------; if size(ssodd,/Type) eq 7 then begin 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) ;--II.2-- Mass Structure was Provided --------------------------------------------------------; endif else begin ssoddNum = ssodd.num ssoddName= ssodd.name ssoddVal = ssodd.val ssoddUnc = ssodd.unc ssoddMeth= ssodd.method ssoddSel = ssodd.select ssoddSrc = ssodd.src endelse ;-----------------------------------------------------------------------------------------------; ;-----------------------------------------------------------------------------------------------; ;--- 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 if keyword_set(noWeight) then avgAll = [mean(result.val),stddev(result.val)] $ else 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: if keyword_set(noWeight) then avgVal = [mean(result[valid].val),stddev(result[valid].val)] $ 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: if keyword_set(noWeight) then begin mMean = mean(result[valid].val) ex = String(mMean, Format='(e8.0)') pt = StrPos(ex, '.') first = StrMid(ex, 0, pt) sign = StrMid(ex, pt+2, 1) mExpo = float(StrMid(ex, pt+3)) mStd = (10^mExpo)*stddev(result[valid].val/10^mExpo) avgSel = [mMean, mStd] endif 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, ' Mass 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,E8.2,3x,E8.2,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