123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524 |
- !#######################################################################
- !
- #define TRACEBACK write (gol,'("in ",a," (",a,", line",i5,")")') rname, __FILE__, __LINE__; call goErr
- #define IF_NOTOK_RETURN(action) if (status/=0) then; TRACEBACK; action; return; end if
- #define IF_ERROR_RETURN(action) if (status >0) then; TRACEBACK; action; return; end if
- !
- !#######################################################################
- module file_grib_gribex
- use GO, only : gol, goErr, goPr
-
- implicit none
- ! --- in/out -------------------------------
- private
- public :: TGribFile
- public :: Init, Done, Opened
-
- public :: Clear
- public :: CopySections, CopyAllSections
- public :: Get
- public :: Check
- public :: Set
-
- public :: ReadRecord
-
- ! public :: pidname, pidmax
- ! public :: pid_T
- ! public :: pid_Q
- ! public :: pid_U, pid_V, pid_W
- ! public :: pid_SP, pid_LNSP
- ! public :: pid_VO, pid_D
- ! public :: pid_Z, pid_LSM
- ! public :: pid_SR, pid_AL, pid_LSRH
- ! public :: pid_SLHF
- ! public :: pid_CLWC, pid_CIWC, pid_CC
- ! --- const ------------------------------
-
- character(len=*), parameter :: mname = 'file_grib_gribex'
-
-
- ! ! *** Type of level (Code Table 3)
- !
- ! integer, parameter :: levtype_sfc = 1 ! ground or water surface
- ! integer, parameter :: levtype_hyb = 109 ! hybrid level
- ! integer, parameter :: levtype_land = 112 ! layer below surface
- !
- ! ! *** parameter identifier (Code Table 2)
- !
- ! ! o numbers
- !
- ! integer, parameter :: pid_Z = 129 ! geopotential (orography)
- ! integer, parameter :: pid_T = 130 ! temperature
- ! integer, parameter :: pid_U = 131 ! u-velocity
- ! integer, parameter :: pid_V = 132 ! v-velocity
- ! integer, parameter :: pid_Q = 133 ! specific humidity
- ! integer, parameter :: pid_SP = 134 ! surface pressure
- ! integer, parameter :: pid_W = 135 ! vertical velocity
- !
- ! integer, parameter :: pid_VO = 138 ! vorticity
- !
- ! integer, parameter :: pid_SLHF = 147 ! surface latent heat flux (W m**-2 s)
- !
- ! integer, parameter :: pid_LNSP = 152 ! ln surface pressure
- !
- ! integer, parameter :: pid_D = 155 ! divergence
- !
- ! integer, parameter :: pid_LSM = 172 ! land sea mask
- ! integer, parameter :: pid_SR = 173 ! Surface roughness m
- ! integer, parameter :: pid_AL = 174 ! Albedo (0-1)
- !
- ! integer, parameter :: pid_LSRH = 234 ! Logarithm of SR length for heat
- !
- ! integer, parameter :: pid_CLWC = 246 ! cloud liquid water content
- ! integer, parameter :: pid_CIWC = 247 ! cloud ice water content
- ! integer, parameter :: pid_CC = 248 ! cloud cover
- !
- ! ! o maximum number
- ! integer, parameter :: pidmax = 260
- !
- ! ! o names
- !
- ! character(len=4), parameter :: pidname(pidmax) = (/ &
- ! 'a ','b ','c ','d ','e ','f ','g ','p008','p009','p010', &
- ! 'p011','p012','p013','p014','p015','p016','p017','p018','p019','p020', &
- ! 'p021','p022','p023','p024','p025','p026','p027','p028','p029','p030', &
- ! 'p031','p032','p033','p034','p035','p036','p037','p038','p039','p040', &
- ! 'p041','p042','p043','p044','p045','p046','p047','p048','p049','p050', &
- ! 'p051','p052','p053','p054','p055','p056','p057','p058','p059','p060', &
- ! 'p061','p062','p063','p064','p065','p066','p067','p068','p069','p070', &
- ! 'p071','p072','p073','p074','p075','p076','p077','p078','p079','p080', &
- ! 'p081','p082','p083','p084','p085','p086','p087','p088','p089','p090', &
- ! 'p091','p092','p093','p094','p095','p096','p097','p098','p099','p100', &
- ! 'p101','p102','p103','p104','p105','p106','p107','p108','p109','p110', &
- ! 'p111','p112','p113','p114','p115','p116','p117','p118','p119','p120', &
- ! 'p121','p122','p123','p124','p125','p126','p127','p128','Z ','T ', &
- ! 'U ','V ','Q ','SP ','W ','p136','p137','VO ','p139','p140', &
- ! 'SD ','LSP ','CP ','SF ','p145','SSHF','SLHF','p148','p149','p150', &
- ! 'p151','LNSP','p153','p154','D ','zg ','pw ','pu ','pv ','sp ', &
- ! 'eu ','du ','dk ','ed ','dd ','p166','T2M ','D2M ','p169','p170', &
- ! 'p171','LSM ','SR ','AL ','p175','SSR ','p177','p178','p179','EWSS', &
- ! 'NSSS','p182','p183','p184','p185','p186','p187','p188','p189','clb ', &
- ! 'clt ','clfs','p193','p194','p195','p196','p197','SRC ','p199','p200', &
- ! 'p201','p202','p203','p204','p205','p206','p207','p208','p209','p210', &
- ! 'p211','p212','p213','p214','p215','p216','p217','p218','p219','p220', &
- ! 'p221','p222','p223','p224','p225','p226','p227','p228','p229','p230', &
- ! 'p231','p232','p233','LSRH','p235','p236','p237','p238','p239','p240', &
- ! 'p241','p242','p243','p244','p245','CLWC','CIWC','CC ','cco ','ccu ', &
- ! 'p251','p252','p253','p254','p255','p256','p257','p258','p259','p260' /)
- !
- ! ! *** data representation type (Code Table 6)
- !
- ! integer, parameter :: gridtype_ll = 0
- ! integer, parameter :: gridtype_gg = 4
- ! integer, parameter :: gridtype_sh = 50
-
- ! --- types -------------------------------
- type TGribFile
- integer :: fu
- character(len=256) :: fname
- ! *** buffer for grib message
- integer :: inbuff_bytes ! length of input buffer
- ! Section 0 - Indicator Section.
- integer :: isec0(2)
- ! Section 1 - Product Definition Section.
- integer :: isec1(512)
- ! Section 2 - Grid Description Section.
- integer :: isec2(512)
- real :: rsec2(512)
- ! Section 3 - ??
- integer :: isec3(2)
- real :: rsec3(2)
- ! Section 4 - Binary Data Section.
- integer :: isec4(512)
- real, pointer :: rsec4(:)
- !
- integer :: kword
- end type TGribFile
- ! --- interfaces ---------------------------
- interface Init
- module procedure gribfile_Init
- end interface
- interface Done
- module procedure gribfile_Done
- end interface
-
- interface Opened
- module procedure gribfile_Opened
- end interface
-
- interface ReadRecord
- module procedure gribfile_ReadRecord
- end interface
-
- interface Clear
- module procedure gribfile_Clear
- end interface
-
- interface CopySections
- module procedure gribfile_CopySections
- end interface
-
- interface CopyAllSections
- module procedure gribfile_CopyAllSections
- end interface
-
- interface Get
- module procedure gribfile_Get
- end interface
- interface Check
- module procedure gribfile_Check
- end interface
-
- interface Set
- module procedure gribfile_Set
- end interface
-
- CONTAINS
- ! =================================================================
- ! Open gribfile.
- !
- ! USAGE
- ! call Init( gribfile, 'input.gb', 'r'|'w' )
- !
- ! DESCRIPTION
- ! Interface around routine 'pbOpen'.
- ! In 'gribfile', space is allocated to store grib sections.
- !
- subroutine gribfile_Init( F, file, mode, status )
- ! --- in/out -----------------------
- type(TGribFile), intent(out) :: F
- character(len=*), intent(in) :: file
- character(len=*), intent(in) :: mode
- integer, intent(out) :: status
-
- ! --- const ------------------------
-
- character(len=*), parameter :: rname = mname//', gribfile_Init'
- ! --- local ------------------------
- ! dummy buffer of insufficient length:
- integer :: inbuff(10)
- ! --- begin ------------------------
- ! *** initialize grib sections
- ! Section 0 - Indicator Section.
- F%isec0 = 0
- ! Section 1 - Product Definition Section.
- F%isec1 = 0
- ! Section 2 - Grid Description Section.
- F%isec2 = 0
- F%rsec2 = 0.0
- ! Section 3 - ??
- F%isec3 = 0
- F%rsec3 = 0.0
- ! Section 4 - Binary Data Section.
- F%isec4 = 0
- nullify( F%rsec4 )
- F%kword = 0
- ! *** Open specified file with requested name.
-
- ! A free file unit seems to be assigned in pbOpen.
- call pbOpen( F%fu, file, mode, status )
- if ( status /= 0 ) then
- write (gol,'("from pbOpen:")'); call goErr
- select case ( status )
- case (-1)
- write (gol,'(" could not open file")'); call goErr
- case (-2)
- write (gol,'(" invalid file name")') ; call goErr
- case (-3)
- write (gol,'(" invalid open mode")'); call goErr
- case default
- write (gol,'(" unknown return status: ",i6)') status; call goErr
- end select
- write (gol,'(" file: ",a)') trim(file); call goErr
- TRACEBACK; status=1; return
- end if
- ! save filename
- F%fname = file
- select case ( mode )
-
- case ( 'r' )
-
- ! Determine length of records ('messages' in grib context);
- ! open with insufficient buffer, and check error messages:
-
- status = 1 ! force return even if error occures
- call pbGrib( F%fu, inbuff, size(inbuff)*kind(inbuff), F%inbuff_bytes, status )
- select case ( status )
- case ( 0)
- ! no error ?
- write (gol,'("tried to read record into buffer with insuficient length,")'); call goErr
- write (gol,'("but no error occured ...")'); call goErr
- TRACEBACK; status=1; return
- case (-1)
- write (gol,'("end-of-file is hit before a GRIB product is read")'); call goErr
- TRACEBACK; status=1; return
- case (-3)
- ! size of input buffer was not sufficient (as expected)
- case default
- write (gol,'("unknown return status from pbGrib : ",i6)') status; call goErr
- TRACEBACK; status=1; return
- end select
- ! adhoc increment (sometimes first record is very different form others)
- F%inbuff_bytes = F%inbuff_bytes*2
- ! Close file:
- call pbClose( F%fu, status )
- if ( status /= 0 ) then
- write (gol,'("error in call to pbClose; status=",i6)') status; call goErr
- TRACEBACK; status=1; return
- end if
- ! Reopen file:
- call pbOpen( F%fu, file, mode, status )
- if ( status /= 0 ) then
- write (gol,'("from second open; status=",i6)') status; call goErr
- TRACEBACK; status=1; return
- end if
-
- case ( 'w' )
-
- ! nothing special
-
- case default
-
- write (gol,'(" unknown mode `",a,"`")') mode; call goErr
- TRACEBACK; status=1; return
-
- end select
- end subroutine gribfile_Init
- ! ===
- ! Close gribfile, clear buffers
- !
- ! USAGE
- ! call Done( gribfile )
- !
- ! DESCRIPTION
- ! Interface around routine 'pbClose'.
- !
- subroutine gribfile_Done( F, status )
- ! --- in/out -----------------------
- type(TGribFile), intent(inout) :: F
- integer, intent(inout) :: status
- ! --- const ------------------------
-
- character(len=*), parameter :: rname = mname//', gribfile_Done'
- ! --- begin ------------------------
- ! close file:
- call pbClose( F%fu, status )
- if ( status /= 0 ) then
- write (gol,'("from closing grib file:")'); call goErr
- write (gol,'(" status : ",i6)') status; call goErr
- write (gol,'(" file : ",a)') trim(F%fname); call goErr
- TRACEBACK; status=1; return
- end if
-
- ! clear section 4 :
- if (associated(F%rsec4)) deallocate( F%rsec4 )
-
- end subroutine gribfile_Done
- ! ===
-
-
- ! Grib file opened ?
-
- logical function gribfile_Opened( gribfile )
-
- ! --- in/out ------------------------------
-
- type(TGribFile), intent(in) :: gribfile
-
- ! --- begin -------------------------
-
- inquire( unit=gribfile%fu, opened=gribfile_Opened )
- end function gribfile_Opened
-
- ! =============================================================
- subroutine gribfile_CopySections( gribIn, gribOut, status )
-
- ! ---in/out ------------------------------
-
- type(TGribFile), intent(in) :: gribIn
- type(TGribFile), intent(out) :: gribOut
- integer, intent(inout) :: status
- ! --- begin -------------------------
-
- !gribOut%isec0 = gribIn%isec0
- gribOut%isec1 = gribIn%isec1
- gribOut%isec2 = gribIn%isec2
- gribOut%rsec2 = gribIn%rsec2
- gribOut%isec3 = gribIn%isec3
- gribOut%isec4 = gribIn%isec4
-
- ! ok
- status = 0
- end subroutine gribfile_CopySections
- ! ***
- subroutine gribfile_CopyAllSections( gribIn, gribOut )
-
- ! ---in/out ------------------------------
-
- type(TGribFile), intent(in) :: gribIn
- type(TGribFile), intent(out) :: gribOut
- integer, intent(inout) :: status
-
- ! --- begin -------------------------
-
- !gribOut%isec0 = gribIn%isec0
- gribOut%isec1 = gribIn%isec1
- gribOut%isec2 = gribIn%isec2
- gribOut%rsec2 = gribIn%rsec2
- gribOut%isec3 = gribIn%isec3
- gribOut%isec4 = gribIn%isec4
- if ( associated(gribOut%rsec4) ) then
- if ( size(gribOut%rsec4) /= size(gribIn%rsec4) ) then
- deallocate( gribOut%rsec4 )
- allocate( gribOut%rsec4(size(gribIn%rsec4)) )
- end if
- else
- allocate( gribOut%rsec4(size(gribIn%rsec4)) )
- end if
- gribOut%rsec4 = gribIn%rsec4
-
- ! ok
- status = 0
- end subroutine gribfile_CopyAllSections
- ! ***
- subroutine gribfile_Clear( F )
- ! --- in/out -----------------------
- type(TGribFile), intent(out) :: F
- integer, intent(inout) :: status
-
- ! --- begin ------------------------
-
- ! Section 0 - Indicator Section.
- F%isec0 = 0
- ! Section 1 - Product Definition Section.
- F%isec1 = 0
- ! Section 2 - Grid Description Section.
- F%isec2 = 0
- F%rsec2 = 0.0
- ! Section 3 - ??
- F%isec3 = 0
- F%rsec3 = 0.0
- ! Section 4 - Binary Data Section.
- F%isec4 = 0
- if ( associated(F%rsec4) ) F%rsec4 = 0.0
- ! default number of bits
- F%isec4(2) = 24
- F%kword = 0
- ! ok
- status = 0
- end subroutine gribfile_Clear
- ! ==================================================================
-
- ! USAGE
- ! call ReadRecord( gribfile [,debug=0|1] [,status=status] )
- !
- ! DESCRIPTION
- ! Reads next grib record in buffers.
- !
- ! RETURN STATUS
- ! 0 : no error
- ! 1 : eof
- ! 2 : some error
- ! Execution might stop if other errors are encountered.
- !
-
- subroutine gribfile_ReadRecord( F, status )
- ! --- in/out -------------------------
- type(TGribFile), intent(inout) :: F
- integer, intent(out) :: status
-
- ! --- const --------------------------
-
- character(len=*), parameter :: rname = mname//'/grib_ReadRecord'
- ! --- local --------------------------
-
- integer, allocatable :: inbuff(:)
- integer :: length, len4
-
- ! --- begin --------------------------
- ! allocate array to store packed data:
- allocate( inbuff(ceiling(F%inbuff_bytes*1.0/kind(inbuff))) )
- ! read record:
- call pbGrib( F%fu, inbuff, size(inbuff)*kind(inbuff), length, status )
- select case ( status )
- case ( 0)
- ! no error !
- case (-1)
- write (gol,'("end-of-file is hit before a GRIB product is read")') ; call goErr
- write (gol,'(" grib file : ",a)') F%fname ; call goErr
- TRACEBACK; status=1; return
- case (-3)
- ! size of input buffer is not sufficient for the GRIB product !
- write (gol,'("size of input buffer is not sufficient for the GRIB product:")') ; call goErr
- write (gol,'(" current size : ",i8)') size(inbuff)*kind(inbuff) ; call goErr
- write (gol,'(" required : ",i8)') length ; call goErr
- write (gol,'(" grib file : ",a)') F%fname ; call goErr
- TRACEBACK; status=2; return
- case default
- write (gol,'("unknown return status from pbGrib : ",i6)') status ; call goErr
- write (gol,'(" grib file : ",a)') F%fname ; call goErr
- write (gol,'("in ",a)') rname ; call goErr
- TRACEBACK; status=2; return
- end select
- ! Decode.
- ! The array to hold the unpacked data may need to be 4 times
- ! as long as that for the packed data (or more!).
- len4 = ceiling(4*F%inbuff_bytes*1.0/kind(F%rsec4))
- if ( associated(F%rsec4) ) then
- if ( size(F%rsec4) < len4 ) then
- deallocate( F%rsec4 )
- allocate( F%rsec4(len4) )
- end if
- else
- allocate( F%rsec4(len4) )
- end if
- call GribEx(F%isec0,F%isec1,F%isec2,F%rsec2,F%isec3,F%rsec3,&
- F%isec4, F%rsec4, size(F%rsec4)*kind(F%rsec4), &
- inbuff, size(inbuff), F%kword, 'D' , status )
- if ( status /= 0 ) then
- select case ( status )
- case (-6)
- write (gol,'("in call to GribEx : ")'); call goErr
- write (gol,'(" found pseudo data in grib file: ",a)') F%fname; call goErr
- TRACEBACK; status=2; return
- case default
- write (gol,'("unknown return status from GribEx : ",i6)') status; call goErr
- TRACEBACK; status=2; return
- end select
- end if
-
- ! clear input buffer:
- deallocate( inbuff )
-
- ! ok
- status = 0
-
- end subroutine gribfile_ReadRecord
- ! ***
-
-
- ! encode and write grib sections
- subroutine gribfile_WriteRecord( F, status )
-
- ! --- in/out --------------------
-
- type(TGribFile), intent(in) :: F
- integer, intent(out) :: status
- ! --- const ---------------------
-
- character(len=*), parameter :: rname = mname//'/gribfile_WriteRecord'
-
- ! --- local ---------------------
-
- integer, allocatable :: outbuff(:)
-
- ! --- begin ---------------------
- ! *** encode
-
- status = 1
- allocate( outbuff(size(F%rsec4)) )
- call GribEx(F%isec0,F%isec1,F%isec2,F%rsec2,F%isec3,F%rsec3,&
- F%isec4, F%rsec4, size(F%rsec4)*kind(F%rsec4), &
- outbuff, size(outbuff), F%kword, 'C' , status )
- select case ( status )
- case (-2)
- write (gol,'("WARNING: bitmap was encountered with all bits set to 1")'); call goPr
- case (-3)
- write (gol,'("WARNING: predefined bitmap was encountered.")'); call goPr
- case (-4)
- write (gol,'("WARNING: bitmap was encountered.")'); call goPr
- case (-5)
- write (gol,'("WARNING: bitmap was encountered and the data has not been decoded.")'); call goPr
- case (-6)
- write (gol,'("WARNING: ECMWF pseudo-GRIB data (TIDE or BUDG) has been encountered.")'); call goPr
- case ( 0 )
- ! ok
- case default
- write (gol,'("unknown status from GribEx : ",i6)') status
- TRACEBACK; status=1; return
- end select
- ! *** write GRIB record
- ! PBWRITE: Writes a block of bytes to a file.
- ! status : -1 = Could not write to file.
- ! >= 0 = Number of bytes written.
- !
- call pbWrite( F%fu, outbuff, F%isec0(1), status )
- if ( status == -1 ) then
- write (gol,'("could not write to file")'); call goErr
- write (gol,'("in ",a)') rname; status=1; return
- else if ( status >= 0 ) then
- ! bytes written correctly
- else
- write (gol,'("unknown status from GribEx : ",i6)') status; call goErr
- write (gol,'("in ",a)') rname; status=1; return
- end if
-
- ! done
- deallocate( outbuff )
-
- ! ok
- status = 0
- end subroutine gribfile_WriteRecord
-
- ! ============================================================
- ! Extract data from grib sections.
- ! Optional arguments are passed to read parameter id, date, etc.
- ! If the same option is preceded by 'check_', an error
- ! message is written if the grib file does not match
- !
- ! pid : parameter identifier (integer number)
- !
- ! level : index of hybride level
- !
- ! reftime : 5 element integer array : yy, mm, dd, hh, min
- ! timerange : 4 element ingeger array : unit, val1, val2, indicator
- !
- subroutine gribfile_Get( F, status, &
- model_id, pid, pidShortName, &
- levtype, level, nlev, hyb_a, hyb_b, &
- reftime, timerange, &
- gridtype, &
- ll, &
- lon_first, lon_last, lon_inc, lon_n, &
- lat_first, lat_last, lat_inc, lat_n, &
- T, sh, &
- N, gg )
- use file_grib_base, only : pidName
- use file_grib_base, only : gridtype_ll, gridtype_gg, gridtype_sh
- ! --- in/out -------------------------
- type(TGribFile), intent(in) :: F
- integer, intent(out) :: status
- integer, intent(out), optional :: model_id
- integer, intent(out), optional :: pid
- character(72), intent(out), optional :: pidShortName
- integer, intent(out), optional :: levtype, level, nlev
- real, intent(out), optional :: hyb_a(:), hyb_b(:)
- integer, intent(out), optional :: reftime(5)
- integer, intent(out), optional :: timerange(4)
- integer, intent(out), optional :: gridtype
- real, intent(out), optional :: lon_first, lon_last, lon_inc
- integer, intent(out), optional :: lon_n
- real, intent(out), optional :: lat_first, lat_last, lat_inc
- integer, intent(out), optional :: lat_n
- real, intent(out), optional :: ll(:,:)
- integer, intent(out), optional :: T
- complex, intent(out), optional :: sh(:)
- integer, intent(out), optional :: N
- real, intent(out), optional :: gg(:)
- ! --- const --------------------------------------
-
- character(len=*), parameter :: name = mname//'/gribfile_Get'
-
- ! --- local --------------------------
-
- integer :: grib_reftime(5)
- integer :: grib_timerange(4)
- integer :: base
- integer :: grib_n
- real, allocatable :: rsec4_adhoc(:)
- ! --- begin --------------------------
-
- ! -- model id
- if ( present( model_id ) ) then
- model_id = F%isec1(3)
- end if
- ! -- parameter
- if ( present( pid ) ) then
- pid = F%isec1(6)
- end if
- ! -- parameter short name
- if ( present( pidShortName ) ) then
- pidShortName = pidName(F%isec1(6))
- end if
- ! -- level
- if ( present(levtype) ) levtype = F%isec1(7)
- if ( present(level ) ) level = F%isec1(8)
- ! -- Vertical Coordinate Parameters
- if ( present(hyb_a) .or. present(hyb_b) ) then
- if ( .not. (present(hyb_a) .and. present(hyb_b)) ) then
- write (gol,'("extract both hybride params or none")'); call goErr
- TRACEBACK; status=1; return
- end if
- if ( F%isec2(12) /= size(hyb_a) + size(hyb_b) ) then
- write (gol,'("numbers of hybride parameters do not match:")') ; call goErr
- write (gol,'(" expected : ",i6)') size(hyb_a)+size(hyb_b) ; call goErr
- write (gol,'(" found : ",i6)') F%isec2(12) ; call goErr
- TRACEBACK; status=1; return
- end if
- base = 10 ; hyb_a = F%rsec2(base+1:base+size(hyb_a))
- base = 10+size(hyb_a); hyb_b = F%rsec2(base+1:base+size(hyb_b))
- end if
-
- ! number of levels
- if ( present(nlev) ) then
- nlev = F%isec2(12)/2 - 1
- end if
- ! -- reference time
- if ( present(reftime) ) then
- ! extract reference time:
- ! extract reference time:
- grib_reftime(1) = (F%isec1(21)-1)*100 + F%isec1(10) ! year incl. century
- grib_reftime(2) = F%isec1(11) ! month
- grib_reftime(3) = F%isec1(12) ! day
- grib_reftime(4) = F%isec1(13) ! hour
- grib_reftime(5) = F%isec1(14) ! minutes
- reftime = grib_reftime
- end if
- ! -- time range
- if ( present(timerange) ) then
- grib_timerange(1:4) = F%isec1(15:18)
- timerange = grib_timerange
- end if
- ! --- grid
-
- if ( present(gridtype) ) gridtype = F%isec2( 1)
- if ( present(lon_n) ) lon_n = F%isec2( 2)
- if ( present(lat_n) ) lat_n = F%isec2( 3)
- if ( present(lat_first) ) lat_first = F%isec2( 4) / 1000.0
- if ( present(lon_first) ) lon_first = F%isec2( 5) / 1000.0
- if ( present(lat_last) ) lat_last = F%isec2( 7) / 1000.0
- if ( present(lon_last) ) lon_last = F%isec2( 8) / 1000.0
- if ( present(lon_inc) ) lon_inc = F%isec2( 9) / 1000.0
- if ( present(lat_inc) ) lat_inc = F%isec2(10) / 1000.0
- ! -- lat/lon grid
-
- if ( present(ll) ) then
- !call Check( F, gridtype=gridtype_ll )
- ! >>> no recursive call >>>>>>>>>>>>>>
- grib_n = F%isec2(1)
- if ( grib_n /= gridtype_ll ) then
- write (gol,'("grid types do not match:")') ; call goErr
- write (gol,'(" expected : ",i4," (ll)")') gridtype_ll ; call goErr
- write (gol,'(" found : ",i4)') grib_n ; call goErr
- TRACEBACK; status=1; return
- end if
- ! <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
- if ( (size(ll,1)/=F%isec2(2)) .or. (size(ll,2)/=F%isec2(3)) ) then
- write (gol,'("grid sizes do not match:")') ; call goErr
- write (gol,'(" expected : ",i4," x ",i4)') size(ll,1), size(ll,2) ; call goErr
- write (gol,'(" found : ",i4," x ",i4)') F%isec2(2), F%isec2(3) ; call goErr
- TRACEBACK; status=1; return
- end if
- if ( .not. associated(F%rsec4) ) then
- write (gol,'("no grib section 4 read")'); call goErr
- TRACEBACK; status=1; return
- end if
- ll = reshape( F%rsec4(1:size(ll)), shape(ll) )
- end if
- ! -- gaussian lat/lon grid
-
- if ( present(N) ) then
- !call Check( F, gridtype=gridtype_gg )
- ! >>> no recursive call >>>>>>>>>>>>>>
- grib_n = F%isec2(1)
- if ( grib_n /= gridtype_gg ) then
- write (gol,'("grid types do not match:")') ; call goErr
- write (gol,'(" expected : ",i4," (gg)")') gridtype_gg ; call goErr
- write (gol,'(" found : ",i4)') grib_n ; call goErr
- TRACEBACK; status=1; return
- end if
- ! <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
- N = F%isec2(10)
- end if
- if ( present(gg) ) then
- !call Check( F, gridtype=gridtype_gg )
- ! >>> no recursive call >>>>>>>>>>>>>>
- grib_n = F%isec2(1)
- if ( grib_n /= gridtype_gg ) then
- write (gol,'("grid typess do not match:")') ; call goErr
- write (gol,'(" expected : ",i4," (gg)")') gridtype_gg ; call goErr
- write (gol,'(" found : ",i4)') grib_n ; call goErr
- TRACEBACK
- status=1; return
- end if
- ! <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
- if ( size(gg) /= F%isec4(1) ) then
- write (gol,'("gg grid sizes do not match:")') ; call goErr
- write (gol,'(" expected : ",i4)') size(gg) ; call goErr
- write (gol,'(" found : ",i4)') F%isec4(1) ; call goErr
- TRACEBACK; status=1; return
- end if
- ! data present ?
- if ( .not. associated(F%rsec4) ) then
- write (gol,'("no grib section 4 read")'); call goErr
- TRACEBACK; status=1; return
- end if
- gg = F%rsec4(1:size(gg))
- end if
-
- ! -- spectral coef
-
- if ( present(T) ) then
- !call Check( F, gridtype=gridtype_sh )
- ! >>> no recursive call >>>>>>>>>>>>>>
- grib_n = F%isec2(1)
- if ( grib_n /= gridtype_sh ) then
- write (gol,'("grid types do not match:")') ; call goErr
- write (gol,'(" expected : ",i4," (sh)")') gridtype_sh ; call goErr
- write (gol,'(" found : ",i4)') grib_n ; call goErr
- TRACEBACK; status=1; return
- end if
- ! <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
- T = F%isec2(4)
- end if
- if ( present(sh) ) then
- !call Check( F, gridtype=gridtype_sh )
- ! >>> no recursive call >>>>>>>>>>>>>>
- grib_n = F%isec2(1)
- if ( grib_n /= gridtype_sh ) then
- write (gol,'("grid typess do not match:")') ; call goErr
- write (gol,'(" expected : ",i4," (sh)")') gridtype_sh ; call goErr
- write (gol,'(" found : ",i4)') grib_n ; call goErr
- TRACEBACK; status=1; return
- end if
- ! <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
- ! check number of elements; complex is 2 elements !
- if ( size(sh) /= F%isec4(1)/2 ) then
- write (gol,'("numbers of spectral coefficients do not match:")') ; call goErr
- write (gol,'(" expected : ",i6)') size(sh) ; call goErr
- write (gol,'(" found : ",i6)') F%isec4(1)/2 ; call goErr
- TRACEBACK; status=1; return
- end if
- ! convert from real to complex:
- ! >>> NOTE: this call lets 'f90 -C' fail on SUN compiler !
- !sh = transfer( F%rsec4(1:F%isec4(1)), (/(0.0,0.0)/) )
- ! <<< fix >>>
- allocate( rsec4_adhoc(F%isec4(1)) )
- rsec4_adhoc = F%rsec4(1:F%isec4(1))
- sh = transfer( rsec4_adhoc, (/(0.0,0.0)/) )
- deallocate( rsec4_adhoc )
- ! <<<
- end if
- ! ok
- status = 0
- end subroutine gribfile_Get
- ! ===
- ! NOTE
- ! Do not check hybride coeff; different number of bits etc
- ! cause small differences ...
-
- subroutine gribfile_Check( F, status, debug, &
- model_id, pid, &
- levtype, level, &
- reftime, timerange, &
- gridtype, &
- lon_first, lon_last, lon_inc, lon_n, &
- lat_first, lat_last, lat_inc, lat_n, &
- T )
-
- ! --- in/out -------------------------
- type(TGribFile), intent(in) :: F
- integer, intent(out) :: status
- integer, intent(in), optional :: debug
- integer, intent(in), optional :: model_id
- integer, intent(in), optional :: pid
- integer, intent(in), optional :: levtype, level
- !real, intent(in), optional :: hyb_a(:), hyb_b(:)
- integer, intent(in), optional :: reftime(5)
- integer, intent(in), optional :: timerange(4)
- integer, intent(in), optional :: gridtype
- integer, intent(in), optional :: lon_first, lon_last, lon_inc, lon_n
- integer, intent(in), optional :: lat_first, lat_last, lat_inc, lat_n
- integer, intent(in), optional :: T
- ! --- const --------------------------------------
-
- character(len=*), parameter :: name = mname//'/gribfile_Check'
-
- ! --- local --------------------------
- logical :: match
- integer :: grib_model_id
- integer :: grib_pid
- integer :: grib_levtype, grib_level
- integer :: grib_reftime(5)
- integer :: grib_timerange(4)
- integer :: grib_n
- integer :: grib_T
-
- logical :: verbose
- ! --- begin --------------------------
- ! write error messages ?
- verbose = .false.
- if ( present(debug) ) verbose = debug > 0
- ! ok by default
- status = 0
- ! -- check model id
-
- if ( present( model_id ) ) then
- call Get( F, status, model_id=grib_model_id )
- if (status/=0) then
- TRACEBACK; status=1; return
- end if
- if ( grib_model_id /= model_id ) then
- if ( verbose ) then
- write (gol,'("model id''s do not match:")') ; call goErr
- write (gol,'(" expected : ",i4)') model_id ; call goErr
- write (gol,'(" found : ",i4)') grib_model_id ; call goErr
- write (gol,'(" in ",a)') trim(F%fname) ; call goErr
- TRACEBACK
- end if
- status=status+1
- end if
- end if
- ! -- check parameter
- if ( present( pid ) ) then
- call Get( F, status, pid=grib_pid )
- if (status/=0) then
- TRACEBACK ; status=1; return
- end if
- if ( grib_pid /= pid ) then
- if ( verbose ) then
- write (gol,'("parameter id''s do not match:")') ; call goErr
- write (gol,'(" expected : ",i6)') pid ; call goErr
- write (gol,'(" found : ",i6)') grib_pid ; call goErr
- write (gol,'(" in ",a)') trim(F%fname) ; call goErr
- TRACEBACK
- end if
- status=status+1
- end if
- end if
- ! -- check level
- if ( present(levtype) ) then
- call Get( F, status, levtype=grib_levtype )
- if (status/=0) then
- TRACEBACK ; status=1; return
- end if
- if ( grib_levtype /= levtype ) then
- if ( verbose ) then
- write (gol,'("level types do not match:")') ; call goErr
- write (gol,'(" expected : ",i6)') levtype ; call goErr
- write (gol,'(" found : ",i6)') grib_levtype ; call goErr
- write (gol,'(" in ",a)') trim(F%fname) ; call goErr
- TRACEBACK
- end if
- status=status+1
- end if
- end if
- if ( present(level) ) then
- call Get( F, status, level=grib_level )
- if (status/=0) then
- TRACEBACK ; status=1; return
- end if
- if ( grib_level /= level ) then
- if ( verbose ) then
- write (gol,'("levels do not match:")') ; call goErr
- write (gol,'(" expected : ",i6)') level ; call goErr
- write (gol,'(" found : ",i6)') grib_level ; call goErr
- write (gol,'(" in ",a)') trim(F%fname) ; call goErr
- TRACEBACK
- end if
- status=status+1
- end if
- end if
- ! -- check reference time
- ! extract reference time:
- grib_reftime(1) = (F%isec1(21)-1)*100 + F%isec1(10) ! year incl. century
- grib_reftime(2) = F%isec1(11) ! month
- grib_reftime(3) = F%isec1(12) ! day
- grib_reftime(4) = F%isec1(13) ! hour
- grib_reftime(5) = F%isec1(14) ! minutes
- if ( present(reftime) ) then
- if ( any( grib_reftime /= reftime ) ) then
- if ( verbose ) then
- write (gol,'("reference times do not match:")') ; call goErr
- write (gol,'(" expected : ",i4,4i3)') reftime ; call goErr
- write (gol,'(" found : ",i4,4i3)') grib_reftime ; call goErr
- write (gol,'(" in ",a)') trim(F%fname) ; call goErr
- TRACEBACK
- end if
- status=status+1
- end if
- end if
- ! -- check time range
- grib_timerange(1:4) = F%isec1(15:18)
- if ( present(timerange) ) then
- if ( any( grib_timerange /= timerange ) ) then
- if ( verbose ) then
- write (gol,'("time ranges do not match:")') ; call goErr
- write (gol,'(" expected : ",4i3)') timerange ; call goErr
- write (gol,'(" found : ",4i3)') grib_timerange ; call goErr
- write (gol,'(" in ",a)') trim(F%fname) ; call goErr
- TRACEBACK
- end if
- status=status+1
- end if
- end if
- ! --- check grid
- grib_n = F%isec2(1)
- if ( present(gridtype) ) then
- if ( grib_n /= gridtype ) then
- if ( verbose ) then
- write (gol,'("gridtypes do not match:")') ; call goErr
- write (gol,'(" expected : ",i6)') gridtype ; call goErr
- write (gol,'(" found : ",i6)') grib_n ; call goErr
- write (gol,'(" in ",a)') trim(F%fname) ; call goErr
- TRACEBACK
- end if
- status=status+1
- end if
- end if
- grib_n = F%isec2(2)
- if ( present(lon_n) ) then
- if ( grib_n /= lon_n ) then
- if ( verbose ) then
- write (gol,'("number of longitudes do not match:")') ; call goErr
- write (gol,'(" expected : ",i6)') lon_n ; call goErr
- write (gol,'(" found : ",i6)') grib_n ; call goErr
- write (gol,'(" in ",a)') trim(F%fname) ; call goErr
- TRACEBACK
- end if
- status=status+1
- end if
- end if
- grib_n = F%isec2(3)
- if ( present(lat_n) ) then
- if ( grib_n /= lat_n ) then
- if ( verbose ) then
- write (gol,'("number of latitudes do not match:")') ; call goErr
- write (gol,'(" expected : ",i6)') lat_n ; call goErr
- write (gol,'(" found : ",i6)') grib_n ; call goErr
- write (gol,'(" in ",a)') trim(F%fname) ; call goErr
- TRACEBACK
- end if
- status=status+1
- end if
- end if
- grib_n = F%isec2(4)
- if ( present(lat_first) ) then
- if ( grib_n /= lat_first ) then
- if ( verbose ) then
- write (gol,'("first latitudes do not match:")') ; call goErr
- write (gol,'(" expected : ",i6)') lat_first ; call goErr
- write (gol,'(" found : ",i6)') grib_n ; call goErr
- write (gol,'(" in ",a)') trim(F%fname) ; call goErr
- TRACEBACK
- end if
- status=status+1
- end if
- end if
- grib_n = F%isec2(5)
- if ( present(lon_first) ) then
- if ( grib_n /= lon_first ) then
- if ( verbose ) then
- write (gol,'("first longitudes do not match:")') ; call goErr
- write (gol,'(" expected : ",i6)') lon_first ; call goErr
- write (gol,'(" found : ",i6)') grib_n ; call goErr
- write (gol,'(" in ",a)') trim(F%fname) ; call goErr
- TRACEBACK
- end if
- status=status+1
- end if
- end if
- grib_n = F%isec2(7)
- if ( present(lat_last) ) then
- if ( grib_n /= lat_last ) then
- if ( verbose ) then
- write (gol,'("last latitudes do not match:")') ; call goErr
- write (gol,'(" expected : ",i6)') lat_last ; call goErr
- write (gol,'(" found : ",i6)') grib_n ; call goErr
- write (gol,'(" in ",a)') trim(F%fname) ; call goErr
- TRACEBACK
- end if
- status=status+1
- end if
- end if
- grib_n = F%isec2(8)
- if ( present(lon_last) ) then
- if ( grib_n /= lon_last ) then
- if ( verbose ) then
- write (gol,'("last longitudes do not match:")') ; call goErr
- write (gol,'(" expected : ",i6)') lon_last ; call goErr
- write (gol,'(" found : ",i6)') grib_n ; call goErr
- write (gol,'(" in ",a)') trim(F%fname) ; call goErr
- TRACEBACK
- end if
- status=status+1
- end if
- end if
- grib_n = F%isec2(9)
- if ( present(lon_inc) ) then
- if ( grib_n /= lon_inc ) then
- if ( verbose ) then
- write (gol,'("longitude increments do not match:")') ; call goErr
- write (gol,'(" expected : ",i6)') lon_inc ; call goErr
- write (gol,'(" found : ",i6)') grib_n ; call goErr
- write (gol,'(" in ",a)') trim(F%fname) ; call goErr
- TRACEBACK
- end if
- status=status+1
- end if
- end if
- grib_n = F%isec2(10)
- if ( present(lat_inc) ) then
- if ( grib_n /= lat_inc ) then
- if ( verbose ) then
- write (gol,'("latitude increments do not match:")') ; call goErr
- write (gol,'(" expected : ",i6)') lat_inc ; call goErr
- write (gol,'(" found : ",i6)') grib_n ; call goErr
- write (gol,'(" in ",a)') trim(F%fname) ; call goErr
- TRACEBACK ; status=1; return
- end if
- status=status+1
- end if
- end if
- ! --- check truncation
- if ( present(T) ) then
- grib_T = F%isec2(4)
- if ( grib_T /= T ) then
- if ( verbose ) then
- write (gol,'("spectral truncations do not match:")') ; call goErr
- write (gol,'(" expected : ",i6)') T ; call goErr
- write (gol,'(" found : ",i6)') grib_T ; call goErr
- write (gol,'(" in ",a)') trim(F%fname) ; call goErr
- TRACEBACK
- end if
- status=status+1
- end if
- end if
- ! return with status equal to number of failures
- end subroutine gribfile_Check
- ! ===
-
-
- ! fill gribsections
- subroutine gribfile_Set( F, status, model_id, pid, &
- levtype, hyb_a, hyb_b, level, &
- reftime, timerange, &
- gridtype, &
- ll, &
- lon_first, lon_inc, lon_last, lon_n, &
- lat_first, lat_inc, lat_last, lat_n, &
- scanning_mode, nbits )
-
- ! --- in/out ----------------------
-
- type(TGribFile), intent(inout) :: F
- integer, intent(out) :: status
- integer, intent(in), optional :: model_id
-
- integer, intent(in), optional :: pid
- integer, intent(in), optional :: levtype
- integer, intent(in), optional :: level
- real, intent(in), optional :: hyb_a(:), hyb_b(:)
- integer, intent(in), optional :: reftime(5) ! (/yy,mm,dd,hh,min/)
- integer, intent(in), optional :: timerange(4)
- integer, intent(in), optional :: gridtype
- real, intent(in), optional :: ll(:,:)
- integer, intent(in), optional :: lon_n, lat_n
- integer, intent(in), optional :: lon_first, lon_inc, lon_last ! mili degree
- integer, intent(in), optional :: lat_first, lat_inc, lat_last ! mili degree
- integer, intent(in), optional :: scanning_mode
- integer, intent(in), optional :: nbits
- ! --- const --------------------------------------
-
- character(len=*), parameter :: rname = mname//'/gribfile_Set'
- ! --- local ------------------------
-
- integer :: base
-
- ! --- begin ------------------------
- ! Section 1 - Product Definition Section.
- ! ---------------------------------------
-
- ! Code Table 2 Version Number.
- F%isec1(1) = 128
- ! Originating centre identifier.
- F%isec1(2) = 98 ! ECMWF
-
- ! Model identification.
- if ( present(model_id) ) F%isec1(3) = model_id
-
- ! Grid definition.
- F%isec1(4) = 255 ! ???
-
- ! Flag (Code Table 1) 10000000
- F%isec1(5) = 128 ! ???
-
- ! Parameter identifier (Code Table 2, NO LOCAL TABLE FOR KNMI)
- if ( present(pid) ) F%isec1(6) = pid
-
- ! Type of level (Code Table 3). 109 ; hybride
- ! Value 1 of level (Code Table 3). 1
- ! Value 2 of level (Code Table 3). 0
- if ( present(levtype) ) F%isec1(7) = levtype
- if ( present(level ) ) F%isec1(8) = level
- F%isec1(9) = 0
- ! 10. Year of reference time of data.
- ! 11. Month of reference time of data.
- ! 12. Day of reference time of data.
- ! 13. Hour of reference time of data.
- ! 14. Minute of reference time of data.
- ! 21. Century of reference time of data.
- if ( present(reftime) ) then
- F%isec1(21) = int(reftime(1)/100.0) + 1
- F%isec1(10) = mod(reftime(1),100)
- F%isec1(11:14) = reftime(2:5)
- end if
- ! Time unit (Code Table 4).
- ! Time range one.
- ! Time range two.
- ! Time range indicator (Code Table 5)
- if ( present(timerange) ) F%isec1(15:18) = timerange
- ! Number averaged.
- F%isec1(19) = 0
-
- ! Number missing from average.
- F%isec1(20) = 0
-
- ! Section 2 - Grid Description Section.
- ! -------------------------------------
- ! (Southern latitudes and Western longitudes are negative.)
-
- ! 1. Data represent type (Table 6) 0 = lat/long
- if ( present(gridtype) ) F%isec2(1) = gridtype
-
- ! 2. Number of points along a parallel. 144
- ! 3. Number of points along a meridian. 72
- ! 4. Latitude of first grid point. -88750 mdeg
- ! 5. Longitude of first grid point. -180000 mdeg
- ! 6. Resolution and components flag. 10000000
- ! 7. Latitude of last grid point. 88750
- ! 8. Longitude of last grid point. 177500
- ! 9. i direction (East-West) increment. 2500
- ! 10. j direction (North-South) increment. 2500
-
- if ( present(lon_n) .or. present(lon_first) .or. present(lon_last) .or. present(lon_inc) ) then
-
- if ( present(lon_n) ) F%isec2(2) = lon_n
- if ( present(lon_first) ) F%isec2(5) = lon_first
- if ( present(lon_last) ) F%isec2(8) = lon_last
- if ( present(lon_inc) ) F%isec2(9) = lon_inc
-
- if ( present(lon_first) .and. present(lon_last) .and. present(lon_inc) ) then
- ! lon_n
- F%isec2(2) = (lon_last-lon_first)/lon_inc + 1
- else if ( present(lon_n) .and. present(lon_first) .and. present(lon_inc) ) then
- ! lon_last
- F%isec2(8) = lon_first + lon_inc*(lon_n-1)
- else if ( present(lon_n) .and. present(lon_first) .and. present(lon_last) ) then
- ! lon_inc
- F%isec2(9) = (lon_last-lon_first)/lon_n
- else
- write (gol,'("expected at least 3 of lon_n,lon_first,lon_last,lon_inc")'); call goErr
- TRACEBACK; status=1; return
- end if
-
- end if
-
- if ( present(lat_n) .or. present(lat_first) .or. present(lat_last) .or. present(lat_inc) ) then
-
- if ( present(lat_n) ) F%isec2(3) = lat_n
- if ( present(lat_first) ) F%isec2(4) = lat_first
- if ( present(lat_last) ) F%isec2(7) = lat_last
- if ( present(lat_inc) ) F%isec2(10) = lat_inc
-
- if ( present(lat_first) .and. present(lat_last) .and. present(lat_inc) ) then
- ! lat_n
- F%isec2(3) = (lat_last-lat_first)/lat_inc + 1
- else if ( present(lat_n) .and. present(lat_first) .and. present(lat_inc) ) then
- ! lat_last
- F%isec2(7) = lat_first + lat_inc*(lat_n-1)
- else if ( present(lat_n) .and. present(lat_first) .and. present(lat_last) ) then
- ! lat_inc
- F%isec2(10) = (lat_last-lat_first)/lat_n
- else
- write (gol,'("expected at least 3 of lon_n,lon_first,lon_last,lon_inc")'); call goErr
- TRACEBACK; status=1; return
- end if
-
- end if
-
- F%isec2(6) = 128
-
- ! 11. Scanning mode flags (Code Table 8)
- ! bit 1 : 0 = west to east , 1 = east to west
- ! bit 2 : 0 = north to south , 1 = south to north
- ! bit 3 : 0 = store lon rows , 1 = store lat columns
- ! default scanning mode 0
- !F%isec2(11) = 0
- !if ( F%isec2(8) < F%isec2(5) ) F%isec2(11) = F%isec2(11) + 4 ! east to west
- !if ( F%isec2(7) > F%isec2(4) ) F%isec2(11) = F%isec2(11) + 2 ! south to north
- ! PROBLEM >>> GribEx seems to accept scanning mode 0 only ..
- F%isec2(11) = 0
- ! <<<
- if ( present(scanning_mode) ) F%isec2(11) = scanning_mode
-
- ! 12. Number of vertical coordinate parameters.
- ! Vertical Coordinate Parameters strored in rsec2, start in element 11
- if ( present(hyb_a) .and. present(hyb_b) ) then
- F%isec2(12) = size(hyb_a) + size(hyb_b)
- base = 10 ; F%rsec2(base+1:base+size(hyb_a)) = hyb_a
- base = 10+size(hyb_a); F%rsec2(base+1:base+size(hyb_b)) = hyb_b
- end if
-
- ! set rest to zero for safety
- F%isec2(13:size(F%isec2)) = 0
-
- ! Section 4 - Binary Data Section.
- ! -------------------------------------
- ! 1. Number of data values coded/decoded. 11556
- ! 2. Number of bits per data value. 16
- !
- ! 3. Type of data (0=grid pt, 128=spectral). 128
- ! 4. Type of packing (0=simple, 64=complex). 64
- ! 5. Type of data (0=float, 32=integer). 0
- ! 6. Additional flags (0=none, 16=present). 0
- ! 7. Reserved. 0
- ! 8. Number of values (0=single, 64=matrix). 0
- ! 9. Secondary bit-maps (0=none, 32=present). 0
- ! 10. Values width (0=constant, 16=variable). 0
- ! 11. Byte offset of start of packed data (N). 2214
- ! 12. Power (P * 1000). 500
- ! 13. Pentagonal resolution parameter J for subset. 20
- ! 14. Pentagonal resolution parameter K for subset. 20
- ! 15. Pentagonal resolution parameter M for subset. 20
-
- ! set lat/lon grid:
- ! 3. Type of data (0=grid pt, 128=spectral). 0
- ! 4. Type of packing (0=simple, 64=complex). 0
- ! 5. Type of data (0=float, 32=integer). 0
- ! 6. Additional flags (0=none, 16=present). 0
- ! 7. Reserved. 0
- ! 8. Number of values (0=single, 64=matrix). 0
- ! 9. Secondary bit-maps (0=none, 32=present). 0
- ! 10. Values width (0=constant, 16=variable). 0
- if ( present(ll) ) then
-
- ! check grid size:
- if ( F%isec2(2) /= size(ll,1) .or. F%isec2(3) /= size(ll,2) ) then
- write (gol,'("grid sizes do not match:")'); call goErr
- write (gol,'(" expected : ",i4," x ",i4)') size(ll,1), size(ll,2); call goErr
- write (gol,'(" found : ",i4," x ",i4)') F%isec2(2), F%isec2(3); call goErr
- TRACEBACK; status=1; return
- end if
- ! 1. Number of data values coded/decoded. 11556
- F%isec4(1) = size(ll)
- ! 3. Type of data (0=grid pt, 128=spectral). 0
- ! 4. Type of packing (0=simple, 64=complex). 0
- ! 5. Type of data (0=float, 32=integer). 0
- ! 6. Additional flags (0=none, 16=present). 0
- ! 7. Reserved. 0
- ! 8. Number of values (0=single, 64=matrix). 0
- ! 9. Secondary bit-maps (0=none, 32=present). 0
- ! 10. Values width (0=constant, 16=variable). 0
- F%isec4(3:10) = 0
- ! allocate space to store field
- ! NOTE: allocate extra, sometimes errors if fit exately!
- if ( associated(F%rsec4) ) then
- if ( size(F%rsec4) < size(ll) ) then
- deallocate( F%rsec4 )
- allocate( F%rsec4(size(ll)*2) )
- end if
- else
- allocate( F%rsec4(size(ll)*2) )
- end if
-
- ! convert to 1D array:
- F%rsec4(1:size(ll)) = reshape( ll, (/ size(ll) /) )
-
- end if
-
- ! 2. Number of bits per data value. 16
- if ( present(nbits) ) F%isec4(2) = nbits
-
- ! ok
- status = 0
- end subroutine gribfile_Set
- end module file_grib_gribex
-
|