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) :: long_name,units ! long_name(),units(): [netcdf] "long_name" and "units" attributes character (len=50) :: altlong_name,altunits,altpositive ! altlong_name(): [netcdf] altitude "long_name" attribute ! altunits(): [netcdf] altitude "units" attribute ! altpositive(): [netcdf] altitude "positive" attribute 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: user's answers at multiple questions (especially, answer='y'/'Y') character (len=1) :: average ! average: the character 'y' to average within the Ls timestep integer :: nid,varid,ierr,miss,validr ! 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 real, dimension(:), allocatable:: lat,lon,alt,time,lsgcm,timels,ctl ! 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) ! ctl(): array, stores controle array integer :: latlen,lonlen,altlen,timelen,Nls,Sls,ctllen ! 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,ctldim ! latdim: [netcdf] "latitude" dim ID ! londim: [netcdf] "longitude" dim ID ! altdim: [netcdf] "altdim" dim ID ! timedim: [netcdf] "timedim" dim ID ! ctldim: [netcdf] "controle" dim ID integer :: latvar,lonvar,altvar,timevar,ctlvar ! 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 !============================================================================== ! 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 ! Get the variables' names from the input file (and store them in var()) write(*,*) "" nbvar=nbvarfile-(start_var-1) allocate(var(nbvar)) 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=infile(1:len_trim(infile)-3)//"_Ls.nc" write(*,*) "" write(*,*) "Output file : "//trim(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) ! Get altitude attributes to handle files with any altitude type ierr=nf_get_att_text(nid,altvar,'long_name',altlong_name) ierr=nf_get_att_text(nid,altvar,'units',altunits) ierr=nf_get_att_text(nid,altvar,'positive',altpositive) 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 ierr=NF_INQ_DIMID(nid,"index",ctldim) if (ierr.NE.NF_NOERR) then write(*,*) ' Dimension is missing in file '//trim(infile) ctllen=0 !stop endif ierr=NF_INQ_VARID(nid,"controle",ctlvar) if (ierr.NE.NF_NOERR) then write(*,*) 'Field is missing in file '//trim(infile) ctllen=0 !stop else ierr=NF_INQ_DIMLEN(nid,ctldim,ctllen) endif allocate(ctl(ctllen),stat=ierr) if (ierr.ne.0) then write(*,*) "Error: failed to allocate ctl(ctllen)" stop endif if (ctllen .ne. 0) then ierr = NF_GET_VAR_REAL(nid,ctlvar,ctl) if (ierr.ne.0) then write(*,*) "Error: failed to load controle" write(*,*) NF_STRERROR(ierr) stop endif endif ! of if (ctllen .ne. 0) !============================================================================== ! 2.2. Create (and initialize) latitude, longitude and altitude in output file !============================================================================== ! Initialize output file's lat,lon,alt and time dimensions call initiate(outfile,lat,lon,alt,ctl,latlen,lonlen,altlen,ctllen,& altlong_name,altunits,altpositive,& nout,latdimout,londimout,altdimout,timedimout,timevarout) ! Initialize output file's aps,bps and phisinit variables call init2(nid,lonlen,latlen,altlen,altdim,& nout,londimout,latdimout,altdimout) write(*,*)"" !============================================================================== ! 2.3. Read time from input file !============================================================================== ierr=NF_INQ_DIMID(nid,"Time",timedim) if (ierr.NE.NF_NOERR) then write(*,*) 'ERROR: Dimension