반응형

     정보

    • 업무명    : 그라즈 텍스트 (CSV) 형식인 ECMWF 해수면 온도 자료를 이용한 단번에 자료 처리 (Text) 및 시각화

    • 작성자    : 이상호

    • 작성일    : 2020-07-05

    • 설   명    :

    • 수정이력 :

     

     내용

    [개요]

    • 안녕하세요? 기상 연구 및 웹 개발을 담당하고 있는 해솔입니다.

    • GrADS는 텍스트 자료를 이용하여 직접적인 시각화하기 하기 어렵기 때문에 그에 따른 자료 처리 기술이 요구됩니다.

    • 그러나 오늘 포스팅에서는 텍스트 (CSV) 형식인 ECMWF 해수면 온도 자료를 이용한 단번에 자료 처리 (Text) 및 시각화를 소개해 드리고자 합니다.

    • 추가로 오프라인 환경에서 GrADS 설치 및 공용 라이브러리 설정 방법을 소개한 링크를 보내드립니다.

     

    [GrADS] 오프라인 리눅스 (Linux) 환경에서 그라즈 (GrADS) 설치 및 공용 라이브러리 (Library) 설정

     정보 업무명 : 오프라인 리눅스 (Linux) 환경에서그라즈 (GrADS) 설치 및 공용 라이브러리 (Library) 설정 작성자 : 이상호 작성일 : 2020-07-05 설  명 : 수정이력 :  내용 [개요] 안녕하세요? 기상 연구 ��

    shlee1990.tistory.com

    • 추가로 그라즈 텍스트 (CSV) 형식인 ECMWF 해수면 온도 자료를 이용한 자료 처리 (Grid, Binary, Ct, Map) 및 시각화를 소개한 링크를 보내드립니다.

     

    [GrADS] 그라즈 텍스트 (CSV) 형식인 ECMWF 해수면 온도 자료를 이용한 자료 처리 (Grid, Binary, Ctl, Map) ��

     정보 업무명 : 그라즈 텍스트 (CSV) 형식인 ECMWF 해수면 온도 자료를 이용한 자료 처리 (Grid, Binary, Ctl, Map) 및 시각화 작성자 : 이상호 작성일 : 2020-07-05 설  명 : 수정이력 :  내용 [개요] 안녕하..

    shlee1990.tistory.com

     

    [특징]

    • GrADS를 통해 시각화하기 위해서 자료 처리 기술이 요구되며 이 프로그램은 이러한 목적을 달성하기 위해서 고안된 소프트웨어

     

    [기능]

    • 텍스트 파일을 이용하여 컬러바 부여

    • 각 위/경도에 따른 시각화

     

    [활용 자료]

    • 자료명 : sst.txt

    • 자료 종류 : 일평균 해수면 온도

    • 확장자 : txt

    • 영역 : 대한민국 한반도

    • 기간 : 2019년 01월 01일 - 2019년 01월 31일

    • 공간 해상도 : 25 km

    sst.txt
    3.52MB

     

    [자료 처리 방안 및 활용 분석 기법]

    • 없음

     

    [사용법]

    • 입력 자료를 동일 디렉터리에 위치

    • 소스 코드를 실행 (bash RunShell.sh)

    • 가시화 결과 확인

     

    [사용 OS]

    • Linux (CentOS v7.3)

    • VMware Workstation Pro v15.5

     

    [사용 언어]

    • GrADS v2.1.1

    • Shell Script (Bash)

    • Fortran

     

     소스 코드

    • 해당 작업을 하기 위한 컴파일 및 실행 코드는 GrADS, Shell Script, Fortran으로 작성되었으며 시각화를 위한 라이브러리는 kodama Library를 이용하였습니다.

    • 작업 환경의 경우 5개 디렉터리로 구성되며 주 프로그램은 RunShell.sh로 구성되어 있습니다.

     

     

    • 소스 코드는 단계별로 수행하며 상세 설명은 다음과 같습니다.

      • 1 단계는 유용한 쉘 스크립트 함수 (로그 기록, 종료 코드 검사)를 초기 설정합니다.

      • 2 단계는 작업 경로 및 필요한 라이브러리 경로를 설정합니다.

      • 3 단계는 텍스트 (CSV) 파일을 소프트웨어에 입력하기 용이한 형태로 변환합니다.

      • 4단계는 정적 소스 코드에 대한 Template를 생성합니다.

      • 5단계는 동적 변수에 대한 변경 그리고 Fortran을 컴파일/실행하여 메모리상에 저장하고 가시화를 위한 초기 설정합니다.

      • 6 단계는 ctl에 따라 영상 장면 표출하여 이미지 형식으로 저장합니다. 이 과정에서 포스트 스크립트 (EPS) 형식에서 PNG로 변환합니다.

     

    [명세]

    • [1 단계] 유용한 쉘 스크립트 함수를 초기 기록

      • 로그 레벨 (silent, notify, ok, warn, info, debug, error, crit)에 따른 컬러 부여

      • 실행 명령어에 대한 경고/종료 코드 검사

      • 세부 내용은 다음을 참조하시기 바랍니다.

    #================================================
    # Function
    #===============================================
    source ~/.DefaultCommon.sh
    
    #------------------
    # Log Level Print
    #------------------
    # silent ""
    # notify ""
    # ok ""
    # warn ""
    # info ""
    # debug ""
    # error ""
    # crit ""
    
    #------------------
    # Exit Code Check
    #------------------
    # fnCheckWarn "$?"
    # fnCheckExit "$?"

     

     

    !/bin/bash
    
    # color
    colBlk='\033[0;30m' # Black Default
    colRed='\033[0;31m' # Red
    colGrn='\033[0;32m' # Green
    colYlw='\033[0;33m' # Yellow
    colPur='\033[0;35m' # Purple
    colBlu='\033[0;34m' # Blue
    colCya='\033[0;36m' # Cyan
    colRst='\033[0m'    # Text Reset
    
    verbosity=6
    
    # verbosity levels
    sil_lvl=0
    crt_lvl=1
    err_lvl=2
    wrn_lvl=3
    ntf_lvl=4
    inf_lvl=5
    dbg_lvl=6
    
    # esilent prints output even in silent mode
    function silent() { verb_lvl=$sil_lvl log "${colCya}[SILE ]${colRst} $@" ; }
    function notify() { verb_lvl=$ntf_lvl log "${colCya}[NOTI ]${colRst} $@" ; }
    function ok()     { verb_lvl=$ntf_lvl log "${colBlu}[SUCC ]${colRst} $@" ; }
    function warn()   { verb_lvl=$wrn_lvl log "${colYlw}[WARN ]${colRst} $@" ; }
    function info()   { verb_lvl=$inf_lvl log "${colBlk}[INFO ]${colRst} $@" ; }
    function debug()  { verb_lvl=$dbg_lvl log "${colGrn}[DEBUG]${colRst} $@" ; }
    function error()  { verb_lvl=$err_lvl log "${colRed}[ERROR]${colRst} $@" ; }
    function crit()   { verb_lvl=$crt_lvl log "${colPur}[FATAL]${colRst} $@" ; }
    function log() {
            if [ $verbosity -ge $verb_lvl ]; then
                    datestring=`date +"%Y-%m-%d %H:%M:%S"`
                    echo -e "$datestring $@"
            fi
    }
    
    function fnCheckWarn() {
       exitCode=$1
       shift
          if [ $exitCode -eq 0 ]; then
             ok $@ succeded with exit code $exitCode
          else
             warn $@ failed with exit code $exitCode. The script will continue.
          fi
    
          # return the same code so other checks can follow this one inside the script
          return $exitCode
    }
    
    function fnCheckExit() {
       exitCode=$1
       shift
    
       if [ $exitCode -eq 0 ]; then
          ok $@ succeded with exit code $exitCode
       else
          error $@ failed with exit code $exitCode. The script will exit.
          exit $exitCode
       fi

     

    • [2 단계] 작업 경로 및 필요한 라이브러리 경로를 설정

      • pid : 수행 쉘 작업 번호

      • presentYmd : 현재 시각

      • contextPath : 현재 작업 경로 설정

      • *Path : 로그/입력/출력/이미지/임시 경로를 설정하고 해당 디렉터리 생성

      • libPath, mapPath : GrADS 시각화를 위한 라이브러리 및 지도 경로 설정

      • logPathName : 로그 파일명 설정

    #===============================================
    # Config
    #===============================================
    
    pid=$(echo $$)
    presentYmd=$(date +"%Y%m%d")
    # echo "pid : " $pid
    # echo "presentTime : " $presentTime
    
    contextPath=$(pwd)
    logPath=$contextPath/LOG
    inpPath=$contextPath/INPUT
    outPath=$contextPath/OUTPUT
    imgPath=$contextPath/IMG
    tmpPath=$contextPath/TMP
    
    if [ ! -d $logPath ]; then mkdir -p $logPath; fi
    if [ ! -d $inpPath ]; then mkdir -p $inpPath; fi
    if [ ! -d $outPath ]; then mkdir -p $outPath; fi
    if [ ! -d $imgPath ]; then mkdir -p $imgPath; fi
    if [ ! -d $tmpPath ]; then mkdir -p $tmpPath; fi
    
    libPath=/usr/local/grads-2.1.1.b0/lib
    mapPath=/usr/local/grads-2.1.1.b0/map
    
    logPathName=$logPath/Run_${presentYmd}.log

     

    • [3 단계] 텍스트 (CSV) 파일을 소프트웨어에 입력하기 용이한 형태로 변환

      • 해당 CSV 형식에서 ,1칸 공백으로 변환

    #================================================
    # Data Preprocessing
    #================================================
    info "======================== [START] Run Shell ======================================"
    
    cat $inpPath/sst.txt | sed -e "s/,/ /g" > $inpPath/sstL1.txt

     

     

     

    • [4단계] 정적 소스 코드에 대한 Template를 생성

      • makeTextToBin.f90

        • 위/경도 자료 (CSV 파일 형식)을 읽고 4열에 컬러 번호 부여

        • 컬러 번호의 경우 17-107로 부여되며 최솟값 미만일 경우 16이고 최댓값 초과는 199로 설정되어 있다.

      • makePlotUsingGrADS.exec

        • mapPoint.ctl를 통해 필요한 배경을 그리고 d t로 배경 이미지로 표출

        • 실질적으로 Library_For_Mapping_ASCII_Format.gs에서 전달 인자 (파일명, 위도, 경도, 해수면 온도, 컬러 번호)를 통해 시각화

        • 그리고 Library_For_Creating_Colorbar_From_ASCII_Format.gs에서 전달 인자 (아래 세부 그림 참조)를 통해 컬러바 표출

      • 해당 Template에서 %변수명의 경우 동적 변수를 의미

    #================================================
    # Template
    #================================================
    # set Val
    # Fortran
    cat > makeTextToBin.f90 << EOF
          ! implicit none
    
          character(8) :: sta
          integer(4) :: flag, lev, alt, year, month
          real(4) :: lat, lon, val, time
          integer(4) :: div, colNum
          real :: setMin, setMax
    
          open(8, file="$inpPath/sstL1.txt")
          
    
          ! Header Info
          read(8, *)
    
          colMin = 16
          colStart = 17
          colEnd = 199
          colDiv = 90
          setMin = 0
          setMax = 30
    
          do
             read(8, *, end=999) sta, lon, lat, val
    
             if (sta /= "%dtYmd") cycle
             if (val < 0) cycle
    
             if (val < setMin) then
                colNum = 16
             else if (val > setMax) then
                colNum = 199
             else
                colNum = colStart + ((val - setMin) / (setMax - setMin) * colDiv)
             endif
    
             write(99, *) lat, lon, val, colNum
          enddo
    
    999   stop
          end
    EOF
    
    # GrADS
    cat > makePlotUsingGrADS.exec << EOF
       reinit
       ${libPath}/xopen.gs mapPoint.ctl
    
       set display color white
       set cmin 10000
       set mpdraw off
    
       set parea 0 11.0 1.5 8.0
       set xlopts 1 6 0.18
       set ylopts 1 6 0.18
    
       set lat 28 40
       set lon 120 136
       set xlint 4
       set ylint 4
       set font 0
    
       set grads off
       set grid off
    
       set gxout shaded
       set csmooth on
    
       d t
    
       Library_For_Mapping_ASCII_Format.gs fort.99 1 2 3 4
       Library_For_Creating_Colorbar_From_ASCII_Format.gs   0  5.5  0.5   0.25 1.2   8.0 1.0  17 116 0 30 0 30 3
    
       set rgb 116 0 0 0   
       draw shp ${mapPath}/gshhg-shp-2.3.4/GSHHS_shp/f/GSHHS_f_L1.shp
    
       draw title %dtBdY
       set string 1 tc
       set strsiz 0.18 0.18
       draw string 5.5 1.05 Sea Surface Temperature [C]
    
    *   gxprint ${imgPath}/%imgPathName.png
       
       ${libPath}/save.gs ${imgPath}/%imgPathName -background white
       !convert -trim -density 600 -rotate 90 ${imgPath}/%imgPathName.eps ${imgPath}/%imgPathName.png
       !rm -f ${imgPath}/%imgPathName.eps
    
       quit
    EOF

     

     

     

    • [5단계] 동적 변수에 대한 변경 그리고 Fortran을 컴파일/실행하여 메모리상에 저장하고 가시화를 위한 초기 설정

      • seq를 통해 기준 날짜 (2019-01-01)를 기준으로 일별로 생성하고 dtDateList 변수 설정

      • 해당 변수를 통해 dtYmd, dtBdY, imgPathName 동적 변수를 설정

      • cat 및 sed 명령어를 통해 동적 변수를 치환하여 임시 소스 코드 (tmp.f90) 생성

      • gfortran를 통해 컴파일 및 실행하여 가시화를 위한 초기 설정

     

    #===============================================
    # Run
    #===============================================
    
    setDate="2019-01-01"
    
    dtDateList=$(seq 0 1 30 | xargs -I {} date -d "${setDate} {} days" +"%Y-%m-%d")
    # dtDateList=$(seq 0 1 0 | xargs -I {} date -d "${setDate} {} days" +"%Y-%m-%d")
    
    for getDate in $dtDateList; do
       dtYmd=$(date -d "${getDate}" +"%Y%m%d")
       dtBdY=$(date -d "${getDate}" +"%B %d, %Y")
       imgPathName=Image_${dtYmd}
       # imgPathName=Print_Image_${dtYmd}
       
       debug ">>>>> [CHECK] getDate : $getDate <<<<<"
       
       # Fortran
       debug "[START] Run Fortran"
       
       cat makeTextToBin.f90 \
          | sed -e "s/%dtYmd/${dtYmd}/g" \
          > $tmpPath/tmp.f90
       
       gfortran $tmpPath/tmp.f90
       fnCheckWarn "$?"
       
       ./a.out
       fnCheckWarn "$?"
    
       debug "[END] Run Fortran"
    
       # GrADS
       debug "[START] Run GrADS"
    
       cat makePlotUsingGrADS.exec \
          |  sed -e "s/%dtBdY/${dtBdY}/g" \
                 -e "s/%imgPathName/${imgPathName}/g" \
          > $tmpPath/tmp.exec
    
       grads -blc "exec $tmpPath/tmp.exec" > $logPathName 2>&1 
       fnCheckWarn "$?"
    
       debug "[END] Run GrADS"
    
      done
    
    info "======================== [END]   Run Shell ======================================"

     

    • [6 단계] 출력 파일 (fort.99)에 따라 영상 장면 표출하여 이미지 형식으로 저장합니다. 이 과정에서 포스트 스크립트 (EPS) 형식에서 PNG로 변환

      • GrADS에서도 cat 및 sed 명령어를 통해 동적 변수를 치환하여 임시 소스 코드 (tmp.exec) 생성

      • grads -blc를 통해 백그라운드로 실행하여 이미지를 생성한다.

     


    [가시화에 필요한 라이브러리]

    • Library_For_Mapping_ASCII_Format.gs

    function main(args)
    
    fname1=subwrd(args,1)
    latco=subwrd(args,2)
    lonco=subwrd(args,3)
    valco=subwrd(args,4)
    colco=subwrd(args,5)
    * xi=subwrd(args,5)
    * xd=subwrd(args,6)
    
    color='14 4 13 3 10 7 12 8 2 6'
    palgrey()
    
    'q dims'
    rec2=sublin(result,2)
    rec3 =sublin(result,3)
    xlon0=subwrd(rec2,6)
    xlon1=subwrd(rec2,8)
    ylat0=subwrd(rec3,6)
    ylat1=subwrd(rec3,8)
    
    ret=read(fname1)
    
    'q ll2xy 'xlon0' 'ylat0
    x0=subwrd(result,1)
    y0=subwrd(result,2)
    'q ll2xy  'xlon1' 'ylat1
    x1=subwrd(result,1)
    y1=subwrd(result,2)
    xs=x1-x0
    ys=y1-y0
    
    * if size of dot is too large, change number
    * 5 km
    * dx2=xs*0.05/(xlon1-xlon0) 
    * dy2=ys*0.05/(ylat1-ylat0)
    
    dx2 = xs * 0.125 / (xlon1 - xlon0) 
    dy2 = ys * 0.125 / (ylat1 - ylat0)
    
    while (1)
      ret = read(fname1)
      rc = sublin(ret,1)
      if (rc>0) 
        if (rc!=2) 
          say 'File I/O Error'
          return
        endif
        break
      endif
      rec = sublin(ret,2)
      time= subwrd(rec,valco)
      ylat= subwrd(rec,latco)
      xlon= subwrd(rec,lonco)
      xcl = subwrd(rec,colco)
      if (xlon < 0);xlon=xlon+360;endif;
      
      if (xlon >= xlon0 & xlon <= xlon1 & ylat >= ylat0 & ylat <= ylat1)
         x=x0+xs*(xlon-xlon0)/(xlon1-xlon0)
         y=y0+ys*(ylat-ylat0)/(ylat1-ylat0)
    *   xx=xi
    *   xc=1
    *   xcol=10
    *   if (time <= xx);xcol=1;endif;
    *   while (xc < 10)
    *   xo=xx
    *   xx=xx+xd
    *   xc=xc+1
    *   if (time > xo & time <= xx);xcol=xc;endif;
    *   endwhile
    *   xcol=13
    
    *    xcl=color2(time,xi,xd)
    *    say xcl
    *    xcl=subwrd(color,xcol)
         'set line 'xcl
         'draw recf 'x-dx2' 'y-dy2' 'x+dx2' 'y+dy2
    *    'draw recf 'x'-'dx2' 'y'-'dy2' 'x'+'dx2' 'y'+'dy2
    *    'draw mark 3 'x' 'y' 0.1'
      endif
    endwhile
    
    
    return
    
    
    function palgrey()
    
    ***************** Rainbow ********************
    * 13 color
    *
    *'set rgb 16 64 64 64'
    *
    *'set rgb 17 240   0 130'
    *'set rgb 18 250  60  60'
    *'set rgb 19 240 130  40'
    *'set rgb 20 230 175  45'
    *'set rgb 21 230 220  50'
    *'set rgb 22 160 230  50'
    *'set rgb 23   0 220   0'
    *'set rgb 24   0 210 140'
    *'set rgb 25   0 200 200'
    *'set rgb 26   0 160 255'
    *'set rgb 27  30  60 255'
    *'set rgb 28 130   0 220'
    *'set rgb 29 160   0 200'
    *
    *'set rgb 99 255 255 255'
    
    ***************** KMA Radar ********************
    * color 30
    *
    *'set rgb  16  64  64  64'
    *
    *'set rgb  17 135 217 255'
    *'set rgb  18  62 193 255'
    *'set rgb  19   7 171 255'
    *'set rgb  20   0 141 255'
    *'set rgb  21   0 119 255'
    *'set rgb  22 105 252 105'
    *'set rgb  23  30 242 105'
    *'set rgb  24   0 213   0'
    *'set rgb  25   0 164   0'
    *'set rgb  26   0 128   0'
    *'set rgb  27 255 241 111'
    *'set rgb  28 255 226  86'
    *'set rgb  29 255 208  57'
    *'set rgb  30 255 188  30'
    *'set rgb  31 255 170   9'
    *'set rgb  32 255 156   0'
    *'set rgb  33 255 139  27'
    *'set rgb  34 255 128  81'
    *'set rgb  35 255 110 110'
    *'set rgb  36 246  94 103'
    *'set rgb  37 232  74  86'
    *'set rgb  38 217  52  62'
    *'set rgb  39 201  31  37'
    *'set rgb  40 188  13  15'
    *'set rgb  41 179   0   0'
    *'set rgb  42 197 125 255'
    *'set rgb  43 194  62 255'
    *'set rgb  44 173   7 255'
    *'set rgb  45 146   0 255'
    *'set rgb  46 127   0 191'
    *
    *'set rgb 99 255 255 255'
    
    
    ************* Rainbow *************************
    * 39 color
    
    *'set rgb 16  64  64  64'
    *
    *'set rgb 17 153 102 255'
    *'set rgb 18 131  87 255'
    *'set rgb 19 109  73 255'
    *'set rgb 20  87  58 255'
    *'set rgb 21  66  44 255'
    *'set rgb 22  44  29 255'
    *'set rgb 23   0   0 255'
    *'set rgb 24   0  72 255'
    *'set rgb 25   0 117 255'
    *'set rgb 26   0 156 255'
    *'set rgb 27   0 192 255'
    *'set rgb 28   0 213 255'
    *'set rgb 29   0 232 255'
    *'set rgb 30   0 246 255'
    *'set rgb 31   0 255 249'
    *'set rgb 32   0 255 213'
    *'set rgb 33   0 255 193'
    *'set rgb 34   0 255 159'
    *'set rgb 35   0 255 126'
    *'set rgb 36   0 255  77'
    *'set rgb 37   0 255  15'
    *'set rgb 38  50 255   0'
    *'set rgb 39 114 255   0'
    *'set rgb 40 152 255   0'
    *'set rgb 41 181 255   0'
    *'set rgb 42 227 255   0'
    *'set rgb 43 243 255   0'
    *'set rgb 44 255 253   0'
    *'set rgb 45 255 232   0'
    *'set rgb 46 255 211   0'
    *'set rgb 47 255 189   0'
    *'set rgb 48 255 168   0'
    *'set rgb 49 255 146   0'
    *'set rgb 50 255 124   0'
    *'set rgb 51 255 102   0'
    *'set rgb 52 255  87   0'
    *'set rgb 53 255  73   0'
    *'set rgb 54 255  58   0'
    *'set rgb 55 255  29   0'
    *'set rgb 56 255   0   0'
    *
    *'set rgb 99 255 255 255'
    *
    ************* Diff ****************************
    * 37 color
    *
    *'set rgb 16   0   0   0'
    *
    *'set rgb 17   0   0 255'
    *'set rgb 18  38  38 255'
    *'set rgb 19  51  51 255'
    *'set rgb 20  63  63 255'
    *'set rgb 21  76  76 255'
    *'set rgb 22  89  89 255'
    *'set rgb 23 102 102 255'
    *'set rgb 24 114 114 255'
    *'set rgb 25 127 127 255'
    *'set rgb 26 140 140 255'
    *'set rgb 27 153 153 255'
    *'set rgb 28 165 165 255'
    *'set rgb 29 178 178 255'
    *'set rgb 30 191 191 255'
    *'set rgb 31 204 204 255'
    *'set rgb 32 216 216 255'
    *'set rgb 33 229 229 255'
    *'set rgb 34 242 242 255'
    *'set rgb 35 255 255 255'
    *'set rgb 36 255 243 243'
    *'set rgb 37 255 230 230'
    *'set rgb 38 255 217 217'
    *'set rgb 39 255 205 205'
    *'set rgb 40 255 192 192'
    *'set rgb 41 255 179 179'
    *'set rgb 42 255 166 166'
    *'set rgb 43 255 154 154'
    *'set rgb 44 255 141 141'
    *'set rgb 45 255 128 128'
    *'set rgb 46 255 115 115'
    *'set rgb 47 255 102 102'
    *'set rgb 48 255  90  90'
    *'set rgb 49 255  77  77'
    *'set rgb 50 255  64  64'
    *'set rgb 51 255  51  51'
    *'set rgb 52 255  38  38'
    *'set rgb 53 255   0   0'
    *
    *'set rgb 99 255 255 255'
    
    **************  Forest  ****************
    * 65 color
    *
    *'set rgb 16  64  64  64'
    *
    *'set rgb 17   0   0  30'
    *'set rgb 18   5  26   2'
    *'set rgb 19  10  32   4'
    *'set rgb 20  15  38   6'
    *'set rgb 21  20  44   8'
    *'set rgb 22  25  50  10'
    *'set rgb 23  30  56  12'
    *'set rgb 24  35  62  14'
    *'set rgb 25  40  68  16'
    *'set rgb 26  45  74  18'
    *'set rgb 27  50  80  20'
    *'set rgb 28  55  86  22'
    *'set rgb 29  60  92  24'
    *'set rgb 30  65  98  26'
    *'set rgb 31  70 104  28'
    *'set rgb 32  75 110  30'
    *'set rgb 33  80 116  32'
    *'set rgb 34  85 122  34'
    *'set rgb 35  90 128  36'
    *'set rgb 36  95 134  38'
    *'set rgb 37 100 140  40'
    *'set rgb 38 105 146  42'
    *'set rgb 39 110 152  44'
    *'set rgb 40 115 158  46'
    *'set rgb 41 120 164  48'
    *'set rgb 42 125 170  50'
    *'set rgb 43 130 176  52'
    *'set rgb 44 135 182  54'
    *'set rgb 45 140 188  56'
    *'set rgb 46 145 194  58'
    *'set rgb 47 150 200  60'
    *'set rgb 48 155 206  62'
    *'set rgb 49 255 250 110'
    *'set rgb 50 249 238  98'
    *'set rgb 51 243 226  86'
    *'set rgb 52 237 214  74'
    *'set rgb 53 231 202  62'
    *'set rgb 54 225 190  50'
    *'set rgb 55 219 178  38'
    *'set rgb 56 213 166  26'
    *'set rgb 57 207 154  14'
    *'set rgb 58 201 142   2'
    *'set rgb 59 195 130   0'
    *'set rgb 60 189 118   0'
    *'set rgb 61 183 106   0'
    *'set rgb 62 177  94   0'
    *'set rgb 63 171  82   0'
    *'set rgb 64 165  70   0'
    *'set rgb 65 159  58   0'
    *'set rgb 66 153  46   0'
    *'set rgb 67 147  34   0'
    *'set rgb 68 141  22   0'
    *'set rgb 69 135  10   0'
    *'set rgb 70 129   0   0'
    *'set rgb 71 123   0   0'
    *'set rgb 72 117   0   0'
    *'set rgb 73 111   0   0'
    *'set rgb 74 105   0   0'
    *'set rgb 75  99   0   0'
    *'set rgb 76  93   0   0'
    *'set rgb 77  87   0   0'
    *'set rgb 78  81   0   0'
    *'set rgb 79  75   0   0'
    *'set rgb 80  69   0   0'
    *'set rgb 81  20   0   0'
    *
    *'set rgb 99 255 255 255'
    *
    **************  Rainbow [Red ~ Blue] ****************
    * color 100 
    
    'set rgb  16  64  64  64'
    
    'set rgb  17   0   0 130'
    'set rgb  18   0   0 134'
    'set rgb  19   0   0 146'
    'set rgb  20   0   0 154'
    'set rgb  21   0   0 166'
    'set rgb  22   0   0 174'
    'set rgb  23   0   0 186'
    'set rgb  24   0   0 198'
    'set rgb  25   0   0 206'
    'set rgb  26   0   0 218'
    'set rgb  27   0   0 226'
    'set rgb  28   0   0 238'
    'set rgb  29   0   0 250'
    'set rgb  30   0   0 254'
    'set rgb  31   0  11 254'
    'set rgb  32   0  19 254'
    'set rgb  33   0  31 254'
    'set rgb  34   0  39 254'
    'set rgb  35   0  51 254'
    'set rgb  36   0  63 254'
    'set rgb  37   0  71 254'
    'set rgb  38   0  83 254'
    'set rgb  39   0  91 254'
    'set rgb  40   0 103 254'
    'set rgb  41   0 115 254'
    'set rgb  42   0 123 254'
    'set rgb  43   0 134 254'
    'set rgb  44   0 142 254'
    'set rgb  45   0 154 254'
    'set rgb  46   0 162 254'
    'set rgb  47   0 174 254'
    'set rgb  48   0 186 254'
    'set rgb  49   0 194 254'
    'set rgb  50   0 206 254'
    'set rgb  51   0 214 254'
    'set rgb  52   0 226 254'
    'set rgb  53   0 238 254'
    'set rgb  54   0 246 254'
    'set rgb  55   0 254 254'
    'set rgb  56   7 254 246'
    'set rgb  57  19 254 234'
    'set rgb  58  31 254 222'
    'set rgb  59  39 254 214'
    'set rgb  60  51 254 202'
    'set rgb  61  59 254 194'
    'set rgb  62  71 254 181'
    'set rgb  63  79 254 174'
    'set rgb  64  91 254 162'
    'set rgb  65 103 254 150'
    'set rgb  66 111 254 142'
    'set rgb  67 123 254 130'
    'set rgb  68 130 254 123'
    'set rgb  69 142 254 111'
    'set rgb  70 154 254  99'
    'set rgb  71 162 254  91'
    'set rgb  72 174 254  79'
    'set rgb  73 182 254  71'
    'set rgb  74 194 254  59'
    'set rgb  75 202 254  51'
    'set rgb  76 214 254  39'
    'set rgb  77 226 254  27'
    'set rgb  78 234 254  19'
    'set rgb  79 246 254   7'
    'set rgb  80 254 254   0'
    'set rgb  81 254 242   0'
    'set rgb  82 254 230   0'
    'set rgb  83 254 222   0'
    'set rgb  84 254 210   0'
    'set rgb  85 254 202   0'
    'set rgb  86 254 190   0'
    'set rgb  87 254 178   0'
    'set rgb  88 254 170   0'
    'set rgb  89 254 158   0'
    'set rgb  90 254 150   0'
    'set rgb  91 254 138   0'
    'set rgb  92 254 130   0'
    'set rgb  93 254 119   0'
    'set rgb  94 254 107   0'
    'set rgb  95 254  99   0'
    'set rgb  96 254  87   0'
    'set rgb  97 254  79   0'
    'set rgb  98 254  67   0'
    'set rgb  99 254  55   0'
    'set rgb 100 254  47   0'
    'set rgb 101 254  35   0'
    'set rgb 102 254  27   0'
    'set rgb 103 254  15   0'
    'set rgb 104 254   7   0'
    'set rgb 105 249   0   0'
    'set rgb 106 236   0   0'
    'set rgb 107 227   0   0'
    'set rgb 108 214   0   0'
    'set rgb 109 205   0   0'
    'set rgb 110 192   0   0'
    'set rgb 111 179   0   0'
    'set rgb 112 170   0   0'
    'set rgb 113 157   0   0'
    'set rgb 114 148   0   0'
    'set rgb 115 135   0   0'
    'set rgb 116 130   0   0'
    
    'set rgb 199   0   0   0'
    
    return

     

    • Library_For_Creating_Colorbar_From_ASCII_Format.gs

    function colorbar (args)
    
    vert=subwrd(args,1)
    xmid=subwrd(args,2)
    ymid=subwrd(args,3)
    barw=subwrd(args,4)
    sfc=subwrd(args,5)
    xsiz=subwrd(args,6)
    ysiz=subwrd(args,7)
    col1=subwrd(args,8)
    col2=subwrd(args,9)
    val1=subwrd(args,10)
    val2=subwrd(args,11)
    cl1=subwrd(args,12)
    cl2=subwrd(args,13)
    cli=subwrd(args,14)
    
    dum2=cli
    if (cli<0) ;dum2=cli*-1;endif
    dum1=cl2-cl1
    if (cl1>cl2);dum1=cl1-cl2;endif
    blnum=dum1/dum2+1
    
    * col1 & col2 : should be determined when dot-alb.f
    *               (min and max # of color scale) 
    * val1 & val2 : actual maginitude corresponding colors, col1 & col2
    *   if you set alb=0 to col#=40, and set alb=1.0 to col#=85, then
    *      val1=0, val2=1, col1=40, col2=85
    * cl1=val1, cl2=val2, I will change later, 
    * cli=interval of # under colorbar
    
    cnum=col2-col1+1
    
      stroff=0.05*sfc
      strxsiz=0.12*sfc
      strysiz=0.13*sfc
    
    *
    *	logic for setting the bar orientation with user overides
    *
        if(vert = 0) ; vchk = 0 ; endif
        if(vert = 1) ; vchk = 1 ; endif
    *
    *	vertical bar
    *
    
      if (vchk = 1 )
    
        ywid = ysiz / cnum
        xl = xmid - barw/2
        xr = xmid + barw/2
        yb = ymid-ysiz/2
        y1 = yb
        vert = 1
    
      else
    
    *
    *	horizontal bar
    *
    
        xwid = xsiz / cnum
        yt = ymid + barw/2
        yb = ymid - barw/2
        xl = xmid-xsiz/2
        x1 = xl
        'set string 1 tc 5'
        vert = 0
      endif
    
    *
    *  Plot colorbar
    *
      num = 1
      while (num<=cnum) 
        col = col1-1+num
        if (vert) 
          yt = yb + ywid
        else 
          xr = xl + xwid
        endif
    
        'set line 'col
        'draw recf 'xl' 'yb' 'xr' 'yt
    
        num = num + 1
        if (vert); yb = yt;
        else; xl = xr; endif;
      endwhile
    
     bli = 1
    
      'set strsiz 'strxsiz' 'strysiz
          if (vert)
            'set string 1 l 5'
             cl = cl1
             yp=y1 + ywid
             xp=xr+stroff
             yd = (ysiz - 2*ywid)/dum1*dum2
            while (bli <= blnum)
            'draw string 'xp' 'yp' 'cl
             cl = cl + cli
             yp = yp + yd
             bli=bli+1
            endwhile
          else
            'set string 1 tc 5'
             xp=x1 + xwid
             cl = cl1
             yp=yb-stroff
             xd = (xsiz - 2*xwid)/dum1*dum2
           while (bli <= blnum)
            'draw string 'xp' 'yp' 'cl
             cl = cl + cli
             xp = xp + xd
             bli=bli+1
            endwhile
          endif
    
    return

     

    • mapPoint.ctl

    DSET   ^mapPoint.bin
    OPTIONS little_endian
    UNDEF  -2.56E33
    TITLE 5 Days of Sample Model Output
    XDEF 72 LINEAR  -180 6.0
    YDEF 45 LINEAR  -86.0 4.0
    ZDEF 1 LEVELS 1000
    TDEF 12 LINEAR JAN1987 1mo
    VARS 1
    	t     0   99   Surface Pressure
    ENDVARS

     

    • mapPoint.bin

    mapPoint.bin
    2.27MB

     

    [전체]

    • RunShell.sh

    #!/bin/bash
    
    # [Run Shell]
    # bash RunShell.sh 
    # bash RunShell.sh > LOG/Run_$(date +"%Y%m%d").log 
    
    #================================================
    # Function
    #===============================================
    source ~/.DefaultCommon.sh
    
    #------------------
    # Log Level Print
    #------------------
    # silent ""
    # notify ""
    # ok ""
    # warn ""
    # info ""
    # debug ""
    # error ""
    # crit ""
    
    #------------------
    # Exit Code Check
    #------------------
    # fnCheckWarn "$?"
    # fnCheckExit "$?"
    
    #===============================================
    # Config
    #===============================================
    
    pid=$(echo $$)
    presentYmd=$(date +"%Y%m%d")
    # echo "pid : " $pid
    # echo "presentTime : " $presentTime
    
    contextPath=$(pwd)
    logPath=$contextPath/LOG
    inpPath=$contextPath/INPUT
    outPath=$contextPath/OUTPUT
    imgPath=$contextPath/IMG
    tmpPath=$contextPath/TMP
    
    if [ ! -d $logPath ]; then mkdir -p $logPath; fi
    if [ ! -d $inpPath ]; then mkdir -p $inpPath; fi
    if [ ! -d $outPath ]; then mkdir -p $outPath; fi
    if [ ! -d $imgPath ]; then mkdir -p $imgPath; fi
    if [ ! -d $tmpPath ]; then mkdir -p $tmpPath; fi
    
    libPath=/usr/local/grads-2.1.1.b0/lib
    mapPath=/usr/local/grads-2.1.1.b0/map
    
    logPathName=$logPath/Run_${presentYmd}.log
    
    #================================================
    # Data Preprocessing
    #================================================
    info "======================== [START] Run Shell ======================================"
    
    cat $inpPath/sst.txt | sed -e "s/,/ /g" > $inpPath/sstL1.txt
    
    #================================================
    # Template
    #================================================
    # set Val
    # Fortran
    cat > makeTextToBin.f90 << EOF
          ! implicit none
    
          character(8) :: sta
          integer(4) :: flag, lev, alt, year, month
          real(4) :: lat, lon, val, time
          integer(4) :: div, colNum
          real :: setMin, setMax
    
          open(8, file="$inpPath/sstL1.txt")
          
    
          ! Header Info
          read(8, *)
    
          colMin = 16
          colStart = 17
          colEnd = 199
          colDiv = 90
          setMin = 0
          setMax = 30
    
          do
             read(8, *, end=999) sta, lon, lat, val
    
             if (sta /= "%dtYmd") cycle
             if (val < 0) cycle
    
             if (val < setMin) then
                colNum = 16
             else if (val > setMax) then
                colNum = 199
             else
                colNum = colStart + ((val - setMin) / (setMax - setMin) * colDiv)
             endif
    
             write(99, *) lat, lon, val, colNum
          enddo
    
    999   stop
          end
    EOF
    
    # GrADS
    cat > makePlotUsingGrADS.exec << EOF
       reinit
       ${libPath}/xopen.gs mapPoint.ctl
    
       set display color white
       set cmin 10000
       set mpdraw off
    
       set parea 0 11.0 1.5 8.0
       set xlopts 1 6 0.18
       set ylopts 1 6 0.18
    
       set lat 28 40
       set lon 120 136
       set xlint 4
       set ylint 4
       set font 0
    
       set grads off
       set grid off
    
       set gxout shaded
       set csmooth on
    
       d t
    
       Library_For_Mapping_ASCII_Format.gs fort.99 1 2 3 4
       Library_For_Creating_Colorbar_From_ASCII_Format.gs   0  5.5  0.5   0.25 1.2   8.0 1.0  17 116 0 30 0 30 3
    
       set rgb 116 0 0 0   
       draw shp ${mapPath}/gshhg-shp-2.3.4/GSHHS_shp/f/GSHHS_f_L1.shp
    
       draw title %dtBdY
       set string 1 tc
       set strsiz 0.18 0.18
       draw string 5.5 1.05 Sea Surface Temperature [C]
    
    *   gxprint ${imgPath}/%imgPathName.png
       
       ${libPath}/save.gs ${imgPath}/%imgPathName -background white
       !convert -trim -density 600 -rotate 90 ${imgPath}/%imgPathName.eps ${imgPath}/%imgPathName.png
       !rm -f ${imgPath}/%imgPathName.eps
    
       quit
    EOF
    
    #===============================================
    # Run
    #===============================================
    
    setDate="2019-01-01"
    
    dtDateList=$(seq 0 1 30 | xargs -I {} date -d "${setDate} {} days" +"%Y-%m-%d")
    # dtDateList=$(seq 0 1 0 | xargs -I {} date -d "${setDate} {} days" +"%Y-%m-%d")
    
    for getDate in $dtDateList; do
       dtYmd=$(date -d "${getDate}" +"%Y%m%d")
       dtBdY=$(date -d "${getDate}" +"%B %d, %Y")
       imgPathName=Image_${dtYmd}
       # imgPathName=Print_Image_${dtYmd}
       
       debug ">>>>> [CHECK] getDate : $getDate <<<<<"
       
       # Fortran
       debug "[START] Run Fortran"
       
       cat makeTextToBin.f90 \
          | sed -e "s/%dtYmd/${dtYmd}/g" \
          > $tmpPath/tmp.f90
       
       gfortran $tmpPath/tmp.f90
       fnCheckWarn "$?"
       
       ./a.out
       fnCheckWarn "$?"
    
       debug "[END] Run Fortran"
    
       # GrADS
       debug "[START] Run GrADS"
    
       cat makePlotUsingGrADS.exec \
          |  sed -e "s/%dtBdY/${dtBdY}/g" \
                 -e "s/%imgPathName/${imgPathName}/g" \
          > $tmpPath/tmp.exec
    
       grads -blc "exec $tmpPath/tmp.exec" > $logPathName 2>&1 
       fnCheckWarn "$?"
    
       debug "[END] Run GrADS"
    
      done
    
    info "======================== [END]   Run Shell ======================================"

     

     

     참고 문헌

    [논문]

    • 없음

    [보고서]

    • 없음

    [URL]

    • 없음

     

     문의사항

    [기상학/프로그래밍 언어]

    • sangho.lee.1990@gmail.com

    [해양학/천문학/빅데이터]

    • saimang0804@gmail.com

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

    본 블로그는 파트너스 활동을 통해 일정액의 수수료를 제공받을 수 있음
    반응형
    • 네이버 블러그 공유하기
    • 네이버 밴드에 공유하기
    • 페이스북 공유하기
    • 카카오스토리 공유하기