brender documentation

42
BRender Documentation Release 1.0 Hayk Hakobyan Sep 30, 2018

Upload: others

Post on 23-Apr-2022

8 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: BRender Documentation

BRender DocumentationRelease 1.0

Hayk Hakobyan

Sep 30, 2018

Page 2: BRender Documentation
Page 3: BRender Documentation

Contents:

1 Getting things ready 11.1 Installation for Mac users . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11.2 Installation for tigressdata users . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3

2 Basics of BRender 92.1 Camera . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92.2 Viewport navigation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102.3 Rendering . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112.4 Bounding box . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112.5 Creating a sphere . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122.6 Running a script . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122.7 Interactive viewport . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12

3 Volume plot 133.1 Generating VOXEL data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 133.2 Making volumetric plot . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153.3 Full python script . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16

4 Particle plot 234.1 Generating particle coordinates . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 234.2 Making particle plot . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 244.3 Full python script . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26

5 Fieldline plot 315.1 Generating fieldlines . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 315.2 Plotting fieldlines . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 325.3 Full python script . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35

i

Page 4: BRender Documentation

ii

Page 5: BRender Documentation

CHAPTER 1

Getting things ready

1.1 Installation for Mac users

1.1.1 Installation

Clone BRender repo

1. Go to any desired directory of your choice within the terminal.

2. Clone the repo:

$ git clone https://github.com/haykh/brender_astro.git

3. The library and all the necessary files will be downloaded to the current directory.

Warning: We’ll next download and install the main Blender app. This requires several hundreds MB of diskspace, so be prepared.

Installing and configuring Blender

1. Download Blender app from here.

2. Drag and drop Blender app to the Applications folder.

Note: We then need to adjust some of the Blender import/export files. You can do it manually following steps 3-6, orif you have version 2.79 you can simply download the already fixed files and replace the original ones (see step 7).

3. Navigate to the following folder:

1

Page 6: BRender Documentation

BRender Documentation, Release 1.0

$ cd /Applications/blender.app/Contents/Resources/2.**/scripts/addons/io_scene_→˓obj/

where 2.** is your Blender version, which in my case is 2.79.

4. Open import_obj.py and add these two lines:

# ...elif line_id == b'tf':

# rgb, filter color, blender has no support for this.pass

elif line_id == b'em': # ADD THIS LINE (BRender)context_material.emit = float_func(line_split[1]) # ADD THIS LINE (BRender)

elif line_id == b'illum':illum = int(line_split[1])

# ...

5. In the same file comment out the following line:

# ...if emit_value > 1e-6:

if use_cycles:print("WARNING, currently unsupported emit value, skipped.")

# We have to adapt it to diffuse color too...emit_value /= sum(context_material.diffuse_color) / 3.0

# context_material.emit = emit_value # <- COMMENT THIS LINE OUT (BRender)if not do_ambient:

context_material.ambient = 0.0# ...

6. Save the file and open export_obj.py. Add this line and save the file:

# ...elif mat.use_transparency and mat.transparency_method == 'RAYTRACE':

fw('illum 9\n') # 'Glass' transparency and no Ray trace reflection...→˓fuzzy matching, but...

else:fw('illum 2\n') # light normaly

fw('em %.6f\n' % mat.emit) # ADD THIS LINE (BRender)else:

# Write a dummy material here?# ...

7. For the sake of convenience, I added those two .py files for Blender 2.79, so you can just download and replacethe original ones which are in here /Applications/blender.app/Contents/Resources/2.79/scripts/addons/io_scene_obj/.

Configuring Blender’s bundled python

• For Blender version 2.79 (on Mac) do:

$ bash setup_python.sh

from the setup_python/ directory (where the get-pip.py file is). This will install pip using the get-pip.py file (from the same directory as the .sh file) in the bundled python and will then install h5py which is necessaryfor loading hdf5 files in the Blender.

2 Chapter 1. Getting things ready

Page 7: BRender Documentation

BRender Documentation, Release 1.0

• For newer/older versions you can try adjusting the directory in the .sh file, but since the python versioncan change, this might not work. Anyway, in general the idea is to have Blender’s bundled python run theget-pip.py file (to install pip), and then run the newly installed Blender’s bundled pip to install h5py.Something like this:

$ /path/to/blender.app/Contents/Resources/2.XX/python/bin/python get-pip.py$ /path/to/blender.app/Contents/Resources/2.XX/python/bin/pip install h5py

1.1.2 Blender setup

1. If you haven’t cloned this repo yet, it’s time to do it:

$ cd /any-folder-you-like/$ git clone https://github.com/haykh/brender_astro.git

2. Then navigate to initialize_blender/ inside the cloned repository and open init_script.py.

3. Modify the path in the 2-nd line writing the correct path to the downloaded BRender repo.

4. Open bash_profile with $ open -e ~/.bash_profile and add the following line with a correctpath to the downloaded repo:

alias blender='/Applications/blender.app/Contents/MacOS/blender -P /path/to/→˓brender/initialize_blender/init_script.py'

5. Restart the terminal. Now if we do $ blender in the terminal, the Blender app will launch pre-running theinit_script.py, which imports the module and does a quick setup of lighting.

6. From cloned BRender repo copy initialize_blender/mac/startup.blend file to /Users/<user>/Library/Application Support/Blender/2.**/config (if the folder doesn’t exist -create it). This will set a default working screen that (for me) fits the best for script-based visualization.

Now once you run:

$ blender

from the terminal, you should see two Blender windows (especially convenient if you use two screens).

• (left) code editor in case we want to run or edit a large script

• (right) python console that uses Blender’s bundled Python 3 (most of the time we’ll be using this console)

• (down) code editor log

• (left) 3D viewport with all the objects of our scene

• (middle) rendered image will be displayed here, which is now just empty

• (right) Properties tab with all the material and object properties

7. You can also configure your own workspace layout (consoles, 3d viewports etc) and save it as default by doingCtrl+U.

1.2 Installation for tigressdata users

1.2.1 Installation

For tigressdata cluster machines you can go in two different ways.

1.2. Installation for tigressdata users 3

Page 8: BRender Documentation

BRender Documentation, Release 1.0

4 Chapter 1. Getting things ready

