FTN77 $FILES 1,2 Program MAPR3 (1,10) C ============= C C Make a map of the sun/moon/etc using the PC-Steer control system. C C USAGE: XQ MAPR3 C C where: is the LU of the log terminal C is the object to be mapped C is <>0 to suppress the plotter C C C MODIFICATIONS : 1992-04-29 JQ C * Now assumes a certain PC-Steer Feed System C arrangement in SysName, NDcode, DScode, TND C Tilted etc. and performs automatic setup C accordingly. C * Checks consistency of Feed System definition C against PC-Steer and also compares clocks. C * Will run to System console by default but can be C set to the Esprit by typing XQ,SUN6,7 C C 1992-06-25 JQ C * Now suggests more intelligent defaults for scan C spacing and rate for each Feed system. C * The map need no longer be square and the centre C may also be offset in both Ecliptic Long and Lat. C * PC-Steer Errors now cause the program to suspend C and ask for user intervention. C C EXTENDED VERSION 1993-02-16 JQ SUN7 -> MAPR1 C * Extended to allow mapping of objects other than C the Sun, in particular the Moon. C C 1993-03-18 JQ MAPR1 -> MAPR2 C * Now saves and retrieves all suitable parameters C in/from parameter file MAPPRM::16, which is C created but not maintained internally. C C 1994-03-16 JQ MAPR2 -> MAPR3 C * Now estimates ecliptic longitude tracking errors C and outputs real track number including rough C average longitude built in. C C 1994-03-28 JQ C * Now scans in opposite direction in ecliptic coords C during first six months of year to reduce HA scanning C effects C C 1995-06-30 JQ C * Added a second IPRAM which suppresses use of the C HP9872S plotter when non zero C C 1997-03-07 JQ C * Now allows differing scan & bin spacings C Implicit None C C Remember to update DATA statements below if MaxSys or Other is changed C Integer Direction, MaxSys, MaxBin, Sun, Moon, Other, NCHAR C Parameter ( MaxSys=10 , MaxBin=1001, Sun=1, Moon=2, Other=3 ) C Logical Tilted(MaxSys), FilExist, FAULT, Found, LEAPYR, * Plot C Character SysName(MaxSys)*14, Reply*166, junk*1, FILNAM*10, * SysonPC*14, Names(Other)*15, FILPRE(Other)*2, * Coordtype*10, Long*5, Lat*5, Answer, Today*9, * Tomorrow*9, Type*15 C Integer*2 IPRAM(5), ITIME(5), IYEAR, UThrs, UTmin, UTsec C Integer Ad, Am, As, UNcmd(2), Lbuf(500), AntennaLU, FLukeLU, * PlotLU, FeedSys, Nscan, iscan, Count(MaxBin), Nsys, * NDcode(MaxSys), DScode(MaxSys), I, Nfile, iSrate, * ISWIT, SWIN, Istat, Nbins, Object, DyTm, YrTm C Real Atoday, Atomorrow, ScanRate, SpacLat, A0obj, A1obj, * DeltaT, Tscale, Zscale, Out(MaxBin), DVMmax, Base, * FOCUS, TILT, Rdvm, TND(MaxSys), FracDay, SizeLong, * SizeLat, A0off, B0off, SpacDef(MaxSys), a(6), b(6), * p(5), B0obj, Prlax, Old_DeltaT, ScanLong(MaxBin), * SpacLong C Double Precision MJDPC, MJDHP C Data AntennaLU /39/, FlukeLU /35/, PlotLU /31/ C C Feed System names : must agree with those in PC-STEER C Data SysName / '2.5cm Single ', '3.6cm Beam A ', * '3.6cm Beam B ', '4.5cm Single ', * '6.0cm Beam A ', '6.0cm Beam B ', * '6.0cm Single ', '13.0cm Single ', * '18.0cm Single ', '18.0cm Untilt ' / C C Noise Diode select codes to be output to DIO channel 3 C Data NDcode / 2, 1, 1, 2, 3, 3, 2, 4, 5, 5 / C C DVM select codes to be output to DIO channal 5 C Data DScode / 6, 1, 1, 6, 3, 3, 3, 5, 7, 7 / C C Equivalent Temperature of Noise Diodes in Kelvin C Data TND / 158.0, 10.0, 10.0, 82.0, 1.54, * 1.54, 16.0, 3.96, 33.0, 33.0 / C C Required Sub-Reflector position i.e. Tilted ? Y/N C Data Tilted / .FALSE., .FALSE., .FALSE., .FALSE., * .FALSE., .FALSE., .FALSE., .FALSE., * .FALSE., .TRUE. / C C Suitable scan spacing ( approximately FWHM/2 of beam ) C Data SpacDef / 0.030, 0.050, 0.050, 0.060, 0.080, * 0.080, 0.080, 0.160, 0.250, 0.250 / C C Total Number of usable Feed Systems C Data Nsys / 10 / C C Default output filename ( 000 replaced by Day Number ) C Data FILNAM / ' 000A::15' /, * FILPRE / 'SU', 'MN', 'OB' /, * Today / 'd000,0000' /, * Tomorrow / 'd000,0000' / C C Object Descriptors ( Another object replaced later ) C Data Names / 'The Sun ', * 'The Moon ', * 'Another object ' / C Call LGBUF (Lbuf,250) C C recall system console LU from parameter list. Defaults to 1 C Call RMPAR (IPRAM) Call FSYSU (IPRAM(1),IPRAM(1)) Object = IPRAM(2) Plot = (IPRAM(3).EQ.0) Print '(a)',CHAR(12) C C check PC vs HP clock and obtain Day Number and Year C Call EXEC (11,ITIME,IYEAR) Read (AntennaLU,'(27x,f13.6)') MJDPC Call UNLT Call MJDAY (IYEAR,ITIME,MJDHP) C If ( DABS(MJDPC-MJDHP) .gt. 0.58D-5 ) then C C clocks differ by more than half a second - warn user C Print *,' ' Print *,'!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!' Print *,'!!! PC-STEER & HP1000 Clocks do not agree !!!' Print *,'!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!' Print *,' ' endif C Print '(" General Purpose Mapping Program MAPR3 Day ",I3.3, * ", ",I4)', ITIME(5), IYEAR Print *, '===================================================' Print *, ' Version <970701.1101>' If (Plot) then Print *, 'The HP9872S Plotter MUST be connected to the HPIB' Print *, ' of the CONTROL computer during this program.' else Print *,'Use of HP9872S Plotter disabled for this run' endif Print *, ' ' Print *, 'Ephemeris Ref : "The Astronomical Almanac" Sec. C,D&K' Print *, ' ' C 10101 If (Object .gt. 0 .and. Object .le. Other) go to 20202 Object = Sun Print *, ' ' Print *, 'Available Targets for mapping :' Print *, ' ' DO I=1,Other/2*2,2 Print *,I,' : ',Names(I),' ',I+1,' : ',Names(I+1) enddo If (Other/2*2 .lt. Other) * Print *,Other,' : ',Names(Other) Print *, ' ' Print *,'Enter Object (1-',Other,' / =',Object,'): _' Read *, Object GO TO 10101 C 20202 If (Object .eq. Other) then Print *, ' ' Print *, 'Enter Object Name ( 15 chars ): _' Read '(a15)', Names(Object) endif C C set up default file name using Day Number and Object Prefix C Write (FILNAM(1:2),'(A2)') FILPRE(Object) Write (FILNAM(3:5),'(I3.3)') ITIME(5) C DyTm = ITIME(5) + 1 YrTm = IYEAR If ( (.not. LEAPYR(IYEAR) .and. DyTm .gt. 365) * .OR. (DyTm.GT.366) ) then DyTm = 1 YrTm = IYEAR + 1 endif Write (Today(2:4),'(I3.3)') ITIME(5) Write (Today(6:9),'(I4.4)') IYEAR Write (Tomorrow(2:4),'(I3.3)') DyTm Write (Tomorrow(6:9),'(I4.4)') YrTm C Print *, ' ' Print *, 'Mapping ', Names(Object) C C Default direction is as before C Direction = 1 C If (Object .eq. Sun ) then C Coordtype = 'Ecliptic' Long = 'Long.' Lat = 'Lat. ' C Call Set_Type ( Type, 'SUN', Coordtype, Long ) C Print *, ' ' Call Get_Parm ( Type, ITIME(5), IYEAR, 1, Atoday, Found ) If ( Found ) then Print *, 'Eclip. Long. of Sun at 0h DT today ', * Today, ' = _' Print '(F9.5)', Atoday else Print *, 'Enter Eclip. Long. of Sun for 0h DT today ', * Today, ' (dd mm ss): _' Read *, Ad, Am, As Atoday = Ad + Am / 60.0 + As / 3600.0 Call Put_Parm ( Type, ITIME(5), IYEAR, 1, Atoday ) endif C Print *, ' ' Call Get_Parm ( Type, DyTm, YrTm, 1, Atomorrow, Found ) If ( Found ) then Print *, 'Eclip. Long. of Sun at 0h DT tomorrow ', * Tomorrow, ' = _' Print '(F9.5)', Atomorrow else Print *, 'Enter Eclip. Long. of Sun for 0h DT tomorrow ', * Tomorrow, ': _' Read *, Ad, Am, As Atomorrow = Ad + Am / 60.0 + As / 3600.0 Call Put_Parm ( Type, DyTm, YrTm, 1, Atomorrow ) endif C B0obj = 0.0 Prlax = 0.0 C C If DOY < 174 ie. before 23 June, reverse scanning direction C Direction = -1 C elseif (Object .eq. Moon) then C Coordtype = 'Apparent' Long = 'RA ' Lat = 'DEC' C Call Set_Type ( Type, 'MOON', CoordType, Long ) C Print *, ' ' Call Get_Parm ( Type, ITIME(5), IYEAR, 6, a, Found ) If ( Found ) then Print *, 'RA poly. coef. of Moon today ',Today,' are :' Write (*,'(5(2X,F11.7,/),2X,F11.7)') (a(I),I=1,6) else Print *, 'Enter RA poly. coef. of Moon for today ', * Today, ' : _' Read *, (a(I),I=1,6) Call Put_Parm ( Type, ITIME(5), IYEAR, 6, a ) endif C Call Set_Type ( Type, 'MOON', CoordType, Lat ) C Print *, ' ' Call Get_Parm ( Type, ITIME(5), IYEAR, 6, b, Found ) If ( Found ) then Print *, 'DEC poly. coef. of Moon today ',Today,' are :' Write (*,'(5(2X,F11.7,/),2X,F11.7)') (b(I),I=1,6) else Print *, 'Enter DEC poly. coef. of Moon for today ', * Today, ' : _' Read *, (b(I),I=1,6) Call Put_Parm ( Type, ITIME(5), IYEAR, 6, b ) endif C Call Set_Type ( Type, 'MOON', CoordType, 'PRLX' ) C Print *, ' ' Call Get_Parm ( Type, ITIME(5), IYEAR, 5, p, Found ) If ( Found ) then Print *, 'Parallax poly. coef. for today ',Today,' are :' Write (*,'(4(4X,F10.8,/),4X,F10.8)') (p(I),I=1,5) else Print *, 'Enter Parallax poly. coef. for today ', * Today, ' : _' Read *, (p(I),I=1,5) Call Put_Parm ( Type, ITIME(5), IYEAR, 5, p ) endif C else C 30303 Print *, ' ' Print *, 'Enter Co-ord Type : (G)alactic, (B)1950, (M)ean ', * 'or (J)2000: _' Read *, Answer Call Upcase(Answer) If (INDEX('GBMJ',Answer) .eq. 0) go to 30303 C If (Answer .eq. 'G') then Coordtype = 'Galactic' Long = 'Long.' Lat = 'Lat. ' elseif (Answer .eq. 'B') then Coordtype = 'B1950' Long = 'RA ' Lat = 'DEC' elseif (Answer .eq. 'M') then Coordtype = 'Mean' Long = 'RA ' Lat = 'DEC' elseif (Answer .eq. 'J') then Coordtype = 'J2000' Long = 'RA ' Lat = 'DEC' endif C Print *, ' ' Print *, 'Enter ', CoordType(1:NCHAR(Coordtype)), * ' ', Long(1:NCHAR(Long)), * ' of ',Names(Object)(1:NCHAR(Names(Object))),'_' If (Long .eq. 'RA ') then Print *, '(hh mm ss): _' else Print *, '(dd mm ss): _' endif Read *, Ad, Am, As A0obj = Ad + Am / 60.0 + As / 3600.0 If (Long .eq. 'RA ') A0obj = 15.0 * A0obj C Print *, ' ' Print *, 'Enter ', Coordtype(1:NCHAR(Coordtype)), * ' ', Lat(1:NCHAR(Lat)), * ' of ',Names(Object)(1:NCHAR(Names(Object))), * ' (dd mm ss): _' Read *, Ad, Am, As B0obj = Ad + Am / 60.0 + As / 3600.0 C Prlax = 0.0 C endif C Print *, ' ' Call Get_Parm ( 'TAI-UTC', 0, IYEAR, 1, Old_DeltaT, Found ) If (Found) then DeltaT = Old_DeltaT Print '(1X,"Enter the difference TAI-UTC from page K9 ", * "( / = ",I2," ): _")', INT(DeltaT) Read *, DeltaT Found = (Old_DeltaT .eq. DeltaT) else DeltaT = 0.0 Print *, 'Enter the difference TAI-UTC from page K9: _' Read *, DeltaT endif If (.not. Found) * Call Put_Parm ( 'TAI-UTC', ITIME(5), IYEAR, 1, DeltaT ) C C Allow for 32.184s offset between TAI and TDT of ephemerides C DeltaT = DeltaT + 32.184 C 40404 FeedSys = 1 Print *, ' ' Print *, 'PC-Steer Feed systems as implemented here :' Print *, ' ' DO I=1,Nsys/2*2,2 Print *,I,' : ',SysName(I),' ',I+1,' : ',SysName(I+1) enddo If (Nsys/2*2 .lt. Nsys) * Print *,Nsys,' : ',SysName(Nsys) Print *, ' ' Print *, 'Enter Feed System (1-8 / =',FeedSys,'): _' Read *, FeedSys If (FeedSys .le. 0 .or. FeedSys .gt. Nsys) go to 40404 C C check subreflector position C FAULT = .FALSE. CALL RHYP (FOCUS, TILT) If (.not. Tilted(FeedSys)) then If ( FOCUS .lt. 7.4 ) then PRINT *,' ' PRINT *,'Hyperbola focus = ',FOCUS,' not 8.0' FAULT = .TRUE. endif If ( TILT .gt. -0.5 ) then PRINT *,' ' PRINT *,'Hyperbola tilt = ',TILT,' not -0.66' FAULT = .TRUE. endif else If ( FOCUS .gt. 5.1 ) then PRINT *,' ' PRINT *,'Hyperbola focus = ',FOCUS,' not 5.0' FAULT = .TRUE. endif If ( TILT .lt. 9.7 ) then PRINT *,' ' PRINT *,'Hyperbola tilt = ',TILT,' not 9.80' FAULT = .TRUE. endif endif If (FAULT) goto 40404 C SizeLong = 1.0 Print *, ' ' Print '(1X,"Enter Map Size in ",A," ",A," (deg / = ",F4.2, * "): _")', Coordtype(1:NCHAR(Coordtype)), * Long(1:NCHAR(Long)), SizeLong Read *, SizeLong C SizeLat = SizeLong Print *, ' ' Print '(1X,"Enter Map Size in ",A," ",A," (deg / = ",F4.2, * "): _")', Coordtype(1:NCHAR(Coordtype)), * Lat(1:NCHAR(Lat)), SizeLat Read *, SizeLat C A0off = 0.0 Print *, ' ' Print '(1X,"Enter Map Centre ",A," offset (deg / = ",F4.2, * "): _")', Long(1:NCHAR(Long)), A0off Read *, A0off C B0off = 0.0 Print *, ' ' Print '(1X,"Enter Map Centre ",A," offset (deg / = ",F4.2, * "): _")', Lat(1:NCHAR(Lat)), B0off Read *, B0off C SpacLong = SpacDef(FeedSys) Print *, ' ' Print '(1X,"Enter Scan Spacing (deg / = ",F4.3,"): _")',SpacLong Read *, SpacLong C SpacLat=SpacLong Print *, ' ' Print '(1X,"Enter Bin Spacing (deg /= ",F4.3,"): _")',SpacLat Read *, SpacLat C ScanRate = SpacLat * 1.2 Print *, ' ' Print '(1X,"Enter Scan Rate (deg/sec / = ",F4.3, * "): _")',ScanRate Read *, ScanRate C Zscale = 7.5 Print *, ' ' Print *, 'Enter central height (cm / =',Zscale,'): _' Read *, Zscale C C convert to Plot-Units ( normalised to sun after calibration ) C Zscale = Zscale * 400.0 C C set Fluke to required sample rate C iSrate = 1 Print *, ' ' Print *,'Enter DVM sampling rate ( 0=S, 1=M, 2=F, / =',iSrate, * '): _' Read *, iSrate Write (FlukeLU,'(a,i1)') '*S',iSrate C C select DVM inputs according to FeedSys C Call EXEC (2, 113B, DScode(FeedSys)*11B, 1, 5, 5) Call EXEC (12,0,2,0,-1) C C kill the TEMPS program if it is running C Call MESSS (10HOF,TEMPS,1,10) C Nscan = (Nint(SizeLong / SpacLong) / 2) * 2 + 1 SizeLong = SpacLong * (Nscan - 1) Nbins = (Nint(SizeLat / SpacLat) / 2) * 2 + 1 If (Nbins .gt. MaxBin) then Print *,' ' Print *,'!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!' Print *,'!!! Nbins >',MaxBin,' : Latitude size corrected !!' Print *,'!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!' Print *,' ' Nbins=MaxBin endif SizeLat = SpacLat * (Nbins - 1) C C calculate co-ordinates of required object C Read (AntennaLU,'(27x,f13.6)') MJDPC Call UNLT FracDay = Dmod(MJDPC,1.0D0) + DeltaT/86400.0 If (Object .eq. Sun) then C If (Atomorrow .lt. Atoday) Atomorrow = Atomorrow + 360.0 A1obj = (Atomorrow - Atoday) / 86400.0 A0obj = Atoday + FracDay * A1obj * 86400.0 C elseif (Object .eq. Moon) then C A0obj = ((((a(6)+FracDay+a(5))*FracDay+a(4))*FracDay+a(3)) * *FracDay+a(2))*FracDay+a(1) B0obj = ((((b(6)*FracDay+b(5))*FracDay+b(4))*FracDay+b(3)) * *FracDay+b(2))*FracDay+b(1) Prlax = (((p(5)*FracDay+p(4))*FracDay+p(3))*FracDay+p(2)) * *FracDay+p(1) C endif C C drive to calculated position of object ( Note : no Centre offset ) C Write (AntennaLU,'(a)') 'Begin FindObj' Write (AntennaLU,'(a)') 'Clear_Fifo' Write (AntennaLU,'(a)') 'Duration 900' Write (AntennaLU,'(a," ",a)') 'Coordinate_System', Coordtype Write (AntennaLU,'(a)') 'Pointing On' Write (AntennaLU,'(a,i2)') 'Feed_System ', FeedSys Write (AntennaLU,'(a)') 'A0 0.0' Write (AntennaLU,'(a)') 'A1 0.0' Write (AntennaLU,'(a)') 'B0 0.0' Write (AntennaLU,'(a)') 'B1 0.0' Write (AntennaLU,'(a,f7.3)') 'Psi ', A0obj Write (AntennaLU,'(a,f7.3)') 'Phi ',-B0obj Write (AntennaLU,'(a)') 'Theta 0.0' Write (AntennaLU,'(a,f7.3)') 'Parallax ', Prlax Write (AntennaLU,'(a)') 'End' Call UNLT C Print *, ' ' Print *, 'Driving to ',Names(Object)(1:NCHAR(Names(Object))), * ' .....' C C check PC Selected Feed System Name against internal name C Read (AntennaLU,'(40x,a14)') SysonPC Call UNLT If (SysonPC .ne. SysName(FeedSys)) then C C PC-STEER Feed name differs from internal - warn user C Print *,' ' Print *,'!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!' Print *,'!!! PC-STEER Feed System list inconsistent !!!' Print *,'!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!' Print *,' ' endif C C dither till PC-STEER is 'On Source' or an error occurs C 1 Call EXEC (12,0,2,0,-3) Read (AntennaLU,'(a)') Reply Call UNLT If (Reply(1:1) .eq. '1') goto 1 C If (Reply(1:1) .ne. '0') then read (Reply,'(I1)') Istat call ERROR (Istat,FAULT) If (FAULT) goto 999 goto 1 endif C Print *, ' ' Print *, 'Tracking Source, Adjust radiometer attenuation' Print *, 'Press RETURN when ready: _' Read (*,'(a)') junk C C ensure that all noise diodes are turned off C Call EXEC(2,113B,0,1,3,3) Call EXEC(12,0,2,0,-2) C C sample signal peak on the source for scaling purposes C Read (FlukeLU,*) DVMmax C Do iscan = -(Nscan/2) , +(Nscan/2) C C recalculate co-ordinates of Object for present time C Read (AntennaLU,'(27x,f13.6)') MJDPC Call UNLT FracDay = Dmod(MJDPC,1.0D0) + DeltaT/86400.0 UThrs = INT( Dmod(MJDPC,1.0D0)*24.0 ) UTmin = INT( (Dmod(MJDPC,1.0D0)*24.0-UThrs)*60.0 ) UTsec = INT(((Dmod(MJDPC,1.0D0)*24.0-UThrs)*60.0-UTmin)*60.0) If (Object .eq. Sun) then C A0obj = Atoday + FracDay * A1obj * 86400.0 C elseif (Object .eq. Moon) then C A0obj = ((((a(6)+FracDay+a(5))*FracDay+a(4))*FracDay+a(3)) * *FracDay+a(2))*FracDay+a(1) B0obj = ((((b(6)*FracDay+b(5))*FracDay+b(4))*FracDay+b(3)) * *FracDay+b(2))*FracDay+b(1) Prlax = (((p(5)*FracDay+p(4))*FracDay+p(3))*FracDay+p(2)) * *FracDay+p(1) C endif C C drive to start of next scan ( Map centre offset from Object ) C Write (AntennaLU,'(a,i2.2)') 'Begin Start', iscan+Nscan/2+1 Write (AntennaLU,'(a)') 'Duration 400' Write (AntennaLU,'(a,f7.3)') 'Psi ', A0obj + A0off Write (AntennaLU,'(a,f7.3)') 'Phi ',-B0obj - B0off Write (AntennaLU,'(a,f7.3)') 'Parallax ', Prlax Write (AntennaLU,'(a,f7.3)') 'A0 ', SpacLong*iscan Write (AntennaLU,'(a,f7.3)') 'B0 ', -Direction*SizeLat / 2.0 Write (antennaLU,'(a)') 'B1 0.0' Write (AntennaLU,'(a)') 'End' Call UNLT Print *,' ' Print *,'Driving to scan',iscan+Nscan/2+1,'_' Print '(3X,I2,2(":",I2.2)," ... _" )', UThrs, UTmin, UTsec C If (iscan .ne. (-Nscan/2)) then C C plot and write to disc the previous scan C CALL OutScan (iscan-1, Nscan, Nbins, Tscale, Zscale, * SpacLong, Out, ScanLong, Count, Plot) else If (Plot) then C C set up the plotter C Write (PlotLU,'("in;")') Write (PlotLU,'("sp 1;pu;pa 4000,10000")') Write (PlotLU,'("si 1.5,1.5;lb ",a,a)') * Names(Object)(1:NCHAR(Names(Object))), Char(3) Write (PlotLU,'(";pu;pa 400,2500")') Write (PlotLU,'("si 0.2,0.3;lb Using ",4a)') * SysName(FeedSys), Char(10), Char(13), Char(3) Write (PlotLU,'("lb Map Size ",F3.1," by ",F3.1," deg",3a)') * SizeLong, SizeLat, Char(10), Char(13), Char(3) Write (PlotLU,'("lb Scan Spacing ",F5.3," deg",3a)') * SpacLong, Char(10), Char(13), Char(3) Write (PlotLU,'("lb Bin Spacing ",F5.3," deg",3a)') * SpacLat, Char(10), Char(13), Char(3) Write (PlotLU,'("lb Scan Rate ",F5.3," deg/s",3a)') * ScanRate, Char(10), Char(13), Char(3) If (UThrs .lt. 10) then Write (PlotLU,'("lb ",I1,2(":",I2.2)," Day ",I3.3,I5,3a)') * UThrs, UTmin, UTsec, ITIME(5), IYEAR, Char(10), * Char(13), Char(3) else Write (PlotLU,'("lb ",I2,2(":",I2.2)," Day ",I3.3,I5,3a)') * UThrs, UTmin, UTsec, ITIME(5), IYEAR, Char(10), * Char(13), Char(3) endif endif C C set up the standard output disc file C FilExist=.TRUE. Nfile=0 DO WHILE (FilExist) FILNAM(6:6)=CHAR(ICHAR('A')+Nfile) Inquire (FILE=FILNAM, EXIST=FilExist) Nfile = Nfile+1 enddo Print *,' ' Print *,' ' Print *,'Creating results file ',FILNAM,' ...' Open (FILE=FILNAM, UNIT=20, STATUS='NEW') If (Plot) then Write (PlotLU,'("si 0.2,0.3;lb Output File ",4a)') * FILNAM, Char(10), Char(13), Char(3) Write (PlotLU,'("sp 0;")') endif endif C C wait here till drive to start of scan is complete C 2 Call EXEC (12,0,2,0,-2) Read (AntennaLU,'(a)') Reply Call UNLT If (Reply(1:1) .eq. '1') goto 2 C If (Reply(1:1) .ne. '0') then read (Reply,'(I1)') Istat call ERROR (Istat,FAULT) If (FAULT) goto 999 goto 2 endif C C If (iscan .eq. (-Nscan/2)) then C C calibrate on the first scan C If (Object .eq. Sun) then Print *, ' ' Print *, 'Ready to Calibrate : Remove 20dB of attenuation' Print *, 'Press RETURN when ready: _' Read (*,'(a)') junk endif C Print *,' ' CALL CALIBRATE (TND(FeedSys), NDcode(FeedSys), Tscale, FAULT) Print *, ' ' If (FAULT) goto 999 C If (Object .eq. Sun) then Print *, 'Done ! Put back 20dB attenuation' Print *, 'Press RETURN when ready: _' Read (*,'(a)') junk Print *, ' ' Tscale = Tscale*100.0 endif C C sample signal at map corner for base level C Base = 0.0 DO I=1,20 Read (FlukeLU,*) Rdvm Base = Base + Rdvm enddo Base = Base / 20.0 C C Normalise central height by signal on sun C Zscale = Zscale / (DVMmax - Base) C endif C C reselect Fluke DVM inputs C Call EXEC (2, 113B, DScode(FeedSys)*11B, 1, 5, 5) Call EXEC (12,0,2,0,-1) C C duration extended by 5 Seconds to ensure Scan is completed C Write (AntennaLU,'(a,i2.2)') 'Begin ObjScn', iscan+Nscan/2+1 Write (AntennaLU,'(a,f8.3)') 'Duration ', SizeLat/ScanRate+5 Write (AntennaLU,'(a,f7.3)') 'B1 ', Direction*ScanRate Write (AntennaLU,'(a)') 'End' Call UNLT Print *,'Doing scan', iscan+Nscan/2+1,' of',Nscan,' _' CALL DoScan (Nbins, SizeLat, Base, Out, ScanLong, * Count, FAULT) If (FAULT) goto 999 enddo C CALL OutScan (iscan-1, Nscan, Nbins, Tscale, Zscale, * SpacLong, Out, ScanLong, Count) C Close (20,err=900) C 900 Print *, ' ' Print *, '|======================|' Print *, '| Map scans finished |' Print *, '|======================|' If (Plot) then C C Chart Advance on the Plotter C Write (PlotLU,'("af;")') endif C C Send telescope to Zenith if bit 11 is set C If (ISSW(11) .lt. 0) then ISWIT = SWIN(0) ISWIT = ISWIT .AND. 173777B CALL SWOUT(ISWIT) Write (AntennaLU,'(a)') 'Begin ZENITH' Write (AntennaLU,'(a)') 'Clear_Fifo' Write (AntennaLU,'(a)') 'Duration 9999' Write (AntennaLU,'(a)') 'Coordinate_System HORIZON' Write (AntennaLU,'(a)') 'Pointing Off' Write (AntennaLU,'(a)') 'Feed_System 0' Write (AntennaLU,'(a)') 'A0 0.0' Write (AntennaLU,'(a)') 'A1 0.0' Write (AntennaLU,'(a)') 'B0 90.0' Write (AntennaLU,'(a)') 'B1 0.0' Write (AntennaLU,'(a)') 'Psi 0.0' Write (AntennaLU,'(a)') 'Phi 0.0' Write (AntennaLU,'(a)') 'Theta 0.0' Write (AntennaLU,'(a)') 'Parallax 0.0' Write (AntennaLU,'(a)') 'End' Call UNLT endif C 999 Print *,'Bye !' Stop End C C SUBROUTINE CALIBRATE (TND, NDcode, Tscale, FAULT) C ==================== C To obtain the Kelvins / Volt calibration factor C Modified to take out linear slope in sampling C C inputs : TND real Cal Noise Diode in Kelvins C NDcode integer Cal Noise Diode select code in DIO C C outputs: Tscale real Kelvins / Volt calibration factor C FAULT logical .TRUE. if unable to calibrate C Implicit None C Logical FAULT C Integer I, J, NVALID(4), NDcode, FlukeLU, Retries, Number C Real TND, Tscale, DTScale C Double Precision DVM(4), DVMSQD(4), ADVM(4), DMS(4), RMS(4), * RDVM, RMS_SUM, DMS_SUM, cal_COUNT C Data FlukeLU / 35 / C Retries = 0 Number = 150 FAULT = .FALSE. Print *,' System calibration :' Print *,' ' C C restart point after error - allow for up to 10 failures C 10 Retries = Retries + 1 DMS_SUM = 0D0 RMS_SUM = 0D0 C C sample with noise cal off (J = 1,4) or on (J = 2,3) C DO J = 1, 4 DVM(J) = 0D0 DVMSQD(J) = 0D0 NVALID(J) = 0 If (J .eq. 2) then C C turn on the noise diode C Call EXEC (2,113B,NDcode,1,3,3) endif If (J .eq. 1 .or. J .eq. 4) then C C turn off the noise diode C Call EXEC (2,113B,0,1,3,3) endif If (J .ne. 3) then C C let the system settle C Call EXEC (12,0,2,0,-2) endif C C sample 0.1 sec filtered 'direct' radiometer output C DO I = 1,Number read (FlukeLU,*) RDVM C C Store DVM and DVM SQUARED readings C NVALID(J) = NVALID(J) + 1 DVM(J) = DVM(J) + RDVM DVMSQD(J) = DVMSQD(J) + RDVM * RDVM enddo C C sampling done : calculate average DVM reading and rms error C If (NVALID(J) .gt. 2) then C C average DVM reading C ADVM(J) = DVM(J) / NVALID(J) DMS(J) = (DVMSQD(J) - DVM(J)*DVM(J)/NVALID(J)) * / (NVALID(J) - 1.0) DMS_SUM = DMS_SUM + DMS(J) C C rms error in reading C RMS(J) = DSQRT(DMS(J)) RMS_SUM = RMS_SUM + RMS(J) C If (J .eq. 1 .or. J .eq. 4) then Print *,' Noise cal. off : _' endif If (J .eq. 2 .or. J .eq. 3) then Print *,' Noise cal. on : _' endif Print '(F12.6,'' +-'',F12.6,'' V'')',ADVM(J),RMS(J) endif enddo C C error trap C If (Retries .ge. 10) then FAULT = .TRUE. Print *,' ' Print *,' Abandoning calibration' RETURN endif C C check noise tube > 4 * average rms noise C cal_COUNT = ((ADVM(2) + ADVM(3)) - (ADVM(1) + ADVM(4)))/2 If (DABS(cal_COUNT) .lt. RMS_SUM) then Print *,' ' Print *,' Noise cal not seen - trying again' Print *,' ' go to 10 endif C C calculate Kelvins per DVM unit conversion factor C Tscale = TND / cal_COUNT C C fractional error in Tscale is half of the square root of the sum of C the squares of the fractional errors in the four DVM averages C DTscale = Tscale * DSQRT (DMS_SUM / (2*cal_COUNT)**2) DTscale = ABS (DTscale) Print *,' ' Print '(1x,"Calibration gives",F12.6," +-",F8.6, * " Kelvins / Volt")', Tscale, DTscale C Return End C C SUBROUTINE DOSCAN (Nbins, SizeLat, Base, Out, ScanLong, * Count, FAULT) C ================= C To sample the DVM and PC-Steer co-ordinates during a scan C and then bin and average them as required. C C inputs : Nbins integer No of output bins required C Sizelat real Eclip. Lat. length of scan C Base real DVM output reading base level C C outputs: Out(*) real Binned averaged DVM output C ScanLong(*) real Binned averaged scan ScanLongitude C Count(*) integer No of values averaged in bin C FAULT logical Unrecoverable PC-Steer Error C Implicit None C Integer Nbins, Count(*), AntennaLU, FlukeLU, i, * Istat, Nempty C Real X, DVM, Y, Out(*), ScanLong(*), SizeLat, Base C Logical FAULT C DATA AntennaLU /39/, FlukeLU /35/ C Do i = 1 , Nbins Count(i) = 0 Out(i) = 0.0 ScanLong(i) = 0.0 enddo C 1 Read (AntennaLU,'(i1,151x,2f8.3)') Istat, X, Y Call UNLT If (Istat .ge. 2) goto 2 Read (FlukeLU,*) DVM if (X.gt.180.0) X = X - 360.0 i = Nint ((SizeLat/2.0 + Y) / SizeLat * Nbins) If (i .ge. 1 .and. i .le. Nbins) then Count(i) = Count(i) + 1 Out(i) = Out(i) + DVM-Base ScanLong(i) = ScanLong(i) + X endif goto 1 C 2 If (Istat .ne. 2) then call ERROR (Istat,FAULT) If (FAULT) goto 999 endif C Nempty=0 Do i = 1 , Nbins If (Count(i) .ne. 0) then Out(i) = Out(i) / Count(i) ScanLong(i) = ScanLong(i) / Count(i) else Nempty=Nempty+1 endif enddo Print *,'( ',Nempty,' empty bins )' C 999 Return End C C SUBROUTINE OutScan (iscan, Nscan, Nbins, Tscale, Zscale, * Spacing, Out, ScanLong, Count, Plot) C =================== C To output the binned data for each scan both into the output C file and to the plotter in the form of a continuous line. C C inputs : iscan integer Present scan number C Nscan integer Total no of scans in map C Nbins integer No of output bins in scan C Tscale real Kelvin/Volt calibration factor C Zscale real Plot-Unit/Volt scale factor C Spacing real Scan spacing in longitude C Out(*) real Binned averaged DVM output C ScanLong(*) real Binned averaged scan ScanLongitude C Count(*) integer No of values in bin C Plot logical Output to Plotter ? C C outputs : None except to file and plotter C Implicit None C Integer iscan, Nscan, Nbins, Count(*), PlotLU, i C Logical Plot C Real Tscale, Zscale, Spacing, Out(*), ScanLong(*) C DATA PlotLU /31/ C If (Plot) then Write (PlotLU,'("pu;")') If (iscan .lt. 0) Write (PlotLU,'("sp 2;")') If (iscan .eq. 0) Write (PlotLU,'("sp 3;")') If (iscan .gt. 0) Write (PlotLU,'("sp 4;")') endif C Do i = 1, Nbins If (Count(i) .gt. 0) then If (Plot) then Write (PlotLU,'("pa ",i6,",",i6,";pd;")') * Nint(FLOAT(i)/Nbins*9000+3000), * Nint(Out(i)*Zscale) + * FLOAT(Iscan+Nscan/2)/Nscan*6000 + 500 endif Write (20,'(F8.2,'','',I5,'','',F12.5,'','',I5)') * -ScanLong(i)/Spacing, i-Nbins/2-1, * Out(i)*Tscale, Count(i) else Write (20,'(I3,''.00,'',I3,'','',12X,'','',I5)') * -iscan, i-Nbins/2-1, Count(i) endif enddo If (Plot) then Write (PlotLU,'("pu;")') Write (PlotLU,'("sp 0;")') endif C Return End C C Subroutine UNLT C =============== C To reset the PC-Steer HPIB card to UNLISTEN mode C C inputs : None C C outputs: None except on HPIB C Integer Cmd(2) C DATA Cmd /2, 2H_?/ C Call CMDR (30,Cmd,0) C Return End C C Subroutine MJDAY (IYR, ITIME, MJD) C ================ C To calculate the Modified Julian Day, as defined in the C Astronomical Almanac, for a given year, day & time C C inputs : IYR Integer*2 Year ( from 1983 - ) C ITIME(5) Integer*2 Day No, Hr, Min, Sec, 100th C C outputs: MJD Double Precision Modified Julian Day Number C C Implicit None C Integer*2 IYR, ITIME(5) C Integer JYR C Double Precision MJD C Logical LEAPYR C MJD = ( ( (DBLE(ITIME(1))/100D0 + DBLE(ITIME(2)) ) / 60.0D0 * + DBLE(ITIME(3)) ) / 60.0D0 * + DBLE(ITIME(4)) ) / 24.0D0 * + DBLE(ITIME(5)) C If (IYR .lt. 1983) then C Print '(I4," - year not catered for in MJD routine MJDAY")', * IYR MJD = 0.0D0 C else C MJD = MJD + 45334.0D0 ! 1983 offset DO 100 JYR = 1984, IYR MJD = MJD + 365.0D0 If (LEAPYR(JYR-1)) MJD = MJD + 1.0D0 100 CONTINUE C endif C Return End C C Logical Function LEAPYR (IYEAR) C ======================= C To determine if any given year is a leap year C C inputs : IYEAR Integer Year to be assessed C C outputs: LEAPYR Logical .TRUE. if IYEAR is a leap year C Implicit None C Integer IYEAR C LEAPYR = (((MOD(IYEAR,4) .eq. 0) .AND. (MOD(IYEAR,100) .ne. 0)) * .OR. (MOD(IYEAR,400) .eq. 0)) C Return End C C Subroutine ERROR (Istat,FAULT) C ================ C To report PC-Steer Errors and request User intervention C C inputs : Istat Integer PC-Steer Error Number C C outputs: FAULT Logical Condition Fatal so terminate C Implicit None C Integer Istat C Character CHAR Logical FAULT C Print *,' ' Print *,'!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!' Print *,'!!! PC-Steer Error',Istat,' has been detected !!' Print *,'!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!' Print *,' ' C FAULT = .FALSE. 1 Print *,'Should Map be terminated ( = ',FAULT,' ) ? _' Read (*,'(a)') CHAR Call Upcase(CHAR) If (CHAR .eq. 'Y' .or. CHAR .eq. 'T' ) then FAULT =.TRUE. goto 999 endif If (CHAR .ne. 'N' .and. CHAR .ne. 'F' .and. CHAR .ne. '/' .and. * CHAR .ne. ' ' ) goto 1 C 999 Return End C C Subroutine Set_Type ( Type, Object, CoordSys, Coord ) C =================== C To construct the appropriate Parameter Identifier from the C various descriptive strings to an underscore separated list. C C inputs : Object Character*(*) Map Object Identifier C CoordSys Character*(*) Coordinate System C Coord Character*(*) Coordinate Identifier C C outputs: Type Character*(*) Parameter Identifier C Implicit None C Character Type*(*), Object*(*), CoordSys*(*), Coord*(*) C Integer Nchar, L1, L2, L3 C C evaluate lengths of three components, maximums 4_5_4 C L1 = MIN( 4, Nchar( Object ) ) L2 = MIN( 5, Nchar( CoordSys ) ) L3 = MIN( 4, Nchar( Coord ) ) If (Coord(L3:L3) .eq. '.') L3 = L3 - 1 C C construct Parameter Identify as Object_CoordSys_Coord C Type = Object(1:L1) //'_'// CoordSys(1:L2) //'_'// Coord(1:L3) Call Upcase ( Type ) C Return End C C Subroutine Open_File ( Filename, LU, Position, IERR ) C ==================== C To open any sequential file if not already opened and to return C the LU number associated with the file. New LU's are allocated C sequentially from 7 upwards as necessary. Note that the file C will be created if it does not exist already. C C inputs : Filename Character*(*) Name of file to be opened C Position Character*(*) 'START' or 'END' of file C C outputs: LU Integer Logical Unit attatched C IERR Integer I/O IOSTAT error number C Implicit None C Character Filename*(*), Position*(*), Junk C Integer LU, Default, IERR C Logical Exists, OpenNow, Used C Data Default / 65 / C C first we must determine if the required file is open already C Call Upcase ( Position ) Inquire ( FILE=Filename, IOSTAT=IERR, ERR=995, * EXIST=Exists, OPENED=OpenNow, NUMBER=LU ) C If (.not. OpenNow) then C C if file is not yet opened, determine free LU to use for file C Used = .TRUE. LU = Default - 1 Do While (Used) LU = LU + 1 Inquire ( UNIT=LU, IOSTAT=IERR, ERR=995, OPENED=Used ) enddo C C and open required file FILENAME, creating if necessary C Open ( FILE=Filename, UNIT=LU, IOSTAT=IERR, ERR=995, * STATUS='UNKNOWN', ACCESS='SEQUENTIAL' ) C C if file did not exist before then write EOF marker C If (.not. Exists) Endfile ( UNIT=LU, IOSTAT=IERR, ERR=995 ) C endif C C if Position='START' then simply rewind file and Exit C If (Position .eq. 'START') then Rewind ( UNIT=LU, IOSTAT=IERR, ERR=995 ) goto 999 endif C C if Position='END' then rewind, locate EOF C If (Position .eq. 'END') then Rewind (UNIT=LU, IOSTAT=IERR, ERR=995 ) Do While (.TRUE.) Read ( LU, *, IOSTAT=IERR, ERR=995, END=999 ) JUNK enddo endif C 990 Print '("Unknown Position ",A," in Open_File")', Position goto 999 C 995 Print '("I/O Error ",I4," on opening file ",A," to ",A)', * IERR, Filename, Position C 999 Return End C C Subroutine Get_Parm ( Type, DayNo, Year, Nvals, Values, Found ) C =================== C To get the values associated with Type on the day no. DayNo of C year Year from the MAPPRM::16 parameter file. C Note: A DayNo of 0 will retrieve the most recent value. C C inputs : Type Chsracter*(*) Keyword identifying Parameter C DayNo Integer Julian Day Number and ... C Year Integer Year the values are required for C Nvals Integer No of associated values C C outputs: Values Real(*) Values retrieved from file C Found Logical If vslues were available C Implicit None C Character Type*(*), FType*15 C Integer DayNo, Year, Nvals, FileLU, IERR, FDyNo, FYear, I C Logical Found C Real Values(*), SValue(20), Epoch, FEpch C C first Open the MAPPRM::16 parameter storage file at the START C Epoch = 0.0 Found = .FALSE. Call Upcase ( Type ) Call Open_File ( 'MAPPRM::16', FileLU, 'START', IERR ) If (IERR .gt. 0) goto 995 C C read next line in file till Parameter is found or EOF detected C Do While (.NOT. Found .OR. DayNo .eq. 0) Read ( FileLU, *, IOSTAT=IERR, ERR=995, END=900 ) FType C C if Type matches that read from file, backspace and read values C If (Index(FType,Type) .eq. 1) then Backspace ( UNIT=FileLU, IOSTAT=IERR, ERR=995 ) Read ( FileLU, *, IOSTAT=IERR, ERR=995, END=900 ) * FType, FDyNo, FYear, (Values(I),I=1,Nvals) C C if searching for latest value, compare Epoch's etc C If (DayNo .eq. 0) then FEpch = FYear + (FDyNo-1)/366.0 If (FEpch .ge. Epoch .or. .not. Found) then Found = .TRUE. Epoch = FEpch Do I = 1, Nvals SValue(I) = Values(I) enddo endif C C otherwise both Day No. and Year should match C elseif (DayNo .eq. FDyNo .and. Year .eq. Fyear ) then Found = .TRUE. endif C endif enddo C C at EOF must copy back latest values if DAYNO = 0 and then Exit C 900 If (Found .and. DayNo .eq. 0) then Do I = 1, Nvals Values(I) = SValue(I) enddo endif goto 999 C 995 Print '("I/O Error ",I4," on MAPPRM::16 in Get_Parm")', IERR C 999 Return End C C Subroutine Put_Parm ( Type, DayNo, Year, Nvals, Values ) C =================== C To put the values associated with Type on the day no. DayNo of C year Year into the MAPPRM::16 parameter file. A total of Nvals C values are saved from the Values array. C C inputs : Type Chsracter*(*) Keyword identifying Parameter C DayNo Integer Julian Day Number and ... C Year Integer Year the values are valid on C Nvals Integer No of associated values C Values Real(*) Values to be saved on file C C outputs: None except to file C Implicit None C Character Type*(*) C Integer DayNo, Year, Nvals, FileLU, IERR, I, Nchar C Real Values(*) C C first Open the MAPPRM::16 parameter storage file at the END C Call Upcase ( Type ) Call Open_File ( 'MAPPRM::16', FileLU, 'END', IERR ) If (IERR .gt. 0) goto 995 C C write suitable line into file followed by an EOF marker and Exit C Write ( FileLU, 100, IOSTAT=IERR, ERR=995 ) * Type(1:Nchar(Type)), DayNo, Year, (Values(I),I=1,Nvals) 100 Format ( "'", A, "'", I4.3, I5, 20F13.8 ) Endfile ( UNIT=FileLU, IOSTAT=IERR, ERR=995 ) goto 999 C 995 Print '("I/O Error ",I4," on MAPPRM::16 in Put_Parm")', IERR C 999 Return End C C======================= INCLUDE &RHYP::16 INCLUDE &NCHAR::16 INCLUDE UPCASE::16 C=======================