Subversion Repositories contrack

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
3 michaesp 1
program contrack
2
 
3
! ----------------------------------------------------------------------
4
!
5
! Date: 1st January 2011
6
!                                                              
7
!
8
! ------->> Purpose: Spatial and temporal contour tracking programm
9
!             
10
! This programm is a completely re-written new version of the tracking 
11
! programm used for the studies in e.g. Schwierz et al. (2005), 
12
! Croci-Maspoli et al. (2007a,b), Croci-Maspoli et al. (2009).
13
!
14
! ------->> What is necessary to compile contrack?
15
 
16
! - contrack has been compiled with gfortran 
17
!   (included in the GCC family, http://gcc.gnu.org/ ). Feel free
18
!   to test other fortran compilers.
19
! - contrack requires the netcdf-4.0.1 library (also compiled with gfortran).
20
! - contrack comes with a simple make-file (you have to adjust this file
21
!   before compiling).
22
!
23
! ------->> What netCDF-file is necessary as input?
24
!
25
! - a single CF-netCDF-file (http://cf-pcmdi.llnl.gov/) including all required
26
!   time steps.
27
! - a longitude, latitude and time dimension.
28
! - contrack does not calculate a climatological anomaly field. This needs to
29
!   be calculated before running contrack.
30
!
31
! ------->> How does the output file look like?
32
!
33
! - the output CF-netCDF file has the same dimensions as the input netCDF file 
34
! - the output has a binary format (0 and 1), whereas 1 captures regions of
35
!   the blocks.
36
!   
37
! ------->> Known issues or features not implemented yet in contrack 0.8:
38
!
39
! 1) The calculation and saving of common statistical blocking features 
40
!    (e.g. blocking size, blocking length, blocking path, ...) is not 
41
!    implemented yet. My intention is to save these information directly 
42
!    on the netCDF file.
43
! 2) Only two-dimensional netCDF-files can be used as input file (longitude,
44
!    latitude and time). The code can not handle a third dimension (e.g.
45
!    vertical) on the same netCDF-file yet.
46
! 3) The asymmetry of the blocking features is not implemented yet.
47
! 3) ... more to come!
48
!
49
! ------->>  Version control
50
 
51
! Version 0.1-0.8: May 2010 - fortran 90 compatible
52
!                           - CF-netCDF compatible (instead of IVE-netCDF)
53
!                           - new tracking algorithm
54
!                  Oct 2011 - started with handling also different vertical
55
!                             levels but not finished yet.
56
!                  Jan 2011 - added these explanations
57
!
58
! If you have any comments please send them to mischa.croci-maspoli@alumni.ethz.ch.
59
!
60
! This programm code comes with no guarantee and is currently still 
61
! under construction. Be aware that no extensive testing and comparison to the
62
! old code has been performed yet. 
63
!
64
! Copyright: mischa.croci-maspoli@alumni.ethz.ch
65
!
66
! Modifications SP: omit first and last n time steps in output,
67
!                   where n=persistence;
68
!                   comment out allocation etc. related to vertical dimension
69
!
70
! ----------------------------------------------------------------------
71
 
72
USE netcdf 
73
 
74
implicit none
75
 
76
integer, external :: iargc
77
 
78
integer :: i,j,t,k,ii,jj,tt,counter
79
integer :: persistence, verbose, calcmeranom, cont
80
integer :: titleLength, commentLength, sourceLength, institLength
81
integer :: errmsg, outarr
82
integer :: nrcontours
83
integer :: ttbegin, ttend
84
real    :: fraction, areacon, areaover, overlap, threshold
85
 
86
character*(100) infilename,outfilename,arg
87
character*(100) outvarname,outstandvarname, outvarunit
88
character*(100) invarname, inlat, inlon, intime, inver
89
character*(100) contrackversion
90
character*(5) gorl
91
 
92
character*(1000) cfcomment, cftitle, cfsource, cfinstit
93
character*(1000) cfoutcomment, cfouttitle, cfoutsource, cfoutinstit
94
integer :: ncid, status, nDims, nVars, nGlobalAtts, unlimDimID
95
integer :: label, nrsmooth, nrg, nrgc
96
 
