; docformat = 'rst' ; ; NAME: ; ssoddBuild ; PURPOSE: ; Build the summary table for diameter, mass, density, porosity of ; the Solar System Objects Density Database. ; ;+ ; :Description: ; Build the summary table for diameter, mass, density, porosity of ; the Solar System Objects Density Database. ; ; :Categories: ; Database, SSODD, Asteroid, Density ; ; :Params: ; cwd: in, required, type=string ; Path to drop database files on output ; ; :Keywords: ; SSODD: in, optional, type=string ; Path to the SSODD repositery ; CONFIG: in, optional, type=string ; Path to the configuration file for catalogs, at the ; minimum this file should contain the following lines to be used ; by current routine:: ; [Solar System Objects Density Database] ; mass = PATH_TO_YOUR_SSODD_MASS_FILE ; diam = PATH_TO_YOUR_SSODD_DIAM_FILE ; dens = PATH_TO_YOUR_SSODD_DENS_FILE ; met = PATH_TO_YOUR_SSODD_METEORITE_FILE ; VERBOSE: in, optional, type=boolean, default=0 ; Trigger dialog with user ; NoFigure: in, optional, type=boolean, default=0 ; Do not generate individual figures for each SSO if set ; ; :Examples: ; Build the SSODD main table:: ; IDL> ssoddBuild, './' ; IDL> ssoddBuild, '~/ssodd/', config='~/ssodd/local_config.ini' ; ; :Uses: ; initIDL, readfmt, ssoddGetMass, ssoddGetDiam, ssoddGetDens, ssoddGetMet, ; ssoddPlotSSO ; ; :Author: ; B.Carry (OCA) ; ; :History: ; Change History:: ; Written in June 2014, B. Carry (IMCCE) ; 2017 Dec. - B. Carry (OCA) - Added NoFigure keyword ; 2017 Dec. - B. Carry (OCA) - Corrected BAD typo in porosity/macro porosity computation ;- pro ssoddBuild, cwd, ssodd=ssodd, config=config, verbose=verbose, NoFigure=NoFigure COMPILE_OPT hidden ;-----------------------------------------------------------------------------------------------; ;-----------------------------------------------------------------------------------------------; ;--- TAG --- I -- Initialization And Input Verification -----------------------; ;-----------------------------------------------------------------------------------------------; ;-----------------------------------------------------------------------------------------------; ;--I.1-- Check Output Location ---------------------------------------------------------------; if not keyword_set(cwd) then begin message, /ioError, 'Usage: ssoddBuild, cwd [, config=, /Verbose, /NoFigure]' endif else begin cwd+='/' if not file_test(cwd,/dir) then file_mkdir, cwd if not file_test(cwd+'latex',/dir) then file_mkdir, cwd+'latex' if not file_test(cwd+'figures',/dir) then file_mkdir, cwd+'figures' endelse ;--I.2-- Set IDL to Local Working Environment ------------------------------------------------; ;--I.2.1-- SSODD Root Configuration if not keyword_set(ssodd) then begin if not keyword_set(config) then begin config = initIDL(/Catalog) endif SSODD = config.ssodd endif ;--I.2.2-- SSODD Graphics Configuration ssoddConf=ssoddLoadConfig(ssodd.conf) ;--I.3-- Code Verbosity ----------------------------------------------------------------------; if keyword_set(verbose) then verbose=1 else verbose=0 if keyword_set(verbose) then print, ' SSODD -- Initialization' ;-----------------------------------------------------------------------------------------------; ;-----------------------------------------------------------------------------------------------; ;--- TAG --- II -- Database Step 1: Census of Objects -----------------------; ;-----------------------------------------------------------------------------------------------; ;-----------------------------------------------------------------------------------------------; ;--II.1-- Read Individual Database Files -----------------------------------------------------; if keyword_set(verbose) then print, ' SSODD -- Reading databases' ;--II.1.1-- Try to Read mass = ssoddGetMass(/dump, ssodd=ssodd.mass) diam = ssoddGetDiam(/dump, ssodd=ssodd.diam) dens = ssoddGetDens(/dump, ssodd=ssodd.dens) met = ssoddGetMet( /dump, ssodd=ssodd.met ) ;--II.1.2-- Catch Exceptions ;--II.1.2/A-- SSODD Mass if size(mass,/Type) ne 8 then begin case mass of -2: message, /ioError, 'File Not Found (SSODD Mass): '+strTrim(ssodd.mass,2) else: print, 'Weird... ' endcase stop endif ;--II.1.2/B-- SSODD Diameter if size(diam,/Type) ne 8 then begin case diam of -2: message, /ioError, 'File Not Found (SSODD Diam): '+strTrim(ssodd.diam,2) else: print, 'Weird... ' endcase stop endif ;--II.1.2/C-- SSODD Density if size(dens,/Type) ne 8 then begin case dens of -2: message, /ioError, 'File Not Found (SSODD Dens): '+strTrim(ssodd.dens,2) else: print, 'Weird... ' endcase stop endif ;--II.1.2/D-- SSODD Meteorites if size(met,/Type) ne 8 then begin case met of -2: message, /ioError, 'File Not Found (SSODD Met): '+strTrim(ssodd.met,2) else: print, 'Weird... ' endcase stop endif ;--II.2-- Identify Unique Objects ------------------------------------------------------------; ;--II.2.1-- Create Unique List ; fullName = [mass.name, diam.name, dens.name] ; fullNum = [mass.num, diam.num, dens.num] fullNum = [mass.num, dens.num] fullName = [mass.name, dens.name] uniqName = fullName[uniq(fullName,sort(fullName))] uniqNum = fullNum[uniq(fullName,sort(fullName))] nbSSO = n_elements(uniqName) if keyword_set(verbose) then print, ' SSODD -- Number of unique SSO: '+strTrim(string(nbSSO,format='(I)'),2) ;--II.2.2-- Order Unique List num = where( uniqNum gt 0, comp=noNum) resName = uniqName[noNum] resNum = uniqNum[noNum] ;--II.2.2/A-- Numbered partNum1 = uniqNum[num] partName1 = uniqName[num] ;--II.2.2/B-- Comets com = where( resNum lt 0, comp=noNum ) ord=sort(resNum[com]) partNum3 = resNum[com[ord]] partName3 = resName[com[ord]] ;--II.2.2/C-- Not Numbered partNum2 = resNum[noNum] partName2 = resName[noNum] uniqName = [partName1[sort(partNum1)], partName2, partName3] uniqNum = [partNum1[sort(partNum1)], partNum2 , partNum3 ] ;--II.3-- Definition of the Output Structure -------------------------------------------------; valUnc={val:0., unc:0., rank:''} empty={num:0L, name:'', $ ;-Official # and Designation type:'', $ ;-aster|comet|planet|satel class: '', $ ;-aster: NEA|MB>, comet:JFC|LPC, satel:Mars|Jupiter taxo: '', $ ;-Taxonomic class analog: '', $ ;-Analog material mass:valUnc, $ ;-Average Mass diam:valUnc, $ ;-Average Diameter density:valUnc, $ ;-Resulting Density porosity:valUnc, $ ;-Resulting Porosity macroporosity:valUnc, $ ;-Resulting Macroporosity rank: ''} ;-Subjective Classification on Values db=replicate(empty,nbSSO) ;--II.4-- Read SSO-Meteorite Links DB --------------------------------------------------------; link = ssoddGetLink(ssodd=ssodd.link) ;--II.5-- Determine Dynamical Classes --------------------------------------------------------; ;--II.5.1-- Comets comet = where( uniqNum lt 0, comp=aster) db[comet].type = 'comet' ;--II.5.2-- Asteroids dynClass = astClass(uniqName[aster]) db[aster].type = 'aster' db[aster].class = dynClass.type+'>'+dynClass.subtype ;--II.6-- DB Ancillary Files -----------------------------------------------------------------; openw, uLatexDiam, /get_lun, cwd+'latex/loadDiam.tex' openw, uLatexMass, /get_lun, cwd+'latex/loadMass.tex' openw, uLatexDens, /get_lun, cwd+'latex/loadDens.tex' ;--II.7-- Loop Over Individual Objects -------------------------------------------------------; if keyword_set(verbose) then print, ' SSODD -- Loop over SSOs' for kSSO=0, nbSSO-1 do begin ;-----------------------------------------------------------------------------------------------; ;-----------------------------------------------------------------------------------------------; ;--- TAG --- III -- Database Step 2: Average Values -----------------------; ;-----------------------------------------------------------------------------------------------; ;-----------------------------------------------------------------------------------------------; ;--III.1-- Read Mass, Diameter, Density for Current SSO ------------------------------------; mass = ssoddGetMass(uniqName[kSSO], ssodd=ssodd.mass) diam = ssoddGetDiam(uniqName[kSSO], ssodd=ssodd.diam) dens = ssoddGetDens(uniqName[kSSO], ssodd=ssodd.dens) ;---TEST MEDIAN ; db[kSSO].diam.val = weighted_median(diam.ind(*).val, 1./diam.ind(*).unc) ; db[kSSO].diam.unc = weighted_median(abs( diam.ind(*).val-db[kSSO].diam.val ), 1./diam.ind(*).unc) ; ; ; dimMass=size(mass) ; if dimMass(dimMass(0)+1) eq 8 then begin ; db[kSSO].mass.val = weighted_median(mass.ind(*).val, 1./mass.ind(*).unc) ; db[kSSO].mass.unc = weighted_median(abs( mass.ind(*).val-db[kSSO].mass.val ), 1./mass.ind(*).unc) ; ; val= db[kSSO].mass.val / (!PI*(db[kSSO].diam.val^3)/6) * 1e-12 ; unc= val*sqrt( (db[kSSO].mass.unc/db[kSSO].mass.val)^2. + 9.*(db[kSSO].diam.unc/db[kSSO].diam.val)^2. ) ; dens={num:mass.num, name:mass.name, sel:{val:val, dev:unc}, method:'Average', ind:0} ; db[kSSO].density.val = dens.sel.val ; db[kSSO].density.unc = dens.sel.dev ; ; endif else begin ; ; typeDens=size(dens) ; if typeDens(typeDens(0)+1) eq 8 then begin ; db[kSSO].density.val = weighted_median(dens.ind(*).val, 1./dens.ind(*).unc) ; db[kSSO].density.unc = weighted_median(abs( dens.ind(*).val-db[kSSO].density.val ), 1./dens.ind(*).unc) ; endif ; ; val= db[kSSO].density.val * (!PI*(db[kSSO].diam.val^3)/6) * 1e12 ; unc= val*sqrt( (db[kSSO].density.unc/db[kSSO].density.val)^2. + 9.*(db[kSSO].diam.unc/db[kSSO].diam.val)^2. ) ; mass={num:dens.num, name:dens.name, sel:{val:val, dev:unc}, method:'Average', ind:0} ; db[kSSO].mass.val = val ; db[kSSO].mass.val = unc ; endelse ;---TEST MEAN ; db[kSSO].diam.val = weighted_mean(diam.ind(*).val, 1./diam.ind(*).unc) ; db[kSSO].diam.unc = weighted_mean(abs( diam.ind(*).val-db[kSSO].diam.val ), 1./diam.ind(*).unc) ; ; ; dimMass=size(mass) ; if dimMass(dimMass(0)+1) eq 8 then begin ; db[kSSO].mass.val = weighted_mean(mass.ind(*).val, 1./mass.ind(*).unc) ; db[kSSO].mass.unc = weighted_mean(abs( mass.ind(*).val-db[kSSO].mass.val ), 1./mass.ind(*).unc) ; ; val= db[kSSO].mass.val / (!PI*(db[kSSO].diam.val^3)/6) * 1e-12 ; unc= val*sqrt( (db[kSSO].mass.unc/db[kSSO].mass.val)^2. + 9.*(db[kSSO].diam.unc/db[kSSO].diam.val)^2. ) ; dens={num:mass.num, name:mass.name, sel:{val:val, dev:unc}, method:'Average', ind:0} ; db[kSSO].density.val = dens.sel.val ; db[kSSO].density.unc = dens.sel.dev ; ; endif else begin ; ; typeDens=size(dens) ; if typeDens eq 8 then begin ; db[kSSO].density.val = weighted_mean(dens.ind(*).val, 1./dens.ind(*).unc) ; db[kSSO].density.unc = weighted_mean(abs( dens.ind(*).val-db[kSSO].density.val ), 1./dens.ind(*).unc) ; endif ; ; val= db[kSSO].density.val * (!PI*(db[kSSO].diam.val^3)/6) * 1e12 ; unc= val*sqrt( (db[kSSO].density.unc/db[kSSO].density.val)^2. + 9.*(db[kSSO].diam.unc/db[kSSO].diam.val)^2. ) ; mass={num:dens.num, name:dens.name, sel:{val:val, dev:unc}, method:'Average', ind:0} ; db[kSSO].mass.val = val ; db[kSSO].mass.val = unc ; endelse ;--III.1.2-- Compute Missing Component of Triumvirat typeMass=size(mass,/Type) if typeMass ne 8 then begin val= dens.sel.val * (!PI*(diam.sel.val^3)/6) * 1e12 unc= val*sqrt( (dens.sel.unc/dens.sel.val)^2. + 9.*(diam.sel.unc/diam.sel.val)^2. ) mass={num:dens.num, name:dens.name, sel:{val:val, unc:unc}, method:'Average', ind:0} endif else begin locDens = ssoddCompDens( mass.sel, diam.sel ) dens={num:mass.num, name:mass.name, sel:locDens, method:'Average', ind:0} ; val= mass.sel.val / (!PI*(diam.sel.val^3)/6) * 1e-12 ; unc= val*sqrt( (mass.sel.unc/mass.sel.val)^2. + 9.*(diam.sel.unc/diam.sel.val)^2. ) ; dens={num:mass.num, name:mass.name, sel:{val:val, unc:unc}, method:'Average', ind:0} endelse ;--III.1.3-- Fill SSODD Database db[kSSO].mass.val = mass.sel.val db[kSSO].mass.unc = mass.sel.unc db[kSSO].diam.val = diam.sel.val db[kSSO].diam.unc = diam.sel.unc db[kSSO].density.val = dens.sel.val db[kSSO].density.unc = dens.sel.unc ;--III.2-- Identify Analog & Compute Porosity ----------------------------------------------; ;--III.2.1-- Retrieve Taxonomy and Meteorite Associations analog = ssoddGetAnalog(uniqName[kSSO], ssodd=ssodd.analog) db[kSSO].taxo = analog.taxo.class ;--III.2.2-- Specific SSO-Meteorite Link if not strCmp(analog.met.class,'-') then begin db[kSSO].analog = analog.met.class ;--III.2.3-- Generic Analogs endif else begin ;--III.2.3/A-- Objects with Known Taxonomy if not strCmp(analog.taxo.class,'-') then begin select=where(strCmp(analog.taxo.class,link.class)) analog.met.class = link[select].met db[kSSO].analog = analog.met.class ;--III.2.3/B-- Objects with Unknown Composition endif else begin ;--III.2.3/B.1-- Comets if strCmp(db[kSSO].type,'comet',/fold) then begin select=where(strCmp(link.pop,'comet')) analog.met.class = link[select].met endif ;--III.2.3/B.2-- KBO if strCmp(db[kSSO].type,'aster',/fold) and $ strCmp(db[kSSO].class,'KBO',3,/fold) then begin select=where(strCmp(link.pop,'KBO')) analog.met.class = link[select].met endif ;--III.2.3/B.3-- Asteroids without Taxonomy if strCmp(db[kSSO].type,'aster',/fold) and $ not strCmp(db[kSSO].class,'KBO',3,/fold) then begin select=where(strCmp(link.pop,'aster')) analog.met.class = link[select].met endif db[kSSO].analog = analog.met.class endelse endelse ;--III.2.4-- Retrieve Analog Meteorite Properties met = ssoddGetMet(analog.met.class) ;--III.2.5-- Porosity Computation db[kSSO].porosity.val = 100. *( 1. - db[kSSO].density.val/met.grain.val ) db[kSSO].porosity.unc = sqrt( (met.grain.unc/met.grain.val)^2. + (db[kSSO].density.unc/db[kSSO].density.val)^2. ) db[kSSO].porosity.unc *= sqrt(2.) * db[kSSO].porosity.val ;--III.2.6-- Macroporosity Computation db[kSSO].macroporosity.val = 100. *( 1. - db[kSSO].density.val/met.bulk.val ) db[kSSO].macroporosity.unc = sqrt( (met.bulk.unc/met.bulk.val)^2. + (db[kSSO].density.unc/db[kSSO].density.val)^2. ) db[kSSO].macroporosity.unc *= sqrt(2.) * db[kSSO].macroporosity.val ;--III.3-- Fill SSODD Main Structure -------------------------------------------------------; db[kSSO].num = uniqNum[kSSO] db[kSSO].name= uniqName[kSSO] ;--III.4-- GUI: Summary of Structure -------------------------------------------------------; if keyword_set(verbose) then $ print, kSSO+1, nbSSO, $ db[kSSO].num, db[kSSO].name, $ db[kSSO].type, db[kSSO].class, $ db[kSSO].taxo, db[kSSO].analog, $ db[kSSO].mass.val, db[kSSO].mass.unc, $ db[kSSO].diam.val, db[kSSO].diam.unc, $ db[kSSO].density.val, db[kSSO].density.unc, $ db[kSSO].porosity.val, db[kSSO].porosity.unc, $ db[kSSO].macroporosity.val, db[kSSO].macroporosity.unc, $ format='(I3,"/",I3,1x,I6,1x,A-15,1x,'+$ 'A-6,1x,A-3,1x,'+$ 'A-3,1x,A-3,1x,'+$ '2(E8.2,1x),2(F7.2,1x),2(F6.2),1x,'+$ '2(F8.1),1x,2(F8.1),1x,A-3)' ;-----------------------------------------------------------------------------------------------; ;-----------------------------------------------------------------------------------------------; ;--- TAG --- IV -- Database Step 3: Figures for each SSO -----------------------; ;-----------------------------------------------------------------------------------------------; ;-----------------------------------------------------------------------------------------------; if not keyword_set(NoFigure) then begin ;--IV.1-- Graphics Configuration ---------------------------------------------------------; if db[kSSO].num ge 0 then $ rootName = string(db[kSSO].num,format='(I06)')+'-'+strTrim(db[kSSO].name,2) $ else begin split = strsplit(strTrim(db[kSSO].name,2),'/',/extract,count=nbField) if nbField eq 1 then rootName = string(db[kSSO].num,format='(I06)')+'-'+split $ else rootName = string(db[kSSO].num,format='(I06)')+'-'+split[0]+'_'+split[1] endelse pos = strpos(rootName,' ') if pos[0] ne -1 then strput, rootName, '_', pos ;--IV.2-- Create Figures -----------------------------------------------------------------; nameDiam = 'figures/figDiam-'+rootName nameDens = 'figures/figDens-'+rootName nameMass = 'figures/figMass-'+rootName if n_elements(diam.ind) gt 1 then ssoddPlotSSO, diam, dump=cwd+nameDiam, graph=ssoddConf if n_elements(mass.ind) gt 1 then ssoddPlotSSO, mass, dump=cwd+nameMass, graph=ssoddConf if n_elements(dens.ind) gt 1 then ssoddPlotSSO, dens, dump=cwd+nameDens, graph=ssoddConf ;--IV.3-- Add Figures to LaTeX -----------------------------------------------------------; ;--IV.3.1-- Diameter if n_elements(diam.ind) gt 1 then begin printf, uLatexDiam, '' if db[kSSO].num gt 0 then begin printf, uLatexDiam, '('+strTrim(string(db[kSSO].num,format='(I6)'),2)+') '+db[kSSO].name+' \\' endif else begin printf, uLatexDiam, db[kSSO].name+' \\' endelse printf, uLatexDiam, ' \includegraphics[width=0.5\textwidth]{'+nameDiam+'} \\' endif ;--IV.3.2-- Mass if n_elements(mass.ind) gt 1 then begin printf, uLatexMass, '' if db[kSSO].num gt 0 then begin printf, uLatexMass, '('+strTrim(string(db[kSSO].num,format='(I6)'),2)+') '+db[kSSO].name+' \\' endif else begin printf, uLatexMass, db[kSSO].name+' \\' endelse printf, uLatexMass, ' \includegraphics[width=0.5\textwidth]{'+nameMass+'} \\' endif ;--IV.3.3-- Density if n_elements(dens.ind) gt 1 then begin printf, uLatexDens, '' if db[kSSO].num gt 0 then begin printf, uLatexDens, '('+strTrim(string(db[kSSO].num,format='(I6)'),2)+') '+db[kSSO].name+' \\' endif else begin printf, uLatexDens, db[kSSO].name+' \\' endelse printf, uLatexDens, ' \includegraphics[width=0.5\textwidth]{'+nameDens+'} \\' endif endif endfor ;-----------------------------------------------------------------------------------------------; ;-----------------------------------------------------------------------------------------------; ;--- TAG --- V -- Database Step 4: Export to Disk -----------------------; ;-----------------------------------------------------------------------------------------------; ;-----------------------------------------------------------------------------------------------; ;--V.1-- SSODD Main Table in ASCII-------------------------------------------------------------; forprint, db.num, db.name, db.type, db.class, db.taxo, db.analog, $ db.mass.val, db.mass.unc, db.diam.val, db.diam.unc, db.density.val, db.density.unc, $ db.porosity.val, db.porosity.unc, db.macroporosity.val, db.macroporosity.unc, $ format='(I6,1x,A-15,1x,'+$ 'A-6,1x,A-3,1x,'+$ 'A-3,1x,A-3,1x,'+$ '2(E8.2,1x),2(F7.2,1x),2(F6.2),1x,'+$ '2(F8.1),1x,2(F8.1),1x,A-3)', $ textout=cwd+'ssodd.dat', /Silent, $ comment='#Number Name Type DynClass Taxonomy Meteorite Mass dMass Diameter dDiameter Density dDensity Porosity dPorosity Macroporosity dMacroporosity' ;--V.2-- SSODD Main Table in CSV -------------------------------------------------------------; forprint, db.num, db.name, db.type, db.class, db.taxo, db.analog, $ db.mass.val, db.mass.unc, db.diam.val, db.diam.unc, db.density.val, db.density.unc, $ db.porosity.val, db.porosity.unc, db.macroporosity.val, db.macroporosity.unc, $ format='(I6,",",A-15,",",'+$ 'A-6,",",A-15,",",'+$ 'A-3,",",A-3,",",'+$ '2(E8.2,","),2(F7.2,","),2(F6.2,","),'+$ '2(F8.1,","),F8.1,",",F8.1)', $ textout=cwd+'ssodd.csv',/Silent, $ comment='Number, Name, Type, Dynamical Class, Taxonomy, Analog Meteorite, Mass, Mass uncertainty, Diameter, Diameter uncertainty, Density, Density uncertainty, Porosity, Porosity uncertainty, Macroporosity, Macroporosity uncertainty' ;--V.3-- SSODD Main Table in LaTeX -----------------------------------------------------------; head= ['\longtab[1]{ ',$ '\begin{longtable}{rlllccrrcc} ',$ '\caption{\label{tab:ssodd}Dynamical class (IMB, MMB, and OMB stand ',$ ' for Inner, Middle, and Outer belt respectively), taxonomic class, ',$ ' mass ($\mathcal{M}$), diameter ($\mathcal{D}$), and density ($\rho$) ',$ ' of Ch/Cgh asteroids used in this work, compiled following the ',$ ' recipes described in \citet{2012-PSS-73-Carry}.}\\ ',$ '\hline\hline ',$ ' \multicolumn{1}{c}{\#} & \multicolumn{1}{c}{Name} & ',$ ' \multicolumn{1}{c}{Dyn.} & \multicolumn{1}{c}{Taxo.} & ',$ ' \multicolumn{1}{c}{$\mathcal{M}$} & \multicolumn{1}{c}{$\delta \mathcal{M}$} & ',$ ' \multicolumn{1}{c}{$\mathcal{D}$} & \multicolumn{1}{c}{$\delta \mathcal{D}$} & ',$ ' \multicolumn{1}{c}{$\rho$} & \multicolumn{1}{c}{$\delta \rho$} \\ ',$ ' &&&&\multicolumn{1}{c}{(kg)} & \multicolumn{1}{c}{(kg)} & ',$ ' \multicolumn{1}{c}{(km)} & \multicolumn{1}{c}{(km)} & ',$ ' \multicolumn{1}{c}{(g$\cdot$cm$^{-3}$)} & \multicolumn{1}{c}{(g$\cdot$cm$^{-3}$)} \\',$ '\hline ',$ '\endfirsthead ',$ '\caption{continued.}\\ ',$ '\hline\hline ',$ ' \multicolumn{1}{c}{\#} & \multicolumn{1}{c}{Name} & ',$ ' \multicolumn{1}{c}{Dyn.} & \multicolumn{1}{c}{Taxo.} & ',$ ' \multicolumn{1}{c}{$\mathcal{M}$} & \multicolumn{1}{c}{$\delta \mathcal{M}$} & ',$ ' \multicolumn{1}{c}{$\mathcal{D}$} & \multicolumn{1}{c}{$\delta \mathcal{D}$} & ',$ ' \multicolumn{1}{c}{$\rho$} & \multicolumn{1}{c}{$\delta \rho$} \\ ',$ ' &&&&\multicolumn{1}{c}{(kg)} & \multicolumn{1}{c}{(kg)} & ',$ ' \multicolumn{1}{c}{(km)} & \multicolumn{1}{c}{(km)} & ',$ ' \multicolumn{1}{c}{(g$\cdot$cm$^{-3}$)} & \multicolumn{1}{c}{(g$\cdot$cm$^{-3}$)} \\',$ '\hline',$ '\endhead',$ '\hline',$ '\endfoot'] foot=['\end{longtable}}'] forprint, db.num, db.name, db.type, db.class, db.taxo, db.analog, $ ; db.mass.val, db.mass.unc, $ ; db.diam.val, db.diam.unc, $ ; db.density.val, db.density.unc, $ db.mass.val, db.mass.unc*3, $ db.diam.val, db.diam.unc*3, $ db.density.val, db.density.unc*3, $ db.porosity.val, db.porosity.unc, db.macroporosity.val, db.macroporosity.unc, $ format='(I6,"&",A-15,"&",'+$ 'A-6,"&",A-15,"&",'+$ 'A-3,"&",A-3,"&",'+$ '2(E8.2,"&"),2(F7.2,"&"),2(F6.2,"&"),'+$ '2(F8.1,"&"),F8.1,"&",F8.1,"\\")', $ textout=cwd+'ssodd.tex',/Silent, $ comment=head openW, idIn, cwd+'ssodd.tex', /Get_lun, /Append for kF=0, n_elements(foot)-1 do printf, idIn, foot[kF] close, idIn stop ;--V.4-- SSODD Latex Files -------------------------------------------------------------------; free_lun, uLatexDiam free_lun, uLatexMass free_lun, uLatexDens end