program lslin ! Program to interpolate data in Solar Longitude linear time coordinate ! (usable with grads) from Netcdf diagfi or concatnc files ! author Y. Wanherdrick, K. Dassas 2004 ! Modified by F.Forget 04/2005 ! More modifications by Ehouarn Millour 12/2005 ! Modified by Ehouarn Millour 10/2007 (changed evaluation of 'start_var' ! from hard-coded values to a computed value) ! Read controle field, if available TN, October 2013 ! Allow to chose a starting Ls and to average within Ls timestep a ! (great to compare with TES and MCS data. F. Forget december 2013) implicit none include "netcdf.inc" ! NetCDF definitions character (len=50) :: infile ! infile(): input file name character (len=50), dimension(:), allocatable :: var ! var(): names of the variables character (len=50) :: title,units ! title(),units(): [netcdf] "title" and "units" attributes character (len=50) :: units_alt ! var(): units of altitude which can be 'km' or 'Pa' (after zrecast) character (len=100) :: outfile ! outfile(): output file name character (len=100) :: vartmp ! vartmp(): used for temporary storage of various strings character (len=1) :: answer ! answer: the character 'y' (or 'Y'), if input file is of 'concatnc' type character (len=1) :: average ! average: the character 'y' to average within the Ls timestep integer :: nid,varid,ierr,miss ! nid: [netcdf] ID # of input file ! varid: [netcdf] ID # of a variable ! ierr: [netcdf] error code (returned by subroutines) integer :: nout,varidout ! nout: [netcdf] ID # of output file ! varidout: [netcdf] ID # of a variable (to write in the output file) integer :: i,j,k,l,x,y,n ! counters for various loops integer :: start_var ! starting index/ID # from which physical variables are to be found integer :: reptime ! Ehouarn: integer or real ? ! rep_time: starting date/time of the run (given by user) integer :: day_ini ! Ehouarn: integer or real ? ! day_ini: starting date/time of the run stored in input file integer, parameter :: length=100 ! length: (default) lenght of tab_cntrl() real, dimension(length) :: tab_cntrl ! tab_cntrl(length): array, stored in the input file, ! which contains various control parameters. real, dimension(:), allocatable:: lat,lon,alt,time,lsgcm,timels ! lat(): latitude coordinates (read from input file) ! lon(): longitude coordinates (read from input file) ! alt(): altitude coordinates (read from input file) ! time(): time coordinates (in "sol", read from input file) ! lsgcm(): time coordinate (in unevenly spaced "Ls") ! timels(): new time coordinates (evenly spaced "Ls"; written to output file) integer :: latlen,lonlen,altlen,timelen,Nls,Sls ! latlen: # of elements of lat() array ! lonlen: # of elements of lon() array ! altvar: # of elements of alt() array ! timelen: # of elements of time() and lsgcm() arrays ! Nls: # of elements of timels() array integer :: nbvarfile,nbvar,ndim !,nbfile ! nbvar: # of time-dependent variables ! nbvarfile: total # of variables (in netcdf file) ! ndim: [netcdf] # of dimensions (3 or 4) of a variable integer :: latdim,londim,altdim,timedim ! latdim: [netcdf] "latitude" dim ID ! londim: [netcdf] "longitude" dim ID ! altdim: [netcdf] "altdim" dim ID ! timedim: [netcdf] "timedim" dim ID integer :: latvar,lonvar,altvar,timevar ! latvar: [netcdf] ID of "latitude" variable ! lonvar: [netcdf] ID of "longitude" variable ! altvar: [netcdf] ID of "altitude" variable ! timevar: [netcdf] ID of "Time" variable integer :: latdimout,londimout,altdimout,timedimout,timevarout ! latdimout: [netcdf] output latitude (dimension) ID ! londimout: [netcdf] output longitude (dimension) ID ! altdimout: [netcdf] output altitude (dimension) ID ! timedimout: [netcdf] output time (dimension) ID ! timevarout: [netcdf] ID of output "Time" variable integer, dimension(4) :: corner,edges,dim ! corner(4): [netcdf] start indexes (where block of data will be written) ! edges(4): [netcdf] lenght (along dimensions) of block of data to write ! dim(4): [netcdf] lat, long, alt and time dimensions real, dimension(:,:,:,:), allocatable :: var3d,var3dls ! var3d(,,,): 4D array to store a variable (on initial lat/lon/alt/sol grid) ! var3dls(,,,): 4D array to store a variable (on new lat/lon/alt/Ls grid) real, dimension(:), allocatable :: var3dxy ! var3dxy(): to store the temporal evolution of a variable (at fixed lat/lon/alt) real :: deltatsol,deltals,resultat,ls0 ! deltatsol: time step (in sols) of input file data ! deltals: time step (in Ls) for the data sent to output ! ls0: first Ls value for the data sent to output ! resultat: to temporarily store the result of the interpolation character (len=3) :: mon ! mon(3): to store (and write to file) the 3 first letters of a month real :: date ! date: used to compute/build a fake date (for grads output) real :: missing ! to handle missing value when reading /writing files real, dimension(2) :: valid_range ! valid range !============================================================================== ! 1. Initialisation step !============================================================================== !============================================================================== ! 1.1. Get input file name and 'type' (to initialize start_var and reptime) !============================================================================== write(*,*) "which file do you want to use?" read(*,'(a50)') infile !write(*,*) "Is it a concatnc file? (y/n)?" write(*,*) "Do you want to specify the beginning day of the file" write(*,*) "in case the controle field is not present ? (y/n)?" read(*,*) answer if ((answer=="y").or.(answer=="Y")) then write(*,*) "Beginning day of the file?" read(*,*) reptime ! start_var=8 ! 'concatnc' type of file !else ! start_var=16 ! 'diagfi' type of file ! N.B.: start_var is now computed; see below endif !============================================================================== ! 1.2. Open input file and read/list the variables it contains !============================================================================== write(*,*) "opening "//trim(infile)//"..." ierr = NF_OPEN(infile,NF_NOWRITE,nid) if (ierr.NE.NF_NOERR) then write(*,*) 'Failed to open file '//infile write(*,*) NF_STRERROR(ierr) stop "" endif ! Compute 'start_var', the index from which variables are lon-lat-time ! and/or lon-lat-alt-time ! WARNING: We assume here that the ordering of variables in the NetCDF ! file is such that 0D, 1D and 2D variables are placed BEFORE 3D and 4D ! variables i=1 ! dummy initialization to enter loop below start_var=0 ! initialization do while (i.lt.3) start_var=start_var+1 ! request number of dims of variable number 'start_var' ierr=NF_INQ_VARNDIMS(nid,start_var,i) if (ierr.ne.NF_NOERR) then write(*,*) "Failed to get number of dims for variable number:",start_var write(*,*) NF_STRERROR(ierr) stop "" endif enddo write(*,*) "start_var=",start_var ierr=NF_INQ_NVARS(nid,nbvarfile) ! nbvarfile is now equal to the (total) number of variables in input file allocate(var(nbvarfile-(start_var-1))) ! Yield the list of variables (to the screen) write(*,*) do i=start_var,nbvarfile ierr=NF_INQ_VARNAME(nid,i,vartmp) write(*,*) trim(vartmp) enddo !nbvar=0 ! Ehouarn: Redundant (and obsolete) lines ? ! nbvar=nbvarfile-(start_var-1) ! do j=start_var,nbvarfile ! ierr=nf_inq_varname(nid,j,var(j-(start_var-1))) ! enddo ! Get the variables' names from the input file (and store them in var()) nbvar=nbvarfile-(start_var-1) do i=1,nbvar ierr=NF_INQ_VARNAME(nid,i+(start_var-1),var(i)) write(*,'(a9,1x,i2,1x,a1,1x,a50)') "variable ",i,":",var(i) enddo !============================================================================== ! 1.3. Output file name !============================================================================== ! outfile="lslin.nc" outfile=infile(1:len_trim(infile)-3)//"_Ls.nc" write(*,*) outfile !============================================================================== ! 2. Work: read input, build new time coordinate and write it to output !============================================================================== !============================================================================== ! 2.1. Read (and check) latitude, longitude and altitude from input file !============================================================================== ierr=NF_INQ_DIMID(nid,"latitude",latdim) ierr=NF_INQ_VARID(nid,"latitude",latvar) if (ierr.NE.NF_NOERR) then write(*,*) 'ERROR: Field is missing' write(*,*) NF_STRERROR(ierr) stop "" endif ierr=NF_INQ_DIMLEN(nid,latdim,latlen) ! write(*,*) "latlen: ",latlen ierr=NF_INQ_DIMID(nid,"longitude",londim) ierr=NF_INQ_VARID(nid,"longitude",lonvar) if (ierr.NE.NF_NOERR) then write(*,*) 'ERROR: Field is missing' write(*,*) NF_STRERROR(ierr) stop "" endif ierr=NF_INQ_DIMLEN(nid,londim,lonlen) ! write(*,*) "lonlen: ",lonlen ierr=NF_INQ_DIMID(nid,"altitude",altdim) ierr=NF_INQ_VARID(nid,"altitude",altvar) if (ierr.NE.NF_NOERR) then write(*,*) 'ERROR: Field is missing' write(*,*) NF_STRERROR(ierr) ! stop "" altlen = 1 else ierr=NF_INQ_DIMLEN(nid,altdim,altlen) units_alt=" " ierr=NF_GET_ATT_TEXT(nid,varid,"units",units_alt) endif write(*,*) "altlen: ",altlen ! Allocate lat(), lon() and alt() allocate(lat(latlen)) allocate(lon(lonlen)) allocate(alt(altlen)) ! Read lat(),lon() and alt() from input file ierr = NF_GET_VAR_REAL(nid,latvar,lat) ierr = NF_GET_VAR_REAL(nid,lonvar,lon) ierr = NF_GET_VAR_REAL(nid,altvar,alt) if (ierr.NE.NF_NOERR) then if (altlen.eq.1) alt(1)=0. end if !============================================================================== ! 2.2. Create (and initialize latitude, longitude and altitude in) output file !============================================================================== call initiate(outfile,lat,lon,alt,nout,& latdimout,londimout,altdimout,timedimout,timevarout,units_alt) !============================================================================== ! 2.3. Read time from input file !============================================================================== ierr=NF_INQ_DIMID(nid,"Time",timedim) if (ierr.NE.NF_NOERR) then write(*,*) 'ERROR: Dimension