97
integer :: LatDimID,LonDimID, TimeDimID,timeVarID,lonVarID,latVarID,vorpotVarID
98
integer :: VerDimID
99
integer :: varLatID,varLonID,varPVID,varTimeID
100
integer :: nLats,nLong,nTimes,nVert
101
 
102
integer, dimension(:), allocatable :: times, latitude, longitude, longi
103
integer, dimension(:), allocatable :: vertical
104
integer, dimension(:), allocatable :: iiv, jjv, ttv
105
integer, dimension(:), allocatable :: time_array
106
real, dimension(:,:,:), allocatable :: inarr, arr, arr1, arr2
107
real, dimension(:,:), allocatable :: latmean
108
 
109
 
110
! --------------------------------------------------------------
111
! input handling
112
! --------------------------------------------------------------
113
 
114
contrackversion = 'version 0.8'
115
status = 0
116
 
117
print*, '-------------------------------------------------------'
118
print*, 'contrack ', trim(contrackversion)
119
print*, '-------------------------------------------------------'
120
 
121
999 continue
122
 
123
if ( (iargc().ne.1).or.(status.gt.0) ) then
124
   print*, '-------------------------------------------------------'
125
   print*, 'contrack ', trim(contrackversion)
126
   print*, '-------------------------------------------------------'
127
   print*, 'Usage: contrack inputfile'
128
   print*, '-------------------------------------------------------'
129
   print*, 'The inputfile needs the following structure:'
130
   print*, ''
131
   print*, 'infilename   -> name of the input CF-netCDF file'
132
   print*, 'invarname    -> name of the netCDF variable name'
133
   print*, 'inlat        -> name of the netCDF latitude variable'
134
   print*, 'inlon        -> name of the netCDF longitude variable'
135
   print*, 'intime       -> name of the netCDF time variable'
136
   print*, 'threshold    -> threshold value to detect contours'
137
   print*, 'gorl         -> find contours that are greater or '
138
   print*, '                lower threshold value [ge,le,gt,lt]'
139
   print*, 'persistence  -> temporal persistence (in time steps)'
140
   print*, '                of the contour life time'
141
   print*, 'overlap      -> overlapping fraction of two contours'
142
   print*, '                between two time steps [0-1]'
143
   print*, 'nrsmooth     -> temporal smoothing of the infilename'
144
   print*, '                (in time steps)'
145
   print*, 'outarr       -> values of the contours in the output array'
146
   print*, '                0: contours are numbered by each contour'
147
   print*, '                1: contours are labeled 0 and 1'
148
   print*, 'outfilename  -> name of the output CF-netCDF file'
149
   print*, 'outvarname   -> name of the output netCDF variable name'
150
   print*, 'outstvarname -> name of the output netCDF standard'
151
   print*, '                variable name'
152
   print*, 'outvarunit   -> name of the outuput netCDF unit'
153
   print*, 'verbose      -> [0 or 1]'
154
   print*, 'calcmeranom  -> flag whether to calc meriodonal anomalies'
155
   print*, '                or not [0 or 1]'
156
   print*, '-------------------------------------------------------'
157
   print*, 'Please send any comments / bugs to:'
158
   print*, 'mischa.croci-maspoli@alumni.ethz.ch'
159
   print*, '-------------------------------------------------------'
160
   print*, ''
161
   print*, '-->> contrack not executed, an error occured!'
162
   print*, ''
163
   call exit(1)
164
endif
165
 
166
! Read inputfile
167
! --------------
168
call getarg(1,arg)
169
infilename=trim(arg)
170
 
171
 
172
! Open inputfile and read variables
173
! ---------------------------------
174
open(2,file=infilename,status='old',iostat=status)
175
 if ( status.gt.0 ) then
176
    print*, ''
177
    print*, '-> Problem in contrack: Your ASCII input file "', trim(infilename), &
178
            '" can not be found'
179
    print*, '-> For further information use ./contrack only'
180
    print*, ''
181
    stop
182
 endif
183
 
184
 read(2,*,iostat=status) infilename
185
 if ( status.gt.0 ) goto 999
186
 read(2,*,iostat=status) invarname
187
 if ( status.gt.0 ) goto 999
188
 read(2,*,iostat=status) inlat
189
 if ( status.gt.0 ) goto 999
190
 read(2,*,iostat=status) inlon
191
 if ( status.gt.0 ) goto 999
