! extractmod.f90 ! module procedure written by Tim Mitchell in Dec 1999 ! last modification on 16.02.00 ! contains all the routines necessary to extract a given run from raw files ! BlockKey, ExtractMonth, ExtractFile module ExtractMod use ArrayMod implicit none contains !******************************************************************************* subroutine BlockKey (FileYearN, JobMonthN, FileYear0, FileYear1, JobMonth0, JobMonth1, & FilePathThis, FilePathNext, FileStyleThis, FileStyleNext, FileBlockKey) integer, pointer, dimension (:,:) :: FileBlockKey integer, intent (in) :: FileYearN, FileYear0, FileYear1, JobMonthN, JobMonth0, JobMonth1 integer, intent (inout) :: FileStyleThis, FileStyleNext character (len=80), intent (inout) :: FilePathThis, FilePathNext real, parameter :: MissVal = -999.0 integer :: AllocStat ! status of allocation integer :: OverLap ! 0=none 1=overlap integer :: XYear, XMonth integer :: LastSeasonA ! last season contained within fileA !*************************************** if (FileYearN.NE.10) print*, " > ##### Cannot use files other than 10 years in length #####" allocate (FileBlockKey (FileYearN, 12), stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: Allocation failure #####" FileBlockKey = 0 if ( (JobMonth1-JobMonth0).GE.0 ) then OverLap = 0 else OverLap = 1 end if if (OverLap.EQ.0) then FilePathNext = "blank" FileStyleNext = MissVal do XYear = FileYear0, FileYear1 FileBlockKey (XYear, JobMonth0) = 1 if (JobMonthN.GE.3) then do XMonth = (JobMonth0+1),(JobMonth1-1) FileBlockKey (XYear, XMonth) = 2 end do end if FileBlockKey (XYear, JobMonth1) = 3 end do else if (FileYear1.EQ.FileYearN .AND. FilePathNext.NE."blank") then LastSeasonA = FileYear1 - 1 else LastSeasonA = FileYear1 end if do XYear = FileYear0, LastSeasonA FileBlockKey (XYear, JobMonth0) = 1 if ((12-JobMonth0).GE.1) then do XMonth = (JobMonth0+1),12 FileBlockKey (XYear, XMonth) = 2 end do end if if (JobMonth1.GT.1) then do XMonth = 1,(JobMonth1-1) FileBlockKey ((XYear+1), XMonth) = 2 end do end if FileBlockKey ((XYear+1), JobMonth1) = 3 end do if (FileYear1.EQ.FileYearN .AND. FilePathNext.NE."blank") then FileBlockKey (FileYear1, JobMonth0) = 1 if ((12-JobMonth0).GE.1) then do XMonth = (JobMonth0+1),12 FileBlockKey (10, XMonth) = 2 end do end if if (JobMonth1.GT.1) then do XMonth = 1,(JobMonth1-1) FileBlockKey (1, XMonth) = -2 end do end if FileBlockKey (1, JobMonth1) = -3 else FilePathNext = "blank" FileStyleNext = MissVal end if end if end subroutine BlockKey !******************************************************************************* subroutine DefineStyle (StyleIndex, FileFormat, FileMissVal, FileRowN, FileColN, FileHeaderN) integer, intent (in) :: StyleIndex integer, intent (out) :: FileRowN, FileColN, FileHeaderN character (len=10), intent (out) :: FileFormat real, intent (out) :: FileMissVal real, parameter :: MissVal = -999.0 FileRowN = MissVal ! the standard series is 101... FileColN = MissVal ! the series 201 and 301... are = 101... (and must be maintained thus) FileHeaderN = MissVal ! the rule is that 101... is used unless the data is in temk (deg K) form FileFormat = "blank" ! in which case, the equivalent from the 201...series must be used FileMissVal = MissVal ! ...or unless the data is in degC * 10 form, ! in which case, the equivalent from the 301...series must be used if (StyleIndex.EQ.101.OR.StyleIndex.EQ.201.OR.StyleIndex.EQ.301) then FileFormat = "e12.5" FileMissVal = 10000 FileHeaderN = 6 FileRowN = 1168 FileColN = 6 else if (StyleIndex.EQ.102.OR.StyleIndex.EQ.202.OR.StyleIndex.EQ.302) then FileFormat = "f8.2" FileMissVal = 9999.99 FileHeaderN = 6 FileRowN = 701 FileColN = 10 else if (StyleIndex.EQ.103.OR.StyleIndex.EQ.203.OR.StyleIndex.EQ.302) then FileFormat = "e13.6" FileMissVal = -999.0 FileHeaderN = 1 FileRowN = 876 FileColN = 8 else if (StyleIndex.EQ.104.OR.StyleIndex.EQ.204.OR.StyleIndex.EQ.304) then FileFormat = "e13.6" FileMissVal = -999.0 FileHeaderN = 1 FileRowN = 1024 FileColN = 8 else if (StyleIndex.EQ.105.OR.StyleIndex.EQ.205.OR.StyleIndex.EQ.305) then FileFormat = "e16.7" FileMissVal = -999.9 FileHeaderN = 0 FileRowN = 73 FileColN = 96 else if (StyleIndex.EQ.106.OR.StyleIndex.EQ.206.OR.StyleIndex.EQ.306) then FileFormat = "e16.7" FileMissVal = -9999.0 FileHeaderN = 0 FileRowN = 32400 FileColN = 8 else print*, " > ##### DefineStyle: style not recognised #####" end if end subroutine DefineStyle !******************************************************************************* subroutine TemktoTemp (RegN,DataVec) real, pointer, dimension (:) :: DataVec ! def,alloc,init in call integer, intent (in) :: RegN real, parameter :: MissVal = -999.0 integer :: XReg do XReg = 1, RegN if (DataVec(XReg).NE.MissVal) then DataVec (XReg) = DataVec (XReg) - 273.15 end if end do end subroutine TemktoTemp !******************************************************************************* subroutine TempTens (RegN,DataVec) real, pointer, dimension (:) :: DataVec ! def,alloc,init in call integer, intent (in) :: RegN real, parameter :: MissVal = -999.0 integer :: XReg do XReg = 1, RegN if (DataVec(XReg).NE.MissVal) then DataVec (XReg) = DataVec (XReg) / 10.0 end if end do end subroutine TempTens !******************************************************************************* subroutine ExtractMonth (FileUnit, FileFormat, FileMissVal, FileRowN, FileColN, FileHeaderN, & ModelDataN, RegN, MapRawReg, RegSizes, GotMonth) integer, pointer, dimension (:) :: MapRawReg, RegSizes real, pointer, dimension (:) :: GotMonth ! def,alloc,init=0 in call integer, intent (in) :: FileUnit, FileRowN, FileColN, FileHeaderN, & ModelDataN, RegN real, intent (in) :: FileMissVal character (len=10), intent (in) :: FileFormat !*************************************** real, allocatable, dimension (:) :: LoadVec integer, allocatable, dimension (:) :: MissReg character (len=80), parameter :: ScratchFile = "/cru/u2/f709762/data/scratch/deleteme.txt" character (len=10) :: RecFormat, RecFormatLast character (len=4) :: FormatPrefix, FormatPrefixLast character (len=1) :: HeaderTrash integer :: FileColNLast ! no of columns in last row integer :: XRec, XDatum, XReg integer :: AllocStat ! status of allocation attempt integer :: RecDatum0, RecDatum1 ! record first, last data integer :: RecTotal integer :: ReadStat integer :: RegMissTot real, parameter :: MissVal = -999.0 !*************************************** allocate (LoadVec (ModelDataN), stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: Allocation failure #####" LoadVec = MissVal allocate (MissReg (RegN), stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: Allocation failure #####" MissReg = 0 FileColNLast = ModelDataN - (FileRowN-1) * FileColN open (unit=(FileUnit+2), file=ScratchFile) write (unit=(FileUnit+2),fmt="(2(I4))"), FileColN, FileColNLast close (FileUnit+2) open (unit=(FileUnit+2), file=ScratchFile) read (unit=(FileUnit+2),fmt="(2(A4))"), FormatPrefix, FormatPrefixLast close (FileUnit+2) RecFormat = '(' // trim(adjustl(FormatPrefix)) // trim(adjustl(FileFormat)) // ')' RecFormatLast = '(' // trim(adjustl(FormatPrefixLast)) // trim(adjustl(FileFormat)) // ')' RecFormat = trim(adjustl(RecFormat)) RecFormatLast = trim(adjustl(RecFormatLast)) !*************************************** RecDatum0 = 1 - FileColN RecDatum1 = 0 do XRec = 1, FileHeaderN read (FileUnit, fmt="(A1)"), HeaderTrash end do do XRec = 1, (FileRowN-1) RecDatum0 = RecDatum0 + FileColN RecDatum1 = RecDatum1 + FileColN read (FileUnit, fmt=RecFormat), (LoadVec (XDatum), XDatum=RecDatum0,RecDatum1) end do RecDatum0 = RecDatum0 + FileColN RecDatum1 = ModelDataN read (FileUnit, fmt=RecFormatLast), (LoadVec (XDatum), XDatum=RecDatum0,RecDatum1) !*************************************** do XDatum = 1, ModelDataN if (MapRawReg(XDatum).NE.nint(MissVal)) then if (MissReg(MapRawReg(XDatum)).LE.0) then if (LoadVec(XDatum).NE.FileMissVal) then GotMonth(MapRawReg(XDatum)) = GotMonth(MapRawReg(XDatum)) + LoadVec (XDatum) MissReg(MapRawReg(XDatum)) = MissReg(MapRawReg(XDatum)) - 1 else MissReg(MapRawReg(XDatum)) = 1 end if end if end if end do do XReg = 1, RegN if (MissReg(XReg).LT.0) then if ((MissReg(XReg)+RegSizes(XReg)).EQ.0) then GotMonth(XReg) = GotMonth(XReg) / real(RegSizes(XReg)) else print*, " > ##### ERROR: ExtractMonth: region size mismatch #####" end if else GotMonth(XReg) = MissVal end if end do !*************************************** deallocate (LoadVec) deallocate (MissReg) end subroutine ExtractMonth !******************************************************************************* ! requires use arraymod in main program subroutine ExtractFile (ModelLongN, ModelLatN, ModelDataN, & FilePathThis, FilePathNext, FileStyleThis, FileStyleNext, & RegN, JobMonthN, FileYearN, FileYear0, & MapRawReg, RegSizes, FileBlockKey, GotDecade) integer, pointer, dimension (:,:) :: FileBlockKey integer, pointer, dimension (:) :: MapRawReg, RegSizes real, pointer, dimension (:,:) :: GotDecade ! allocated and dealloc in call,init=here real, pointer, dimension (:) :: GotMonth ! allocated and deallocated here character (len=80), intent (in) :: FilePathThis, FilePathNext integer, intent (in) :: ModelLongN, ModelLatN, ModelDataN, RegN, JobMonthN, FileYearN, FileYear0 integer, intent (in) :: FileStyleThis, FileStyleNext !*************************************** integer, allocatable, dimension (:,:) :: MissDecade integer :: XYear, XMonth, XReg, XRec, XChar integer :: RandomNumber integer :: AllocStat integer :: FileUnit integer :: ReadStatus integer :: ThisSeason ! season/year 1...10 integer :: FileHeaderN, FileRowN, FileColN character (len=80) :: UnZippedDump character (len=80) :: GetFile character (len=10) :: FileFormat character (len=6) :: RandomCha character (len=1) :: UnwantedMonth real :: FileMissVal, RandomReal real, parameter :: MissVal = -999.0 !*************************************** call DefineStyle (FileStyleThis,FileFormat,FileMissVal,FileRowN,FileColN,FileHeaderN) allocate (GotMonth (RegN), stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: Allocation failure #####" GotMonth = 0.0 allocate (MissDecade(RegN,FileYearN), stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: Allocation failure #####" MissDecade = 0 GotDecade = 0.0 ! deliberately initialised to zero, because this is accumulated into UnZippedDump = "blank" open (1, file=FilePathThis, status="old", iostat=ReadStatus) if (ReadStatus .EQ. 0) then close (1) GetFile = FilePathThis else call RandomiseSeed call random_number (RandomReal) RandomNumber = RandomReal * 999999 ! RandomNumber = 1038 ! do XChar = 1, len(trim(adjustr(FilePathThis))) ! RandomNumber = RandomNumber + iachar (FilePathThis(XChar:XChar)) ! end do open (1,file='/cru/u2/f709762/data/scratch/temp.dat',status='replace') write (1,"(I6)"), RandomNumber close (1) open (1,file='/cru/u2/f709762/data/scratch/temp.dat',status='old') read (1,"(A6)"), RandomCha close (1) UnZippedDump = '/cru/u2/f709762/data/scratch/eraseme' // trim(adjustl(RandomCha)) call system ('uncompress -c ' // FilePathThis // ' > ' // UnZippedDump) GetFile = UnZippedDump end if ThisSeason = FileYear0 - 1 FileUnit = 7 open (unit=FileUnit,file=GetFile,status="old",access="sequential",action="read",form="formatted") do XYear = 1, FileYearN do XMonth = 1, 12 if (FileBlockKey(XYear,XMonth) .LE. 0) then do XRec = 1, FileHeaderN read (FileUnit, "(A1)"), UnwantedMonth end do do XRec = 1, FileRowN read (FileUnit, "(A1)"), UnwantedMonth end do end if if (FileBlockKey(XYear,XMonth) .EQ. 1) ThisSeason = ThisSeason + 1 if (FileBlockKey(XYear,XMonth) .GE. 1) then GotMonth = 0.0 call ExtractMonth (FileUnit,FileFormat,FileMissVal,FileRowN,FileColN,FileHeaderN, & ModelDataN,RegN,MapRawReg,RegSizes,GotMonth) if (FileStyleThis.GE.200.AND.FileStyleThis.LE.299) call TemkToTemp (RegN,GotMonth) if (FileStyleThis.GE.300.AND.FileStyleThis.LE.399) call TempTens (RegN,GotMonth) do XReg = 1, RegN if (MissDecade(XReg,ThisSeason).EQ.0) then if (GotMonth(XReg).NE.MissVal) then GotDecade(XReg,ThisSeason) = GotDecade(XReg,ThisSeason) + GotMonth(XReg) else MissDecade(XReg,ThisSeason) = 1 end if end if end do end if if (FileBlockKey(XYear,XMonth) .EQ. 3) then do XReg = 1, RegN if (MissDecade(XReg,ThisSeason).EQ.0) then GotDecade(XReg,ThisSeason) = GotDecade(XReg,ThisSeason) / real(JobMonthN) else GotDecade(XReg,ThisSeason) = MissVal end if end do end if end do end do close (FileUnit) if (UnZippedDump.NE."blank") call system ('rm ' // UnZippedDump) !*************************************** if (FilePathNext.NE."blank") then call DefineStyle (FileStyleNext,FileFormat,FileMissVal,FileRowN,FileColN,FileHeaderN) UnZippedDump = "blank" open (1, file=FilePathNext, status="old", iostat=ReadStatus) if (ReadStatus .EQ. 0) then close (1) GetFile = FilePathNext else RandomNumber = 1123 do XChar = 1, len(trim(adjustr(FilePathNext))) RandomNumber = RandomNumber + iachar (FilePathNext(XChar:Xchar)) end do open (2,file='/cru/u2/f709762/data/scratch/temp.dat',status='replace') write (2,"(I6)"), RandomNumber close (2) open (2,file='/cru/u2/f709762/data/scratch/temp.dat',status='old') read (2,"(A6)"), RandomCha close (2) UnZippedDump = '/cru/u2/f709762/data/scratch/eraseme' // trim(adjustl(RandomCha)) call system ('uncompress -c ' // FilePathNext // ' > ' // UnZippedDump) GetFile = UnZippedDump end if FileUnit = 7 open (unit=FileUnit,file=GetFile,status="old",access="sequential",action="read",form="formatted") do XMonth = 1, 12 if (FileBlockKey(1,XMonth) .LE. -2) then GotMonth = 0.0 call ExtractMonth (FileUnit,FileFormat,FileMissVal,FileRowN,FileColN,FileHeaderN, & ModelDataN,RegN,MapRawReg,RegSizes,GotMonth) if (FileStyleThis.GE.200.AND.FileStyleThis.LE.299) call TemkToTemp (RegN,GotMonth) if (FileStyleThis.GE.300.AND.FileStyleThis.LE.399) call TempTens (RegN,GotMonth) if (MissDecade(XReg,ThisSeason).EQ.0) then if (GotMonth(XReg).NE.MissVal) then GotDecade(XReg,ThisSeason) = GotDecade(XReg,ThisSeason) + GotMonth(XReg) else MissDecade(XReg,ThisSeason) = 1 end if end if end if if (FileBlockKey(1,XMonth) .EQ. -3) then if (MissDecade(XReg,ThisSeason).EQ.0) then GotDecade(XReg,ThisSeason) = GotDecade(XReg,ThisSeason) / real(JobMonthN) else GotDecade(XReg,ThisSeason) = MissVal end if end if end do close (FileUnit) if (UnZippedDump.NE."blank") call system ('rm ' // UnZippedDump) end if !*************************************** deallocate (GotMonth) deallocate (MissDecade) end subroutine ExtractFile !******************************************************************************* end module ExtractMod