Page 9: BRender Documentation

BRender Documentation, Release 1.0

• Easy way: you make an alias to run an already configured Blender from my home directory.

• Difficult way: you download and set everything up yourself.

Easy way

Note: Make sure you have pre-loaded module virtualgl. Check this by doing $ module list. To load it youcan do $ module load virtualgl/2.3.3.

1. Open your bash profile by doing:

$ gedit ~/.bashrc

2. Add the following alias to the end of the file:

alias blender="vglrun /home/hakobyan/Downloads/Blender/blender -P /home/hakobyan/→˓Downloads/BRender/initialize_blender/init_script.py"

You’re all set. Now by running blender from the command line you’ll get a Blender app with preloaded BRendermodule. You might also want to set up a default scene, check instructions here.

Difficult way

Clone BRender repo

1. Go to any desired directory of your choice.

2. Do $ git clone https://github.com/haykh/brender_astro.git to clone the repo.

3. The library and all the necessary files will be downloaded to the current directory.

Warning: We’ll next download the Blender app. This requires several hundreds MB of disk space, so be prepared.

Installing and configuring Blender

1. Download Blender 2.76 from here.

2. Extract the archive.

Note: We then need to adjust some of the Blender import/export files. You can do it manually following steps 3-6, oryou can simply download the already fixed files and replace the original ones (see step 7).

3. Navigate to the following folder:

$ cd /path-to-blender-installation/2.76/scripts/addons/io_scene_obj/

4. Open import_obj.py and add these two lines:

1.2. Installation for tigressdata users 5

Page 10: BRender Documentation

BRender Documentation, Release 1.0

# ...elif line_id == b'tf':

# rgb, filter color, blender has no support for this.pass

elif line_id == b'em': # ADD THIS LINE (BRender)context_material.emit = float_func(line_split[1]) # ADD THIS LINE (BRender)

elif line_id == b'illum':illum = int(line_split[1])

# ...

5. In the same file comment out the following line:

# ...if emit_value > 1e-6:

# We have to adapt it to diffuse color too...emit_value /= sum(context_material.diffuse_color) / 3.0

# context_material.emit = emit_value # <- COMMENT THIS LINE OUT (BRender)if not do_ambient:

context_material.ambient = 0.0# ...

6. Save the file and open export_obj.py. Add this line and save the file:

# ...elif mat.use_transparency and mat.transparency_method == 'RAYTRACE':

fw('illum 9\n') # 'Glass' transparency and no Ray trace reflection...→˓fuzzy matching, but...

else:fw('illum 2\n') # light normaly

fw('em %.6f\n' % mat.emit) # ADD THIS LINE (BRender)else:

# Write a dummy material here?# ...

7. For the sake of convenience, I added those two .py files for Blender 2.76, so you can just download and replacethe original ones which are in here /path-to-blender-installation/2.76/scripts/addons/io_scene_obj/.

1.2.2 Blender setup

Note: If you followed the “Easy Way” in the installation section proceed to step 6.

1. If you haven’t cloned this repo yet, it’s time to do it:

$ cd /any-folder-you-like/$ git clone https://github.com/haykh/brender_astro.git

2. Then navigate to initialize_blender/ inside the cloned repository and open init_script.py.

3. Modify the path in the 2-nd line writing the correct path to the downloaded repo.

4. Open bash_profile with $ gedit ~/.bashrc and add the following line with a correct path to the down-loaded repo and blender:

6 Chapter 1. Getting things ready

Page 11: BRender Documentation

BRender Documentation, Release 1.0

alias blender='vglrun /path-to-blender/blender -P /path-to-brender/initialize_→˓blender/init_script.py'

Note: Make sure you have pre-loaded module virtualgl. Check this by doing $ module list. To load it youcan do $ module load virtualgl/2.3.3.

5. Restart the terminal. Now every time we do $ blender in the terminal, the Blender app will launch pre-running the init_script.py, which imports the module and does a quick setup of lighting.

6. From cloned BRender repo (or from here) copy initialize_blender/tigressdata/startup.blend file to /home/<username>/.config/blender/2.76/config/ (if the folder doesn’t exist,create it). This will set a default working screen that (for me) fits the best for script-based visualization.

Now once you run:

$ blender

from the terminal, you should see the following Blender window.

• (top left) 3D viewport with all the objects of our scene

• (top right) rendered image will be displayed here, which is now just empty

• (right) Properties tab with all the material and object properties

• (bottom) python console that uses Blender’s bundled Python 3 (most of the time we’ll be using this console)

7. You can also configure your own workspace layout (consoles, 3d viewports etc) and save it as default by doingCtrl+U.

1.2. Installation for tigressdata users 7

Page 12: BRender Documentation

BRender Documentation, Release 1.0

8 Chapter 1. Getting things ready

Page 13: BRender Documentation

CHAPTER 2

Basics of BRender

Now that we have everything set up and have Blender windows open with console and pre-loaded python script, let’stry to do some basics. In principle, anything done below can be done without coding at all by using the Blender GUI.However, sometimes it is much faster and easier to do things using simple scripts.

First in the console do:

import brender as br

This will import BRender module with all the functions.

2.1 Camera

Let’s first create a camera and an empty object which will serve as a flag where the camera will be pointing:

cam = br.initializeCamera()

Now cam contains the camera object and the related empty object. By default camera will have a particular location,which can be changed by doing:

cam.location = (3.2, -2.5, 1.4)

We can also adjust where the direction at which camera is pointing:

cam.pointing = (0.4, 1., 1.)

This might be handy when doing an animation and need a complex camera motion. Other options to play around with:

cam.type = 'PERSP' # 'ORTHO', 'PANO' # <- this is camera typecam.lens = 50 # <- focal length for type 'PERSP' camera type onlycam.ortho_scale = 3.5 # <- orthographic scale for type 'ORTHO' camera type only

9

Page 14: BRender Documentation

BRender Documentation, Release 1.0

Note: If you want to explore the attributes further, feel free to navigate cursor on different parameters in theProperties bar. When hovering over, Blender will show the python script for the attribute, such as bpy.data.cameras['Camera'].type, where bpy.data.cameras['Camera'] is our cam object.

2.2 Viewport navigation

