SUBROUTINE LOCPX(PMLC,INDEX,XS,YS) ! ! returns the view coordinates for the input mirror location count and ! pixel index ! ! name type description ! ! input arguments: PMLC INT*2 mirror location count of scanline ! INDEX INT*2 pixel position in scanline ! output arguments: XS REAL*4 horizontal view coordinate ! YS REAL*4 vertical view coordinate ! ! COMMON /IMAGE/ IMFILE,FCTDWN,FCTACR,NPHOT,CENTRMLC,PIXOFF COMMON /IMCOORD/IMXMIN,IMXMAX,IMYMAX,STEP,PIXWD,PIXHT, & NSPIN,TSPIN,UTNC1,SOLMSEC1,SP,ALTF,MDIREC COMMON /SCANS/ SCANPIX,LNCOR,MLCS,NPIXL COMMON /MAFREC/ HEADER,SCAN ! BYTE HEADER(404),SCAN(1592),SCANPIX(1568,121) CHARACTER*128 IMFILE INTEGER*2 NPHOT,CENTRMLC,PIXOFF,PMLC,INDEX,MDIREC,LN, & MLCS(121),NPIXL(121) INTEGER*4 NSPIN,TSPIN,FIRSTMLC,LASTMLC,UTNC1,SOLMSEC1 REAL*4 IMXMIN,IMXMAX,IMYMAX,XS,YS,FCTDWN,FCTACR,STEP, & PIXWD,PIXHT,LNCOR(2,121),SP,ALTF ! EQUIVALENCE (HEADER(41),FIRSTMLC),(HEADER(45),LASTMLC) ! IF (NPHOT.EQ.3) THEN XS = IMXMIN + PMLC - MIN(FIRSTMLC,LASTMLC) ELSE XS = IMXMIN + MAX(FIRSTMLC,LASTMLC) - PMLC ENDIF LN = ABS(PMLC-FIRSTMLC) + 1 YS = IMYMAX - LNCOR(1,LN) - INDEX + 1 IF (INDEX.LT.76) YS = YS - LNCOR(2,LN) ! RETURN END ! ! ! SUBROUTINE POINT(XS,YS,ALT,NP,X1,Y1,Z1,X2,Y2,Z2) ! ! for line of sight indicated by the input view coordinates, ! computes GSEq points of intersection with the Earth spheroid ! at the altitude ALT; sets NP to the number of points (0, 1, or 2) ! and sets (X1,Y1,Z1) to the point closer to the s/c ! ! name type description ! ! input arguments: XS REAL*4 horizontal view coordinate ! YS REAL*4 vertical view coordinate ! ALT REAL*4 altitude in kilometers ! output arguments: NP INT*2 number of points of intersection - ! 0, 1, or 2; NP is set to 0 if ! computation can't be done ! X1\ REAL*4\ GSEq position of line-of-sight ! Y1 > REAL*4 > intersect with Earth, if there are ! Z1/ REAL*4/ any; the nearer point of two ! X2\ REAL*4\ GSEq position of second line-of-sight ! Y2 > REAL*4 > intersect with Earth is there is ! Z2/ REAL*4/ one; the farther point ! ! COMMON /IMCOORD/IMXMIN,IMXMAX,IMYMAX,STEP,PIXWD,PIXHT, & NSPIN,TSPIN,UTNC1,SOLMSEC1,SP,ALTF,MDIREC COMMON /MOTION/ POSITION,SPINANG,XP1,SPINX,SPINY,SPINZ, & SUNX,SUNZ ! INTEGER*2 NP,IPOS,MDIREC,XPOS INTEGER*4 UTNC1,NSPIN,TSPIN,SOLMSEC1 REAL*4 IMXMIN,IMXMAX,IMYMAX,STEP,PIXWD,PIXHT, & POSITION(1026,3),SPINANG(1026),XP1, & SPINX,SPINY,SPINZ,SUNX,SUNZ,XS,YS,ALT, & A,B,SCX,SCY,SCZ,GX,GY,GZ,QA,QB,QC,SP,ALTF, & X1,Y1,Z1,X2,Y2,Z2,QX,QY,QZ,Q1,Q2 REAL*8 AXA,BXB,DX,DY,DZ,U,V ! !---screen out sight lines away from Earth IF (ABS(YS*PIXHT).GT.90.) THEN NP = 0 RETURN ENDIF ! !---set up earth size A = 6378.164 + ALT B = 6356.779 + ALT AXA = DBLE(A)*DBLE(A) BXB = DBLE(B)*DBLE(B) ! !---get look direction in GSEq coordinates CALL VW2GSESC(XS,YS,GX,GY,GZ) IPOS = XPOS(XS,YS) ! !---use quadratic solution to get intersections of line of sight ! with ellipsoid DX = DBLE(GX) DY = DBLE(GY) DZ = DBLE(GZ) IF (ABS(GY).GT.ABS(GX).OR.ABS(GZ).GT.ABS(GX)) GO TO 20 !---solve for X U = POSITION(IPOS,2) - (DY/DX)*POSITION(IPOS,1) V = POSITION(IPOS,3) - (DZ/DX)*POSITION(IPOS,1) QA = (1.D0 + (DY*DY)/(DX*DX))/AXA + (DZ*DZ)/(DX*DX)/BXB QB = 2.D0 * (DY/DX*U/AXA + DZ/DX*V/BXB) QC = (U*U)/AXA + (V*V)/BXB - 1.D0 CALL QUAD(QA,QB,QC,X1,X2,NP) IF (NP.EQ.0) RETURN Y1 = (DY/DX)*(X1-POSITION(IPOS,1)) + POSITION(IPOS,2) Z1 = (DZ/DX)*(X1-POSITION(IPOS,1)) + POSITION(IPOS,3) IF (NP.EQ.1) RETURN Y2 = (DY/DX)*(X2-POSITION(IPOS,1)) + POSITION(IPOS,2) Z2 = (DZ/DX)*(X2-POSITION(IPOS,1)) + POSITION(IPOS,3) GO TO 70 20 IF (ABS(GZ).GT.ABS(GY)) GO TO 30 !---solve for Y U = POSITION(IPOS,1) - (DX/DY)*POSITION(IPOS,2) V = POSITION(IPOS,3) - (DZ/DY)*POSITION(IPOS,2) QA = (1.D0 + (DX*DX)/(DY*DY))/AXA + (DZ*DZ)/(DY*DY)/BXB QB = 2.D0 * (DX/DY*U/AXA + DZ/DY*V/BXB) QC = (U*U)/AXA + (V*V)/BXB - 1.D0 CALL QUAD(QA,QB,QC,Y1,Y2,NP) IF (NP.EQ.0) RETURN X1 = (DX/DY)*(Y1-POSITION(IPOS,2)) + POSITION(IPOS,1) Z1 = (DZ/DY)*(Y1-POSITION(IPOS,2)) + POSITION(IPOS,3) IF (NP.EQ.1) RETURN X2 = (DX/DY)*(Y2-POSITION(IPOS,2)) + POSITION(IPOS,1) Z2 = (DZ/DY)*(Y2-POSITION(IPOS,2)) + POSITION(IPOS,3) GO TO 70 !---solve for Z 30 U = POSITION(IPOS,1) - (DX/DZ)*POSITION(IPOS,3) V = POSITION(IPOS,2) - (DY/DZ)*POSITION(IPOS,3) QA = ((DX*DX)/(DZ*DZ)+(DY*DY)/(DZ*DZ))/AXA + 1.D0/BXB QB = 2.D0/AXA * (DX/DZ*U + DY/DZ*V) QC = (U*U + V*V)/AXA - 1.D0 CALL QUAD(QA,QB,QC,Z1,Z2,NP) IF (NP.EQ.0) RETURN Y1 = (DY/DZ)*(Z1-POSITION(IPOS,3)) + POSITION(IPOS,2) X1 = (DX/DZ)*(Z1-POSITION(IPOS,3)) + POSITION(IPOS,1) IF (NP.EQ.1) RETURN Y2 = (DY/DZ)*(Z2-POSITION(IPOS,3)) + POSITION(IPOS,2) X2 = (DX/DZ)*(Z2-POSITION(IPOS,3)) + POSITION(IPOS,1) ! !---select the solution point closer to the s/c for point 1 70 QX = X1 - POSITION(IPOS,1) QY = Y1 - POSITION(IPOS,2) QZ = Z1 - POSITION(IPOS,3) Q1 = SQRT( QX*QX + QY*QY + QZ*QZ ) QX = X2 - POSITION(IPOS,1) QY = Y2 - POSITION(IPOS,2) QZ = Z2 - POSITION(IPOS,3) Q2 = SQRT( QX*QX + QY*QY + QZ*QZ ) IF (Q1.LT.Q2) RETURN QX = X1 QY = Y1 QZ = Z1 X1 = X2 Y1 = Y2 Z1 = Z2 X2 = QX Y2 = QY Z2 = QZ RETURN ! END ! ! ! SUBROUTINE VW2GEO(XS,YS,ALT,GLAT,GLONG,GLT,GOOD) ! ! converts view coordinates XS and YS to geographic N LAT ! and E LONG in degrees assuming altitude of ALT kilometers above ! the Earth; also provides geographic local time; sets GOOD to ! .FALSE. if line of sight does not intersect the Earth ! ! name type description ! ! input arguments: XS REAL*4 horizontal view coordinate ! YS REAL*4 vertical view coordinate ! ALT REAL*4 altitude in kilometers ! output arguments: GLAT REAL*4 geographic north latitude in deg. ! GLONG REAL*4 geographic east longitude in deg. ! GLT REAL*4 geographic local time in degrees ! GOOD LOG*1 .TRUE. if line of sight intersects ! Earth; .FALSE. if it does not ! ! COMMON /IMCOORD/IMXMIN,IMXMAX,IMYMAX,STEP,PIXWD,PIXHT, & NSPIN,TSPIN,UTNC1,SOLMSEC1,SP,ALTF,MDIREC ! INTEGER*2 MDIREC,NP INTEGER*4 UTNC1,NSPIN,TSPIN,SOLMSEC,SOLMSEC1 REAL*4 IMXMIN,IMXMAX,IMYMAX,STEP,PIXWD,PIXHT,SP,ALTF, & XS,YS,ALT,GX1,GY1,GZ1,GX2,GY2,GZ2,GR,GTHETA, & GPHI,GLT,GLAT,GLONG,X1 LOGICAL*1 GOOD ! !---get GSEq coordinates of the view point CALL POINT(XS,YS,ALT,NP,GX1,GY1,GZ1,GX2,GY2,GZ2) IF (NP.EQ.0) THEN GOOD = .FALSE. RETURN ELSE GOOD = .TRUE. ENDIF ! !---compute local geographic time CALL RECSPHD(GX1,GY1,GZ1,GR,GTHETA,GPHI) GLT = AMOD(GPHI+180.,360.) ! !---convert GSEq coordinates to latitude and longitude IF (MDIREC.EQ.1) THEN X1 = IMXMIN ELSE X1 = IMXMAX ENDIF SOLMSEC = SOLMSEC1 + (XS-X1)*MDIREC*NSPIN CALL GSEGEO(GX1,GY1,GZ1,SOLMSEC,GLAT,GLONG) RETURN ! END ! ! ! INTEGER*2 FUNCTION XPOS(XS,YS) ! ! for the window X-coordinate XS, returns the index of the closest ! s/c position ! ! name type description ! ! input arguments: XS REAL*4 horizontal view coordinate ! YS REAL*4 vertical view coordinate ! result: XPOS INT*2 index of closest position in ! POSITION array ! ! COMMON /MOTION/ POSITION,SPINANG,XP1,SPINX,SPINY,SPINZ, & SUNX,SUNZ ! REAL*4 POSITION(1026,3),SPINANG(1026),XP1, & SPINX,SPINY,SPINZ,SUNX,SUNZ,XS,YS,X,TRUEX ! X = TRUEX(XS,YS) XPOS = NINT(X-XP1) + 1 ! RETURN END ! ! ! SUBROUTINE VW2GSESC(XS,YS,GX,GY,GZ) ! ! finds GSEq vector for the look direction from the s/c indicated by ! the input screen coordinates ! ! name type description ! ! input arguments: XS REAL*4 horizontal view coordinate ! YS REAL*4 vertical view coordinate ! output arguments: GX REAL*4\ ! GY REAL*4 >GSEq vector ! GZ REAL*4/ ! ! COMMON /MOTION/ POSITION,SPINANG,XP1,SPINX,SPINY,SPINZ, & SUNX,SUNZ COMMON /IMCOORD/IMXMIN,IMXMAX,IMYMAX,STEP,PIXWD,PIXHT, & NSPIN,TSPIN,UTNC1,SOLMSEC1,SP,ALTF,MDIREC ! INTEGER*2 IPOS,XPOS,MDIREC REAL*4 POSITION(1026,3),SPINANG(1026),XP1, & SPINX,SPINY,SPINZ,SUNX,SUNZ,GX,GY,GZ,XX,XY,XZ, & YYX,YYY,YYZ,YX,YY,YZ,ZZX,ZZY,ZZZ,ZX,ZY,ZZ, & VX,VY,VZ,VTHETA,VPHI,XS,YS,TRUEX,IMXMIN,IMXMAX, & IMYMAX,STEP,PIXWD,PIXHT,SP,ALTF INTEGER*4 NSPIN,TSPIN,UTNC1,SOLMSEC1 ! !---get position index IPOS = XPOS(XS,YS) ! !---set up rotation matrix - ! X-axis is toward earth center, Y-axis is X-axis cross spin vector CALL NRMLIZ(-POSITION(IPOS,1),-POSITION(IPOS,2), & -POSITION(IPOS,3),XX,XY,XZ) CALL CROSS(XX,XY,XZ,SPINX,SPINY,SPINZ,YYX,YYY,YYZ) CALL NRMLIZ(YYX,YYY,YYZ,YX,YY,YZ) CALL CROSS(XX,XY,XZ,YX,YY,YZ,ZZX,ZZY,ZZZ) CALL NRMLIZ(ZZX,ZZY,ZZZ,ZX,ZY,ZZ) ! !---convert screen angles to view vector VPHI = YS*PIXHT VTHETA = 90. - TRUEX(XS,YS)*PIXWD CALL SPHDREC(1.,VTHETA,VPHI,VX,VY,VZ) ! !---rotate vector GX = VX*XX + VY*YX + VZ*ZX GY = VX*XY + VY*YY + VZ*ZY GZ = VX*XZ + VY*YZ + VZ*ZZ ! RETURN END ! ! ! REAL*4 FUNCTION TRUEX(XS,YS) ! ! corrects view X coordinate for the mirror step to get true angle ! ! name type description ! ! input arguments: XS REAL*4 horizontal view coordinate ! YS REAL*4 vertical view coordinate ! result: TRUEX REAL*4 horizontal view coordinate ! adjusted for mirror step to ! correct from scanline position ! to true angle ! ! COMMON /IMCOORD/IMXMIN,IMXMAX,IMYMAX,STEP,PIXWD,PIXHT, & NSPIN,TSPIN,UTNC1,SOLMSEC1,SP,ALTF,MDIREC ! REAL*4 XS,YS,IMXMIN,IMXMAX,IMYMAX,STEP,PIXWD,PIXHT, & SP,ALTF INTEGER*2 MDIREC INTEGER*4 NSPIN,TSPIN,SOLMSEC1,UTNC1 ! TRUEX = XS IF (-YS*PIXHT.GT.STEP) TRUEX = TRUEX + MDIREC ! RETURN END ! ! ! INTEGER*4 FUNCTION UTPIX(XS,YS) ! ! returns the UT in milliseconds for the collection time of the ! pixel at the input view position ! ! name type description ! ! input arguments: XS REAL*4 horizontal view coordinate ! YS REAL*4 vertical view coordinate ! result: UTPIX INT*4 pixel collection UT in msec. ! ! COMMON /IMCOORD/IMXMIN,IMXMAX,IMYMAX,STEP,PIXWD,PIXHT, & NSPIN,TSPIN,UTNC1,SOLMSEC1,SP,ALTF,MDIREC COMMON /MOTION/ POSITION,SPINANG,XP1,SPINX,SPINY,SPINZ, & SUNX,SUNZ ! REAL*4 XS,YS,IMXMIN,IMXMAX,IMYMAX,STEP,PIXWD,PIXHT, & POSITION(1026,3),SPINANG(1026),XP1,SP,ALTF, & SPINX,SPINY,SPINZ,SUNX,SUNZ INTEGER*2 MDIREC INTEGER*4 NSPIN,TSPIN,UTNC1,SOLMSEC1 ! IF (MDIREC.EQ.1) THEN UTPIX = UTNC1 + (XS-IMXMIN)*NSPIN - YS*3.90625 ELSE UTPIX = UTNC1 + (IMXMAX-XS)*NSPIN - YS*3.90625 ENDIF ! RETURN END