;+ ; NAME: ; SWARM_PCP_CALC_GDI ; ; PURPOSE: ; This routines calculates the linear gradient drift instability growth rate and its error from measurements provided by the Swarm electric field instrument. ; ; CALLING SEQUENCE: ; swarm_pcp_calc_gdi, juls, v_sc, v_ion, background, ndens_gradient, error_ndens_gradient, ndens_edge_gradient, error_ndens_edge_gradient, pcp_flag, ps1idx, ps2idx, pe1idx, pe2idx ; ; INPUTS: ; juls: The Julian dates (as provided by IDL's JULDAY function) of the data points from the EFI ; data files. For n data point inside the file this is a vector of length n. ; v_sc: The spacecraft velocity, from the EFI data files. For n data point inside the file this is a vector of diminsion [n,3]. ; v_ion: The ion drift velocity, from the EFI data files. For n data point inside the file this is a vector of diminsion [n,3]. ; background: The background plasma density calculated from the plasma density measurements of the Langmuir probe of the EFI, from the EFI data files. For n data point inside the file this is a vector of length n. ; ndens_gradient: The plasma density gradient calculated as the slope of a linear least-square fit to the (unfiltered) plasma density data by SWARM_PCP_CALC_NGRAD. ; error_ndens_gradient: The 1-sigma uncertainty estimate of the slope of a linear least-square fit to the (unfiltered) plasma density data. ; ndens_edge_gradient: The plasma density gradient calculated as the slope of a linear least-square fit to the (unfiltered) plasma density data on the polar cap patch edges. ; error_ndens_edge_gradient: The 1-sigma uncertainty estimate of the slope of a linear least-square fit to the (unfiltered) plasma density data on the polar cap patch edges. ; pcp_flag: An array containing the PCP flag, as output from SWARM_PCP_FIND_PATCHES. ; ps1idx: An array of indices which mark the beginning of the patch proper of all patches found. ; ps2idx: An array of indices which mark the beginning of the patch proper of all patches found. ; pe1idx: An array of indices which mark the end of the second edge of all patches found. ; pe2idx: An array of indices which mark the end of the patch proper of all patches found. ; ; OUTPUTS: ; None. ; ; OPTIONAL INPUTS: ; None. ; ; OPTIONAL OUTPUTS: ; None. ; ; KEYWORD PARAMETERS: ; ion_velocity: Set this to a named variable that will upon completion contain the absolute ion drift speed used to calculate the linear gradient drift instability growth rate, calculated as the mean over 27 data points. ; ion_edge_velocity: Set this to a named variable that will upon completion contain the absolute ion drift speed used to calculate the linear gradient drift instability growth rate, calculated over the polar cap patch edges. ; gdi_growth_rate: Set this to a named variable that will upon completion contain the linear gradient drift instability growth rate. ; error_gdi_growth_rate: Set this to a named variable that will upon completion contain the error estimate from Gaussian error propagation of the linear gradient drift instability growth rate. ; gdi_edge_growth_rate: Set this to a named variable that will upon completion contain the linear gradient drift instability growth rate, calculated over the polar cap patch edges. ; error_gdi_edge_growth_rate: Set this to a named variable that will upon completion contain the error estimate from Gaussian error propagation of the linear gradient drift instability growth rate, calculated over the polar cap patch edges. ; vi_vs_angle: Set this to a named variable that will upon completion contain the angle (in degree) between the ion drift velocity and the spacecraft velocity. This is used to distinguish between stable and unstable configurations. ; PGRADLEN: Set this to the same number of data points as used for the window with in SWARM_PCP_CALC_NGRAD. ; ; EXAMPLE: ; ; read the electric field data, i.e., the data from both the Thermal Ion Imager and the ; ; Langmuir Probe ; swarm_efi_read, adate, probe, $ ; juls=juls, glats=glats, glons=glons, alts=alts, $ ; ndens=ndens, v_sc=v_sc, v_ion=v_ion, te=te, $ ; preliminary=preliminary ; ; ; Calculate background ; pcp_flag = swarm_pcp_find_patches( mlats, ndens, 551, 35, 7, 50, $ ; background=background ) ; ; ; Calculate the density gradient ; swarm_pcp_calc_ngrad, juls, ndens, v_sc, glats, glons, alts, $ ; ps1idx, ps2idx, pe1idx, pe2idx, $ ; ndens_gradient=ndens_gradient, error_ndens_gradient=error_ndens_gradient, $ ; ndens_edge_gradient=ndens_edge_gradient, error_ndens_edge_gradient=error_ndens_edge_gradient, $ ; PGRADLEN=PGRADLEN ; ; ; Calculate the density gradient ; swarm_pcp_calc_gdi, juls, v_sc, v_ion, background, ndens_gradient, error_ndens_gradient, $ ; ndens_edge_gradient, error_ndens_edge_gradient, pcp_flag, $ ; ps1idx, ps2idx, pe1idx, pe2idx, $ ; ion_velocity=ion_velocity, ion_edge_velocity=ion_edge_velocity, $ ; gdi_growth_rate=gdi_growth_rate, error_gdi_growth_rate=error_gdi_growth_rate, $ ; gdi_edge_growth_rate=gdi_edge_growth_rate, error_gdi_edge_growth_rate=error_gdi_edge_growth_rate, $ ; vi_vs_angle=vi_vs_angle, $ ; PGRADLEN=PGRADLEN ; ; COPYRIGHT: ; This file was developed as part of the Swarm + Innovation: Polar Cap Products project. ; Please visit http://www.mn.uio.no/fysikk/english/research/projects/swarm/ for more information. ; PCP (Polar Cap Products) is a project funded by the European Space Agency ; (Contract No. 4000114121/15/NL/MP) in the framework of the STSE (Support To Science Element) ; Swarm + Innovation Program. ; If you have any questions, please contact Lasse Clausen (lasse.clausen@fys.uio.no) or Wojciech ; Miloch (w.j.miloch@fys.uio.no). ;- pro swarm_pcp_calc_gdi, juls, v_sc, v_ion, background, ndens_gradient, error_ndens_gradient, $ ndens_edge_gradient, error_ndens_edge_gradient, pcp_flag, $ ps1idx, ps2idx, pe1idx, pe2idx, $ ion_velocity=ion_velocity, ion_edge_velocity=ion_edge_velocity, $ gdi_growth_rate=gdi_growth_rate, error_gdi_growth_rate=error_gdi_growth_rate, $ gdi_edge_growth_rate=gdi_edge_growth_rate, error_gdi_edge_growth_rate=error_gdi_edge_growth_rate, $ vi_vs_angle=vi_vs_angle, $ PGRADLEN=PGRADLEN np = n_elements( juls ) vsx = smooth( v_sc[*,0], PGRADLEN ) vsy = smooth( v_sc[*,1], PGRADLEN ) vsz = smooth( v_sc[*,2], PGRADLEN ) vst = sqrt( vsx^2 + vsy^2 + vsz^2 ) if n_elements( v_ion lt 3 ) then begin ion_velocity = make_array( np, /float, value=0. ) ion_edge_velocity = make_array( np, /float, value=0. ) gdi_growth_rate = make_array( np, /float, value=0. ) gdi_edge_growth_rate = make_array( np, /float, value=0. ) error_gdi_growth_rate = make_array( np, /float, value=0. ) error_gdi_edge_growth_rate = make_array( np, /float, value=0. ) vi_vs_angle = make_array( np, /float, value=0. ) return endif vix = smooth( v_ion[*,0], PGRADLEN ) viy = smooth( v_ion[*,1], PGRADLEN ) viz = smooth( v_ion[*,2], PGRADLEN ) vit = sqrt( vix^2 + viy^2 + viz^2 ) ; idx = where( vit gt 6.e3, nidx ) ; if nidx gt 0 then begin ; vix[idx] = !values.f_nan ; viy[idx] = !values.f_nan ; viz[idx] = !values.f_nan ; vit[idx] = !values.f_nan ; endif arg = ( vix*vsx + viy*vsy + viz*vsz )/( vit*vst ) vi_vs_angle = acos( ( arg < 1.) > (-1.) )*!radeg ion_velocity = vit ion_edge_velocity = fltarr( np ) gdi_growth_rate = fltarr( np ) error_gdi_growth_rate = fltarr( np ) gdi_edge_growth_rate = fltarr( np ) error_gdi_edge_growth_rate = fltarr( np ) error_ndens = 0.1*background error_v_ion = replicate( 50., np ) n_p = n_elements(ps1idx) for p=0, n_p-1 do begin ; if p eq 0 then si = 0 else si = pe1idx[p-1]+1 ; if p eq n_p-1 then fi = np-1 else fi = ps1idx[p]-1 ; if fi-si ge 0 then $ ; ion_velocity[si:fi] = 0. si = ps1idx[p] & fi = pe1idx[p] ; GDI growth rate over the entire patch L = background[si:fi]*1e6/ndens_gradient[si:fi] gdi_growth_rate[si:fi] = ion_velocity[si:fi]/L ; GDI growth rate error e_n0 = -ion_velocity[si:fi]*ndens_gradient[si:fi]/(background[si:fi]*1e6)^2*error_ndens[si:fi]*1e6 e_v0 = ndens_gradient[si:fi]/(background[si:fi]*1e6)*error_v_ion[si:fi] e_kp = ion_velocity[si:fi]/(background[si:fi]*1e6)*error_ndens_gradient[si:fi] error_gdi_growth_rate[si:fi] = sqrt( e_n0^2 + e_v0^2 + e_kp^2 ) si = ps1idx[p] & fi = ps2idx[p] ; GDI growth rate over first edge ion_edge_velocity[si:fi] = mean( ion_velocity[si:fi], /nan ) L_edge = mean( background[si:fi]*1e6 )/ndens_edge_gradient[si] gdi_edge_growth_rate[si:fi] = ion_edge_velocity[si]/L_edge ; GDI growth rate error e_n0 = -ion_edge_velocity[si]*ndens_edge_gradient[si]/mean( background[si:fi]*1e6 )^2*0.1*mean( background[si:fi]*1e6 ) e_v0 = ndens_edge_gradient[si]/mean( background[si:fi]*1e6 )*error_v_ion[si] e_kp = ion_edge_velocity[si]/mean( background[si:fi]*1e6 )*error_ndens_edge_gradient[si] error_gdi_edge_growth_rate[si:fi] = sqrt( e_n0^2 + e_v0^2 + e_kp^2 ) si = pe2idx[p] & fi = pe1idx[p] ; GDI growth rate over second edge ion_edge_velocity[si:fi] = mean( ion_velocity[si:fi], /nan ) L_edge = mean( background[si:fi]*1e6 )/ndens_edge_gradient[si] gdi_edge_growth_rate[si:fi] = ion_edge_velocity[si]/L_edge ; GDI growth rate error e_n0 = -ion_edge_velocity[si]*ndens_edge_gradient[si]/mean( background[si:fi]*1e6 )^2*0.1*mean( background[si:fi]*1e6 ) e_v0 = ndens_edge_gradient[si]/mean( background[si:fi]*1e6 )*error_v_ion[si] e_kp = ion_edge_velocity[si]/mean( background[si:fi]*1e6 )*error_ndens_edge_gradient[si] error_gdi_edge_growth_rate[si:fi] = sqrt( e_n0^2 + e_v0^2 + e_kp^2 ) ; determine leading/trailing edge and set PCP_FLAG ; PCP_FLAG is set to 2 across the entire patch (including edges) in SWARM_PCP_FIND_PATCHES ; ; PCP_FLAG is ; 0 if the plasma density measurement occurred OUTSIDE a polar cap patch; ; 1 if the plasma density measurement occurred at the LEADING edge of a polar cap patch; ; 2 if the plasma density measurement occurred INSIDE a polar cap patch proper; ; 3 if the plasma density measurement occurred at the TRAILING edge of a polar cap patch. if total(v_ion[ps1idx[p]:pe1idx[p],*]) eq 0. then continue mang = mean( vi_vs_angle[ps1idx[p]:pe1idx[p]], /nan ) if finite( mang ) then begin ; spacecraft and ion velocity are parallel, i.e., ; first edge encountered is trailing edge if mang lt 90. then begin pcp_flag[ ps1idx[p]:ps2idx[p]-1 ] = 3 pcp_flag[ pe2idx[p]+1:pe1idx[p] ] = 1 ; spacecraft and ion velocity are anti-parallel, i.e., ; first edge encountered is leading edge endif else begin pcp_flag[ ps1idx[p]:ps2idx[p]-1 ] = 1 pcp_flag[ pe2idx[p]+1:pe1idx[p] ] = 3 ; we need to reverse the sign of the GDI growth rates in this case gdi_growth_rate[ps1idx[p]:pe1idx[p]] *= -1. gdi_edge_growth_rate[ps1idx[p]:pe1idx[p]] *= -1. endelse endif endfor end