SUBROUTINE CH_BRP2BDY(KNO,KLIST,KSLIST,KMXL 1,9
& ,KMARK,PVAL,PSVAL,KALT,KDBURP,CDSTNID
& ,LDMA,KNELE,KNVAL,KNSELE
& ,PSZA,KSZA,PLONG,PLAT
& ,KAVGKERN,KAVGKERP,KCORREL,KCORRELP
& ,K1TBL,K2TBL,KTBL,KNUM,KNBON)
*
IMPLICIT NONE
*
CHARACTER*(*) CDSTNID
LOGICAL LDMA
INTEGER KNO,KNUM,KNELE,KNVAL,KNSELE,KNSVAL,KSZA,KDSZA
INTEGER KMXL,KALT,KDBURP,K1TBL,K2TBL
INTEGER KTBL(K1TBL,K2TBL),KMARK(KMXL),KLIST(KNELE),KSLIST(KNELE)
REAL*8 PVAL(KMXL),PSVAL(KMXL),PSZA(KNVAL),PLONG,PLAT
INTEGER KNBON
INTEGER KAVGKERN,KAVGKERP,KCORREL,KCORRELP
*
#if defined (DOC)
*-----------------------------------------------------------------------
*
***s/r CH_BRP2BDY - EXTRACT AND STORE TO CMA BODY REQUIRED 'TR' FAMILY OBS
* DATA PROVIDED IN THE 2-D OBS BLOCK ARRAYS READ FROM
* A BURP FILE.
*
*Author . Y. Yang and Y.J. Rochon *AQRB/MSC May/June 2005
* (starting with IGETELE and BRPACMA routines as reference)
*
*Revision:
* Y.J. Rochon *ARQX/MSC May 2005 - April 2006
* - Code re-packaged as a subroutine.
* - Changed some aspects related to std. dev.
* - Allowance for multiple obs per block
* - Non-species scalar obs allowed (e.g. temperature but
* not winds). However, no checking for winds.
* - Re-configured for version BURPV2.0 of 'TR' family burp files.
* BURPV2.0 refers to the convention agreed upon by
* for P. Koclas, Y. Pelletier, M. Neish, and Y.J. Rochon
* regarding format.
* Y.J. Rochon ARQX August 2010
* - Added CDSTNID argument to call of CH_GETOBSERR
* - Added *AVGKER* and *CORREL* and reading/saving of
* averaging kernel matrixes. Reading/saving of correlation/covar
* matrixes not validated!
*
* PURPOSE: EXTRACT AND STORE TO CMA BODY REQUIRED 'TR' FAMILY OBS
* DATA PROVIDED IN THE 2-D OBS BLOCK ARRAYS READ FROM
* A BURP FILE.
*
* ARGUMENTS:
*
* INPUT:
*
* -KNO : Block index for obs data block
* -LDMA : Logical for presence of markers
* -KMARK : Marker/flag array from marker block
* -KNELE : Dimension of KLIST
* -KNSELE : Dimension of KSLIST (0 for no std. dev.)
* -KNVAL : Length of profiles
* -K1TBL : First dimension of KTBL
* -K2TBL : Second dimension of KTBL
* -KTBL : Block header info
* -KMXL : Max dimension of array
* -KLIST : Decoded BUFR element names for DATA
* (in 6 digit decimal BUFR format)
* -KSLIST : Decoded BUFR element names for STD. DEV.
* -PVAL : Data profiles
* -PSVAL : Std. dev. profiles
* -KDBURP : Data type number (from report header)
* -CDSTNID : Stn id (from report header)
* -PLONG : Longitude (degrees)
* -PLAT : Latitude (degrees)
* -KAVGKERN: >0 if avg kernels to be read
* -KCORREL : >0 if correlation/covariance matrix to be read
*
* OUTPUT:
*
* -KSZA : Number of SZA values (-1 for no values)
* -PSZA : SZA profile
* -KNUM : Number of obs profiles
* -KNBON : Number of obs elements
*
* -Additions to CMA body
*
*
* COMMENTS:
*
* IMPORTANT: Obs counting in CH_BDY2BRP
* must be consistent with that in CH_BRP2BDY
* (and CH_CMABDY). Otherwise, there will be a position
* mismatch between the required CMA data and the BURP
* report content.
*
*-----------------------------------------------------------------------
#endif
*
#include "pardim.cdk"
#include "comlun.cdk"
#include "comdim.cdk"
#include "comchem.cdk"
#include "cparbrp.cdk"
#include "commatrix.cdk"
*
LOGICAL LLERROR
INTEGER IER,IVCORD,IBTYP,IVCORDTYP,IDATYP,J
INTEGER II3D,I3D,INELE,INVAL
INTEGER IIND,IIND2,JJ,IND,JL,INDSTD,JJ1
INTEGER IBFAM,ISPECN,NOBSTYP,IMAT
REAL*8 ZPROF(jpmxnlv),ZEXTRA(jpmxnlv)
REAL*8 ZPROF2(jpmxnlv), ZPROF3(jpmxnlv)
C
INTEGER IDESC(jpmxnel),ILDESC(jpmxnel),INDESC
C
C Initialization
C
LLERROR=.FALSE.
C
IND=0
KNUM=0
IIND = -1
IIND2 = -1
C
C Extract dimensions and flags of data block.
C
INELE=KTBL(2,KNO)
INVAL=KTBL(3,KNO)
IF (INELE.NE.KNELE.OR.INVAL.NE.KNVAL) THEN
write(nulout,*)
write(nulout, *) 'CH_BRP2BDY: Unexpected block size'
call abort3d(nulout,'CH_BRP2BDY')
END IF
IBTYP=KTBL(7,KNO)
IDATYP=KTBL(10,KNO)
I3D=KTBL(4,KNO)
IBFAM =KTBL(5,KNO)
C
C Identify species (when ISPECN=0, data are not species obs)
C Species identifier number is stored using the 7 left-most
C bits of the 12 bit IBFAM.
C
ISPECN=IBFAM/32
C
IF (I3D.GT.1) THEN
write(nulout,*)
write(nulout, *) 'CH_BRP2BDY: 3D block - cannot be processed'
call abort3d(nulout,'CH_BRP2BDY')
END IF
II3D=1
C
C Get 'TR' family obs. descriptors
C
CALL CH_KGETTRDESC
(KLIST,ISPECN,KNELE,CDSTNID,IDESC,ILDESC,INDESC)
IF (INDESC.EQ.0) RETURN
C
C Get vertical coordinate arrays from BURP report and set related
C flags.
C
C Loop over possible descriptors for vertical coordinates.
C Find and select first vertical coordinate element in KLIST.
C
ZPROF(:)=-1.
ZPROF2(:)=-1.
IIND=0
DO JL=1,KNELE
DO JJ = 1, NALLVCORD
IVCORD = NDESCVCORD(JJ)
IF (IVCORD .LE. 0) go to 900
IF (KLIST(JL).EQ.IVCORD) THEN
IIND=JL-1
CALL CH_GETELEX
(IVCORD,II3D,KLIST,PVAL,
+ ZPROF,KNELE,KNVAL,I3D,IIND)
GO TO 950
END IF
END DO
900 CONTINUE
END DO
950 CONTINUE
C
IF (IIND .GT. 0) THEN
IVCORDTYP = NDESVTYP(JJ)
C
C Check for second column denoting same vertical coordinate.
C The presence of a second column implies obs
C of column integrals or column averages.
C The two values denote the layer top and bottom.
C
C Second column must be beside (and to the right of) the first.
C
IIND2=-1
JJ1=JJ
DO JJ = JJ1, NALLVCORD
IF (NDESCVCORD(JJ).LE.0) go to 960
IF (IVCORDTYP.EQ.NDESVTYP(JJ)) THEN
IIND2=IIND
CALL CH_GETELEX
(NDESCVCORD(JJ),II3D,KLIST,PVAL,
+ ZPROF2,KNELE,KNVAL,I3D,IIND2)
IF (IIND2.EQ.IIND+1) go to 960
END IF
END DO
960 IF (IIND2.NE.IIND+1) IIND2=0
END IF
C
C Finalize vertical coordinate arrays and related flags.
C Step 1: Test for availability of required coordinate info.
C Step 2: Add station altitude to heights when appropriate
C Step 3: For IIND2>0, ensure that the layer top is stored in zprof
C and the layer bottom is in zprof2
C
CALL CH_VCOORD
(IIND,IIND2,KNVAL,INDESC,KALT,
& IVCORDTYP,IVCORD,IDESC,ZPROF,ZPROF2)
C
C Set observation handling flag IOBSTYP. This flag identifies which
C forward model, and related adjoint model and TLM, are to be used
C for the observation (see CH_JOCALC, CH_ODA_H*TR, and CH_ONEOBS)
C
CALL CH_OBSTYP
(IIND,IIND2,INDESC,CDSTNID,NOBSTYP,IDESC)
C
C Get the solar zenith angle associated to each observation
C (if present).
C
CALL GETELE(007025,II3D,KLIST,PVAL,
+ PSZA,KNELE,KNVAL,I3D,KSZA)
C
C Loop over data profiles (assumes 1 profile for species block and
C possible multi-profiles for non-species blocks.
C
DO J=1,INDESC
C
C Select and set final obs error std. dev.
C
LLERROR=.TRUE.
CALL CH_GETOBSERR
(0,ILDESC(J),ISPECN,II3D,KLIST,
+ PVAL,ZEXTRA,KNELE,KNVAL,I3D,INDSTD,
+ LLERROR,KNSELE,KSLIST,PSVAL,KMXL,CDSTNID)
IF (LLERROR) THEN
write(nulout,*) 'CH_BRP2BDY: No set obs error std. dev. ',
+ 'for stnid ',cdstnid,ISPECN,KLIST(ILDESC(J))
call abort3d(nulout,'CH_BRP2BDY')
ELSE
C
C Store valid obs data in CMA
C
C Note: Loop over obs is done outside CH_CMABDY.
C (For CMABDY, loop is done inside routine)
C
CALL CH_CMABDY
(PVAL,KLIST,KMARK,
+ ZEXTRA,LLERROR,INDESC,ISPECN,ILDESC(J),
+ KNELE,KNVAL,I3D,IND,
+ IIND2,IVCORDTYP,ZPROF,ZPROF2,II3D,NOBSTYP,
+ PLONG,PLAT,CDSTNID)
KNBON=KNBON+IND
C
C Read/save averaging kernel matrix
C
IF (INDESC.eq.1) THEN ! requires one obs variable only per block
IF (KAVGKERN.GT.0) THEN
IF (NUMAVGK.GT.-1) THEN
NUMAVGK=NUMAVGK+1
IF (NUMAVGK.GT.NMATMAX) THEN
write(nulout,*) 'NMATMAX =',NMATMAX
call ABORT3D(NULOUT,'CH_BRP2BDY: Max number of matrices reached')
END IF
ELSE
NUMAVGK=1
END IF
KAVGKERP=NUMAVGK
NAVGKERN(NUMAVGK,1)=KNVAL ! Assuming KNSVAL=KNVAL when KNSELE.ne.0
NAVGKERN(NUMAVGK,2)=KAVGKERN
IF (KNSELE.EQ.0) THEN
RAVGKERN(:,:,NUMAVGK)=0.0
DO JJ=1,KNVAL
RAVGKERN(JJ,JJ,NUMAVGK)=1.0
END DO
write(NULOUT,*) 'WARNING - CH_BRP2BDY: Avg. kernel matrix not set here.'
ELSE
IMAT=0
CALL CH_GETMATX
(15044,II3D,KSLIST,PSVAL,
+ RAVGKERN(1,1,NUMAVGK),KNSELE,KNVAL,
+ JPNFLEV,KAVGKERN,I3D,IMAT)
IF (IMAT.LE.0) call ABORT3D(NULOUT,'CH_BRP2BDY: Matrix not found')
END IF
END IF
C
C Read/save correlation/covariance matrix
C
IF (KCORREL.GT.0) THEN ! TBD
call ABORT3D(nulout,'CH_BRP2BDY: Correlation/covar matrix requested.')
IF (NUMCORL.GT.-1) THEN
NUMCORL=NUMCORL+1
IF (NUMCORL.GT.NMATMAX) THEN
write(nulout,*) 'NMATMAX =',NMATMAX
call ABORT3D(NULOUT,'CH_BRP2BDY: Max number of matrices reached')
END IF
ELSE
NUMCORL=1
END IF
KCORRELP=NUMCORL
NCORREL(NUMCORL,1)=KNVAL ! Assuming KNSVAL=KNVAL when KNSELE.ne.0
NCORREL(NUMCORL,2)=KCORREL
IF (KNSELE.EQ.0) THEN
RCORREL(:,:,NUMCORL)=0.0
DO JJ=1,KNVAL
RCORREL(JJ,JJ,NUMCORL)=1.0
END DO
write(NULOUT,*) 'WARNING - CH_BRP2BDY: Covar matrix not set here'
ELSE
IMAT=0
CALL CH_GETMATX
(59239,II3D,KSLIST,PSVAL,
+ RCORREL(1,1,NUMCORL),KNSELE,KNSVAL,
+ JPNFLEV,KCORREL,I3D,IMAT)
IF (IMAT.LE.0) call ABORT3D(NULOUT,'CH_BRP2BDY: Covar matrix not found')
END IF
END IF
END IF
END IF
IF (KNBON.GT.0) KNUM=INDESC
END DO
C
RETURN
END