PageRenderTime 57ms CodeModel.GetById 18ms RepoModel.GetById 1ms app.codeStats 0ms

/wrfv2_fire/share/wrf_fddaobs_in.F

http://github.com/jbeezley/wrf-fire
FORTRAN Legacy | 1917 lines | 1186 code | 202 blank | 529 comment | 93 complexity | e351a9244cba5754755f2c8cd21ad44d MD5 | raw file
Possible License(s): AGPL-1.0

Large files files are truncated, but you can click here to view the full file

  1. !WRF:MEDIATION_LAYER:IO
  2. ! ---
  3. ! This obs-nudging FDDA module (RTFDDA) is developed by the
  4. ! NCAR/RAL/NSAP (National Security Application Programs), under the
  5. ! sponsorship of ATEC (Army Test and Evaluation Commands). ATEC is
  6. ! acknowledged for releasing this capability for WRF community
  7. ! research applications.
  8. !
  9. ! The NCAR/RAL RTFDDA module was adapted, and significantly modified
  10. ! from the obs-nudging module in the standard MM5V3.1 which was originally
  11. ! developed by PSU (Stauffer and Seaman, 1994).
  12. !
  13. ! Yubao Liu (NCAR/RAL): lead developer of the RTFDDA module
  14. ! Al Bourgeois (NCAR/RAL): lead engineer implementing RTFDDA into WRF-ARW
  15. ! Nov. 2006
  16. !
  17. ! References:
  18. !
  19. ! Liu, Y., A. Bourgeois, T. Warner, S. Swerdlin and J. Hacker, 2005: An
  20. ! implementation of obs-nudging-based FDDA into WRF for supporting
  21. ! ATEC test operations. 2005 WRF user workshop. Paper 10.7.
  22. !
  23. ! Liu, Y., A. Bourgeois, T. Warner, S. Swerdlin and W. Yu, 2006: An update
  24. ! on "obs-nudging"-based FDDA for WRF-ARW: Verification using OSSE
  25. ! and performance of real-time forecasts. 2006 WRF user workshop. Paper 4.7.
  26. !
  27. ! Stauffer, D.R., and N.L. Seaman, 1994: Multi-scale four-dimensional data
  28. ! assimilation. J. Appl. Meteor., 33, 416-434.
  29. !
  30. ! http://www.rap.ucar.edu/projects/armyrange/references.html
  31. !
  32. SUBROUTINE wrf_fddaobs_in (grid ,config_flags)
  33. USE module_domain
  34. USE module_configure
  35. USE module_model_constants !rovg
  36. IMPLICIT NONE
  37. TYPE(domain) :: grid
  38. TYPE(grid_config_rec_type), INTENT(IN) :: config_flags
  39. #if ( EM_CORE == 1 )
  40. ! Local variables
  41. integer :: ktau ! timestep index corresponding to xtime
  42. integer :: krest ! restart timestep
  43. integer :: inest ! nest level
  44. integer :: infreq ! input frequency
  45. integer :: nstlev ! nest level
  46. real :: dtmin ! dt in minutes
  47. real :: xtime ! forecast time in minutes
  48. logical :: iprt_in4dob ! print flag
  49. INTEGER ids , ide , jds , jde , kds , kde , &
  50. ims , ime , jms , jme , kms , kme , &
  51. ips , ipe , jps , jpe , kps , kpe
  52. INTEGER ij, its, ite, jts, jte
  53. ! Modified to also call in4dob intially, since subr in4dob is no
  54. ! longer called from subr fddaobs_init. Note that itimestep is now
  55. ! the model step BEFORE the model integration step, because this
  56. ! routine is now called by med_before_solve_io.
  57. ktau = grid%itimestep ! ktau corresponds to xtime
  58. krest = grid%fdob%ktaur
  59. inest = grid%grid_id
  60. nstlev = grid%fdob%levidn(inest)
  61. infreq = grid%obs_ionf*(grid%parent_grid_ratio**nstlev)
  62. iprt_in4dob = grid%obs_ipf_in4dob
  63. IF( (ktau.GT.krest.AND.MOD(ktau,infreq).EQ.0) &
  64. .OR.(ktau.EQ.krest) ) then
  65. ! Calculate forecast time.
  66. dtmin = grid%dt/60.
  67. xtime = grid%xtime
  68. CALL get_ijk_from_grid ( grid , &
  69. ids, ide, jds, jde, kds, kde, &
  70. ims, ime, jms, jme, kms, kme, &
  71. ips, ipe, jps, jpe, kps, kpe )
  72. !$OMP PARALLEL DO &
  73. !$OMP PRIVATE ( ij )
  74. DO ij = 1 , grid%num_tiles
  75. its = grid%i_start(ij)
  76. ite = min(grid%i_end(ij),ide-1)
  77. jts = grid%j_start(ij)
  78. jte = min(grid%j_end(ij),jde-1)
  79. CALL in4dob(inest, xtime, ktau, krest, dtmin, &
  80. grid%julyr, grid%julday, grid%gmt, & !obsnypatch
  81. grid%obs_nudge_opt, grid%obs_nudge_wind, grid%obs_nudge_temp, &
  82. grid%obs_nudge_mois, grid%obs_nudge_pstr, grid%obs_coef_wind, &
  83. grid%obs_coef_temp, grid%obs_coef_mois, grid%obs_coef_pstr, &
  84. grid%obs_rinxy, grid%obs_rinsig, grid%fdob%window, &
  85. grid%obs_npfi, grid%obs_ionf, &
  86. grid%obs_prt_max, grid%obs_prt_freq, &
  87. grid%obs_idynin, &
  88. grid%obs_dtramp, grid%fdob, grid%fdob%varobs, &
  89. grid%fdob%timeob, grid%fdob%nlevs_ob, grid%fdob%lev_in_ob, &
  90. grid%fdob%plfo, grid%fdob%elevob, grid%fdob%rio, &
  91. grid%fdob%rjo, grid%fdob%rko, &
  92. grid%xlat, grid%xlong, &
  93. config_flags%cen_lat, &
  94. config_flags%cen_lon, &
  95. config_flags%stand_lon, &
  96. config_flags%truelat1, config_flags%truelat2, &
  97. grid%fdob%known_lat, grid%fdob%known_lon, &
  98. config_flags%dx, config_flags%dy, rovg, t0, &
  99. grid%fdob%obsprt, &
  100. grid%fdob%latprt, grid%fdob%lonprt, &
  101. grid%fdob%mlatprt, grid%fdob%mlonprt, &
  102. grid%fdob%stnidprt, &
  103. ide, jde, &
  104. ims, ime, jms, jme, &
  105. its, ite, jts, jte, &
  106. config_flags%map_proj, &
  107. model_config_rec%parent_grid_ratio, &
  108. model_config_rec%i_parent_start(inest), &
  109. model_config_rec%j_parent_start(inest), &
  110. model_config_rec%max_dom, &
  111. model_config_rec%nobs_ndg_vars, grid%max_obs, iprt_in4dob)
  112. ENDDO
  113. !$OMP END PARALLEL DO
  114. ENDIF
  115. RETURN
  116. #endif
  117. END SUBROUTINE wrf_fddaobs_in
  118. #if ( EM_CORE == 1 )
  119. !------------------------------------------------------------------------------
  120. ! Begin subroutine in4dob and its subroutines
  121. !------------------------------------------------------------------------------
  122. SUBROUTINE in4dob(inest, xtime, ktau, ktaur, dtmin, &
  123. myear, julday, gmt, & !obsnypatch
  124. nudge_opt, iswind, istemp, &
  125. ismois, ispstr, giv, &
  126. git, giq, gip, &
  127. rinxy, rinsig, twindo, &
  128. npfi, ionf, prt_max, prt_freq, idynin, &
  129. dtramp, fdob, varobs, &
  130. timeob, nlevs_ob, lev_in_ob, &
  131. plfo, elevob, rio, &
  132. rjo, rko, &
  133. xlat, xlong, &
  134. cen_lat, &
  135. cen_lon, &
  136. stand_lon, &
  137. true_lat1, true_lat2, &
  138. known_lat, known_lon, &
  139. dxm, dym, rovg, t0, &
  140. obs_prt, &
  141. lat_prt, lon_prt, &
  142. mlat_prt, mlon_prt, &
  143. stnid_prt, &
  144. e_we, e_sn, &
  145. ims, ime, jms, jme, &
  146. its, ite, jts, jte, &
  147. map_proj, &
  148. parent_grid_ratio, &
  149. i_parent_start, &
  150. j_parent_start, &
  151. maxdom, &
  152. nndgv, niobf, iprt)
  153. USE module_domain
  154. USE module_model_constants, ONLY : rcp
  155. USE module_date_time , ONLY : geth_idts
  156. USE module_llxy
  157. IMPLICIT NONE
  158. ! THIS IS SUBROUTINE READS AN OBSERVATION DATA FILE AND
  159. ! SELECTS ONLY THOSE VALUES OBSERVED AT TIMES THAT FALL
  160. ! WITHIN A TIME WINDOW (TWINDO) CENTERED ABOUT THE CURRENT
  161. ! FORECAST TIME (XTIME). THE INCOMING OBS FILES MUST BE
  162. ! IN CHRONOLOGICAL ORDER.
  163. !
  164. ! NOTE: This routine was originally designed for MM5, which uses
  165. ! a nonstandard (I,J) coordinate system. For WRF, I is the
  166. ! east-west running coordinate, and J is the south-north
  167. ! running coordinate. So "J-slab" here is west-east in
  168. ! extent, not south-north as for MM5. RIO and RJO have
  169. ! the opposite orientation here as for MM5. -ajb 06/10/2004
  170. ! NOTE - IN4DOB IS CALLED ONLY FOR THE COARSE MESH TIMES
  171. ! - VAROBS(IVAR,N) HOLDS THE OBSERVATIONS.
  172. ! IVAR=1 OBS U
  173. ! IVAR=2 OBS V
  174. ! IVAR=3 OBS T
  175. ! IVAR=4 OBS Q
  176. ! IVAR=5 OBS Pressure
  177. ! IVAR=6 OBS Height
  178. INTEGER, intent(in) :: niobf ! maximum number of observations
  179. INTEGER, intent(in) :: nndgv ! number of nudge variables
  180. INTEGER, intent(in) :: INEST ! nest level
  181. REAL, intent(in) :: xtime ! model time in minutes
  182. INTEGER, intent(in) :: KTAU ! current timestep
  183. INTEGER, intent(in) :: KTAUR ! restart timestep
  184. REAL, intent(in) :: dtmin ! dt in minutes
  185. INTEGER, intent(in) :: myear ! model year !obsnypatch
  186. INTEGER, intent(in) :: julday ! Julian day
  187. REAL, intent(in) :: gmt ! Model GMT at start of run
  188. INTEGER, intent(in) :: nudge_opt ! obs-nudge flag for this nest
  189. INTEGER, intent(in) :: iswind ! nudge flag for wind
  190. INTEGER, intent(in) :: istemp ! nudge flag for temperature
  191. INTEGER, intent(in) :: ismois ! nudge flag for moisture
  192. INTEGER, intent(in) :: ispstr ! nudge flag for pressure (obsolete)
  193. REAL, intent(in) :: giv ! coefficient for wind
  194. REAL, intent(in) :: git ! coefficient for temperature
  195. REAL, intent(in) :: giq ! coefficient for moisture
  196. REAL, intent(in) :: gip ! coefficient for pressure
  197. REAL, intent(in) :: rinxy ! horizontal radius of influence (km)
  198. REAL, intent(in) :: rinsig ! vertical radius of influence (on sigma)
  199. REAL, intent(inout) :: twindo ! (time window)/2 (min) for nudging
  200. INTEGER, intent(in) :: npfi ! coarse-grid time-step frequency for diagnostics
  201. INTEGER, intent(in) :: ionf ! coarse-grid time-step frequency for obs-nudging calcs
  202. INTEGER, intent(in) :: prt_max ! max number of entries of obs for diagnostic printout
  203. INTEGER, intent(in) :: prt_freq ! frequency (in obs index) for diagnostic printout.
  204. INTEGER, intent(in) :: idynin ! for dynamic initialization using a ramp-down function
  205. REAL, intent(in) :: dtramp ! time period in minutes for ramping
  206. TYPE(fdob_type), intent(inout) :: fdob ! derived data type for obs data
  207. REAL, intent(inout) :: varobs(nndgv,niobf) ! observational values in each variable
  208. REAL, intent(inout) :: timeob(niobf) ! model times for each observation (hours)
  209. REAL, intent(inout) :: nlevs_ob(niobf) ! numbers of levels in sounding obs
  210. REAL, intent(inout) :: lev_in_ob(niobf) ! level in sounding-type obs
  211. REAL, intent(inout) :: plfo(niobf) ! index for type of obs-platform
  212. REAL, intent(inout) :: elevob(niobf) ! elevations of observations (meters)
  213. REAL, intent(inout) :: rio(niobf) ! west-east grid coordinate (non-staggered grid)
  214. REAL, intent(inout) :: rjo(niobf) ! south-north grid coordinate (non-staggered grid)
  215. REAL, intent(inout) :: rko(niobf) ! vertical grid coordinate
  216. REAL, DIMENSION( ims:ime, jms:jme ), &
  217. INTENT(IN ) :: xlat, xlong ! lat/lon on mass-pt grid (for diagnostics only)
  218. REAL, intent(in) :: cen_lat ! center latitude for map projection
  219. REAL, intent(in) :: cen_lon ! center longitude for map projection
  220. REAL, intent(in) :: stand_lon ! standard longitude for map projection
  221. REAL, intent(in) :: true_lat1 ! truelat1 for map projection
  222. REAL, intent(in) :: true_lat2 ! truelat2 for map projection
  223. REAL, intent(in) :: known_lat ! latitude of domain origin point (i,j)=(1,1)
  224. REAL, intent(in) :: known_lon ! longigude of domain origin point (i,j)=(1,1)
  225. REAL, intent(in) :: dxm ! grid size in x (meters)
  226. REAL, intent(in) :: dym ! grid size in y (meters)
  227. REAL, intent(in) :: rovg ! constant rho over g
  228. REAL, intent(in) :: t0 ! background temperature
  229. INTEGER, intent(inout) :: obs_prt(prt_max) ! For printout of obs index
  230. REAL, intent(inout) :: lat_prt(prt_max) ! For printout of obs latitude
  231. REAL, intent(inout) :: lon_prt(prt_max) ! For printout of obs longitude
  232. REAL, intent(inout) :: mlat_prt(prt_max) ! For printout of model lat at obs (ri,rj)
  233. REAL, intent(inout) :: mlon_prt(prt_max) ! For printout of model lon at obs (ri,rj)
  234. INTEGER, intent(inout) :: stnid_prt(40,prt_max) ! For printout of model lon at obs (ri,rj)
  235. INTEGER, intent(in) :: e_we ! max grid index in south-north coordinate
  236. INTEGER, intent(in) :: e_sn ! max grid index in west-east coordinate
  237. INTEGER, intent(in) :: ims ! grid memory start index (west-east dim)
  238. INTEGER, intent(in) :: ime ! grid memory end index (west-east dim)
  239. INTEGER, intent(in) :: jms ! grid memory start index (south-north dim)
  240. INTEGER, intent(in) :: jme ! grid memory end index (south-north dim)
  241. INTEGER, intent(in) :: its ! grid tile start index (west-east dim)
  242. INTEGER, intent(in) :: ite ! grid tile end index (west-east dim)
  243. INTEGER, intent(in) :: jts ! grid tile start index (south-north dim)
  244. INTEGER, intent(in) :: jte ! grid tile end index (south-north dim)
  245. INTEGER, intent(in) :: map_proj ! map projection index
  246. INTEGER, intent(in) :: parent_grid_ratio ! parent to nest grid ration
  247. INTEGER, intent(in) :: i_parent_start ! starting i coordinate in parent domain
  248. INTEGER, intent(in) :: j_parent_start ! starting j coordinate in parent domain
  249. INTEGER, intent(in) :: maxdom ! maximum number of domains
  250. LOGICAL, intent(in) :: iprt ! print flag
  251. !*** DECLARATIONS FOR IMPLICIT NONE
  252. integer :: n, ndum, nopen, nvol, idate, imm, iss
  253. integer :: nlast ! last obs in list of valid obs from prev window
  254. integer :: nsta ! number of stations held in timeobs array
  255. integer :: nstaw ! # stations within the actual time window
  256. integer :: nprev ! previous n in obs read loop (for printout only)
  257. integer :: meas_count, imc, njend, njc, njcc, julob, kn
  258. real :: hourob, rjulob
  259. real :: xhour, tback, tforwd, rjdate1, timanl1, rtimob
  260. real :: rj, ri, elevation, pressure_data
  261. real :: pressure_qc, height_data, height_qc, temperature_data
  262. real :: temperature_qc, u_met_data, u_met_qc, v_met_data
  263. real :: v_met_qc, rh_data, rh_qc, r_data, slp_data, slp_qc
  264. real :: ref_pres_data, ref_pres_qc, psfc_data, psfc_qc
  265. real :: precip_data, precip_qc, tbar, twdop
  266. real*8 :: tempob
  267. INTEGER, EXTERNAL :: nvals_le_limit ! for finding #obs with timeobs <= tforwd
  268. ! Local variables
  269. TYPE (PROJ_INFO) :: obs_proj ! Structure for obs projection information.
  270. character*14 date_char
  271. character*19 obs_date !obsnypatch
  272. integer idts !obsnypatch
  273. character*40 platform,source,id,namef
  274. character*2 fonc
  275. character(len=200) :: msg ! Argument to wrf_message
  276. real latitude,longitude
  277. logical :: newpass ! New pass flag (used for printout)
  278. logical is_sound,bogus
  279. LOGICAL OPENED,exist
  280. integer :: ieof(5),ifon(5)
  281. data ieof/0,0,0,0,0/
  282. data ifon/0,0,0,0,0/
  283. integer :: nmove, nvola
  284. integer :: iyear, itimob !obsnypatch
  285. integer :: errcnt
  286. DATA NMOVE/0/,NVOLA/61/
  287. ! if(ieof(inest).eq.2.and.fdob%nstat.eq.0)then
  288. ! IF (iprt) print *,'returning from in4dob'
  289. ! return
  290. ! endif
  291. ! IF (iprt) print *,'start in4dob ',inest,xtime
  292. IF(nudge_opt.NE.1)RETURN
  293. ! Initialize obs for printout
  294. obs_prt = -999
  295. newpass = .true.
  296. errcnt = 0
  297. ! if start time, or restart time, set obs array to missing value
  298. IF(KTAU.EQ.0.OR.KTAU.EQ.KTAUR) THEN
  299. DO N=1,NIOBF
  300. TIMEOB(N)=99999.
  301. ENDDO
  302. fdob%xtime_at_rest = xtime !yliu 20080127
  303. ENDIF
  304. ! set number of obs=0 if at start or restart
  305. IF(KTAU.EQ.KTAUR)fdob%NSTAT=0
  306. NSTA=fdob%NSTAT
  307. XHOUR=XTIME/60.
  308. XHOUR=AMAX1(XHOUR,0.0)
  309. ! DEFINE THE MAX LIMITS OF THE WINDOW
  310. TBACK=XHOUR-TWINDO
  311. TFORWD=XHOUR+TWINDO
  312. IF (iprt) then
  313. write(msg,fmt='(2(a,f8.3),a,i2)') &
  314. 'OBS NUDGING: Reading new obs for time window TBACK = ', &
  315. tback,' TFORWD = ',tforwd,' for grid = ',inest
  316. call wrf_message(msg)
  317. ENDIF
  318. ! For obs that have become invalid because they are too old for the current time
  319. ! window, mark with 99999 to set up for removal from the rolling valid-obs list.
  320. IF(NSTA.NE.0) THEN
  321. NDUM=0
  322. t_window : DO N=1,NSTA+1
  323. IF((TIMEOB(N)-TBACK).LT.0) THEN
  324. TIMEOB(N)=99999.
  325. ENDIF
  326. IF(TIMEOB(N).LT.9.E4) EXIT t_window
  327. NDUM=N
  328. ENDDO t_window
  329. IF (iprt .and. ndum>0) THEN
  330. write(msg,fmt='(a,i5,2a)') 'OBS NUDGING: ',ndum,' previously read obs ', &
  331. 'are now too old for the current window and have been removed.'
  332. call wrf_message(msg)
  333. ENDIF
  334. ! REMOVE OLD OBS DENOTED BY 99999. AT THE FRONT OF TIMEOB ARRAY
  335. ! IF (iprt) print *,'ndum at 20=',ndum
  336. NDUM=ABS(NDUM)
  337. NMOVE=NIOBF-NDUM
  338. IF(NMOVE.GT.0 .AND. NDUM.NE.0 ) THEN
  339. DO N=1,NMOVE
  340. do KN = 1,nndgv
  341. VAROBS(KN,N)=VAROBS(KN,N+NDUM)
  342. enddo
  343. ! RIO is the west-east coordinate. RJO is south-north. (ajb)
  344. RJO(N)=RJO(N+NDUM)
  345. RIO(N)=RIO(N+NDUM)
  346. RKO(N)=RKO(N+NDUM)
  347. TIMEOB(N)=TIMEOB(N+NDUM)
  348. nlevs_ob(n)=nlevs_ob(n+ndum)
  349. lev_in_ob(n)=lev_in_ob(n+ndum)
  350. plfo(n)=plfo(n+ndum)
  351. elevob(n)=elevob(n+ndum)
  352. ENDDO
  353. ENDIF
  354. NOPEN=NMOVE+1
  355. IF(NOPEN.LE.NIOBF) THEN
  356. DO N=NOPEN,NIOBF
  357. do KN = 1,nndgv
  358. VAROBS(KN,N)=99999.
  359. enddo
  360. RIO(N)=99999.
  361. RJO(N)=99999.
  362. RKO(N)=99999.
  363. TIMEOB(N)=99999.
  364. nlevs_ob(n)=99999.
  365. lev_in_ob(n)=99999.
  366. plfo(n)=99999.
  367. elevob(n)=99999.
  368. ENDDO
  369. ENDIF
  370. ENDIF
  371. ! Compute map projection info.
  372. call set_projection(obs_proj, map_proj, cen_lat, cen_lon, &
  373. true_lat1, true_lat2, stand_lon, &
  374. known_lat, known_lon, &
  375. e_we, e_sn, dxm, dym )
  376. ! FIND THE LAST OBS IN THE LIST
  377. NLAST=0
  378. last_ob : DO N=1,NIOBF
  379. ! print *,'nlast,n,timeob(n)=',nlast,n,timeob(n)
  380. IF(TIMEOB(N).GT.9.E4) EXIT last_ob
  381. NLAST=N
  382. ENDDO last_ob
  383. ! print *,'in4dob, after 90 ',nlast,ktau,ktaur,nsta
  384. ! open file if at beginning or restart
  385. IF(KTAU.EQ.0.OR.KTAU.EQ.KTAUR) THEN
  386. fdob%RTLAST=-999.
  387. INQUIRE (NVOLA+INEST-1,OPENED=OPENED)
  388. IF (.NOT. OPENED) THEN
  389. ifon(inest)=1
  390. write(fonc(1:2),'(i2)')ifon(inest)
  391. if(fonc(1:1).eq.' ')fonc(1:1)='0'
  392. INQUIRE (file='OBS_DOMAIN'//CHAR(INEST+ICHAR('0'))//fonc(1:2) &
  393. ,EXIST=exist)
  394. if(exist)then
  395. IF (iprt) THEN
  396. write(msg,*) 'opening first fdda obs file, fonc=', &
  397. fonc,' inest=',inest
  398. call wrf_message(msg)
  399. write(msg,*) 'ifon=',ifon(inest)
  400. call wrf_message(msg)
  401. ENDIF
  402. OPEN(NVOLA+INEST-1, &
  403. FILE='OBS_DOMAIN'//CHAR(INEST+ICHAR('0'))//fonc(1:2), &
  404. FORM='FORMATTED',STATUS='OLD')
  405. else
  406. ! no first file to open
  407. IF (iprt) call wrf_message("there are no fdda obs files to open")
  408. return
  409. endif
  410. ENDIF
  411. ENDIF !end if(KTAU.EQ.0.OR.KTAU.EQ.KTAUR)
  412. ! print *,'at jc check1'
  413. !**********************************************************************
  414. ! -------------- BIG 100 LOOP OVER N --------------
  415. !**********************************************************************
  416. ! NOW CHECK TO SEE IF EXTRA DATA MUST BE READ IN FROM THE
  417. ! DATA FILE. CONTINUE READING UNTIL THE REACHING THE EOF
  418. ! (DATA TIME IS NEGATIVE) OR FIRST TIME PAST TFORWD. THE
  419. ! LAST OBS CURRENTLY AVAILABLE IS IN N=NMOVE.
  420. N=NLAST
  421. IF(N.EQ.0)GOTO 110
  422. 1001 continue
  423. ! ieof=2 means no more files
  424. IF(IEOF(inest).GT.1) then
  425. GOTO 130
  426. endif
  427. 100 CONTINUE
  428. !ajb 20070116 bugfix for zero array index. N=0 if first obs is not in the domain.
  429. IF(N.ne.0) THEN
  430. IF(TIMEOB(N).GT.TFORWD.and.timeob(n).lt.99999.) THEN
  431. GOTO 130
  432. ENDIF
  433. ENDIF
  434. ! OBSFILE: no more data in the obsfile
  435. ! AJB note: This is where we would implement multi-file reading.
  436. if(ieof(inest).eq.1 )then
  437. ieof(inest)=2
  438. goto 130
  439. endif
  440. !**********************************************************************
  441. ! -------------- 110 SUBLOOP OVER N --------------
  442. !**********************************************************************
  443. 110 continue
  444. ! THE TIME OF THE MOST RECENTLY ACQUIRED OBS IS .LE. TFORWD,
  445. ! SO CONTINUE READING
  446. IF(N.GT.NIOBF-1)GOTO 120
  447. ! REPLACE NVOLA WITH LUN 70, AND USE NVOLA AS A FILE COUNTER
  448. NVOL=NVOLA+INEST-1
  449. IF(fdob%IEODI.EQ.1)GOTO 111
  450. read(nvol,101,end=111,err=111)date_char
  451. 101 FORMAT(1x,a14)
  452. n=n+1
  453. ! Convert the form of the observation date for geth_idts.
  454. call fmt_date(date_char, obs_date)
  455. ! Compute the time period in seconds from the model reference
  456. ! date (fdob%sdate) until the observation date.
  457. call geth_idts(obs_date, fdob%sdate(1:19), idts)
  458. ! Convert time in seconds to hours.
  459. ! In case of restart, correct for new sdate.
  460. idts = idts + nint(fdob%xtime_at_rest*60.) ! yliu 20080127
  461. rtimob =float(idts)/3600.
  462. timeob(n)=rtimob
  463. ! print *,'read in ob ',n,timeob(n),rtimob
  464. IF(IDYNIN.EQ.1.AND.TIMEOB(N)*60..GT.fdob%DATEND) THEN
  465. IF (iprt) THEN
  466. write(msg,*) ' IN4DOB: FOR INEST = ',INEST,' AT XTIME = ',XTIME, &
  467. ' TIMEOB = ',TIMEOB(N)*60.,' AND DATEND = ',fdob%DATEND,' :'
  468. call wrf_message(msg)
  469. write(msg,*) ' END-OF-DATA FLAG SET FOR OBS-NUDGING', &
  470. ' DYNAMIC INITIALIZATION'
  471. call wrf_message(msg)
  472. ENDIF
  473. fdob%IEODI=1
  474. TIMEOB(N)=99999.
  475. rtimob=timeob(n)
  476. ENDIF
  477. read(nvol,102)latitude,longitude
  478. 102 FORMAT(2x,2(f9.4,1x))
  479. ! if(ifon.eq.4)print *,'ifon=4',latitude,longitude
  480. ! this works only for lc projection
  481. ! yliu: add llxy for all 3 projection
  482. !ajb Arguments ri and rj have been switched from MM5 orientation.
  483. CALL latlon_to_ij(obs_proj, latitude, longitude, ri, rj)
  484. !ajb ri and rj are referenced to the non-staggered grid (not mass-pt!).
  485. ! (For MM5, they were referenced to the dot grid.)
  486. ri = ri + .5 !ajb Adjust from mass-pt to non-staggered grid.
  487. rj = rj + .5 !ajb Adjust from mass-pt to non-staggered grid.
  488. rio(n)=ri
  489. rjo(n)=rj
  490. read(nvol,1021)id,namef
  491. 1021 FORMAT(2x,2(a40,3x))
  492. read(nvol,103)platform,source,elevation,is_sound,bogus,meas_count
  493. 103 FORMAT( 2x,2(a16,2x),f8.0,2x,2(l4,2x),i5)
  494. ! write(6,*) '----- OBS description ----- '
  495. ! write(6,*) 'platform,source,elevation,is_sound,bogus,meas_count:'
  496. ! write(6,*) platform,source,elevation,is_sound,bogus,meas_count
  497. ! yliu
  498. elevob(n)=elevation
  499. ! jc
  500. ! change platform from synop to profiler when needed
  501. if(namef(2:9).eq.'PROFILER')platform(7:14)='PROFILER'
  502. ! yliu
  503. if(namef(2:6).eq.'ACARS')platform(7:11)='ACARS'
  504. if(namef(1:7).eq.'SATWNDS') platform(1:11)='SATWNDS '
  505. if(namef(1:8).eq.'CLASS DA')platform(7:10)='TEMP'
  506. ! yliu end
  507. rko(n)=-99.
  508. !yliu 20050706
  509. ! if((platform(7:11).eq.'METAR').or.(platform(7:11).eq.'SPECI').or.
  510. ! 1 (platform(7:10).eq.'SHIP').or.(platform(7:11).eq.'SYNOP').or.
  511. ! 1 (platform(1:4).eq.'SAMS'))
  512. ! 1 rko(n)=1.0
  513. if(.NOT. is_sound) rko(n)=1.0
  514. !yliu 20050706 end
  515. ! plfo is inFORMATion on what platform. May use this later in adjusting weights
  516. plfo(n)=99.
  517. if(platform(7:11).eq.'METAR')plfo(n)=1.
  518. if(platform(7:11).eq.'SPECI')plfo(n)=2.
  519. if(platform(7:10).eq.'SHIP')plfo(n)=3.
  520. if(platform(7:11).eq.'SYNOP')plfo(n)=4.
  521. if(platform(7:10).eq.'TEMP')plfo(n)=5.
  522. if(platform(7:11).eq.'PILOT')plfo(n)=6.
  523. if(platform(1:7).eq.'SATWNDS')plfo(n)=7.
  524. if(platform(7:11).eq.'SATWI')plfo(n)=7.
  525. if(platform(1:4).eq.'SAMS')plfo(n)=8.
  526. if(platform(7:14).eq.'PROFILER')plfo(n)=9.
  527. ! yliu: ACARS->SATWINDS
  528. if(platform(7:11).eq.'ACARS')plfo(n)=7.
  529. ! yliu: end
  530. if(plfo(n).eq.99.) then
  531. IF (iprt) then
  532. write(msg,*) 'n=',n,' unknown ob of type ',platform
  533. call wrf_message(msg)
  534. ENDIF
  535. endif
  536. !======================================================================
  537. !======================================================================
  538. ! THIS PART READS SOUNDING INFO
  539. IF(is_sound)THEN
  540. nlevs_ob(n)=real(meas_count)
  541. lev_in_ob(n)=1.
  542. do imc=1,meas_count
  543. ! write(6,*) '0 inest = ',inest,' n = ',n
  544. ! the sounding has one header, many levels. This part puts it into
  545. ! "individual" observations. There's no other way for nudob to deal
  546. ! with it.
  547. if(imc.gt.1)then ! sub-loop over N
  548. n=n+1
  549. if(n.gt.niobf)goto 120
  550. nlevs_ob(n)=real(meas_count)
  551. lev_in_ob(n)=real(imc)
  552. timeob(n)=rtimob
  553. rio(n)=ri
  554. rjo(n)=rj
  555. rko(n)=-99.
  556. plfo(n)=plfo(n-imc+1)
  557. elevob(n)=elevation
  558. endif
  559. read(nvol,104)pressure_data,pressure_qc, &
  560. height_data,height_qc, &
  561. temperature_data,temperature_qc, &
  562. u_met_data,u_met_qc, &
  563. v_met_data,v_met_qc, &
  564. rh_data,rh_qc
  565. 104 FORMAT( 1x,6(f11.3,1x,f11.3,1x))
  566. ! yliu: Ensemble - add disturbance to upr obs
  567. ! if(plfo(n).eq.5.or.plfo(n).eq.6.or.plfo(n).eq.9) then FORE07E08
  568. ! if(imc.eq.1) then FORE07E08
  569. ! call srand(n)
  570. ! t_rand =- (rand(2)-0.5)*6
  571. ! call srand(n+100000)
  572. ! u_rand =- (rand(2)-0.5)*6
  573. ! call srand(n+200000)
  574. ! v_rand =- (rand(2)-0.5)*6
  575. ! endif FORE07E08
  576. ! if(temperature_qc.ge.0..and.temperature_qc.lt.30000..and.
  577. ! & temperature_data .gt. -88880.0 )
  578. ! & temperature_data = temperature_data + t_rand
  579. ! if((u_met_qc.ge.0..and.u_met_qc.lt.30000.).and.
  580. ! & (v_met_qc.ge.0..and.v_met_qc.lt.30000.).and.
  581. ! make sure at least 1 of the components is .ne.0
  582. ! & (u_met_data.ne.0..or.v_met_data.ne.0.) .and.
  583. ! & (u_met_data.gt.-88880.0 .and. v_met_data.gt.-88880.0) )then
  584. ! u_met_data = u_met_data + u_rand
  585. ! v_met_data = v_met_data + v_rand
  586. ! endif
  587. ! endif FORE07E08
  588. ! yliu: Ens test - end
  589. ! jc
  590. ! hardwire to switch -777777. qc to 0. here temporarily
  591. ! -777777. is a sounding level that no qc was done on.
  592. if(temperature_qc.eq.-777777.)temperature_qc=0.
  593. if(pressure_qc.eq.-777777.)pressure_qc=0.
  594. if(height_qc.eq.-777777.)height_qc=0.
  595. if(u_met_qc.eq.-777777.)u_met_qc=0.
  596. if(v_met_qc.eq.-777777.)v_met_qc=0.
  597. if(rh_qc.eq.-777777.)rh_qc=0.
  598. if(temperature_data.eq.-888888.)temperature_qc=-888888.
  599. if(pressure_data.eq.-888888.)pressure_qc=-888888.
  600. if(height_data.eq.-888888.)height_qc=-888888.
  601. if(u_met_data.eq.-888888.)u_met_qc=-888888.
  602. if(v_met_data.eq.-888888.)v_met_qc=-888888.
  603. if(rh_data.eq.-888888.)rh_qc=-888888.
  604. ! jc
  605. ! Hardwire so that only use winds in pilot obs (no winds from temp) and
  606. ! only use temperatures and rh in temp obs (no temps from pilot obs)
  607. ! Do this because temp and pilot are treated as 2 platforms, but pilot
  608. ! has most of the winds, and temp has most of the temps. If use both,
  609. ! the second will smooth the effect of the first. Usually temps come in after
  610. ! pilots. pilots usually don't have any temps, but temp obs do have some
  611. ! winds usually.
  612. ! plfo=5 is TEMP ob, range sounding is an exception
  613. !yliu start -- comment out to test with merged PILOT and TEMP and
  614. ! do not use obs interpolated by little_r
  615. ! if(plfo(n).eq.5. .and. namef(1:8).ne.'CLASS DA')then
  616. ! u_met_data=-888888.
  617. ! v_met_data=-888888.
  618. ! u_met_qc=-888888.
  619. ! v_met_qc=-888888.
  620. ! endif
  621. if(plfo(n).eq.5..and.(u_met_qc.eq.256..or.v_met_qc.eq.256.))then
  622. u_met_data=-888888.
  623. v_met_data=-888888.
  624. u_met_qc=-888888.
  625. v_met_qc=-888888.
  626. endif
  627. !yliu end
  628. ! plfo=6 is PILOT ob
  629. if(plfo(n).eq.6.)then
  630. temperature_data=-888888.
  631. rh_data=-888888.
  632. temperature_qc=-888888.
  633. rh_qc=-888888.
  634. endif
  635. !ajb Store temperature for WRF
  636. ! NOTE: The conversion to potential temperature, performed later in subroutine
  637. ! errob, requires good pressure data, either directly or via good height data.
  638. ! So here, in addition to checking for good temperature data, we must also
  639. ! do a check for good pressure or height.
  640. if(temperature_qc.ge.0..and.temperature_qc.lt.30000.)then
  641. if( (pressure_qc.ge.0..and.pressure_qc.lt.30000.) .or. &
  642. (height_qc .ge.0..and.height_qc .lt.30000.) ) then
  643. varobs(3,n) = temperature_data
  644. else
  645. varobs(3,n)=-888888.
  646. endif
  647. else
  648. varobs(3,n)=-888888.
  649. endif
  650. !ajb Store obs height
  651. if(height_qc.ge.0..and.height_qc.lt.30000.)then
  652. varobs(6,n)=height_data
  653. else
  654. varobs(6,n)=-888888.
  655. endif
  656. if(pressure_qc.ge.0..and.pressure_qc.lt.30000.)then
  657. ! if(pressure_qc.ge.0.)then
  658. varobs(5,n)=pressure_data
  659. else
  660. varobs(5,n)=-888888.
  661. IF (iprt) THEN
  662. if(varobs(6,n).eq.-888888.000) then
  663. if (errcnt.le.10) then
  664. write(msg,*) '*** PROBLEM: sounding, p and ht undefined',latitude,longitude
  665. call wrf_message(msg)
  666. errcnt = errcnt + 1
  667. if (errcnt.gt.10) call wrf_message("MAX of 10 warnings issued.")
  668. endif
  669. endif
  670. ENDIF
  671. endif
  672. if(varobs(5,n).ge.0.)varobs(5,n)=varobs(5,n)*1.e-3
  673. ! don't use data above 80 mb
  674. if((varobs(5,n).gt.0.).and.(varobs(5,n).le.8.))then
  675. u_met_data=-888888.
  676. v_met_data=-888888.
  677. u_met_qc=-888888.
  678. v_met_qc=-888888.
  679. temperature_data=-888888.
  680. temperature_qc=-888888.
  681. rh_data=-888888.
  682. rh_qc=-888888.
  683. endif
  684. ! Store horizontal wind components for WRF
  685. if((u_met_qc.ge.0..and.u_met_qc.lt.30000.).and. &
  686. (v_met_qc.ge.0..and.v_met_qc.lt.30000.).and. &
  687. ! make sure at least 1 of the components is .ne.0
  688. (u_met_data.ne.0..or.v_met_data.ne.0.))then
  689. ! If Earth-relative wind vector, need to rotate it to grid-relative coords
  690. if(u_met_qc.eq.129. .and. v_met_qc.eq.129.) then
  691. CALL rotate_vector(longitude,u_met_data,v_met_data, &
  692. obs_proj,map_proj)
  693. endif
  694. varobs(1,n)=u_met_data
  695. varobs(2,n)=v_met_data
  696. else
  697. varobs(1,n)=-888888.
  698. varobs(2,n)=-888888.
  699. endif
  700. r_data=-888888.
  701. if(rh_qc.ge.0..and.rh_qc.lt.30000.)then
  702. if((pressure_qc.ge.0.).and.(temperature_qc.ge.0.).and. &
  703. (pressure_qc.lt.30000.).and.(temperature_qc.lt.30000.))then
  704. call rh2r(rh_data,temperature_data,pressure_data*.01, &
  705. r_data,0) ! yliu, change last arg from 1 to 0
  706. else
  707. ! print *,'rh, but no t or p to convert',temperature_qc, &
  708. ! pressure_qc,n
  709. r_data=-888888.
  710. endif
  711. endif
  712. varobs(4,n)=r_data
  713. enddo ! end do imc=1,meas_count
  714. ! print *,'--- sdng n=',n,nlevs_ob(n),lev_in_ob(n),timeob(n)
  715. ! read in non-sounding obs
  716. ELSEIF(.NOT.is_sound)THEN
  717. nlevs_ob(n)=1.
  718. lev_in_ob(n)=1.
  719. read(nvol,105)slp_data,slp_qc, &
  720. ref_pres_data,ref_pres_qc, &
  721. height_data,height_qc, &
  722. temperature_data,temperature_qc, &
  723. u_met_data,u_met_qc, &
  724. v_met_data,v_met_qc, &
  725. rh_data,rh_qc, &
  726. psfc_data,psfc_qc, &
  727. precip_data,precip_qc
  728. 105 FORMAT( 1x,9(f11.3,1x,f11.3,1x))
  729. ! Ensemble: add disturbance to sfc obs
  730. ! call srand(n)
  731. ! t_rand =+ (rand(2)-0.5)*5
  732. ! call srand(n+100000)
  733. ! u_rand =+ (rand(2)-0.5)*5
  734. ! call srand(n+200000)
  735. ! v_rand =+ (rand(2)-0.5)*5
  736. ! if(temperature_qc.ge.0..and.temperature_qc.lt.30000. .and.
  737. ! & temperature_data .gt. -88880.0 )
  738. ! & temperature_data = temperature_data + t_rand
  739. ! if((u_met_qc.ge.0..and.u_met_qc.lt.30000.).and.
  740. ! & (v_met_qc.ge.0..and.v_met_qc.lt.30000.).and.
  741. ! make sure at least 1 of the components is .ne.0
  742. ! & (u_met_data.ne.0..or.v_met_data.ne.0.) .and.
  743. ! & (u_met_data.gt.-88880.0 .and. v_met_data.gt.-88880.0) )then
  744. ! u_met_data = u_met_data + u_rand
  745. ! v_met_data = v_met_data + v_rand
  746. ! endif
  747. ! yliu: Ens test - end
  748. !Lilis
  749. ! calculate psfc if slp is there
  750. if((psfc_qc.lt.0.).and.(slp_qc.ge.0..and.slp_qc.lt.30000.).and. &
  751. (temperature_qc.ge.0..and.temperature_qc.lt.30000.).and. &
  752. (slp_data.gt.90000.))then
  753. tbar=temperature_data+0.5*elevation*.0065
  754. psfc_data=slp_data*exp(-elevation/(rovg*tbar))
  755. varobs(5,n)=psfc_data
  756. psfc_qc=0.
  757. endif
  758. !c *No* **Very rough** estimate of psfc from sfc elevation if UUtah ob and elev>1000m
  759. ! estimate psfc from temp and elevation
  760. ! Do not know sfc pressure in model at this point.
  761. ! if((psfc_qc.lt.0.).and.(elevation.gt.1000.).and.
  762. ! 1 (temperature_qc.ge.0..and.temperature_qc.lt.30000.)
  763. ! 1 .and.(platform(7:16).eq.'SYNOP PRET'))then
  764. if((psfc_qc.lt.0.).and. &
  765. (temperature_qc.ge.0..and.temperature_qc.lt.30000.))then
  766. tbar=temperature_data+0.5*elevation*.0065
  767. psfc_data=100000.*exp(-elevation/(rovg*tbar))
  768. varobs(5,n)=psfc_data
  769. psfc_qc=0.
  770. endif
  771. if((psfc_qc.ge.0..and.psfc_qc.lt.30000.).and.(psfc_data.gt.70000. &
  772. .and.psfc_data.lt.105000.))then
  773. varobs(5,n)=psfc_data
  774. else
  775. varobs(5,n)=-888888.
  776. endif
  777. if(varobs(5,n).ge.0.)varobs(5,n)=varobs(5,n)*1.e-3
  778. !Lilie
  779. !ajb Store temperature for WRF
  780. if(temperature_qc.ge.0..and.temperature_qc.lt.30000.)then
  781. if((psfc_qc.ge.0..and.psfc_qc.lt.30000.).and. &
  782. (psfc_data.gt.70000. .and.psfc_data.lt.105000.))then
  783. varobs(3,n) = temperature_data
  784. else
  785. varobs(3,n)=-888888.
  786. endif
  787. else
  788. varobs(3,n)=-888888.
  789. endif
  790. ! Store horizontal wind components for WRF
  791. if((u_met_qc.ge.0..and.u_met_qc.lt.30000.).and. &
  792. (v_met_qc.ge.0..and.v_met_qc.lt.30000.).and. &
  793. ! make sure at least 1 of the components is .ne.0
  794. (u_met_data.ne.0..or.v_met_data.ne.0.))then
  795. ! If Earth-relative wind vector, need to rotate it to grid-relative coords
  796. if(u_met_qc.eq.129. .and. v_met_qc.eq.129.) then
  797. CALL rotate_vector(longitude,u_met_data,v_met_data, &
  798. obs_proj,map_proj)
  799. endif
  800. varobs(1,n)=u_met_data
  801. varobs(2,n)=v_met_data
  802. else
  803. varobs(1,n)=-888888.
  804. varobs(2,n)=-888888.
  805. endif
  806. ! jc
  807. ! if a ship ob has rh<70%, then throw out
  808. if(plfo(n).eq.3..and.rh_qc.ge.0..and.rh_data.lt.70.)then
  809. rh_qc=-888888.
  810. rh_data=-888888.
  811. endif
  812. !
  813. r_data=-888888.
  814. if(rh_qc.ge.0..and.rh_qc.lt.30000.)then
  815. if((psfc_qc.ge.0..and.psfc_qc.lt.30000.) &
  816. .and.(temperature_qc.ge.0..and.temperature_qc.lt.30000.))then
  817. ! rh_data=amin1(rh_data,96.) ! yliu: do not allow surface to be saturated
  818. call rh2r(rh_data,temperature_data,psfc_data*.01, &
  819. r_data,0) ! yliu, change last arg from 1 to 0
  820. else
  821. ! print *,'rh, but no t or p',temperature_data,
  822. ! 1 psfc_data,n
  823. r_data=-888888.
  824. endif
  825. endif
  826. varobs(4,n)=r_data
  827. ELSE
  828. IF (iprt) THEN
  829. call wrf_message(" ====== ")
  830. call wrf_message(" NO Data Found ")
  831. ENDIF
  832. ENDIF !end if(is_sound)
  833. ! END OF SFC OBS INPUT SECTION
  834. !======================================================================
  835. !======================================================================
  836. ! check if ob time is too early (only applies to beginning)
  837. IF(RTIMOB.LT.TBACK-TWINDO)then
  838. IF (iprt) call wrf_message("ob too early")
  839. n=n-1
  840. GOTO 110
  841. ENDIF
  842. ! check if this ob is a duplicate
  843. ! this check has to be before other checks
  844. njend=n-1
  845. if(is_sound)njend=n-meas_count
  846. do njc=1,njend
  847. ! Check that time, lat, lon, and platform all match exactly.
  848. ! Platforms 1-4 (surface obs) can match with each other. Otherwise,
  849. ! platforms have to match exactly.
  850. if( (timeob(n).eq.timeob(njc)) .and. &
  851. (rio(n).eq.rio(njc)) .and. &
  852. (rjo(n).eq.rjo(njc)) .and. &
  853. (plfo(njc).ne.99.) ) then
  854. !yliu: if two sfc obs are departed less than 1km, consider they are redundant
  855. ! (abs(rio(n)-rio(njc))*dscg.gt.1000.) &
  856. ! .or. (abs(rjo(n)-rjo(njc))*dscg.gt.1000.) &
  857. ! .or. (plfo(njc).eq.99.) )goto 801
  858. !yliu end
  859. ! If platforms different, and either > 4, jump out
  860. if( ( (plfo(n).le.4.).and.(plfo(njc).le.4.) ) .or. &
  861. (plfo(n).eq.plfo(njc)) ) then
  862. ! if not a sounding, and levels are the same then replace first occurrence
  863. if((.not.is_sound).and.(rko(njc).eq.rko(n))) then
  864. ! print *,'dup single ob-replace ',n,inest,
  865. ! plfo(n),plfo(njc)
  866. ! this is the sfc ob replacement part
  867. do KN = 1,nndgv
  868. VAROBS(KN,njc)=VAROBS(KN,n)
  869. enddo
  870. ! don't need to switch these because they're the same
  871. ! RIO(njc)=RIO(n)
  872. ! RJO(njc)=RJO(n)
  873. ! RKO(njc)=RKO(n)
  874. ! TIMEOB(njc)=TIMEOB(n)
  875. ! nlevs_ob(njc)=nlevs_ob(n)
  876. ! lev_in_ob(njc)=lev_in_ob(n)
  877. ! plfo(njc)=plfo(n)
  878. ! end sfc ob replacement part
  879. n=n-1
  880. goto 100
  881. ! It's harder to fix the soundings, since the number of levels may be different
  882. ! The easiest thing to do is to just set the first occurrence to all missing, and
  883. ! keep the second occurrence, or vice versa.
  884. ! For temp or profiler keep the second, for pilot keep the one with more levs
  885. ! This is for a temp or prof sounding, equal to same
  886. ! also if a pilot, but second one has more obs
  887. elseif( (is_sound).and.(plfo(njc).eq.plfo(n)) .and. &
  888. ( (plfo(njc).eq.5.).or.(plfo(njc).eq.9.).or. &
  889. ( (plfo(njc).eq.6.).and. &
  890. (nlevs_ob(n).ge.nlevs_ob(njc)) ) ) )then
  891. IF (iprt) THEN
  892. write(msg,*) 'duplicate sounding - eliminate first occurrence', &
  893. n,inest,meas_count,nlevs_ob(njc), &
  894. latitude,longitude,plfo(njc)
  895. call wrf_message(msg)
  896. ENDIF
  897. if(lev_in_ob(njc).ne.1.) then
  898. IF (iprt) THEN
  899. write(msg,*) 'problem ******* - dup sndg ', &
  900. lev_in_ob(njc),nlevs_ob(njc)
  901. call wrf_message(msg)
  902. ENDIF
  903. endif
  904. ! n=n-meas_count
  905. ! set the first sounding ob to missing
  906. do njcc=njc,njc+nint(nlevs_ob(njc))-1
  907. do KN = 1,nndgv
  908. VAROBS(KN,njcc)=-888888.
  909. enddo
  910. plfo(njcc)=99.
  911. enddo
  912. goto 100
  913. ! if a pilot, but first one has more obs
  914. elseif( (is_sound).and.(plfo(njc).eq.plfo(n)) .and. &
  915. (plfo(njc).eq.6.).and. &
  916. (nlevs_ob(n).lt.nlevs_ob(njc)) )then
  917. IF (iprt) THEN
  918. write(msg,*) &
  919. 'duplicate pilot sounding - eliminate second occurrence', &
  920. n,inest,meas_count,nlevs_ob(njc), &
  921. latitude,longitude,plfo(njc)
  922. call wrf_message(msg)
  923. ENDIF
  924. if(lev_in_ob(njc).ne.1.) then
  925. IF (iprt) THEN
  926. write(msg,*) 'problem ******* - dup sndg ', &
  927. lev_in_ob(njc),nlevs_ob(njc)
  928. call wrf_message(msg)
  929. ENDIF
  930. endif
  931. n=n-meas_count
  932. !ajb Reset timeob for discarded indices.
  933. do imc = n+1, n+meas_count
  934. timeob(imc) = 99999.
  935. enddo
  936. goto 100
  937. ! This is for a single-level satellite upper air ob - replace first
  938. elseif( (is_sound).and. &
  939. (nlevs_ob(njc).eq.1.).and. &
  940. (nlevs_ob(n).eq.1.).and. &
  941. (varobs(5,njc).eq.varobs(5,n)).and. &
  942. (plfo(njc).eq.7.).and.(plfo(n).eq.7.) ) then
  943. IF (iprt) then
  944. write(msg,*) &
  945. 'duplicate single lev sat-wind ob - replace first',n, &
  946. inest,meas_count,varobs(5,n)
  947. call wrf_message(msg)
  948. ENDIF
  949. ! this is the single ua ob replacement part
  950. do KN = 1,nndgv
  951. VAROBS(KN,njc)=VAROBS(KN,n)
  952. enddo
  953. ! don't need to switch these because they're the same
  954. ! RIO(njc)=RIO(n)
  955. ! RJO(njc)=RJO(n)
  956. ! RKO(njc)=RKO(n)
  957. ! TIMEOB(njc)=TIMEOB(n)
  958. ! nlevs_ob(njc)=nlevs_ob(n)
  959. ! lev_in_ob(njc)=lev_in_ob(n)
  960. ! plfo(njc)=plfo(n)
  961. ! end single ua ob replacement part
  962. n=n-1
  963. goto 100
  964. else
  965. ! IF (iprt) THEN
  966. ! write(msg,*) 'duplicate location, but no match otherwise',n,njc, &
  967. ! plfo(n),varobs(5,n),nlevs_ob(n),lev_in_ob(n), &
  968. ! plfo(njc),varobs(5,njc),nlevs_ob(njc),lev_in_ob(njc)
  969. ! call wrf_message(msg)
  970. ! ENDIF
  971. endif
  972. endif
  973. endif
  974. ! end of njc do loop
  975. enddo
  976. ! check if ob is a sams ob that came in via UUtah - discard
  977. if( plfo(n).eq.4..and.(platform(7:16).eq.'SYNOP PRET').and. &
  978. (id(7:15).eq.'METNET= 3') )then
  979. ! print *,'elim metnet=3',latitude,longitude,rtimob
  980. n=n-1
  981. goto 100
  982. endif
  983. ! check if ob is in the domain
  984. if( (ri.lt.2.).or.(ri.gt.real(e_we-1)).or.(rj.lt.2.).or. &
  985. (rj.gt.real(e_sn-1)) ) then
  986. n=n-meas_count
  987. !ajb Reset timeob for discarded indices.
  988. do imc = n+1, n+meas_count
  989. timeob(imc) = 99999.
  990. enddo
  991. goto 100
  992. endif
  993. IF(TIMEOB(N).LT.fdob%RTLAST) THEN
  994. IF (iprt) THEN
  995. call wrf_message("2 OBS ARE NOT IN CHRONOLOGICAL ORDER")
  996. call wrf_message("NEW YEAR?")
  997. write(msg,*) 'timeob,rtlast,n=',timeob(n),fdob%rtlast,n
  998. call wrf_message(msg)
  999. ENDIF
  1000. call wrf_error_fatal ( 'wrf_fddaobs_in: in4dob STOP 111' )
  1001. ELSE
  1002. fdob%RTLAST=TIMEOB(N)
  1003. ENDIF
  1004. ! Save obs and model latitude and longitude for printout
  1005. CALL collect_obs_info(newpass,inest,n,latitude,longitude, &
  1006. nlast,nprev,niobf,id,stnid_prt, &
  1007. rio,rjo,prt_max,prt_freq,xlat,xlong, &
  1008. obs_prt,lat_prt,lon_prt,mlat_prt,mlon_prt, &
  1009. e_we,e_sn,ims,ime,jms,jme,its,ite,jts,jte)
  1010. GOTO 100
  1011. 111 CONTINUE
  1012. !**********************************************************************
  1013. ! -------------- END BIG 100 LOOP OVER N --------------
  1014. !**********************************************************************
  1015. if (iprt) then
  1016. write(msg,5403) NVOL,XTIME
  1017. call wrf_message(msg)
  1018. endif
  1019. IEOF(inest)=1
  1020. close(NVOLA+INEST-1)
  1021. IF (iprt) then
  1022. write(msg,*) 'closed fdda file for inest=',inest,nsta
  1023. call wrf_message(msg)
  1024. ENDIF
  1025. ! AJB note: Go back and check for more files. (Multi-file implementation)
  1026. goto 1001
  1027. 120 CONTINUE
  1028. ! THE OBSERVATION ARRAYS ARE FULL AND THE MOST RECENTLY
  1029. ! ACQUIRED OBS STILL HAS TIMEOB .LE. TFORWD. SO START
  1030. ! DECREASING THE SIZE OF THE WINDOW
  1031. ! get here if too many obs
  1032. IF (iprt) THEN
  1033. write(msg,121) N,NIOBF
  1034. call wrf_message(msg)
  1035. ENDIF
  1036. call wrf_error_fatal ( 'wrf_fddaobs_in: in4dob STOP 122' )
  1037. 130 CONTINUE
  1038. ! READ CYCLE IS COMPLETED. DETERMINE THE NUMBER OF OBS IN
  1039. ! THE CURRENT WINDOW
  1040. !
  1041. !CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
  1042. ! BUT FIRST, WHEN KTAU.EQ.0 (OR IN GENERAL, KTAUR), DISCARD THE
  1043. ! "OLD" OBS FIRST...
  1044. ! Get here if at end of file, or if obs time is beyond what we need right now.
  1045. ! On startup, we report the index of the last obs read.
  1046. ! For restarts, we need to remove any old obs and then repack obs list.
  1047. IF(KTAU.EQ.KTAUR)THEN
  1048. NSTA=0
  1049. keep_obs : DO N=1,NIOBF
  1050. ! try to keep all obs, but just don't use yet
  1051. ! (don't want to throw away last obs read in - especially if
  1052. ! its a sounding, in which case it looks like many obs)
  1053. IF(TIMEOB(N).GT.9.e4) EXIT keep_obs
  1054. if(timeob(n).gt.tforwd) then
  1055. if(iprt) then
  1056. write(msg,950) inest
  1057. call wrf_message(msg)
  1058. write(msg,951) n,timeob(n),tforwd
  1059. call wrf_message(msg)
  1060. endif
  1061. 950 FORMAT('Saving index of first ob after end of current time window ', &
  1062. 'for nest = ', i3,':')
  1063. 951 FORMAT(' ob index = ',i8,', time of ob = ',f8.4, &
  1064. ' hrs, end of time window = ',f8.4,' hrs')
  1065. endif
  1066. NSTA=N
  1067. ENDDO keep_obs
  1068. NDUM=0
  1069. ! make time=99999. if ob is too old
  1070. ! print *,'tback,nsta=',tback,nsta
  1071. old_obs : DO N=1,NSTA+1
  1072. IF((TIMEOB(N)-TBACK).LT.0)THEN
  1073. TI

Large files files are truncated, but you can click here to view the full file