This part is strictly GUI based. Usually the navigation in the 3d viewport is being done by numpad keys, howevermost of the people don’t have numpads.

2.2.1 Mac users

On mac the easiest way of navigation is via trackpad. Standard gestures are:

• two-finger pinch (for zoom)

• swipe (for rotate)

• Shift + swipe (for move)

Mouse gestures:

• middle mouse scroll (for zoom)

• middle mouse + move (for rotate)

• Shift + middle mouse + move (for move)

These gestures can be configured from inside Blender: File -> User Preferences (Cmd+,), from the Inputtab find 3D View and then 3D View (Global) dropdown menu. Then click Save User Settings below.

2.2.2 Tigressdata users

On tigressdata (via vnc) Mac trackpad gestures do not work. So you will either need to have a mouse with the samegestures (see above), or you can configure gestures

These gestures can be configured from inside Blender: File -> User Preferences (Ctrl+Alt+U), from theInput tab find 3D View and then 3D View (Global) dropdown menu. Adjust:

• Set 3D Cursor set to something else

• Rotate View set Left Mouse

• Move View set Shift Left Mouse

Again, click Save User Settings. Now you can rotate and move with a simple trackpad click.

Note: You can also just copy my userpref.blend file from here (/home/hakobyan/.config/blender/2.76/config/) and paste it to your (/home/<username>/.config/blender/2.76/config/) direc-tory. If the directory doesn’t exist, create it.

10 Chapter 2. Basics of BRender

Page 15: BRender Documentation

BRender Documentation, Release 1.0

2.3 Rendering

Let us first assign a render directory and a desired tag-name for the rendered images:

render_directory = '/directory-of-choice/'name = 'plot_'render = br.Render(render_directory, render_name)

Now if we want to render an image from the active camera we simply run:

render.render()

This is handy if we’re doing multiple shots, but if we just want to look at a single snapshot, it’s probably easier to pressF12 (fn+F12 for Mac) for quick render. The result will be shown in one of the Blender windows.

We can also change the resolution of our render by doing:

br.Render.set_resolution(1000, 1000) # <- these are the values I usually use

2.4 Bounding box

In some cases we’ll need a simple bounding box to make a 3D image more clear for perception. In BRender we cansimply do:

bbox = br.BoundingBox(name = 'bbox')bbox.size = [3.5, 1, 2] # <-- adjusting shapebbox.location = [1, 0, 0] # <-- adjusting locationbbox.color = '#36b3c4' # <-- you can give color in any other format, e.g., (0.2, 0.34,→˓ 0.8) etcbbox.intensity = 15. # <-- adjusting emission intensity of the bounding box

2.3. Rendering 11

Page 16: BRender Documentation

BRender Documentation, Release 1.0

Note: I naturally prefer to keep everything simple, so all the visualization made in this module will be rescaled andplotted in the 2x2x2 cube (or with different aspect) centered in the (0,0,0).

Note: We can also change the material parameters from the GUI. The easiest way to do this is to access the materialtab in the Properties and adjust the relevant numbers.

2.5 Creating a sphere

Sometimes it’s useful to visualize a simple object (such as a star) along with the simulation results to give a senseabout the scales involved. In BRender you can do this by simply typing:

star = br.Sphere(name = 'my_star')# then we can adjust location, color, size and emission intensity in the same fashionstar.size = (1.4, 1.4, 1.4)star.location = (1, 0.4, -1)star.intensity = 0.5

2.6 Running a script

If scripting in the Blender console doesn’t work for you, one can easily run a script written in the .py file withrunScript() function:

br.runScript('/path-to-script/script.py')

Note: Be aware, that after a script is ran from the file you cannot directly access the objects from the console. Runninga script like that is handy if you already have a tested code and you don’t want to copy+paste it to console every timeyou want to visualize new data.

2.7 Interactive viewport

Sometimes when we need to briefly look at the render result from different angles to choose the right perspective, wecan do this without actually rendering the image itself in a sort of interactive render regime.

To do this, activate Rendered viewport shading option in the 3D viewport as shown in the animation below.

The resulting interactive regime is shown below.

12 Chapter 2. Basics of BRender

Page 17: BRender Documentation

CHAPTER 3

Volume plot

Before starting this section make sure to have a camera set up. Also if there’s a bounding box in the scene, it’s generallyeasier to navigate and understand the directions in space. So before moving forward, check previous tutorial on basicsof BRender.

Note: for tigressdata users. Blender’s bundled python does not support hdf5 documents, and I wasn’t able to installit (no access). So you’ll have to do all the reading and primary analysis of all the data from some python outsideBlender.

3.1 Generating VOXEL data

In general BRender is not constrained to any specific code output, and can be fed by any sort of Blender VOXEL(volumetric pixel) data file generated in advance. So if you know how to generate a .bvox file from a specific codeoutput, feel free to skip to the next section where we’ll be making a volumetric plot.

Here we’ll discuss how to generate a .bvox file particularly for TRISTAN code output (hdf5 format), which will belater used to make a plot. Note again, that if you’re working from within the tigressdata, you’ll have to do this from apython outside Blender, Mac users can do this from inside Blender console. We first need to specify several paths andnames:

# For tigressdata do this whole procedure from outside Blender python consoleout_path = '/output-dir-for-bvox/' # <-- make sure to have slash in the endfname = '/path-to/flds.tot.001' # <-- this one is specifically a TRISTAN output fileprefix = 'density' # <-- this is the prefix name of the file, in our case - density

Let’s say we want to plot a density. For that we specify a value function which takes the code data as an input andoutputs the desired field in the correct form:

def valueFunc(data):return data['dens'].value # <-- we output whatever is under 'dens' key value

13

Page 18: BRender Documentation

BRender Documentation, Release 1.0

Note: If you don’t specify valueFunc() it will take a default function (which is just the 'dens' key).

Note: You could think of something more complicated, like a current density normalized by the distance to the centerof the grid squared (this is relevant to pulsar magnetosphere simulations):

def valueFunc(data):sx, sy, sz = data['jx'].value.shapehalfx, halfy, halfz = map(np.floor, np.array([sx, sy, sz]*0.5))rsquared = np.array([[[((x - halfx)**2 + (y - halfy)**2 + (z - halfz)**2) for x

→˓in range(sx)] for y in range(sy)] for z in range(sz)])return np.sqrt(np.array(data['jx'].value)**2 + np.array(data['jy'].value)**2 + np.

→˓array(data['jz'].value)**2) * rsquared