192
 read(2,*,iostat=status) intime
193
 if ( status.gt.0 ) goto 999
194
 read(2,*,iostat=status) threshold
195
 if ( status.gt.0 ) goto 999
196
 read(2,*,iostat=status) gorl
197
 if ( status.gt.0 ) goto 999
198
 read(2,*,iostat=status) persistence
199
 if ( status.gt.0 ) goto 999
200
 read(2,*,iostat=status) overlap
201
 if ( status.gt.0 ) goto 999
202
 read(2,*,iostat=status) nrsmooth
203
 if ( status.gt.0 ) goto 999
204
 read(2,*,iostat=status) outarr
205
 if ( status.gt.0 ) goto 999
206
 read(2,*,iostat=status) outfilename
207
 if ( status.gt.0 ) goto 999
208
 read(2,*,iostat=status) outvarname
209
 if ( status.gt.0 ) goto 999
210
 read(2,*,iostat=status) outstandvarname
211
 if ( status.gt.0 ) goto 999
212
 read(2,*,iostat=status) outvarunit 
213
 if ( status.gt.0 ) goto 999
214
 read(2,*,iostat=status) verbose
215
 if ( status.gt.0 ) goto 999
216
 read(2,*,iostat=status) calcmeranom
217
 if ( status.gt.0 ) goto 999
218
close(2)
219
 
220
 
221
! --------------------------------------------------------------
222
! read CF-netCDF file
223
! --------------------------------------------------------------
224
 
225
allocate(time_array(8))
226
call date_and_time (values=time_array)
227
write(*,100), "-> Read ", trim(infilename), time_array(5), ':', time_array(6), ':', time_array(7)
228
100 format(A,A,I5,A,I2,A,I2)
229
 
230
! Initially set error to indicate no errors.
231
status = 0
232
 
233
! open netCDF file
234
status = nf90_open(infilename, nf90_nowrite, ncid)
235
 
236
! get dimensions
237
status = nf90_inq_dimid(ncid, inlat, LatDimID)
238
status = nf90_inquire_dimension(ncid, LatDimID, len = nLats)
239
 
240
status = nf90_inq_dimid(ncid, inlon, LonDimID)
241
status = nf90_inquire_dimension(ncid, LonDimID, len = nLong)
242
 
243
!status = nf90_inq_dimid(ncid, inver, VerDimID)
244
!status = nf90_inquire_dimension(ncid, VerDimID, len = nVert)
245
 
246
status = nf90_inq_dimid(ncid, intime, TimeDimID)
247
status = nf90_inquire_dimension(ncid, TimeDimID, len = nTimes)
248
 
249
! allocate arrays
250
allocate(times(nTimes))
251
allocate(latitude(nLats))
252
allocate(longitude(nLong))
253
!allocate(vertical(nVert))
254
allocate(inarr(nLong,nLats,nTimes))
255
allocate(arr(nLong,nLats,nTimes))
256
allocate(arr1(nLong,nLats,nTimes))
257
allocate(arr2(nLong,nLats,nTimes))
258
allocate(latmean(nLats,nTimes))
259
allocate(iiv(nLats*nLong*nTimes))
260
allocate(jjv(nLats*nLong*nTimes))
261
allocate(ttv(nLats*nLong*nTimes))
262
 
263
! get variables
264
status = nf90_inq_varid(ncid, intime, timeVarID)
265
status = nf90_get_var(ncid, timeVarID, times)
266
 
267
status = nf90_inq_varid(ncid, inlon, lonVarID)
268
status = nf90_get_var(ncid, lonVarID, longitude)
269
 
270
status = nf90_inq_varid(ncid, inlat, latVarID)
271
status = nf90_get_var(ncid, latVarID, latitude)
272
 
273
status = nf90_inq_varid(ncid, invarname, vorpotVarID)
274
status = nf90_get_var(ncid, vorpotVarID, inarr)
275
 
