<jupyter_start><jupyter_text>Denton Analysis ToolThe `Denton` Analysis Tool may be used on MMS data to contrust 3d magnetic field vectors.The main interface is the `Denton` object, which is a subclass of `Kamodo`, a CCMC toolthat provides a functional interface for space weather models and data.<jupyter_code>cd ../AsherCode
from Denton import Denton

sDirData = "/Users/apembrok/git/mms/AsherCode/"

denton = Denton(sDirData=sDirData, solve = True)<jupyter_output><empty_output><jupyter_text>Fieldline visualizationTo visualize field lines, we need to solve the initial value problem on $\vec{B}(\vec{x},t)$ given an initial set of seeds points. Variable selectionFirst we'll construct a new kamodo instance so we can focus on just the field manipulation<jupyter_code>from kamodo import Kamodo
fields = Kamodo(Bvec = denton.Bvec)
fields<jupyter_output><empty_output><jupyter_text>Time selectionSince we are tracing in space and not time, we need a new function representing the field at a fixed time.<jupyter_code>t0 = 32.91
from kamodo import kamodofy, pointlike
import numpy as np

@kamodofy
@pointlike(signature = '(n,m)->(n,m)', otypes = [np.float], squeeze = 0)
def bvec(xvec):
    return denton.Bvec(xvec, bvec.t)

bvec.t = t0 

fields['bvec'] = bvec
fields<jupyter_output><empty_output><jupyter_text>Note that $\vec{b}(\vec{x_1(t)})$ should match $\hat{B_1}(t)$<jupyter_code>denton.Bvechat_1(t0)
fields.bvec(denton.xvec_1(t0))<jupyter_output><empty_output><jupyter_text>Field normalizationTo control the spatial resolution of the solver, we'll register a normalized version of the field.<jupyter_code>import numpy as np

@kamodofy(equation = "$$\\hat{n}(\\vec{y}) = \\vec{y}/\\sqrt{\\vec{y} \\cdot \\vec{y}} $$")
@pointlike(signature = '(m,n)->(m,n)', squeeze = 0)
def normalized(yvec):   
    r = np.linalg.norm(yvec, axis = 1)
    r[r==0] = np.nan

    try:
        return yvec/r
    except:
        return (yvec.T/r).T
    
fields['nhat'] = normalized
fields<jupyter_output><empty_output><jupyter_text>Now that we can register a normalized version of the spatial magnetic field.<jupyter_code>fields['bhat'] = 'nhat(bvec)'
fields<jupyter_output><empty_output><jupyter_text>Tracer limitsWe need to specify a boundary condition for the tracer so it does not go out of bounds. This can be any function of field line length and current position, but it must return positive when inside the bounds and negatie when outide.<jupyter_code>from kamodo import event


def boundary(s, rvec):
    """Boundary of the tracer domain"""
    r = np.linalg.norm(rvec)
    
    if np.isnan(r):
        result = 0
    else:
        result = boundary.rmax - r
    return result

# set boundary parameters
boundary.rmax = denton.intro.Lmax
boundary.terminal = True
boundary.direction = 0
fields['bc'] = kamodofy(boundary)
fields<jupyter_output><empty_output><jupyter_text>Defining Seed pointsWe will trace from locations of the four MMS spacecraft for this point in time.<jupyter_code>t0
seeds = np.vstack([denton['xvec_{}'.format(isat+1)](t0) for isat in range(4)])
seeds<jupyter_output><empty_output><jupyter_text>Tracing the fieldWe now have everything we need to trace the fieldlines. First import the solve method kamodo, which wraps scipy's solve_ivp method.<jupyter_code>from kamodo.util import solve
fields['lvec'] = solve(
    fields.bhat,
    seeds, 's',
    (0,3),
    npoints = 15,
    events = fields.bc)
fields<jupyter_output><empty_output><jupyter_text>To get the positions along the fieldline, call $\vec{l}$ with default arguments.<jupyter_code>fields.lvec().head()<jupyter_output><empty_output><jupyter_text>VisualizationWe visualize the results using plotly.<jupyter_code>from plotly.offline import init_notebook_mode, iplot
init_notebook_mode(connected = True)
fig = fields.plot('lvec', bhat = dict(xvec = fields.lvec()))<jupyter_output><empty_output><jupyter_text>The plot command above generates a figure depicting fieldlines along with associated vectors. However, in order to match the perspective from the paper, we need to modify some of the figure's scene properties:<jupyter_code>fig.layout['scene']['camera']['projection']['type'] = 'orthographic'
fig.layout['autosize'] = True
fig.layout.scene.xaxis.title.text = 'L/L_sc'
fig.layout.scene.zaxis.title.text = 'N/N_sc'
fig.layout.scene.xaxis.range = [-2.5,2.5]
fig.layout.scene.yaxis.range = [-2.5,2.5]
fig.layout.scene.zaxis.range = [-2.5,2.5]
# fig.layout['width'] = 1500
# fig.layout['height'] = 700
fig.layout.scene.aspectmode = 'cube'<jupyter_output><empty_output><jupyter_text>Save the figure as svg with plotly-orca!!! note    You must have plotly-orca installed `conda install -c plotly plotly-orca`<jupyter_code>import plotly.io as pio
pio.write_image(fig, 'images/streamlines3d.svg')<jupyter_output><empty_output><jupyter_text>![streamlines](images/streamlines3d.svg?3)<jupyter_code># use iplot for an interactive plot in jupyter notebook
iplot(fig)<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.11763518966908798, 'fraction_numerical': 0.009887005649717515, 'mean_word_length': 5.522368421052631, 'pattern_counts': {'":': 0, '<': 57, '<?xml version=': 0, '>': 59, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '14', 'dir': 'jupyter-structured-clean-dedup', 'id': '381098', 'license': 'MIT', 'n_tokens_mistral': 1743, 'n_tokens_neox': 1688, 'n_words': 459, 'path': 'docs/FieldLines.ipynb', 'repo_name': 'asherp/mms_reconstruction', 'size': '4956'}