We can also specify a normalization function if we want (the default is just linear normalization):

def normalizeFunc(value):return np.log(1. + value) # <-- accepts real value and outputs normalized value

Other two options to specify are the maximum and minimum value. After the normalization, any value in the 3D gridabove that maximum value and below the minimum will be diminished and set to the specified value:

min_val = 0.1 # <-- our function does the following val[val < min_val] = min_valmax_val = 0.8 # <-- our function does the following val[val > max_val] = max_val

Note: Default (in case you don’t specify) for min_val is 0, and for max_val is 1.

Ok, now with all those variables and functions specified, we are ready to output a .bvox file in the directory specifiedabove:

import lib.to_bvox as bvoxbvoxfile = bvox.makeBvox(out_path, fname,

valueFunc = valueFunc, # optionalnormalizeFunc = normalizeFunc, # optionalmin_val = min_val, max_val = max_val, # optionalprefix = prefix) # optional

# now bvoxfile is a string containing the path to the generated `.bvox` file in case→˓you need it

This might take some time, but you need to do this once to generate the .bvox file, later you can just refer to it witha full path to make plots.

Warning: For tigressdata you’ll first need to append sys.path when working outside Blender (add this at thestart of code):

import syssys.path.append('/path-to-BRender-repo/') # you can use mine '/home/hakobyan/→˓Downloads/brender_astro'

Also make sure you have h5py module loaded (in the terminal):

$ module load h5py27

14 Chapter 3. Volume plot

Page 19: BRender Documentation

BRender Documentation, Release 1.0

3.2 Making volumetric plot

3.2.1 Finding the shape and scale

Since you’ll later need a shape of your simulation and scaling factor for your visualization, I’d suggest to do it rightaway with the following code:

# make sure to do 'import lib.to_bvox as bvox' as you probably did abovefname = '/path-to/flds.tot.001'shape0 = np.array(bvox.getShape(fname, 'dens'))scale = 2. / shape0.min()shape = shape0 * scale

Now shape is a tuple of 3 float numbers with the normalized (size-x, size-y, size-z) of your data, andscale is a float number that determines how much is the original data “squeezed”. Again, tigressdata users can runthis only outside Blender’s python.

3.2.2 Nailing the plot

Note: For tigressdata the rest can be done within the Blender console.

If you working within tigressdata, specify a path to .bvox file:

bvoxfile = '/path-to/dens.bvox'

You then can make an object that will have your volumetric plot:

density = br.VolumePlot(bvoxfile, name = 'my_density')

Note: If you later decide to redo your plot using a different .bvox file, there is no need to delete the object. Simplydo:

density.voxdata = '/path-to-new/bvoxfile.bvox'

This will redo the plot only changing the volumetric pixel data provided (shape and other parameters will remain thesame).

This creates a cube and fills it in according to voxel data. You can then work with this density object. By defaultthe density is in 2x2x2 cube. We can adjust it by doing:

density.size = shape # <-- set the shape to already predefined

We can also adjust the colormap and brightness:

# let us first define a colormapcmap = [[0.0, # <-- this is the position of the first color tag

(0, 0, 1, 0)], # <-- this is the color in terms of (r, g, b, a)[0.7,

(0, 0, 1, 0.3)],[0.86,

(0.56, 0.878, 0.002, 0.8)],

(continues on next page)

3.2. Making volumetric plot 15

Page 20: BRender Documentation

BRender Documentation, Release 1.0

(continued from previous page)

[1,(1, 0, 0, 1.0)]]

# ... and brightnessbrightness = 0.6density.cmap = cmapdensity.brightness = brightness

Other more complex parameters to adjust are the density and contrast:

density.density = 5.density.contrast = 0.35

Note: You can always play with those parameters (colormap, brightness, contrast, density, etc) from the Blender GUI(see below).

Below is a rendering result of such a plot.

Note: We can also enable the interactive viewport to look at the result from different angles on the fly (see here onhow to do this).

3.3 Full python script

3.3.1 for Mac

"""Example code to run within Blender to produce the plot show above (Mac version)

Note: Make sure to change all the paths below

"""

import brender as br

# # # # # # # # # # # # # # # # # # # # # # # ### 1. Preparing## # # # # # # # # # # # # # # # # # # # # # # ## setting up the cameracam = br.initializeCamera()cam.location = (4.5, -1.2, 0.7)cam.pointing = (0, 0, 0)

# setting up the rendererrender_directory = '/any-folder/images/'render_name = 'mysim_'render = br.Render(render_directory, render_name)

br.Render.set_resolution(1000, 1000)

(continues on next page)

16 Chapter 3. Volume plot

Page 21: BRender Documentation

BRender Documentation, Release 1.0

3.3. Full python script 17

Page 22: BRender Documentation

BRender Documentation, Release 1.0

(continued from previous page)

import lib.to_bvox as bvoximport numpy as np

# finding the shape and scale of our simulationfname = '/path-to/flds.tot.001' # <-- this is for TRISTANshape0 = np.array(bvox.getShape(fname, 'dens'))scale = 2. / (shape0.min())shape = shape0 * scale

# # # # # # # # # # # # # # # # # # # # # # # ### 2. Generating .bvox file# if the .bvox already exists, just skip this step## # # # # # # # # # # # # # # # # # # # # # # #out_path = '/any-folder/bvoxfile/'

prefix = 'current'

# we will be plotting the |j|*R^2 for pulsar simulationdef valueFunc(data):

sx = len(data['jx'].value[0][0])sy = len(data['jx'].value[0])sz = len(data['jx'].value)halfx = np.floor(sx/2.)halfy = np.floor(sy/2.)halfz = np.floor(sz/2.)rsquared = np.array([[[((x - halfx)**2 + (y - halfy)**2 + (z - halfz)**2)

for x in range(sx)]for y in range(sy)]for z in range(sz)])

return np.sqrt(np.array(data['jx'].value)**2 + np.array(data['jy'].value)**2 + np.→˓array(data['jz'].value)**2) * rsquared

