!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ! NASA/GSFC, Data Assimilation Office, Code 910.3, GEOS/DAS ! !BOP ------------------------------------------------------------------- ! ! !MODULE: m_Sndx - Sounding index generator ! ! !DESCRIPTION: ! ! !INTERFACE: module m_Sndx 1,35 use m_odsmeta, only : kxmax use m_odsmeta, only : kxmod use m_die, only : perr implicit none private ! except public :: setSndx ! Set sounding index values public :: Sndx2pix ! another sounding index (pix) public :: dumpks interface setSndx; module procedure & setstn_, & setkx_, & setll_, & set_; end interface ! !REVISION HISTORY: ! 05Jun00 - Jing Guo <guo@dao.gsfc.nasa.gov> ! - initial prototype/prolog/code !EOP ___________________________________________________________________ character(len=*),parameter :: myname='m_Sndx' contains !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ! NASA/GSFC, Data Assimilation Office, Code 910.3, GEOS/DAS ! !BOP ------------------------------------------------------------------- ! ! !IROUTINE: setstn_ - set sounding index by stn. IDs. ! ! !DESCRIPTION: ! ! !INTERFACE: subroutine setstn_(ks,kx,stn) use m_SortingTools,only : indexSet,indexSort use m_die ,only : die use m_mall,only : mall_ison,mall_mci,mall_mco implicit none integer ,dimension(:),intent(out) :: ks ! sounding index integer ,dimension(:),intent(in ) :: kx ! instrument IDs character(len=*),dimension(:),intent(in ) :: stn ! station IDs ! REVISION HISTORY: ! 22Apr04 - Jing Guo <guo@dao.gsfc.nasa.gov> ! - initial prototype/prolog/code !EP ___________________________________________________________________ character(len=*),parameter :: myname_=myname//'::setstn_' integer :: ikx,iks,i,j character(len=len(stn)) :: xID integer,allocatable,dimension(:) :: indx integer :: lobs integer :: ier lobs=size(kx) if(lobs/=size(ks) .or. lobs/=size(stn)) then call perr(myname_,'size( ks)',size( ks)) call perr(myname_,'size( kx)',size( kx)) call perr(myname_,'size(stn)',size(stn)) call die(myname_,'mismatched argument sizes',ier) endif if(lobs==0) return allocate(indx(lobs), stat=ier) if(ier/=0) call die(myname_,'allocate()',ier) if(mall_ison()) call mall_mci(indx,myname) ! local sorting by kx and by station IDs. call indexSet(indx) call indexSort(indx,stn) call indexSort(indx,kx) iks=1 i=1 j=indx(i) ikx=kx(j) xid=stn(j) ks(j)=iks ! Set all sounding index values. All soundings of the same ! instrument are assumed to be on the same PE. do i=2,lobs j=indx(i) ! refer to the actual location if(kx(j)/=ikx) then ! if this is a new intrument type (kx), reset sounding index ! counter (iks) and instrument marker (ikx) to the new value. iks=1 ikx=kx(j) xID=stn(j) else ! if this is the same intrument type as the previous entry, if(stn(j)/=xID) then ! if this is a new stn ID, reset sounding index (ks). xID=stn(j) iks=iks+1 endif endif ks(j)=iks end do if(mall_ison()) call mall_mco(indx,myname) deallocate(indx, stat=ier) if(ier/=0) call die(myname_,'deallocate()',ier) end subroutine setstn_ !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ! NASA/GSFC, Data Assimilation Office, Code 910.3, GEOS/DAS ! !BOP ------------------------------------------------------------------- ! ! !IROUTINE: setkx_ - assign sounding indices ! ! !DESCRIPTION: ! ! !INTERFACE: subroutine setkx_(ks,kx,rlat,rlon) use m_SortingTools,only : indexSet,indexSort use m_die ,only : die use m_mall,only : mall_ison,mall_mci,mall_mco implicit none integer,dimension(:),intent(out) :: ks integer,dimension(:),intent(in ) :: kx real ,dimension(:),intent(in ) :: rlat real ,dimension(:),intent(in ) :: rlon ! !REVISION HISTORY: ! 05Jun00 - Jing Guo <guo@dao.gsfc.nasa.gov> ! - initial prototype/prolog/code !EOP ___________________________________________________________________ character(len=*),parameter :: myname_=myname//'::setkx_' integer :: ndat integer :: ier integer :: i,l integer :: kx_i integer :: kx_l real :: rlon_l real :: rlat_l integer :: ks_l integer,allocatable,dimension(:) :: indx ndat=size(ks) if(ndat<=0) return allocate(indx(ndat),stat=ier) if(ier/=0) call die(myname_,'allocate()',ier) if(mall_ison()) call mall_mci(indx,myname) call indexSet(indx) call indexSort(indx,rlon) call indexSort(indx,rlat) call indexSort(indx,kx) !________________________________________ ! Segmentation using indices l=indx(1) ! Process the initial data point. kx_i=kx(l) ! Count as another sounding and save the current data. ks_l=1 kx_l=kx_i rlon_l=rlon(l) rlat_l=rlat(l) ks(l)=ks_l ! Save the current sounding index. ! Process rest data points. do i=2,ndat l=indx(i) kx_i=kx(l) ! If the saved data are not the same as the current, ! count as another sounding and save the current data. if(kx_l/=kx_i .or. rlon_l/=rlon(l) .or. rlat_l/=rlat(l)) then ! The following statement relies on the sorting order ! of the data to be primerily by kx. The purpose is ! to restart a counter for every kx. if(kx_l/=kx_i) ks_l=0 ks_l=ks_l+1 kx_l=kx_i rlon_l=rlon(l) rlat_l=rlat(l) endif ! Save the current sounding index. ks(l)=ks_l end do if(mall_ison()) call mall_mco(indx,myname) deallocate(indx,stat=ier) if(ier/=0) call die(myname_,'deallocate()',ier) end subroutine setkx_ !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ! NASA/GSFC, Data Assimilation Office, Code 910.3, GEOS/DAS ! !BOP ------------------------------------------------------------------- ! ! !IROUTINE: set_ - assign sounding indices ! ! !DESCRIPTION: ! ! !INTERFACE: subroutine set_(ks,rlat,rlon) use m_SortingTools,only : indexSet,indexSort use m_die ,only : die use m_mall,only : mall_ison,mall_mci,mall_mco implicit none integer,dimension(:),intent(out) :: ks real ,dimension(:),intent(in ) :: rlat real ,dimension(:),intent(in ) :: rlon ! !REVISION HISTORY: ! 05Jun00 - Jing Guo <guo@dao.gsfc.nasa.gov> ! - initial prototype/prolog/code !EOP ___________________________________________________________________ character(len=*),parameter :: myname_=myname//'::set_' integer :: ndat integer :: ier integer :: i,l real :: rlon_l real :: rlat_l integer :: ks_l integer,allocatable,dimension(:) :: indx ndat=size(ks) if(ndat<=0) return allocate(indx(ndat),stat=ier) if(ier/=0) call die(myname_,'allocate()',ier) if(mall_ison()) call mall_mci(indx,myname) call indexSet(indx) call indexSort(indx,rlon) call indexSort(indx,rlat) !________________________________________ ! Segmentation using indices l=indx(1) ! Process the initial data point. ! Count as another sounding and save the current data. ks_l=1 rlon_l=rlon(l) rlat_l=rlat(l) ks(l)=ks_l ! Save the current sounding index. ! Process rest data points. do i=2,ndat l=indx(i) ! If the saved data are not the same as the current, ! count as another sounding and save the current data. if(rlon_l/=rlon(l) .or. rlat_l/=rlat(l)) then ks_l=ks_l+1 rlon_l=rlon(l) rlat_l=rlat(l) endif ! Save the current sounding index. ks(l)=ks_l end do if(mall_ison()) call mall_mco(indx,myname) deallocate(indx,stat=ier) if(ier/=0) call die(myname_,'deallocate()',ier) end subroutine set_ !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ! NASA/GSFC, Data Assimilation Office, Code 910.3, GEOS/DAS ! !BOP ------------------------------------------------------------------- ! ! !IROUTINE: setll_ - set sounding indices locally from lat-lon values ! ! !DESCRIPTION: ! ! !INTERFACE: subroutine setll_(ks,rlat,dlat,rlon,dlon) use m_die,only : die implicit none integer,dimension(:),intent(out) :: ks real ,dimension(:),intent(in) :: rlat real ,intent(in) :: dlat real ,dimension(:),intent(in) :: rlon real ,intent(in) :: dlon ! !REVISION HISTORY: ! 03Nov00 - Jing Guo <guo@dao.gsfc.nasa.gov> ! - initial prototype/prolog/code !EOP ___________________________________________________________________ character(len=*),parameter :: myname_=myname//'::setll_' integer :: i integer :: nlon,ilon,ilat real :: alat,alon alat=abs(dlat) alon=abs(dlon) if(alat*alon < .0001) call die(myname_,'unreliable configuration') nlon=360./alon do i=1,size(ks) ilat=nint(rlat(i)/alat) ilon=modulo(nint(rlon(i)/alon),nlon) ks(i)=ilat*nlon+ilon end do end subroutine setll_ !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ! NASA/GSFC, Data Assimilation Office, Code 910.3, GEOS/DAS ! !BOP ------------------------------------------------------------------- ! ! !IROUTINE: Sndx2pix - ! ! !DESCRIPTION: ! ! !INTERFACE: subroutine Sndx2pix(ks,kx,rlat,rlon) implicit none integer,dimension(:),intent(inout) :: ks integer,dimension(:),intent(in) :: kx real ,dimension(:),intent(in) :: rlat real ,dimension(:),intent(in) :: rlon ! !REVISION HISTORY: ! 22Jun00 - Jing Guo <guo@dao.gsfc.nasa.gov> ! - initial prototype/prolog/code ! 04Jun04 - Todling removed kxmax.h (using m_odsmeta) !EOP ___________________________________________________________________ character(len=*),parameter :: myname_=myname//'::Sndx2pix' integer :: i,nobs integer :: ks_i,kx_i real :: rlat_i,rlon_i integer :: knt(kxmax) integer :: pix_now logical :: begin_prof !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ nobs=size(ks) if (nobs.le.0) return knt(1:kxmax)=-1 ! none yet ! this part needs to be serially processed, since it is ! it is upto the previous entry to determine the pix ! value of the current entry. kx_i=kx(1) ks_i=ks(1) rlat_i=rlat(1) rlon_i=rlon(1) knt(kx_i)=knt(kx_i)+1 pix_now=kx_i+knt(kx_i)*kxmod ks(1)=pix_now do i=2,nobs begin_prof= ks_i.ne.ks(i) .or. & kx_i.ne.kx(i) kx_i=kx(i) ks_i=ks(i) rlat_i=rlat(i) rlon_i=rlon(i) if(begin_prof) then ! If a new profile, count it knt(kx_i)=knt(kx_i)+1 pix_now=kx_i+knt(kx_i)*kxmod endif ks(i)=pix_now end do !_______________________________________________________________________ end subroutine Sndx2pix !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ! NASA/GSFC, Data Assimilation Office, Code 910.3, GEOS/DAS ! !BOP ------------------------------------------------------------------- ! ! !IROUTINE: dumpks - ! ! !DESCRIPTION: ! ! !INTERFACE: subroutine dumpks(fname,kx,ks,rlat,rlon) use m_ioutil,only : luavail,opntext,clstext implicit none character(len=*),intent(in) :: fname integer,dimension(:),intent(in) :: kx integer,dimension(:),intent(in) :: ks real ,dimension(:),intent(in) :: rlat real ,dimension(:),intent(in) :: rlon ! !REVISION HISTORY: ! 22Jun00 - Jing Guo <guo@dao.gsfc.nasa.gov> ! - initial prototype/prolog/code !EOP ___________________________________________________________________ character(len=*),parameter :: myname_=myname//'::dumpks' integer :: lu,ier,i lu=luavail() call opntext(lu,fname,'unknown',ier) do i=1,size(kx) write(lu,'(3i8,2f8.2)') i,kx(i),ks(i),rlat(i),rlon(i) end do call clstext(lu,ier) end subroutine dumpks end module m_Sndx