BTK Python wrapper  0.3dev.0
Python bindings for the Biomechanical ToolKit library (BTK)
Getting started

The following list gives you the steps to use BTK in a Python environment.


Note: A special thanks to Fabien Leboeuf (Laboratoire du Mouvement, CHU Nantes) who wrote the original version of this tutorial.

Why a python implementation?

Python is a high-level language, free to use, running on different environments (Windows, Linux, MacOS X). It favours the object-oriented programming, which do not prevent to implement functional programming. The syntax is clear, doing python easy to learn and faster to develop. The popularity of Python increases in the scientific community. Indeed, lot of libraries can respond to any scientifical expectations (signal processing (Scipy) , 3D modelisation (pyVtk) , optimization (pyOpt), etc). Moreover, advanced interactive- development environment, like spyder (see figure below), appears allowing to easily switch from Matlab.

scipy-spyder.jpg
Screenshot of the software Spyder: Scientific PYthon Development EnviRonment

For further informations about Python versus matlab comparison, you can read this article.

Getting started

Add the package btk in Python

If you put the two files (btk.py and btk.pyd (Windows), btk.so (Linux/MacOS X)) in the working directory, you only have to add the following code: import btk in you script header.
Otherwise, if the package is located in another folder then you need to add the path in the known path by Python.

1 import sys
2 sys.path.append("path of btk python package")
3 import btk

Note: if you use Spyder, you can add interactively this path by using the menu Tools > PYTHONPATH manager.

The command import btk creates the namespace btk which have to be specified as a prefix if you create a new BTK object. As an example, a new reader acquisition object will be built with:

Enjoy with a c3d acquisition file

The primary advantage of BTK is to offer lots of methods for handling a motion capture file, especially the C3D extension. This binary file embeds four containers:

Read an aquisition

Reading an acquisition is simple.

1 reader = btk.btkAcquisitionFileReader() # build a btk reader object
2 reader.SetFilename("dynamic.c3d") # set a filename to the reader
3 reader.Update()
4 acq = reader.GetOutput() # acq is the btk aquisition object

The output is the BTK-aquisition objet acq on which you can use different accessors for exploring and setting data.

Explore an acquisition

Point object

First of all, BTK prevents to extract point frame number and point-aquisition frequency from the metadata. Special accessors are proposed:

1 acq.GetPointFrequency() # give the point frequency
2 acq.GetPointFrameNumber() # give the number of frames

Now, let’s imagine that your acquisition only contains the points named into the acquisition:

You can extract them from the aquisition object acq with these methods:

1 point1 = acq.GetPoint("LASI")
2 point2 = acq.GetPoint("LKneeAngles")
3 #if you rather prefer handle index instead of point name, you can use
4 point1 = acq.GetPoint(0)
5 point2 = acq.GetPoint(1)

Then point1 is the BTK-object characterizing the LASI marker. To access to its 3d-values:

1 values = point1.GetValues() # return a Numpy array of nrows, and 3 columns
2 # for slicing the previous Numpy Array, you can use
3 point1.GetValues()[0,0] # return the value of the first row, first column.
4 point1.GetValues()[:,0] # extract the first column
5 point1.GetValue(0,0) # another method for extracting the first row, first col

Except that the index begins at 0, accessing to element of a numpy array is similar to the matlab syntax. For help about Numpy slicing and equivalent matlab functions, you can read the following user guide Numpy for Matlab Users.

Analog object

Extracting analog object is similar to point extraction. Generally, analog measures are acquired at high-speed frequency. This parameter can be accessed with the method btkAcquisiton::GetAnalogFrequency() as the number of frame with the accessors btkAcquisition::GetAnalogFrameNumber(). Imagine that the c3d contains the muscular activities labeled: Emg1, Emg2, Emg3,... The following code will explain how to extract their values:

1 analog1 = acq.GetAnalog("Emg1") # attribute a btk-analog object to the measurement
2 values = analog1.GetValues() # return a 1D Numpy array

Event

An event extracts from the aquisition with the method btkAcquisition::GetEvent(). This creates the BTK-object event of which main features are:

Accessing to these informations is easy with the method btkEvent::GetLabel, btkEvent::GetContext, btkEvent::GetFrame. As an example:

1 event = acq.GetEvent(0) # extract the first event of the aquisition
2 event.GetLabel() # return a string representing the Label
3 event.GetContext() # return a string representing the Context
4 event.GetFrame() # return the frame as an integer

Metadata

To access the metadata, you have to use the method btkAcquisition::GetMetaData() on the BTK-acquisition object acq. A metadata represents a tree structure as in the figure below.

mokka-metadata.png
Dialog window from the software Mokka showing the metadata of an acquisition.

To extract the content of the metada POINT:MOVIE_DELAY, you can do it as following

1 metadata = acq.GetMetaData()
2 delay = metadata.FindChild("POINT").value().FindChild("MOVIE_DELAY").value().GetInfo().toDouble()
3 # return a Tuple of double.

Modify an acquisition

Writing data into an acquisition is as easy as reading data. The package proposed dedicated methods to do it directly on an aquisition object.

Modify and append a point

The following code firsly explains how to modify one point value. Secondly, a new point will be appended into the acquisition. In this case, developpers can use different signatures to build a new btkpoint object. In this example two signatures are illustrated. Others are detailed in the Doxygen help (see documentation of the class btkPoint).

1 point1 = acq.GetPoint("LASI")
2 # 1) Modifying an element (first raw and first column)
3 point1.SetValue(0,0,1000.0) # the new coordinate is to 1000
4 # 2) Appending a new point
5 newValue = numpy.ones(acq.GetPointFrameNumber(),3) # identity numpy array with 3 colum and PointFrameNumber rows.
6 # minimal signature = indicate the number of point frame
7 newpoint = btk.btkPoint(acq.GetPointFrameNumber()) # create an empty new point object
8 newpoint.SetLabel(â™newPoint’) # set newPoint as label newpoint.SetValues(newValue) # set the value acq.AppendPoint(newpoint) # append the new point into the acquisition object # other possible siganture # => the new point is automatically built with the label "newPointShort" newpoint_short = btk.btkPoint(’newPointShort’, acq.GetPointFrameNumber()) newpoint_short.SetValues(value)€newPoint’) # set newPoint as label newpoint.SetValues(newValue) # set the value acq.AppendPoint(newpoint) # append the new point into the acquisition object # other possible siganture # => the new point is automatically built with the label "newPointShort" newpoint_short = btk.btkPoint(’newPointShort’, acq.GetPointFrameNumber()) newpoint_short.SetValues(value)™ewPoint’) # set newPoint as label newpoint.SetValues(newValue) # set the value acq.AppendPoint(newpoint) # append the new point into the acquisition object # other possible siganture # => the new point is automatically built with the label "newPointShort" newpoint_short = btk.btkPoint(’newPointShort’, acq.GetPointFrameNumber()) newpoint_short.SetValues(value)newPointâ™) # set newPoint as label newpoint.SetValues(newValue) # set the value acq.AppendPoint(newpoint) # append the new point into the acquisition object # other possible siganture # => the new point is automatically built with the label "newPointShort" newpoint_short = btk.btkPoint(’newPointShort’, acq.GetPointFrameNumber()) newpoint_short.SetValues(value)€) # set newPoint as label newpoint.SetValues(newValue) # set the value acq.AppendPoint(newpoint) # append the new point into the acquisition object # other possible siganture # => the new point is automatically built with the label "newPointShort" newpoint_short = btk.btkPoint(’newPointShort’, acq.GetPointFrameNumber()) newpoint_short.SetValues(value)™ # set newPoint as label newpoint.SetValues(newValue) # set the value acq.AppendPoint(newpoint) # append the new point into the acquisition object # other possible siganture # => the new point is automatically built with the label "newPointShort" newpoint_short = btk.btkPoint(’newPointShort’, acq.GetPointFrameNumber()) newpoint_short.SetValues(value)) # set newPoint as label
9 newpoint.SetValues(newValue) # set the value
10 acq.AppendPoint(newpoint) # append the new point into the acquisition object
11 # other possible siganture
12 # => the new point is automatically built with the label "newPointShort"
13 newpoint_short = btk.btkPoint(â™newPointShort’, acq.GetPointFrameNumber()) newpoint_short.SetValues(value)€newPointShort’, acq.GetPointFrameNumber()) newpoint_short.SetValues(value)™ewPointShort’, acq.GetPointFrameNumber()) newpoint_short.SetValues(value)newPointShortâ™, acq.GetPointFrameNumber()) newpoint_short.SetValues(value)€, acq.GetPointFrameNumber()) newpoint_short.SetValues(value)™ acq.GetPointFrameNumber()) newpoint_short.SetValues(value), acq.GetPointFrameNumber())
14 newpoint_short.SetValues(value)