276
status = nf90_inquire_attribute(ncid, nf90_global, "comment", len = commentLength)
277
status = nf90_get_att(ncid, NF90_GLOBAL, 'comment', cfcomment)
278
status = nf90_inquire_attribute(ncid, nf90_global, "title", len = titleLength)
279
status = nf90_get_att(ncid, NF90_GLOBAL, 'title', cftitle)
280
status = nf90_inquire_attribute(ncid, nf90_global, "source", len = sourceLength)
281
status = nf90_get_att(ncid, NF90_GLOBAL, 'source', cfsource)
282
status = nf90_inquire_attribute(ncid, nf90_global, "institution", len = institLength)
283
status = nf90_get_att(ncid, NF90_GLOBAL, 'institution', cfinstit)
284
 
285
status = nf90_close(ncid)
286
 
287
 
288
! --------------------------------------------------------------
289
! Calculate meridional anomaly
290
! --------------------------------------------------------------
291
 
292
if ( calcmeranom.eq.1 ) then
293
 
294
print*, '-->> calculate meridional mean anomaly'
295
 
296
! Calculate latitudinal mean
297
! --------------------------------------------------------------
298
do t = 1,nTimes
299
do j = 1,nLats
300
do i = 1,nLong
301
   latmean(j,t) = latmean(j,t) + inarr(i,j,t)
302
enddo
303
enddo
304
enddo
305
 
306
! Subtract latitudinal mean
307
! --------------------------------------------------------------
308
do t = 1,nTimes
309
do j = 1,nLats
310
do i = 1,nLong
311
  arr(i,j,t) = inarr(i,j,t) - latmean(j,t)/nLong
312
enddo
313
enddo
314
enddo
315
 
316
 
317
! Calculate running means (centered at the first file)
318
! --------------------------------------------------------------
319
do t = 1,nTimes
320
do j = 1,nLats
321
do i = 1,nLong
322
  do k = 0,nrsmooth
323
     arr1(i,j,t) = arr1(i,j,t) + arr(i,j,t+k)
324
  enddo
325
enddo
326
enddo
327
enddo
328
 
329
arr = arr1/nrsmooth
330
 
331
else
332
  print*, '-->> no anomaly calculated'
333
  arr(:,:,:) = inarr(:,:,:)
334
endif
335
 
336
 
337
! Define closed contours by a threshold value
338
! --------------------------------------------------------------
339
 
340
print*, '-->> define contours with threshold value'
341
 
342
do t = 1,nTimes
343
do j = 1,nLats
344
do i = 1,nLong
345
 
346
  if ( trim(gorl).eq.'ge' ) then
347
     if ( arr(i,j,t).ge.threshold) then
348
        arr(i,j,t) = 1
349
     else
350
        arr(i,j,t) = 0
351
     endif
352
  endif
353
  if ( trim(gorl).eq.'le' ) then
354
     if ( arr(i,j,t).le.threshold) then
355
        arr(i,j,t) = 1
356
     else
357
        arr(i,j,t) = 0
358
     endif
359
  endif
360
  if ( trim(gorl).eq.'gt' ) then
361
     if ( arr(i,j,t).gt.threshold) then
362
        arr(i,j,t) = 1
363
     else
364
        arr(i,j,t) = 0
365
     endif
366
  endif
367
  if ( trim(gorl).eq.'lt' ) then
368
     if ( arr(i,j,t).lt.threshold) then
369
        arr(i,j,t) = 1
370
     else
371
        arr(i,j,t) = 0
372
     endif
373
  endif
374
 
375
 
376
 
377
 
378
enddo
379
enddo
380
enddo
381
 
382
 
383
! Identify individual contour areas on a 2D-space (only x-y, no time)
384
! -------------------------------------------------------------------
385
 
386
print*, '-->> identify individual contours'
387
 
388
arr2(:,:,:) = 0    ! set arr2 to zero
389
 
390
do t = 1,nTimes
391
label = 1          ! begin labeling with 1
392
do j = 1,nLats
393
do i = 1,nLong
394
 
395
  if ( (arr(i,j,t).eq.1).and.(arr2(i,j,t).lt.1) ) then
396
 
397
     arr2(i,j,t) = label    ! first identified grid point in countour
398
     nrg         = 1        ! number of grid points
399
     nrgc        = 1        ! number of grid points counter
400
     iiv(nrgc)   = i        ! x-dir coordinates within contour
401
     jjv(nrgc)   = j        ! y-dir coordinates within contour
402
 
403
     do while ( nrgc.le.nrg )
404
 
405
       do ii=-1,1
406
       do jj=-1,1
