! opnormals.f90 ! f90 program written by Tim Mitchell on 04.10.02 ! last modified on 04.10.02 ! program to manipulate CRU ts normals files (.nrm) ! f90 -o ./../obs/opnormals filenames.f90 time.f90 grimfiles.f90 crutsfiles.f90 convert.f90 ! basicfun.f90 ./../obs/opnormals.f90 program OpNormals use FileNames use Time use GrimFiles use CRUtsFiles use Convert use BasicFun implicit none real, pointer, dimension (:) :: ALat,ALon,AElv,BLat,BLon,BElv,CLat,CLon,CElv integer, pointer, dimension (:,:) :: NormalsA,NormalsB,NormalsC integer, pointer, dimension (:,:) :: StnInfoA,StnInfoB,StnInfoC integer, pointer, dimension (:) :: AStn,BStn,CStn integer, pointer, dimension (:) :: CfromA,CfromB integer, pointer, dimension (:) :: ANmlYr0,ANmlYr1,ANmlSrc,ANmlInc integer, pointer, dimension (:) :: BNmlYr0,BNmlYr1,BNmlSrc,BNmlInc integer, pointer, dimension (:) :: CNmlYr0,CNmlYr1,CNmlSrc,CNmlInc character (len=20), pointer, dimension (:) :: StnNameA,StnNameB,StnNameC character (len=13), pointer, dimension (:) :: StnCtyA,StnCtyB,StnCtyC character (len=09), pointer, dimension (:) :: StnLocalA,StnLocalB,StnLocalC real, parameter :: MissVal = -999.0 integer, parameter :: DataMissVal = -9999 real :: FactorA,FactorB,Value,Constant integer :: ReadStatus,AllocStat integer :: QMenu,QConversion,QRestrict,QOperation integer :: XMonth,XAStn,XBStn,XCStn integer :: NMonth,NAStn,NBStn,NCStn integer :: VarSuffBeg,Log1,Log2,Log3,Log4,NormalBeg,NormalEnd,AScore,BScore integer :: Min,MinImpose,Max,MaxImpose character (len=80) :: GivenFile,LoadFileA,LoadFileB,SaveFileA,SaveFileB,SaveFileC character (len=04) :: VarSuffA,VarSuffB call Intro call Menu if (QMenu.EQ. 1) call ConvertHdr if (QMenu.EQ.11) call ConvertVar if (QMenu.EQ.12) call MergeTwo if (QMenu.EQ.18) call AopConstant if (QMenu.EQ.80) call FilterYrs call Finish contains !******************************************************************************* subroutine Intro open (99,file="/cru/mikeh1/f709762/scratch/log/log-normals.dat",status="replace",action="write") print* print*, " > ***** OpNormals: manipulates .nrm files *****" print* NMonth = 12 end subroutine Intro !******************************************************************************* subroutine Menu print*, " > Select an operation to perform (0=list): " do read (*,*,iostat=ReadStatus), QMenu if (QMenu.EQ.0) then print*, " > 1. Convert into a .hdr file." print*, " > 11. Convert variable." print*, " > 12. Merge two .nrm files." print*, " > 18. A.k --> B" print*, " > 80. Filter unlikely years. [ANTIQUE]" end if if (ReadStatus.LE.0.AND.QMenu.NE.0) exit end do end subroutine Menu !******************************************************************************* ! 1. convert .nrm to .hdr subroutine ConvertHdr print*, " > Select the .nrm file to load: " do read (*,*,iostat=ReadStatus), GivenFile if (ReadStatus.LE.0.AND.GivenFile.NE."") exit end do LoadFileA = LoadPath (GivenFile,".nrm") print*, " > Select the .hdr file to save: " do read (*,*,iostat=ReadStatus), GivenFile if (ReadStatus.LE.0.AND.GivenFile.NE."") exit end do SaveFileA = SavePath (GivenFile,".hdr") print*, " > Operating..." call LoadCTS (StnInfoA,StnLocalA,StnNameA,StnCtyA,Code=AStn,Lat=ALat,Lon=ALon,Elv=AElv, & CallFile=LoadFileA,Normals=NormalsA,NmlYr0=ANmlYr0,NmlYr1=ANmlYr1, & NmlSrc=ANmlSrc,NmlInc=ANmlInc) call MakeStnInfo (StnInfoB,AStn,ALat,ALon,AElv,1,YearAD0=ANmlYr0,YearAD1=ANmlYr1) call SaveCTS (StnInfoB,StnLocalA,StnNameA,StnCtyA,CallFile=SaveFileA,HeadOnly=1) end subroutine ConvertHdr !******************************************************************************* ! 11. convert variable subroutine ConvertVar print*, " > Select the conversion (0=list): " do read (*,*,iostat=ReadStatus), QConversion if (QConversion.EQ.0) then print*, " > 1. .snh to .spc" print*, " > 2. .spc to .cld" end if if (ReadStatus.LE.0.AND.QConversion.NE.0) exit end do if (QConversion.EQ.1) then VarSuffA=".snh" ; VarSuffB=".spc" ; FactorA=0.1 ; FactorB=0.1 else if (QConversion.EQ.2) then VarSuffA=".spc" ; VarSuffB=".cld" ; FactorA=0.1 ; FactorB=0.1 end if print*, " > Select the .nrm file to load: " do VarSuffBeg = 0 read (*,*,iostat=ReadStatus), GivenFile if (ReadStatus.LE.0) VarSuffBeg = index(GivenFile,VarSuffA) if (VarSuffBeg.GT.0) exit end do LoadFileA = LoadPath (GivenFile,".nrm") print*, " > Select the .nrm file to save: " do VarSuffBeg = 0 read (*,*,iostat=ReadStatus), GivenFile if (ReadStatus.LE.0) VarSuffBeg = index(GivenFile,VarSuffB) if (VarSuffBeg.GT.0) exit end do SaveFileB = SavePath (GivenFile,".nrm") print*, " > Operating..." call LoadCTS (StnInfoA,StnLocalA,StnNameA,StnCtyA,Code=AStn,Lat=ALat,Lon=ALon,Elv=AElv, & CallFile=LoadFileA,Normals=NormalsA,NmlYr0=ANmlYr0,NmlYr1=ANmlYr1, & NmlSrc=ANmlSrc,NmlInc=ANmlInc) NAStn=size(AStn,1) ; Log1=0 ; Log2=0 do XMonth = 1, NMonth do XAStn = 1, NAStn if (NormalsA(XMonth,XAStn).NE.DataMissVal) then Value = real(NormalsA(XMonth,XAStn))*FactorA if (QConversion.EQ.1) Value=SunPCfromHours(Value,ALat(XAStn),XMonth) if (QConversion.EQ.2) Value=100.0-Value if (Value.NE.DataMissVal) then NormalsA(XMonth,XAStn)=nint(Value/FactorB) else Log2=Log2+1 end if else Log1=Log1+1 end if end do end do Log3=(NMonth*NAStn) ; Log4=((NMonth*NAStn)-Log1-Log2) print "(a)", " > Totals: checked, original missing, didn't convert, and valid: " print "(4(a,i6))", " ",Log3," ",Log1," ",Log2, & " ",Log4 call MakeStnInfo (StnInfoB,AStn,ALat,ALon,AElv,1,YearAD0=ANmlYr0,YearAD1=ANmlYr1) call SaveCTS (StnInfoB,StnLocalA,StnNameA,StnCtyA,CallFile=SaveFileB, & Normals=NormalsA,NmlSrc=ANmlSrc,NmlInc=ANmlInc) end subroutine ConvertVar !******************************************************************************* ! 12. merge 2 .nrm files subroutine MergeTwo print*, " > Select the MASTER .nrm file to load: " do read (*,*,iostat=ReadStatus), GivenFile if (ReadStatus.LE.0.AND.GivenFile.NE."") exit end do LoadFileA = LoadPath (GivenFile,".nrm") print*, " > Select the SUPPLEMENTARY .nrm file to load: " do read (*,*,iostat=ReadStatus), GivenFile if (ReadStatus.LE.0.AND.GivenFile.NE."") exit end do LoadFileB = LoadPath (GivenFile,".nrm") print*, " > Select the .nrm file to save: " do read (*,*,iostat=ReadStatus), GivenFile if (ReadStatus.LE.0.AND.GivenFile.NE."") exit end do SaveFileC = SavePath (GivenFile,".nrm") print*, " > Enter the normals period to target (beg,end): " do read (*,*,iostat=ReadStatus), NormalBeg,NormalEnd if (ReadStatus.LE.0.AND.NormalEnd.GE.NormalBeg) exit end do print*, " > Operating..." call LoadCTS (StnInfoA,StnLocalA,StnNameA,StnCtyA,Code=AStn,Lat=ALat,Lon=ALon,Elv=AElv, & CallFile=LoadFileA,Normals=NormalsA,NmlYr0=ANmlYr0,NmlYr1=ANmlYr1, & NmlSrc=ANmlSrc,NmlInc=ANmlInc) call LoadCTS (StnInfoB,StnLocalB,StnNameB,StnCtyB,Code=BStn,Lat=BLat,Lon=BLon,Elv=BElv, & CallFile=LoadFileB,Normals=NormalsB,NmlYr0=BNmlYr0,NmlYr1=BNmlYr1, & NmlSrc=BNmlSrc,NmlInc=BNmlInc) call CombineStn (AStn,BStn,CStn,CfromA,CfromB) ! see CRUtsFiles NAStn=size(AStn) ; NBStn=size(BStn) ; NCStn=size(CStn) allocate (CStn(NCStn), CLat(NCStn), CLon(NCStn), CElv(NCStn), & CNmlYr0(NCStn), CNmlYr1(NCStn), StnLocalC(NCStn), StnNameC(NCStn), StnCtyC(NCStn), & NormalsC(NMonth,NCStn), CNmlSrc(NCStn), CNmlInc(NCStn), stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: MergeTwo: Allocation failure: C* #####" write (99,*), "STATIONS OVERWRITTEN:" Log1=0 ; Log2=0 do XCStn = 1, NCStn if (CfromA(XCStn).NE.-999.AND.CfromB(XCStn).NE.-999) then if (BNmlYr0(CfromB(XCStn)).NE.9999.AND.BNmlYr1(CfromB(XCStn)).NE.9999) then if (BNmlYr0(CfromB(XCStn)).GE.NormalBeg.AND.BNmlYr1(CfromB(XCStn)).LE.NormalEnd) then if (ANmlYr0(CfromA(XCStn)).GE.NormalBeg.AND.ANmlYr1(CfromA(XCStn)).LE.NormalEnd) then AScore = (ANmlYr1(CfromA(XCStn))-ANmlYr0(CfromA(XCStn))+1)*ANmlInc(CfromA(XCStn)) BScore = (BNmlYr1(CfromB(XCStn))-BNmlYr0(CfromB(XCStn))+1)*BNmlInc(CfromB(XCStn)) if (AScore.GE.BScore) then CfromB(XCStn) = -999 else write (99,"(i7,x,a3,2i5,i4,12i5)"), CStn(XCStn), "Asc",ANmlYr0(CfromA(XCStn)),& ANmlYr1(CfromA(XCStn)),ANmlInc(CfromA(XCStn)),(NormalsA(XMonth,CfromA(XCStn)),XMonth=1,NMonth) write (99,"(7x,x,a3,2i5,i4,12i5)"), "Bsc",BNmlYr0(CfromB(XCStn)),& BNmlYr1(CfromB(XCStn)),BNmlInc(CfromB(XCStn)),(NormalsB(XMonth,CfromB(XCStn)),XMonth=1,NMonth) CfromA(XCStn) = -999 end if else write (99,"(i7,x,a3,2i5,i4,12i5)"), CStn(XCStn), "Ayr",ANmlYr0(CfromA(XCStn)),& ANmlYr1(CfromA(XCStn)),ANmlInc(CfromA(XCStn)),(NormalsA(XMonth,CfromA(XCStn)),XMonth=1,NMonth) write (99,"(7x,x,a3,2i5,i4,12i5)"), "Byr",BNmlYr0(CfromB(XCStn)),& BNmlYr1(CfromB(XCStn)),BNmlInc(CfromB(XCStn)),(NormalsB(XMonth,CfromB(XCStn)),XMonth=1,NMonth) CfromA(XCStn) = -999 end if else CfromB(XCStn) = -999 end if else CfromB(XCStn) = -999 end if end if if (CfromA(XCStn).NE.-999.AND.CfromB(XCStn).EQ.-999) then Log1=Log1+1 do XMonth = 1, NMonth NormalsC(XMonth,XCStn) = NormalsA(XMonth,CfromA(XCStn)) end do else if (CfromA(XCStn).EQ.-999.AND.CfromB(XCStn).NE.-999) then Log2=Log2+1 do XMonth = 1, NMonth NormalsC(XMonth,XCStn) = NormalsB(XMonth,CfromB(XCStn)) end do end if if (CfromA(XCStn).NE.-999.AND.CfromB(XCStn).EQ.-999) then CStn(XCStn)=AStn(CfromA(XCStn)) ; CLat(XCStn)=ALat(CfromA(XCStn)) CLon(XCStn)=ALon(CfromA(XCStn)) ; CElv(XCStn)=AElv(CfromA(XCStn)) CNmlYr0(XCStn)=ANmlYr0(CfromA(XCStn)) ; CNmlYr1(XCStn)=ANmlYr1(CfromA(XCStn)) StnLocalC(XCStn)=StnLocalA(CfromA(XCStn)) ; StnNameC(XCStn)=StnNameA(CfromA(XCStn)) StnCtyC(XCStn)=StnCtyA(CfromA(XCStn)) ; CNmlSrc(XCStn)=ANmlSrc(CfromA(XCStn)) CNmlInc(XCStn)=ANmlInc(CfromA(XCStn)) else if (CfromA(XCStn).EQ.-999.AND.CfromB(XCStn).NE.-999) then CStn(XCStn)=BStn(CfromB(XCStn)) ; CLat(XCStn)=BLat(CfromB(XCStn)) CLon(XCStn)=BLon(CfromB(XCStn)) ; CElv(XCStn)=BElv(CfromB(XCStn)) CNmlYr0(XCStn)=BNmlYr0(CfromB(XCStn)) ; CNmlYr1(XCStn)=BNmlYr1(CfromB(XCStn)) StnLocalC(XCStn)=StnLocalB(CfromB(XCStn)) ; StnNameC(XCStn)=StnNameB(CfromB(XCStn)) StnCtyC(XCStn)=StnCtyB(CfromB(XCStn)) ; CNmlSrc(XCStn)=BNmlSrc(CfromB(XCStn)) CNmlInc(XCStn)=BNmlInc(CfromB(XCStn)) end if end do print*, " > Overwritten stations dumped to log." print "(a,2i7)", " > Stns: kept from master, added from supplement: ", Log1,Log2 call MakeStnInfo (StnInfoC,CStn,CLat,CLon,CElv,1,YearAD0=CNmlYr0,YearAD1=CNmlYr1) call SaveCTS (StnInfoC,StnLocalC,StnNameC,StnCtyC,CallFile=SaveFileC, & Normals=NormalsC,NmlSrc=CNmlSrc,NmlInc=CNmlInc) end subroutine MergeTwo !******************************************************************************* ! 18. A.k --> B subroutine AopConstant print*, " > Select the .nrm file to load: " do read (*,*,iostat=ReadStatus), GivenFile if (ReadStatus.LE.0.AND.GivenFile.NE."") exit end do LoadFileA = LoadPath (GivenFile,".nrm") print*, " > Select the .nrm file to save: " do read (*,*,iostat=ReadStatus), GivenFile if (ReadStatus.LE.0.AND.GivenFile.NE."") exit end do SaveFileA = SavePath (GivenFile,".nrm") print*, " > Select the operation (A/k=1, A*k=2, A-k=3, A+k=4, sqrt=5, **k=6, abs=7): " do read (*,*,iostat=ReadStatus), QOperation if (ReadStatus.LE.0 .AND. QOperation.GE.1 .AND. QOperation.LE.7) exit end do Constant = -999.0 if (QOperation.NE.5.AND.QOperation.NE.7) then print*, " > Select the constant: " do read (*,*,iostat=ReadStatus), Constant if (ReadStatus.LE.0) exit end do end if call EnquireRestrict print*, " > Operating..." call LoadCTS (StnInfoA,StnLocalA,StnNameA,StnCtyA,Code=AStn,Lat=ALat,Lon=ALon,Elv=AElv, & CallFile=LoadFileA,Normals=NormalsA,NmlYr0=ANmlYr0,NmlYr1=ANmlYr1, & NmlSrc=ANmlSrc,NmlInc=ANmlInc) NAStn = size(NormalsA,2) do XAStn = 1, NAStn do XMonth = 1, 12 if (NormalsA(XMonth,XAStn).NE.-9999) NormalsA(XMonth,XAStn) = & OpAwithB (real(NormalsA(XMonth,XAStn)),Constant,QOperation) if (QRestrict.Eq.1.OR.QRestrict.Eq.3) then if (NormalsA(XMonth,XAStn).LT.Min) NormalsA(XMonth,XAStn) = MinImpose end if if (QRestrict.Eq.2.OR.QRestrict.Eq.3) then if (NormalsA(XMonth,XAStn).GT.Max) NormalsA(XMonth,XAStn) = MaxImpose end if end do end do call SaveCTS (StnInfoA,StnLocalA,StnNameA,StnCtyA,CallFile=SaveFileA, & Normals=NormalsA,NmlSrc=ANmlSrc,NmlInc=ANmlInc) end subroutine AopConstant !******************************************************************************* ! 80. Filter unlikely years. [ANTIQUE] subroutine FilterYrs print*, " > Select the .nrm file to load: " do read (*,*,iostat=ReadStatus), GivenFile if (ReadStatus.LE.0.AND.GivenFile.NE."") exit end do LoadFileA = LoadPath (GivenFile,".nrm") print*, " > Select the .nrm file to save: " do read (*,*,iostat=ReadStatus), GivenFile if (ReadStatus.LE.0.AND.GivenFile.NE."") exit end do SaveFileA = SavePath (GivenFile,".nrm") print*, " > Operating..." call LoadCTS (StnInfoA,StnLocalA,StnNameA,StnCtyA,Code=AStn,Lat=ALat,Lon=ALon,Elv=AElv, & CallFile=LoadFileA,Normals=NormalsA,NmlYr0=ANmlYr0,NmlYr1=ANmlYr1, & NmlSrc=ANmlSrc,NmlInc=ANmlInc) NAStn = size(NormalsA,2) do XAStn = 1, NAStn if (ANmlYr0(XAStn).LT.1600.OR.ANmlYr0(XAStn).GT.2100) then ANmlYr0(XAStn) = 9999 ; ANmlYr1(XAStn) = 9999 else if (ANmlYr1(XAStn).LT.1600.OR.ANmlYr1(XAStn).GT.2100) then ANmlYr0(XAStn) = 9999 ; ANmlYr1(XAStn) = 9999 end if end do call MakeStnInfo (StnInfoB,AStn,ALat,ALon,AElv,1,YearAD0=ANmlYr0,YearAD1=ANmlYr1) call SaveCTS (StnInfoB,StnLocalA,StnNameA,StnCtyA,CallFile=SaveFileA, & Normals=NormalsA,NmlSrc=ANmlSrc,NmlInc=ANmlInc) end subroutine FilterYrs !******************************************************************************* subroutine EnquireRestrict print*, " > Impose min (=1), max (=2), both (=3), neither (=0):" do read (*,*,iostat=ReadStatus), QRestrict if (ReadStatus.LE.0.AND.QRestrict.GE.0.AND.QRestrict.LE.3) exit end do if (QRestrict.EQ.1.OR.QRestrict.EQ.3) then print*, " > Enter the minimum value to accept, and value to impose:" do read (*,*,iostat=ReadStatus), Min,MinImpose if (ReadStatus.LE.0) exit end do end if if (QRestrict.EQ.2.OR.QRestrict.EQ.3) then print*, " > Enter the maximum value to accept, and value to impose:" do read (*,*,iostat=ReadStatus), Max,MaxImpose if (ReadStatus.LE.0) exit end do end if end subroutine EnquireRestrict !******************************************************************************* subroutine Finish print* close (99) end subroutine Finish !******************************************************************************* end program OpNormals