--- a
+++ b/app/scratch/Leap2BVH_rot_vec.py
@@ -0,0 +1,255 @@
+import inspect
+import os
+import re
+import sys
+
+import numpy as np
+# import math
+from pymo.RotationUtil import vec2eul, rot2eul
+
+from leapmotion_setup_rot import root_name, skeleton, framerate
+from pymo.data import MocapData
+
+src_dir = os.path.dirname(inspect.getfile(inspect.currentframe()))
+# Windows and Linux
+arch_dir = '../../lib/x64' if sys.maxsize > 2 ** 32 else '../../lib/x86'
+
+sys.path.insert(0, os.path.abspath(os.path.join(src_dir, arch_dir)))
+import Leap
+
+
+class Leap2BVH:
+    """
+    A class to convert LeapMotion frames to PyMO data structure (MocapData) to be parsed to a BVH file
+
+    Calculates translations (offsets) and rotation data for the joints
+    """
+
+    def __init__(self, filename=None):
+        self._skeleton = {}
+        self.bone_context = []
+        self._motion_channels = []
+        self._motions = []
+        self.current_token = 0
+        self.framerate = 0.0
+        self.root_name = ''
+        self.data = MocapData()
+
+        self.do()
+
+    def parse(self):
+        self.data.skeleton = self._skeleton
+        self.data.channel_names = self._motion_channels
+        self.data.values = self._to_DataFrame()
+        self.data.root_name = self.root_name
+        self.data.framerate = self.framerate
+
+        return self.data
+
+    def do(self):
+        self._skeleton = skeleton
+        # self._motion_channels = motion_channels
+        self.root_name = root_name
+        self.framerate = framerate  # TODO: framerate
+
+        # frame_count = 188#TODO:frame_count
+        # frame_time = 0.0
+        # self._motions = [()] * frame_count
+
+        for key, value in self._skeleton.items():
+            value['offsets'] = [0, 0, 0]
+            for channel in value['channels']:
+                self._motion_channels.append((key, channel))
+
+        # for ii in range(frame_count):
+        #     channel_values = []
+        #     for key, value in self._skeleton.items():
+        #         for channel in value['channels']:
+        #             channel_values.append((key, channel, float(1)))
+        #     self._motions[ii] = (frame_time, channel_values)
+        #     frame_time = frame_time + framerate
+
+    def add_frame(self, frame_id, hand):
+        channel_values = []
+        for key, value in self._skeleton.items():
+            if frame_id == 0:
+                # offsets
+                if key == 'Leap_Root':
+                    x_offset, y_offset, z_offset, _, _, _ = self._get_root_values()
+                elif key == 'RightHand':
+                    x_offset, y_offset, z_offset, _, _, _ = self._get_wrist_values(hand)
+                elif 'End' in key:
+                    # Workaround for getting motion data also from finger tip by adding a not used end
+                    x_offset = y_offset = z_offset = 0.0
+                else:
+                    x_offset, y_offset, z_offset, _, _, _ = self._get_finger_values(key, hand)
+                value['offsets'] = [x_offset, y_offset, z_offset]
+
+                # print("pitch hand x = {}, angle hand x = {}".format(hand.basis.x_basis.pitch * Leap.RAD_TO_DEG,
+                #                                                     hand.basis.x_basis.angle_to(Leap.Vector.x_axis) * Leap.RAD_TO_DEG))
+
+            for channel in value['channels']:
+                # motion data with rotations
+                if key == 'Leap_Root':
+                    x_pos, y_pos, z_pos, x_rot, y_rot, z_rot = self._get_root_values()
+                elif key == 'RightHand':
+                    x_pos, y_pos, z_pos, x_rot, y_rot, z_rot = self._get_wrist_values(hand)
+                else:
+                    x_pos, y_pos, z_pos, x_rot, y_rot, z_rot = self._get_finger_values(key, hand)
+
+                if channel == 'Xposition':
+                    channel_values.append((key, channel, x_pos))
+                if channel == 'Yposition':
+                    channel_values.append((key, channel, y_pos))
+                if channel == 'Zposition':
+                    channel_values.append((key, channel, z_pos))
+                if channel == 'Xrotation':
+                    channel_values.append((key, channel, x_rot))
+                if channel == 'Yrotation':
+                    channel_values.append((key, channel, y_rot))
+                if channel == 'Zrotation':
+                    channel_values.append((key, channel, z_rot))
+
+        self._motions.append((frame_id, channel_values))
+
+    @staticmethod
+    def _get_root_values():
+        return 0, 0, 0, 0, 0, 0
+
+    def _get_wrist_values(self, hand):
+        x_wrist = hand.wrist_position.x
+        y_wrist = hand.wrist_position.y
+        z_wrist = hand.wrist_position.z
+
+        # rotation matrix from basis vectors
+        rotmat = self._basis2rot(hand.basis)
+        eul_x, eul_y, eul_z = rot2eul(rotmat)
+
+        return \
+            x_wrist, \
+            y_wrist, \
+            z_wrist, \
+            eul_x * Leap.RAD_TO_DEG, \
+            eul_y * Leap.RAD_TO_DEG, \
+            eul_z * Leap.RAD_TO_DEG
+
+    def _get_finger_values(self, key, hand):
+        key, bone_number = self._split_key(key)
+
+        fingerlist = hand.fingers.finger_type(self._get_finger_type(key))
+
+        # vector between wrist and metacarpal proximal (carpals)
+        if bone_number == 1 or ('Thumb' in key and bone_number == 2):
+            bone = fingerlist[0].bone(self._get_bone_type(bone_number))
+            x_wrist, y_wrist, z_wrist, _, _, _ = self._get_wrist_values(hand)
+            # print("1: key: {}, bone_number: {}, bone: {}, prev_joint: {}"
+            #       .format(key, bone_number, bone, bone.prev_joint))
+            # print("p1_rot = [{}; {}; {}];".format(x_wrist, y_wrist, z_wrist))
+            # print("p2_rot = [{}; {}; {}];".format(bone.prev_joint.x, bone.prev_joint.y, bone.prev_joint.z))
+            # print("p3_rot = [{}; {}; {}];".format(bone.next_joint.x, bone.next_joint.y, bone.next_joint.z))
+
+            # print('bone.next_joint.x = {}, bone.prev_joint.x = {}, x_wrist = {}, vec_prev = {}'.format(bone.next_joint.x, bone.prev_joint.x, x_wrist, vec_prev[0]))
+            # print('bone.next_joint.y = {}, bone.prev_joint.y = {}, y_wrist = {}, vec_prev = {}'.format(bone.next_joint.y, bone.prev_joint.y, y_wrist, vec_prev[1]))
+            # print('bone.next_joint.z = {}, bone.prev_joint.z = {}, z_wrist = {}, vec_prev = {}'.format(bone.next_joint.z, bone.prev_joint.z, z_wrist, vec_prev[2]))
+
+            return \
+                bone.prev_joint.x - x_wrist, \
+                bone.prev_joint.y - y_wrist, \
+                bone.prev_joint.z - z_wrist, \
+                0.0, \
+                0.0, \
+                0.0
+
+        # vector for bones metacarpal, proximal, intermediate, distal
+        bone_prev = fingerlist[0].bone(self._get_bone_type(bone_number - 1))
+
+        #  no rotation for finger tip
+        if not bone_number == 5:
+            bone_next = fingerlist[0].bone(self._get_bone_type(bone_number))
+
+            # # rotation matrix from basis vectors
+            # rotmat_prev = self._basis2rot(bone_prev.basis)
+            # rotmat_next = self._basis2rot(bone_next.basis)
+            #
+            # # rotation matrix between rotmat_prev and rotmat_next by multiplying
+            # eul_x, eul_y, eul_z = rot2eul(np.matmul(rotmat_next, np.transpose(rotmat_prev)))
+
+            vec_prev = np.array([bone_prev.next_joint.x - bone_prev.prev_joint.x,
+                                 bone_prev.next_joint.y - bone_prev.prev_joint.y,
+                                 bone_prev.next_joint.z - bone_prev.prev_joint.z])
+
+            vec_next = np.array([bone_next.next_joint.x - bone_next.prev_joint.x,
+                                 bone_next.next_joint.y - bone_next.prev_joint.y,
+                                 bone_next.next_joint.z - bone_next.prev_joint.z])
+
+            eul_x, eul_y, eul_z = vec2eul(vec_prev, vec_next)
+
+            return \
+                bone_prev.next_joint.x - bone_prev.prev_joint.x, \
+                bone_prev.next_joint.y - bone_prev.prev_joint.y, \
+                bone_prev.next_joint.z - bone_prev.prev_joint.z, \
+                eul_x * Leap.RAD_TO_DEG, \
+                eul_y * Leap.RAD_TO_DEG, \
+                eul_z * Leap.RAD_TO_DEG
+
+        return \
+            bone_prev.next_joint.x - bone_prev.prev_joint.x, \
+            bone_prev.next_joint.y - bone_prev.prev_joint.y, \
+            bone_prev.next_joint.z - bone_prev.prev_joint.z, \
+            0.0, \
+            0.0, \
+            0.0
+
+    @staticmethod
+    def _split_key(key):
+        key_split = re.split('(\d)', key)
+        key = key_split[0]
+        if key_split[-1] == '_Nub':
+            return key, 5
+        else:
+            return key, int(key_split[1])
+
+    @staticmethod
+    def _get_finger_type(key):
+        if key == 'RightHandThumb':
+            return Leap.Finger.TYPE_THUMB
+        if key == 'RightHandIndex':
+            return Leap.Finger.TYPE_INDEX
+        if key == 'RightHandMiddle':
+            return Leap.Finger.TYPE_MIDDLE
+        if key == 'RightHandRing':
+            return Leap.Finger.TYPE_RING
+        if key == 'RightHandPinky':
+            return Leap.Finger.TYPE_PINKY
+        else:
+            raise Exception('Key ({}) did not match'.format(key))
+
+    @staticmethod
+    def _get_bone_type(bone_number):
+        if bone_number == 4:
+            return Leap.Bone.TYPE_DISTAL
+        if bone_number == 3:
+            return Leap.Bone.TYPE_INTERMEDIATE
+        if bone_number == 2:
+            return Leap.Bone.TYPE_PROXIMAL
+        if bone_number == 1:
+            return Leap.Bone.TYPE_METACARPAL
+        else:
+            raise Exception('bone number ({}) did not match'.format(bone_number))
+
+    @staticmethod
+    def _basis2rot(basis):
+        return np.array([[basis.x_basis.x, basis.y_basis.x, basis.z_basis.x],
+                        [basis.x_basis.y, basis.y_basis.y, basis.z_basis.y],
+                        [basis.x_basis.z, basis.y_basis.z, basis.z_basis.z]])
+
+    def _to_DataFrame(self):
+        """Returns all of the channels parsed from the file as a pandas DataFrame"""
+
+        import pandas as pd
+        time_index = pd.to_timedelta([f[0] for f in self._motions], unit='s')
+        frames = [f[1] for f in self._motions]
+        channels = np.asarray([[channel[2] for channel in frame] for frame in frames])
+        column_names = ['%s_%s' % (c[0], c[1]) for c in self._motion_channels]
+
+        return pd.DataFrame(data=channels, index=time_index, columns=column_names)