407
 
408
        if (  (arr(iiv(nrgc)+ii,jjv(nrgc)+jj,t).eq.1).and. &
409
             (arr2(iiv(nrgc)+ii,jjv(nrgc)+jj,t).ne.label) ) then
410
 
411
             arr2(iiv(nrgc)+ii,jjv(nrgc)+jj,t) = label
412
             nrg                               = nrg + 1
413
             iiv(nrg)                          = iiv(nrgc)+ii
414
             jjv(nrg)                          = jjv(nrgc)+jj
415
 
416
        endif
417
 
418
       enddo
419
       enddo
420
 
421
     nrgc = nrgc + 1
422
 
423
     enddo
424
 
425
 
426
  label = label + 1
427
 
428
  endif
429
 
430
enddo
431
enddo
432
enddo
433
 
434
 
435
! Define temporal overlapping
436
! --------------------------------------------------------------
437
 
438
print*, '-->> overlapping'
439
 
440
do t  = 1,nTimes
441
do ii = 1,int(maxval(arr2(:,:,t)))   ! loop over the number of individual contours
442
 
443
areacon  = 0.
444
areaover = 0.
445
fraction = 0.
446
 
447
  do i  = 1,nLong
448
  do j  = 1,nLats
449
 
450
      if ( ( arr2(i,j,t).eq.ii) ) then
451
         areacon = areacon+(111*(111*cos(2*3.14159/360*j)))
452
      endif
453
 
454
      if ( ( arr2(i,j,t).eq.ii).and.(arr2(i,j,t+1).ge.1) ) then
455
         areaover = areaover+(111*(111*cos(2*3.14159/360*j)))
456
      endif
457
 
458
  enddo
459
  enddo
460
 
461
  fraction = 1 / areacon * areaover
462
  !print*, ii, int(maxval(arr2(:,:,t))), fraction
463
 
464
  do i  = 1,nLong
465
  do j  = 1,nLats
466
     if ( (fraction.lt.overlap).and.(arr2(i,j,t).eq.ii) ) then
467
         arr2(i,j,t) = 0.
468
     endif
469
  enddo
470
  enddo
471
 
472
enddo
473
enddo
474
 
475
 
476
! Identify individual contour areas (3D including time)
477
! --------------------------------------------------------------
478
 
479
print*, '-->> identify 3D contours'
480
 
481
arr(:,:,:)  = arr2(:,:,:)
482
 
483
do t = 1,nTimes
484
do j = 1,nLats
485
do i = 1,nLong
486
 
487
   if ( arr(i,j,t).ge.1 ) then
488
        arr(i,j,t) = 1
489
   endif
490
 
491
enddo
492
enddo
493
enddo
494
 
495
arr2(:,:,:) = 0    ! set arr2 to zero
496
label = 1          ! begin labeling with 1
497
 
498
do t = 1,nTimes
499
do j = 1,nLats
500
do i = 1,nLong
501
 
502
  if ( (arr(i,j,t).eq.1).and.(arr2(i,j,t).lt.1) ) then
503
 
504
     arr2(i,j,t) = label    ! first identified grid point in countour
505
     nrg         = 1        ! number of grid points
506
     nrgc        = 1        ! number of grid points counter
507
     iiv(nrgc)   = i        ! x-dir coordinates within contour
508
     jjv(nrgc)   = j        ! y-dir coordinates within contour
509
     ttv(nrgc)   = t        ! t-dir coordinates within contour
510
     ttbegin     = t        ! genesis time
511
 
512
!     print*, i,j,t,label
513
 
514
     do while ( nrgc.le.nrg )
515
 
516
       do ii=-1,1
517
       do jj=-1,1
518
       do tt=-1,1
519
 
520
        if (  (arr(iiv(nrgc)+ii,jjv(nrgc)+jj,ttv(nrgc)+tt).eq.1).and. &
521
             (arr2(iiv(nrgc)+ii,jjv(nrgc)+jj,ttv(nrgc)+tt).ne.label) ) then
522
 
523
             arr2(iiv(nrgc)+ii,jjv(nrgc)+jj,ttv(nrgc)+tt) = label
524
             nrg                               = nrg + 1
525
             iiv(nrg)                          = iiv(nrgc)+ii