Modify and append and analog channel

The syntax is equivalent to the above point section.

1 # 1) modifying an element
2 analog1 = acq.GetAnalog("Emg1") # extract the analog channel Emg1
3 analog1.SetValue(0,1000.0) # modifiy the first value
4 # 2) appending a new analog signal
5 newValueAnalog = np.ones( (acq.GetAnalogFrameNumber(),1)) # identity numpy array with 1 column and AnalogFrameNumber rows.
6 newAnalog=btk.btkAnalog(acq.GetAnalogFrameNumber()) # create an empty new analog channel
7 newAnalog.SetValues(newValueAnalog) # set its values
8 newAnalog.SetLabel("NewAnalog") # set its label
9 acq.AppendAnalog(newAnalog) # append the new analog object to the aquisition

Modify and append an event

If you want to change features of the first event, you can use

1 event=acq.GetEvent(0) # extract the first event of the aquisition
2 event.SetLabel("Foot off") # replace the label
3 event.SetContext("general")
4 event.SetFrame(25)

Appending a new event to the aquisition is possible with following script:

1 newEvent=btk.btkEvent() # build an empty event object
2 newEvent.SetLabel("Foot Off") # set the label
3 newEvent.SetContext("Left") #
4 newEvent.SetFrame(390)
5 acq.AppendEvent(newEvent) # append the new event to the aquisition object

Modify metadata

To modify the value of the metadata MOVIE_DELAY:

1 metadata = acq.GetMetaData()
2 # access a sp´ecific element
3 MOVIE_DELAY = metadata.FindChild(â™POINT’).value().FindChild(’MOVIE_DELAY’).value().GetInfo() MOVIE_DELAY.SetValue(0,2) #setting the first element with the value 2€POINT’).value().FindChild(’MOVIE_DELAY’).value().GetInfo() MOVIE_DELAY.SetValue(0,2) #setting the first element with the value 2™OINT’).value().FindChild(’MOVIE_DELAY’).value().GetInfo() MOVIE_DELAY.SetValue(0,2) #setting the first element with the value 2POINTâ™).value().FindChild(’MOVIE_DELAY’).value().GetInfo() MOVIE_DELAY.SetValue(0,2) #setting the first element with the value 2€).value().FindChild(’MOVIE_DELAY’).value().GetInfo() MOVIE_DELAY.SetValue(0,2) #setting the first element with the value 2™.value().FindChild(’MOVIE_DELAY’).value().GetInfo() MOVIE_DELAY.SetValue(0,2) #setting the first element with the value 2).value().FindChild(â™MOVIE_DELAY’).value().GetInfo() MOVIE_DELAY.SetValue(0,2) #setting the first element with the value 2€MOVIE_DELAY’).value().GetInfo() MOVIE_DELAY.SetValue(0,2) #setting the first element with the value 2™OVIE_DELAY’).value().GetInfo() MOVIE_DELAY.SetValue(0,2) #setting the first element with the value 2MOVIE_DELAYâ™).value().GetInfo() MOVIE_DELAY.SetValue(0,2) #setting the first element with the value 2€).value().GetInfo() MOVIE_DELAY.SetValue(0,2) #setting the first element with the value 2™.value().GetInfo() MOVIE_DELAY.SetValue(0,2) #setting the first element with the value 2).value().GetInfo()
4 MOVIE_DELAY.SetValue(0,2) #setting the first element with the value 2

Recording a c3d with the modification

All modifications are definitely recorded into a C3D file ONLY IF the following lines end your script. This code consists in building a btkAcquisitionFileWriter object and linking it to the modified acquisition. The method btkAcquisitionFileWriter::SetFilename allows you either to overwrite the existing file or to create a new one.

2 writer.SetInput(acq)
3 writer.SetFilename(â™newFile.c3d’) writer.Update()€newFile.c3d’) writer.Update()™ewFile.c3d’) writer.Update()newFile.c3dâ™) writer.Update()€) writer.Update()™ writer.Update())
4 writer.Update()

Process data

With Python language, one interest of BTK is to take advantage of scipy modules to implement biomechanical processes.

Filter data

An unavoidable process is to filter the data. To this end, the module scipy.signal presents a large panel of filtering methods, with a syntax close to Matlab. For example, this code show how to filter an analog data with a Butterworth filter.

1 # modules to import
2 import os
3 import sys
4 import btk
5 from matplotlib import pyplot as plt
6 import numpy as np
7 import scipy.signal
8 # Raw data represent the analog measures labelled Emg1 into the c3d
9 analog1 = acq.GetAnalog("Emg1")
10 RawValue = analogs1.GetValues()
11 # Application of a 4-order low-pass Butterworth filter with a frequency set at 9 Hz
12 # use of the module Scipy/signal
13 order = 4
14 Fc = 9
15 b, a = scipy.signal.butter(order, fc/(0.5*acq.GetAnalogFrequency()))
16 FilteringData = scipy.signal.filtfilt(b, a,RawValue[:,0])
17 # plotting data (use of the library matplotlib, prefixed here by plt)
18 plt.figure() #create figure
19 plt.plot(RawValue) # plot raw data
20 plt.plot(FilteringData) # plot filtering data
21 plt.show()

Compute reference frame from markers

The second biomechanical process takes as example show how to find the nearest rotation matrix from the movement of the pelvis cluster, according Challis, 1995 (A procedure for determining rigid body transformation parameters, Journal of Biomechanics, 28(6), pp. 733-737). The code manipulates method associated with a numpy array object and used the linear algebra module of Scipy.

