1program midas_oMinusF
2 !
3 !:Purpose: Main program for Observation minus Forecast (O-F) computation.
4 !
5 ! ---
6 !
7 !:Algorithm: The non-linear observation operators map a gridded state vector into the
8 ! observation space to compute the difference between the observations
9 ! and that state in observation space. The gridded state vector can be
10 ! background state or the analysis. In case of background state, the
11 ! difference is the innovation vector: ``y-H(xb)``. If asked by
12 ! the user, the diagonal of the background errors standard deviation in
13 ! observation space, :math:`{diag(H B H^{T})}^{1/2}`, are also computed.
14 ! The bias corrections are applied for satellite radiances before writing
15 ! the observation files.
16 !
17 ! --
18 !
19 !============================================== ==============================================================
20 ! Input and Output Files Description of file
21 !============================================== ==============================================================
22 ! ``flnml`` In - Main namelist file with parameters user may modify
23 ! ``flnml_static`` In - The "static" namelist that should not be modified
24 ! ``trlm_$NN`` (e.g. ``trlm_01``) In - Background state (a.k.a. trial) files for each timestep
25 ! ``analysisgrid`` In - File defining grid for computing the analysis increment
26 ! ``obsfiles_$FAM/obs$FAM_$NNNN_$NNNN`` In - Observation file for each "family" and MPI task
27 ! ``obserr`` In - Observation error statistics
28 ! ``obsfiles_$FAM.updated/obs$FAM_$NNNN_$NNNN`` Out - Updated obs file for each "family" and MPI task
29 ! Remainder are files related to radiance obs:
30 ! ``stats_$SENSOR_assim`` In - Satellite radiance observation errors of different sensors
31 ! ``stats_tovs`` In - Satellite radiance observation errors
32 ! ``stats_tovs_symmetricObsErr`` In - User-defined symmetric TOVS errors for all sky
33 ! ``Cmat_$PLATFORM_$SENSOR.dat`` In - Inter-channel observation-error correlations
34 ! ``dynbcor.coeffs.$SENSOR.*.coeffs_$SENSOR`` In - Dynamic bias correction file
35 ! ``ceres_global.std`` In - High-res surface type and water fraction for radiance obs
36 ! ``rtcoef_$PLATFORM_$SENSOR.dat`` In - RTTOV coefficient files
37 ! ``rttov_h2o_limits.dat`` In - Min/max humidity limits applied to analysis
38 ! ``ozoneclim98`` In - Ozone climatology
39 !============================================== ==============================================================
40 !
41 ! --
42 !
43 !:Synopsis: Below is a summary of the ``oMinusF`` program calling sequence:
44 !
45 ! - **Initial setups:**
46 !
47 ! - Read the NAMOMF namelist and check/modify some values.
48 !
49 ! - Various modules are setup: ``obsFiles_mod``, ``timeCoord_mod``.
50 !
51 ! - Setup ``gridStateVector`` module.
52 !
53 ! - Setup horizontal and vertical grid objects from either
54 ! ``analysisgrid`` or first trial file: ``trlm_01``.
55 !
56 ! - Setup ``obsSpaceData`` object and read observations from
57 ! files: ``inn_setupObs``.
58 !
59 ! - Applying optional bias corrections to some observation types.
60 !
61 ! - Setup ``columnData`` module (read list of analysis variables
62 ! from namelist) and allocate column object.
63 !
64 ! - Allocate a stateVector object and then read the state
65 ! (either trials or analysis): ``gio_readTrials``.
66 !
67 ! - **Computation**
68 !
69 ! - Compute interpolated column on trial level ``columnTrlOnTrlLev``
70 ! from the state: ``inn_setupColumnsOnTrlLev``.
71 !
72 ! - Compute innovation from background state: ``inn_computeInnovation``.
73 !
74 ! - For computing background errors in observation space,
75 ! ``columnTrlOnTrlLev`` are interpolated from background to analysis
76 ! levels, ``columnTrlOnAnlIncLev``, and the linearize operators are
77 ! initialized: ``inn_setupColumnsOnAnlIncLev``.
78 !
79 ! - Update radiance bias correction in ``obsSpaceData`` and apply
80 ! the bias corrections to the observations and innovations for
81 ! radiances: ``bcs_calcBias``, ``bcs_applyBiasCorrection``.
82 !
83 ! - Write the final bias corrected results into the observation file.
84 !
85 ! --
86 !
87 !:Options: `List of namelist blocks <../namelists_in_each_program.html#ominusf>`_
88 ! that can affect the ``oMinusF`` program.
89 !
90 ! * The use of ``oMinusF`` program is controlled by the namelist block
91 ! ``&NAMOMF`` read by the ``oMinusF`` program.
92 !
93 ! * Some of the other relevant namelist blocks used to configure the
94 ! ``oMinusF`` are listed in the following table:
95 !
96 !=========================== ========================= =========================================
97 ! Module Namelist Description of what is controlled
98 !=========================== ========================= =========================================
99 ! ``biasCorrectionConv_mod`` ``NAMBIASCONV`` variables to perform bias correction
100 ! for conventional observations.
101 ! ``biasCorrectionConv_mod`` ``NAMSONDETYPES`` additional variables to perform bias
102 ! correction for radiosondes conventional
103 ! observations.
104 ! ``biasCorrectionSat_mod`` ``NAMBIASSAT`` variables to perform bias correction
105 ! for satellite radiances.
106 ! ``burpread_mod`` ``NAMADDTOBURP`` element IDs to add to the BURP file
107 !=========================== ========================= =========================================
108 !
109 use version_mod
110 use oMinusF_mod
111 use obsSpaceData_mod
112 use columnData_mod
113 use obsFiles_mod
114 use utilities_mod
115 use midasMpi_mod
116 use biasCorrectionSat_mod
117 use ensembleObservations_mod
118 use fileNames_mod
119 implicit none
120
121 ! Namelist
122 integer :: nEns ! ensemble size
123 logical :: addHBHT ! choose to add the value of HBHT to obsSpaceData so it can be output
124 logical :: addSigmaO ! choose to add the value of sigma_obs to obsSpaceData so it can be output
125 NAMELIST /NAMOMF/addHBHT, addSigmaO, nEns
126
127 integer :: fnom, fclos, nulnam, ierr, headerIndex
128
129 type(struct_columnData),target :: columnTrlOnAnlIncLev
130 type(struct_columnData),target :: columnTrlOnTrlLev
131 type(struct_obs), target :: obsSpaceData
132 type(struct_eob), target :: ensObs
133
134 character(len=20) :: oMinusFmode
135 character(len=256) :: ensPathName = 'ensemble'
136 character(len=256) :: ensFileName
137 character(len=256) :: trlFileName = './trlm_01'
138
139 logical :: ensFileExists, trlFileExists
140
141 call ver_printNameAndVersion('oMinusF','Computation of the innovation')
142
143 !
144 !- 1. Initialization
145 !
146
147 !- 1.1 mpi
148 call mmpi_initialize
149
150 !- 1.2 timings
151 call tmg_init(mmpi_myid, 'TMG_INFO')
152 call utl_tmg_start(0,'Main')
153
154 if ( mmpi_myid == 0 ) then
155 call utl_writeStatus('VAR3D_BEG')
156 endif
157
158 !- 1.3 Namelist
159 addHBHT = .false. ! default value
160 addSigmaO = .false.
161 nEns = 20
162
163 nulnam = 0
164 ierr = fnom(nulnam,'./flnml','FTN+SEQ+R/O',0)
165 read(nulnam,nml=namomf,iostat=ierr)
166 if (ierr /= 0) call utl_abort('midas-OminusF: Error reading namelist')
167 if (mmpi_myid == 0) write(*,nml=namomf)
168 ierr = fclos(nulnam)
169
170 !- 1.4 Set mode
171 inquire(file=trim(trlFileName),exist=trlFileExists)
172 call fln_ensFileName(ensFileName, ensPathName, memberIndex_opt=1, &
173 shouldExist_opt=.false.)
174 inquire(file=trim(ensFileName),exist=ensFileExists)
175
176 if (trlFileExists) then
177 write(*,*)
178 write(*,*) 'Trial/Prog file found'
179 write(*,*) 'Setting mode to DETERMINISTIC'
180 oMinusFmode = 'deterministic'
181 else if (ensFileExists) then
182 write(*,*)
183 write(*,*) 'Ensemble file found'
184 write(*,*) 'Setting mode to ENSEMBLE'
185 oMinusFmode = 'ensemble'
186 else
187 write(*,*)
188 write(*,*) 'trlFileName = ', trim(trlFileName)
189 write(*,*) 'ensFileName = ', trim(ensFileName)
190 call utl_abort('oMinusF : did not find a trial/prog or ensemble file')
191 end if
192
193 !
194 !- 2. Calculate the Observation - Forecast difference
195 !
196 if (trim(oMinusFmode) == 'deterministic') then
197
198 !- 2.1 Compute O-F and store in obsSpaceDate
199 call omf_oMinusF(columnTrlOnAnlIncLev, columnTrlOnTrlLev, obsSpaceData, &
200 'OminusF', addHBHT, addSigmaO)
201
202 !- 2.2 Remove biases
203 call bcs_calcBias(obsSpaceData,columnTrlOnTrlLev) ! Fill in OBS_BCOR obsSpaceData column with computed bias correction
204
205 call bcs_applyBiasCorrection(obsSpaceData,OBS_VAR,"TO") ! Apply bias correction to OBS
206 call bcs_applyBiasCorrection(obsSpaceData,OBS_OMP,"TO") ! Apply bias correction to O-F
207
208 !- 2.3 Write the results
209
210 ! 2.3.1 Into the listings
211 write(*,*)
212 write(*,*) '> midas-OminusF: printing the FIRST header and body'
213 do headerIndex = 1, min(1,obs_numHeader(obsSpaceData))
214 call obs_prnthdr(obsSpaceData,headerIndex)
215 call obs_prntbdy(obsSpaceData,headerIndex)
216 end do
217 ! 2.3.2 Into the observation files
218 write(*,*)
219 write(*,*) '> midas-OminusF: writing to file'
220 call obsf_writeFiles(obsSpaceData)
221
222 else ! ensemble
223
224 !- 2.1 Compute O-F and store in ensObs
225 call omf_oMinusFens( ensObs, obsSpaceData, nEns, ensPathName, &
226 'OminusF', addHBHT, addSigmaO)
227
228 !- 2.3 Write the results
229 call obsf_writeFiles(obsSpaceData, ensObs_opt=ensObs)
230
231 end if
232
233 !
234 !- 3. Ending
235 !
236 write(*,*)
237 write(*,*) '> midas-OminusF: Ending'
238
239 call obs_finalize(obsSpaceData) ! deallocate obsSpaceData
240
241 call utl_tmg_stop(0)
242 call tmg_terminate(mmpi_myid, 'TMG_INFO')
243
244 call rpn_comm_finalize(ierr)
245
246 if ( mmpi_myid == 0 ) then
247 call utl_writeStatus('VAR3D_END')
248 endif
249
250end program midas_oMinusF