midas_obsImpact sourceΒΆ

  1program midas_obsImpact
  2  !
  3  !:Purpose: Main program for computing the Forecast Sensitivity to Observation Impact (FSOI)
  4  !
  5  !           ---
  6  !
  7  !:Algorithm: FSOI partitions the forecast error reduction within the current system from 
  8  !            assimilating the observations. The total forecast error reduction defined as:
  9  !
 10  !             :math:`(e_{t}^{fa})^{T}*C*(e_{t}^{fa})-(e_{t}^{fb})^{T}*C*(e_{t}^{fb})`
 11  !
 12  !             where :math:`e_{t}^{fa}=M(x_{0}^{a})-x_{t}^{a}`
 13  !
 14  !             and :math:`e_{t}^{fb}=M(x_{0}^{b})-x_{t}^{a}`
 15  !
 16  !            and C is the energy norm. 
 17  !             
 18  !            --
 19  !
 20  !            In this program, there are the hybrid FSOI approach (HFSOI) and the ensemble FSOI (EFSOI) approaches.
 21  !            The hybrid approach is appropriate for computing the impact of observations assimilated with 4D-EnVar.
 22  !            It combines the ensemble approach for propagating the sensitivities from forecast to analysis time and
 23  !            the variational approach for the adjoint of the assimilation procedure. The ensemble approach is 
 24  !            appropriate for computing the impact of observations assimilated with the LETKF. It relies purely on
 25  !            analysis and forecast ensemble for the calculation. 
 26  !
 27  !
 28  !            More details on HFSOI can be found in the paper: `HFSOI approach <https://doi.org/10.1175/MWR-D-17-0252.1>`_
 29  !
 30  !
 31  !            More details on EFSOI can be found in the paper:`EFSOI approach <http://doi.org/10.3402/tellusa.v65i0.20038>`_
 32  !
 33  !            --
 34  !
 35  !:File I/O: The required input files and produced output files are listed as follows.
 36  !
 37  !           --
 38  !
 39  !============================================== ====================================================================
 40  ! Input and Output Files                         Description of file
 41  !============================================== ====================================================================
 42  ! ``flnml``                                      In - Main namelist file with parameters user may modify
 43  ! ``trlm_$NN`` (e.g. ``trlm_01``)                In - Background state (a.k.a. trial) files for each timestep
 44  ! ``analysisgrid``                               In - File defining grid for computing the analysis increment
 45  ! ``bgcov``                                      In - Static (i.e. NMC) B matrix file for NWP fields
 46  ! ``ensemble/$YYYYMMDDHH_006_$NNNN``             In - Ensemble member files defining ensemble B matrix
 47  ! ``ensemble/$YYYYMMDDHH_foradv``                In - advection files
 48  ! ``obsfiles_$FAM/obs$FAM_$NNNN_$NNNN``          In - Observation file for each "family" and MPI task
 49  ! ``obserr``                                     In - Observation error statistics
 50  ! ``forecasts/forecast_*``                       In - Global deterministic forecast from backgroud and analysis
 51  ! ``forecasts/analysis``                         In - Verifying analysis
 52  ! ``diafiles_$FAM.updated/obs$FAM_$NNNN_$NNNN``  Out - Updated obs file for each "family" and MPI task in SQLite 
 53  ! Remainder are files related to radiance obs:
 54  ! ``stats_$SENSOR_assim``                        In - Satellite radiance observation errors of difference sensors
 55  ! ``stats_tovs``                                 In - Satellite radiance observation errors 
 56  ! ``rtcoef_$PLATFORM_$SENSOR.**``                In - RTTOV coefficient files 
 57  ! ``rttov_h2o_limits.dat``                       In - Min/Max humidity limits 
 58  ! ``stats_tovs_symmetricObsErr``                 In - user-defined symmetric TOVS errors for all sky
 59  ! ``Cmat_$PLATFORM_$SENSOR.dat``                 In - Inter-channel observation-error correlations
 60  !============================================== ====================================================================
 61  !
 62  !           --
 63  !
 64  !:Synopsis: Below is a summary of the ``obsImpact`` program calling sequence:
 65  !
 66  !           - **Initial setups:**
 67  !
 68  !             - Initialize FSOI module, read the namelist from ``fso_setup``
 69  !
 70  !             - Setup horizontal and vertical grid objects for "analysis
 71  !               grid" from ``analysisgrid`` file and for "trial grid" from
 72  !               first trial file: ``trlm_01``.
 73  !
 74  !             - Setup ``obsSpaceData`` object and read observations from
 75  !               files: ``inn_setupObs``.
 76  !
 77  !             - Setup ``columnData`` and ``gridStateVector`` modules (read
 78  !               list of analysis variables from namelist) and allocate column
 79  !               object for storing trial on analysis levels.
 80  ! 
 81  !             - Setup the observation error statistics in ``obsSpaceData``
 82  !               object: ``oer_setObsErrors``.
 83  !
 84  !             - Allocate a stateVector object on the trial grid and then
 85  !               read the trials: ``gio_readTrials``.
 86  !
 87  !             - Setup the B matrices: ``bmat_setup``.
 88  !
 89  !             - Setup the ``gridVariableTransforms``. 
 90  !
 91  !           - **Computation:** 
 92  !
 93  !             - ``incdatr``: Setup dateStamp(one extra timestamp: leadTime) for FSOI.
 94  !
 95  !             - ``inn_computeInnovation``: Compute innovation 
 96  !
 97  !             - ``calcFcstError``: Read the forcasts from background and analysis, and 
 98  !                                  the verifying analysis as well, calculate the forecast
 99  !                                  error norm defined as: 
