New URL for NEMO forge!   http://forge.nemo-ocean.eu

Since March 2022 along with NEMO 4.2 release, the code development moved to a self-hosted GitLab.
This present forge is now archived and remained online for history.
iom_cdf.f90 in trunk/NEMOGCM/TOOLS/SIREN/src – NEMO

source: trunk/NEMOGCM/TOOLS/SIREN/src/iom_cdf.f90 @ 7646

Last change on this file since 7646 was 7646, checked in by timgraham, 7 years ago

Merge of dev_merge_2016 into trunk. UPDATE TO ARCHFILES NEEDED for XIOS2.
LIM_SRC_s/limrhg.F90 to follow in next commit due to change of kind (I'm unable to do it in this commit).
Merged using the following steps:

1) svn merge --reintegrate svn+ssh://forge.ipsl.jussieu.fr/ipsl/forge/projets/nemo/svn/trunk .
2) Resolve minor conflicts in sette.sh and namelist_cfg for ORCA2LIM3 (due to a change in trunk after branch was created)
3) svn commit
4) svn switch svn+ssh://forge.ipsl.jussieu.fr/ipsl/forge/projets/nemo/svn/trunk
5) svn merge svn+ssh://forge.ipsl.jussieu.fr/ipsl/forge/projets/nemo/svn/branches/2016/dev_merge_2016 .
6) At this stage I checked out a clean copy of the branch to compare against what is about to be committed to the trunk.
6) svn commit #Commit code to the trunk

In this commit I have also reverted a change to Fcheck_archfile.sh which was causing problems on the Paris machine.