# in log unitsdef normalizeFunc(value):

return np.log(1. + value)

bvoxfile = bvox.makeBvox(out_path, fname,valueFunc = valueFunc,normalizeFunc = normalizeFunc,max_val = 0.1,prefix = prefix)

# now bvoxfile has the path to .bvox

# # # # # # # # # # # # # # # # # # # # # # # ### 3. Plotting## # # # # # # # # # # # # # # # # # # # # # # ## generating the VolumePlot class objectdensity = br.VolumePlot(bvoxfile, name = 'my_current')

# adjusting shape, etcdensity.size = shape

(continues on next page)

18 Chapter 3. Volume plot

Page 23: BRender Documentation

BRender Documentation, Release 1.0

(continued from previous page)

density.brightness = 1.1density.contrast = 1.1density.intensity = 10.density.density = 3.

# making a bounding boxbbox = br.BoundingBox(name = 'bbox')

# adjusting parametersbbox.size = shapebbox.color = '#36b3c4'bbox.intensity = 0.2

# ...and finally rendering (or use Fn+F12)render.render()# image saved to the directory defined above

3.3.2 for tigressdata

outside Blender:

"""Example code to run outside Blender (tigressdata version)

Note: Make sure to change all the paths belowNote2: This is to be run outside Blender

"""

import syssys.path.append('/path-to-brender-repo') # you can use mine: '/home/hakobyan/→˓Downloads/brender_astro'import lib.to_bvox as bvox

# # # # # # # # # # # # # # # # # # # # # # # ### 1. Preparing## # # # # # # # # # # # # # # # # # # # # # # #fname = '/path-to/flds.tot.001'shape0 = np.array(bvox.getShape(fname, 'dens'))scale = 2. / (shape0.min())shape = shape0 * scale

# you need to copy this parameters laterprint (shape)print (scale)

# # # # # # # # # # # # # # # # # # # # # # # ### 2. Generating .bvox file# if the .bvox already exists, just skip this step## # # # # # # # # # # # # # # # # # # # # # # #out_path = '/any-folder/bvoxfile/'

(continues on next page)

3.3. Full python script 19

Page 24: BRender Documentation

BRender Documentation, Release 1.0

(continued from previous page)

prefix = 'current'

# we will be plotting the |j|*R^2 for pulsar simulationdef valueFunc(data):

sx = len(data['jx'].value[0][0])sy = len(data['jx'].value[0])sz = len(data['jx'].value)halfx = np.floor(sx/2.)halfy = np.floor(sy/2.)halfz = np.floor(sz/2.)rsquared = np.array([[[((x - halfx)**2 + (y - halfy)**2 + (z - halfz)**2)

for x in range(sx)]for y in range(sy)]for z in range(sz)])

return np.sqrt(np.array(data['jx'].value)**2 + np.array(data['jy'].value)**2 + np.→˓array(data['jz'].value)**2) * rsquared

# in log unitsdef normalizeFunc(value):

return np.log(1. + value)

bvoxfile = bvox.makeBvox(out_path, fname,valueFunc = valueFunc,normalizeFunc = normalizeFunc,max_val = 0.1,prefix = prefix)

inside Blender:

"""Example code to run inside Blender (tigressdata version)

Note: Make sure to change all the paths belowNote2: This is to be run inside Blender, we do not refer to h5py here

"""

# # # # # # # # # # # # # # # # # # # # # # # ### 1. Preparing## # # # # # # # # # # # # # # # # # # # # # # ## setting up the cameracam = br.initializeCamera()cam.location = (4.5, -1.2, 0.7)cam.pointing = (0, 0, 0)

# setting up the rendererrender_directory = '/any-folder/images/'render_name = 'mysim_'render = br.Render(render_directory, render_name)

br.Render.set_resolution(1000, 1000)

# # # # # # # # # # # # # # # # # # # # # # # ### 2. Plotting#

(continues on next page)

20 Chapter 3. Volume plot

Page 25: BRender Documentation

BRender Documentation, Release 1.0

(continued from previous page)

# # # # # # # # # # # # # # # # # # # # # # # ## generating the VolumePlot class objectbvoxfile = '/path-to-saved/bvoxfile.bvox'density = br.VolumePlot(bvoxfile, name = 'my_current')

# adjusting shape, etcdensity.size = [...] # <-- set by hands from the print output abovedensity.brightness = 1.1density.contrast = 1.1density.intensity = 10.density.density = 3.

# making a bounding boxbbox = br.BoundingBox(name = 'bbox')

# adjusting parametersbbox.size = shapebbox.color = '#36b3c4'bbox.intensity = 0.2

# ...and finally rendering (or use Fn+F12)render.render()# image saved to the directory defined above

3.3. Full python script 21

Page 26: BRender Documentation

BRender Documentation, Release 1.0

22 Chapter 3. Volume plot

Page 27: BRender Documentation

CHAPTER 4

Particle plot

Before starting this section make sure to have a camera set up. Also if there’s a bounding box in the scene, it’s generallyeasier to navigate and understand the directions in space. So before moving forward, check previous tutorial on basicsof BRender.

Note: for tigressdata users. Blender’s bundled python does not support hdf5 documents, and I wasn’t able to installit (no access). So you’ll have to do all the reading and primary analysis of all the data from some python outsideBlender.

4.1 Generating particle coordinates

Again, similar to the previous section, BRender is not constrained to any specific code output, and can be fed by anysort of particle data generated in advance. So if you know how to generate a set of coordinates kept in an array from aspecific code output, feel free to skip to the next section where we’ll be making a particle plot.

Here we’ll discuss how to generate particle array particularly for TRISTAN code output (hdf5 format), which will belater used to make a plot. Note again, that if you’re working from within the tigressdata, you’ll have to do this from apython outside Blender, Mac users can do this from inside Blender console. We first need to specify several paths andnames:

# For tigressdata do this whole procedure from outside Blender python consoleimport lib.particle_output as prtl

out_path = '/output-dir-for-particles/' # <-- make sure to have slash in the endfpart = '/path-to/prtl.tot.001' # <-- this one is specifically a TRISTAN output file

n_particles = 20000 # number of particles per each sort

