From 826170bdf54bc6e097855ac91e60982ca7c799ef Mon Sep 17 00:00:00 2001 From: Philippe WAUTELET <philippe.wautelet@aero.obs-mip.fr> Date: Thu, 17 Sep 2015 17:36:38 +0200 Subject: [PATCH] lfi2cdf: new option: '-m or --merge' to merge LFI splitted files --- tools/lfi2cdf/src/lfi2cdf.f90 | 48 +++++++++++++-- tools/lfi2cdf/src/mode_util.f90 | 100 ++++++++++++++++++++++++++++---- tools/lfi2cdf/src/newmain.c | 32 +++++++--- 3 files changed, 154 insertions(+), 26 deletions(-) diff --git a/tools/lfi2cdf/src/lfi2cdf.f90 b/tools/lfi2cdf/src/lfi2cdf.f90 index cd16876f0..bd1342db7 100644 --- a/tools/lfi2cdf/src/lfi2cdf.f90 +++ b/tools/lfi2cdf/src/lfi2cdf.f90 @@ -1,18 +1,29 @@ -subroutine LFI2CDFMAIN(hinfile,iiflen,houtfile,ioflen,hvarlist,ivlen,olfi2cdf,olfilist,ohdf5) +subroutine LFI2CDFMAIN(hinfile,iiflen,ooutname,houtfile,ioflen,hvarlist,ivlen,olfi2cdf,olfilist,ohdf5,omerge,nb_levels) USE mode_util IMPLICIT NONE INTEGER :: iiflen, ioflen, ivlen + INTEGER :: nb_levels !Number of vertical levels to merge (for LFI splitted files) CHARACTER(LEN=iiflen) :: hinfile CHARACTER(LEN=ioflen) :: houtfile CHARACTER(LEN=ivlen) :: hvarlist - LOGICAL :: olfi2cdf, olfilist, ohdf5 + LOGICAL :: ooutname, olfi2cdf, olfilist, ohdf5, omerge INTEGER :: ibuflen INTEGER :: ilu INTEGER :: inaf, ji + INTEGER :: nbvar_lfi ! number of variables available in the LFI file INTEGER :: icdf_id + INTEGER :: first_level, current_level, last_level + INTEGER(KIND=LFI_INT) :: iresp,iverb,inap + CHARACTER(LEN=3) :: suffix + CHARACTER(LEN=iiflen) :: filename TYPE(workfield), DIMENSION(:), POINTER :: tzreclist + !Remove level in the filename if merging LFI splitted files + if (omerge .AND. .NOT.ooutname) then + houtfile=houtfile(1:len(houtfile)-9)//houtfile(len(houtfile)-3:) + end if + CALL OPEN_FILES(hinfile, houtfile, olfi2cdf, olfilist, ohdf5, icdf_id, ilu, inaf) IF (olfilist) return @@ -29,9 +40,36 @@ subroutine LFI2CDFMAIN(hinfile,iiflen,houtfile,ioflen,hvarlist,ivlen,olfi2cdf,o END DO END IF - CALL parse_lfi(ilu,hvarlist,inaf,tzreclist,ibuflen) - CALL def_ncdf(tzreclist,inaf,icdf_id) - CALL fill_ncdf(ilu,icdf_id,tzreclist,inaf,ibuflen) + !Standard treatment (one LFI file only) + IF (.not.omerge) THEN + CALL parse_lfi(ilu,hvarlist,inaf,tzreclist,ibuflen) + CALL def_ncdf(tzreclist,inaf,icdf_id,omerge) + CALL fill_ncdf(ilu,icdf_id,tzreclist,inaf,ibuflen) + ELSE + !Treat several LFI files and merge into 1 NC file + iverb = 0 !Verbosity level for LFI + + !Determine first level (eg needed to find suffix of the variable name) + read( hinfile(len(hinfile)-6:len(hinfile)-4) , "(I3)" ) first_level + current_level = first_level + last_level = first_level + nb_levels - 1 + + !Read 1st LFI file + CALL parse_lfi(ilu,hvarlist,inaf,tzreclist,ibuflen,current_level) + CALL def_ncdf(tzreclist,inaf,icdf_id,omerge) + + DO current_level = first_level,last_level + print *,'Treating level ',current_level + IF (current_level/=first_level) THEN + write(suffix,'(I3.3)') current_level + filename=hinfile(1:len(hinfile)-7)//suffix//'.lfi' + CALL LFIOUV(iresp,ilu,ltrue,filename,'OLD',lfalse,lfalse,iverb,inap,nbvar_lfi) + CALL read_data_lfi(ilu,hvarlist,inaf,tzreclist,ibuflen,current_level) + END IF + CALL fill_ncdf(ilu,icdf_id,tzreclist,inaf,ibuflen,current_level) + IF (current_level/=last_level) CALL LFIFER(iresp,ilu,'KEEP') + END DO + END IF ELSE ! Conversion NetCDF -> LFI diff --git a/tools/lfi2cdf/src/mode_util.f90 b/tools/lfi2cdf/src/mode_util.f90 index b5780e832..5deedbc85 100644 --- a/tools/lfi2cdf/src/mode_util.f90 +++ b/tools/lfi2cdf/src/mode_util.f90 @@ -65,12 +65,13 @@ CONTAINS END IF END SUBROUTINE FMREADLFIN1 - SUBROUTINE parse_lfi(klu, hvarlist, knaf, tpreclist, kbuflen) + SUBROUTINE parse_lfi(klu, hvarlist, knaf, tpreclist, kbuflen, current_level) INTEGER, INTENT(IN) :: klu INTEGER, INTENT(INOUT) :: knaf CHARACTER(LEN=*), intent(IN) :: hvarlist TYPE(workfield), DIMENSION(:), POINTER :: tpreclist INTEGER, INTENT(OUT) :: kbuflen + INTEGER, INTENT(IN), OPTIONAL :: current_level INTEGER :: ji,jj INTEGER :: ndb, nde @@ -79,6 +80,7 @@ CONTAINS INTEGER :: ich INTEGER :: fsize,sizemax CHARACTER(LEN=FM_FIELD_SIZE) :: yrecfm + CHARACTER(LEN=4) :: suffix #ifdef LOWMEM INTEGER(KIND=8),DIMENSION(:),ALLOCATABLE :: iwork #endif @@ -116,6 +118,12 @@ CONTAINS ALLOCATE(tpreclist(knaf)) sizemax = 0 + IF (present(current_level)) THEN + write(suffix,'(I4.4)') current_level + ElSE + suffix='' + END IF + ! Phase 1 : build articles list to convert. ! ! Pour l'instant tous les articles du fichier LFI sont @@ -132,7 +140,7 @@ CONTAINS yrecfm = hvarlist(ndb:ndb+nde-2) ndb = nde+ndb - CALL LFINFO(iresp,ilu,yrecfm,ileng,ipos) + CALL LFINFO(iresp,ilu,trim(yrecfm)//trim(suffix),ileng,ipos) IF (iresp /= 0 .OR. ileng == 0) THEN PRINT *,'Article ',TRIM(yrecfm), ' not found!' @@ -173,7 +181,7 @@ CONTAINS ! Infos are put in tpreclist. CALL init_dimCDF() DO ji=1,inaf - yrecfm = tpreclist(ji)%name + yrecfm = trim(tpreclist(ji)%name)//trim(suffix) CALL LFINFO(iresp,ilu,yrecfm,ileng,ipos) #ifdef LOWMEM CALL LFILEC(iresp,ilu,yrecfm,iwork,ileng) @@ -208,6 +216,55 @@ CONTAINS knaf = inaf END SUBROUTINE parse_lfi + SUBROUTINE read_data_lfi(klu, hvarlist, nbvar, tpreclist, kbuflen, current_level) + INTEGER, INTENT(IN) :: klu + INTEGER, INTENT(INOUT) :: nbvar + CHARACTER(LEN=*), intent(IN) :: hvarlist + TYPE(workfield), DIMENSION(:), POINTER :: tpreclist + INTEGER, INTENT(IN) :: kbuflen + INTEGER, INTENT(IN), OPTIONAL :: current_level + + INTEGER :: ji,jj + INTEGER :: ndb, nde + LOGICAL :: ladvan + INTEGER :: ich + INTEGER :: fsize,sizemax + CHARACTER(LEN=FM_FIELD_SIZE) :: yrecfm + CHARACTER(LEN=4) :: suffix +#ifdef LOWMEM + INTEGER(KIND=8),DIMENSION(:),ALLOCATABLE :: iwork +#endif + INTEGER(KIND=LFI_INT) :: iresp,ilu,ileng,ipos + + ilu = klu + + IF (present(current_level)) THEN + write(suffix,'(I4.4)') current_level + ElSE + suffix='' + END IF + +#ifdef LOWMEM + ALLOCATE(iwork(kbuflen)) +#endif + + DO ji=1,nbvar + yrecfm = trim(tpreclist(ji)%name)//trim(suffix) + CALL LFINFO(iresp,ilu,yrecfm,ileng,ipos) +#ifdef LOWMEM + CALL LFILEC(iresp,ilu,yrecfm,iwork,ileng) + tpreclist(ji)%grid = iwork(1) +#else + CALL LFILEC(iresp,ilu,yrecfm,lfiart(ji)%iwtab,ileng) + tpreclist(ji)%grid = lfiart(ji)%iwtab(1) +#endif + END DO + +#ifdef LOWMEM + DEALLOCATE(iwork) +#endif + END SUBROUTINE read_data_lfi + SUBROUTINE HANDLE_ERR(status,line) INTEGER :: status,line @@ -217,10 +274,11 @@ CONTAINS END IF END SUBROUTINE HANDLE_ERR - SUBROUTINE def_ncdf(tpreclist,knaf,kcdf_id) + SUBROUTINE def_ncdf(tpreclist,knaf,kcdf_id,omerge) TYPE(workfield),DIMENSION(:),INTENT(INOUT) :: tpreclist INTEGER, INTENT(IN) :: knaf INTEGER, INTENT(OUT):: kcdf_id + LOGICAL, INTENT(IN) :: omerge INTEGER :: status INTEGER :: ji @@ -255,6 +313,7 @@ CONTAINS ivdims(1) = tpreclist(ji)%dim%id ELSE invdims = tpreclist(ji)%dim%ndims + IF(omerge) invdims=invdims+1 !when merging variables from LFI splitted files SELECT CASE(invdims) CASE(2) ivdims(1)=ptdimx%id @@ -332,26 +391,40 @@ CONTAINS END SUBROUTINE def_ncdf - SUBROUTINE fill_ncdf(klu,kcdf_id,tpreclist,knaf,kbuflen) + SUBROUTINE fill_ncdf(klu,kcdf_id,tpreclist,knaf,kbuflen,current_level) INTEGER, INTENT(IN):: klu INTEGER, INTENT(IN):: kcdf_id TYPE(workfield), DIMENSION(:),INTENT(IN):: tpreclist INTEGER, INTENT(IN):: knaf INTEGER, INTENT(IN):: kbuflen + INTEGER, INTENT(IN), OPTIONAL :: current_level + #ifdef LOWMEM INTEGER(KIND=8),DIMENSION(:),ALLOCATABLE :: iwork #endif INTEGER :: ji,jj - INTEGER,DIMENSION(:),ALLOCATABLE :: itab + INTEGER,DIMENSION(:),ALLOCATABLE :: itab REAL (KIND=8),DIMENSION(:),ALLOCATABLE :: xtab CHARACTER, DIMENSION(:), ALLOCATABLE :: ytab INTEGER :: status INTEGER :: extent, ndims INTEGER :: ich - INTEGER(KIND=LFI_INT) :: iresp,ilu,ileng,ipos + INTEGER :: level + INTEGER(KIND=LFI_INT) :: iresp,ilu,ileng,ipos + CHARACTER(LEN=4) :: suffix + ! ilu = klu ! + + IF (present(current_level)) THEN + write(suffix,'(I4.4)') current_level + level = current_level + ElSE + suffix='' + level = 1 + END IF + #if LOWMEM ALLOCATE(iwork(kbuflen)) #endif @@ -360,8 +433,8 @@ CONTAINS DO ji=1,knaf #if LOWMEM - CALL LFINFO(iresp,ilu,tpreclist(ji)%name,ileng,ipos) - CALL LFILEC(iresp,ilu,tpreclist(ji)%name,iwork,ileng) + CALL LFINFO(iresp,ilu,trim(tpreclist(ji)%name)//trim(suffix),ileng,ipos) + CALL LFILEC(iresp,ilu,trim(tpreclist(ji)%name)//trim(suffix),iwork,ileng) #endif IF (ASSOCIATED(tpreclist(ji)%dim)) THEN extent = tpreclist(ji)%dim%len @@ -387,7 +460,8 @@ print *,'lowmem: not tested!!!!!' (to be compared with no low mem version) CASE (1) status = NF90_PUT_VAR(kcdf_id,tpreclist(ji)%id,itab(1:extent),count=(/extent/)) CASE (2) - status = NF90_PUT_VAR(kcdf_id,tpreclist(ji)%id,reshape(itab,(/ptdimx%len,ptdimy%len/))) + status = NF90_PUT_VAR(kcdf_id,tpreclist(ji)%id,reshape(itab,(/ptdimx%len,ptdimy%len/)), & + start = (/1,1,level/) ) CASE (3) status = NF90_PUT_VAR(kcdf_id,tpreclist(ji)%id,reshape(itab,(/ptdimx%len,ptdimy%len,ptdimz%len/))) CASE DEFAULT @@ -409,7 +483,8 @@ print *,'lowmem: not tested!!!!!' (to be compared with no low mem version) CASE (1) status = NF90_PUT_VAR(kcdf_id,tpreclist(ji)%id,xtab(1:extent),count=(/extent/)) CASE (2) - status = NF90_PUT_VAR(kcdf_id,tpreclist(ji)%id,reshape(xtab,(/ptdimx%len,ptdimy%len/))) + status = NF90_PUT_VAR(kcdf_id,tpreclist(ji)%id,reshape(xtab,(/ptdimx%len,ptdimy%len/)), & + start = (/1,1,level/) ) CASE (3) status = NF90_PUT_VAR(kcdf_id,tpreclist(ji)%id,reshape(xtab,(/ptdimx%len,ptdimy%len,ptdimz%len/))) CASE DEFAULT @@ -446,7 +521,8 @@ print *,'lowmem: not tested!!!!!' (to be compared with no low mem version) CASE (1) status = NF90_PUT_VAR(kcdf_id,tpreclist(ji)%id,xtab(1:extent),count=(/extent/)) CASE (2) - status = NF90_PUT_VAR(kcdf_id,tpreclist(ji)%id,reshape(xtab,(/ptdimx%len,ptdimy%len/))) + status = NF90_PUT_VAR(kcdf_id,tpreclist(ji)%id,reshape(xtab,(/ptdimx%len,ptdimy%len/)), & + start = (/1,1,level/) ) CASE (3) status = NF90_PUT_VAR(kcdf_id,tpreclist(ji)%id,reshape(xtab,(/ptdimx%len,ptdimy%len,ptdimz%len/))) CASE DEFAULT diff --git a/tools/lfi2cdf/src/newmain.c b/tools/lfi2cdf/src/newmain.c index 05b93adc4..8b6b9b9d2 100644 --- a/tools/lfi2cdf/src/newmain.c +++ b/tools/lfi2cdf/src/newmain.c @@ -5,7 +5,7 @@ #define BUFSIZE 4096 -extern lfi2cdfmain_(char*, int*, char*, int*, char*, int*, int*, int*, int*); +extern lfi2cdfmain_(char*, int*, int *, char*, int*, char*, int*, int*, int*, int*, int*, int*); char *cleancomma(char *varlist) { @@ -30,6 +30,8 @@ int main(int argc, char **argv) int list_flag; int l2c_flag; int hdf5_flag; + int merge_flag, nb_levels; + int outname_flag; char *cmd, *infile; int c; char buff[BUFSIZE]; @@ -52,17 +54,23 @@ int main(int argc, char **argv) p = buff; *p = '\0'; + /* Default values for merging of LFI splitted files */ + merge_flag = 0; + nb_levels = 1; + while (1) { int option_index = 0; static struct option long_options[] = { - {"cdf4", no_argument, 0, '4'}, - {"list", no_argument, 0, 'l' }, - {"var", required_argument, 0, 'v' }, - {0, 0, 0, 0 } + {"cdf4", no_argument, 0, '4' }, + {"list", no_argument, 0, 'l' }, + {"merge", required_argument, 0, 'm' }, + {"output", required_argument, 0, 'o' }, + {"var", required_argument, 0, 'v' }, + {0, 0, 0, 0 } }; - c = getopt_long(argc, argv, "lo:v:4", + c = getopt_long(argc, argv, "4lm:o:v:", long_options, &option_index); if (c == -1) break; @@ -80,7 +88,12 @@ int main(int argc, char **argv) case 'l': list_flag = 1; break; + case 'm': + merge_flag = 1; + nb_levels = atoi(optarg); + break; case 'o': + outname_flag = 1; outfile = optarg; olen = strlen(outfile); break; @@ -105,8 +118,8 @@ int main(int argc, char **argv) } if (optind == argc) { - printf("usage : lfi2cdf [--cdf4 -4] [-l] [-v var1[,...]] [-o output-file.nc] input-file.lfi\n"); - printf(" cdf2lfi [-o output-file.lfi] input-file.nc\n"); + printf("usage : lfi2cdf [--cdf4 -4] [-l] [-v --var var1[,...]] [-m --merge number_of_z_levels] [-o --output output-file.nc] input-file.lfi\n"); + printf(" cdf2lfi [-o --output output-file.lfi] input-file.nc\n"); exit(EXIT_FAILURE); } @@ -142,7 +155,8 @@ int main(int argc, char **argv) infile, ilen, outfile, olen, varlist, varlistlen); */ - lfi2cdfmain_(infile, &ilen, outfile, &olen, varlist, &varlistlen, &l2c_flag, &list_flag, &hdf5_flag); + lfi2cdfmain_(infile, &ilen, &outname_flag, outfile, &olen, varlist, &varlistlen, &l2c_flag, &list_flag, &hdf5_flag, &merge_flag, + &nb_levels); exit(EXIT_SUCCESS); } -- GitLab