File size: 84.5 KB
Line 
1!----------------------------------------------------------------------
2! NEMO system team, System and Interface for oceanic RElocable Nesting
3!----------------------------------------------------------------------
4!
5! MODULE: iom_cdf
6!
7! DESCRIPTION:
8!> @brief NETCDF Input/Output manager :  Library to read Netcdf input files
9!>
10!> @details
11!>    to open netcdf file:<br/>
12!> @code
13!>    CALL iom_cdf_open(td_file)
14!> @endcode
15!>       - td_file is file structure (see @ref file)
16!>
17!>    to write in netcdf file:<br/>
18!> @code
19!>    CALL  iom_cdf_write_file(td_file)
20!> @endcode
21!>
22!>    to close netcdf file:<br/>
23!> @code
24!>    CALL iom_cdf_close(tl_file)
25!> @endcode
26!>
27!>    to read one dimension in netcdf file:<br/>
28!> @code
29!>    tl_dim = iom_cdf_read_dim(tl_file, id_dimid)
30!> @endcode
31!>    or
32!> @code
33!>    tl_dim = iom_cdf_read_dim(tl_file, cd_name)
34!> @endcode
35!>       - id_dimid is dimension id<br/>
36!>       - cd_name is dimension name
37!>
38!>    to read one attribute in netcdf file:<br/>
39!> @code
40!>    tl_att = iom_cdf_read_att(tl_file, id_varid, id_attid)
41!> @endcode
42!>    or
43!> @code
44!>    tl_att = iom_cdf_read_att(tl_file, id_varid, cd_name)
45!> @endcode
46!>       - id_varid is variable id
47!>       - id_attid is attribute id<br/>
48!>       - cd_name is attribute name
49!>   
50!>    to read one variable in netcdf file:<br/>
51!> @code
52!>    tl_var = iom_cdf_read_var(td_file, id_varid, [id_start, id_count])
53!> @endcode
54!>    or
55!> @code
56!>    tl_var = iom_cdf_read_var(td_file, cd_name, [id_start, [id_count,]])
57!> @endcode
58!>       - id_varid is variabale id
59!>       - cd_name is variabale name
60!>       - id_start is a integer(4) 1D array of index from which the data
61!>          values will be read [optional]
62!>       - id_count is a integer(4) 1D array of the number of indices selected
63!>          along each dimension [optional]
64!>
65!> @author
66!> J.Paul
67! REVISION HISTORY:
68!> @date November, 2013 - Initial Version
69!
70!> @note Software governed by the CeCILL licence     (NEMOGCM/NEMO_CeCILL.txt)
71!----------------------------------------------------------------------
72MODULE iom_cdf
73   USE netcdf                          ! nf90 library
74   USE global                          ! global parameter
75   USE kind                            ! F90 kind parameter
76   USE fct                             ! basic useful function
77   USE logger                          ! log file manager
78   USE att                             ! attribute manage
79   USE dim                             ! dimension manager
80   USE var                             ! variable manager
81   USE file                            ! file manager
82   IMPLICIT NONE
83   ! NOTE_avoid_public_variables_if_possible
84
85   ! function and subroutine
86   PUBLIC :: iom_cdf_open        !< open or create netcdf file, return file structure
87   PUBLIC :: iom_cdf_close       !< close netcdf file
88   PUBLIC :: iom_cdf_read_dim    !< read one dimension in an opened netcdf file, return dimension structure
89   PUBLIC :: iom_cdf_read_att    !< read one attribute in an opened netcdf file, return attribute structure
90   PUBLIC :: iom_cdf_read_var    !< read one variable  in an opened netcdf file, return variable  structure
91   PUBLIC :: iom_cdf_fill_var    !< fill variable value in an opened netcdf file
92   PUBLIC :: iom_cdf_write_file  !< write file structure contents in an opened netcdf file
93
94   PRIVATE :: iom_cdf__check           ! provides a simple interface to netcdf error message
95   PRIVATE :: iom_cdf__get_info        ! get global information in an opened netcdf file
96   PRIVATE :: iom_cdf__get_file_dim    ! read dimension on an opened netcdf file, and reorder it
97   PRIVATE :: iom_cdf__get_file_att    ! read global attribute on an opened netcdf file
98   PRIVATE :: iom_cdf__get_file_var    ! read information about variable on an opened netcdf file
99   PRIVATE :: iom_cdf__read_dim_id     ! read one dimension in an opened netcdf file, given dimension id.
100   PRIVATE :: iom_cdf__read_dim_name   ! read one dimension in an opened netcdf file, given dimension name.
101   PRIVATE :: iom_cdf__read_att_name   ! read variable or global attribute in an opened netcdf file, given attribute name.
102   PRIVATE :: iom_cdf__read_att_id     ! read variable or global attribute in an opened netcdf file, given attribute id.
103   PRIVATE :: iom_cdf__read_var_id     ! read variable value in an opened netcdf file, given variable id.
104   PRIVATE :: iom_cdf__read_var_name   ! read variable value in an opened netcdf file, given variable name or standard name.
105   PRIVATE :: iom_cdf__read_var_meta   ! read metadata of a variable in an opened netcdf file.
106   PRIVATE :: iom_cdf__read_var_dim    ! read variable dimension in an opened netcdf file.
107   PRIVATE :: iom_cdf__read_var_att    ! read variable attributes in an opened netcdf file.
108   PRIVATE :: iom_cdf__read_var_value  ! read variable value in an opened netcdf file.
109   PRIVATE :: iom_cdf__write_dim       ! write one dimension in an opened netcdf file in write mode.
110   PRIVATE :: iom_cdf__write_att       ! write a variable attribute in an opened netcdf file.
111   PRIVATE :: iom_cdf__write_var       ! write a variable in an opened netcdf file.
112   PRIVATE :: iom_cdf__write_var_def   ! define variable in an opened netcdf file.
113   PRIVATE :: iom_cdf__write_var_value ! put variable value in an opened netcdf file.
114   PRIVATE :: iom_cdf__fill_var_id     ! fill variable value in an opened netcdf file, given variable id
115   PRIVATE :: iom_cdf__fill_var_name   ! fill variable value in an opened netcdf file, given variable name
116   PRIVATE :: iom_cdf__fill_var_all    ! fill all variable value in an opened netcdf file
117   PRIVATE :: iom_cdf__del_coord_var   ! remove coordinate variable from an opened netcdf file
118
119   INTERFACE iom_cdf_read_var
120      MODULE PROCEDURE iom_cdf__read_var_id
121      MODULE PROCEDURE iom_cdf__read_var_name
122   END INTERFACE iom_cdf_read_var
123
124   INTERFACE iom_cdf_fill_var
125      MODULE PROCEDURE iom_cdf__fill_var_id
126      MODULE PROCEDURE iom_cdf__fill_var_name
127      MODULE PROCEDURE iom_cdf__fill_var_all
128   END INTERFACE iom_cdf_fill_var
129
130   INTERFACE iom_cdf_read_dim
131      MODULE PROCEDURE iom_cdf__read_dim_id
132      MODULE PROCEDURE iom_cdf__read_dim_name
133   END INTERFACE iom_cdf_read_dim
134
135   INTERFACE iom_cdf_read_att
136      MODULE PROCEDURE iom_cdf__read_att_id
137      MODULE PROCEDURE iom_cdf__read_att_name
138   END INTERFACE iom_cdf_read_att
139
140CONTAINS
141   !-------------------------------------------------------------------
142   !> @brief This subroutine provides a simple interface to
143   !> netcdf error message
144   !>
145   !> @author J.Paul
146   !> @date November, 2013 - Initial Version
147   !> @date May, 2015 - add optional message to netcdf error message
148   !>
149   !> @param[in] id_status error status
150   !> @param[in] cd_msg    message
151   !-------------------------------------------------------------------
152   SUBROUTINE iom_cdf__check(id_status, cd_msg)
153      IMPLICIT NONE
154      ! Argument     
155      INTEGER(i4)     , INTENT(IN)           :: id_status
156      CHARACTER(LEN=*), INTENT(IN), OPTIONAL :: cd_msg
157      ! local variable
158      CHARACTER(LEN=lc) :: cl_msg
159      !----------------------------------------------------------------
160
161      cl_msg=""
162      IF( PRESENT(cd_msg) ) cl_msg=cd_msg
163
164      IF( id_status /= NF90_NOERR )THEN
165         CALL logger_error(TRIM(cl_msg)//TRIM(NF90_STRERROR(id_status)))
166      ENDIF
167
168   END SUBROUTINE iom_cdf__check
169   !-------------------------------------------------------------------
170   !> @brief This subroutine open a netcdf file in read or write mode.
171   !> @details
172   !> if try to open a file in write mode that did not exist, create it.<br/>
173   !> if file already exist, get information about0:<br/>
174   !> - the number of variables
175   !> - the number of dimensions
176   !> - the number of global attributes
177   !> - the ID of the unlimited dimension
178   !> - the file format
179   !> Finally it read dimensions, and 'longitude' variable to compute East-West
180   !> overlap.
181   !>
182   !> @author J.Paul
183   !> @date November, 2013 - Initial Version
184   !
185   !> @param[inout] td_file   file structure
186   !-------------------------------------------------------------------
187   SUBROUTINE iom_cdf_open(td_file)
188      IMPLICIT NONE
189      ! Argument     
190      TYPE(TFILE), INTENT(INOUT)  :: td_file
191
192      ! local variable
193      LOGICAL     :: ll_exist
194      LOGICAL     :: ll_open
195
196      INTEGER(i4) :: il_status
197      !----------------------------------------------------------------
198
199      ! check file existence
200      INQUIRE(FILE=TRIM(td_file%c_name), EXIST=ll_exist, OPENED=ll_open)
201      ! ll_open do not work for netcdf file, always return FALSE
202      IF( .NOT. ll_exist .OR. TRIM(td_file%c_type) /= 'cdf' )THEN
203
204         IF( .NOT. td_file%l_wrt )THEN
205
206            CALL logger_fatal( " IOM CDF OPEN: can not open file "//&
207            &               TRIM(td_file%c_name) )
208 
209         ELSE
210
211            CALL logger_info( " IOM CDF CREATE: file "//TRIM(td_file%c_name) )
212
213            il_status = NF90_CREATE(TRIM(td_file%c_name),&
214            &                       cmode=NF90_64BIT_OFFSET,&
215            &                       ncid=td_file%i_id)
216            CALL iom_cdf__check(il_status," IOM CDF CREATE: ")
217
218            td_file%l_def=.TRUE.
219
220         ENDIF
221
222      ELSE
223
224         IF( td_file%i_id /= 0 )THEN
225
226            CALL logger_error( " IOM CDF OPEN: file "//&
227            &               TRIM(td_file%c_name)//" already opened")
228
229         ELSE
230 
231            IF( .NOT. td_file%l_wrt )THEN
232
233               CALL logger_info( " IOM CDF OPEN: file "//&
234               &              TRIM(td_file%c_name)//" in read only mode" )
235
236               il_status = NF90_OPEN( TRIM(td_file%c_name), &
237               &                      NF90_NOWRITE,         &
238               &                      td_file%i_id)
239               CALL iom_cdf__check(il_status," IOM CDF OPEN: ")
240
241            ELSE
242
243               CALL logger_info( "IOM CDF OPEN: file "//&
244               &              TRIM(td_file%c_name)//" in write mode" )
245
246               il_status = NF90_OPEN( TRIM(td_file%c_name), &
247               &                      NF90_WRITE,           &
248               &                      td_file%i_id)
249               CALL iom_cdf__check(il_status,"IOM CDF OPEN: ")
250
251            ENDIF
252
253            ! get general information about file
254            CALL iom_cdf__get_info(td_file)
255
256            ! read dimension in file
257            CALL iom_cdf__get_file_dim(td_file) 
258
259            ! read global attribute in file
260            CALL iom_cdf__get_file_att(td_file)
261
262            ! get information about variables in file
263            CALL iom_cdf__get_file_var(td_file)
264
265            ! remove dimension variable from list of variable
266            CALL iom_cdf__del_coord_var(td_file)
267
268         ENDIF
269
270      ENDIF
271
272   END SUBROUTINE iom_cdf_open
273   !-------------------------------------------------------------------
274   !> @brief This subroutine close netcdf file.
275   !>
276   !> @author J.Paul
277   !> @date November, 2013 - Initial Version
278   !
279   !> @param[inout] td_file   file structure
280   !-------------------------------------------------------------------
281   SUBROUTINE iom_cdf_close(td_file)
282      IMPLICIT NONE
283      ! Argument     
284      TYPE(TFILE), INTENT(INOUT) :: td_file
285
286      ! local variable
287      INTEGER(i4) :: il_status
288      !----------------------------------------------------------------
289
290      ! check if file opened
291      IF( td_file%i_id == 0 )THEN
292
293         CALL logger_error( &
294         &  " IOM CDF CLOSE: no id associated to file "//TRIM(td_file%c_name))
295
296      ELSE
297         CALL logger_info( &
298         &  " IOM CDF CLOSE: file "//TRIM(td_file%c_name))
299
300         il_status = NF90_CLOSE(td_file%i_id)
301         CALL iom_cdf__check(il_status,"IOM CDF CLOSE: ")
302
303         td_file%i_id = 0
304
305      ENDIF
306
307   END SUBROUTINE iom_cdf_close
308   !-------------------------------------------------------------------
309   !> @brief This subroutine get global information in an opened netcdf
310   !> file.
311   !> @details
312   !> It gets the number of variables, the number of dimensions,
313   !> the number of global attributes, the ID of the unlimited dimension
314   !> and finally the format version and filled file strucuture with it.
315   !>
316   !> @author J.Paul
317   !> @date November, 2013 - Initial Version
318   !> @date October, 2016
319   !> - define cdf4 as cdf.
320   !
321   !> @param[inout] td_file   file structure
322   !-------------------------------------------------------------------
323   SUBROUTINE iom_cdf__get_info(td_file)
324      IMPLICIT NONE
325      ! Argument     
326      TYPE(TFILE), INTENT(INOUT) :: td_file
327
328      ! local variable
329      INTEGER(i4) :: il_fmt   ! format version
330      INTEGER(i4) :: il_status
331      !----------------------------------------------------------------
332
333      CALL logger_trace( &
334      &  " IOM CDF GET INFO: about netcdf file "//TRIM(td_file%c_name))
335
336      il_status=NF90_INQUIRE(td_file%i_id, td_file%i_ndim, &
337      &     td_file%i_nvar, td_file%i_natt, td_file%i_uldid, il_fmt)
338      CALL iom_cdf__check(il_status,"IOM CDF GET INFO: ")
339
340      SELECT CASE(il_fmt)
341         CASE(nf90_format_classic, nf90_format_64bit)
342            td_file%c_type='cdf'
343         CASE(nf90_format_netcdf4, nf90_format_netcdf4_classic)
344            !td_file%c_type='cdf4'
345            td_file%c_type='cdf'
346      END SELECT
347
348      ! record header infos
349      td_file%i_rhd=1
350
351   END SUBROUTINE iom_cdf__get_info
352   !-------------------------------------------------------------------
353   !> @brief This subroutine read dimension on an opened netcdf file, and
354   !> reorder dimension to ('x', 'y', 'z', 't').
355   !> The dimension structure inside file structure is then completed.
356   !>
357   !> @author J.Paul
358   !> @date November, 2013 - Initial Version
359   !> @date October, 2016
360   !> - check unknown dimension
361   !>
362   !> @param[inout] td_file   file structure
363   !-------------------------------------------------------------------
364   SUBROUTINE iom_cdf__get_file_dim(td_file)
365      IMPLICIT NONE
366      ! Argument     
367      TYPE(TFILE), INTENT(INOUT) :: td_file
368      ! local variable
369      TYPE(TDIM) :: tl_dim
370
371      ! loop indices
372      INTEGER(i4) :: ji
373      INTEGER(i4) :: ii
374      !----------------------------------------------------------------
375
376      ! clean dimension
377      DO ji=1,ip_maxdim
378         CALL dim_clean(td_file%t_dim(ji))
379      ENDDO
380
381      IF( td_file%i_ndim > 0 )THEN
382
383         ii=1
384         DO ji = 1, td_file%i_ndim
385            ! read dimension information
386            tl_dim=iom_cdf_read_dim( td_file, ji)
387            ! sname == 'u' if dimension is unknown (not to be used)
388            IF( TRIM(tl_dim%c_sname) /= 'u' )THEN
389               IF( ii > ip_maxdim )THEN
390                  CALL logger_fatal("IOM CDF OPEN: too much dimension "//&
391                  & "to be read. you could choose dimension to be used. see "//&
392                  & " configuration file")
393               ENDIF
394               td_file%t_dim(ii)=dim_copy(tl_dim)
395               ii=ii+1
396            ENDIF
397         ENDDO
398
399         ! inform unlimited dimension
400         IF( td_file%i_uldid == -1 )THEN
401            CALL logger_warn( &
402            &  " IOM CDF GET FILE DIM: there is no unlimited dimension in file "//&
403            &  TRIM(td_file%c_name))
404         !ELSE
405         !   td_file%t_dim( td_file%i_uldid )%l_uld=.TRUE.
406         ENDIF
407
408      ELSE
409
410         CALL logger_warn( &
411         &  " IOM CDF GET FILE DIM: there is no dimension in file "//&
412         &  TRIM(td_file%c_name))
413
414      ENDIF
415
416      ! reorder dimension to ('x','y','z','t')
417      CALL dim_reorder(td_file%t_dim(:))
418
419   END SUBROUTINE iom_cdf__get_file_dim
420   !-------------------------------------------------------------------
421   !> @brief This subroutine read global attribute on an opened netcdf
422   !> file.
423   !> The attribute structure inside file structure is then completed.
424   !
425   !> @author J.Paul
426   !> @date November, 2013 - Initial Version
427   !> @date September, 2014
428   !> - use attribute periodicity read from the file if present.
429   !
430   !> @param[inout] td_file   file structure
431   !-------------------------------------------------------------------
432   SUBROUTINE iom_cdf__get_file_att(td_file)
433      IMPLICIT NONE
434      ! Argument     
435      TYPE(TFILE), INTENT(INOUT) :: td_file
436
437      ! local variable
438      TYPE(TATT) :: tl_att
439
440      ! loop indices
441      INTEGER(i4) :: ji
442      INTEGER(i4) :: ii
443      !----------------------------------------------------------------
444
445      IF( td_file%i_natt > 0 )THEN
446         IF(ASSOCIATED(td_file%t_att))THEN
447            CALL att_clean(td_file%t_att(:))
448            DEALLOCATE(td_file%t_att)
449         ENDIF
450         ALLOCATE(td_file%t_att(td_file%i_natt))
451
452         ii=1
453         DO ji = 1, td_file%i_natt
454            ! read global attribute
455            tl_att=iom_cdf_read_att( td_file, NF90_GLOBAL, ji)
456            IF( .NOT. att_is_dummy(tl_att) )THEN
457               td_file%t_att(ii)=att_copy(tl_att)
458               ii=ii+1
459            ENDIF
460           
461         ENDDO
462
463      ELSE
464         CALL logger_debug( &
465         &  " IOM CDF GET FILE ATT: there is no global attribute in file "//&
466         &  TRIM(td_file%c_name))
467      ENDIF
468
469   END SUBROUTINE iom_cdf__get_file_att
470   !-------------------------------------------------------------------
471   !> @brief This subroutine read information about variable of an
472   !> opened netcdf file.
473   !> The variable structure inside file structure is then completed.
474   !> @note variable value are not read !
475   !>
476   !> @author J.Paul
477   !> @date November, 2013 - Initial Version
478   !> @date September, 2015
479   !> - manage useless (dummy) variable
480   !> @date January, 2016
481   !> - increment n3d for 4D variable
482   !> @date October, 2016
483   !> - check if variable to be used (variable's dimension allowed and variable
484   !> not "dummy")
485   !>
486   !> @param[inout] td_file   file structure
487   !-------------------------------------------------------------------
488   SUBROUTINE iom_cdf__get_file_var(td_file)
489      IMPLICIT NONE
490      ! Argument     
491      TYPE(TFILE), INTENT(INOUT) :: td_file
492
493      ! local variable
494      INTEGER(i4) :: il_attid
495      INTEGER(i4) :: il_nvar
496
497      TYPE(TVAR), DIMENSION(:), ALLOCATABLE  :: tl_var
498
499      ! loop indices
500      INTEGER(i4) :: ji
501      INTEGER(i4) :: ii
502      !----------------------------------------------------------------
503
504      IF( td_file%i_nvar > 0 )THEN
505
506         IF(ASSOCIATED(td_file%t_var))THEN
507            CALL var_clean(td_file%t_var(:))
508            DEALLOCATE(td_file%t_var)
509         ENDIF
510
511         il_nvar=td_file%i_nvar
512         ALLOCATE(tl_var(il_nvar))
513         DO ji = 1, il_nvar
514           ! read variable information
515           tl_var(ji)=iom_cdf__read_var_meta( td_file, ji) 
516         ENDDO
517
518         ! update number of variable used
519         td_file%i_nvar=COUNT(tl_var(:)%l_use)
520
521         ALLOCATE(td_file%t_var(td_file%i_nvar))
522
523         ii=0
524         DO ji = 1, il_nvar
525            IF( tl_var(ji)%l_use )THEN
526               ii=ii+1
527               td_file%t_var(ii)=var_copy(tl_var(ji))
528               SELECT CASE(td_file%t_var(ii)%i_ndim)
529                  CASE(0)
530                     td_file%i_n0d=td_file%i_n0d+1
531                  CASE(1)
532                     td_file%i_n1d=td_file%i_n1d+1
533                     td_file%i_rhd=td_file%i_rhd+1
534                  CASE(2)
535                     td_file%i_n2d=td_file%i_n2d+1
536                     td_file%i_rhd=td_file%i_rhd+1
537                  CASE(3,4)
538                     td_file%i_n3d=td_file%i_n3d+1
539                     td_file%i_rhd=td_file%i_rhd+td_file%t_dim(3)%i_len
540               END SELECT
541
542               ! look for depth id
543               IF( INDEX(TRIM(fct_lower(td_file%t_var(ii)%c_name)),'depth')/=0 )THEN
544                  IF( td_file%i_depthid == 0 )THEN
545                     td_file%i_depthid=ji
546                  ELSE
547                     IF( td_file%i_depthid /= ji )THEN
548                        CALL logger_error("IOM CDF GET FILE VAR: find more"//&
549                           &  " than one depth variable in file "//&
550                           &  TRIM(td_file%c_name) )
551                     ENDIF
552                  ENDIF
553               ENDIF
554
555               ! look for time id
556               IF( INDEX(TRIM(fct_lower(td_file%t_var(ii)%c_name)),'time')/=0 )THEN
557                  IF( td_file%i_timeid == 0 )THEN
558                     td_file%i_timeid=ji
559                  ELSE
560                     IF( td_file%i_timeid /= ji )THEN
561                        CALL logger_warn("IOM CDF GET FILE VAR: find more "//&
562                        &                 "than one time variable in file "//&
563                        &                 TRIM(td_file%c_name)//". see "//&
564                        &                 "dummy.cfg configuration file to"//&
565                        &                 " not used dummy variables.")
566                     ENDIF
567                     il_attid=0
568                     IF( ASSOCIATED(td_file%t_var(ii)%t_att) )THEN
569                        il_attid=att_get_id(td_file%t_var(ii)%t_att(:),'calendar')
570                     ENDIF
571                     IF( il_attid /= 0 )THEN
572                        td_file%i_timeid=ji
573                     ENDIF
574                  ENDIF
575               ENDIF
576
577            ENDIF
578         ENDDO
579
580         CALL var_clean(tl_var(:))
581         DEALLOCATE(tl_var)
582
583      ELSE
584         CALL logger_debug( &
585         &  " IOM CDF GET FILE VAR: there is no variable in file "//&
586         &  TRIM(td_file%c_name))
587      ENDIF
588
589   END SUBROUTINE iom_cdf__get_file_var
590   !-------------------------------------------------------------------
591   !> @brief This subroutine delete coordinate variable from an
592   !> opened netcdf file if present.
593   !
594   !> @author J.Paul
595   !> @date November, 2013 - Initial Version
596   !
597   !> @param[inout] td_file   file structure
598   !-------------------------------------------------------------------
599   SUBROUTINE iom_cdf__del_coord_var(td_file)
600      IMPLICIT NONE
601      ! Argument     
602      TYPE(TFILE), INTENT(INOUT) :: td_file
603
604      ! local variable
605      CHARACTER(LEN=lc) :: cl_name
606      CHARACTER(LEN=lc) :: cl_sname
607
608      ! loop indices
609      INTEGER(i4) :: ji
610      INTEGER(i4) :: jj
611      !----------------------------------------------------------------
612      IF( td_file%i_nvar > 0 )THEN
613         DO ji=td_file%i_nvar,1,-1
614            cl_name=TRIM(td_file%t_var(ji)%c_name)
615            DO jj=1,ip_maxdim
616               IF( td_file%t_dim(jj)%l_use )THEN
617                  cl_sname=fct_upper(td_file%t_dim(jj)%c_sname)
618                  IF( TRIM(cl_name) == TRIM(cl_sname) )THEN
619                     CALL file_del_var(td_file,TRIM(cl_name))
620                     EXIT
621                  ENDIF
622               ENDIF
623            ENDDO
624         ENDDO
625      ELSE
626         CALL logger_debug( &
627         &  " IOM CDF DEL VAR DIM: there is no variable in file "//&
628         &  TRIM(td_file%c_name))
629      ENDIF
630   END SUBROUTINE iom_cdf__del_coord_var
631   !-------------------------------------------------------------------
632   !> @brief This function read one dimension in an opened netcdf file,
633   !> given dimension id.
634   !
635   !> @author J.Paul
636   !> @date November, 2013 - Initial Version
637   !> @date February, 2015 - create unused dimension, when reading dimension
638   !> of length less or equal to zero
639   !
640   !> @param[in] td_file   file structure
641   !> @param[in] id_dimid  dimension id
642   !> @return  dimension structure
643   !-------------------------------------------------------------------
644   TYPE(TDIM) FUNCTION iom_cdf__read_dim_id(td_file, id_dimid)
645      IMPLICIT NONE
646      ! Argument     
647      TYPE(TFILE), INTENT(IN) :: td_file
648      INTEGER(i4), INTENT(IN) :: id_dimid
649
650      ! local variable
651      INTEGER(i4)       :: il_status
652      INTEGER(i4)       :: il_len
653      CHARACTER(LEN=lc) :: cl_name
654      LOGICAL           :: ll_use
655      !----------------------------------------------------------------
656
657      ! check if file opened
658      IF( td_file%i_id == 0 )THEN
659
660         CALL logger_error( &
661         &  " IOM CDF READ DIM: no id associated to file "//TRIM(td_file%c_name))
662
663      ELSE
664
665         CALL logger_trace( &
666         &  " IOM CDF READ DIM: dimension "//TRIM(fct_str(id_dimid))//&
667         &  " in file "//TRIM(td_file%c_name))
668
669         il_status=NF90_INQUIRE_DIMENSION(td_file%i_id, id_dimid, &
670         &                                cl_name, il_len )
671         CALL iom_cdf__check(il_status,"IOM CDF READ DIM: ")
672
673         ll_use=.TRUE.
674         IF( il_len <= 0 )THEN
675            CALL logger_warn( &
676         &  " IOM CDF READ DIM: dimension "//TRIM(fct_str(id_dimid))//&
677         &  " in file "//TRIM(td_file%c_name)//" is less or equel to zero")
678            il_len=1
679            ll_use=.FALSE.
680         ENDIF
681         iom_cdf__read_dim_id=dim_init(cl_name, il_len, ld_use=ll_use)
682
683      ENDIF
684
685      iom_cdf__read_dim_id%i_id=id_dimid
686
687   END FUNCTION iom_cdf__read_dim_id
688   !-------------------------------------------------------------------
689   !> @brief This function read one dimension in an opened netcdf file,
690   !> given dimension name.
691   !
692   !> @author J.Paul
693   !> @date November, 2013 - Initial Version
694   !
695   !> @param[in] td_file   file structure
696   !> @param[in] cd_name   dimension name
697   !> @return  dimension structure
698   !-------------------------------------------------------------------
699   TYPE(TDIM) FUNCTION iom_cdf__read_dim_name(td_file, cd_name)
700      IMPLICIT NONE
701      ! Argument     
702      TYPE(TFILE),      INTENT(IN) :: td_file
703      CHARACTER(LEN=*), INTENT(IN) :: cd_name
704
705      ! local variable
706      INTEGER(i4) :: il_status
707      INTEGER(i4) :: il_dimid
708      !----------------------------------------------------------------
709
710      ! check if file opened
711      IF( td_file%i_id == 0 )THEN
712
713         CALL logger_error( &
714         &  " IOM CDF READ DIM: no id associated to file "//&
715         &  TRIM(td_file%c_name))
716
717      ELSE     
718
719         il_status=NF90_INQ_DIMID( td_file%i_id, TRIM(ADJUSTL(cd_name)), &
720         &                         il_dimid)
721         CALL iom_cdf__check(il_status,"IOM CDF READ DIM: ")
722
723         iom_cdf__read_dim_name=iom_cdf_read_dim(td_file, il_dimid)
724
725      ENDIF
726
727   END FUNCTION iom_cdf__read_dim_name
728   !-------------------------------------------------------------------
729   !> @brief This function read variable or global attribute in an opened
730   !> netcdf file, given attribute name.
731   !
732   !> @author J.Paul
733   !> @date November, 2013 - Initial Version
734   !
735   !> @param[in] td_file   file structure
736   !> @param[in] id_varid  variable id. use NF90_GLOBAL to read global
737   !> attribute in a file
738   !> @param[in] cd_name   attribute name
739   !> @return  attribute structure
740   !-------------------------------------------------------------------
741   TYPE(TATT) FUNCTION iom_cdf__read_att_name(td_file, id_varid, cd_name)
742      IMPLICIT NONE
743      ! Argument     
744      TYPE(TFILE),      INTENT(IN) :: td_file
745      INTEGER(i4),      INTENT(IN) :: id_varid
746      CHARACTER(LEN=*), INTENT(IN) :: cd_name
747
748      ! local variable
749      CHARACTER(LEN=lc) :: cl_name
750
751      INTEGER(i4) :: il_status
752      INTEGER(i4) :: il_attid
753      INTEGER(i4) :: il_type
754      INTEGER(i4) :: il_len
755
756      CHARACTER(LEN=lc) :: cl_value
757     
758      INTEGER(i1), DIMENSION(:), ALLOCATABLE :: bl_value
759      INTEGER(i2), DIMENSION(:), ALLOCATABLE :: sl_value
760      INTEGER(i4), DIMENSION(:), ALLOCATABLE :: il_value
761      REAL(sp)   , DIMENSION(:), ALLOCATABLE :: fl_value
762      REAL(dp)   , DIMENSION(:), ALLOCATABLE :: dl_value
763      !----------------------------------------------------------------
764      ! check if file opened
765      IF( td_file%i_id == 0 )THEN
766
767         CALL logger_error( &
768         &  " IOM CDF READ ATT: no id associated to file "//TRIM(td_file%c_name))
769
770      ELSE     
771
772         cl_name=TRIM(ADJUSTL(cd_name))
773
774         ! inquire attribute
775         IF( id_varid == NF90_GLOBAL )THEN
776
777            CALL logger_trace( &
778            &  " IOM CDF READ ATT: inquire global attribute "//&
779            &  " in file "//TRIM(td_file%c_name))
780
781         ELSE
782
783            CALL logger_trace( &
784            &  " IOM CDF READ ATT: inquire attribute "//&
785            &  " of variable "//TRIM(fct_str(id_varid))//&
786            &  " in file "//TRIM(td_file%c_name))
787
788         ENDIF
789
790         il_status=NF90_INQUIRE_ATTRIBUTE(td_file%i_id, id_varid,  &
791         &                                cl_name,&
792         &                                il_type,&
793         &                                il_len, &
794         &                                il_attid )
795         CALL iom_cdf__check(il_status,"IOM CDF READ ATT: ")
796
797         !! get attribute value
798         CALL logger_debug( " IOM CDF READ ATT: get attribute "//&
799            &            TRIM(cl_name)//" in file "//TRIM(td_file%c_name))
800
801         SELECT CASE( il_type )
802
803            CASE(NF90_CHAR)
804
805               ! check string lengths
806               IF( LEN(cl_value) < il_len )THEN
807
808                  CALL logger_warn( &
809                  &  " IOM CDF READ ATT: not enough space to put "//&
810                  &  "attribute "//TRIM(cl_name) )
811
812               ELSE
813
814                  ! Read the attributes
815                  il_status=NF90_GET_ATT(td_file%i_id, id_varid, &
816                  &                      cl_name, &
817                  &                      cl_value )
818                  CALL iom_cdf__check(il_status,"IOM CDF READ ATT: ")
819
820                  iom_cdf__read_att_name=att_init(cl_name, cl_value)
821
822               ENDIF
823         
824            CASE(NF90_BYTE)
825
826               ALLOCATE( bl_value( il_len), &
827               &         stat=il_status)
828               IF(il_status /= 0 )THEN
829
830                  CALL logger_error( "IOM CDF READ ATT: "//&
831                  &  "not enough space to put attribute "//TRIM(cl_name) )
832
833               ELSE
834
835                  ! Read the attributes
836                  il_status=NF90_GET_ATT(td_file%i_id, id_varid, &
837                  &                      cl_name, &
838                  &                      bl_value(:))
839                  CALL iom_cdf__check(il_status,"IOM CDF READ ATT: ")   
840
841                  iom_cdf__read_att_name=att_init(cl_name, bl_value(:))
842
843               ENDIF
844
845               DEALLOCATE(bl_value)
846
847            CASE(NF90_SHORT)
848
849               ALLOCATE( sl_value( il_len), &
850               &         stat=il_status)
851               IF(il_status /= 0 )THEN
852
853                  CALL logger_error( &
854                  &  " IOM CDF READ ATT: not enough space to put "//&
855                  &  "attribute "//TRIM(cl_name) )
856
857               ELSE
858
859                  ! Read the attributes
860                  il_status=NF90_GET_ATT(td_file%i_id, id_varid, &
861                  &                      cl_name, &
862                  &                      sl_value(:))
863                  CALL iom_cdf__check(il_status,"IOM CDF READ ATT: ")   
864
865                  iom_cdf__read_att_name=att_init(cl_name, sl_value(:))
866
867               ENDIF
868
869               DEALLOCATE(sl_value)
870
871            CASE(NF90_INT)
872
873               ALLOCATE( il_value( il_len), &
874               &         stat=il_status)
875               IF(il_status /= 0 )THEN
876
877                  CALL logger_error( &
878                  &  " IOM CDF READ ATT: not enough space to put "//&
879                  &  "attribute "//TRIM(cl_name) )
880
881               ELSE
882
883                  ! Read the attributes
884                  il_status=NF90_GET_ATT(td_file%i_id, id_varid, &
885                  &                      cl_name, &
886                  &                      il_value(:))
887                  CALL iom_cdf__check(il_status,"IOM CDF READ ATT: ")   
888
889                  iom_cdf__read_att_name=att_init(cl_name, il_value(:))
890               ENDIF
891
892               DEALLOCATE(il_value)
893
894            CASE(NF90_FLOAT)
895
896               ALLOCATE( fl_value( il_len), &
897               &         stat=il_status)
898               IF(il_status /= 0 )THEN
899
900                  CALL logger_error( &
901                  &  " IOM CDF READ ATT: not enough space to put "//&
902                  &  "attribute "//TRIM(cl_name) )
903
904               ELSE
905
906                  ! Read the attributes
907                  il_status=NF90_GET_ATT(td_file%i_id, id_varid, &
908                  &                      cl_name, &
909                  &                      fl_value(:))
910                  CALL iom_cdf__check(il_status,"IOM CDF READ ATT: ")   
911
912                  iom_cdf__read_att_name=att_init(cl_name, fl_value(:))
913
914               ENDIF
915
916               DEALLOCATE(fl_value)
917
918            CASE(NF90_DOUBLE)
919
920               ALLOCATE( dl_value( il_len), &
921               &         stat=il_status)
922               IF(il_status /= 0 )THEN
923
924                  CALL logger_error( &
925                  &  " IOM CDF READ ATT: not enough space to put "//&
926                  &  "attribute "//TRIM(cl_name) )
927
928               ELSE
929
930                  ! Read the attributes
931                  il_status=NF90_GET_ATT(td_file%i_id, id_varid, &
932                  &                      cl_name, &
933                  &                      dl_value(:))
934                  CALL iom_cdf__check(il_status,"IOM CDF READ ATT: ")   
935
936                  iom_cdf__read_att_name=att_init(cl_name, dl_value(:))
937
938               ENDIF
939
940               DEALLOCATE(dl_value)
941
942         END SELECT
943
944         iom_cdf__read_att_name%i_id=il_attid
945
946      ENDIF
947
948   END FUNCTION iom_cdf__read_att_name
949   !-------------------------------------------------------------------
950   !> @brief This function read variable or global attribute in an opened
951   !> netcdf file, given attribute id.
952   !
953   !> @author J.Paul
954   !> @date November, 2013 - Initial Version
955   !
956   !> @param[in] td_file   file structure
957   !> @param[in] id_varid  variable id. use NF90_GLOBAL to read global
958   !> attribute in a file
959   !> @param[in] id_attid  attribute id
960   !> @return  attribute structure
961   !-------------------------------------------------------------------
962   TYPE(TATT) FUNCTION iom_cdf__read_att_id(td_file, id_varid, id_attid)
963      IMPLICIT NONE
964      ! Argument     
965      TYPE(TFILE), INTENT(IN) :: td_file
966      INTEGER(i4), INTENT(IN) :: id_varid
967      INTEGER(i4), INTENT(IN) :: id_attid
968
969      ! local variable
970      INTEGER(i4)       :: il_status
971      CHARACTER(LEN=lc) :: cl_name
972      !----------------------------------------------------------------
973      ! check if file opened
974      IF( td_file%i_id == 0 )THEN
975
976         CALL logger_error( &
977         &  "IOM CDF READ ATT: no id associated to file "//TRIM(td_file%c_name))
978
979      ELSE
980
981         ! get attribute name
982         il_status=NF90_INQ_ATTNAME(td_file%i_id, id_varid, id_attid, cl_name)
983         CALL iom_cdf__check(il_status,"IOM CDF READ ATT: ")
984
985         ! read attribute
986         iom_cdf__read_att_id=iom_cdf__read_att_name(td_file, id_varid, cl_name)
987
988      ENDIF
989
990   END FUNCTION iom_cdf__read_att_id
991   !-------------------------------------------------------------------
992   !> @brief This function read variable value in an opened
993   !> netcdf file, given variable id.
994   !> @details
995   !> Optionaly, start indices and number of indices selected along each dimension
996   !> could be specify in a 4 dimension array (/'x','y','z','t'/)
997   !
998   !> @author J.Paul
999   !> @date November, 2013 - Initial Version
1000   !
1001   !> @param[in] td_file   file structure
1002   !> @param[in] id_varid  variable id
1003   !> @param[in] id_start  index in the variable from which the data values
1004   !> will be read
1005   !> @param[in] id_count  number of indices selected along each dimension
1006   !> @return  variable structure
1007   !-------------------------------------------------------------------
1008   TYPE(TVAR) FUNCTION iom_cdf__read_var_id(td_file, id_varid,&
1009   &                                        id_start, id_count)
1010      IMPLICIT NONE
1011      ! Argument     
1012      TYPE(TFILE),               INTENT(IN) :: td_file
1013      INTEGER(i4),               INTENT(IN) :: id_varid
1014      INTEGER(i4), DIMENSION(:), INTENT(IN), OPTIONAL :: id_start
1015      INTEGER(i4), DIMENSION(:), INTENT(IN), OPTIONAL :: id_count
1016
1017      ! local variable
1018      INTEGER(i4), DIMENSION(1) :: il_ind
1019      !----------------------------------------------------------------
1020      ! check if file opened
1021      IF( td_file%i_id == 0 )THEN
1022
1023         CALL logger_error( &
1024         &  " IOM CDF READ VAR: no id associated to file "//TRIM(td_file%c_name))
1025
1026      ELSE
1027
1028         ! look for variable index
1029         il_ind(:)=MINLOC(td_file%t_var(:)%i_id,mask=(td_file%t_var(:)%i_id==id_varid))
1030         IF( il_ind(1) /= 0 )THEN
1031
1032            iom_cdf__read_var_id=var_copy(td_file%t_var(il_ind(1)))
1033
1034            !!! read variable value
1035            CALL iom_cdf__read_var_value(td_file, iom_cdf__read_var_id, &
1036            &                            id_start, id_count)
1037
1038         ELSE
1039            CALL logger_error( &
1040            &  " IOM CDF READ VAR: there is no variable with id "//&
1041            &  TRIM(fct_str(id_varid))//" in file "//TRIM(td_file%c_name))
1042         ENDIF
1043
1044      ENDIF
1045   END FUNCTION iom_cdf__read_var_id
1046   !-------------------------------------------------------------------
1047   !> @brief This function read variable value in an opened
1048   !> netcdf file, given variable name or standard name.
1049   !> @details
1050   !> Optionaly, start indices and number of indices selected along each dimension
1051   !> could be specify in a 4 dimension array (/'x','y','z','t'/)
1052   !>
1053   !> look first for variable name. If it doesn't
1054   !> exist in file, look for variable standard name.<br/>
1055   !
1056   !> @author J.Paul
1057   !> @date November, 2013 - Initial Version
1058   !
1059   !> @param[in] td_file   file structure
1060   !> @param[in] cd_name   variable name or standard name.
1061   !> @param[in] id_start  index in the variable from which the data values will be read
1062   !> @param[in] id_count  number of indices selected along each dimension
1063   !> @return  variable structure
1064   !-------------------------------------------------------------------
1065   TYPE(TVAR) FUNCTION iom_cdf__read_var_name(td_file, cd_name,  &
1066   &                                          id_start, id_count )
1067      IMPLICIT NONE
1068      ! Argument     
1069      TYPE(TFILE)     ,                INTENT(IN) :: td_file
1070      CHARACTER(LEN=*),                INTENT(IN), OPTIONAL :: cd_name
1071      INTEGER(i4)     , DIMENSION(:),  INTENT(IN), OPTIONAL :: id_start
1072      INTEGER(i4)     , DIMENSION(:),  INTENT(IN), OPTIONAL :: id_count
1073
1074      ! local variable
1075      INTEGER(i4)       :: il_varid
1076      !----------------------------------------------------------------
1077      ! check if file opened
1078      IF( td_file%i_id == 0 )THEN
1079
1080         CALL logger_error( &
1081         &  " IOM CDF READ VAR: no id associated to file "//TRIM(td_file%c_name))
1082
1083      ELSE
1084
1085         IF( .NOT. PRESENT(cd_name) )THEN
1086
1087            CALL logger_error( &
1088            &  " IOM CDF READ VAR: you must specify a variable to read "//&
1089            &  " in file "//TRIM(td_file%c_name))
1090
1091         ELSE
1092
1093            il_varid=var_get_index(td_file%t_var(:), cd_name)
1094            IF( il_varid /= 0 )THEN
1095
1096               iom_cdf__read_var_name=var_copy(td_file%t_var(il_varid))
1097
1098               !!! read variable value
1099               CALL iom_cdf__read_var_value( td_file, &
1100               &                             iom_cdf__read_var_name, &
1101               &                             id_start, id_count)
1102
1103            ELSE
1104
1105               CALL logger_error( &
1106               &  " IOM CDF READ VAR: there is no variable with "//&
1107               &  " name or standard name "//TRIM(cd_name)//&
1108               &  " in file "//TRIM(td_file%c_name) )
1109            ENDIF
1110
1111         ENDIF
1112
1113      ENDIF
1114     
1115   END FUNCTION iom_cdf__read_var_name
1116   !-------------------------------------------------------------------
1117   !> @brief This subroutine fill all variable value from an opened
1118   !> netcdf file.
1119   !> @details
1120   !> Optionaly, start indices and number of indices selected along each dimension
1121   !> could be specify in a 4 dimension array (/'x','y','z','t'/)
1122   !
1123   !> @author J.Paul
1124   !> @date November, 2013 - Initial Version
1125   !
1126   !> @param[inout] td_file   file structure
1127   !> @param[in] id_start     index in the variable from which the data values
1128   !> will be read
1129   !> @param[in] id_count     number of indices selected along each dimension
1130   !-------------------------------------------------------------------
1131   SUBROUTINE iom_cdf__fill_var_all(td_file, id_start, id_count)
1132      IMPLICIT NONE
1133      ! Argument     
1134      TYPE(TFILE),               INTENT(INOUT) :: td_file
1135      INTEGER(i4), DIMENSION(:), INTENT(IN   ),  OPTIONAL :: id_start
1136      INTEGER(i4), DIMENSION(:), INTENT(IN   ),  OPTIONAL :: id_count
1137
1138      ! local variable
1139
1140      ! loop indices
1141      INTEGER(i4) :: ji
1142      !----------------------------------------------------------------
1143      ! check if file opened
1144      IF( td_file%i_id == 0 )THEN
1145
1146         CALL logger_error( &
1147         &  " IOM CDF FILL VAR: no id associated to file "//TRIM(td_file%c_name))
1148
1149      ELSE
1150
1151         DO ji=1,td_file%i_nvar
1152            CALL iom_cdf_fill_var(td_file, td_file%t_var(ji)%i_id, &
1153            &                     id_start, id_count)
1154         ENDDO
1155
1156      ENDIF
1157   END SUBROUTINE iom_cdf__fill_var_all
1158   !-------------------------------------------------------------------
1159   !> @brief This subroutine fill variable value in an opened
1160   !> netcdf file, given variable id.
1161   !> @details
1162   !> Optionaly, start indices and number of indices selected along each dimension
1163   !> could be specify in a 4 dimension array (/'x','y','z','t'/)
1164   !
1165   !> @author J.Paul
1166   !> @date November, 2013 - Initial Version
1167   !
1168   !> @param[inout] td_file   file structure
1169   !> @param[in] id_varid     variable id
1170   !> @param[in] id_start     index in the variable from which the data values
1171   !> will be read
1172   !> @param[in] id_count     number of indices selected along each dimension
1173   !-------------------------------------------------------------------
1174   SUBROUTINE iom_cdf__fill_var_id(td_file, id_varid, id_start, id_count)
1175      IMPLICIT NONE
1176      ! Argument     
1177      TYPE(TFILE),               INTENT(INOUT) :: td_file
1178      INTEGER(i4),               INTENT(IN)    :: id_varid
1179      INTEGER(i4), DIMENSION(:), INTENT(IN),  OPTIONAL :: id_start
1180      INTEGER(i4), DIMENSION(:), INTENT(IN),  OPTIONAL :: id_count
1181
1182      ! local variable
1183      INTEGER(i4), DIMENSION(1) :: il_varid
1184
1185      ! loop indices
1186      INTEGER(i4) :: ji
1187      !----------------------------------------------------------------
1188      ! check if file opened
1189      IF( td_file%i_id == 0 )THEN
1190
1191         CALL logger_error( &
1192         &  "IOM CDF FILL VAR: no id associated to file "//TRIM(td_file%c_name))
1193
1194      ELSE
1195
1196         ! look for variable id
1197         il_varid(:)=MINLOC( td_file%t_var(:)%i_id, &
1198         &                 mask=(td_file%t_var(:)%i_id==id_varid))
1199         IF( il_varid(1) /= 0 )THEN
1200
1201            !!! read variable value
1202            CALL iom_cdf__read_var_value(td_file, td_file%t_var(il_varid(1)), &
1203            &                            id_start, id_count)
1204
1205            DO ji=1,td_file%i_nvar
1206               CALL logger_debug(" IOM CDF FILL VAR: var id "//&
1207               &     TRIM(td_file%t_var(ji)%c_name)//" "//&
1208               &     TRIM(fct_str(td_file%t_var(ji)%i_id)) )
1209            ENDDO
1210         ELSE
1211            CALL logger_error( &
1212            &  " IOM CDF FILL VAR: there is no variable with id "//&
1213            &  TRIM(fct_str(id_varid))//" in file "//TRIM(td_file%c_name))
1214         ENDIF
1215
1216      ENDIF
1217   END SUBROUTINE iom_cdf__fill_var_id
1218   !-------------------------------------------------------------------
1219   !> @brief This subroutine fill variable value in an opened
1220   !> netcdf file, given variable name or standard name.
1221   !> @details
1222   !> Optionaly, start indices and number of indices selected along each dimension
1223   !> could be specify in a 4 dimension array (/'x','y','z','t'/)
1224   !>
1225   !> look first for variable name. If it doesn't
1226   !> exist in file, look for variable standard name.<br/>
1227   !
1228   !> @author J.Paul
1229   !> @date November, 2013 - Initial Version
1230   !
1231   !> @param[inout] td_file   file structure
1232   !> @param[in] cd_name      variable name or standard name
1233   !> @param[in] id_start     index in the variable from which the data values will be read
1234   !> @param[in] id_count     number of indices selected along each dimension
1235   !-------------------------------------------------------------------
1236   SUBROUTINE iom_cdf__fill_var_name(td_file, cd_name, id_start, id_count )
1237      IMPLICIT NONE
1238      ! Argument     
1239      TYPE(TFILE),                   INTENT(INOUT) :: td_file
1240      CHARACTER(LEN=*),              INTENT(IN)    :: cd_name
1241      INTEGER(i4),     DIMENSION(:), INTENT(IN),  OPTIONAL :: id_start
1242      INTEGER(i4),     DIMENSION(:), INTENT(IN),  OPTIONAL :: id_count
1243
1244      ! local variable
1245      INTEGER(i4)       :: il_varid
1246      !----------------------------------------------------------------
1247      ! check if file opened
1248      IF( td_file%i_id == 0 )THEN
1249
1250         CALL logger_error( &
1251         &  "IOM CDF FILL VAR: no id associated to file "//TRIM(td_file%c_name))
1252
1253      ELSE
1254
1255            il_varid=var_get_index(td_file%t_var(:), cd_name)
1256            IF( il_varid /= 0 )THEN
1257
1258               !!! read variable value
1259               CALL iom_cdf__read_var_value(td_file, td_file%t_var(il_varid), &
1260               &                            id_start, id_count)
1261
1262            ELSE
1263
1264               CALL logger_error( &
1265               &  "IOM CDF FILL VAR: there is no variable with "//&
1266               &  "name or standard name"//TRIM(cd_name)//&
1267               &  " in file "//TRIM(td_file%c_name))
1268            ENDIF
1269
1270      ENDIF
1271     
1272   END SUBROUTINE iom_cdf__fill_var_name
1273   !-------------------------------------------------------------------
1274   !> @brief This function read metadata of a variable in an opened
1275   !> netcdf file.
1276   !
1277   !> @note variable value are not read
1278   !
1279   !> @author J.Paul
1280   !> @date November, 2013 - Initial Version
1281   !> @date September, 2014
1282   !> - force to use FillValue=1.e20 if no FillValue for coordinate variable.
1283   !> @date September, 2015
1284   !> - manage useless (dummy) attribute
1285   !
1286   !> @param[in] td_file   file structure
1287   !> @param[in] id_varid  variable id
1288   !> @return  variable structure
1289   !-------------------------------------------------------------------
1290   TYPE(TVAR) FUNCTION iom_cdf__read_var_meta(td_file, id_varid)
1291      IMPLICIT NONE
1292      ! Argument     
1293      TYPE(TFILE), INTENT(IN) :: td_file
1294      INTEGER(i4), INTENT(IN) :: id_varid
1295
1296      ! local variable
1297      CHARACTER(LEN=lc)                                       :: cl_name
1298
1299      INTEGER(i4)                                             :: il_status
1300      INTEGER(i4)                                             :: il_type
1301      INTEGER(i4)                                             :: il_ndim
1302      INTEGER(i4)                                             :: il_natt
1303      INTEGER(i4)                                             :: il_attid
1304      INTEGER(i4), DIMENSION(NF90_MAX_VAR_DIMS)               :: il_dimid
1305
1306      TYPE(TDIM) , DIMENSION(ip_maxdim)                       :: tl_dim
1307      TYPE(TATT)                                              :: tl_fill
1308      TYPE(TATT) , DIMENSION(:)                 , ALLOCATABLE :: tl_att
1309      TYPE(TATT) , DIMENSION(:)                 , ALLOCATABLE :: tl_tmp
1310
1311      ! loop indices
1312      INTEGER(i4) :: ji
1313      !----------------------------------------------------------------
1314      ! check if file opened
1315      IF( td_file%i_id == 0 )THEN
1316
1317         CALL logger_error( &
1318         &  " IOM CDF READ VAR META: no id associated to file "//&
1319         &   TRIM(td_file%c_name))
1320
1321      ELSE
1322
1323         ! inquire variable
1324         CALL logger_debug( &
1325         &  " IOM CDF READ VAR META: inquire variable "//&
1326         &  TRIM(fct_str(id_varid))//&
1327         &  " in file "//TRIM(td_file%c_name))
1328         
1329         il_dimid(:)=0
1330
1331         il_status=NF90_INQUIRE_VARIABLE( td_file%i_id, id_varid,        &
1332         &                                cl_name,    &
1333         &                                il_type,    &
1334         &                                il_ndim,    &
1335         &                                il_dimid(:),&
1336         &                                il_natt )
1337         CALL iom_cdf__check(il_status,"IOM CDF READ VAR META: ")
1338
1339         !!! fill variable dimension structure
1340         tl_dim(:)=iom_cdf__read_var_dim( td_file, il_ndim, cl_name, il_dimid(:) )
1341
1342         IF( il_natt /= 0 )THEN
1343            ALLOCATE( tl_att(il_natt) )
1344            !!! fill variable attribute structure
1345            tl_att(:)=iom_cdf__read_var_att(td_file, id_varid, il_natt)
1346
1347            !! look for _FillValue. if none add one
1348            il_attid=att_get_id(tl_att(:),'_FillValue')
1349            IF( il_attid == 0 )THEN
1350               CALL logger_info("IOM CDF READ VAR META: no _FillValue for variable "//&
1351               &  TRIM(cl_name)//" in file "//TRIM(td_file%c_name) )
1352
1353               il_attid=att_get_id(tl_att(:),'missing_value')
1354               IF( il_attid /= 0 )THEN
1355                  ! create attribute _FillValue
1356                  CALL logger_info("IOM CDF READ VAR META: assume _FillValue is equal to "//&
1357                  &                "missing_value for variable "//TRIM(cl_name) )
1358                  tl_fill=att_init('_FillValue',tl_att(il_attid)%d_value(:), &
1359                  &                 id_type=tl_att(il_attid)%i_type)
1360               ELSE
1361                  ! create attribute _FillValue
1362                  SELECT CASE(TRIM(fct_lower(cl_name)))
1363                     CASE DEFAULT
1364                        CALL logger_info("IOM CDF READ VAR META: assume _FillValue is equal to "//&
1365                        &                "zero for variable "//TRIM(cl_name) )
1366                        tl_fill=att_init('_FillValue',0.)
1367                     CASE('nav_lon','nav_lat', 'nav_lev', &
1368                        &  'glamt','glamu','glamv','glamf', &
1369                        &  'gphit','gphiu','gphiv','gphif')
1370                        CALL logger_info("IOM CDF READ VAR META: assume _FillValue is equal to "//&
1371                        &                "dummy fillValue (1.e20) for variable "//TRIM(cl_name) )
1372                        tl_fill=att_init('_FillValue',1.e20)
1373                  END SELECT
1374               ENDIF
1375
1376               ALLOCATE( tl_tmp(il_natt) )
1377               ! save read attribut
1378               tl_tmp(:)=att_copy(tl_att(:))
1379               ! change number of attribute in array
1380               CALL att_clean(tl_att(:))
1381               DEALLOCATE( tl_att )
1382               ALLOCATE( tl_att(il_natt+1) )
1383               ! copy read attribut
1384               tl_att(1:il_natt)=att_copy(tl_tmp(:))
1385               ! clean
1386               CALL att_clean(tl_tmp(:))
1387               DEALLOCATE( tl_tmp )
1388
1389               ! create attribute _FillValue
1390               tl_att(il_natt+1)=att_copy(tl_fill)
1391
1392            ENDIF
1393
1394         ELSE
1395            ALLOCATE(tl_att(il_natt+1) )
1396            ! create attribute _FillValue
1397            SELECT CASE(TRIM(fct_lower(cl_name)))
1398               CASE DEFAULT
1399                  CALL logger_info("IOM CDF READ VAR META: assume _FillValue is equal to "//&
1400                  &                "zero for variable "//TRIM(cl_name) )
1401                  tl_fill=att_init('_FillValue',0.)
1402               CASE('nav_lon','nav_lat', &
1403                  &  'glamt','glamu','glamv','glamf', &
1404                  &  'gphit','gphiu','gphiv','gphif')
1405                  CALL logger_info("IOM CDF READ VAR META: assume _FillValue is equal to "//&
1406                  &                "dummy fillValue (1.e20) for variable "//TRIM(cl_name) )
1407                  tl_fill=att_init('_FillValue',1.e20)
1408            END SELECT           
1409            ! create attribute _FillValue
1410            tl_att(il_natt+1)=att_copy(tl_fill)
1411         ENDIF
1412
1413         !! initialize variable
1414         iom_cdf__read_var_meta=var_init( cl_name, il_type, tl_dim(:), &
1415         &                                tl_att(:), id_id=id_varid )
1416
1417         !! look for dummy attribute
1418         DO ji=il_natt,1,-1
1419            IF( att_is_dummy(tl_att(ji)) )THEN
1420               CALL var_del_att(iom_cdf__read_var_meta, tl_att(ji))
1421            ENDIF
1422         ENDDO
1423
1424         !! check if variable is dummy
1425         IF( var_is_dummy(iom_cdf__read_var_meta) )THEN
1426            iom_cdf__read_var_meta%l_use=.FALSE.
1427         ENDIF
1428
1429         !! check if all dimensions are allowed
1430         DO ji=1,il_ndim
1431            IF( ALL(td_file%t_dim(:)%i_id /= il_dimid(ji)) )THEN
1432               iom_cdf__read_var_meta%l_use=.FALSE.
1433            ENDIF
1434         ENDDO
1435
1436         ! clean
1437         CALL dim_clean(tl_dim(:))
1438         CALL att_clean(tl_fill)
1439         CALL att_clean(tl_att(:))
1440         DEALLOCATE( tl_att )
1441
1442      ENDIF
1443
1444   END FUNCTION iom_cdf__read_var_meta
1445   !-------------------------------------------------------------------
1446   !> @brief This subroutine read variable dimension
1447   !> in an opened netcdf file.
1448   !>
1449   !> @details
1450   !> the number of dimension can't exceed 4,
1451   !> and should be 'x', 'y', 'z', 't' (whatever their order).<br/>
1452   !> If the number of dimension read is less than 4, the array of dimension
1453   !> strucure is filled with unused dimension.<br/>
1454   !> So the array of dimension structure of a variable is always compose of 4
1455   !> dimension (use or not).
1456   !>
1457   !> @warn dummy dimension are not used.
1458   !>
1459   !> @author J.Paul
1460   !> @date November, 2013 - Initial Version
1461   !> @date July, 2015
1462   !> - Bug fix: use order to disorder table (see dim_init)
1463   !> @date September, 2015
1464   !> - check dummy dimension
1465   !>
1466   !> @param[in] td_file   file structure
1467   !> @param[in] id_ndim   number of dimension
1468   !> @param[in] cd_name   variable name
1469   !> @param[in] id_dimid  array of dimension id
1470   !> @return array dimension structure
1471   !-------------------------------------------------------------------
1472   FUNCTION iom_cdf__read_var_dim(td_file, id_ndim, cd_name, id_dimid)
1473      IMPLICIT NONE
1474      ! Argument     
1475      TYPE(TFILE),               INTENT(IN) :: td_file
1476      INTEGER(i4),               INTENT(IN) :: id_ndim
1477      CHARACTER(LEN=*)         , INTENT(IN) :: cd_name
1478      INTEGER(i4), DIMENSION(:), INTENT(IN) :: id_dimid
1479
1480      ! function
1481      TYPE(TDIM), DIMENSION(ip_maxdim) :: iom_cdf__read_var_dim
1482
1483      ! local variable
1484      INTEGER(i4), DIMENSION(ip_maxdim) :: il_xyzt2
1485
1486      TYPE(TDIM) , DIMENSION(ip_maxdim) :: tl_dim
1487
1488      ! loop indices
1489      INTEGER(i4) :: ji
1490      INTEGER(i4) :: ii
1491      !----------------------------------------------------------------
1492
1493      IF( id_ndim == 0 )THEN
1494
1495         tl_dim(:)%l_use=.FALSE.
1496
1497         ! reorder dimension to ('x','y','z','t')
1498         CALL dim_reorder(tl_dim(:))
1499
1500         iom_cdf__read_var_dim(:)=dim_copy(tl_dim(:))
1501
1502         ! clean
1503         CALL dim_clean(tl_dim(:))
1504
1505      ELSE IF( id_ndim > 0 )THEN
1506
1507         ii=1
1508         DO ji = 1, id_ndim
1509
1510            ! check if dimension to be used, is allowed
1511            IF( ANY(td_file%t_dim(:)%i_id == id_dimid(ji)) )THEN
1512               IF( ii > ip_maxdim )THEN
1513                  CALL logger_error(" IOM CDF READ VAR DIM: "//&
1514                  &  "too much dimensions for variable "//&
1515                  &  TRIM(cd_name)//". check dummy configuration file.")
1516               ENDIF
1517
1518               CALL logger_debug( " IOM CDF READ VAR DIM: get variable "//&
1519                  &  "dimension "//TRIM(fct_str(ji)) )
1520
1521               il_xyzt2(ii)=td_file%t_dim(id_dimid(ji))%i_xyzt2
1522               
1523               ! read dimension information
1524               tl_dim(ii) = dim_init( td_file%t_dim(il_xyzt2(ii))%c_name, &
1525               &                      td_file%t_dim(il_xyzt2(ii))%i_len )
1526
1527               ii=ii+1
1528            ELSE
1529               CALL logger_debug( " IOM CDF READ VAR DIM: dummy variable "//&
1530               &  "dimension "//TRIM(fct_str(ji))//" not used." )
1531            ENDIF
1532         ENDDO
1533
1534         ! reorder dimension to ('x','y','z','t')
1535         CALL dim_reorder(tl_dim(:))
1536 
1537         iom_cdf__read_var_dim(:)=dim_copy(tl_dim(:))
1538
1539         ! clean
1540         CALL dim_clean(tl_dim(:))
1541
1542      ENDIF
1543
1544   END FUNCTION iom_cdf__read_var_dim
1545   !-------------------------------------------------------------------
1546   !> @brief This subroutine read variable attributes
1547   !> in an opened netcdf file.
1548   !
1549   !> @author J.Paul
1550   !> @date November, 2013 - Initial Version
1551   !
1552   !> @param[in] td_file   file structure
1553   !> @param[in] id_varid  variable id
1554   !> @param[in] id_natt   number of attributes
1555   !> @return array of attribute structure
1556   !-------------------------------------------------------------------
1557   FUNCTION iom_cdf__read_var_att(td_file, id_varid, id_natt)
1558      IMPLICIT NONE
1559      ! Argument     
1560      TYPE(TFILE), INTENT(IN) :: td_file
1561      INTEGER(i4), INTENT(IN) :: id_varid
1562      INTEGER(i4), INTENT(IN) :: id_natt     
1563
1564      ! function
1565      TYPE(TATT), DIMENSION(id_natt) :: iom_cdf__read_var_att
1566
1567      ! local variable
1568
1569      ! loop indices
1570      INTEGER(i4) :: ji
1571      !----------------------------------------------------------------
1572
1573      IF( id_natt > 0 )THEN
1574     
1575         ! read attributes
1576         DO ji = 1, id_natt
1577            CALL logger_trace( " IOM CDF READ VAR ATT: get attribute "//&
1578            &               TRIM(fct_str(ji)) )
1579
1580            iom_cdf__read_var_att(ji)=iom_cdf_read_att(td_file, id_varid, ji)
1581
1582         ENDDO
1583
1584      ELSE
1585
1586         CALL logger_debug( " IOM CDF READ VAR ATT: no attribute for variable " )
1587
1588      ENDIF
1589
1590   END FUNCTION iom_cdf__read_var_att
1591   !-------------------------------------------------------------------
1592   !> @brief This subroutine read variable value
1593   !> in an opened netcdf file.
1594   !> @details
1595   !> Optionaly, start indices and number of indices selected along each dimension
1596   !> could be specify in a 4 dimension array (/'x','y','z','t'/)
1597   !
1598   !> @author J.Paul
1599   !> @date November, 2013 - Initial Version
1600   !> @date June, 2015
1601   !> - use scale factor and offset, as soon as read variable value
1602   !
1603   !> @param[in] td_file   file structure
1604   !> @param[inout] td_var variable structure
1605   !> @param[in] id_start  index in the variable from which the data values will be read
1606   !> @param[in] id_count  number of indices selected along each dimension
1607   !> @return variable structure completed
1608   !-------------------------------------------------------------------
1609   SUBROUTINE iom_cdf__read_var_value(td_file, td_var, &
1610   &                                  id_start, id_count )
1611      IMPLICIT NONE
1612      ! Argument     
1613      TYPE(TFILE),               INTENT(IN)    :: td_file
1614      TYPE(TVAR) ,               INTENT(INOUT) :: td_var
1615      INTEGER(i4), DIMENSION(:), INTENT(IN),   OPTIONAL :: id_start
1616      INTEGER(i4), DIMENSION(:), INTENT(IN),   OPTIONAL :: id_count
1617
1618      ! local variable
1619      INTEGER(i4)                                    :: il_status
1620      INTEGER(i4)                                    :: il_tmp1
1621      INTEGER(i4)                                    :: il_tmp2
1622      INTEGER(i4)                                    :: il_varid
1623      INTEGER(i4), DIMENSION(ip_maxdim)              :: il_start
1624      INTEGER(i4), DIMENSION(ip_maxdim)              :: il_count
1625      INTEGER(i4), DIMENSION(ip_maxdim)              :: il_start_ord
1626      INTEGER(i4), DIMENSION(ip_maxdim)              :: il_count_ord
1627
1628      REAL(dp)   , DIMENSION(:,:,:,:)  , ALLOCATABLE :: dl_value
1629      REAL(dp)   , DIMENSION(:,:,:,:)  , ALLOCATABLE :: dl_tmp
1630
1631      ! loop indices
1632      INTEGER(i4) :: ji
1633      !----------------------------------------------------------------
1634
1635      ! check if variable in file structure
1636      il_varid=var_get_id(td_file%t_var(:),TRIM(td_var%c_name))
1637      IF( il_varid /= 0 )THEN
1638
1639         ! check id_count and id_start optionals parameters...
1640         IF( (       PRESENT(id_start)  .AND. (.NOT. PRESENT(id_count))) .OR. &
1641             ((.NOT. PRESENT(id_start)) .AND.        PRESENT(id_count) ) )THEN
1642            CALL logger_warn( "IOM CDF READ VAR VALUE: id_start and id_count"//&
1643               & " should be both specify")
1644         ENDIF
1645         IF( PRESENT(id_start).AND.PRESENT(id_count) )THEN
1646
1647            IF( SIZE(id_start(:)) /= ip_maxdim .OR. &
1648            &   SIZE(id_count(:)) /= ip_maxdim )THEN
1649               CALL logger_error("IOM CDF READ VAR: dimension of array start"//&
1650                  &  " or count are invalid to read variable "//&
1651                  &  TRIM(td_var%c_name)//" in file "//TRIM(td_file%c_name) )
1652            ENDIF
1653
1654            ! change dimension order from ('x','y','z','t')
1655            il_start(:)=dim_reorder_xyzt2(td_var%t_dim, id_start(:))
1656            il_count(:)=dim_reorder_xyzt2(td_var%t_dim, id_count(:))
1657
1658            ! keep ordered array ('x','y','z','t')
1659            il_start_ord(:)=id_start(:)
1660            il_count_ord(:)=id_count(:)
1661
1662         ELSE
1663
1664            ! change dimension order from ('x','y','z','t')
1665            il_start(:)=(/1,1,1,1/)
1666            il_count(:)=dim_reorder_xyzt2(td_var%t_dim(:),td_var%t_dim(:)%i_len)
1667
1668            ! keep ordered array ('x','y','z','t')
1669            il_start_ord(:)=(/1,1,1,1/)
1670            il_count_ord(:)=td_var%t_dim(:)%i_len
1671
1672         ENDIF
1673
1674         ! check dimension
1675         IF( .NOT. ALL(il_start_ord(:)>=(/1,1,1,1/)) )THEN
1676
1677            CALL logger_error( "IOM CDF READ VAR VALUE: start indices should"//&
1678            &  " be greater than or equal to 1")
1679
1680         ENDIF
1681
1682         IF(.NOT.ALL(il_start_ord(:)+il_count_ord(:)-1 <= &
1683            &  (/td_var%t_dim( 1 )%i_len,&
1684            &    td_var%t_dim( 2 )%i_len,&
1685            &    td_var%t_dim( 3 )%i_len,&
1686            &    td_var%t_dim( 4 )%i_len &
1687            &                                            /)) )THEN
1688
1689            DO ji = 1, ip_maxdim
1690               il_tmp1=il_start_ord(ji)+il_count_ord(ji)-1
1691               il_tmp2=td_var%t_dim(ji)%i_len
1692               CALL logger_debug( "IOM CDF READ VAR VALUE: start + count -1:"//&
1693               &  TRIM(fct_str(il_tmp1))//" variable dimension"//&
1694               &  TRIM(fct_str(il_tmp2)))
1695            ENDDO
1696            CALL logger_error( "IOM CDF READ VAR VALUE: start + count exceed "//&
1697            &  "variable dimension for "//TRIM(td_var%c_name) )
1698
1699         ELSE
1700
1701            ! Allocate space to hold variable value (disorder)
1702            ALLOCATE(dl_value( il_count(1), &
1703               &               il_count(2), &
1704               &               il_count(3), &
1705               &               il_count(4)),&
1706               &               stat=il_status)
1707            IF( il_status /= 0 )THEN
1708
1709              CALL logger_error( &
1710               &  "IOM CDF READ VAR VALUE: not enough space to put variable "//&
1711               &  TRIM(td_var%c_name))
1712
1713            ENDIF
1714
1715            ! read values
1716            CALL logger_debug( &
1717            &  "IOM CDF READ VAR VALUE: get variable "//TRIM(td_var%c_name)//&
1718            &  " in file "//TRIM(td_file%c_name))
1719
1720            il_status = NF90_GET_VAR( td_file%i_id, il_varid,           &
1721            &                                       dl_value(:,:,:,:),  &
1722            &                                       start = il_start(:),&
1723            &                                       count = il_count(:) )
1724            CALL iom_cdf__check(il_status,"IOM CDF READ VAR VALUE: ")
1725
1726            ! Allocate space to hold variable value in structure
1727            IF( ASSOCIATED(td_var%d_value) )THEN
1728               DEALLOCATE(td_var%d_value)   
1729            ENDIF
1730 
1731            ! new dimension length
1732            td_var%t_dim(:)%i_len=il_count_ord(:)
1733
1734!>   dummy patch for pgf95
1735            ALLOCATE( dl_tmp( td_var%t_dim(1)%i_len, &
1736            &                 td_var%t_dim(2)%i_len, &
1737            &                 td_var%t_dim(3)%i_len, &
1738            &                 td_var%t_dim(4)%i_len),&
1739            &        stat=il_status)
1740            IF(il_status /= 0 )THEN
1741
1742               CALL logger_error( &
1743               &  "IOM CDF READ VAR VALUE: not enough space to put variable "//&
1744               &  TRIM(td_var%c_name)//&
1745               &  " in variable structure")
1746            ENDIF
1747            dl_tmp(:,:,:,:)=td_var%d_fill
1748
1749            ! reshape values to be ordered as ('x','y','z','t')
1750            dl_tmp(:,:,:,:)=dim_reshape_2xyzt(td_var%t_dim(:), &
1751            &                                 dl_value(:,:,:,:))
1752
1753            DEALLOCATE(dl_value)
1754
1755            ALLOCATE(td_var%d_value( td_var%t_dim(1)%i_len, &
1756            &                        td_var%t_dim(2)%i_len, &
1757            &                        td_var%t_dim(3)%i_len, &
1758            &                        td_var%t_dim(4)%i_len),&
1759            &        stat=il_status)
1760            IF(il_status /= 0 )THEN
1761
1762               CALL logger_error( &
1763               &  "IOM CDF READ VAR VALUE: not enough space to put variable "//&
1764               &  TRIM(td_var%c_name)//&
1765               &  " in variable structure")
1766
1767            ENDIF
1768!            ! FillValue by default
1769!            td_var%d_value(:,:,:,:)=td_var%d_fill
1770!
1771!            ! reshape values to be ordered as ('x','y','z','t')
1772!            td_var%d_value(:,:,:,:)=dim_reshape_2xyzt(td_var%t_dim(:), &
1773!            &                                         dl_value(:,:,:,:))
1774!
1775!            DEALLOCATE(dl_value)
1776
1777            td_var%d_value(:,:,:,:)=dl_tmp(:,:,:,:)
1778            DEALLOCATE(dl_tmp)
1779!<   dummy patch for pgf95
1780
1781            ! force to change _FillValue to avoid mistake
1782            ! with dummy zero _FillValue
1783            IF( td_var%d_fill == 0._dp )THEN
1784               CALL var_chg_FillValue(td_var)
1785            ENDIF
1786
1787            ! use scale factor and offset
1788            WHERE( td_var%d_value(:,:,:,:) /= td_var%d_fill )
1789               td_var%d_value(:,:,:,:) = &
1790               &  td_var%d_value(:,:,:,:)*td_var%d_scf + td_var%d_ofs
1791            END WHERE
1792
1793         ENDIF
1794      ELSE
1795         CALL logger_error( &
1796         &  "IOM CDF READ VAR VALUE: no variable "//TRIM(td_var%c_name)//&
1797         &  " in file structure "//TRIM(td_file%c_name))
1798      ENDIF
1799
1800   END SUBROUTINE iom_cdf__read_var_value
1801   !-------------------------------------------------------------------
1802   !> @brief This subroutine write file structure in an opened netcdf file.
1803   !>
1804   !> @details
1805   !> optionally, you could specify dimension order (default 'xyzt')
1806   !>
1807   !> @author J.Paul
1808   !> @date November, 2013 - Initial Version
1809   !> @date July, 2015
1810   !> - add dimension order option
1811   !
1812   !> @param[inout] td_file   file structure
1813   !-------------------------------------------------------------------
1814   SUBROUTINE iom_cdf_write_file(td_file, cd_dimorder)
1815      IMPLICIT NONE
1816      ! Argument     
1817      TYPE(TFILE)     , INTENT(INOUT) :: td_file
1818      CHARACTER(LEN=*), INTENT(IN   ), OPTIONAL :: cd_dimorder
1819
1820      ! local variable
1821      INTEGER(i4), DIMENSION(:), ALLOCATABLE :: il_value
1822
1823      CHARACTER(LEN=lc)                      :: cl_dimorder
1824
1825      TYPE(TVAR)                             :: tl_var
1826
1827      TYPE(TDIM), DIMENSION(ip_maxdim)       :: tl_dim
1828
1829      ! loop indices
1830      INTEGER(i4) :: ji
1831      INTEGER(i4) :: jj
1832      INTEGER(i4) :: jvar
1833      !----------------------------------------------------------------
1834
1835      cl_dimorder='xyzt'
1836      IF( PRESENT(cd_dimorder) ) cl_dimorder=TRIM(cd_dimorder)
1837
1838      ! check if file opened
1839      IF( td_file%i_id == 0 )THEN
1840
1841         CALL logger_error( &
1842         &  " IOM CDF WRITE FILE: no id associated to file "//TRIM(td_file%c_name))
1843
1844      ELSE
1845         IF( td_file%l_wrt )THEN
1846
1847            ! remove dummy variable
1848            CALL file_del_var(td_file,'no0d')
1849            CALL file_del_var(td_file,'no1d')
1850            CALL file_del_var(td_file,'no2d')
1851            CALL file_del_var(td_file,'no3d')
1852
1853            DO ji = 1, td_file%i_nvar
1854               CALL var_check_dim( td_file%t_var(ji) )
1855            ENDDO
1856
1857            ! save usefull dimension
1858            IF( ASSOCIATED(td_file%t_var) )THEN
1859               tl_dim(:)=var_max_dim(td_file%t_var(:))
1860
1861               DO ji=1,ip_maxdim
1862                  IF( tl_dim(ji)%l_use ) CALL file_move_dim(td_file, tl_dim(ji))
1863               ENDDO
1864               ! clean
1865               CALL dim_clean(tl_dim(:))
1866            ENDIF
1867
1868            ! change dimension order
1869            IF( TRIM(cl_dimorder) /= 'xyzt' )THEN
1870               CALL dim_reorder(td_file%t_dim(:),TRIM(cl_dimorder))
1871               DO jvar=1,td_file%i_nvar
1872                  CALL logger_debug("VAR REORDER: "//TRIM(td_file%t_var(jvar)%c_name))
1873                  CALL var_reorder(td_file%t_var(jvar),TRIM(cl_dimorder))
1874               ENDDO
1875            ENDIF
1876
1877            ! write dimension in file
1878            DO ji = 1, ip_maxdim
1879               IF( td_file%t_dim(ji)%l_use )THEN
1880                  CALL iom_cdf__write_dim(td_file, td_file%t_dim(ji))
1881
1882                  ! write dimension variable
1883                  ALLOCATE(il_value(td_file%t_dim(ji)%i_len))
1884                  il_value(:)=(/(jj,jj=1,td_file%t_dim(ji)%i_len)/)
1885
1886                  tl_var=var_init( fct_upper(td_file%t_dim(ji)%c_sname), &
1887                  &                il_value(:),                          &
1888                  &                td_dim=td_file%t_dim(ji) )
1889
1890                  DEALLOCATE(il_value)
1891
1892                  ! do not use FillValue for dimension variable
1893                  CALL var_del_att(tl_var, "_FillValue")
1894                   
1895                  CALL iom_cdf__write_var(td_file,tl_var)
1896                  ! clean
1897                  CALL var_clean(tl_var)
1898
1899               ENDIF
1900            ENDDO
1901
1902            ! write global attibute in file
1903            DO ji = 1, td_file%i_natt
1904               CALL iom_cdf__write_att(td_file, NF90_GLOBAL, td_file%t_att(ji))
1905            ENDDO
1906
1907            ! write variable in file
1908            DO ji = 1, td_file%i_nvar
1909               CALL iom_cdf__write_var(td_file, td_file%t_var(ji)) 
1910            ENDDO
1911
1912         ELSE
1913
1914            CALL logger_error( &
1915            &  "IOM CDF WRITE FILE: try to write in file "//TRIM(td_file%c_name)//&
1916            &  ", not opened in write mode")
1917
1918         ENDIF
1919      ENDIF
1920
1921   END SUBROUTINE iom_cdf_write_file
1922   !-------------------------------------------------------------------
1923   !> @brief This subroutine write one dimension in an opened netcdf
1924   !> file in write mode.
1925   !
1926   !> @author J.Paul
1927   !> @date November, 2013 - Initial Version
1928   !
1929   !> @param[inout] td_file   file structure
1930   !> @param[inout] td_dim    dimension structure
1931   !-------------------------------------------------------------------
1932   SUBROUTINE iom_cdf__write_dim(td_file, td_dim)
1933      IMPLICIT NONE
1934      ! Argument     
1935      TYPE(TFILE), INTENT(INOUT) :: td_file
1936      TYPE(TDIM),  INTENT(INOUT) :: td_dim
1937
1938      ! local variable
1939      INTEGER(i4) :: il_status
1940      !----------------------------------------------------------------
1941
1942      IF( .NOT. td_file%l_def )THEN
1943
1944         CALL logger_trace( &
1945         &  " IOM CDF WRITE FILE DIM: Enter define mode, file "//TRIM(td_file%c_name))
1946
1947         ! Enter define mode
1948         il_status=NF90_REDEF(td_file%i_id)
1949         CALL iom_cdf__check(il_status,"IOM CDF WRITE FILE DIM: ")
1950
1951         td_file%l_def=.TRUE.
1952
1953      ENDIF
1954
1955      IF( td_dim%l_use )THEN
1956         IF( td_dim%l_uld )THEN
1957            ! write unlimited dimension
1958            CALL logger_trace( &
1959            &  "IOM CDF WRITE FILE DIM: write unlimited dimension "//&
1960            &  TRIM(td_dim%c_name)//" in file "//TRIM(td_file%c_name))
1961
1962            il_status=NF90_DEF_DIM(td_file%i_id, fct_upper(td_dim%c_sname), &
1963            &                      NF90_UNLIMITED, td_dim%i_id)
1964            CALL iom_cdf__check(il_status,"IOM CDF WRITE FILE DIM: ")
1965
1966         ELSE
1967            ! write not unlimited dimension
1968            CALL logger_debug( &
1969            &  "IOM CDF WRITE FILE DIM: write dimension "//TRIM(td_dim%c_name)//&
1970            &  " in file "//TRIM(td_file%c_name))
1971           
1972            il_status=NF90_DEF_DIM(td_file%i_id, fct_upper(td_dim%c_sname), &
1973            &                      td_dim%i_len, td_dim%i_id)
1974            CALL iom_cdf__check(il_status,"IOM CDF WRITE FILE DIM: ")
1975
1976         ENDIF
1977      ENDIF
1978
1979   END SUBROUTINE iom_cdf__write_dim
1980   !-------------------------------------------------------------------
1981   !> @brief This subroutine write a variable attribute in
1982   !> an opened netcdf file.
1983   !
1984   !> @author J.Paul
1985   !> @date November, 2013 - Initial Version
1986   !
1987   !> @param[inout] td_file   file structure
1988   !> @param[in] id_varid     variable id. use NF90_GLOBAL to write
1989   !> global attribute in a file
1990   !> @param[in] td_att       attribute structure
1991   !-------------------------------------------------------------------
1992   SUBROUTINE iom_cdf__write_att(td_file, id_varid, td_att)
1993      IMPLICIT NONE
1994      ! Argument     
1995      TYPE(TFILE), INTENT(INOUT) :: td_file
1996      INTEGER(i4), INTENT(IN)    :: id_varid
1997      TYPE(TATT),  INTENT(IN)    :: td_att
1998
1999      ! local variable
2000      INTEGER(i4) :: il_status
2001      !----------------------------------------------------------------
2002
2003      IF( .NOT. td_file%l_def )THEN
2004
2005         CALL logger_trace( &
2006         &  "IOM CDF WRITE FILE ATT: Enter define mode, file "//TRIM(td_file%c_name))
2007
2008         ! Enter define mode
2009         il_status=NF90_REDEF(td_file%i_id)
2010         CALL iom_cdf__check(il_status,"IOM CDF WRITE FILE ATT: ")
2011
2012         td_file%l_def=.TRUE.
2013
2014      ENDIF
2015
2016      !! put attribute value
2017      CALL logger_trace( &
2018      &  "IOM CDF WRITE FILE ATT: write attribute "//TRIM(td_att%c_name)//&
2019      &  " of variable "//TRIM(fct_str(id_varid))//&
2020      &  " in file "//TRIM(td_file%c_name))
2021      SELECT CASE( td_att%i_type )
2022
2023         CASE(NF90_CHAR)
2024            ! put the attribute
2025            il_status = NF90_PUT_ATT(td_file%i_id, id_varid, &
2026            &  td_att%c_name, td_att%c_value )
2027            CALL iom_cdf__check(il_status,"IOM CDF WRITE FILE ATT: ")
2028
2029         CASE(NF90_BYTE, NF90_SHORT, NF90_INT, NF90_FLOAT, NF90_DOUBLE)
2030            ! put the attribute
2031            il_status = NF90_PUT_ATT(td_file%i_id, id_varid, &
2032            &  td_att%c_name, td_att%d_value )
2033            CALL iom_cdf__check(il_status,"IOM CDF WRITE FILE ATT: ")
2034
2035      END SELECT
2036
2037   END SUBROUTINE iom_cdf__write_att
2038   !-------------------------------------------------------------------
2039   !> @brief This subroutine write a variable in an opened netcdf file.
2040   !
2041   !> @author J.Paul
2042   !> @date November, 2013 - Initial Version
2043   !> @date September, 2015
2044   !> - do not force to use zero as FillValue for any meshmask variable
2045   !
2046   !> @param[inout] td_file   file structure
2047   !> @param[inout] td_var    variable structure
2048   !-------------------------------------------------------------------
2049   SUBROUTINE iom_cdf__write_var(td_file, td_var)
2050      IMPLICIT NONE
2051      ! Argument     
2052      TYPE(TFILE), INTENT(INOUT) :: td_file
2053      TYPE(TVAR),  INTENT(INOUT) :: td_var
2054
2055      ! local variable
2056      INTEGER(i4) :: il_status
2057      LOGICAL     :: ll_chg
2058      ! loop indices
2059      INTEGER(i4) :: ji
2060      !----------------------------------------------------------------
2061
2062      IF( .NOT. td_file%l_def )THEN
2063
2064         CALL logger_trace( &
2065         &  " IOM CDF WRITE VAR: Enter define mode, file "//&
2066         &  TRIM(td_file%c_name))
2067
2068         ! Enter define mode
2069         il_status=NF90_REDEF(td_file%i_id)
2070         CALL iom_cdf__check(il_status,"IOM CDF WRITE VAR: ")
2071
2072         td_file%l_def=.TRUE.
2073
2074      ENDIF
2075 
2076      ! check if file and variable dimension conform
2077      IF( file_check_var_dim(td_file, td_var) )THEN
2078
2079         ll_chg=.TRUE.
2080         DO ji=1,ip_maxdim
2081            IF( TRIM(fct_lower(cp_dimorder(ji:ji))) == &
2082            &   TRIM(fct_lower(td_var%c_name)) )THEN
2083               ll_chg=.FALSE.
2084               CALL logger_trace(TRIM(fct_lower(td_var%c_name))//' is var dimension')
2085               EXIT
2086            ENDIF
2087         ENDDO
2088         ! ugly patch until NEMO do not force to use 0. as FillValue
2089         IF( ll_chg )THEN
2090            ! not a dimension variable
2091            ! change FillValue
2092            SELECT CASE( TRIM(fct_lower(td_var%c_name)) )
2093               CASE DEFAULT
2094                  CALL var_chg_FillValue(td_var,0._dp)
2095               CASE('nav_lon','nav_lat', &
2096                  & 'glamt','glamu','glamv','glamf', &
2097                  & 'gphit','gphiu','gphiv','gphif', &
2098                  & 'e1t','e1u','e1v','e1f',         &
2099                  & 'e2t','e2u','e2v','e2f','ff',    &
2100                  & 'gcost','gcosu','gcosv','gcosf', &
2101                  & 'gsint','gsinu','gsinv','gsinf', &
2102                  & 'mbathy','misf','isf_draft','isfdraft',     &
2103                  & 'hbatt','hbatu','hbatv','hbatf', &
2104                  & 'gsigt','gsigu','gsigv','gsigf', &
2105                  & 'e3t_0','e3u_0','e3v_0','e3w_0', &
2106                  & 'e3f_0','gdepw_1d','gdept_1d',   &
2107                  & 'e3tp','e3wp','gdepw_0','rx1',   &
2108                  & 'gdept_0','gdepu','gdepv',       &
2109                  & 'hdept','hdepw','e3w_1d','e3t_1d',&
2110                  & 'tmask','umask','vmask','fmask'  )
2111                  ! do not change for coordinates and meshmask variables
2112            END SELECT
2113         ENDIF
2114
2115         ! define variable in file
2116         td_var%i_id=iom_cdf__write_var_def(td_file, td_var) 
2117
2118         IF( td_file%l_def )THEN
2119
2120            CALL logger_trace( &
2121            &  " IOM CDF WRITE VAR: Leave define mode, file "//&
2122            &  TRIM(td_file%c_name))
2123
2124            ! Leave define mode
2125            il_status=NF90_ENDDEF(td_file%i_id)
2126            CALL iom_cdf__check(il_status,"IOM CDF WRITE VAR: ")
2127
2128            td_file%l_def=.FALSE.
2129
2130         ENDIF
2131
2132         IF( ASSOCIATED(td_var%d_value) )THEN
2133            ! write variable value in file
2134            CALL iom_cdf__write_var_value(td_file, td_var)
2135         ENDIF
2136
2137      ENDIF
2138
2139   END SUBROUTINE iom_cdf__write_var
2140   !-------------------------------------------------------------------
2141   !> @brief This function define variable in an opened netcdf file.
2142   !
2143   !> @author J.Paul
2144   !> @date November, 2013 - Initial Version
2145   !
2146   !> @param[in] td_file   file structure
2147   !> @param[in] td_var    variable structure
2148   !> @return  variable id
2149   !-------------------------------------------------------------------
2150   INTEGER(i4) FUNCTION iom_cdf__write_var_def(td_file, td_var)
2151      IMPLICIT NONE
2152      ! Argument     
2153      TYPE(TFILE), INTENT(IN) :: td_file
2154      TYPE(TVAR),  INTENT(IN) :: td_var
2155
2156      ! local variable
2157      INTEGER(i4)                       :: il_status
2158      INTEGER(i4)                       :: il_ind
2159      INTEGER(i4), DIMENSION(ip_maxdim) :: il_dimid
2160
2161      TYPE(TVAR)                        :: tl_var
2162
2163      ! loop indices
2164      INTEGER(i4) :: ji
2165      INTEGER(i4) :: jj
2166      !----------------------------------------------------------------
2167
2168      ! copy structure
2169      tl_var=var_copy(td_var)
2170
2171      ! forced to use float type
2172      IF( tl_var%d_unf /= 1. .AND. tl_var%i_type==NF90_SHORT )THEN
2173         tl_var%i_type=NF90_FLOAT
2174      ENDIF
2175
2176      IF( ALL( .NOT. tl_var%t_dim(:)%l_use ) )THEN
2177         CALL logger_debug( &
2178         &  "IOM CDF WRITE VAR DEF scalar: define variable "//&
2179         &  TRIM(tl_var%c_name)//" in file "//TRIM(td_file%c_name))
2180         ! scalar value
2181         il_status = NF90_DEF_VAR(td_file%i_id, TRIM(tl_var%c_name), &
2182         &                        tl_var%i_type, varid=iom_cdf__write_var_def) 
2183         CALL iom_cdf__check(il_status,"IOM CDF WRITE VAR DEF: ")
2184      ELSE
2185
2186         ! check which dimension use
2187         jj=0
2188         il_dimid(:)=0
2189         ! reorder dimension, so unused dimension won't be written
2190         DO ji = 1,  ip_maxdim
2191            IF( tl_var%t_dim(ji)%l_use )THEN
2192               jj=jj+1
2193               il_dimid(jj)=dim_get_id(td_file%t_dim(:),tl_var%t_dim(ji)%c_name)
2194            ENDIF
2195         ENDDO
2196
2197         CALL logger_debug( &
2198         &  "IOM CDF WRITE VAR DEF: define dimension to be used for variable "//&
2199         &  TRIM(tl_var%c_name)//" in file "//TRIM(td_file%c_name))
2200
2201         DO ji=1,jj
2202            CALL logger_debug("IOM CDF WRITE VAR DEF: dimid "//TRIM(fct_str(il_dimid(ji))) )
2203         ENDDO
2204
2205         il_status = NF90_DEF_VAR(td_file%i_id, TRIM(tl_var%c_name),     &
2206         &                        tl_var%i_type,                         &
2207         &                        il_dimid(1:jj),                        &
2208         &                        varid=iom_cdf__write_var_def           )
2209         CALL iom_cdf__check(il_status,"IOM CDF WRITE VAR DEF: ")
2210      ENDIF
2211      CALL logger_debug("IOM CDF WRITE VAR DEF: type = "//TRIM(fct_str(tl_var%i_type)))
2212
2213      ! remove unuseful attribute
2214      il_ind=att_get_index( tl_var%t_att(:), "ew_overlap" )
2215      IF( il_ind /= 0 )THEN
2216         IF( tl_var%t_att(il_ind)%d_value(1) == -1 )THEN
2217            CALL var_del_att(tl_var, tl_var%t_att(il_ind))
2218         ENDIF
2219      ENDIF
2220
2221      DO ji = 1, tl_var%i_natt
2222         CALL logger_debug( &
2223         &  " IOM CDF WRITE VAR DEF: put attribute "//TRIM(tl_var%t_att(ji)%c_name)//&
2224         &  " for variable "//TRIM(tl_var%c_name)//&
2225         &  " in file "//TRIM(td_file%c_name) )
2226
2227         ! forced FillValue to have same type than variable
2228         IF( TRIM(tl_var%t_att(ji)%c_name) == '_FillValue' )THEN
2229            tl_var%t_att(ji)%i_type=tl_var%i_type
2230         ENDIF
2231
2232         SELECT CASE(tl_var%t_att(ji)%i_type)
2233            CASE(NF90_CHAR)
2234               IF( TRIM(tl_var%t_att(ji)%c_value) /= '' )THEN
2235                  il_status = NF90_PUT_ATT(td_file%i_id, iom_cdf__write_var_def, &
2236                  &                        TRIM(tl_var%t_att(ji)%c_name),        &
2237                  &                        TRIM(tl_var%t_att(ji)%c_value)        )
2238               ENDIF
2239            CASE(NF90_BYTE)
2240               il_status = NF90_PUT_ATT(td_file%i_id,                   &
2241               &                        iom_cdf__write_var_def,         &
2242               &                        TRIM(tl_var%t_att(ji)%c_name),  &
2243               &                        INT(tl_var%t_att(ji)%d_value(:),i1))
2244            CASE(NF90_SHORT)
2245               il_status = NF90_PUT_ATT(td_file%i_id,                   &
2246               &                        iom_cdf__write_var_def,         &
2247               &                        TRIM(tl_var%t_att(ji)%c_name),  &
2248               &                        INT(tl_var%t_att(ji)%d_value(:),i2))
2249            CASE(NF90_INT)
2250               il_status = NF90_PUT_ATT(td_file%i_id,                   &
2251               &                        iom_cdf__write_var_def,         &
2252               &                        TRIM(tl_var%t_att(ji)%c_name),  &
2253               &                        INT(tl_var%t_att(ji)%d_value(:),i4))
2254            CASE(NF90_FLOAT)
2255               il_status = NF90_PUT_ATT(td_file%i_id,                   &
2256               &                        iom_cdf__write_var_def,         &
2257               &                        TRIM(tl_var%t_att(ji)%c_name),  &
2258               &                        REAL(tl_var%t_att(ji)%d_value(:),sp))
2259            CASE(NF90_DOUBLE)
2260               il_status = NF90_PUT_ATT(td_file%i_id,                   &
2261               &                        iom_cdf__write_var_def,         &
2262               &                        TRIM(tl_var%t_att(ji)%c_name),  &
2263               &                        REAL(tl_var%t_att(ji)%d_value(:),dp))
2264         END SELECT
2265         CALL iom_cdf__check(il_status,"IOM CDF WRITE VAR DEF: ")
2266
2267      ENDDO
2268
2269   END FUNCTION iom_cdf__write_var_def
2270   !-------------------------------------------------------------------
2271   !> @brief This subroutine put variable value in an opened netcdf file.
2272   !
2273   !> @details
2274   !> The variable is written in the type define in variable structure.
2275   !> Only dimension used are printed, and fillValue in array are
2276   !> replaced by default fill values defined in module netcdf for each type.
2277   !
2278   !> @author J.Paul
2279   !> @date November, 2013 - Initial Version
2280   !> @date June, 2015
2281   !> - reuse scale factor and offset, before writing variable
2282   !
2283   !> @param[in] td_file   file structure
2284   !> @param[in] td_var    variable structure
2285   !-------------------------------------------------------------------
2286   SUBROUTINE iom_cdf__write_var_value(td_file, td_var)
2287      IMPLICIT NONE
2288      ! Argument     
2289      TYPE(TFILE), INTENT(IN) :: td_file
2290      TYPE(TVAR),  INTENT(IN) :: td_var
2291
2292      ! local variable
2293      INTEGER(i4)                       :: il_status
2294      INTEGER(i4), DIMENSION(ip_maxdim) :: il_order
2295      INTEGER(i4), DIMENSION(ip_maxdim) :: il_shape
2296      REAL(dp),    DIMENSION(:,:,:,:), ALLOCATABLE :: dl_value
2297
2298      ! loop indices
2299      INTEGER(i4) :: ji, jj
2300      !----------------------------------------------------------------
2301
2302      ! check which dimension use
2303      CALL logger_trace( &
2304      &  "IOM CDF WRITE VAR VALUE: get dimension to be used for variable "//&
2305      &  TRIM(td_var%c_name)//" in file "//TRIM(td_file%c_name))
2306   
2307      ! use scale factor and offset
2308      WHERE( td_var%d_value(:,:,:,:) /= td_var%d_fill )
2309         td_var%d_value(:,:,:,:) = &
2310         &  (td_var%d_value(:,:,:,:)-td_var%d_ofs)/td_var%d_scf
2311      END WHERE
2312
2313      jj=0
2314      DO ji = 1, ip_maxdim
2315         IF( td_var%t_dim(ji)%l_use )THEN
2316            jj=jj+1
2317            il_order(jj)=ji
2318            il_shape(jj)=td_var%t_dim(ji)%i_len
2319         ENDIF
2320      ENDDO
2321      ! dimension not use
2322      DO ji = 1, ip_maxdim
2323         IF( .NOT. td_var%t_dim(ji)%l_use )THEN
2324            jj=jj+1
2325            il_order(jj)=ji
2326            il_shape(jj)=td_var%t_dim(ji)%i_len
2327         ENDIF
2328      ENDDO
2329
2330      ALLOCATE( dl_value( il_shape(1),il_shape(2),il_shape(3),il_shape(4) ) )
2331
2332      ! reshape array, so unused dimension won't be written
2333      dl_value(:,:,:,:)=RESHAPE(source=td_var%d_value(:,:,:,:),&
2334      &                         SHAPE = il_shape(:), &
2335      &                         ORDER = il_order(:))
2336
2337      ! put value
2338      CALL logger_debug( &
2339      &  "IOM CDF WRITE VAR VALUE: put "//TRIM(td_var%c_name)//" value "//&
2340      &  "in file "//TRIM(td_file%c_name))
2341
2342      il_status = NF90_PUT_VAR( td_file%i_id, td_var%i_id, dl_value(:,:,:,:))
2343      CALL iom_cdf__check(il_status,"IOM CDF WRITE VAR VALUE ("//&
2344         &  TRIM(td_var%c_name)//") :" )
2345
2346      DEALLOCATE( dl_value )
2347
2348   END SUBROUTINE iom_cdf__write_var_value
2349END MODULE iom_cdf
Note: See TracBrowser for help on using the repository browser.