For the particle output, you need to somehow tell the function what’s the physical shape of your simulation (in units ofcode). For that, it either takes the values from the param.*** file from the same location as the prtl.tot.***

23

Page 28: BRender Documentation

BRender Documentation, Release 1.0

file, or it takes it from flds.tot.*** (then you’ll have to provide it with istep value), or you can also specify itmanually with the shape attribute (the function will take care of it):

# in this case I have the `flds.tot.001` in the same location, so I only provide the→˓`istep`fpath = prtl.makeParticles(out_path, fpart, n_particles, istep = 4)

This will create a particles.dat file in the location given by out_path with an array of particles: (x, y, z,ind), where ind being the index of a particle (0 for electrons and 1 for ions) and x, y, z being the coordinatesof a random sample of n_particles particles scaled so the smallest edge is 2 (with the center in (0,0,0)). Thetypical output looks like this:

# content of `particles.dat`...0.0632148981094 -0.047459602356 0.227420449257 0.0

-0.0733104348183 -0.135616958141 0.0196393728256 0.00.437074899673 0.260051727295 0.24244260788 0.00.0026843547821 -0.0520194172859 -0.214550793171 0.0

-0.21538990736 -0.138226926327 0.0670219659805 0.0...-0.160959780216 -0.0728992819786 0.0648549795151 1.00.0687325000763 0.0521985292435 -0.0412805080414 1.0

-0.0846030116081 0.332876563072 -0.349565148354 1.0-0.00664752721786 -0.320498406887 -0.0523825287819 1.0-0.414578616619 0.0203070640564 0.0408389568329 1.0...

In the next section we will import this data and feed it to a class that creates the particle plot.

4.2 Making particle plot

Note: For tigressdata the rest can be done within the Blender console.

The only data you need to have is an array of (x, y, z) coordinates scaled within a given shape (it’s convenient tohave a min edge size of 2). If you have those arrays (as many as you like depending on how many particle species youhave), skip to the step 2.

If you working within tigressdata, specify a path to particles.dat file:

fpath = '/path-to/particles.dat'

1. We will then import the particle data, split the particles into different arrays according to their indices (if neces-sary):

import numpy as np

xs, ys, zs, inds = np.loadtxt(fpath, unpack=True, usecols=(0,1,2,3))

# electrons with `ind` = 0xs_e = xs[inds == 0]ys_e = ys[inds == 0]zs_e = zs[inds == 0]coords_e = list(zip(xs_e, ys_e, zs_e))# ions with `ind` = 1

(continues on next page)

24 Chapter 4. Particle plot

Page 29: BRender Documentation

BRender Documentation, Release 1.0

(continued from previous page)

xs_i = xs[inds == 1]ys_i = ys[inds == 1]zs_i = zs[inds == 1]coords_i = list(zip(xs_i, ys_i, zs_i))

2. You then can make two objects that will have your particle plots for both electrons and ions:

# blue electronspart_lec = br.ParticlePlot(coords_e, name = 'lecs', halo_size = 0.005, color = (0,→˓ 0, 1))# red electronspart_ion = br.ParticlePlot(coords_e, name = 'ions', halo_size = 0.005, color = (1,→˓ 0, 0))

The halo_size parameter sets the characteristic “particle size”. You can later adjust color, location and scale (withrespect to your original coords scaling) by doing (e.g.):

part_lec.color = '#123123'part_lec.location = (-0.5, 0.2, 0.3)part_lec.halo_size = 0.001part_lec.scale = 2. # this will inflate the data cube twice

One can also redraw the whole thing with updated coordinates (stored in coords_new) by doing:

part_lec.coords = coords_new

Note: You can always play with all the parameters from the Blender GUI (see below).

4.2. Making particle plot 25

Page 30: BRender Documentation

BRender Documentation, Release 1.0

Below is a rendering result of such a plot.

4.3 Full python script

4.3.1 for Mac

"""Example code to run within Blender to produce the plot show above (Mac version)

Note: Make sure to change all the paths below

(continues on next page)

26 Chapter 4. Particle plot

Page 31: BRender Documentation

BRender Documentation, Release 1.0

(continued from previous page)

"""

import brender as br

# # # # # # # # # # # # # # # # # # # # # # # ### 1. Preparing## # # # # # # # # # # # # # # # # # # # # # # ## setting up the cameracam = br.initializeCamera()cam.location = (4.5, -1.2, 0.7)cam.pointing = (0, 0, 0)

# setting up the rendererrender_directory = '/any-folder/images/'render_name = 'mysim_'render = br.Render(render_directory, render_name)

br.Render.set_resolution(1000, 1000)

import lib.particle_output as prtl

out_path = '/output-dir-for-particles/' # <-- make sure to have slash in the endfpart = '/path-to/prtl.tot.001' # <-- this one is specifically a TRISTAN output file

n_particles = 20000 # number of particles per each sort

# # # # # # # # # # # # # # # # # # # # # # # ### 2. Generating `particles.dat` file# You can skip this, if you already have the particles' (x,y,z) loaded into an→˓array## # # # # # # # # # # # # # # # # # # # # # # ## in this case I have the `flds.tot.001` in the same location, so I only provide the→˓`istep`fpath = prtl.makeParticles(out_path, fpart, n_particles, istep = 4)

# reading everything to 2 arraysimport numpy as np

xs, ys, zs, inds = np.loadtxt(fpath, unpack=True, usecols=(0,1,2,3))

# electrons with `ind` = 0xs_e = xs[inds == 0]ys_e = ys[inds == 0]zs_e = zs[inds == 0]coords_e = list(zip(xs_e, ys_e, zs_e))# ions with `ind` = 1xs_i = xs[inds == 1]ys_i = ys[inds == 1]zs_i = zs[inds == 1]coords_i = list(zip(xs_i, ys_i, zs_i))

# # # # # # # # # # # # # # # # # # # # # # # #(continues on next page)

4.3. Full python script 27

Page 32: BRender Documentation

BRender Documentation, Release 1.0

(continued from previous page)

## 3. Plotting## # # # # # # # # # # # # # # # # # # # # # # ## blue electronspart_lec = br.ParticlePlot(coords_e, name = 'lecs', halo_size = 0.005, color = (0, 0,→˓1))# red electronspart_ion = br.ParticlePlot(coords_e, name = 'ions', halo_size = 0.005, color = (1, 0,→˓0))

