; plotcruts.pro ; IDL program written by Tim Mitchell on 07.11.02 pro PlotCRUts, $ DataFile=DataFile, $ FileType=FileType, $ SetDivisor=SetDivisor, $ NoMetaPlot=NoMetaPlot, $ ; remove meta info from plot XSizeMulti=XSizeMulti, $ ; default = 1.0 YSizeMulti=YSizeMulti, $ ; default = 1.0 ForceScale=ForceScale, $ ; 61(absT),62(anoT),63(absP),64(anoP) ForceMin=ForceMin, $ ; force minimum of scale ForceMax=ForceMax, $ ; force maximum of scale Manual=Manual, $ ; set for manual mode ManYear0=ManYear0, $ ; in manual, force first yr of plot to this year AD ManYear1=ManYear1 ; in manual, force last yr of plot to this year AD QManualAuto = 1 if (keyword_set(Manual) or keyword_set(DataFile) or keyword_set(filetype)) then QManualAuto = 0 if not(keyword_set(DataFile)) then DataFile = "" if not(keyword_set(FileType)) then FileType = 1 ; *************************************** intro print, "" print, " > ***** PlotCRUts.pro: plots station from CRU time-series file *****" if (QManualAuto EQ 1) then print, " > ***** AUTOMATIC mode: you many minimise this terminal *****" print, "" Black = 0 & Grey = 254 & White = 255 MissVal = -999.0 & MissCol = White ScaleSegN = 10 & BatchFileN = 0 & GivenYear = 0 & SuspectBreak = -999 InputText = "" & GivenFile = "" & LastDumpText="standard" RangeFract = 0.0D & ColSelect = 0.0D Int0=0L & Int1=0L & Int2=0L & Int3=0L & Int4=0L & Int5=0L Int6=0L & Int7=0L & Int8=0L & Int9=0L & Int10=0L & Int11=0L DumpWMO=0L & DumpName="" & DumpCty="" & DumpYearN=0 & DumpText="" MemYearAD0=-999 & MemYearAD1=-999 & QFound=-1 Months = [0.5,1.5,2.5,3.5,4.5,5.5,6.5,7.5,8.5,9.5,10.5,11.5] XLabel = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'] if (keyword_set(NoMetaPlot)) then begin PlotCorners = [0.10,0.05,0.80,0.95] ScaleCorners = [0.85,0.05,0.95,0.95] endif else begin PlotCorners = [0.10,0.12,0.80,0.88] ScaleCorners = [0.85,0.08,0.95,0.88] endelse XPixels=12 & YPixels=12 if (keyword_set(XSizeMulti)) then XPixels = XPixels * XSizeMulti if (keyword_set(YSizeMulti)) then YPixels = YPixels * YSizeMulti ; *************************************** load CRU ts file if (QManualAuto EQ 1) then begin ; automatic spawn, 'rm /cru/tyn1/f014/scratch/f90toidl.pipe', StOut spawn, 'mkfifo -m a=rw /cru/tyn1/f014/scratch/f90toidl.pipe' spawn, 'tail < /cru/tyn1/f014/scratch/f90toidl.pipe', F90info DataFile = strtrim(F90info(0),2) QNoData = strpos(DataFile,".nrm") if (QNoData GT -1) then begin ; nothing required endif else begin LoadCRUtsHeads, Code,Lat,Lon,Elv,YearAD0,YearAD1,NameStn,NameCty, $ CallFile=DataFile,Data=Data,YearAD=YearAD,TmpPre=TmpPre,Divisor=Divisor endelse endif else begin ; manual QNoData = -1 LoadCRUtsHeads, Code,Lat,Lon,Elv,YearAD0,YearAD1,NameStn,NameCty, $ CallFile=DataFile,Data=Data,YearAD=YearAD,TmpPre=TmpPre,Divisor=Divisor endelse if (QNoData EQ -1) then begin DataSize = size(Data) & YearN = DataSize[3] & MonthN = DataSize[2] & StationN = DataSize[1] endif else begin TmpPre=0 ; Divisor=1.0 endelse if (keyword_set(SetDivisor)) then begin Divisor=SetDivisor & print, " > Divisor set to ", Divisor endif AbsScale=61 & AnoScale=62 & StDevRange=10 if (TmpPre EQ 1) then begin AbsScale=63 & AnoScale=64 & StDevRange=5 endif if (keyword_set(ForceScale)) then begin loadanyct, ForceScale endif else begin loadanyct, AbsScale endelse DumpMissVal = -9999.0/Divisor ; *************************************** main station loop QCode=-1L ;QCode = -1L & on_ioerror, badIO ;badIO: if (QCode NE -1L) then print, " > Bad input. Try again." while (QCode NE 99) do begin if (QManualAuto EQ 0) then begin read, prompt="Code (99=exit):", QCode ; get station code QSetYears=1 endif else begin spawn, 'tail < /cru/tyn1/f014/scratch/f90toidl.pipe', F90info QCode = long(strtrim(F90info(0),2)) print, "" print, "QCode = ", QCode if (QCode EQ 88) then begin spawn, 'tail < /cru/tyn1/f014/scratch/f90toidl.pipe', F90info ; get file path DumpFile = strtrim(F90info(0),2) print, "file = ", strtrim(DumpFile,2) spawn, 'tail < /cru/tyn1/f014/scratch/f90toidl.pipe', F90info ; get file path QSetYears = long(strtrim(F90info(0),2)) print, "range = ", QSetYears endif else if (QCode NE 99) then begin spawn, 'tail < /cru/tyn1/f014/scratch/f90toidl.pipe', F90info ; get break year SuspectBreak = long(strtrim(F90info(0),2)) print, "year = ", SuspectBreak QSetYears = 1 endif endelse if (QCode NE 99) then begin if (QCode NE 88) then begin XStation = -1 & QFound = -1 while (QFound EQ -1 AND XStation LT StationN-1) do begin ; locate station XStation = XStation + 1 if (Code(XStation) EQ QCode) then QFound = XStation endwhile if (QFound EQ -1) then begin print, " > Station not found. Try again." endif else begin ; XYear0 = YearAD0(QFound)-YearAD(0) & XYear1 = YearAD1(QFound)-YearAD(0) LastQFound = QFound if (keyword_set(ManYear0)) then begin PlotYearAD0=ManYear0 & XYear0 = ManYear0-YearAD(0) endif else begin PlotYearAD0=YearAD0(QFound) & XYear0 = YearAD0(QFound)-YearAD(0) endelse if (keyword_set(ManYear1)) then begin PlotYearAD1=ManYear1 & XYear1 = ManYear1-YearAD(0) endif else begin PlotYearAD1=YearAD1(QFound) & XYear1 = YearAD1(QFound)-YearAD(0) endelse print, "Adopting range: ", PlotYearAD0,PlotYearAD1 endelse endif else begin ; load station data openr, lunDump, DumpFile, /get_lun readf, lunDump, DumpWMO, DumpName, DumpCty, DumpYearN, DumpText, format="(i8,x,a20,x,a13,x,i4,x,a8)" DumpData=fltarr(12,DumpYearN) & DumpData(*,*)=DumpMissVal & DumpYearAD=intarr(DumpYearN) for XDumpYear = 0, DumpYearN-1 do begin readf, lunDump, HYear,Int0,Int1,Int2,Int3,Int4,Int5,Int6,Int7,Int8,Int9,Int10,Int11, format="(i4,12i5)" DumpYearAD(XDumpYear)=HYear DumpData(0,XDumpYear)=float(Int0)/Divisor & DumpData(1,XDumpYear)=float(Int1)/Divisor & DumpData(2,XDumpYear)=float(Int2)/Divisor DumpData(3,XDumpYear)=float(Int3)/Divisor & DumpData(4,XDumpYear)=float(Int4)/Divisor & DumpData(5,XDumpYear)=float(Int5)/Divisor DumpData(6,XDumpYear)=float(Int6)/Divisor & DumpData(7,XDumpYear)=float(Int7)/Divisor & DumpData(8,XDumpYear)=float(Int8)/Divisor DumpData(9,XDumpYear)=float(Int9)/Divisor & DumpData(10,XDumpYear)=float(Int10)/Divisor & DumpData(11,XDumpYear)=float(Int11)/Divisor endfor free_lun, lunDump if (Divisor NE 10.0 AND (DumpText EQ "Homogeno" OR strmid(DumpText,4,4) EQ "Diff")) then begin print, "Correcting for non-standard multiplier" DumpData = DumpData * 10.0 Missings = where (DumpData EQ (DumpMissVal*10.0)) DumpData(Missings) = DumpMissVal endif if (MemYearAD0 EQ -999 OR QSetYears GE 0) then begin XYear0 = 100000000 for XDumpYear = 0, DumpYearN-1 do begin for XMonth = 0, 11 do begin if (XYear0 GT XDumpYear AND DumpData(XMonth,XDumpYear) NE DumpMissVal) then XYear0 = XDumpYear endfor endfor XYear1 = -100000000 for XDumpYear = DumpYearN-1, 0, -1 do begin for XMonth = 0, 11 do begin if (XYear1 LT XDumpYear AND DumpData(XMonth,XDumpYear) NE DumpMissVal) then XYear1 = XDumpYear endfor endfor if (XYear0 NE 100000000) then begin PlotYearAD0=DumpYearAD(XYear0) & PlotYearAD1=DumpYearAD(XYear1) print, "Adopting implicit range: ", DumpYearAD(XYear0),DumpYearAD(XYear1) endif else begin XYear1=XYear0 endelse endif else begin ; QSetYears=-1 XYear0=0 & XYear1=DumpYearN-1 for XDumpYear = 0, DumpYearN-1 do begin if (DumpYearAD(XDumpYear) EQ MemYearAD0) then XYear0=XDumpYear if (DumpYearAD(XDumpYear) EQ MemYearAD1) then XYear1=XDumpYear endfor PlotYearAD0=MemYearAD0 & PlotYearAD1=MemYearAD1 print, "Adopting memorised range: ", MemYearAD0,MemYearAD1 endelse Missings = where (DumpData EQ DumpMissVal, Count) if (Count GT 0) then DumpData [Missings] = !Values.F_NaN endelse endif if ((QCode EQ 88 OR (QCode NE 99 AND QFound NE -1))) then begin if (XYear1 GT XYear0) then begin if (QCode EQ 88) then begin Reformed = reform(DumpData(*,XYear0:XYear1)) if (strtrim(DumpText,2) EQ 'Homogeno') then begin DataMin = 0-StDevRange & DataMax = StDevRange endif else if (strmid(DumpText,4,4) EQ 'Diff') then begin DataMin = 0-(StDevRange*2) & DataMax = (StDevRange*2) endif else if (strtrim(DumpText,2) EQ 'Rev-Orig') then begin DataMin=OrigDataMin & DataMax=OrigDataMax endif else if (strmid(DumpText,4,4) EQ 'Orig' AND $ strmid(LastDumpText,4,4) EQ 'Comb') then begin DataMin=OrigDataMin & DataMax=OrigDataMax endif else if (strmid(DumpText,0,4) EQ 'Anom') then begin DataMax = max(abs(Reformed), /nan) & DataMin = 0-DataMax endif else begin if (TmpPre EQ 0) then begin DataMin = min(Reformed,max=DataMax, /nan) endif else begin Moments = moment(Reformed,/nan) DataMin = Moments(0)-(2.0*sqrt(Moments(1))) DataMax = Moments(0)+(2.0*sqrt(Moments(1))) if (DataMin LT 0) then DataMin=0 endelse OrigDataMin=DataMin & OrigDataMax=DataMax endelse Years = DumpYearAD(XYear0:XYear1) PlotTitle = strtrim(DumpName,2) + ' (' + strtrim(DumpCty,2) + ', ' + $ strtrim(string(DumpWMO),2) + ')' SavePath = '/cru/tyn1/f014/scratch/plotcruts.' + strtrim(string(DumpText),2) $ + '.' + strtrim(string(DumpWMO),2) + '.eps' endif else begin Reformed = reform(Data(QFound,*,XYear0:XYear1)) if (TmpPre EQ 0) then begin DataMin = min(Reformed,max=DataMax, /nan) endif else begin Moments = moment(Reformed,/nan) DataMin = Moments(0)-(2.0*sqrt(Moments(1))) DataMax = Moments(0)+(2.0*sqrt(Moments(1))) if (DataMin LT 0) then DataMin=0 endelse Years = YearAD(XYear0:XYear1) PlotTitle = strtrim(NameStn(QFound),2) + ' (' + strtrim(NameCty(QFound),2) + ', ' + $ strtrim(string(QCode),2) + ')' DumpText='Raw-Orig' SavePath = '/cru/tyn1/f014/scratch/plotcruts.Original.' + strtrim(string(QCode),2) + '.eps' endelse if (QSetYears EQ 1) then begin ; set memory MemYearAD0 = PlotYearAD0 & MemYearAD1 = PlotYearAD1 print, "Memorising range: ", MemYearAD0,MemYearAD1 endif YearADFlt = float(Years)/10.0 YearADInt = round(YearADFlt) YTickVal = where (float(YearADInt) EQ YearADFlt, YTickCount) YearADInt = YearADInt * 10 if (ytickcount eq 0) then begin ; no decade data range, do start/end instead YearADInt = Years YearADIntDim = size (YearADInt) ytickcount = 2 ytickval = intarr(ytickcount) ytickval(*) = [0,YearADIntDim[1]-1] endif if (not keyword_set(ForceScale) and (strtrim(DumpText,2) EQ 'Homogeno' OR strmid(DumpText,4,4) EQ 'Diff' OR $ strtrim(DumpText,2) EQ 'Anomalys')) then loadanyct, AnoScale if (keyword_set(ForceMin)) then DataMin = ForceMin if (keyword_set(ForceMax)) then DataMax = ForceMax GetContours, [DataMin,DataMax], [1,253], Contours, ContourColors, 21 ContoursSparse = fltarr(5) for XSparse = 0, 4 do begin ContoursSparse(XSparse) = DataMin + (XSparse * ((DataMax-DataMin) / 4)) endfor TrimToScale, Reformed, TrimSlice, [DataMin,DataMax], /SinglePrec Set_Plot, 'ps', /copy device, filename=SavePath, bits_per_pixel=8, xsize=XPixels, ysize=YPixels,/Color,/encapsulated if (keyword_set(NoMetaPlot)) then begin plot, [PlotYearAD0,PlotYearAD1], xrange=[0.5,11.5], yrange=[PlotYearAD0,PlotYearAD1], position=PlotCorners, $ ticklen=1.0,color=Black,/noerase,/nodata,charsize=0.8, $ xstyle=1, xticks=11, xthick=1, xtickv=months, xtickname=xlabel, font=5, $ ystyle=1, yticks=YTickCount-1, ythick=1, ytickv=YearADInt[YTickVal] endif else begin plot, [PlotYearAD0,PlotYearAD1], xrange=[0.5,11.5], yrange=[PlotYearAD0,PlotYearAD1], position=PlotCorners, $ ticklen=1.0,color=Black,/noerase,/nodata,subtitle=PlotTitle,title=DumpText,charsize=0.8, $ xstyle=1, xticks=11, xthick=1, xtickv=months, xtickname=xlabel, font=5, $ ystyle=1, yticks=YTickCount-1, ythick=1, ytickv=YearADInt[YTickVal] endelse contour, TrimSlice, Months, Years, levels=Contours, $ c_colors=ContourColors, /cell_fill, /overplot,/noerase if (keyword_set(NoMetaPlot)) then begin plot, [PlotYearAD0,PlotYearAD1], xrange=[0.5,11.5], yrange=[PlotYearAD0,PlotYearAD1], position=PlotCorners, $ ticklen=1.0,color=Black,/noerase,/nodata,charsize=0.8, $ xstyle=1, xticks=11, xthick=1, xtickv=months, xtickname=xlabel, font=5, $ ystyle=1, yticks=YTickCount-1, ythick=1, ytickv=YearADInt[YTickVal] endif else begin plot, [PlotYearAD0,PlotYearAD1], xrange=[0.5,11.5], yrange=[PlotYearAD0,PlotYearAD1], position=PlotCorners, $ ticklen=1.0,color=Black,/noerase,/nodata,subtitle=PlotTitle,title=DumpText,charsize=0.8, $ xstyle=1, xticks=11, xthick=1, xtickv=months, xtickname=xlabel, font=5, $ ystyle=1, yticks=YTickCount-1, ythick=1, ytickv=YearADInt[YTickVal] endelse if (SuspectBreak NE -999) then plots, [0.5,11.5], [SuspectBreak+0.5,SuspectBreak+0.5], $ linestyle=1, color=Black DrawConScale,ScaleCorners,Contours,ContourColors,$ ContoursSparse,"(f7.2)",0.8,1,"",XPixels,YPixels,0 device, /close set_plot, 'X' if (not keyword_set(ForceScale) and (strtrim(DumpText,2) EQ 'Homogeno' OR strmid(DumpText,4,4) EQ 'Diff' OR $ strtrim(DumpText,2) EQ 'Anomalys')) then loadanyct, AbsScale LastDumpText=DumpText & DumpText="standard" GVcommand = 'ghostview ' + strtrim(SavePath,2) + ' &' spawn, GVcommand, StOutText endif else begin print, "Insufficiently long period for plot." endelse endif endwhile ; *************************************** end print, "" if (QManualAuto EQ 1) then spawn, 'rm /cru/tyn1/f014/scratch/f90toidl.pipe' spawn, 'rm /cru/tyn1/f014/scratch/plotcruts*' spawn, 'rm /cru/tyn1/f014/scratch/??????.*.txt' end