100  !                                  :math:`(C*(e_{t}^{fa}+e_{t}^{fb}))`.
101  !
102  !             - ``bmat_sqrtBT``: Compute the variable :math:`\hat{v}` for minimization in HFSO mode.             
103  !                                       :math:`\hat{v}=B_{t}^{T/2}*C*(e_{t}^{fa}+e_{t}^{fb})` 
104  !
105  !             - ``minimize``: Do the minimization to apply the adjoint of the 4D-EnVar assimilation  
106  !                             to :math:`\hat{v}` with the result being :math:`\hat{a}`.
107  !
108  !             - ``bmat_sqrt``: Compute :math:`B^{1/2}*\hat{a}` .
109  !
110  !             - ``s2c_tl``, ``oop_Htl``: Apply the observation operators :math:`H*B^{1/2}*\hat{a}` .
111  !
112  !             - ``rmat_RsqrtInverseAllObs``: Multiply by the inverse of the observation error variances
113  !                                                    :math:`R^{-1}*H*B^{1/2}*\hat{a}` 
114  !
115  !             - ``obs_bodySet_r``: Multiply the resulting sensitivity value by the innovation and put  
116  !                                  the result in the ``obsSpaceDate`` column ``OBS_FSO`` so it can be stored in
117  !                                  the observation files 
118  !
119  !             - ``sumFSO``: Print out the FSOI value, including total and the one from each obs family.
120  !
121  !           - **Final steps:** 
122  !
123  !             - ``obsf_writeFiles``: Write the final FSOI value in SQLite file.
124  !
125  !           --
126  !
127  !:Options: `List of namelist blocks <../namelists_in_each_program.html#obsimpact>`_
128  !          that can affect the ``obsImpact`` program.
129  !
130  !          * The use of ``obsImpact`` program is controlled mainly by the namelist block
131  !            ``&NAMFSO`` read by the ``fso_mod`` module. 
132  ! 
133  !          * Some of the other relevant namelist blocks used to configure FSOI
134  !            are listed in the following table:
135  !
136  !   
137  !========================= ====================== =============================================================
138  ! Module                   Namelist               Description of what is controlled
139  !========================= ====================== =============================================================
140  ! ``timeCoord_mod``        ``NAMTIME``            assimilation time window length, temporal resolution of
141  !                                                 the background state and increment
142  ! ``bMatrixEnsemble_mod``  ``NAMBEN``             weight and other parameters for ensemble-based B matrix
143  !                                                 component
144  !========================= ====================== =============================================================
145  !
146  !
147  use version_mod
148  use codePrecision_mod
149  use ramDisk_mod
150  use utilities_mod
151  use midasMpi_mod
152  use mathPhysConstants_mod
153  use horizontalCoord_mod
154  use verticalCoord_mod
155  use timeCoord_mod
156  use columnData_mod
157  use obsSpaceData_mod
158  use gridStateVector_mod
159  use gridStateVectorFileIO_mod
160  use bMatrix_mod
161  use innovation_mod
162  use obsFiles_mod
163  use obsErrors_mod
164  use gridVariableTransforms_mod
165  use fsoi_mod
166
167  implicit none
168
169  integer :: istamp,exdb,exfin,ierr, dateStampFromObs
170
171  type(struct_obs),       target :: obsSpaceData
172  type(struct_columnData),target :: columnTrlOnAnlIncLev
173  type(struct_columnData),target :: columnTrlOnTrlLev
174  type(struct_gsv)               :: stateVectorTrialHighRes
175
176  character(len=48) :: obsMpiStrategy
177  character(len=3)  :: obsColumnMode
178
179  type(struct_vco),        pointer :: vco_anl => null()
180  type(struct_hco),        pointer :: hco_anl => null()
181  type(struct_hco),        pointer :: hco_trl => null()
182  type(struct_vco),        pointer :: vco_trl => null()
183  type(struct_hco),        pointer :: hco_core => null()
184  integer,external    :: get_max_rss
185  logical             :: allocHeightSfc
186
187  istamp = exdb('OBSIMPACT','DEBUT','NON')
188
189  call ver_printNameAndVersion('obsImpact','Calculation of observation impact')
190
191  ! MPI initilization
192  call mmpi_initialize
193
194  call tmg_init(mmpi_myid, 'TMG_INFO')
195
196  call utl_tmg_start(0,'Main')
197
198  if (mmpi_myid == 0) then
199    call utl_writeStatus('VAR3D_BEG')
200  end if
201
202  call ram_setup
203
204  !
205  !- 1. Settings 
206  !
207  obsColumnMode  = 'VAR'
208  obsMpiStrategy = 'LIKESPLITFILES'
209
210  !
211  !- Initialize the Temporal grid and set dateStamp from env variable
212  !
213  call tim_setup()
214  !     
215  !- Initialize burp file names and set datestamp if not already
216  !
217  call obsf_setup(dateStampFromObs, 'FSO')
218  if (tim_getDateStamp() == 0) then
219    if (dateStampFromObs > 0) then
220      call tim_setDatestamp(dateStampFromObs)
221    else
222      call utl_abort('obsImpact: DateStamp was not set')
223    end if
224  end if
225  !
226  !- Initialize constants
227  !
228  if ( mmpi_myid == 0 ) then
229    call mpc_printConstants(6)
230    call pre_printPrecisions
231  end if
232
233  !
234  !- Initialize variables of the model states
235  !
236  call gsv_setup
237  write(*,*) 'Memory Used: ',get_max_rss()/1024,'Mb'
238  !
239  !- Initialize the Analysis grid
240  !
241  if (mmpi_myid.eq.0) write(*,*)''
242  if (mmpi_myid.eq.0) write(*,*)'obsImpact: Set hco parameters for analysis grid'
243  call hco_SetupFromFile(hco_anl, './analysisgrid', 'ANALYSIS', 'Analysis' ) ! IN
244
245  !- Do FSO module set up
246  call fso_setup(hco_anl)
247
248  if ( hco_anl % global ) then
249    hco_core => hco_anl
250  else
251    !- Iniatilized the core (Non-Exteded) analysis grid
252    call hco_SetupFromFile( hco_core, './analysisgrid', 'COREGRID', 'AnalysisCore' ) ! IN
253  end if
254
255  !     
256  !- Initialisation of the analysis grid vertical coordinate from analysisgrid file !
257  call vco_SetupFromFile( vco_anl,        & ! OUT
258                          './analysisgrid') ! IN
259
260  call col_setVco(columnTrlOnAnlIncLev,vco_anl)
261  write(*,*) 'Memory Used: ',get_max_rss()/1024,'Mb'
262
263  !
264  !- Setup and read observations
265  !
266  call inn_setupObs(obsSpaceData, hco_anl, obsColumnMode, obsMpiStrategy, 'FSO') ! IN
267  write(*,*) 'Memory Used: ',get_max_rss()/1024,'Mb'
268
269  !
270  !- Basic setup of columnData module
271  !
272  call col_setup
273  write(*,*) 'Memory Used: ',get_max_rss()/1024,'Mb'
274
275  !
276  !- Memory allocation for background column data
277  !
278  call col_allocate(columnTrlOnAnlIncLev,obs_numheader(obsSpaceData),mpiLocal_opt=.true.)
279
280  !
281  !- Initialize the observation error covariances
282  !
283  call oer_setObsErrors(obsSpaceData, 'FSO') ! IN
284  write(*,*) 'Memory Used: ',get_max_rss()/1024,'Mb'
285
286  ! Reading trials
287  call inn_getHcoVcoFromTrlmFile( hco_trl, vco_trl )
288  allocHeightSfc = ( vco_trl%Vcode /= 0 )
289
290  call gsv_allocate( stateVectorTrialHighRes, tim_nstepobs, hco_trl, vco_trl,  &
291                     dateStamp_opt=tim_getDateStamp(), mpi_local_opt=.true., &
292                     mpi_distribution_opt='Tiles', dataKind_opt=4,  &
293                     allocHeightSfc_opt=allocHeightSfc, hInterpolateDegree_opt='LINEAR', &
294                     beSilent_opt=.false. )
295  call gsv_zero( stateVectorTrialHighRes )
296  call gio_readTrials( stateVectorTrialHighRes )
297  write(*,*) 'Memory Used: ',get_max_rss()/1024,'Mb'
298
299  ! Horizontally interpolate trials to trial columns
300  call inn_setupColumnsOnTrlLev( columnTrlOnTrlLev, obsSpaceData, hco_core, &
301                                   stateVectorTrialHighRes )
302  write(*,*) 'Memory Used: ',get_max_rss()/1024,'Mb'
303
304  !
305  !- Initialize the background-error covariance, also sets up control vector module (cvm)
306  !
307  call bmat_setup(hco_anl,hco_core,vco_anl)
308  write(*,*) 'Memory Used: ',get_max_rss()/1024,'Mb'
309
310  !
311  ! - Initialize the gridded variable transform module
312  !
313  call gvt_setup(hco_anl,hco_core,vco_anl)
314  call gvt_setupRefFromTrialFiles('HU')
315  call gvt_setupRefFromTrialFiles('height')
316
317  !
318  !- 2. Do the actual job
319  !
320
321  ! Interpolate trial columns to analysis levels and setup for linearized H
322  call inn_setupColumnsOnAnlIncLev(columnTrlOnTrlLev,columnTrlOnAnlIncLev)
323
324  ! Compute observation innovations and prepare obsSpaceData for minimization
325  call inn_computeInnovation(columnTrlOnTrlLev,obsSpaceData)
326
327  ! Perform forecast sensitivity to observation calculation using ensemble approach 
328  call fso_ensemble(columnTrlOnAnlIncLev,obsSpaceData)
329
330  ! Deallocate memory related to B matrices
331  call bmat_finalize()
332
333  ! Now write out the observation data files
334  if ( .not. obsf_filesSplit() ) then
335    write(*,*) 'We read/write global observation files'
336    call obs_expandToMpiGlobal(obsSpaceData)
337    if (mmpi_myid == 0) call obsf_writeFiles(obsSpaceData)
338  else
339    ! redistribute obs data to how it was just after reading the files
340    call obs_MpiRedistribute(obsSpaceData,OBS_IPF)
341    call obsf_writeFiles(obsSpaceData)
342  end if
343  
344  ! Deallocate copied obsSpaceData
345  call obs_finalize(obsSpaceData)
346
347  !
348  !- 3. Job termination
349  !
350  istamp = exfin('OBSIMPACT','FIN','NON')
351
352  if (mmpi_myid == 0) then
353    call utl_writeStatus('VAR3D_END')
354  endif
355
356  call utl_tmg_stop(0)
357
358  call tmg_terminate(mmpi_myid, 'TMG_INFO')
359
360  call rpn_comm_finalize(ierr)
361
362end program midas_obsImpact