4.3.2 for tigressdata

outside Blender:

"""Example code to run outside Blender (tigressdata version)

Note: Make sure to change all the paths belowNote2: This is to be run outside Blender

"""

import syssys.path.append('/path-to-brender-repo') # you can use mine: '/home/hakobyan/→˓Downloads/brender_astro'import lib.particle_output as prtl

# # # # # # # # # # # # # # # # # # # # # # # ### Generating `particles.dat` file# You can skip this, if you already have the particles' (x,y,z) loaded into an→˓array## # # # # # # # # # # # # # # # # # # # # # # #

out_path = '/output-dir-for-particles/' # <-- make sure to have slash in the endfpart = '/path-to/prtl.tot.001' # <-- this one is specifically a TRISTAN output file

n_particles = 20000 # number of particles per each sort

# in this case I have the `flds.tot.001` in the same location, so I only provide the→˓`istep`fpath = prtl.makeParticles(out_path, fpart, n_particles, istep = 4)

inside Blender:

"""Example code to run inside Blender (tigressdata version)

Note: Make sure to change all the paths belowNote2: This is to be run inside Blender, we do not refer to h5py here

"""

# # # # # # # # # # # # # # # # # # # # # # # ##

(continues on next page)

28 Chapter 4. Particle plot

Page 33: BRender Documentation

BRender Documentation, Release 1.0

(continued from previous page)

# 1. Preparing## # # # # # # # # # # # # # # # # # # # # # # ## setting up the cameracam = br.initializeCamera()cam.location = (4.5, -1.2, 0.7)cam.pointing = (0, 0, 0)

# setting up the rendererrender_directory = '/any-folder/images/'render_name = 'mysim_'render = br.Render(render_directory, render_name)

br.Render.set_resolution(1000, 1000)

# # # # # # # # # # # # # # # # # # # # # # # ### 2. Reading `particles.dat` file# You can skip this, if you already have the particles' (x,y,z) loaded into an→˓array## # # # # # # # # # # # # # # # # # # # # # # #

fpath = '/path-to/particles.dat'

# reading everything to 2 arraysimport numpy as np

xs, ys, zs, inds = np.loadtxt(fpath, unpack=True, usecols=(0,1,2,3))

# electrons with `ind` = 0xs_e = xs[inds == 0]ys_e = ys[inds == 0]zs_e = zs[inds == 0]coords_e = list(zip(xs_e, ys_e, zs_e))# ions with `ind` = 1xs_i = xs[inds == 1]ys_i = ys[inds == 1]zs_i = zs[inds == 1]coords_i = list(zip(xs_i, ys_i, zs_i))

# # # # # # # # # # # # # # # # # # # # # # # ### 3. Plotting## # # # # # # # # # # # # # # # # # # # # # # #

# blue electronspart_lec = br.ParticlePlot(coords_e, name = 'lecs', halo_size = 0.005, color = (0, 0,→˓1))# red electronspart_ion = br.ParticlePlot(coords_e, name = 'ions', halo_size = 0.005, color = (1, 0,→˓0))

4.3. Full python script 29

Page 34: BRender Documentation

BRender Documentation, Release 1.0

30 Chapter 4. Particle plot

Page 35: BRender Documentation

CHAPTER 5

Fieldline plot

Before starting this section make sure to have a camera set up. Also if there’s a bounding box in the scene, it’s generallyeasier to navigate and understand the directions in space. So before moving forward, check previous tutorial on basicsof BRender. Also since we’re going to do a plot fieldlines, it’s a good idea to have either volumetric or particle dataplotted before moving forward (see previous sections for that).

Note: for tigressdata users. Blender’s bundled python does not support hdf5 documents, and I wasn’t able to installit (no access). So you’ll have to do all the reading and primary analysis of all the data from some python outsideBlender.

5.1 Generating fieldlines

To generate streamlines we here use a custom method that was generalized for 3D case from matplotlib’sstreamplot function. I’m not going to describe it here in details, the only thing to have in mind is that you’llhave to specify several parameters before generating fieldlines.

• keys (default: ('bx', 'by', 'bz')) - the field keys that will be taken from hdf5 as a vector field.

• density (default: 1) - very similar to that in streamplot, a parameter that determines how dense are thefieldlines.

• n_traj (default: 100) - total number of fieldline trajectories.

• seg_step (default: 0.2) - integration step (in simulation units); make sure to keep it less than 1.

• min_seglen (default: 100.) - minimum fieldline length (in simulation units).

• region(point) (default: True) - function that takes as argument the tuple of (x,y,z) coordinates (insimulation units) and returns a logical expression that determines which constraints the region of fieldlines.

Let’s define all those variables in a following manner (for tigressdata do this outside Blender):

31

Page 36: BRender Documentation

BRender Documentation, Release 1.0

fname = '/path-to/flds.tot.001'

density = 2.n_traj = 50seg_step = 0.8min_seglen = 100

def region(point):x, y, z = point# this means only the region with 400 < x < 600 will be consideredreturn (x > 400 and x < 600)

To generate trajectories we’ll first need to import the module and then use generateFieldlines() function:

import lib.export_trajectories as fldlns

trajectories = fldlns.generateFieldlines(fname, density = density, keys = ('bx', 'by',→˓ 'bz'),

n_traj = n_traj, region = region, min_→˓seglen = min_seglen,

seg_step = seg_step)

Now each of trajectories[i] array contains all the fieldlines in the following form:

x1 y1 z1x2 y2 z2...xN yN zN

Note: If you’re doing this in tigressdata you’ll have to save those trajectories to later import them from inside Blender.Do:

out_file = '/path-to/fieldlines.dat'fldlns.exportFieldlines(trajectories, out_file)

5.2 Plotting fieldlines

If you’re working in Mac you will simply have your fieldlines in the trajectories variable. You’ll also need toknow the shape and scale of your simulation box:

import numpy as np # if not yet importedimport lib.to_bvox as bvox

fname = '/path-to/flds.tot.001'shape0 = np.array(bvox.getShape(fname, 'dens'))scale = 2. / shape0.min()shape = shape0 * scale

