;+ ; NAME: ; GSM2LMN ; ; PURPOSE: ; Routine transforms vector field from GSM to LMN (boundary-normal) ; coordinate system for magnetopause. Shue et al., 1998 magnetopause model ; is used. ; ; CATEGORY: ; Coordinate Transformation ; ; CALLING SEQUENCE: ; gsm2lmn,txyz,Bxyz,Blmn,swdat ; ; INPUTS: ; txyz: | t | x | y | z | - time and GSM position of the input vector (Bxyz). ; - 2D array (nvectors,4) ; Bxyz: | Bx | By | Bz | - vector field to transform (in GSM). ; - 2D array (nvectors,3) ; OPTIONAL INPUT: ; swdat: | t | Dp | Bz | of IMF at the bow-shock nose covering time ; interval of interest. 2D array (ntimepoints,3). The time points ; may be different from those of the vector field. However, they ; should use the same time units. ; If this input is not provided, the SPDF standard static SW data ; are generated. ; ; KEYWORDS: none ; ; PARAMETERS: none ; ; OUTPUTS: ; Blmn: | Bl | Bm | Bn | - vector in LMN at the same space-time points. ; - 2D array (nvectors,3) ; ; DEPENDENCIES: None - can be used alone. Lowest-level part of LMN transform package. ; ; MODIFICATION HISTORY: ; Written by: Vladimir Kondratovich 2007/12/28 on the base of ; the code xyz2lmnshue by Liu Jiang (09/21/2007) ; Modified for error handling, changed () to [] for arrays, and now correctly ; indexes for loop with long integers for large arrays ; by: Lynn B. Wilson III 2012/10/26 ;- ; ; THE CODE BEGINS: PRO gsm2lmn,txyz,Bxyz,Blmn,swdat ;Some input check for vector field sizebxyz = SIZE(bxyz) sizetxyz = SIZE(txyz) IF (sizebxyz[0] NE 2) THEN BEGIN dprint, 'gsm2lmn: Bxyz must be vector (array).' RETURN ENDIF IF (sizetxyz[0] NE 2) THEN BEGIN dprint, 'gsm2lmn: You must provide space-time coordinates of input vectors as 2D array.' RETURN ENDIF IF (sizebxyz[1] NE sizetxyz[1]) THEN BEGIN dprint, 'gsm2lmn: first dimensions of coordinate and vector arrays must be equal.' RETURN ENDIF ;Check SW input. sizesw = SIZE(swdat) IF (sizesw[0] EQ 0) THEN BEGIN ;Generate static "standard" SW data. dprint, 'gsm2lmn: No SW input detected. Static MP considered with Bz=0 and Dp=2.088 nPa.' swdata = DBLARR(sizebxyz[1],3) swdata[*,0] = txyz[*,0] swdata[*,1] = 2.088 swdata[*,2] = 0.D ENDIF ELSE BEGIN swdata = DBLARR(sizebxyz[1],3) ;Replace bad values with static data and INTERPOLate Bz and Dp onto the timegrid of Bxyz. timeb = REFORM(txyz[*,0]) swdata[*,0] = timeb timesw = REFORM(swdat[*,0]) dparr = REFORM(swdat[*,1]) ind = WHERE(FINITE(dparr),n,COMPLEMENT=indbad,NCOMPLEMENT=nbad) IF (nbad GT 0) THEN dparr[indbad] = 2.088 ;; nPa - a 'standard' value dparra = INTERPOL(dparr,timesw,timeb) swdata[*,1] = dparra bzarr = REFORM(swdat[*,2]) ind = WHERE(FINITE(bzarr),n,COMPLEMENT=indbad,NCOMPLEMENT=nbad) IF (nbad GT 0) THEN bzarr[indbad] = 0. ;; nT - a 'standard' value bzarra = INTERPOL(bzarr,timesw,timeb) swdata[*,2] = bzarra ENDELSE blmn = DBLARR(sizebxyz[1],sizebxyz[2]) npoints = sizebxyz[1] ;; Transformation starts FOR i=0L, npoints - 1L DO BEGIN bz = swdata[i,2] dp = swdata[i,1] > 0.01 x = txyz[i,1] y = txyz[i,2] z = txyz[i,3] alpha = (0.58 - 0.007*bz)*(1 + 0.024*ALOG(dp)) theta = ACOS(x/SQRT(x^2 + y^2 + z^2)) rho = SQRT(y^2 + z^2) IF (rho GT 0.) THEN BEGIN tang1 = [0.,z,-y] tang2 = [x,y,z]*alpha*SIN(theta)/(1 + COS(theta)) + [-rho^2, x*y, x*z]/rho tang1 = tang1/SQRT(TOTAL(tang1^2)) tang2 = tang2/SQRT(TOTAL(tang2^2)) dN = CROSSP(tang1,tang2) dM = CROSSP(dN, [0,0,1]) dM = dM/SQRT(TOTAL(dM^2)) dL = CROSSP(dM, dN) ENDIF ELSE BEGIN dN = [1.,0.,0.] dM = [0.,-1.,0.] dL = [0.,0.,1.] ENDELSE ;; Define transformation matrix transm = [[dL],[dM],[dN]] ;; Rotate input: GSM -> LMN blmn[i,*] = bxyz[i,*] # transm ENDFOR dprint, 'gsm2lmn finished.' END