Visualizer
Animated visualization for 1-qubit and 2-qubit controls
Table of Contents
- Overview
- Getting started
- Usage
- Layout Settings
- Data Format
- Code and Dev Guide
- Publishing updates to NPM
Overview
Getting started
Previewing the visualizer as a demo App
- Clone the repo
- On the command line
cd
into the repo and run yarn
- Run
yarn start
- Open http://localhost:3000/ in your browser if it
doesn't happen automatically
- Look at the file:
/src/ExampleImplementation.js
for an example of how Bloch Sphere components are implemented in a React App. This example is using dummy data from /src/twoQubitTestData.js
- See below for further props and settings to use with the component
Adding a Visualizer component to the Q-CTRL App / new React App
- Login to npm from the command line:
npm login
your npm account must be linked and have access to the qtrl org - Install the Visualizer module with
yarn add @qctrl/visualizer
- Import the Visualizer component to your App
import Visualizer from '@qctrl/visualizer'
- See below and
/src/ExampleImplementation.js
in the repo for usage guidelines
Usage: Props and Layout
Props
-
The following props can be passed: onUpdate
, onError
, isPlaying
, progress
, inputState
, labels
, cameraPreset
. Also layout
and data
which will be discussed further down.
onUpdate
should be a function that takes one argument, which will be a state object. ie:
onUpdate={ object => {
this.setState(object);
}}
onError
If any errors are thrown within the visualizer component this function will be called (if it has been passed as a prop) with the errors object as the only argument:
onError={errors => {
console.log(errors);
}}
inputState
an object with structure { x:<x>, y:<y>, z:<z> }
that will be set as an arbitrary starting / position for the pulse indicatorisPlaying
tells the Bloch sphere component to start or stop the animationprogress
will have the pulse path starting at the progress percent specified. Eg: if you want to have the whole path showing on mount set progress to 1
progress={<float between 0 and 1>}
Labels
needs to be an object with the following structure and will control the visibility of individual labels:
{
xAxis: true,
yAxis: true,
zAxis: true,
theta: true,
thetaArc: true,
phi: true,
phiArc: true,
northPole: true,
southPole: true
}
Layout
- See the file
./src/lib/layout/index.js
to see what structure layout settings need to be in - If no
layout
prop is passed, all default settings will be used from the layout settings file - You are able to pass a subset of layout settings for a Bloch Sphere and these will be merged with the rest of the default settings from the settings file, no need to pass all the settings if you only need to customise a few things
Some common layout settings explained
animation: {fps: 30}
how many times per second the animation loop is called, changes the playback rate, animation will become choppy at lower rateselementTypes
//TODO: add info about element layout settingsequatorialPlane: {}
is the face of the disc that spans the equatorequatorialOutline: {}
is the outline that runs around the surface of the equatoraxes: {}
controls the guide x, y, z axespulsePoint: {}
changes the circle at the end of the pulse line. radius
controls the size, outlineFactor
controls how much larger than the main circle the outline ispulseArcCurrentSegment: {}
controls the look of the currently animating pulse segment or the segment being hovered over after the animation has completedpulseArc: { geometrySegments: 16 }
, needs to be set for larger block spheres for smooth looking points/circles, default value is 6, this also applies to pulsePoint: { geometrySegments: 16 }
Data
A data object must be passed as a prop called data
Format/structure
Structure for 2-qubit-data:
{
"qubits": [
{
"name": "qubit1",
"x": [],
"y": [],
"z": []
},
{
"name": "qubit2",
"x": [],
"y": [],
"z": []
}
],
"vectors": [
{
"name": "a",
"x": [],
"y": [],
"z": []
},
{
"name": "b",
"x": [],
"y": [],
"z": []
},
{
"name": "c",
"x": [],
"y": [],
"z": []
}
]
}
- See
twoQubitTestData.js
for a working example
Code and Development Guide
- The React component lives in
BlochSphere/index.js
- It is a React class component with internal state that controls animation and pulse path display
- A
ref
is used to get the div in the render function's reference and pass it to a scene manager so that canvas element that THREE.js will render to can be created - The file:
/BlochSphere/threejs/scene.js
is imported to the React component file and is used to create a THREE.js scene
, renderer
, camera
and controls
which ae all returned as an object from the function nd stored as a Class variable in this.SceneManager
this object now holds references to the above scene objects so they can be called in other places in the component - The same pattern is used to create and reference objects in the scene such as the sphere and pulse lines
Custom Component Methods
threeRender()
, animate()
, update()
are all required by THREE.js to render an animate a sceneanimate()
is called recursively via requestAnimationFrame
- All calculations for updating the positions and display of Bloch Sphere data is done here
componentDidMount()
is used to instantiate all THREE.js objects and add them to the scene / renderercomponentDidUpdate()
checks for new props and updates state appropriately, this allows the animation to be started and stopped and the display of the pulse path to be controlled via propscomponentWillUnmount()
is used to clean up all THREE.js objects, the renderer and the animation loop to free up memory and GPU_handleMouseMove()
is used to calculate mouse over effects for the pulse segments
Utils
Contains some specific maths functions for doing various circle / polar geometry stuff as well as some specific THREE.js utils / addons.
Publishing updates to NPM
- Once you have made and tested your updates you first need to update the version number in
src/package.json
. The best way to do this is to cd into src
from the command line and run npm version <update_type>
update_type should be patch
, minor
or major
, see here for semantic versioning explanation - From the
src
directory run npm run publishnpm
this will first build/compile using babel then publish the compiled lib to NPM. Note that you need to be logged in to NPM and your account needs to be linked and have access to the qtrl Org. Also note that using yarn to run the publishnpm script will fail - Everything under the
src/lib
folder will be compiled and published - You may also want to update the version number in the package.json file in the root of the repo to match the
src
package.json file.