;+ ; NAME: ; RemoteView_Init_FOV ; PURPOSE: ; Set up structure for RemoteView_FOV ; CATEGORY: ; RemoteView project ; CALLING SEQUENCE: FUNCTION RemoteView_Init_FOV, iT, V3D, M3D ; INPUTS: ; iT scalar; type: integer ; counter for current view (as index into V3D) ; V3D array[1]; type; structure ; structure array containing information about the views ; to be calculated. ; M3D array[1]; type: structure ; structure containing 3D density matrices and associated ; information; passed to Sky_Grid_Struct ; OUTPUTS: ; FOVInfo array[1]; type: structure ; structure combining information about a single 3D density ; matrix and a single view. The single density matrix and ; view are derived from the two input structure arrays. ; INCLUDE: @compile_opt.pro ; On error, return to caller ; CALLS: ; TimeOp, TimeUnit, RemoteView_FOV_xyz, EulerRotate, sphere_distance ; AlignHeliosphere ; RESTRICTIONS: ; The interpolation scheme assumes that the matrices are sorted into ; chronological order. ; PROCEDURE: ; > The time for view iT is compared with the matrix times. A new matrix is ; calculated by interpolating between two matrices. ; > If the view time coincides exactly with a matrix time then no ; interpolation is needed. In this case the FOVInfo structure will just ; point to the appropriate original matrix. ; > If only one matrix is specified then this matrix is always used (i.e. ; the specified times are ignored. ; ; > The V3D and M3D contain information about ALL views and ALL matrices, ; respectively. The SKYVIEW_FOV structure is assembled from the two ; structures and describes a single view and matrix. ; ; matrix This is a pointer to a 3D density matrix ; matrix_index Time index into 3D matrix (=0 for interpolated matrix) ; matrix_rect Set to 1 for rectangular matrix ; matrix_rEdge Inner and outer radius of data (AU) ; matrix_dR AU/grid spacing ; matrix_Origin Location of origin (grid spacings; only for rectangular data) ; matrix_lng0 Start heliographic longitude of matrix ; ; view_loc Viewing location : lng, lat in radians; distance in AU ; view_dir Viewing direction: lng, lat in radians ; ; view_fov Angular half-width field of view (radians) ; view_tilt Field of view tilt angle (radians) ; ; view_ndim Dimensions of field of view cube ; view_eqtrans ; ; view_extent Minimum, maximum distance along line of sight ; view_elo Elongation across field of view ; ; MODIFICATION HISTORY: ; DEC-2000, Paul Hick (UCSD/CASS; pphick@ucsd.edu) ;- ; Identify the proper 3D matrix to be used by comparing the ; current view time with the times of all matrices. TView = (*V3D.Time)[iT < (n_elements(*V3D.Time)-1)] ; Time of current view nMatrix = M3D.nMatrix ; # available volume data nMatrixB = M3D.nMatrixB ; # available magnetic field data (=1, or =nMatrix) TMatrix = *M3D.Time ; Available matrix times (nMatrix times) dT = TimeOp(/subtract, TMatrix, TView, TimeUnit(/days)) ; Find matrix time closest to view time TT. ; If only one matrix is specified then always iTMinR = iTMinL = 0. dTMin = min([abs(dT)], iTMinR) ; iTMinR: index in TMatrix closest to TView iTMinL = iTMinR+(1-2*long(dT[iTMinR] GT 0)); iTMinL: neigboring index in TMatrix bracketing TView iTMinL = (iTMinL > 0) < (nMatrix-1) ; Stay inside array IF M3D.rectangular OR iTMinL EQ iTMinR THEN BEGIN ; If iTMinL = iTMinR then the density matrix to be used is exactly one ; of the matrices stored in M3D.F3D. ptr_matrix = M3D.F3D ; Pointer to matrix ind_matrix = iTMinR ; Offset in 4th dimension (time) ptr_matrixb = M3D.B3D ; Pointer to magnetic field matrix (could be null pntr) CASE nMatrixB OF 0 : ind_matrixb = -1 ; No magnetic field 1 : ind_matrixb = 0 ; Only one magnetic field matrix ELSE: ind_matrixb = ind_matrix ; Magnetic field matix with same time offset as volume data ENDCASE extra_matrix = 0 extra_matrixb = 0 ENDIF ELSE BEGIN ; Calculate difference in start longitude of the L matrix relative to the R matrix nLng = (size(*M3D.F3D, /dim))[0] ; # longitudes dL = (2*!dpi)/(nLng-1) ; Radians/bin dL = ((*M3D.Lng0)[iTMinL] - (*M3D.Lng0)[iTMinR])/dL ; Offset in bins ; Align the L matrix with the R matrix (making the start longitudes the same) ptr_matrix = AlignHeliosphere( (*M3D.F3D)[*,*,*,iTMinL], dL, aligneps=1.e-5) ; Take a weighted mean between the R matrix and the aligned L matrix ; The new matrix has the same start longitude as the R matrix ptr_matrix = (dT[iTMinR]*ptr_matrix-dT[iTMinL]*(*M3D.F3D)[*,*,*,iTMinR])/(dT[iTMinR]-dT[iTMinL]) ptr_matrix = ptr_new(ptr_matrix, /no_copy) ind_matrix = 0 extra_matrix = 1 CASE nMatrixB OF 0: BEGIN ptr_matrixb = M3D.B3D ; Null pointer ind_matrixb = -1 ; No magnetic field extra_matrixb = 0 END 1: BEGIN ptr_matrixb = M3D.B3D ind_matrixb = 0 ; Only one magnetic field matrix extra_matrixb = 0 END nMatrixB: BEGIN ptr_matrixb = AlignHeliosphere( (*M3D.B3D)[*,*,*,iTMinL], dL ) ptr_matrixb = (dT[iTMinR]*ptr_matrixb-dT[iTMinL]*(*M3D.B3D)[*,*,*,iTMinR])/(dT[iTMinR]-dT[iTMinL]) ptr_matrixb = ptr_new(ptr_matrixb, /no_copy) ind_matrixb = 0 extra_matrixb = 1 END ENDCASE ENDELSE rOuter = M3D.rEdge[1] ; Set up the proper view vectors. Loc = (*V3D.Loc )[*,iT < (n_elements(*V3D.Loc )/3-1)] ; 3-element array Dir = (*V3D.Dir )[*,iT < (n_elements(*V3D.Dir )/2-1)] ; 2-element array Fov = (*V3D.Fov )[*,iT < (n_elements(*V3D.Fov )/2-1)] ; 2-element array Tilt = (*V3D.Tilt)[ iT < (n_elements(*V3D.Tilt) -1)] ; scalar rNear = (Loc[2]-rOuter) > V3D.rNear ; Distance to nearest data (AU) ; If Fov = 0 then: ; if viewer location inside data sphere set it to 90 degrees ; if viewer location outside data sphere set the fov somewhat larger than half the ; angular width of the data sphere s = !pi/2-2./!radeg ; Safety margin: stay away from 90 deg IF Fov[0] EQ 0 THEN Fov[0] = (1.01*asin(rOuter/(Loc[2] > rOuter))) < s IF Fov[1] EQ 0 THEN Fov[1] = (1.01*asin(rOuter/(Loc[2] > rOuter))) < s ; A slight safety margin is needed to keep fov away from 90 degree (we are going ; to divide by tan(fov). IF Fov[0] GE s THEN BEGIN message, /info, 'Horizontal fov size too close to 180 degrees, set to'+strcompress(2*s*!radeg)+' degrees' Fov[0] = s ENDIF IF Fov[1] GE s THEN BEGIN message, /info, 'Vertical fov size too close to 180 degrees, set to'+strcompress(2*s*!radeg)+' degrees' Fov[1] = s ENDIF ; We still need the elongations across the field of view. Sun = [!pi+Loc[0],-Loc[1],Loc[2]] ; Location of Sun in X-Y-Z system Sun = EulerRotate([!pi+Dir[0],-(!pi/2.-Dir[1]),-Tilt], Sun) Sun = cv_coord(from_sphere=Sun, /to_rect) ; Calculate elongation using the depth layer in x which ; is farthest away from the viewer location Elo = fltarr(3,V3D.nDim[0],V3D.nDim[1], /nozero) Elo = RemoteView_FOV_xyz(Elo, fov=Fov, eqtrans=V3D.EqTrans); Fill with x,y,z coordinates Elo = sphere_distance(Elo, Sun) Elo = reform(Elo, V3D.nDim[0],V3D.nDim[1], /overwrite) ptr_elo = ptr_new(Elo, /no_copy) FOVInfo = {SKYVIEW_FOV, $ matrix : ptr_matrix, $ ; This is a pointer to a 4D matrix (3D space + time) matrix_index : ind_matrix, $ ; Time index into 3D matrix. matrix_extra : extra_matrix, $ ; Interpolated matrix? matrixb : ptr_matrixb, $ ; This is a pointer to a 4D matrix (3D space + time) matrixb_index: ind_matrixb, $ ; Time index into 3D matrix. matrixb_extra: extra_matrixb, $ ; Interpolated matrix? matrix_rect : M3D.rectangular, $ ; Set for rectangular matrix matrix_rEdge : M3D.rEdge, $ ; Inner and outer radius of data (AU) matrix_dR : M3D.dR, $ ; AU/grid spacing matrix_Origin: M3D.Origin, $ ; Location of origin (grid spacings; only for rectangular data) matrix_lng0 : (*M3D.Lng0)[iTMinR], $ ; Loc, Dir, and Tilt are all specified in spherical, heliographic coordinates (in radians) view_time : TView, $ ; Viewign time: structure view_loc : Loc, $ ; Viewing location : lng, lat in radians; distance in AU view_dir : Dir, $ ; Viewing direction: lng, lat in radians view_fov : Fov, $ ; Angular half-width field of view (radians) view_tilt : Tilt, $ ; Field of view tilt angle (radians) view_ndim : V3D.nDim, $ ; Dimensions of field of view cube view_eqtrans: V3D.EqTrans, $ view_stereo : V3D.stereo, $ ; Add a number of fields to be used by other procedures. view_extent : rNear+[0,2.*rOuter], $ ; Minimum, maximum distance along line of sight view_elo : ptr_elo } RETURN, FOVInfo & END