Ignore:
Timestamp:
Apr 7, 2015, 11:55:58 AM (10 years ago)
Author:
emillour
Message:

Mars GCM:
Update of lslin utility: Added possibility to bin data (instead of interpolating) over the time intervals.
FF

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/LMDZ.MARS/util/lslin.F90

    r1073 r1409  
    1111! from hard-coded values to a computed value)
    1212! Read controle field, if available TN, October 2013
     13! Allow to chose a starting Ls and to average within Ls timestep a
     14! (great to compare with TES and MCS data. F. Forget december 2013)
    1315
    1416
     
    2325character (len=50) :: title,units
    2426! title(),units(): [netcdf] "title" and "units" attributes
     27character (len=50) :: units_alt
     28! var(): units of altitude which can be 'km' or 'Pa' (after zrecast)
    2529character (len=100) :: outfile
    2630! outfile(): output file name
     
    2933character (len=1) :: answer
    3034! answer: the character 'y' (or 'Y'), if input file is of 'concatnc' type
    31 integer :: nid,varid,ierr
     35character (len=1) :: average
     36! average: the character 'y' to average within the Ls timestep
     37integer :: nid,varid,ierr,miss
    3238! nid: [netcdf] ID # of input file
    3339! varid: [netcdf] ID # of a variable
     
    3642! nout: [netcdf] ID # of output file
    3743! varidout: [netcdf] ID # of a variable (to write in the output file)
    38 integer :: i,j,k,l,x,y
     44integer :: i,j,k,l,x,y,n
    3945! counters for various loops
    4046integer :: start_var
     
    5662! lsgcm(): time coordinate (in unevenly spaced "Ls")
    5763! timels(): new time coordinates (evenly spaced "Ls"; written to output file)
    58 integer :: latlen,lonlen,altlen,timelen,Nls
     64integer :: latlen,lonlen,altlen,timelen,Nls,Sls
    5965! latlen: # of elements of lat() array
    6066! lonlen: # of elements of lon() array
     
    9197real, dimension(:), allocatable :: var3dxy
    9298! var3dxy(): to store the temporal evolution of a variable (at fixed lat/lon/alt)
    93 real :: deltatsol,deltals,resultat
     99real :: deltatsol,deltals,resultat,ls0
    94100! deltatsol: time step (in sols) of input file data
    95101! deltals: time step (in Ls) for the data sent to output
     102! ls0: first Ls value for the data sent to output
    96103! resultat: to temporarily store the result of the interpolation
    97104character (len=3) :: mon
     
    99106real :: date
    100107! date: used to compute/build a fake date (for grads output)
     108real :: missing
     109! to handle missing value when reading /writing files
     110real, dimension(2) :: valid_range
     111! valid range
    101112
    102113!==============================================================================
     
    229240   else
    230241      ierr=NF_INQ_DIMLEN(nid,altdim,altlen)
     242      units_alt="                                                    "
     243      ierr=NF_GET_ATT_TEXT(nid,varid,"units",units_alt)
    231244   endif
    232245   write(*,*) "altlen: ",altlen
     
    256269
    257270call initiate(outfile,lat,lon,alt,nout,&
    258            latdimout,londimout,altdimout,timedimout,timevarout)
     271           latdimout,londimout,altdimout,timedimout,timevarout,units_alt)
    259272
    260273!==============================================================================
     
    334347do i=1,timelen
    335348   call sol2ls(day_ini+time(i),lsgcm(i))
     349  if (lsgcm(i).lt.lsgcm(1)) lsgcm(i)=lsgcm(i) + 360.
    336350enddo
    337351
     
    356370    if (0.6*deltatsol.ge.3) deltals=3.
    357371    if (0.6*deltatsol.ge.5) deltals=5.
     372    ls0=lsgcm(1) ! First Ls date
    358373else
    359374    write(*,*) "New timestep in Ls (deg)"
    360375    read(*,*) deltals
    361 endif
    362   NLs=int(Int((lsgcm(timelen)-lsgcm(1))/deltals) +1)
     376    write(*,*) "First Ls (deg)"
     377    read(*,*) ls0
     378    if (ls0.lt.lsgcm(1)) then
     379       write(*,*) 'with this file, the earliest Ls is ',lsgcm(1),'let s use it'
     380       ls0=lsgcm(1)
     381    end if
     382    write(*,*) "First Ls date (deg) = ", ls0  ! FF2013
     383
     384    do while((average.ne.'y').and.(average.ne.'n'))
     385       write(*,*) "Average data within the Ls timestep (y/n) or interpolate ? "
     386       read(*,*) average
     387    end do
     388endif
     389  NLs=int(Int((lsgcm(timelen)-ls0)/deltals) +1)   ! FF2013
    363390!********************************************
    364391allocate(timels(Nls))
    365392
    366393! Build timels()
    367 timels(1) = 0.01*nint(100.*lsgcm(1)) ! Ehouarn: what the !!!???!!!
     394timels(1) = 0.01*nint(100.*ls0) ! Ehouarn: what the !!!???!!!
    368395do k=2,Nls
    369396   timels(k) = timels(k-1) + deltals
     
    470497
    471498   ierr = NF_GET_VAR_REAL(nid,varid,var3d)
    472 
    473 
    474 !==============================================================================
    475 ! 3.5 Interpolate
     499   miss = NF_GET_ATT_REAL(nid,varid,"missing_value",missing)
     500   miss = NF_GET_ATT_REAL(nid,varid,"valid_range",valid_range)
     501
     502
     503!==============================================================================
     504! 3.6 interpolate or average
    476505!==============================================================================
    477506
     
    483512!        write(*,*) 'd: x, y', x, y
    484513        do l=1,timelen
    485         var3dxy(l)=var3d(x,y,l,1)
     514          var3dxy(l)=var3d(x,y,l,1)
    486515        enddo
    487         do l=1,Nls
    488         call interpolf(timels(l),resultat,lsgcm,var3dxy,timelen)
    489         var3dls(x,y,l,1)=resultat
     516        do n=1,Nls
     517          if(average.eq.'y') then
     518            resultat=0.
     519            Sls=0 ! (gcm data counter within each Ls timestep)
     520            do l=1,timelen
     521               if((lsgcm(l).ge.(timels(n)-deltals/2.)).and.   &
     522               (lsgcm(l).lt.(timels(n)+deltals/2.))) then
     523                  if(var3dxy(l) .ne. missing) then
     524                    Sls= Sls +1
     525                    resultat = resultat + var3dxy(l)
     526                  end if
     527               end if
     528               if (Sls.ne.0) then
     529                  var3dls(x,y,n,1)=resultat/float(Sls)
     530               else
     531                  var3dls(x,y,n,1)=missing
     532               endif
     533            enddo
     534          else   ! average = n
     535            call interpolf(timels(n),resultat,lsgcm,var3dxy,timelen)
     536            var3dls(x,y,n,1)=resultat
     537          endif
    490538        enddo
    491539       enddo
     
    500548        var3dxy(l)=var3d(x,y,k,l)
    501549        enddo
    502          do l=1,Nls
    503         call interpolf(timels(l),resultat,lsgcm,var3dxy,timelen)
    504         var3dls(x,y,k,l)=resultat
     550        do n=1,Nls
     551          if(average.eq.'y') then
     552            resultat=0.
     553            Sls=0 ! (gcm data counter within each Ls timestep)
     554            do l=1,timelen
     555               if((lsgcm(l).ge.(timels(n)-deltals/2.)).and.   &
     556               (lsgcm(l).lt.(timels(n)+deltals/2.))) then
     557                  if(var3dxy(l) .ne. missing) then
     558                    Sls= Sls +1
     559                    resultat = resultat + var3dxy(l)
     560                  end if
     561               end if
     562               if (Sls.ne.0) then
     563                  var3dls(x,y,k,n)=resultat/float(Sls)
     564               else
     565                  var3dls(x,y,k,n)=missing
     566               endif
     567            enddo
     568          else   ! average = n
     569             call interpolf(timels(n),resultat,lsgcm,var3dxy,timelen)
     570             var3dls(x,y,k,n)=resultat
     571          end if
    505572         enddo
    506573        enddo
     
    510577
    511578!==============================================================================
    512 ! 3.4 Write variable to output file
     579! 3.7 Write variable to output file
    513580!==============================================================================
    514581
     
    523590      stop ""
    524591   endif
     592
     593! In case there is a "missing value" attribute and "valid range"
     594   if (miss.eq.NF_NOERR) then
     595      call missing_value(nout,varidout,valid_range,missing) 
     596   end if
    525597
    526598   deallocate(var3d)
     
    561633 if(date.ge.305) mon='nov'
    562634 if(date.ge.335) mon='dec'
    563 write(33,98) outfile
     635write(33,98) "^"//outfile
    56463698 format("DSET ",a)
    565637  write(33,99) Nls, 15,mon, int(timels(1)),nint(deltals*12),'mo'
     
    571643!************************************
    572644subroutine initiate (filename,lat,lon,alt,&
    573                      nout,latdimout,londimout,altdimout,timedimout,timevarout)
     645                     nout,latdimout,londimout,altdimout,timedimout,timevarout,units_alt)
    574646!==============================================================================
    575647! Purpose:
     
    607679integer, intent(out):: timevarout
    608680! timevarout: [netcdf] "Time" (considered as a variable) ID
     681character (len=50) :: units_alt
     682! var(): units of altitude which can be m or Pa (after zrecast)
     683
    609684
    610685!==============================================================================
     
    674749
    675750ierr = NF_PUT_ATT_TEXT (nout,nvarid,"long_name",8,"altitude")
    676 ierr = NF_PUT_ATT_TEXT (nout,nvarid,'units',2,"km")
    677 ierr = NF_PUT_ATT_TEXT (nout,nvarid,'positive',2,"up")
     751!********************* temlporaire ****************
     752!ierr = NF_PUT_ATT_TEXT (nout,nvarid,'units',2,units_alt)
     753!if((units_alt(1:2).eq.'Pa').or.(units_alt(1:2).eq.'pa')) then
     754!   ierr = NF_PUT_ATT_TEXT (nout,nvarid,'positive',2,"down")
     755!else
     756!   ierr = NF_PUT_ATT_TEXT (nout,nvarid,'positive',2,"up")
     757!end if
     758!********************* temlporaire ****************
     759ierr = NF_PUT_ATT_TEXT (nout,nvarid,'units',2,'Pa')
     760   ierr = NF_PUT_ATT_TEXT (nout,nvarid,'positive',4,'down')
     761!********************* temlporaire ****************
    678762
    679763! End netcdf define mode
     
    762846data year_day /669./            ! # of sols in a martian year
    763847data peri_day /485.0/           
    764 data timeperi /1.9082314/
     848data timeperi /1.9082314/! True anomaly at vernal equinox = 2*PI-Lsperi
    765849data e_elips  /0.093358/
    766850data twopi       /6.2831853/    ! 2.*pi
     
    872956     
    873957end
     958
     959
     960
     961!******************************************************************************
     962!******************************************************************************
     963subroutine  missing_value(nout,nvarid,valid_range,missing)
     964!==============================================================================
     965! Purpose:
     966! Write "valid_range" and "missing_value" attributes (of a given
     967! variable) to a netcdf file
     968!==============================================================================
     969! Remarks:
     970! NetCDF file must be open
     971! Variable (nvarid) ID must be set
     972!==============================================================================
     973
     974implicit none
     975
     976include "netcdf.inc"  ! NetCDF definitions
     977
     978!==============================================================================
     979! Arguments:
     980!==============================================================================
     981integer, intent(in) :: nout
     982! nout: [netcdf] file ID #
     983integer, intent(in) :: nvarid
     984! varid: [netcdf] variable ID #
     985real, dimension(2), intent(in) :: valid_range
     986! valid_range(2): [netcdf] "valid_range" attribute (min and max)
     987real, intent(in) :: missing
     988! missing: [netcdf] "missing_value" attribute
     989
     990!==============================================================================
     991! Local variables:
     992!==============================================================================
     993integer :: ierr
     994! ierr: [netcdf] subroutine returned error code
     995!      INTEGER nout,nvarid,ierr
     996!      REAL missing
     997!      REAL valid_range(2)
     998
     999! Switch to netcdf dataset define mode
     1000ierr = NF_REDEF (nout)
     1001if (ierr.ne.NF_NOERR) then
     1002   print*,'missing_value: '
     1003   print*, NF_STRERROR(ierr)
     1004endif
     1005
     1006! Write valid_range() attribute
     1007#ifdef NC_DOUBLE
     1008ierr=NF_PUT_ATT_DOUBLE(nout,nvarid,'valid_range',NF_DOUBLE,2,valid_range)
     1009#else
     1010ierr=NF_PUT_ATT_REAL(nout,nvarid,'valid_range',NF_FLOAT,2,valid_range)
     1011#endif
     1012
     1013if (ierr.ne.NF_NOERR) then
     1014   print*,'missing_value: valid_range attribution failed'
     1015   print*, NF_STRERROR(ierr)
     1016   !write(*,*) 'NF_NOERR', NF_NOERR
     1017   !CALL abort
     1018   stop ""
     1019endif
     1020
     1021! Write "missing_value" attribute
     1022#ifdef NC_DOUBLE
     1023ierr= NF_PUT_ATT_DOUBLE(nout,nvarid,'missing_value',NF_DOUBLE,1,missing)
     1024#else
     1025ierr= NF_PUT_ATT_REAL(nout,nvarid,'missing_value',NF_FLOAT,1,missing)
     1026#endif
     1027
     1028if (ierr.NE.NF_NOERR) then
     1029   print*, 'missing_value: missing value attribution failed'
     1030   print*, NF_STRERROR(ierr)
     1031!    WRITE(*,*) 'NF_NOERR', NF_NOERR
     1032!    CALL abort
     1033   stop ""
     1034endif
     1035
     1036! End netcdf dataset define mode
     1037ierr = NF_ENDDEF(nout)
     1038
     1039end subroutine  missing_value
     1040!******************************************************************************
Note: See TracChangeset for help on using the changeset viewer.