If you’re working within tigressdata, you’ll have to specify shape and size manually (e.g. by running the codeabove from outside Blender and then printing and copy-pasting values). The trajectories can be imported from the.dat filed saved above (make sure to have import brender as br):

32 Chapter 5. Fieldline plot

Page 37: BRender Documentation

BRender Documentation, Release 1.0

out_path = '/path-to/fieldlines.dat'trajectories = br.importFieldlines(out_path)

Now with either system, simply run (make sure to have import brender as br):

fieldlines = br.FieldLines(trajectories, name = 'b-field', size = shape, scale =→˓scale)

This will create a FieldLines object with the given fieldlines. You can later configure color and intensity:

fieldlines.color = '#123123'fieldlines.intensity = 0.5

Below are two rendering results.

5.2. Plotting fieldlines 33

Page 38: BRender Documentation

BRender Documentation, Release 1.0

34 Chapter 5. Fieldline plot

Page 39: BRender Documentation

BRender Documentation, Release 1.0

5.3 Full python script

5.3.1 for Mac

"""Example code to run within Blender to produce the plot show above (Mac version)

Note: Make sure to change all the paths below

"""

import brender as br

# # # # # # # # # # # # # # # # # # # # # # # ### 1. Preparing## # # # # # # # # # # # # # # # # # # # # # # ## setting up the cameracam = br.initializeCamera()cam.location = (4.5, -1.2, 0.7)cam.pointing = (0, 0, 0)

# setting up the rendererrender_directory = '/any-folder/images/'render_name = 'mysim_'render = br.Render(render_directory, render_name)

br.Render.set_resolution(1000, 1000)

import lib.to_bvox as bvoximport numpy as np

# finding the shape and scale of our simulationfname = '/path-to/flds.tot.001' # <-- this is for TRISTANshape0 = np.array(bvox.getShape(fname, 'dens'))scale = 2. / (shape0.min())shape = shape0 * scale

# # # # # # # # # # # # # # # # # # # # # # # ### 2. Generating .bvox file# if the .bvox already exists, just skip this step## # # # # # # # # # # # # # # # # # # # # # # #density = 0.5n_traj = 50seg_step = 0.2min_seglen = 60

def region(point):x, y, z = point# this means only the region with 400 < x < 600 will be consideredreturn (x > 400) and (x < 600)

import lib.export_trajectories as fldlns

(continues on next page)

5.3. Full python script 35

Page 40: BRender Documentation

BRender Documentation, Release 1.0

(continued from previous page)

trajectories = fldlns.generateFieldlines(fname, density = density, keys = ('bx', 'by',→˓ 'bz'),

n_traj = n_traj, region = region, min_→˓seglen = min_seglen,

seg_step = seg_step)

# # # # # # # # # # # # # # # # # # # # # # # ### 3. Plotting## # # # # # # # # # # # # # # # # # # # # # # ## generating the FieldLines class objectfieldlines = br.FieldLines(trajectories, name = 'b-field', size = shape, scale =→˓scale)

# adjusting intensity, etcfieldlines.intensity = 0.2fieldlines.color = (0,1,1)

# ...and finally rendering (or use Fn+F12)render.render()# image saved to the directory defined above

5.3.2 for tigressdata

outside Blender:

"""Example code to run outside Blender (tigressdata version)

Note: Make sure to change all the paths belowNote2: This is to be run outside Blender

"""import sysimport numpy as npsys.path.append('/path-to-brender-repo') # you can use mine: '/home/hakobyan/→˓Downloads/brender_astro'import lib.to_bvox as bvoximport lib.export_trajectories as fldlns

# # # # # # # # # # # # # # # # # # # # # # # ### 1. Preparing## # # # # # # # # # # # # # # # # # # # # # # #fname = '/path-to/flds.tot.001'shape0 = np.array(bvox.getShape(fname, 'dens'))scale = 2. / (shape0.min())shape = shape0 * scale

# you need to copy this parameters laterprint (shape)print (scale)

# # # # # # # # # # # # # # # # # # # # # # # #

(continues on next page)

36 Chapter 5. Fieldline plot

Page 41: BRender Documentation

BRender Documentation, Release 1.0

(continued from previous page)

## 2. Generating .dat file with trajectories## # # # # # # # # # # # # # # # # # # # # # # #fname = '/path-to/flds.tot.001'

density = 0.5n_traj = 50seg_step = 0.2min_seglen = 60

def region(point):x, y, z = point# this means only the region with 400 < x < 600 will be consideredreturn (x > 400) and (x < 600)

import lib.export_trajectories as fldlns

trajectories = fldlns.generateFieldlines(fname, density = density, keys = ('bx', 'by',→˓ 'bz'),

n_traj = n_traj, region = region, min_→˓seglen = min_seglen,

seg_step = seg_step)

out_file = '/path-to/fieldlines.dat'fldlns.exportFieldlines(trajectories, out_file)

inside Blender:

"""Example code to run inside Blender (tigressdata version)

Note: Make sure to change all the paths belowNote2: This is to be run inside Blender, we do not refer to h5py here

"""

# # # # # # # # # # # # # # # # # # # # # # # ### 1. Preparing## # # # # # # # # # # # # # # # # # # # # # # ## setting up the cameracam = br.initializeCamera()cam.location = (4.5, -1.2, 0.7)cam.pointing = (0, 0, 0)

# setting up the rendererrender_directory = '/any-folder/images/'render_name = 'mysim_'render = br.Render(render_directory, render_name)

br.Render.set_resolution(1000, 1000)

# # # # # # # # # # # # # # # # # # # # # # # ### 2. Plotting#

(continues on next page)

5.3. Full python script 37

Page 42: BRender Documentation

BRender Documentation, Release 1.0

(continued from previous page)

# # # # # # # # # # # # # # # # # # # # # # # #out_path = '/path-to/fieldlines.dat'field_data = br.importFieldlines(out_path) # importing trajectories

# set `shape` and `scale` manually belowfieldlines = br.FieldLines(field_data, name = 'b-field', size = shape, scale = scale)

# adjusting intensity, etcfieldlines.intensity = 0.2fieldlines.color = (0,1,1)

38 Chapter 5. Fieldline plot