1 # modules to import
2 import os
3 import btk
4 import numpy as np
5 import scipy.linalg
6 # Creation of an numpy array for the referencial frame and the chosen frame
7 # each row is the X,Y, Z coordinates of the one pelvis marker at the reference frame
8 data_FrameRef = np.array([acq.GetPoint(â™LASI’).GetValues()[0,:], acq.GetPoint(’RASI’).GetValues()[0,:], acq.GetPoint(’LPSI’).GetValues()[0,:], acq.GetPoint(’RPSI’).GetValues()[0,:]]) Frame = 40 data_FrameChosen = np.array([acq.GetPoint(’LASI’).GetValues()[Frame,:], acq.GetPoint(’RASI’).GetValues()[Frame,:], acq.GetPoint(’LPSI’).GetValues()[Frame,:], acq.GetPoint(’RPSI’).GetValues()[Frame,:]]) # Difference with mean values A = data_FrameRef-np.mean(data_FrameRef,axis=0) B = data_FrameChosen-np.mean(data_FrameChosen,axis=0) # transposition of the data A = A.transpose() B = B.transpose() # matrix multiplication # (Note : with a numpy array, it’s the dot method, not the multiplication operator) C = np.dot(B,A.transpose()) # singular decomposition, called the svd method of the scipy/linalg module P,T,Q = scipy.linalg.svd(C) # computation of the nearest rotation matrix R mat = np.array([[ 1., 0., 0.], [ 0., 1., 0.], [ 0., 0., scipy.linalg.det(np.dot(P,Q.transpose()))]]) R = np.dot(P,np.dot(mat,Q.transpose()))€LASI’).GetValues()[0,:], acq.GetPoint(’RASI’).GetValues()[0,:], acq.GetPoint(’LPSI’).GetValues()[0,:], acq.GetPoint(’RPSI’).GetValues()[0,:]]) Frame = 40 data_FrameChosen = np.array([acq.GetPoint(’LASI’).GetValues()[Frame,:], acq.GetPoint(’RASI’).GetValues()[Frame,:], acq.GetPoint(’LPSI’).GetValues()[Frame,:], acq.GetPoint(’RPSI’).GetValues()[Frame,:]]) # Difference with mean values A = data_FrameRef-np.mean(data_FrameRef,axis=0) B = data_FrameChosen-np.mean(data_FrameChosen,axis=0) # transposition of the data A = A.transpose() B = B.transpose() # matrix multiplication # (Note : with a numpy array, it’s the dot method, not the multiplication operator) C = np.dot(B,A.transpose()) # singular decomposition, called the svd method of the scipy/linalg module P,T,Q = scipy.linalg.svd(C) # computation of the nearest rotation matrix R mat = np.array([[ 1., 0., 0.], [ 0., 1., 0.], [ 0., 0., scipy.linalg.det(np.dot(P,Q.transpose()))]]) R = np.dot(P,np.dot(mat,Q.transpose()))™ASI’).GetValues()[0,:], acq.GetPoint(’RASI’).GetValues()[0,:], acq.GetPoint(’LPSI’).GetValues()[0,:], acq.GetPoint(’RPSI’).GetValues()[0,:]]) Frame = 40 data_FrameChosen = np.array([acq.GetPoint(’LASI’).GetValues()[Frame,:], acq.GetPoint(’RASI’).GetValues()[Frame,:], acq.GetPoint(’LPSI’).GetValues()[Frame,:], acq.GetPoint(’RPSI’).GetValues()[Frame,:]]) # Difference with mean values A = data_FrameRef-np.mean(data_FrameRef,axis=0) B = data_FrameChosen-np.mean(data_FrameChosen,axis=0) # transposition of the data A = A.transpose() B = B.transpose() # matrix multiplication # (Note : with a numpy array, it’s the dot method, not the multiplication operator) C = np.dot(B,A.transpose()) # singular decomposition, called the svd method of the scipy/linalg module P,T,Q = scipy.linalg.svd(C) # computation of the nearest rotation matrix R mat = np.array([[ 1., 0., 0.], [ 0., 1., 0.], [ 0., 0., scipy.linalg.det(np.dot(P,Q.transpose()))]]) R = np.dot(P,np.dot(mat,Q.transpose()))LASIâ™).GetValues()[0,:], acq.GetPoint(’RASI’).GetValues()[0,:], acq.GetPoint(’LPSI’).GetValues()[0,:], acq.GetPoint(’RPSI’).GetValues()[0,:]]) Frame = 40 data_FrameChosen = np.array([acq.GetPoint(’LASI’).GetValues()[Frame,:], acq.GetPoint(’RASI’).GetValues()[Frame,:], acq.GetPoint(’LPSI’).GetValues()[Frame,:], acq.GetPoint(’RPSI’).GetValues()[Frame,:]]) # Difference with mean values A = data_FrameRef-np.mean(data_FrameRef,axis=0) B = data_FrameChosen-np.mean(data_FrameChosen,axis=0) # transposition of the data A = A.transpose() B = B.transpose() # matrix multiplication # (Note : with a numpy array, it’s the dot method, not the multiplication operator) C = np.dot(B,A.transpose()) # singular decomposition, called the svd method of the scipy/linalg module P,T,Q = scipy.linalg.svd(C) # computation of the nearest rotation matrix R mat = np.array([[ 1., 0., 0.], [ 0., 1., 0.], [ 0., 0., scipy.linalg.det(np.dot(P,Q.transpose()))]]) R = np.dot(P,np.dot(mat,Q.transpose()))€).GetValues()[0,:], acq.GetPoint(’RASI’).GetValues()[0,:], acq.GetPoint(’LPSI’).GetValues()[0,:], acq.GetPoint(’RPSI’).GetValues()[0,:]]) Frame = 40 data_FrameChosen = np.array([acq.GetPoint(’LASI’).GetValues()[Frame,:], acq.GetPoint(’RASI’).GetValues()[Frame,:], acq.GetPoint(’LPSI’).GetValues()[Frame,:], acq.GetPoint(’RPSI’).GetValues()[Frame,:]]) # Difference with mean values A = data_FrameRef-np.mean(data_FrameRef,axis=0) B = data_FrameChosen-np.mean(data_FrameChosen,axis=0) # transposition of the data A = A.transpose() B = B.transpose() # matrix multiplication # (Note : with a numpy array, it’s the dot method, not the multiplication operator) C = np.dot(B,A.transpose()) # singular decomposition, called the svd method of the scipy/linalg module P,T,Q = scipy.linalg.svd(C) # computation of the nearest rotation matrix R mat = np.array([[ 1., 0., 0.], [ 0., 1., 0.], [ 0., 0., scipy.linalg.det(np.dot(P,Q.transpose()))]]) R = np.dot(P,np.dot(mat,Q.transpose()))™.GetValues()[0,:], acq.GetPoint(’RASI’).GetValues()[0,:], acq.GetPoint(’LPSI’).GetValues()[0,:], acq.GetPoint(’RPSI’).GetValues()[0,:]]) Frame = 40 data_FrameChosen = np.array([acq.GetPoint(’LASI’).GetValues()[Frame,:], acq.GetPoint(’RASI’).GetValues()[Frame,:], acq.GetPoint(’LPSI’).GetValues()[Frame,:], acq.GetPoint(’RPSI’).GetValues()[Frame,:]]) # Difference with mean values A = data_FrameRef-np.mean(data_FrameRef,axis=0) B = data_FrameChosen-np.mean(data_FrameChosen,axis=0) # transposition of the data A = A.transpose() B = B.transpose() # matrix multiplication # (Note : with a numpy array, it’s the dot method, not the multiplication operator) C = np.dot(B,A.transpose()) # singular decomposition, called the svd method of the scipy/linalg module P,T,Q = scipy.linalg.svd(C) # computation of the nearest rotation matrix R mat = np.array([[ 1., 0., 0.], [ 0., 1., 0.], [ 0., 0., scipy.linalg.det(np.dot(P,Q.transpose()))]]) R = np.dot(P,np.dot(mat,Q.transpose()))).GetValues()[0,:],
9  acq.GetPoint(â™RASI’).GetValues()[0,:], acq.GetPoint(’LPSI’).GetValues()[0,:], acq.GetPoint(’RPSI’).GetValues()[0,:]]) Frame = 40 data_FrameChosen = np.array([acq.GetPoint(’LASI’).GetValues()[Frame,:], acq.GetPoint(’RASI’).GetValues()[Frame,:], acq.GetPoint(’LPSI’).GetValues()[Frame,:], acq.GetPoint(’RPSI’).GetValues()[Frame,:]]) # Difference with mean values A = data_FrameRef-np.mean(data_FrameRef,axis=0) B = data_FrameChosen-np.mean(data_FrameChosen,axis=0) # transposition of the data A = A.transpose() B = B.transpose() # matrix multiplication # (Note : with a numpy array, it’s the dot method, not the multiplication operator) C = np.dot(B,A.transpose()) # singular decomposition, called the svd method of the scipy/linalg module P,T,Q = scipy.linalg.svd(C) # computation of the nearest rotation matrix R mat = np.array([[ 1., 0., 0.], [ 0., 1., 0.], [ 0., 0., scipy.linalg.det(np.dot(P,Q.transpose()))]]) R = np.dot(P,np.dot(mat,Q.transpose()))€RASI’).GetValues()[0,:], acq.GetPoint(’LPSI’).GetValues()[0,:], acq.GetPoint(’RPSI’).GetValues()[0,:]]) Frame = 40 data_FrameChosen = np.array([acq.GetPoint(’LASI’).GetValues()[Frame,:], acq.GetPoint(’RASI’).GetValues()[Frame,:], acq.GetPoint(’LPSI’).GetValues()[Frame,:], acq.GetPoint(’RPSI’).GetValues()[Frame,:]]) # Difference with mean values A = data_FrameRef-np.mean(data_FrameRef,axis=0) B = data_FrameChosen-np.mean(data_FrameChosen,axis=0) # transposition of the data A = A.transpose() B = B.transpose() # matrix multiplication # (Note : with a numpy array, it’s the dot method, not the multiplication operator) C = np.dot(B,A.transpose()) # singular decomposition, called the svd method of the scipy/linalg module P,T,Q = scipy.linalg.svd(C) # computation of the nearest rotation matrix R mat = np.array([[ 1., 0., 0.], [ 0., 1., 0.], [ 0., 0., scipy.linalg.det(np.dot(P,Q.transpose()))]]) R = np.dot(P,np.dot(mat,Q.transpose()))™ASI’).GetValues()[0,:], acq.GetPoint(’LPSI’).GetValues()[0,:], acq.GetPoint(’RPSI’).GetValues()[0,:]]) Frame = 40 data_FrameChosen = np.array([acq.GetPoint(’LASI’).GetValues()[Frame,:], acq.GetPoint(’RASI’).GetValues()[Frame,:], acq.GetPoint(’LPSI’).GetValues()[Frame,:], acq.GetPoint(’RPSI’).GetValues()[Frame,:]]) # Difference with mean values A = data_FrameRef-np.mean(data_FrameRef,axis=0) B = data_FrameChosen-np.mean(data_FrameChosen,axis=0) # transposition of the data A = A.transpose() B = B.transpose() # matrix multiplication # (Note : with a numpy array, it’s the dot method, not the multiplication operator) C = np.dot(B,A.transpose()) # singular decomposition, called the svd method of the scipy/linalg module P,T,Q = scipy.linalg.svd(C) # computation of the nearest rotation matrix R mat = np.array([[ 1., 0., 0.], [ 0., 1., 0.], [ 0., 0., scipy.linalg.det(np.dot(P,Q.transpose()))]]) R = np.dot(P,np.dot(mat,Q.transpose()))RASIâ™).GetValues()[0,:], acq.GetPoint(’LPSI’).GetValues()[0,:], acq.GetPoint(’RPSI’).GetValues()[0,:]]) Frame = 40 data_FrameChosen = np.array([acq.GetPoint(’LASI’).GetValues()[Frame,:], acq.GetPoint(’RASI’).GetValues()[Frame,:], acq.GetPoint(’LPSI’).GetValues()[Frame,:], acq.GetPoint(’RPSI’).GetValues()[Frame,:]]) # Difference with mean values A = data_FrameRef-np.mean(data_FrameRef,axis=0) B = data_FrameChosen-np.mean(data_FrameChosen,axis=0) # transposition of the data A = A.transpose() B = B.transpose() # matrix multiplication # (Note : with a numpy array, it’s the dot method, not the multiplication operator) C = np.dot(B,A.transpose()) # singular decomposition, called the svd method of the scipy/linalg module P,T,Q = scipy.linalg.svd(C) # computation of the nearest rotation matrix R mat = np.array([[ 1., 0., 0.], [ 0., 1., 0.], [ 0., 0., scipy.linalg.det(np.dot(P,Q.transpose()))]]) R = np.dot(P,np.dot(mat,Q.transpose()))€).GetValues()[0,:], acq.GetPoint(’LPSI’).GetValues()[0,:], acq.GetPoint(’RPSI’).GetValues()[0,:]]) Frame = 40 data_FrameChosen = np.array([acq.GetPoint(’LASI’).GetValues()[Frame,:], acq.GetPoint(’RASI’).GetValues()[Frame,:], acq.GetPoint(’LPSI’).GetValues()[Frame,:], acq.GetPoint(’RPSI’).GetValues()[Frame,:]]) # Difference with mean values A = data_FrameRef-np.mean(data_FrameRef,axis=0) B = data_FrameChosen-np.mean(data_FrameChosen,axis=0) # transposition of the data A = A.transpose() B = B.transpose() # matrix multiplication # (Note : with a numpy array, it’s the dot method, not the multiplication operator) C = np.dot(B,A.transpose()) # singular decomposition, called the svd method of the scipy/linalg module P,T,Q = scipy.linalg.svd(C) # computation of the nearest rotation matrix R mat = np.array([[ 1., 0., 0.], [ 0., 1., 0.], [ 0., 0., scipy.linalg.det(np.dot(P,Q.transpose()))]]) R = np.dot(P,np.dot(mat,Q.transpose()))™.GetValues()[0,:], acq.GetPoint(’LPSI’).GetValues()[0,:], acq.GetPoint(’RPSI’).GetValues()[0,:]]) Frame = 40 data_FrameChosen = np.array([acq.GetPoint(’LASI’).GetValues()[Frame,:], acq.GetPoint(’RASI’).GetValues()[Frame,:], acq.GetPoint(’LPSI’).GetValues()[Frame,:], acq.GetPoint(’RPSI’).GetValues()[Frame,:]]) # Difference with mean values A = data_FrameRef-np.mean(data_FrameRef,axis=0) B = data_FrameChosen-np.mean(data_FrameChosen,axis=0) # transposition of the data A = A.transpose() B = B.transpose() # matrix multiplication # (Note : with a numpy array, it’s the dot method, not the multiplication operator) C = np.dot(B,A.transpose()) # singular decomposition, called the svd method of the scipy/linalg module P,T,Q = scipy.linalg.svd(C) # computation of the nearest rotation matrix R mat = np.array([[ 1., 0., 0.], [ 0., 1., 0.], [ 0., 0., scipy.linalg.det(np.dot(P,Q.transpose()))]]) R = np.dot(P,np.dot(mat,Q.transpose()))).GetValues()[0,:],
10  acq.GetPoint(â™LPSI’).GetValues()[0,:], acq.GetPoint(’RPSI’).GetValues()[0,:]]) Frame = 40 data_FrameChosen = np.array([acq.GetPoint(’LASI’).GetValues()[Frame,:], acq.GetPoint(’RASI’).GetValues()[Frame,:], acq.GetPoint(’LPSI’).GetValues()[Frame,:], acq.GetPoint(’RPSI’).GetValues()[Frame,:]]) # Difference with mean values A = data_FrameRef-np.mean(data_FrameRef,axis=0) B = data_FrameChosen-np.mean(data_FrameChosen,axis=0) # transposition of the data A = A.transpose() B = B.transpose() # matrix multiplication # (Note : with a numpy array, it’s the dot method, not the multiplication operator) C = np.dot(B,A.transpose()) # singular decomposition, called the svd method of the scipy/linalg module P,T,Q = scipy.linalg.svd(C) # computation of the nearest rotation matrix R mat = np.array([[ 1., 0., 0.], [ 0., 1., 0.], [ 0., 0., scipy.linalg.det(np.dot(P,Q.transpose()))]]) R = np.dot(P,np.dot(mat,Q.transpose()))€LPSI’).GetValues()[0,:], acq.GetPoint(’RPSI’).GetValues()[0,:]]) Frame = 40 data_FrameChosen = np.array([acq.GetPoint(’LASI’).GetValues()[Frame,:], acq.GetPoint(’RASI’).GetValues()[Frame,:], acq.GetPoint(’LPSI’).GetValues()[Frame,:], acq.GetPoint(’RPSI’).GetValues()[Frame,:]]) # Difference with mean values A = data_FrameRef-np.mean(data_FrameRef,axis=0) B = data_FrameChosen-np.mean(data_FrameChosen,axis=0) # transposition of the data A = A.transpose() B = B.transpose() # matrix multiplication # (Note : with a numpy array, it’s the dot method, not the multiplication operator) C = np.dot(B,A.transpose()) # singular decomposition, called the svd method of the scipy/linalg module P,T,Q = scipy.linalg.svd(C) # computation of the nearest rotation matrix R mat = np.array([[ 1., 0., 0.], [ 0., 1., 0.], [ 0., 0., scipy.linalg.det(np.dot(P,Q.transpose()))]]) R = np.dot(P,np.dot(mat,Q.transpose()))™PSI’).GetValues()[0,:], acq.GetPoint(’RPSI’).GetValues()[0,:]]) Frame = 40 data_FrameChosen = np.array([acq.GetPoint(’LASI’).GetValues()[Frame,:], acq.GetPoint(’RASI’).GetValues()[Frame,:], acq.GetPoint(’LPSI’).GetValues()[Frame,:], acq.GetPoint(’RPSI’).GetValues()[Frame,:]]) # Difference with mean values A = data_FrameRef-np.mean(data_FrameRef,axis=0) B = data_FrameChosen-np.mean(data_FrameChosen,axis=0) # transposition of the data A = A.transpose() B = B.transpose() # matrix multiplication # (Note : with a numpy array, it’s the dot method, not the multiplication operator) C = np.dot(B,A.transpose()) # singular decomposition, called the svd method of the scipy/linalg module P,T,Q = scipy.linalg.svd(C) # computation of the nearest rotation matrix R mat = np.array([[ 1., 0., 0.], [ 0., 1., 0.], [ 0., 0., scipy.linalg.det(np.dot(P,Q.transpose()))]]) R = np.dot(P,np.dot(mat,Q.transpose()))LPSIâ™).GetValues()[0,:], acq.GetPoint(’RPSI’).GetValues()[0,:]]) Frame = 40 data_FrameChosen = np.array([acq.GetPoint(’LASI’).GetValues()[Frame,:], acq.GetPoint(’RASI’).GetValues()[Frame,:], acq.GetPoint(’LPSI’).GetValues()[Frame,:], acq.GetPoint(’RPSI’).GetValues()[Frame,:]]) # Difference with mean values A = data_FrameRef-np.mean(data_FrameRef,axis=0) B = data_FrameChosen-np.mean(data_FrameChosen,axis=0) # transposition of the data A = A.transpose() B = B.transpose() # matrix multiplication # (Note : with a numpy array, it’s the dot method, not the multiplication operator) C = np.dot(B,A.transpose()) # singular decomposition, called the svd method of the scipy/linalg module P,T,Q = scipy.linalg.svd(C) # computation of the nearest rotation matrix R mat = np.array([[ 1., 0., 0.], [ 0., 1., 0.], [ 0., 0., scipy.linalg.det(np.dot(P,Q.transpose()))]]) R = np.dot(P,np.dot(mat,Q.transpose()))€).GetValues()[0,:], acq.GetPoint(’RPSI’).GetValues()[0,:]]) Frame = 40 data_FrameChosen = np.array([acq.GetPoint(’LASI’).GetValues()[Frame,:], acq.GetPoint(’RASI’).GetValues()[Frame,:], acq.GetPoint(’LPSI’).GetValues()[Frame,:], acq.GetPoint(’RPSI’).GetValues()[Frame,:]]) # Difference with mean values A = data_FrameRef-np.mean(data_FrameRef,axis=0) B = data_FrameChosen-np.mean(data_FrameChosen,axis=0) # transposition of the data A = A.transpose() B = B.transpose() # matrix multiplication # (Note : with a numpy array, it’s the dot method, not the multiplication operator) C = np.dot(B,A.transpose()) # singular decomposition, called the svd method of the scipy/linalg module P,T,Q = scipy.linalg.svd(C) # computation of the nearest rotation matrix R mat = np.array([[ 1., 0., 0.], [ 0., 1., 0.], [ 0., 0., scipy.linalg.det(np.dot(P,Q.transpose()))]]) R = np.dot(P,np.dot(mat,Q.transpose()))™.GetValues()[0,:], acq.GetPoint(’RPSI’).GetValues()[0,:]]) Frame = 40 data_FrameChosen = np.array([acq.GetPoint(’LASI’).GetValues()[Frame,:], acq.GetPoint(’RASI’).GetValues()[Frame,:], acq.GetPoint(’LPSI’).GetValues()[Frame,:], acq.GetPoint(’RPSI’).GetValues()[Frame,:]]) # Difference with mean values A = data_FrameRef-np.mean(data_FrameRef,axis=0) B = data_FrameChosen-np.mean(data_FrameChosen,axis=0) # transposition of the data A = A.transpose() B = B.transpose() # matrix multiplication # (Note : with a numpy array, it’s the dot method, not the multiplication operator) C = np.dot(B,A.transpose()) # singular decomposition, called the svd method of the scipy/linalg module P,T,Q = scipy.linalg.svd(C) # computation of the nearest rotation matrix R mat = np.array([[ 1., 0., 0.], [ 0., 1., 0.], [ 0., 0., scipy.linalg.det(np.dot(P,Q.transpose()))]]) R = np.dot(P,np.dot(mat,Q.transpose()))).GetValues()[0,:],
11  acq.GetPoint(â™RPSI’).GetValues()[0,:]]) Frame = 40 data_FrameChosen = np.array([acq.GetPoint(’LASI’).GetValues()[Frame,:], acq.GetPoint(’RASI’).GetValues()[Frame,:], acq.GetPoint(’LPSI’).GetValues()[Frame,:], acq.GetPoint(’RPSI’).GetValues()[Frame,:]]) # Difference with mean values A = data_FrameRef-np.mean(data_FrameRef,axis=0) B = data_FrameChosen-np.mean(data_FrameChosen,axis=0) # transposition of the data A = A.transpose() B = B.transpose() # matrix multiplication # (Note : with a numpy array, it’s the dot method, not the multiplication operator) C = np.dot(B,A.transpose()) # singular decomposition, called the svd method of the scipy/linalg module P,T,Q = scipy.linalg.svd(C) # computation of the nearest rotation matrix R mat = np.array([[ 1., 0., 0.], [ 0., 1., 0.], [ 0., 0., scipy.linalg.det(np.dot(P,Q.transpose()))]]) R = np.dot(P,np.dot(mat,Q.transpose()))€RPSI’).GetValues()[0,:]]) Frame = 40 data_FrameChosen = np.array([acq.GetPoint(’LASI’).GetValues()[Frame,:], acq.GetPoint(’RASI’).GetValues()[Frame,:], acq.GetPoint(’LPSI’).GetValues()[Frame,:], acq.GetPoint(’RPSI’).GetValues()[Frame,:]]) # Difference with mean values A = data_FrameRef-np.mean(data_FrameRef,axis=0) B = data_FrameChosen-np.mean(data_FrameChosen,axis=0) # transposition of the data A = A.transpose() B = B.transpose() # matrix multiplication # (Note : with a numpy array, it’s the dot method, not the multiplication operator) C = np.dot(B,A.transpose()) # singular decomposition, called the svd method of the scipy/linalg module P,T,Q = scipy.linalg.svd(C) # computation of the nearest rotation matrix R mat = np.array([[ 1., 0., 0.], [ 0., 1., 0.], [ 0., 0., scipy.linalg.det(np.dot(P,Q.transpose()))]]) R = np.dot(P,np.dot(mat,Q.transpose()))™PSI’).GetValues()[0,:]]) Frame = 40 data_FrameChosen = np.array([acq.GetPoint(’LASI’).GetValues()[Frame,:], acq.GetPoint(’RASI’).GetValues()[Frame,:], acq.GetPoint(’LPSI’).GetValues()[Frame,:], acq.GetPoint(’RPSI’).GetValues()[Frame,:]]) # Difference with mean values A = data_FrameRef-np.mean(data_FrameRef,axis=0) B = data_FrameChosen-np.mean(data_FrameChosen,axis=0) # transposition of the data A = A.transpose() B = B.transpose() # matrix multiplication # (Note : with a numpy array, it’s the dot method, not the multiplication operator) C = np.dot(B,A.transpose()) # singular decomposition, called the svd method of the scipy/linalg module P,T,Q = scipy.linalg.svd(C) # computation of the nearest rotation matrix R mat = np.array([[ 1., 0., 0.], [ 0., 1., 0.], [ 0., 0., scipy.linalg.det(np.dot(P,Q.transpose()))]]) R = np.dot(P,np.dot(mat,Q.transpose()))RPSIâ™).GetValues()[0,:]]) Frame = 40 data_FrameChosen = np.array([acq.GetPoint(’LASI’).GetValues()[Frame,:], acq.GetPoint(’RASI’).GetValues()[Frame,:], acq.GetPoint(’LPSI’).GetValues()[Frame,:], acq.GetPoint(’RPSI’).GetValues()[Frame,:]]) # Difference with mean values A = data_FrameRef-np.mean(data_FrameRef,axis=0) B = data_FrameChosen-np.mean(data_FrameChosen,axis=0) # transposition of the data A = A.transpose() B = B.transpose() # matrix multiplication # (Note : with a numpy array, it’s the dot method, not the multiplication operator) C = np.dot(B,A.transpose()) # singular decomposition, called the svd method of the scipy/linalg module P,T,Q = scipy.linalg.svd(C) # computation of the nearest rotation matrix R mat = np.array([[ 1., 0., 0.], [ 0., 1., 0.], [ 0., 0., scipy.linalg.det(np.dot(P,Q.transpose()))]]) R = np.dot(P,np.dot(mat,Q.transpose()))€).GetValues()[0,:]]) Frame = 40 data_FrameChosen = np.array([acq.GetPoint(’LASI’).GetValues()[Frame,:], acq.GetPoint(’RASI’).GetValues()[Frame,:], acq.GetPoint(’LPSI’).GetValues()[Frame,:], acq.GetPoint(’RPSI’).GetValues()[Frame,:]]) # Difference with mean values A = data_FrameRef-np.mean(data_FrameRef,axis=0) B = data_FrameChosen-np.mean(data_FrameChosen,axis=0) # transposition of the data A = A.transpose() B = B.transpose() # matrix multiplication # (Note : with a numpy array, it’s the dot method, not the multiplication operator) C = np.dot(B,A.transpose()) # singular decomposition, called the svd method of the scipy/linalg module P,T,Q = scipy.linalg.svd(C) # computation of the nearest rotation matrix R mat = np.array([[ 1., 0., 0.], [ 0., 1., 0.], [ 0., 0., scipy.linalg.det(np.dot(P,Q.transpose()))]]) R = np.dot(P,np.dot(mat,Q.transpose()))™.GetValues()[0,:]]) Frame = 40 data_FrameChosen = np.array([acq.GetPoint(’LASI’).GetValues()[Frame,:], acq.GetPoint(’RASI’).GetValues()[Frame,:], acq.GetPoint(’LPSI’).GetValues()[Frame,:], acq.GetPoint(’RPSI’).GetValues()[Frame,:]]) # Difference with mean values A = data_FrameRef-np.mean(data_FrameRef,axis=0) B = data_FrameChosen-np.mean(data_FrameChosen,axis=0) # transposition of the data A = A.transpose() B = B.transpose() # matrix multiplication # (Note : with a numpy array, it’s the dot method, not the multiplication operator) C = np.dot(B,A.transpose()) # singular decomposition, called the svd method of the scipy/linalg module P,T,Q = scipy.linalg.svd(C) # computation of the nearest rotation matrix R mat = np.array([[ 1., 0., 0.], [ 0., 1., 0.], [ 0., 0., scipy.linalg.det(np.dot(P,Q.transpose()))]]) R = np.dot(P,np.dot(mat,Q.transpose()))).GetValues()[0,:]])
12 Frame = 40
13 data_FrameChosen = np.array([acq.GetPoint(â™LASI’).GetValues()[Frame,:], acq.GetPoint(’RASI’).GetValues()[Frame,:], acq.GetPoint(’LPSI’).GetValues()[Frame,:], acq.GetPoint(’RPSI’).GetValues()[Frame,:]]) # Difference with mean values A = data_FrameRef-np.mean(data_FrameRef,axis=0) B = data_FrameChosen-np.mean(data_FrameChosen,axis=0) # transposition of the data A = A.transpose() B = B.transpose() # matrix multiplication # (Note : with a numpy array, it’s the dot method, not the multiplication operator) C = np.dot(B,A.transpose()) # singular decomposition, called the svd method of the scipy/linalg module P,T,Q = scipy.linalg.svd(C) # computation of the nearest rotation matrix R mat = np.array([[ 1., 0., 0.], [ 0., 1., 0.], [ 0., 0., scipy.linalg.det(np.dot(P,Q.transpose()))]]) R = np.dot(P,np.dot(mat,Q.transpose()))€LASI’).GetValues()[Frame,:], acq.GetPoint(’RASI’).GetValues()[Frame,:], acq.GetPoint(’LPSI’).GetValues()[Frame,:], acq.GetPoint(’RPSI’).GetValues()[Frame,:]]) # Difference with mean values A = data_FrameRef-np.mean(data_FrameRef,axis=0) B = data_FrameChosen-np.mean(data_FrameChosen,axis=0) # transposition of the data A = A.transpose() B = B.transpose() # matrix multiplication # (Note : with a numpy array, it’s the dot method, not the multiplication operator) C = np.dot(B,A.transpose()) # singular decomposition, called the svd method of the scipy/linalg module P,T,Q = scipy.linalg.svd(C) # computation of the nearest rotation matrix R mat = np.array([[ 1., 0., 0.], [ 0., 1., 0.], [ 0., 0., scipy.linalg.det(np.dot(P,Q.transpose()))]]) R = np.dot(P,np.dot(mat,Q.transpose()))™ASI’).GetValues()[Frame,:], acq.GetPoint(’RASI’).GetValues()[Frame,:], acq.GetPoint(’LPSI’).GetValues()[Frame,:], acq.GetPoint(’RPSI’).GetValues()[Frame,:]]) # Difference with mean values A = data_FrameRef-np.mean(data_FrameRef,axis=0) B = data_FrameChosen-np.mean(data_FrameChosen,axis=0) # transposition of the data A = A.transpose() B = B.transpose() # matrix multiplication # (Note : with a numpy array, it’s the dot method, not the multiplication operator) C = np.dot(B,A.transpose()) # singular decomposition, called the svd method of the scipy/linalg module P,T,Q = scipy.linalg.svd(C) # computation of the nearest rotation matrix R mat = np.array([[ 1., 0., 0.], [ 0., 1., 0.], [ 0., 0., scipy.linalg.det(np.dot(P,Q.transpose()))]]) R = np.dot(P,np.dot(mat,Q.transpose()))LASIâ™).GetValues()[Frame,:], acq.GetPoint(’RASI’).GetValues()[Frame,:], acq.GetPoint(’LPSI’).GetValues()[Frame,:], acq.GetPoint(’RPSI’).GetValues()[Frame,:]]) # Difference with mean values A = data_FrameRef-np.mean(data_FrameRef,axis=0) B = data_FrameChosen-np.mean(data_FrameChosen,axis=0) # transposition of the data A = A.transpose() B = B.transpose() # matrix multiplication # (Note : with a numpy array, it’s the dot method, not the multiplication operator) C = np.dot(B,A.transpose()) # singular decomposition, called the svd method of the scipy/linalg module P,T,Q = scipy.linalg.svd(C) # computation of the nearest rotation matrix R mat = np.array([[ 1., 0., 0.], [ 0., 1., 0.], [ 0., 0., scipy.linalg.det(np.dot(P,Q.transpose()))]]) R = np.dot(P,np.dot(mat,Q.transpose()))€).GetValues()[Frame,:], acq.GetPoint(’RASI’).GetValues()[Frame,:], acq.GetPoint(’LPSI’).GetValues()[Frame,:], acq.GetPoint(’RPSI’).GetValues()[Frame,:]]) # Difference with mean values A = data_FrameRef-np.mean(data_FrameRef,axis=0) B = data_FrameChosen-np.mean(data_FrameChosen,axis=0) # transposition of the data A = A.transpose() B = B.transpose() # matrix multiplication # (Note : with a numpy array, it’s the dot method, not the multiplication operator) C = np.dot(B,A.transpose()) # singular decomposition, called the svd method of the scipy/linalg module P,T,Q = scipy.linalg.svd(C) # computation of the nearest rotation matrix R mat = np.array([[ 1., 0., 0.], [ 0., 1., 0.], [ 0., 0., scipy.linalg.det(np.dot(P,Q.transpose()))]]) R = np.dot(P,np.dot(mat,Q.transpose()))™.GetValues()[Frame,:], acq.GetPoint(’RASI’).GetValues()[Frame,:], acq.GetPoint(’LPSI’).GetValues()[Frame,:], acq.GetPoint(’RPSI’).GetValues()[Frame,:]]) # Difference with mean values A = data_FrameRef-np.mean(data_FrameRef,axis=0) B = data_FrameChosen-np.mean(data_FrameChosen,axis=0) # transposition of the data A = A.transpose() B = B.transpose() # matrix multiplication # (Note : with a numpy array, it’s the dot method, not the multiplication operator) C = np.dot(B,A.transpose()) # singular decomposition, called the svd method of the scipy/linalg module P,T,Q = scipy.linalg.svd(C) # computation of the nearest rotation matrix R mat = np.array([[ 1., 0., 0.], [ 0., 1., 0.], [ 0., 0., scipy.linalg.det(np.dot(P,Q.transpose()))]]) R = np.dot(P,np.dot(mat,Q.transpose()))).GetValues()[Frame,:],
14  acq.GetPoint(â™RASI’).GetValues()[Frame,:], acq.GetPoint(’LPSI’).GetValues()[Frame,:], acq.GetPoint(’RPSI’).GetValues()[Frame,:]]) # Difference with mean values A = data_FrameRef-np.mean(data_FrameRef,axis=0) B = data_FrameChosen-np.mean(data_FrameChosen,axis=0) # transposition of the data A = A.transpose() B = B.transpose() # matrix multiplication # (Note : with a numpy array, it’s the dot method, not the multiplication operator) C = np.dot(B,A.transpose()) # singular decomposition, called the svd method of the scipy/linalg module P,T,Q = scipy.linalg.svd(C) # computation of the nearest rotation matrix R mat = np.array([[ 1., 0., 0.], [ 0., 1., 0.], [ 0., 0., scipy.linalg.det(np.dot(P,Q.transpose()))]]) R = np.dot(P,np.dot(mat,Q.transpose()))€RASI’).GetValues()[Frame,:], acq.GetPoint(’LPSI’).GetValues()[Frame,:], acq.GetPoint(’RPSI’).GetValues()[Frame,:]]) # Difference with mean values A = data_FrameRef-np.mean(data_FrameRef,axis=0) B = data_FrameChosen-np.mean(data_FrameChosen,axis=0) # transposition of the data A = A.transpose() B = B.transpose() # matrix multiplication # (Note : with a numpy array, it’s the dot method, not the multiplication operator) C = np.dot(B,A.transpose()) # singular decomposition, called the svd method of the scipy/linalg module P,T,Q = scipy.linalg.svd(C) # computation of the nearest rotation matrix R mat = np.array([[ 1., 0., 0.], [ 0., 1., 0.], [ 0., 0., scipy.linalg.det(np.dot(P,Q.transpose()))]]) R = np.dot(P,np.dot(mat,Q.transpose()))™ASI’).GetValues()[Frame,:], acq.GetPoint(’LPSI’).GetValues()[Frame,:], acq.GetPoint(’RPSI’).GetValues()[Frame,:]]) # Difference with mean values A = data_FrameRef-np.mean(data_FrameRef,axis=0) B = data_FrameChosen-np.mean(data_FrameChosen,axis=0) # transposition of the data A = A.transpose() B = B.transpose() # matrix multiplication # (Note : with a numpy array, it’s the dot method, not the multiplication operator) C = np.dot(B,A.transpose()) # singular decomposition, called the svd method of the scipy/linalg module P,T,Q = scipy.linalg.svd(C) # computation of the nearest rotation matrix R mat = np.array([[ 1., 0., 0.], [ 0., 1., 0.], [ 0., 0., scipy.linalg.det(np.dot(P,Q.transpose()))]]) R = np.dot(P,np.dot(mat,Q.transpose()))RASIâ™).GetValues()[Frame,:], acq.GetPoint(’LPSI’).GetValues()[Frame,:], acq.GetPoint(’RPSI’).GetValues()[Frame,:]]) # Difference with mean values A = data_FrameRef-np.mean(data_FrameRef,axis=0) B = data_FrameChosen-np.mean(data_FrameChosen,axis=0) # transposition of the data A = A.transpose() B = B.transpose() # matrix multiplication # (Note : with a numpy array, it’s the dot method, not the multiplication operator) C = np.dot(B,A.transpose()) # singular decomposition, called the svd method of the scipy/linalg module P,T,Q = scipy.linalg.svd(C) # computation of the nearest rotation matrix R mat = np.array([[ 1., 0., 0.], [ 0., 1., 0.], [ 0., 0., scipy.linalg.det(np.dot(P,Q.transpose()))]]) R = np.dot(P,np.dot(mat,Q.transpose()))€).GetValues()[Frame,:], acq.GetPoint(’LPSI’).GetValues()[Frame,:], acq.GetPoint(’RPSI’).GetValues()[Frame,:]]) # Difference with mean values A = data_FrameRef-np.mean(data_FrameRef,axis=0) B = data_FrameChosen-np.mean(data_FrameChosen,axis=0) # transposition of the data A = A.transpose() B = B.transpose() # matrix multiplication # (Note : with a numpy array, it’s the dot method, not the multiplication operator) C = np.dot(B,A.transpose()) # singular decomposition, called the svd method of the scipy/linalg module P,T,Q = scipy.linalg.svd(C) # computation of the nearest rotation matrix R mat = np.array([[ 1., 0., 0.], [ 0., 1., 0.], [ 0., 0., scipy.linalg.det(np.dot(P,Q.transpose()))]]) R = np.dot(P,np.dot(mat,Q.transpose()))™.GetValues()[Frame,:], acq.GetPoint(’LPSI’).GetValues()[Frame,:], acq.GetPoint(’RPSI’).GetValues()[Frame,:]]) # Difference with mean values A = data_FrameRef-np.mean(data_FrameRef,axis=0) B = data_FrameChosen-np.mean(data_FrameChosen,axis=0) # transposition of the data A = A.transpose() B = B.transpose() # matrix multiplication # (Note : with a numpy array, it’s the dot method, not the multiplication operator) C = np.dot(B,A.transpose()) # singular decomposition, called the svd method of the scipy/linalg module P,T,Q = scipy.linalg.svd(C) # computation of the nearest rotation matrix R mat = np.array([[ 1., 0., 0.], [ 0., 1., 0.], [ 0., 0., scipy.linalg.det(np.dot(P,Q.transpose()))]]) R = np.dot(P,np.dot(mat,Q.transpose()))).GetValues()[Frame,:],
15  acq.GetPoint(â™LPSI’).GetValues()[Frame,:], acq.GetPoint(’RPSI’).GetValues()[Frame,:]]) # Difference with mean values A = data_FrameRef-np.mean(data_FrameRef,axis=0) B = data_FrameChosen-np.mean(data_FrameChosen,axis=0) # transposition of the data A = A.transpose() B = B.transpose() # matrix multiplication # (Note : with a numpy array, it’s the dot method, not the multiplication operator) C = np.dot(B,A.transpose()) # singular decomposition, called the svd method of the scipy/linalg module P,T,Q = scipy.linalg.svd(C) # computation of the nearest rotation matrix R mat = np.array([[ 1., 0., 0.], [ 0., 1., 0.], [ 0., 0., scipy.linalg.det(np.dot(P,Q.transpose()))]]) R = np.dot(P,np.dot(mat,Q.transpose()))€LPSI’).GetValues()[Frame,:], acq.GetPoint(’RPSI’).GetValues()[Frame,:]]) # Difference with mean values A = data_FrameRef-np.mean(data_FrameRef,axis=0) B = data_FrameChosen-np.mean(data_FrameChosen,axis=0) # transposition of the data A = A.transpose() B = B.transpose() # matrix multiplication # (Note : with a numpy array, it’s the dot method, not the multiplication operator) C = np.dot(B,A.transpose()) # singular decomposition, called the svd method of the scipy/linalg module P,T,Q = scipy.linalg.svd(C) # computation of the nearest rotation matrix R mat = np.array([[ 1., 0., 0.], [ 0., 1., 0.], [ 0., 0., scipy.linalg.det(np.dot(P,Q.transpose()))]]) R = np.dot(P,np.dot(mat,Q.transpose()))™PSI’).GetValues()[Frame,:], acq.GetPoint(’RPSI’).GetValues()[Frame,:]]) # Difference with mean values A = data_FrameRef-np.mean(data_FrameRef,axis=0) B = data_FrameChosen-np.mean(data_FrameChosen,axis=0) # transposition of the data A = A.transpose() B = B.transpose() # matrix multiplication # (Note : with a numpy array, it’s the dot method, not the multiplication operator) C = np.dot(B,A.transpose()) # singular decomposition, called the svd method of the scipy/linalg module P,T,Q = scipy.linalg.svd(C) # computation of the nearest rotation matrix R mat = np.array([[ 1., 0., 0.], [ 0., 1., 0.], [ 0., 0., scipy.linalg.det(np.dot(P,Q.transpose()))]]) R = np.dot(P,np.dot(mat,Q.transpose()))LPSIâ™).GetValues()[Frame,:], acq.GetPoint(’RPSI’).GetValues()[Frame,:]]) # Difference with mean values A = data_FrameRef-np.mean(data_FrameRef,axis=0) B = data_FrameChosen-np.mean(data_FrameChosen,axis=0) # transposition of the data A = A.transpose() B = B.transpose() # matrix multiplication # (Note : with a numpy array, it’s the dot method, not the multiplication operator) C = np.dot(B,A.transpose()) # singular decomposition, called the svd method of the scipy/linalg module P,T,Q = scipy.linalg.svd(C) # computation of the nearest rotation matrix R mat = np.array([[ 1., 0., 0.], [ 0., 1., 0.], [ 0., 0., scipy.linalg.det(np.dot(P,Q.transpose()))]]) R = np.dot(P,np.dot(mat,Q.transpose()))€).GetValues()[Frame,:], acq.GetPoint(’RPSI’).GetValues()[Frame,:]]) # Difference with mean values A = data_FrameRef-np.mean(data_FrameRef,axis=0) B = data_FrameChosen-np.mean(data_FrameChosen,axis=0) # transposition of the data A = A.transpose() B = B.transpose() # matrix multiplication # (Note : with a numpy array, it’s the dot method, not the multiplication operator) C = np.dot(B,A.transpose()) # singular decomposition, called the svd method of the scipy/linalg module P,T,Q = scipy.linalg.svd(C) # computation of the nearest rotation matrix R mat = np.array([[ 1., 0., 0.], [ 0., 1., 0.], [ 0., 0., scipy.linalg.det(np.dot(P,Q.transpose()))]]) R = np.dot(P,np.dot(mat,Q.transpose()))™.GetValues()[Frame,:], acq.GetPoint(’RPSI’).GetValues()[Frame,:]]) # Difference with mean values A = data_FrameRef-np.mean(data_FrameRef,axis=0) B = data_FrameChosen-np.mean(data_FrameChosen,axis=0) # transposition of the data A = A.transpose() B = B.transpose() # matrix multiplication # (Note : with a numpy array, it’s the dot method, not the multiplication operator) C = np.dot(B,A.transpose()) # singular decomposition, called the svd method of the scipy/linalg module P,T,Q = scipy.linalg.svd(C) # computation of the nearest rotation matrix R mat = np.array([[ 1., 0., 0.], [ 0., 1., 0.], [ 0., 0., scipy.linalg.det(np.dot(P,Q.transpose()))]]) R = np.dot(P,np.dot(mat,Q.transpose()))).GetValues()[Frame,:],
16  acq.GetPoint(â™RPSI’).GetValues()[Frame,:]]) # Difference with mean values A = data_FrameRef-np.mean(data_FrameRef,axis=0) B = data_FrameChosen-np.mean(data_FrameChosen,axis=0) # transposition of the data A = A.transpose() B = B.transpose() # matrix multiplication # (Note : with a numpy array, it’s the dot method, not the multiplication operator) C = np.dot(B,A.transpose()) # singular decomposition, called the svd method of the scipy/linalg module P,T,Q = scipy.linalg.svd(C) # computation of the nearest rotation matrix R mat = np.array([[ 1., 0., 0.], [ 0., 1., 0.], [ 0., 0., scipy.linalg.det(np.dot(P,Q.transpose()))]]) R = np.dot(P,np.dot(mat,Q.transpose()))€RPSI’).GetValues()[Frame,:]]) # Difference with mean values A = data_FrameRef-np.mean(data_FrameRef,axis=0) B = data_FrameChosen-np.mean(data_FrameChosen,axis=0) # transposition of the data A = A.transpose() B = B.transpose() # matrix multiplication # (Note : with a numpy array, it’s the dot method, not the multiplication operator) C = np.dot(B,A.transpose()) # singular decomposition, called the svd method of the scipy/linalg module P,T,Q = scipy.linalg.svd(C) # computation of the nearest rotation matrix R mat = np.array([[ 1., 0., 0.], [ 0., 1., 0.], [ 0., 0., scipy.linalg.det(np.dot(P,Q.transpose()))]]) R = np.dot(P,np.dot(mat,Q.transpose()))™PSI’).GetValues()[Frame,:]]) # Difference with mean values A = data_FrameRef-np.mean(data_FrameRef,axis=0) B = data_FrameChosen-np.mean(data_FrameChosen,axis=0) # transposition of the data A = A.transpose() B = B.transpose() # matrix multiplication # (Note : with a numpy array, it’s the dot method, not the multiplication operator) C = np.dot(B,A.transpose()) # singular decomposition, called the svd method of the scipy/linalg module P,T,Q = scipy.linalg.svd(C) # computation of the nearest rotation matrix R mat = np.array([[ 1., 0., 0.], [ 0., 1., 0.], [ 0., 0., scipy.linalg.det(np.dot(P,Q.transpose()))]]) R = np.dot(P,np.dot(mat,Q.transpose()))RPSIâ™).GetValues()[Frame,:]]) # Difference with mean values A = data_FrameRef-np.mean(data_FrameRef,axis=0) B = data_FrameChosen-np.mean(data_FrameChosen,axis=0) # transposition of the data A = A.transpose() B = B.transpose() # matrix multiplication # (Note : with a numpy array, it’s the dot method, not the multiplication operator) C = np.dot(B,A.transpose()) # singular decomposition, called the svd method of the scipy/linalg module P,T,Q = scipy.linalg.svd(C) # computation of the nearest rotation matrix R mat = np.array([[ 1., 0., 0.], [ 0., 1., 0.], [ 0., 0., scipy.linalg.det(np.dot(P,Q.transpose()))]]) R = np.dot(P,np.dot(mat,Q.transpose()))€).GetValues()[Frame,:]]) # Difference with mean values A = data_FrameRef-np.mean(data_FrameRef,axis=0) B = data_FrameChosen-np.mean(data_FrameChosen,axis=0) # transposition of the data A = A.transpose() B = B.transpose() # matrix multiplication # (Note : with a numpy array, it’s the dot method, not the multiplication operator) C = np.dot(B,A.transpose()) # singular decomposition, called the svd method of the scipy/linalg module P,T,Q = scipy.linalg.svd(C) # computation of the nearest rotation matrix R mat = np.array([[ 1., 0., 0.], [ 0., 1., 0.], [ 0., 0., scipy.linalg.det(np.dot(P,Q.transpose()))]]) R = np.dot(P,np.dot(mat,Q.transpose()))™.GetValues()[Frame,:]]) # Difference with mean values A = data_FrameRef-np.mean(data_FrameRef,axis=0) B = data_FrameChosen-np.mean(data_FrameChosen,axis=0) # transposition of the data A = A.transpose() B = B.transpose() # matrix multiplication # (Note : with a numpy array, it’s the dot method, not the multiplication operator) C = np.dot(B,A.transpose()) # singular decomposition, called the svd method of the scipy/linalg module P,T,Q = scipy.linalg.svd(C) # computation of the nearest rotation matrix R mat = np.array([[ 1., 0., 0.], [ 0., 1., 0.], [ 0., 0., scipy.linalg.det(np.dot(P,Q.transpose()))]]) R = np.dot(P,np.dot(mat,Q.transpose()))).GetValues()[Frame,:]])
17 # Difference with mean values
18 A = data_FrameRef-np.mean(data_FrameRef,axis=0)
19 B = data_FrameChosen-np.mean(data_FrameChosen,axis=0)
20 # transposition of the data
21 A = A.transpose()
22 B = B.transpose()
23 # matrix multiplication
24 # (Note : with a numpy array, it’s the dot method, not the multiplication operator)
25 C = np.dot(B,A.transpose())
26 # singular decomposition, called the svd method of the scipy/linalg module
27 P,T,Q = scipy.linalg.svd(C)
28 # computation of the nearest rotation matrix R
29 mat = np.array([[ 1., 0., 0.],
30  [ 0., 1., 0.],
31  [ 0., 0., scipy.linalg.det(np.dot(P,Q.transpose()))]])
32 R = np.dot(P,np.dot(mat,Q.transpose()))