526
             jjv(nrg)                          = jjv(nrgc)+jj
527
             ttv(nrg)                          = ttv(nrgc)+tt
528
 
529
             ! get time of lysis
530
             if (ttv(nrg).gt.ttend) then
531
                ttend = ttend + 1
532
             endif
533
 
534
        endif
535
 
536
       enddo
537
       enddo
538
       enddo
539
 
540
!       print*, iiv(nrg),jjv(nrg),ttv(nrg), label
541
!       print*, nrg, nrgc, ttv(nrgc)
542
!       if (nrgc.gt.20) stop
543
 
544
     nrgc = nrgc + 1
545
 
546
     enddo
547
 
548
  print*, label, ttbegin, ttend,ttend-ttbegin
549
  label = label + 1
550
 
551
 
552
  endif
553
 
554
enddo
555
enddo
556
enddo
557
 
558
 
559
if ( verbose.eq.1 ) print*, '     -> number of individual contours: ', label-1
560
 
561
! Temporal persistence
562
! --------------------------------------------------------------
563
 
564
print*, '-->> temporal persistence'
565
 
566
do ii = 1,label
567
counter = 0
568
do t = 1,nTimes
569
do j = 1,nLats
570
do i = 1,nLong
571
 
572
   if ( arr2(i,j,t).eq.ii) then
573
      counter = counter + 1
574
      goto 234
575
   endif
576
 
577
enddo
578
enddo
579
 234 continue
580
enddo
581
 
582
do t = 1,nTimes
583
do j = 1,nLats
584
do i = 1,nLong
585
 
586
   if ( (counter.lt.persistence ).and.(arr2(i,j,t).eq.ii) )  then
587
      arr2(i,j,t) = 0.
588
   endif
589
 
590
enddo
591
enddo
592
enddo
593
 
594
enddo
595
 
596
! get contour information
597
! --------------------------------------------------------------
598
 
599
print*, '-->> get contour information'
600
 
601
! number of individual contours
602
! length of individual contours
603
! mean area size of individual contours
604
! genesis/lysis date
605
! genesis/lysis area at specific date
606
 
607
nrcontours = 0
608
do t = 1,nTimes
609
do j = 1,nLats
610
do i = 1,nLong
611
 
612
 if ( arr2(i,j,t).gt.nrcontours ) then
613
  nrcontours = nrcontours + 1 
614
 endif
615
 
616
enddo
617
enddo
618
enddo
619
 
620
print*, '     -> number of tracked contours: ', nrcontours
621
 
622
 
623
 
624
! change output array to a 0/1 array
625
! --------------------------------------------------------------
626
 
627
if ( outarr.eq.1 ) then
628
   do t = 1,nTimes
629
   do j = 1,nLats
630
   do i = 1,nLong
631
 
632
      if ( arr2(i,j,t).gt.0 ) then
633
         arr2(i,j,t) = 1.
634
      endif
635
   enddo
636
   enddo
637
   enddo
638
endif
639
 
640
 
641
arr = arr2
642
 
643
11 continue
644
 
645
 
646
! --------------------------------------------------------------
647
! write CF-netCDF file
648
! --------------------------------------------------------------
649
 
650
call date_and_time (values=time_array)
651
write(*,100), "-> Write ", trim(outfilename), time_array(5), ':', time_array(6), ':', time_array(7)
652
 
653
! definitions
654
! --------------------------------------------------------------
655
 
656
cfoutinstit = cfinstit
657
cfouttitle  = 'contrack '//trim(contrackversion)
658
cfoutsource = cfsource
659
write(cfoutcomment, 101) 'contrack is based upon the following input file attributes: ', &
660
                          trim(cfcomment), &
661
                         ' -->> Contrack specifications:: ',&
662
                         'contours identified that are -', trim(gorl), '- threshold value, ', &
663
                         'threshold value for contour:', threshold, &
664
                         ', overlapping fraction:', overlap, &
665
                         ', persistence time steps:', persistence, &
666
                         ', anomalies calculated by subtracting meridional mean [1] or ', &
667
                         'from the input file directly [0]: ', calcmeranom
668
 
669
101 format(A,A,A,A,A,A,A,F8.3,A,F7.3,A,I5,A,A,I3)
670
 
671
! start writing 
672
! ----------------------------------------------------------------
673
 
