修改6S Fortran77 代码,建立查找表
?
逐像元大氣校正,常預先計算查找表(LUT,LookUp Tabel),6S大氣輻射傳輸模式也可以用來計算LUT。但6S源程序輸出信息多,且浮點數輸出精度低,不利于提取關鍵信息生成LUT,本文描述了怎樣修改6S源碼以生成LUT。
首先確定LUT內容要素。
?????? 閱讀MODIS M?D04 氣溶膠產品生成算法文檔(NASA相關網頁),歸納了以下查找表要素:
- 1)?????? 太陽天頂角觀測天頂角太陽方位角觀測方位角之差(相對方位角)散射角
- 2)?????? 大氣模式
- 3)?????? 氣溶膠模式
- 4)?????? 550nm氣溶膠光學厚度
- 5)?????? 波段號
- 6)?????? 大氣透過率
- 7)?????? atm. intrin. ref.(個人理解,這是大氣程輻射換算后的反射率,用于校正計算)
- 8)?????? total? sca. (總散射,包括rayleigh散射和氣溶膠散射,用于校正計算)
- 9)?????? 表觀反射率
- 10)??? 校正后的地表反射率
- 11)??? xa xb xc參數(物理意義不明,用于校正計算)
其次,閱讀源碼,明確LUT各要素在6S源碼中的變量名。
6S大氣校正計算源碼(Excel驗證中采用此公式)
???????? rog=rapp/tgasm
???????? rog=(rog-ainr(1,1)/tgasm)/sutott/sdtott
???????? rog=rog/(1.+rog*sast)
???? xa=pi*sb/xmus/seb/tgasm/sutott/sdtott
???? xb=srotot/sutott/sdtott/tgasm
???? xc=sast
?????? 由計算源碼確定需輸出的變量。下面是輸出LUT要素的Fortran77代碼示例,建議放在源碼main.f中stop一句之前。
????? write(*,*) asol,phi0,avis,phiv,adif,phi,idatm,iaer,v,taer55,
???? 1? iwave,tgasm,ainr(1,1),sutott*sdtott,rapp,rog,xa,xb,xc
- 其中,asol是太陽天頂角,
- phi0是太陽方位角,
- avis是觀測天頂角,
- phiv是觀測方位角,
- adif是散射角,
- phi是相對方位角,
- idatm是大氣模式號,
- iaer是氣溶膠模式號,
- v是水平能見度,
- taer55是550nm氣溶膠光學厚度,
- iwave表示波段號,
- tgasm表示大氣透過率,
- ainr(1,1)是大氣本身的反射率(姑且這么理解),
- sutott*sdtott表示總散射,
- rapp是表觀反射率,
- rog是校正后的地表反射率,
- xa,xb,xc是校正計算參數。
Fortran77每行長度不能超過80個字符,續前行需在特定位置指明(示例中的iwave前的1即表示續行)。
該示例源碼沒有指定任何輸出樣式。浮點數會按默認樣式輸出,小數點后的位數比較多,精度較好。
挑選一個查找表文件用Excel驗證后表明,excel公式計算值與6S輸出值之間最大誤差小于1E-7。說明方法是可行的。
再次,編譯源碼,編寫Shell腳本:
編譯環境:OpenSUSE操作系統 g95編譯器,版本未知。
編譯命令:g95 *.f -o sixs(在BRDF相關代碼處可能有幾個warning,本文不涉及BRDF,故暫不修改調試。在Windows下用f77編譯,無warning,編譯通過)
生成LUT的bash腳本getLUT.sh:
1: function LUTCalc(){ 2: #{42,44,48,25,27,30} 3: IBand=$1 4: echo "Band ${IBand} is running" 5: for Iref in {0.1,0.5} 6: do 7: fstat=${IBand}"_"${Iref}.res 8: echo "asol,phi0,avis,phiv,adif,phi,idatm,iaer,v,taer55, iwave,tgasm,ainr,tott,rapp,rog,xa,xb,xc" >> ${fstat} 9: for SolarZ in {0,15,30,45,75} 10: do 11: for SolarAz in {0,45,90,135} 12: do 13: for ViewZ in {0,15,30,45,75} 14: do 15: for Iaer in {1,2,3,5,6,7} 16: do 17: for Idatm in {1,2,3,4,5,6} 18: do 19: for IAod in {0.1,0.2,0.5,1.0}; 20: do 21: # Run sixs and output 22: ./sixs <<EOF | tail -n 1 >> ${fstat} 23: 0 24: $SolarZ $SolarAz $ViewZ 0 3 15 25: $Idatm 26: $Iaer 27: 0 28: $IAod 29: -0 30: -1000 31: ${IBand} 32: 0 33: 0 34: 0 35: 0.0 36: -$Iref 37: EOF 38: done 39: done 40: done 41: done 42: done 43: done 44: done 45: } 46: function getLUT() 47: { 48: echo "LUT is Calcing" 49: for iwave in {42,44,48,25,27,30} 50: { 51: LUTCalc ${iwave} 52: } & 53: } 最后調用該腳本>source getLUT.sh
>getLUT
最好晚上計算早晨看結果,如果CPU給力的話,幾個小時后就可以得到結果。
下面是生成的LUT示例:
- asol,phi0,avis,phiv,adif,phi,idatm,iaer,v,taer55, iwave,tgasm,ainr,tott,rapp,rog,xa,xb,xc
- ?? 0.0000000?????? 0.0000000?????? 0.0000000?????? 0.0000000?????? 180.00000?????? 0.0000000??? 1?? 1?? 63.664398????? 0.10000000??? 25? 0.98984975????? 6.89081103E-02? 0.80637234????? 0.10000000????? 3.87301818E-02? 1.98730151E-03? 8.71319696E-02? 0.14777245???
- ?? 0.0000000?????? 0.0000000?????? 0.0000000?????? 0.0000000?????? 180.00000?????? 0.0000000??? 1?? 1?? 26.739149????? 0.20000000??? 25? 0.98984975????? 7.75793791E-02? 0.76532620????? 0.10000000????? 2.94530466E-02? 2.09388486E-03? 0.10336593????? 0.16389242???
- ?? 0.0000000?????? 0.0000000?????? 0.0000000?????? 0.0000000?????? 180.00000?????? 0.0000000??? 1?? 1?? 8.4940033????? 0.50000000??? 25? 0.98984975????? 0.10173188????? 0.64870018????? 0.10000000???? -2.69861287E-03? 2.47033220E-03? 0.15994170????? 0.20088956???
- ?? 0.0000000?????? 0.0000000?????? 0.0000000?????? 0.0000000?????? 180.00000?????? 0.0000000??? 1?? 1?? 3.5674956?????? 1.0000000??? 25? 0.98984975????? 0.13688390????? 0.48083964????? 0.10000000???? -7.89646432E-02? 3.33272247E-03? 0.29038188????? 0.24035060???
- ?????? ……
轉載于:https://www.cnblogs.com/wishmo/p/3429484.html
總結
以上是生活随笔為你收集整理的修改6S Fortran77 代码,建立查找表的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 计算机基础知识总结(一)
- 下一篇: java反射 pdf_java反射学习笔