FV3 Bundle
m_diag_aircft.f90
Go to the documentation of this file.
3  use nc_diag_write_mod, only: nc_diag_init, nc_diag_metadata, nc_diag_write
4 
5  use nc_diag_read_mod, only: nc_diag_read_get_dim
7  use nc_diag_read_mod, only: nc_diag_read_get_var
8  use nc_diag_read_mod, only: nc_diag_read_get_global_attr
9 
10  implicit none
11 
12  private
13  save
14 
15  public :: diag_aircft_header
16  public :: diag_aircft_mass !generic name for non-wind obs - obs w/ single obs associated
17  public :: diag_aircft_wind ! name for wind obs - obs w/ two obs (u,v) associated
18 
20 
22  public :: read_aircft_diag_nc_mass
23 
25  character(3), dimension(:), allocatable :: obstype
26  integer(i_kind) :: n_obstype
27  integer(i_kind), dimension(:), allocatable :: n_observations
28  integer(i_kind) :: n_observations_mass
29  integer(i_kind) :: n_observations_wind
30  integer(i_kind) :: n_observations_total
31  integer(i_kind) :: date
32  end type diag_aircft_header
33 
35  character(8) :: station_id
36  character(3) :: observation_class
37  real(r_single) :: observation_type
38 ! real(r_single) :: Observation_Subtype
39  real(r_single) :: latitude
40  real(r_single) :: longitude
41  real(r_single) :: station_elevation
42  real(r_single) :: pressure
43  real(r_single) :: height
44  real(r_single) :: time
45  real(r_single) :: prep_qc_mark
46  real(r_single) :: setup_qc_mark
47  real(r_single) :: prep_use_flag
48  real(r_single) :: analysis_use_flag
49  real(r_single) :: nonlinear_qc_rel_wgt
50  real(r_single) :: errinv_input
51  real(r_single) :: errinv_adjust
52  real(r_single) :: errinv_final
53  real(r_single) :: observation
54  real(r_single) :: obs_minus_forecast_adjusted
55  real(r_single) :: obs_minus_forecast_unadjusted
56 
57  end type diag_aircft_mass
58 
60  character(8) :: station_id
61  character(3) :: observation_class
62  real(r_single) :: observation_type
63 ! real(r_single) :: Observation_Subtype
64  real(r_single) :: latitude
65  real(r_single) :: longitude
66  real(r_single) :: station_elevation
67  real(r_single) :: pressure
68  real(r_single) :: height
69  real(r_single) :: time
70  real(r_single) :: prep_qc_mark
71  real(r_single) :: setup_qc_mark
72  real(r_single) :: prep_use_flag
73  real(r_single) :: analysis_use_flag
74  real(r_single) :: nonlinear_qc_rel_wgt
75  real(r_single) :: errinv_input
76  real(r_single) :: errinv_adjust
77  real(r_single) :: errinv_final
78  real(r_single) :: u_observation
79  real(r_single) :: u_obs_minus_forecast_adjusted
80  real(r_single) :: u_obs_minus_forecast_unadjusted
81  real(r_single) :: v_observation
82  real(r_single) :: v_obs_minus_forecast_adjusted
83  real(r_single) :: v_obs_minus_forecast_unadjusted
84  real(r_single) :: wind_reduction_factor_at_10m
85  end type diag_aircft_wind
86 
87  integer,parameter :: maxobstype=30
88  integer :: nobstype
89  integer :: aircft_mass_type = 130 ! type for RAOB T and Q
90  integer :: aircft_wind_type = 230 ! type for RAOB U and V
91  integer :: t_qcmark = 1 ! 0=tv; 1=tdry
92 
93 contains
94 
95  integer(i_kind) function get_obstype_index(obstype, obstypearr)
96 ! integer(i_kind) :: get_obstype_index
97  character(3),intent(in) :: obstype
98  character(3),intent(inout),dimension(*) :: obstypearr
99 
100  integer :: i, idx
101  logical :: matched
102 
103  matched = .false.
104 
105  if (nobstype .eq. 0) then
106  nobstype = 1
107  obstypearr(1) = obstype
108  idx = nobstype
109  print *,'obstype=',obstype,' set to index',idx
110  else
111  do i=1,nobstype
112  if (obstype .eq. obstypearr(i)) then
113  idx = i
114  matched = .true.
115  endif
116  enddo
117  if (.not. matched) then
118  nobstype = nobstype + 1
119  obstypearr(nobstype) = obstype
120  idx = nobstype
121  print *,'obstype=',obstype,' set to index',idx
122  endif
123  endif
124 
125 
126  get_obstype_index = idx
127 
128  end function get_obstype_index
129 
130 
131  subroutine write_split_aircft_diag_nc(infn,aircft_header, aircft_mass, aircft_wind, append_suffix)
132  character(120), intent(in) :: infn
133  type(diag_aircft_header), intent(in) :: aircft_header
134  type(diag_aircft_mass),dimension(aircft_header%n_Observations_Mass),intent(in):: aircft_mass
135  type(diag_aircft_wind),dimension(aircft_header%n_Observations_Wind),intent(in):: aircft_wind
136  logical, intent(in) :: append_suffix
137 
138  character(120) :: outfn
139  character(20) :: str, str2
140  integer :: strlen
141  integer :: i, itype
142 
143  do itype=1, aircft_header%n_ObsType
144  str = aircft_header%ObsType(itype)
145  if (.not. append_suffix) then
146  str2 = 'diag_aircft_' // trim(adjustl(str))
147  outfn = replace_text(trim(infn),'diag_aircft',str2)
148  strlen = len(trim(outfn))
149  outfn = outfn(1:strlen-3) // 'nc4'
150  else
151  outfn = trim(infn) // '.' // trim(adjustl(str)) // '.nc4'
152  endif
153 
154  print *,outfn
155 
156  call nc_diag_init(outfn)
157 
158  if (aircft_header%ObsType(itype) .eq. ' uv') then
159  do i=1,aircft_header%n_Observations_Wind
160  call nc_diag_metadata("Station_ID", aircft_wind(i)%Station_ID )
161  call nc_diag_metadata("Observation_Class", aircft_wind(i)%Observation_Class )
162  call nc_diag_metadata("Observation_Type", aircft_wind(i)%Observation_Type )
163 ! call nc_diag_metadata("Observation_Subtype", aircft_wind(i)%Observation_Subtype )
164  call nc_diag_metadata("Latitude", aircft_wind(i)%Latitude )
165  call nc_diag_metadata("Longitude", aircft_wind(i)%Longitude )
166  call nc_diag_metadata("Station_Elevation", aircft_wind(i)%Station_Elevation )
167  call nc_diag_metadata("Pressure", aircft_wind(i)%Pressure )
168  call nc_diag_metadata("Height", aircft_wind(i)%Height )
169  call nc_diag_metadata("Time", aircft_wind(i)%Time )
170  call nc_diag_metadata("Prep_QC_Mark", aircft_wind(i)%Prep_QC_Mark )
171  call nc_diag_metadata("Setup_QC_Mark", aircft_wind(i)%Setup_QC_Mark )
172  call nc_diag_metadata("Prep_Use_Flag", aircft_wind(i)%Prep_Use_Flag )
173  call nc_diag_metadata("Analysis_Use_Flag", aircft_wind(i)%Analysis_Use_Flag )
174  call nc_diag_metadata("Nonlinear_QC_Rel_Wgt", aircft_wind(i)%Nonlinear_QC_Rel_Wgt )
175  call nc_diag_metadata("Errinv_Input", aircft_wind(i)%Errinv_Input )
176  call nc_diag_metadata("Errinv_Adjust", aircft_wind(i)%Errinv_Adjust )
177  call nc_diag_metadata("Errinv_Final", aircft_wind(i)%Errinv_Final )
178  call nc_diag_metadata("u_Observation", aircft_wind(i)%u_Observation )
179  call nc_diag_metadata("u_Obs_Minus_Forecast_adjusted", aircft_wind(i)%u_Obs_Minus_Forecast_adjusted )
180  call nc_diag_metadata("u_Obs_Minus_Forecast_unadjusted", aircft_wind(i)%u_Obs_Minus_Forecast_unadjusted )
181  call nc_diag_metadata("v_Observation", aircft_wind(i)%v_Observation )
182  call nc_diag_metadata("v_Obs_Minus_Forecast_adjusted", aircft_wind(i)%v_Obs_Minus_Forecast_adjusted )
183  call nc_diag_metadata("v_Obs_Minus_Forecast_unadjusted", aircft_wind(i)%v_Obs_Minus_Forecast_unadjusted )
184  call nc_diag_metadata("Wind_Reduction_Factor_at_10m", aircft_wind(i)%Wind_Reduction_Factor_at_10m )
185  enddo
186  else
187  do i=1,aircft_header%n_Observations_Mass
188  if (aircft_mass(i)%Observation_Class .eq. aircft_header%ObsType(itype) ) then
189  call nc_diag_metadata("Station_ID", aircft_mass(i)%Station_ID )
190  call nc_diag_metadata("Observation_Class", aircft_mass(i)%Observation_Class )
191  call nc_diag_metadata("Observation_Type", aircft_mass(i)%Observation_Type )
192 ! call nc_diag_metadata("Observation_Subtype", aircft_mass(i)%Observation_Subtype )
193  call nc_diag_metadata("Latitude", aircft_mass(i)%Latitude )
194  call nc_diag_metadata("Longitude", aircft_mass(i)%Longitude )
195  call nc_diag_metadata("Station_Elevation", aircft_mass(i)%Station_Elevation )
196  call nc_diag_metadata("Pressure", aircft_mass(i)%Pressure )
197  call nc_diag_metadata("Height", aircft_mass(i)%Height )
198  call nc_diag_metadata("Time", aircft_mass(i)%Time )
199  call nc_diag_metadata("Prep_QC_Mark", aircft_mass(i)%Prep_QC_Mark )
200  call nc_diag_metadata("Setup_QC_Mark", aircft_mass(i)%Setup_QC_Mark )
201  call nc_diag_metadata("Prep_Use_Flag", aircft_mass(i)%Prep_Use_Flag )
202  call nc_diag_metadata("Analysis_Use_Flag", aircft_mass(i)%Analysis_Use_Flag )
203  call nc_diag_metadata("Nonlinear_QC_Rel_Wgt", aircft_mass(i)%Nonlinear_QC_Rel_Wgt )
204  call nc_diag_metadata("Errinv_Input", aircft_mass(i)%Errinv_Input )
205  call nc_diag_metadata("Errinv_Adjust", aircft_mass(i)%Errinv_Adjust )
206  call nc_diag_metadata("Errinv_Final", aircft_mass(i)%Errinv_Final )
207  call nc_diag_metadata("Observation", aircft_mass(i)%Observation )
208  call nc_diag_metadata("Obs_Minus_Forecast_adjusted", aircft_mass(i)%Obs_Minus_Forecast_adjusted )
209  call nc_diag_metadata("Obs_Minus_Forecast_unadjusted", aircft_mass(i)%Obs_Minus_Forecast_unadjusted )
210 
211  endif
212  enddo
213  endif
214 
215  call nc_diag_write
216 
217  enddo
218  end subroutine write_split_aircft_diag_nc
219 
220  subroutine read_aircft_diag_nc_header(infn,aircft_header)
221  character(len=*), intent(in) :: infn
222  type(diag_aircft_header), intent(inout) :: aircft_header
223 
224  integer(i_kind) :: fid,nobs
225 
226  nobs=0
227  call nc_diag_read_init(infn,fid)
228  nobs = nc_diag_read_get_dim(fid,'nobs')
229  call nc_diag_read_get_global_attr(fid,"date_time", aircft_header%date )
230  aircft_header%n_Observations_Mass = nobs
231  aircft_header%n_Observations_Wind = nobs
232  call nc_diag_read_close(infn)
233 
234  end subroutine read_aircft_diag_nc_header
235 
236  subroutine read_aircft_diag_nc_mass(infn, aircft_header, aircft_mass, ierr)
237  character(len=*), intent(in) :: infn
238  type(diag_aircft_header), intent(inout) :: aircft_header
239  type(diag_aircft_mass),pointer, intent(inout) :: aircft_mass(:)
240  integer, intent(out) :: ierr
241 
242  character(20) :: str, str2
243  integer(i_kind) :: ii, ic, fid, nobs, naircft, ncount(1)
244  integer(i_kind), allocatable :: indx(:)
245  character(len=8),allocatable, dimension(:) :: c_var
246  integer(i_kind), allocatable, dimension(:) :: i_var
247  real(r_single), allocatable, dimension(:) :: r_var
248 
249  type(diag_aircft_mass), pointer :: rtmp_mass(:)
250 
251  ierr=0
252  call nc_diag_read_init(infn,fid)
253 
254  nobs=aircft_header%n_Observations_Mass
255  allocate(rtmp_mass(nobs))
256  allocate(c_var(nobs))
257  allocate(i_var(nobs))
258  allocate(r_var(nobs))
259 
260 ! if (aircft_mass(i)%Observation_Class .eq. aircft_header%ObsType(itype) ) then
261 ! call nc_diag_read_get_var(fid,"Station_ID", c_var ); rtmp_mass(:)%Station_ID = c_var
262 ! call nc_diag_read_get_var(fid,"Observation_Class", c_var ); rtmp_mass(:)%Observation_Class = c_var
263  call nc_diag_read_get_var(fid,"Observation_Type", i_var ); rtmp_mass(:)%Observation_Type = i_var
264 ! call nc_diag_read_get_var(fid,"Observation_Subtype", i_var ); rtmp_mass(:)%Observation_Subtype = i_var
265  call nc_diag_read_get_var(fid,"Latitude", r_var ); rtmp_mass(:)%Latitude = r_var
266  call nc_diag_read_get_var(fid,"Longitude", r_var ); rtmp_mass(:)%Longitude = r_var
267  call nc_diag_read_get_var(fid,"Pressure", r_var ); rtmp_mass(:)%Pressure = r_var
268  call nc_diag_read_get_var(fid,"Height", r_var ); rtmp_mass(:)%Height = r_var
269  call nc_diag_read_get_var(fid,"Time", r_var ); rtmp_mass(:)%Time = r_var
270  call nc_diag_read_get_var(fid,"Prep_QC_Mark", r_var ); rtmp_mass(:)%Prep_QC_Mark = r_var
271  call nc_diag_read_get_var(fid,"Setup_QC_Mark", r_var ); rtmp_mass(:)%Setup_QC_Mark = r_var
272  call nc_diag_read_get_var(fid,"Prep_Use_Flag", r_var ); rtmp_mass(:)%Prep_Use_Flag = r_var
273  call nc_diag_read_get_var(fid,"Analysis_Use_Flag", r_var ); rtmp_mass(:)%Analysis_Use_Flag = r_var
274  call nc_diag_read_get_var(fid,"Nonlinear_QC_Rel_Wgt", r_var ); rtmp_mass(:)%Nonlinear_QC_Rel_Wgt = r_var
275  call nc_diag_read_get_var(fid,"Errinv_Input", r_var ); rtmp_mass(:)%Errinv_Input = r_var
276  call nc_diag_read_get_var(fid,"Errinv_Adjust", r_var ); rtmp_mass(:)%Errinv_Adjust = r_var
277  call nc_diag_read_get_var(fid,"Errinv_Final", r_var ); rtmp_mass(:)%Errinv_Final = r_var
278  call nc_diag_read_get_var(fid,"Observation", r_var ); rtmp_mass(:)%Observation = r_var
279  call nc_diag_read_get_var(fid,"Obs_Minus_Forecast_adjusted", r_var ); rtmp_mass(:)%Obs_Minus_Forecast_adjusted = r_var
280  call nc_diag_read_get_var(fid,"Obs_Minus_Forecast_unadjusted",r_var ); rtmp_mass(:)%Obs_Minus_Forecast_unadjusted = r_var
281 ! endif
282  deallocate(r_var)
283  deallocate(i_var)
284  deallocate(c_var)
285 
286  ic=0
287  do ii=1,nobs
288  if(rtmp_mass(ii)%Observation_Type==aircft_mass_type.and.&
289  rtmp_mass(ii)%Setup_QC_Mark==t_qcmark) then
290  ic=ic+1
291  endif
292  enddo
293  naircft=ic
294  allocate(indx(naircft))
295 
296  ic=0
297  do ii=1,nobs
298  if(rtmp_mass(ii)%Observation_Type==aircft_mass_type.and.&
299  rtmp_mass(ii)%Setup_QC_Mark==t_qcmark) then
300  ic=ic+1
301  indx(ic)=ii
302  endif
303  enddo
304 
305  print *, ' found this many aircft ', naircft
306  if(ic /= naircft) then
307  print *, 'error determining Aircraft, inconsistent naircft, ic=', naircft, ic
308  deallocate(indx)
309  deallocate(aircft_mass)
310  ierr = 99
311  return
312  endif
313 
314  if(associated(aircft_mass)) deallocate(aircft_mass)
315  allocate (aircft_mass(naircft))
316  aircft_header%n_Observations_Mass = naircft
317 
318 ! aircft_mass(:)%Station_ID = rtmp_mass(indx)
319 ! aircft_mass(:)%Observation_Class = c_var
320  aircft_mass(:)%Observation_Type = rtmp_mass(indx)%Observation_Type
321 ! aircft_mass(:)%Observation_Subtype = rtmp_mass(indx)%Observation_Subtype
322  aircft_mass(:)%Latitude = rtmp_mass(indx)%Latitude
323  aircft_mass(:)%Longitude = rtmp_mass(indx)%Longitude
324  aircft_mass(:)%Pressure = rtmp_mass(indx)%Pressure
325  aircft_mass(:)%Height = rtmp_mass(indx)%Height
326  aircft_mass(:)%Time = rtmp_mass(indx)%Time
327  aircft_mass(:)%Prep_QC_Mark = rtmp_mass(indx)%Prep_QC_Mark
328  aircft_mass(:)%Setup_QC_Mark = rtmp_mass(indx)%Setup_QC_Mark
329  aircft_mass(:)%Prep_Use_Flag = rtmp_mass(indx)%Prep_Use_Flag
330  aircft_mass(:)%Analysis_Use_Flag = rtmp_mass(indx)%Analysis_Use_Flag
331  aircft_mass(:)%Nonlinear_QC_Rel_Wgt= rtmp_mass(indx)%Nonlinear_QC_Rel_Wgt
332  aircft_mass(:)%Errinv_Input = rtmp_mass(indx)%Errinv_Input
333  aircft_mass(:)%Errinv_Adjust = rtmp_mass(indx)%Errinv_Adjust
334  aircft_mass(:)%Errinv_Final = rtmp_mass(indx)%Errinv_Final
335  aircft_mass(:)%Observation = rtmp_mass(indx)%Observation
336  aircft_mass(:)%Obs_Minus_Forecast_adjusted = rtmp_mass(indx)%Obs_Minus_Forecast_adjusted
337  aircft_mass(:)%Obs_Minus_Forecast_unadjusted = rtmp_mass(indx)%Obs_Minus_Forecast_unadjusted
338 
339  deallocate(indx)
340  deallocate(rtmp_mass)
341 
342  call nc_diag_read_close(infn)
343  end subroutine read_aircft_diag_nc_mass
344 
345  function replace_text (s,text,rep) result(outs)
346  character(*) :: s,text,rep
347  character(len(s)+100) :: outs ! provide outs with extra 100 char len
348  integer :: i, nt, nr
349 
350  outs = s ; nt = len_trim(text) ; nr = len_trim(rep)
351  i = index(outs,text(:nt)) !; IF (i == 0) EXIT
352  outs = outs(:i-1) // rep(:nr) // outs(i+nt:)
353  end function replace_text
354 
355 
356 end module m_diag_aircft
integer, parameter maxobstype
integer, parameter, public strlen
integer, parameter, public i_kind
Definition: ncd_kinds.F90:71
integer(i_kind) function get_obstype_index(obstype, obstypearr)
subroutine nc_diag_init(filename, append)
character(len(s)+100) function replace_text(s, text, rep)
subroutine, public read_aircft_diag_nc_header(infn, aircft_header)
subroutine, public write_split_aircft_diag_nc(infn, aircft_header, aircft_mass, aircft_wind, append_suffix)
subroutine, public read_aircft_diag_nc_mass(infn, aircft_header, aircft_mass, ierr)
subroutine nc_diag_read_close(filename, file_ncdr_id, from_pop)
integer aircft_wind_type
integer aircft_mass_type
integer, parameter, public r_double
Definition: ncd_kinds.F90:80
integer, parameter, public r_single
Definition: ncd_kinds.F90:79
integer, parameter, public r_kind
Definition: ncd_kinds.F90:108
subroutine nc_diag_read_init(filename, file_ncdr_id, from_push)