674
! Initially set error to indicate no errors.
675
status = 0
676
 
677
! create the netCDF file
678
status = nf90_create(trim(outfilename), NF90_CLOBBER, ncID)
679
! IF (ierr.NE.0) GOTO 920
680
 
681
! Dimensions -----------------------------------------------------
682
status=nf90_def_dim(ncID,'longitude',nLong,LonDimID)
683
status=nf90_def_dim(ncID,'latitude',nLats,LatDimID)
684
status=nf90_def_dim(ncID,'time',nf90_unlimited, TimeDimID)
685
 
686
! Variables ------------------------------------------------------
687
status = nf90_def_var(ncID,'longitude',NF90_FLOAT,(/ LonDimID /),varLonID)
688
status = nf90_put_att(ncID, varLonID, "standard_name", "longitude")
689
status = nf90_put_att(ncID, varLonID, "units", "degree_east")
690
 
691
status = nf90_def_var(ncID,'latitude',NF90_FLOAT,(/ LatDimID /),varLatID)
692
status = nf90_put_att(ncID, varLatID, "standard_name", "latitude")
693
status = nf90_put_att(ncID, varLatID, "units", "degree_north")
694
 
695
status = nf90_def_var(ncID,'time',NF90_FLOAT, (/ TimeDimID /), varTimeID)
696
status = nf90_put_att(ncID, varTimeID, "axis", "T")
697
status = nf90_put_att(ncID, varTimeID, "calendar", "standard")
698
status = nf90_put_att(ncID, varTimeID, "long_name", "time")
699
status = nf90_put_att(ncID, varTimeID, "units", "hours since &
700
                                            1950-01-01 00:OO UTC")
701
 
702
! Global Attributes -----------------------------------------------
703
status = nf90_put_att(ncID, NF90_GLOBAL, 'Conventions', 'CF-1.0')
704
status = nf90_put_att(ncID, NF90_GLOBAL, 'title', cfouttitle)
705
status = nf90_put_att(ncID, NF90_GLOBAL, 'source', cfoutsource)
706
status = nf90_put_att(ncID, NF90_GLOBAL, 'institution', cfoutinstit)
707
status = nf90_put_att(ncID, NF90_GLOBAL, 'comment', cfoutcomment)
708
 
709
 
710
! Specific variable -----------------------------------------------
711
status = nf90_def_var(ncID,trim(outvarname),NF90_FLOAT,&
712
                   (/ LonDimID, LatDimID, varTimeID /),varPVID)
713
!status = nf90_def_var(ncID,trim(outvarname),NF90_FLOAT,&
714
!                   (/ LatDimID, varTimeID /),varPVID)
715
status = nf90_put_att(ncID, varPVID, "standard_name",trim(outstandvarname))
716
status = nf90_put_att(ncID, varPVID, "units", trim(outvarunit)) 
717
status = nf90_put_att(ncID, varPVID, '_FillValue', -999.99) 
718
 
719
! END variable definitions.
720
 
721
status = nf90_enddef(ncID)
722
IF (status.GT.0) THEN
723
   print*, 'An error occurred while attempting to ', &
724
        'finish definition mode.'
725
   !GOTO 920
726
ENDIF
727
 
728
! write DATA
729
! -------------------------------------------------------------------
730
status = nf90_put_var(ncID,varLonID,longitude)
731
status = nf90_put_var(ncID,varLatID,latitude)
732
!status = nf90_put_var(ncID,varTimeID, times)
733
status = nf90_put_var(ncID,varTimeID, &
734
                      times((persistence+1):(nTimes-persistence)))
735
 
736
 
737
!  Write block
738
!status = nf90_put_var(ncID,varPVID, arr(:,:,:))
739
status = nf90_put_var(ncID,varPVID, &
740
                      arr(:,:,(persistence+1):(nTimes-persistence)))
741
 
742
status = nf90_close(ncID)
743
IF (status.NE.0) THEN
744
   WRITE(0,*) trim(nf90_strerror(status))
745
   WRITE(0,*) 'An error occurred while attempting to ', &
746
              'close the netcdf file.'
747
   WRITE(0,*) 'in clscdf_CF'
748
ENDIF
749
 
750
close(ncID)
751
 
752
 
753
END
754
 
755