#!/usr/bin/pythonw
#-----------------------------------------------------------------------------
# Copyright 2006-2007, Andre D Gouws and York NeuroImaging Centre
#
# Name :          ynicDV3D - ynic Data Viewer 3D
# Description :   multi-modal imaging visualisation toolkit
# Author :        Andre D Gouws
# Created :       2006-October-06
# Last Update:    2007-May-01
# Notes :         requires the following additional files:
#                   
#                   processing.py
#                   wxProcessing.py
#                   tYNI_imginfo.py
#                   tYNI_imports.py
#                   nifti_reader.py
#                   runLogo.py
#                   ynicDV3Dlogo.jpg
#                   func.lut
#                   tYNI.lut
#                   ynicDV3D_wxdialogs.py
#                   dti_processing.py
#
# History:        BETA 0.7 (01.May.2007) - code to be reviewed by M.H.
# Dependencies:   Python 2.4.1 or later, VTK 5.0 or later,
#                  FSL(FMRIB, Oxford) 3.2 or later                                     
#
#
# Major Changes: Added wx menu and remove vtk one      
#                added talairach co-ords
#                dti-data import and searching vectorised
#                
#
# TODO :        URGENT:
#                       wxPython menu / toolbar functionality
#                       fix goto mni/tal co-ordinates
#                       add a single point marker of size/radius x and current colour
#                       add a point list file with radius and colour descriptors and labels
#                       re-include ANALYZE support
#                       
#                 WISHLIST:
#                       switching between func/structural should keep plane positioning
#                       load multiple dti sets
#
#
#-----------------------------------------------------------------------------


print '\nynicDV3D - York NeuroImaging Centre Data Viewer - 3D (c) 2006-2007.'
print '\n ... starting ynicDV3d ...'
print '\nBuilt on Python 2.4.1 and VTK 5.0'
print '\nThe main window will launch shortly ... Once it has started click on the main window to launch the menu.\n\n\n'


import os,sys,os.path
import threading
from subprocess import Popen, PIPE

#############################################################
# --------- File handling ------------

def get_path(path):
    return os.path.join(os.path.split(__file__)[0], path)
    

def my_file_dialog(processing_type, extra_var1, extra_var2):
    p = Popen('pythonw %s %s %s %s' % (get_path('ynicDV3D_wxdialogs.py'), processing_type,
              extra_var1, extra_var2), stdout=PIPE, shell=True)
    p.wait()
    (so, se) = p.communicate()
    return so.strip()
    

help_main = 'file://' + os.path.realpath(get_path(os.path.join('help', 'ynicDV3D_help.html')))




#############################################################
# --------- Startup window ------------


#Check arguments
if len(sys.argv) < 2:
    file_to_load = my_file_dialog(9,0,0)
    if file_to_load == '':
        sys.exit(0)
else:
	file_to_load = sys.argv[1]
print '\n\nLoading the following dataset as structural: %s\n' %file_to_load


#launch a title logo
class StartupThread ( threading.Thread ):
    def run(self):
        os.system('pythonw %s' % get_path('runLogo.py'))

StartupThread().start()




#############################################################
#other imports

import webbrowser
import tempfile
import vtk
from vtk.util.colors import tomato, banana
from struct import unpack, calcsize #from surface
from numpy import *
import scipy as Sci
import scipy.linalg
import sys
import time
from tYNI_imginfo import *
from nifti_reader import *
import tYNI_imports as tYNI
import processing
from dti_processing import create_dti_array, extract_dti_fiber_set
import wx
from wx.lib.colourchooser.pypalette import PyPalette



#############################################################
# --------- other threads ------------

class ProgressTrackingThread( threading.Thread ):
    def run(self):
        os.system('pythonw %s' % get_path('wxProcessing.py'))

ProgressTrackingThread().start()


#############################################################
# --------- globals ------------yeah .. I know there are too many!
planeWidgetX = vtk.vtkImagePlaneWidget()
surf_num = 0
surf_min = []
surf_max = []
fiber_data_loaded = 0   
fibers_visible = 0
fibers_pickable = 0
func_data_loaded = 0
func_data_visible = 0
cortex_data_loaded = 0
ortho_planes_on = 0
profileList = []
plotData = []
lineData = []
instr_visible = 1
x_slice_pos = 88    
y_slice_pos = 128
z_slice_pos = 128
current_mpr_orient = 0
fiber_group = 0
fiber_group_counter = []
counter = 0
a_fibers = []
dti_data_array = []
dti_x_const = 0
dti_y_const = 0
dti_z_const = 0
tmp_menu_ref = ''
bounds = 0

renWin = vtk.vtkRenderWindow()
selected_pos_actor = vtk.vtkActor()
mni_textActor = vtk.vtkActor2D()
tal_textActor = vtk.vtkActor2D()
roiActor_seed = vtk.vtkActor()
boxWidget_seed = vtk.vtkBoxWidget()
roiActor_target = vtk.vtkActor()
boxWidget_target = vtk.vtkBoxWidget()
ortho_planes_on = 0
original_LU_table = vtk.vtkLookupTable()
pos_colour_bar_generated = 0
neg_colour_bar_generated = 0
pos_scalarBar = []
neg_scalarBar = []
functional_2d_volume = []
functionalLut = []
mpr_showing_2d = 0
data_x_offset = 0
data_y_offset = 0
data_z_offset = 0
data_x_thick = 0
data_y_thick = 0
data_z_thick = 0
srow_x = 0
srow_y = 0
srow_z = 0
qrow_x = 0
qrow_y = 0
qrow_z = 0
mni_srow_x = 0
mni_srow_y = 0
mni_srow_z = 0
mni_transform_supplied = 0
to_mni_mat = []
import_data_x_offset = 0

#for dipole datamouse
rows = []
dipole_file_loaded = 0
dipole_rows = []
dipole_transform = 0
dipole_min_time = 0
dipole_max_time = 0
dipole_current_time = 0
dipole_mat = []
cortex_data = 0
origActor = vtk.vtkLODActor()
selectActor = vtk.vtkLODActor()
planes = 0
boxWidget = 0
boxWidget2 = 0

#for headshape files
headshape_loaded = 0
glyph_hs = vtk.vtkActor()

#for headshape files
coils_loaded = 0
glyph_coils = vtk.vtkActor()

# This is the s-form matrix from the MNI avg152 brain supplied with fsl
s_form=array([[-2.0, 0.0, 0.0, 90.0],[0.0, 2.0, 0.0, -126.0],[0.0, 0.0, 2.0, -72.0],[0,0,0,1]])

# This is the MNI-toTalairach transformation matrix from Lancaster et al 2007
MTT_pooled = array([[0.9357, 0.0029, -0.0072, -1.0423],[-0.0065, 0.9396, -0.0726, -1.3940],[0.0103, 0.0752, 0.8967, 3.6475],[0,0,0,1]])


#for min_norm files
mn_loaded = 0
my_mnorm_brain = vtk.vtkActor()

#logic for first loaded volume
first_load = 0

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







#############################################################
###---------ROUTINES FOR INTERACTION BY MENU AND KEYBINDINGS



############# Make markers at points of interest #############

# ---------routines ------------

def load_multipoint_marker_file():
    global ren, renWin, surf_min, surf_max, surf_num, func_data_loaded, data_to_load, pos_colour_bar_generated, neg_colour_bar_generated, pos_scalarBar, neg_scalarBar, mpr_showing_2d, functionalLut, s_form, to_mni_mat
    data_to_load = my_file_dialog(44,0,0)
    if data_to_load == '':
        print 'Load cancelled\n' 
        return
    if (data_to_load[-4:] != '.mpf'):
        print '\nSorry! A multiple point file (.mpf) needs to be supplied.. You can create a blank one by clicking the ''''Make marker template'''' button ...\n'
        return
    else:
        f = open(data_to_load)
        p = f.readlines()
        f.close()
        point_data = []
        for i in range(4,len(p)):
            point_data.append(p[i].strip().split(';'))
        print point_data
        for j in range(len(point_data)):
            new_pt = vtk.vtkSphereSource()
            new_pt.SetRadius(float(point_data[j][2]))
            #new_pt.SetCenter( -trans_coord1[0][0]+ar.fov[0]*ar.pixdim[0], trans_coord1[0][1], trans_coord1[0][2])
            x_coord, y_coord, z_coord = float(point_data[j][0].split(',')[0]),float(point_data[j][0].split(',')[1]),float(point_data[j][0].split(',')[2])
            
            if point_data[j][4] == 'DATA': #adjust to fit at data co-ordinate
                x_coord = float(x_coord) - srow_x[3]
                y_coord = float(y_coord) - srow_y[3]
                z_coord = float(z_coord) - srow_z[3]           
            
                #transform back from rotation +/ scaling
                back_transf_mat = array([[float(srow_x[0]), float(srow_x[1]), float(srow_x[2])],[float(srow_y[0]), float(srow_y[1]), float(srow_y[2])],[float(srow_z[0]), float(srow_z[1]), float(srow_z[2])]])
                new_val = dot(array([x_coord,y_coord,z_coord]),linalg.inv(back_transf_mat))
                new_x_slice, new_y_slice, new_z_slice = new_val[0], new_val[1], new_val[2]
                planeWidgetX.SetPlaneOrientationToXAxes()
                planeWidgetY.SetPlaneOrientationToYAxes()
                planeWidgetZ.SetPlaneOrientationToZAxes()
                planeWidgetX.SetSliceIndex(int(new_x_slice))
                planeWidgetY.SetSliceIndex(int(new_y_slice))
                planeWidgetZ.SetSliceIndex(int(new_z_slice))
                new_pt.SetCenter(planeWidgetX.GetSlicePosition(), planeWidgetY.GetSlicePosition(), planeWidgetZ.GetSlicePosition())
            
            
            elif point_data[j][4] == 'MNI': #adjust to fit at mni co-ordinate
                if mni_transform_supplied == 0:
                    print 'Pt %d could no be added. No MNI transform supplied at startup ...\n' %j
                else:
                    mni_coords_for_marker = array([x_coord,y_coord,z_coord,1])
                    mni_coords_for_marker = dot(linalg.inv(s_form),mni_coords_for_marker)
                    mni_coords_for_marker = mni_coords_for_marker*array([2,2,2,1])
                    mni_coords_for_marker = dot(linalg.inv(to_mni_mat),mni_coords_for_marker)
                    mni_coords_for_marker = mni_coords_for_marker/array(list(ar.pixdim)+[1])                   
                    new_x_slice, new_y_slice, new_z_slice = mni_coords_for_marker[0], mni_coords_for_marker[1], mni_coords_for_marker[2]
                    planeWidgetX.SetPlaneOrientationToXAxes()
                    planeWidgetY.SetPlaneOrientationToYAxes()
                    planeWidgetZ.SetPlaneOrientationToZAxes()
                    planeWidgetX.SetSliceIndex(int(new_x_slice))
                    planeWidgetY.SetSliceIndex(int(new_y_slice))
                    planeWidgetZ.SetSliceIndex(int(new_z_slice))
                    new_pt.SetCenter(planeWidgetX.GetSlicePosition(), planeWidgetY.GetSlicePosition(), planeWidgetZ.GetSlicePosition())
            
            
            elif point_data[j][4] == 'SLICE': #adjust to fit at slice number co-ordinate
                planeWidgetX.SetPlaneOrientationToXAxes()
                planeWidgetY.SetPlaneOrientationToYAxes()
                planeWidgetZ.SetPlaneOrientationToZAxes()
                planeWidgetX.SetSliceIndex(x_coord)
                planeWidgetY.SetSliceIndex(y_coord)
                planeWidgetZ.SetSliceIndex(z_coord)
                new_pt.SetCenter(planeWidgetX.GetSlicePosition(), planeWidgetY.GetSlicePosition(), planeWidgetZ.GetSlicePosition())
            
            
            else:
                print 'ERROR in .mpf file! Please check and try again! \n'
                return
                
            #new_pt.SetCenter(x_coord, y_coord, z_coord)
            PointMapper = vtk.vtkPolyDataMapper()
            PointMapper.SetInput(new_pt.GetOutput())
            PointActor = vtk.vtkActor()
            PointActor.SetMapper(PointMapper)
            PointActor.GetProperty().SetColor(float(point_data[j][1].split(',')[0])/255,float(point_data[j][1].split(',')[1])/255,float(point_data[j][1].split(',')[2])/255) 
            ren.AddActor(PointActor)
            renWin.Render()




def create_multipoint_marker_file_template():
    f = file('/tmp/new_multiple_point_marker_template.mpf.txt','w')
    f.write('#.mpf.txt (multi-point-file text) format - NO SPACES ALLOWED - use under_scores (_)\n')
    f.write('#X,Y,Z;R,G,B;RADIUS; LABEL TEXT;DATA/MNI/SLICE;\n')
    f.write('# first line is an example - replace with your own - add extra below\n')
    f.write('#data lines go below here .. do not delete the commented (#) lines\n')
    f.write('-21,32,12;255,0,0;5;no label;DATA;\n')
    f.close()
    os.system('open /tmp/new_multiple_point_marker_template.mpf.txt &')



############# MNI Coordinates #############

# --------- Map MNI co-ordinate into current data ------------

def map_mni_coods_to_local():
    global mni_transform_supplied
    if mni_transform_supplied == 0:
        print 'No MNI transform supplied at startup\n'
    else:
        mni_coords_to_map = my_file_dialog(11,0,0)
        if mni_coords_to_map == '':
            print 'Load cancelled\n' 
            return
        else:
            print mni_coords_to_map.split(',')
            if len(mni_coords_to_map.split(',')) <> 3:
                if mni_coords_to_map == '':
                    print 'Load cancelled\n' 
                    return
                else:
                    print 'Please enter co-ordinates in the format number,number,number (with commas) .. \n'
                    map_mni_coods_to_local()
            trans_mni = mni_coords_to_map.split(',')
            trans_mni_x = int(trans_mni[0])
            trans_mni_y = int(trans_mni[1])
            trans_mni_z = int(trans_mni[2])



############# MPR PLANES #############

###reset the planewidgets to initial view if required at any time
def resetPlanes():
    global planeWidgetX, planeWidgetY, planeWidgetZ, x_slice_pos, y_slice_pos, z_slice_pos
    planeWidgetX.SetPlaneOrientationToXAxes()
    planeWidgetY.SetPlaneOrientationToYAxes()
    planeWidgetZ.SetPlaneOrientationToZAxes()
    planeWidgetX.SetSliceIndex(x_slice_pos)
    planeWidgetY.SetSliceIndex(y_slice_pos)
    planeWidgetZ.SetSliceIndex(z_slice_pos)



############# HEADSHAPE  FILES #############
### Load a 4D Polhemus headshape file for the subject
def minNorm():
    global mn_loaded, my_mnorm_brain, mn_curr_pos
    
    mn_surface_filename = my_file_dialog(49,0,0)
    if mn_surface_filename == '':
        print 'Load cancelled\n' 
        return    

    mn_data_filename = my_file_dialog(50,0,0)
    if mn_data_filename == '':
        print 'Load cancelled\n' 
        return

    #load the surface
    try_me = vtk.vtkPolyDataReader()
    try_me.SetFileName(mn_surface_filename)

    #load the data    
    f = open(mn_data_filename)
    sz0 = unpack('>l', f.read(calcsize('l')))[0]
    sz1 = unpack('>l', f.read(calcsize('l')))[0]
    start_time = unpack('>f', f.read(calcsize('f')))[0]
    delt = unpack('>f', f.read(calcsize('f')))[0]
    mn_data = reshape(fromfile(f,dtype=float32), (sz0,sz1))
    f.close()

    mn_PolyData = try_me.GetOutput()
    mn_PolyData.Update()

    mn_ScalarValues = mn_PolyData.GetPointData()

    initial_scalars = vtk.vtkFloatArray()

    for i in range(7536):
        initial_scalars.InsertNextValue(mn_data[i][92])

    mn_ScalarValues.SetScalars(initial_scalars)


    mn_PolyData.Update()

    mn_Mapper = vtk.vtkPolyDataMapper()
    mn_Mapper.SetInput(mn_PolyData)
    mn_Mapper.ScalarVisibilityOn()

    mn_Mapper.Update()

    my_mnorm_brain = vtk.vtkActor()
    my_mnorm_brain.SetMapper(mn_Mapper)
    
    ren.AddActor(my_mnorm_brain)
    mn_loaded = 1


############# HEADSHAPE  FILES #############
### Load a 4D Polhemus headshape file for the subject
def HeadShape():
    global ren, renWin, headshape_loaded, glyph_hs

    hs_filename = my_file_dialog(45,0,0)
    if hs_filename == '':
            print 'Load cancelled\n' 
            return
    hs_transform = my_file_dialog(46,0,0)
    if hs_transform == '':
            print 'Load cancelled\n' 
            return

    p = open(hs_filename)
    a = p.readlines()
    p.close()

    my_points = []

    for c in a:
        f = c.split()
        my_points.append(f)

    #remove unwanted parts of the data file:
    for i in range(len(my_points)):
        if len(my_points[i]) < 1:
            pass
        else:
            if my_points[i][0] == 'Digitization':
                header_length = i

    my_points = my_points[header_length+1:] # first x lines are header

    # Total number of points.
    numberOfInputPoints = int(len(my_points))

    inputPoints = vtk.vtkPoints()

    # List of points for each line to be drawn through
    glyphList = []
    
    e = reshape(fromfile(hs_transform, sep=' ') , (4,4))

	

    for i in range(numberOfInputPoints):
        # Extract values for each point and convert from metres to mm
        x = float(my_points[i][0])
        y = float(my_points[i][1])
        z = float(my_points[i][2])
		
        coord1 = array([x, y, z, 1]).reshape(4,1)
        trans_coord1 = dot(e, coord1).reshape(1,4)
        inputPoints.InsertPoint(i, trans_coord1[0][0], trans_coord1[0][1], trans_coord1[0][2])
            
    # The following section will create glyphs for the pivot points

    # Create a polydata to be glyphed.
    inputData = vtk.vtkPolyData()
    inputData.SetPoints(inputPoints)

    # Use sphere as glyph source.
    balls = vtk.vtkSphereSource()
    balls.SetRadius(1.31)
    balls.SetPhiResolution(10)
    balls.SetThetaResolution(10)

    glyphPoints = vtk.vtkGlyph3D()
    glyphPoints.SetInput(inputData)
    glyphPoints.SetSource(balls.GetOutput())

    glyphMapper = vtk.vtkPolyDataMapper()
    glyphMapper.SetInput(glyphPoints.GetOutput())

    glyph_hs = vtk.vtkActor()
    glyph_hs.SetMapper(glyphMapper)
    glyph_hs.GetProperty().SetDiffuseColor((1.0,1.0,0.0))
    glyph_hs.GetProperty().SetSpecular(.3)
    glyph_hs.GetProperty().SetSpecularPower(30)
    ren.AddActor(glyph_hs)
    headshape_loaded = 1
    renWin.Render()
    




############# COIL POSITION  FILES #############
### Load a 4D Polhemus coil position file for the subject
def CoilPositions():
    global ren, renWin, coils_loaded, glyph_coils

    coil_filename = my_file_dialog(47,0,0)
    if coil_filename == '':
            print 'Load cancelled\n' 
            return
    coil_transform = my_file_dialog(48,0,0)
    if coil_transform == '':
            print 'Load cancelled\n' 
            return

    """Read in coil position and orientation in meg SCS from a .m4d file."""
    f=open(coil_filename)
    d = f.readlines()
    f.close()

    info_start = d.index('MSI.Meg_Position_Information.Begin:\n')
    info_end = d.index('MSI.Meg_Position_Information.End:\n')

    my_points = empty( (248,6), float)
    for y in d[info_start+1:info_end]:
        if y[0] != 'A':
            continue
        z=y.split()
        for i in range(1,7):
            my_points[int(z[0][1:])-1, i-1] = float(z[i])

    # Total number of points.
    numberOfInputPoints = int(len(my_points))

    inputPoints = vtk.vtkPoints()

    # List of points for each line to be drawn through
    glyphList = []
    
    e = reshape(fromfile(coil_transform, sep=' ') , (4,4))

	

    for i in range(numberOfInputPoints):
        # Extract values for each point and convert from metres to mm
        x = float(my_points[i][0])
        y = float(my_points[i][1])
        z = float(my_points[i][2])
		
        coord1 = array([x, y, z, 1]).reshape(4,1)
        trans_coord1 = dot(e, coord1).reshape(1,4)
        inputPoints.InsertPoint(i, trans_coord1[0][0], trans_coord1[0][1], trans_coord1[0][2])
            
    # The following section will create glyphs for the pivot points

    # Create a polydata to be glyphed.
    inputData = vtk.vtkPolyData()
    inputData.SetPoints(inputPoints)

    # Use sphere as glyph source.
    balls = vtk.vtkSphereSource()
    balls.SetRadius(3.31)
    balls.SetPhiResolution(10)
    balls.SetThetaResolution(10)

    glyphPoints = vtk.vtkGlyph3D()
    glyphPoints.SetInput(inputData)
    glyphPoints.SetSource(balls.GetOutput())

    glyphMapper = vtk.vtkPolyDataMapper()
    glyphMapper.SetInput(glyphPoints.GetOutput())

    glyph_coils = vtk.vtkActor()
    glyph_coils.SetMapper(glyphMapper)
    glyph_coils.GetProperty().SetDiffuseColor((0.0,0.0,1.0))
    glyph_coils.GetProperty().SetSpecular(.3)
    glyph_coils.GetProperty().SetSpecularPower(30)
    ren.AddActor(glyph_coils)
    coils_loaded = 1
    renWin.Render()





############# DIPOLE ACTOR #############

def Dipole_Load():
    global line, dipole_min_time, dipole_max_time, dipole_file, dipole_transform, first_dipole_point, dipole_current_time, dipole_file_loaded, ren, dipole_rows, trans_coord1, trans_coord2, Sphere, dipoleSphereActor, dipoleLineActor
    ####################### DIPOLE ACTOR #############
    #NB - import dipole data in cm 
    # divide location and magnitude elements by 100, append 1
    # use as a 1*4 vector
    # import spheres.txt transformation matrix  
    # trans_rot * location vector
    dipole_file = my_file_dialog(5,0,0)
    if dipole_file == '':
            print 'Load cancelled\n' 
            return
    dipole_transform = my_file_dialog(6,0,0)
    if dipole_transform == '':
            print 'Load cancelled\n' 
            return
    first_dipole_point = my_file_dialog(20,0,0)
    if first_dipole_point == '':
            print 'Load cancelled\n' 
            return
    dipole_current_time = float(first_dipole_point)
    p = open(dipole_file)       
    d = p.readlines()
    p.close()
    rows = []
    data1 = []
    for c in d:
        f = c.split()
        rows.append(f)
    dipole_file_loaded = 1

    #establish where the dipole values start i.e. how long the header of the output file is (it varies!)

    for i in range(len(rows)):
        if len(rows[i]) < 1:
            pass
        else:
            if rows[i][0] == 'EPOCH':
                header_length = i

    rows = rows[header_length+1:] # first x lines are header
    dipole_rows = array(rows).astype(float)
    dipole_min_time = dipole_rows[0][0]
    dipole_max_time = dipole_rows[len(rows)-1][0]
    dipole_data = dipole_rows[dipole_rows[:,0] >= float(first_dipole_point), :][0]            
    e = reshape(fromfile(dipole_transform, sep=' ') , (4,4))
    coord1 = array([dipole_data[1]/100, dipole_data[2]/100, dipole_data[3]/100,1]).reshape(4,1)
    coord2 = array([dipole_data[4]/100, dipole_data[5]/100, dipole_data[6]/100,1]).reshape(4,1)         
    trans_coord1 = dot(e, coord1).reshape(1,4)
    trans_coord2 = dot(e, coord2).reshape(1,4)
    #  ADD Sphere  #
    Sphere = vtk.vtkSphereSource()
    Sphere.SetCenter( -trans_coord1[0][0]+ar.fov[0]*ar.pixdim[0], trans_coord1[0][1], trans_coord1[0][2])
    Sphere.SetRadius( dipole_data[7]/2 )
    SphereMapper = vtk.vtkPolyDataMapper()
    SphereMapper.SetInput(Sphere.GetOutput())
    dipoleSphereActor = vtk.vtkActor()
    dipoleSphereActor.SetMapper(SphereMapper)
    dipoleSphereActor.GetProperty().SetColor(1,0,0) 
    point1 = [-trans_coord1[0][0]+ar.fov[0]*ar.pixdim[0], trans_coord1[0][1], trans_coord1[0][2]]
    point2 = [-trans_coord2[0][0]-trans_coord1[0][0]+ar.fov[0]*ar.pixdim[0], trans_coord2[0][1]+trans_coord1[0][1], trans_coord2[0][2]+trans_coord1[0][2]]
    point2_rescale = add((subtract(point2,point1))/10,point1)            
    #  ADD Line  #
    line = vtk.vtkLineSource()
    line.SetPoint1(point1)
    line.SetPoint2(point2_rescale)            
    lineMapper = vtk.vtkPolyDataMapper()
    lineMapper.SetInput(line.GetOutput())
    dipoleLineActor = vtk.vtkActor()
    dipoleLineActor.SetMapper(lineMapper)
    dipoleLineActor.GetProperty().SetColor(1,0,0)
    dipoleLineActor.GetProperty().SetLineWidth(2)
    ren.AddActor(dipoleLineActor)
    ren.AddActor(dipoleSphereActor)

def DipoleVisibility():
    if dipoleSphereActor.GetVisibility() == 0:
        dipoleSphereActor.SetVisibility(1)
        dipoleLineActor.SetVisibility(1)
    else:
        dipoleSphereActor.SetVisibility(0)
        dipoleLineActor.SetVisibility(0)


## END DIPOLE ACTOR ##







############# ORTHO VIEWs #############

# --------- Routine for outputting orthogonal views t a third window ------------ 
def ortho_updates():
    global bounds, mni_textActor, ren, renWin, ortho_planes_on, pos_colour_bar_generated, neg_colour_bar_generated, pos_scalarBar, neg_scalarBar, xyz_textActor
    
    #markers for views L-R-A-P-I-S
    markers = []
    marker_pos = []
    marker_txt = []
    marker_list = []
    
    marker_pos.append((15,145))
    marker_pos.append((285,145))
    marker_pos.append((148,285))
    marker_pos.append((148,15))
    
    marker_txt.append("L")
    marker_txt.append("R")  
    marker_txt.append("I")
    marker_txt.append("S")
    marker_txt.append("A")
    marker_txt.append("P")
    
    for j in range(4):
        atext = vtk.vtkTextActor()
        atext.SetDisplayPosition(marker_pos[j][0],marker_pos[j][1])
        tprop = atext.GetTextProperty()
        tprop.SetFontSize(14)
        tprop.SetFontFamilyToArial()
        tprop.SetColor(1, 1, 0)
        tprop.BoldOn()
        marker_list.append(atext)
    
    for j in range(4):
        ren.AddActor(marker_list[j])

    xyz_textActor.VisibilityOff()
    mni_textActor.VisibilityOff()
    tal_textActor.VisibilityOff()
    
    #catch the current main window settings so we can revert to these later
    ttt = ren.GetActiveCamera()
    #set projection to parallel rather than perspective
    ttt.SetParallelProjection(1)
    sz = renWin.GetSize()
    p = planeWidgetX.GetTexturePlaneProperty()
    p.SetOpacity(0)
    p = planeWidgetY.GetTexturePlaneProperty()
    p.SetOpacity(0)
    a,b,c,d,e,g = ttt.GetClippingRange(), ttt.GetDistance(),  ttt.GetEyeAngle(),  ttt.GetFocalDisk(),  ttt.GetPosition(),  ttt.GetViewUp()
    renWin.SetSize(300,300)
    
    if planeWidgetX.GetPlaneProperty().GetOpacity() == 1:
        edges_on = 1
    else:
        edges_on = 0
    
    ## SET UP THE FIRST VIEW
    xxx = ren.GetActiveCamera()
    xxx.SetPosition(bounds[1]/2,bounds[3]/2,bounds[5]/2-750)
    xxx.SetViewUp(0,1,0)
    xxx.SetViewAngle(30)


    ##SET UP THE COLOUR BARS (IF PRESENT)

    if pos_colour_bar_generated == 1:
        pos_scalarBar.VisibilityOn()           
        pos_scalarBar.SetWidth(0.14)
        pos_scalarBar.GetPositionCoordinate().SetValue(0.01,0.65)
    if neg_colour_bar_generated == 1:
        neg_scalarBar.VisibilityOn()
        neg_scalarBar.SetWidth(0.14)
        neg_scalarBar.GetPositionCoordinate().SetValue(0.01,0.30)

    if edges_on == 1:
        planeWidgetX.GetPlaneProperty().SetOpacity(1.0)
        planeWidgetY.GetPlaneProperty().SetOpacity(1.0)
        planeWidgetZ.GetPlaneProperty().SetOpacity(0.0)
        
    #update markers
    marker_list[0].SetInput('')
    marker_list[1].SetInput(marker_txt[0])
    marker_list[2].SetInput(marker_txt[4])
    marker_list[3].SetInput(marker_txt[5])
    for j in range(4):
        marker_list[j].GetTextProperty().SetColor(0,0,1)
    renWin.Render()
    xgrab = vtk.vtkWindowToImageFilter()
    xgrab.SetInput(renWin)
    xgrab.Update()
    x1=xgrab.GetOutput()
    
    ## SET UP THE SECOND VIEW

    if pos_colour_bar_generated == 1:
        pos_scalarBar.VisibilityOff()           
    if neg_colour_bar_generated == 1:
        neg_scalarBar.VisibilityOff()

    p = planeWidgetZ.GetTexturePlaneProperty()
    p.SetOpacity(0)
    p = planeWidgetX.GetTexturePlaneProperty()
    p.SetOpacity(1)
    xxx.SetPosition(bounds[1]/2+750,bounds[3]/2,bounds[5]/2)
    xxx.SetViewUp(0,0,1)
        
    if edges_on == 1:
        planeWidgetX.GetPlaneProperty().SetOpacity(0.0)
        planeWidgetY.GetPlaneProperty().SetOpacity(1.0)
        planeWidgetZ.GetPlaneProperty().SetOpacity(1.0)
    
    #update markers
    marker_list[0].SetInput(marker_txt[5])
    marker_list[1].SetInput(marker_txt[4])
    marker_list[2].SetInput(marker_txt[3])
    marker_list[3].SetInput(marker_txt[2])
    for j in range(4):
        marker_list[j].GetTextProperty().SetColor(1,0,0)
    renWin.Render()
    ygrab = vtk.vtkWindowToImageFilter()
    ygrab.SetInput(renWin)
    ygrab.Update()
    y1=ygrab.GetOutput()
    
    ## SET UP THE THIRD VIEW

    p = planeWidgetX.GetTexturePlaneProperty()
    p.SetOpacity(0)
    p = planeWidgetY.GetTexturePlaneProperty()
    p.SetOpacity(1)
    
    xxx.SetPosition(bounds[1]/2,bounds[3]/2+750,bounds[5]/2)
    xxx.SetViewUp(0,0,1)
    
    if edges_on == 1:
        planeWidgetX.GetPlaneProperty().SetOpacity(1.0)
        planeWidgetY.GetPlaneProperty().SetOpacity(0.0)
        planeWidgetZ.GetPlaneProperty().SetOpacity(1.0)
    
    #update markers
    marker_list[0].SetInput(marker_txt[1])
    marker_list[1].SetInput(marker_txt[0])
    marker_list[2].SetInput(marker_txt[3])
    marker_list[3].SetInput(marker_txt[2])
    for j in range(4):
        marker_list[j].GetTextProperty().SetColor(1,1,0)
    
    xyz_textActor.VisibilityOn()
    if mni_transform_supplied == 1:
        mni_textActor.VisibilityOn()
        tal_textActor.VisibilityOn()
    mni_textActor.SetDisplayPosition(120,30)
    tal_textActor.SetDisplayPosition(220,30)
    
    renWin.Render()
    zgrab = vtk.vtkWindowToImageFilter()
    zgrab.SetInput(renWin)
    zgrab.Update()
    z1=zgrab.GetOutput()
    
    #RESET - reset original window and re-render it
    for j in range(4):
        ren.RemoveActor(marker_list[j])

    if pos_colour_bar_generated == 1:
        pos_scalarBar.VisibilityOn()           
    if neg_colour_bar_generated == 1:
        neg_scalarBar.VisibilityOn()     
    
    if pos_colour_bar_generated ==1:
        pos_scalarBar.SetWidth(0.06)
        pos_scalarBar.GetPositionCoordinate().SetValue(0.05,0.65)
           
    if neg_colour_bar_generated ==1:
        neg_scalarBar.SetWidth(0.06)
        neg_scalarBar.GetPositionCoordinate().SetValue(0.05,0.30)
    
    #set projection back to perspective rather than parallel 
    ttt.SetParallelProjection(0)
    
    renWin.SetSize(sz)
    p = planeWidgetX.GetTexturePlaneProperty()
    p.SetOpacity(1)
    p = planeWidgetY.GetTexturePlaneProperty()
    p.SetOpacity(1)
    p = planeWidgetZ.GetTexturePlaneProperty()
    p.SetOpacity(1)
    
    xxx.SetPosition(e)
    xxx.SetViewUp(g)
    xxx.SetViewAngle(30)
    renWin.Render()
    
    map_x = vtk.vtkImageMapper()
    map_x.SetInput(x1)
    map_x.SetColorLevel(128)
    map_x.SetColorWindow(255)
    
    map_y = vtk.vtkImageMapper()
    map_y.SetInput(y1)
    map_y.SetColorLevel(128)
    map_y.SetColorWindow(255)
    
    map_z = vtk.vtkImageMapper()
    map_z.SetInput(z1)
    map_z.SetColorLevel(128)
    map_z.SetColorWindow(255)
    
    act_x.SetMapper(map_x)
    act_x.SetPosition(0,600)
    act_y.SetMapper(map_y)
    act_y.SetPosition(0,300)
    act_z.SetMapper(map_z)
        
    ren3.AddActor(act_x)
    ren3.AddActor(act_y)
    ren3.AddActor(act_z)
    
    mni_textActor.SetDisplayPosition(100,30)
    tal_textActor.SetDisplayPosition(180,30)
    
    ortho_planes_on = 1
    if edges_on ==1:
        planeWidgetX.GetPlaneProperty().SetOpacity(1.0)
        planeWidgetY.GetPlaneProperty().SetOpacity(1.0)
        planeWidgetZ.GetPlaneProperty().SetOpacity(1.0)
    
    renWin.Render()
    return


##CALL the creation / refresh of ORTHOGONAL IMAGES  ##
def OrthoCreate():
    global renWin3, iren3, ortho_planes_on, myCallBack, ren3
    if ortho_planes_on == 0: #if not already loaded
        ortho_updates()
        renWin3.AddRenderer(ren3)
        renWin3.SetSize(300,900)
        renWin3.SetPosition(1120,0)
        style = vtk.vtkInteractorStyleTrackballCamera()
        iren3.SetInteractorStyle(style) 
        iren3.SetRenderWindow(renWin3)
        iren3.Initialize()
        ortho_planes_on = 1
        iren3.AddObserver("KeyPressEvent", myCallBack)
        iren3.Start()
    else:
        ren3.RemoveActor(act_x)
        ren3.RemoveActor(act_y)
        ren3.RemoveActor(act_z)

        ortho_updates()
        ren3.Render()
        iren3.Render()
        ##  END ORTHOGONAL IMAGES



############# CORTEX ACTOR #############

#Import data to structure
def CortexLoad():
    global cortex_data_loaded, meshActor, polyData, planes, clipper, selectActor, boxWidget2, origActor
    if cortex_data_loaded == 0:
        fn = my_file_dialog(2,0,0)
        if fn == '':
            print 'Load cancelled\n' 
            return
        (meshActor, polyData) = tYNI.import_cortex_data(fn)
        ren.AddActor(meshActor)
        cortex_data_loaded = 1
                    
        planes = vtk.vtkPlanes()
        clipper = vtk.vtkClipPolyData()
        clipper.SetInput(polyData)
        clipper.SetClipFunction(planes)
        clipper.InsideOutOn()
        selectMapper = vtk.vtkPolyDataMapper()
        selectMapper.SetInput(clipper.GetOutput())
        selectActor = vtk.vtkLODActor()
        selectActor.SetMapper(selectMapper)
        selectActor.GetProperty().SetColor(0.6, 0.6, 0.6)
        
        #set some properties for the inner face
        #TODO figure out why inside and outside are the wrong ay around?
        property1 = vtk.vtkProperty()
        property1.SetColor(0.2, 0.9, 0.2)
        #property1.SetDiffuse(0.7)
        #property1.SetSpecular(0.4)
        #property1.SetSpecularPower(20)
        
        selectActor.SetBackfaceProperty(property1)
        selectActor.VisibilityOff()
        selectActor.SetScale(1.01, 1.01, 1.01)
        
        # The SetInteractor method is how 3D widgets are associated with the
        # render window interactor.  Internally, SetInteractor sets up a bunch
        # of callbacks using the Command/Observer mechanism (AddObserver()).
        boxWidget2 = vtk.vtkBoxWidget()
        boxWidget2.SetInteractor(iact)
        boxWidget2.SetKeyPressActivationValue('V')
        boxWidget2.SetPlaceFactor(1.25)
        
        ren.AddActor(origActor)
        ren.AddActor(selectActor)
        
        # This callback funciton does the actual work: updates the vtkPlanes
        # implicit function.  This in turn causes the pipeline to update.
        def SelectPolygons(object, event):
            # object will be the boxWidget
            global meshActor,selectActor, planes
            object.GetPlanes(planes)
            selectActor.VisibilityOn()
            meshActor.VisibilityOff()
         
        # Place the interactor initially. The input to a 3D widget is used to
        # initially position and scale the widget. The "EndInteractionEvent" is
        # observed which invokes the SelectPolygons callback.
        boxWidget2.SetInput(polyData)
        boxWidget2.PlaceWidget()
        boxWidget2.AddObserver("EndInteractionEvent", SelectPolygons)
        
        print 'CORTEX LOADED\n'
    else:
        print 'cortex data already loaded\n'

#cortex on/off once loaded
def CortexVisibility():
    global meshActor
    vis = meshActor.GetVisibility()
    if vis == 1:
        meshActor.VisibilityOff()
    else:
        meshActor.VisibilityOn()
        props = meshActor.GetProperty()
        if props.GetOpacity() == 0:
            meshActor.GetProperty().SetOpacity(0.1)
        ## END CORTEX DATA



############# FIBER DATA #############

#visibility of seed
def SeedVisibility():
    global roiActor_seed, boxWidget_seed
    if roiActor_seed.GetVisibility() == 0:
        roiActor_seed.VisibilityOn()
        boxWidget_seed.On()
    else:
        roiActor_seed.VisibilityOff()
        boxWidget_seed.Off() 

#visibility of actor
def TargetVisibility():
    global roiActor_target, boxWidget_target
    if roiActor_target.GetVisibility() == 0:
        roiActor_target.VisibilityOn()
        boxWidget_target.On()
    else:
        roiActor_target.VisibilityOff()
        boxWidget_target.Off() 

#track fibers through seed / target
def TrackFibers():
    global fiber_group, fiber_data_loaded, roiActor_seed, roiActor_target, profileList_New, profileList, boxWidget_seed, boxWidget_target,import_data_x_offset
    if fiber_data_loaded == 0:
        print 'No fiber data loaded yet! .. \n'
    else:
        xmin, xmax, ymin, ymax, zmin, zmax = roiActor_seed.GetBounds()
        xmin2, xmax2, ymin2, ymax2, zmin2, zmax2 = roiActor_target.GetBounds()
        
        profileList_New = []

        if roiActor_seed.GetVisibility() == 0:
            print 'No seed ROI defined / visible .... \n'
            return
        else:
            if roiActor_target.GetVisibility() == 0:
                print 'Tracking fibers through seed ROI only (no target) ...\n'
                (profileList_New) = extract_dti_fiber_set(dti_data_array, dti_x_const, dti_y_const, dti_z_const, xmin, xmax, ymin, ymax, zmin, zmax, 'None', 'None', 'None', 'None', 'None', 'None',import_data_x_offset)
                if len(profileList_New) == 0:
                    return
            else:
                print 'Tracking fibers through seed ROI and target ...\n'
                (profileList_New) = extract_dti_fiber_set(dti_data_array, dti_x_const, dti_y_const, dti_z_const, xmin, xmax, ymin, ymax, zmin, zmax, xmin2, xmax2, ymin2, ymax2, zmin2, zmax2,import_data_x_offset)
                if len(profileList_New) == 0:
                    return
        
        fiber_group += 1
        print 'fiber_group %d\n' %fiber_group
        orig_fiber_count = len(profileList)
        for j in range(len(profileList_New)):
            profileList.append(profileList_New[j])

        for i in range(orig_fiber_count,len(profileList)):
            profileList[i].my_fiber_group = fiber_group
            ren.AddActor(profileList[i])
        
        for k in range(len(profileList)):
            profileList[k].SetPickable(1)
        
        print 'NEW FIBER DATA READY (IN BACKGROUND)\n'
        fiber_group_counter.append((orig_fiber_count,len(profileList)))                   
        boxWidget_seed.GetOutlineProperty().SetRepresentationToWireframe()
        boxWidget_target.GetOutlineProperty().SetRepresentationToWireframe()

        ## END FIBERS




############# SAVE IMAGES #############

#save ortho window output
def SaveOrthoToTif():
    global ortho_planes_on, renWin3, iren3
    if ortho_planes_on == 0:
        ortho_updates()
        renWin3.AddRenderer(ren3)
        renWin3.SetSize(300,900)
        renWin3.SetPosition(1120,0)
        style = vtk.vtkInteractorStyleTrackballCamera()
        iren3.SetInteractorStyle(style) 
        iren3.SetRenderWindow(renWin3)
        iren3.Initialize()
        iren3.AddObserver("KeyPressEvent", myCallBack)
        ortho_planes_on = 1
        iren3.Start() 
    
    w2i = vtk.vtkWindowToImageFilter()
    writer = vtk.vtkTIFFWriter()
    w2i.SetInput(renWin3)
    w2i.Update()
    writer.SetInputConnection(w2i.GetOutputPort())
    save_name = my_file_dialog(4,0,0)
    if save_name == '':
        print 'Load cancelled\n' 
        return
    writer.SetFileName("%s.tif" %save_name)
    renWin3.Render()
    writer.Write()
    print 'saved ortho-window to %s.tif sucessfully\n' %save_name 


#save main window output
def SaveMainToTif():
    global renWin
    w2i = vtk.vtkWindowToImageFilter()
    writer = vtk.vtkTIFFWriter()
    w2i.SetInput(renWin)
    w2i.Update()
    writer.SetInputConnection(w2i.GetOutputPort())
    save_name = my_file_dialog(4,0,0)
    if save_name == '':
        print 'Load cancelled\n' 
        return
    writer.SetFileName("%s.tif" %save_name)
    writer.Write()
    print 'saved main window to %s.tif sucessfully\n' %save_name






#############################################################
###THE MAIN VTK PROGRAM / WINDOW
#############################################################


def ynicDV3DMainWindow():
    global first_load, my_mnorm_brain, mn_loaded, glyph_hs, dipole_min_time, dipole_max_time, tal_textActor, to_mni_mat,s_form, MTT_pooled, qrow_x, qrow_y, qrow_z, mni_textActor, myCallBack, myCallback2, myCallback3, myCallBack_BF, bounds, selected_pos_sphere, selected_pos_actor, mni_srow_x, mni_srow_y, mni_srow_z, srow_x, srow_y, srow_z, picker1, boxWidget_target, boxWidget_seed, roiActor_seed, roiActor_target, mpr_edges_onoff, mpr_sag_onoff, mpr_cor_onoff, mpr_axial_onoff, load_functional_data, tmp_menu_ref, planeWidgetX, planeWidgetY, planeWidgetZ, renWin, iact, ren, currentActor, currentActor2, surf_num, ttt, a, b, c, d, e, f, g, ortho_planes_on, ren3, renWin3, iren3, act_x, act_y, act_z, fiber_data_loaded, profileList, plotData, lineData, cortex_data_loaded, meshActor, menu_initialised, func_data_visible, func_data_loaded, surf_num, surf_max, surf_min, current_mpr_orient, fiber_group, fiber_group_counter, x_const, y_const, z_const, counter, a_fibers, rows, dipole_file_loaded, dipole_rows, dipole_transform, dipole_min_time, dipole_max_time, dipole_current_time, dipoleSphereActor, dipoleLineActor, dipole_mat, Sphere, SphereMapper, line, lineMapper, cortex_data, origActor, selectActor, planes, boxWidget, boxWidget2,   clipper, brain, triangles, vertices, polyData, first_dipole_point,x,y,stuff,functionalLut, vol, original_LU_table, functionalLut, functional_2d_volume, pos_scalarBar, pos_colour_bar_generated, resetPlanes, mpr_showing_2d, import_data_x_offset, dti_data_array, dti_x_const, dti_y_const, dti_z_const, posTextMapper, mni_posTextMapper, process_functional_input_for_2d, xyz_textActor, neg_colour_bar_generated, pos_colour_bar_generated, pos_scalarBar, neg_scalarBar, resetPlanes


    ######## -- CENTRAL ROUTINES -- #############################################################

    #the print statements in this section are left in for further testing which is required
    def myMouse_tracker(obj, event):
        global first_load, tal_textActor, to_mni_mat, s_form, MTT_pooled, mni_textActor, mni_srow_x, mni_srow_y, mni_srow_z, iact, planeWidgetX, planeWidgetY, planeWidgetZ, srow_x, srow_y, srow_z, posTextMapper, ar, mm_in_mni, mni_transform_supplied, to_mni_mat, mni_posTextMapper
        
        if planeWidgetX.GetCursorDataStatus() == 1:
            r = planeWidgetX.GetCurrentCursorPosition()
        elif planeWidgetY.GetCursorDataStatus() == 1:
            r = planeWidgetY.GetCurrentCursorPosition()
        elif planeWidgetZ.GetCursorDataStatus() == 1:
            r = planeWidgetZ.GetCurrentCursorPosition()
        else:
            return
        
        #now output the current position to the screen
        x = srow_x[0] * r[0] + srow_x[1] * r[1] + srow_x[2] * r[2] + srow_x[3]
        y = srow_y[0] * r[0] + srow_y[1] * r[1] + srow_y[2] * r[2] + srow_y[3]
        z = srow_z[0] * r[0] + srow_z[1] * r[1] + srow_z[2] * r[2] + srow_z[3]
        posTextMapper.SetInput("Dataset\nx = %1.2f \ny = %1.2f \nz = %1.2f" %(x,y,z))
        
        
        if mni_transform_supplied == 1:
            p1=array(list(r)+[1])*array(list(ar.pixdim)+[1]) 
            T = to_mni_mat
            #hard-coded pixel dimensions of  fsl avg1521 brain (2,2,2)
            p2=dot(T,p1)/array(list((2.0,2.0,2.0))+[1])

        
            # go from MNI (slices) to MNI (mm)
            mni_coords =  dot(s_form,p2)
        
            # go from MNI (mm) to Talairach (mm)
            tal_coords = dot(MTT_pooled, mni_coords)
            
            #return (tuple(tal_coords[:3]), tuple(mni_coords[:3]))
            mni_posTextMapper.SetInput("MNI\nx = %1.2f \ny = %1.2f \nz = %1.2f" %(mni_coords[0], mni_coords[1], mni_coords[2]))
            tal_posTextMapper.SetInput("TAL\nx = %1.2f \ny = %1.2f \nz = %1.2f" %(tal_coords[0], tal_coords[1], tal_coords[2]))
    
            mni_textActor.VisibilityOn()
            tal_textActor.VisibilityOn()
            
            ####test inverse
            #x2 = dot(linalg.inv(s_form),mni_coords)
            #x2 = x2*array(list((2.0,2.0,2.0))+[1])
            #x1 = dot(linalg.inv(T),x2)
            #x1 = x1/array(list(ar.pixdim)+[1])
            #r = x1
            #print 'r2'
            #print r
            
        else:
            mni_textActor.VisibilityOff()
            tal_textActor.VisibilityOff()



    ######## -- READERS -- #############################################################
    # --------- Import routines for Nifti and Analyze------------
    x=0
    y=0

    def nifti2vtkImageData(filename):
        global first_load, x, y, data, data_x_offset, data_y_offset, data_z_offset, data_x_thick, data_y_thick, data_z_thick, qrow_x, qrow_y, qrow_z, srow_x, srow_y, srow_z, ar, to_mni_mat, mni_transform_supplied, import_data_x_offset
        """Read in an image in .nii.gz format and return a vtkImageData object"""
            
        # parse the header
        ar = nifti_reader(filename)
        spacing = ar.pixdim
        
        data = ar.get_image_data()
        if ar.dtype == nifti_reader.DT_SIGNED_SHORT:
            bytes_per_sample = 2
            data_type = vtk.VTK_SHORT
        elif ar.dtype == nifti_reader.DT_FLOAT:
            bytes_per_sample = 4
            data_type = vtk.VTK_FLOAT
        elif ar.dtype == nifti_reader.DT_SIGNED_INT:
            bytes_per_sample = 4
            data_type = vtk.VTK_INT
        else:
            bytes_per_sample = 1
            data_type = vtk.VTK_UNSIGNED_CHAR
        
        x = data.max()
        y = data.min()
        vol = vtk.vtkImageImport()
        size = len(data) * bytes_per_sample
        vol.CopyImportVoidPointer(data, size)
        vol.SetDataScalarType(data_type)
        vol.SetNumberOfScalarComponents(1)
        extent = vol.GetDataExtent()

        dim = list(ar.dim)
        dim.reverse()

        vol.SetDataExtent(extent[0],extent[0]+dim[2]-1,
                                            extent[2],extent[2]+dim[1]-1,
                                            extent[4],extent[4]+dim[0]-1)
        vol.SetWholeExtent(extent[0],extent[0]+dim[2]-1,
                                             extent[2],extent[2]+dim[1]-1,
                                             extent[4],extent[4]+dim[0]-1)

        vol.SetDataSpacing(-ar.pixdim[0], ar.pixdim[1], ar.pixdim[2])

        #get the origin offset values from the data header to allow display of mm co-ordinates
        p = os.popen('avwhd %s' %filename)
        d = p.readlines()
        p.close()

        s = []
        for c in d:
            s.append(c.split())

        srow_x = (float(s[56][1]), float(s[56][2]), float(s[56][3]), float(s[56][4]))
        srow_y = (float(s[57][1]), float(s[57][2]), float(s[57][3]), float(s[57][4]))
        srow_z = (float(s[58][1]), float(s[58][2]), float(s[58][3]), float(s[58][4]))
        
        qrow_x = (float(s[47][1]), float(s[47][2]), float(s[47][3]), float(s[47][4]))
        qrow_y = (float(s[48][1]), float(s[48][2]), float(s[48][3]), float(s[48][4]))
        qrow_z = (float(s[49][1]), float(s[49][2]), float(s[49][3]), float(s[49][4]))
        
        
        o = [0,0,0]
        vol.SetDataOrigin(ar.fov[0]*ar.pixdim[0], o[1], o[2])
        #vol.SetDataOrigin(0, o[1], o[2])
        
        import_data_x_offset = ar.fov[0]*ar.pixdim[0]
        #print 'import_data_x_offset = %f' %import_data_x_offset
        
        #TODO - only call this at the first pass?
        #offer the option to supply a transformation matrix for the volume to mni space
        if first_load == 0:
            first_load = 1
            mni_transform_supplied = 0
            to_mni_mat = 0
            mni_transform_to_load = my_file_dialog(10,0,0)
            if mni_transform_to_load == '':
                print 'No MNI transform supplied\n' 
                pass
            else:
                to_mni_mat = reshape(fromfile(mni_transform_to_load, dtype=float, count=-1, sep=' '),(4,4))
                mni_transform_supplied = 1

        return vol


    ###process image data for 2d input
    def process_functional_input_for_2d(structural_vol, functional_vol):
        global x,y,overlay_max,overlay_min,maxval,minval
        """Read in an image in .nii.gz format and return a vtkImageData object"""

        # parse the header
        ar_struct = nifti_reader(structural_vol)
        spacing = ar_struct.pixdim
        grey_data = float32(ar_struct.get_image_data())

        ar_func = nifti_reader(functional_vol)
        spacing = ar_func.pixdim
        func_data = float32(ar_func.get_image_data())
        
        x = func_data.max()
        y = func_data.min()
        overlay_max = x
        overlay_min = y
        #these next 2 vals are the 'lower' bounds of the negative and positive extremes
        # i.e. minval is closer to zero than overlay_min = -7 etc.
        if overlay_max > 0:
            maxval = my_file_dialog(12,overlay_max,0)
            if maxval == 'skip':
                maxval = overlay_max
            else:
                maxval = float(maxval)
                if maxval < 0:
                    maxval = -maxval
        else:
            maxval = overlay_max
            
        if overlay_min < 0:
            minval = my_file_dialog(13,overlay_min,0)
            if minval == 'skip':
                minval = overlay_min
            else:
                minval = float(minval)
                if minval > 0:
                    minval = -minval
        else:
            minval = overlay_min


        #merge the data sets
        pos_mask = clip(func_data,0,overlay_max)
        pos_mask = clip(pos_mask-maxval,0,1)
        
        neg_mask = clip(func_data,overlay_min,0)
        neg_mask = clip(neg_mask-minval,-1,0)
        
        pos_mask_ones = ceil(pos_mask)
        neg_mask_ones = floor(neg_mask)
        mask_ones = pos_mask_ones - neg_mask_ones
        mask_ones = -(mask_ones-1)
        grey_max = grey_data.max()
        masked_200scaled_grey_data = ((grey_data/grey_max)*199)*mask_ones
        
        pos_func_data = clip(func_data,0,func_data.max())
        scaled200_225_pos_func_data1 = ((pos_func_data/func_data.max())*25)+200
        scaled200_225_pos_func_data = scaled200_225_pos_func_data1*pos_mask_ones    
        neg_func_data = clip(func_data,func_data.min(),0)
        scaled225_250_neg_func_data1 = ((neg_func_data/-func_data.min())*25)+250
        scaled225_250_neg_func_data = scaled225_250_neg_func_data1*neg_mask_ones
        
        if minval == overlay_min:
            data = masked_200scaled_grey_data + scaled200_225_pos_func_data
        elif maxval == overlay_max:
            data = masked_200scaled_grey_data - scaled225_250_neg_func_data
        else:
            data = masked_200scaled_grey_data + scaled200_225_pos_func_data - scaled225_250_neg_func_data
            
        #start the processing
        
        if ar_func.dtype == nifti_reader.DT_SIGNED_SHORT:
            bytes_per_sample = 2
            data_type = vtk.VTK_SHORT
        elif ar_func.dtype == nifti_reader.DT_FLOAT:
            bytes_per_sample = 4
            data_type = vtk.VTK_FLOAT
        elif ar_func.dtype == nifti_reader.DT_SIGNED_INT:
            bytes_per_sample = 4
            data_type = vtk.VTK_INT
        

        vol = vtk.vtkImageImport()
        size = len(data) * bytes_per_sample
        vol.CopyImportVoidPointer(data, size)
        vol.SetDataScalarType(data_type)
        vol.SetNumberOfScalarComponents(1)
        extent = vol.GetDataExtent()
        dim = list(ar_func.dim)
        dim.reverse()

        vol.SetDataExtent(extent[0],extent[0]+dim[2]-1,
                                            extent[2],extent[2]+dim[1]-1,
                                            extent[4],extent[4]+dim[0]-1)
        vol.SetWholeExtent(extent[0],extent[0]+dim[2]-1,
                                             extent[2],extent[2]+dim[1]-1,
                                             extent[4],extent[4]+dim[0]-1)

        vol.SetDataSpacing(-ar_func.pixdim[0], ar_func.pixdim[1], ar_func.pixdim[2])

            
        o = [0,0,0]
        vol.SetDataOrigin(ar.fov[0]*ar.pixdim[0], o[1], o[2])
        return vol
        

    def analyze2vtkImageData(filename):
        #global vol
        """Read in an image in analyze format and return a vtkImageData object"""

        # remove any file ending
        if (filename[-4:] == '.hdr') or (filename[-4:] == '.img'):
            filename = filename[:-4]

        # parse the header
        ar = AnalyzeReader(filename)
        #spacing = [abs(x) for x in ar.pixdim]
        spacing = ar.pixdim
        if ar.dtype[0] == 4:
            bytes_per_sample = 2
            data = fromfile(filename + '.img', short)
            data_type = vtk.VTK_SHORT
        elif ar.dtype[0] == 16:
            bytes_per_sample = 4
            data = fromfile(filename + '.img', 'f')
            data_type = vtk.VTK_FLOAT
        elif ar.dtype[0] == 2:
            bytes_per_sample = 1
            data = fromfile(filename + '.img', 'B')
            data_type = vtk.VTK_UNSIGNED_CHAR         
        elif ar.dtype[0] == 8:
            bytes_per_sample = 8
            data = fromfile(filename + '.img', 'i')
            data_type = vtk.VTK_INT
            


        vol = vtk.vtkImageImport()
        size = len(data) * bytes_per_sample
        vol.CopyImportVoidPointer(data, size)
        vol.SetDataScalarType(data_type)
        vol.SetNumberOfScalarComponents(1)
        extent = vol.GetDataExtent()
        dim = list(ar.dim[0:3])
        dim.reverse()

        vol.SetDataExtent(extent[0],extent[0]+dim[2]-1,
                                            extent[2],extent[2]+dim[1]-1,
                                            extent[4],extent[4]+dim[0]-1)
        vol.SetWholeExtent(extent[0],extent[0]+dim[2]-1,
                                             extent[2],extent[2]+dim[1]-1,
                                             extent[4],extent[4]+dim[0]-1)

        vol.SetDataSpacing(spacing[0], spacing[1], spacing[2])
        
        if ar.pixdim[0] < 0:
            vol.SetDataOrigin(-ar.GetFOV()[0], 0, 0)
            
        return vol


    ########  END Readers #############################################################


 

    ######## -- ADD FUNCTIONAL DATA -- #############################################################
    # --------- Routine ------------
        

    def load_functional_data(): 
        global ren, renWin, surf_min, surf_max, surf_num, func_data_loaded, data_to_load, pos_colour_bar_generated, neg_colour_bar_generated, pos_scalarBar, neg_scalarBar, mpr_showing_2d, functionalLut
        #Get user to select functional data
        data_to_load = my_file_dialog(1,0,0)
        if data_to_load == '':
            print 'Load cancelled\n' 
            return
        if (data_to_load[-7:] != '.nii.gz'):
            print '\nSorry! All loaded functional data currently needs to be in NIFTI_GZ format. - analyze will be supported soon! You can use avwchfiletype to convert to nifti first ...\n'
            return
        else:
            f_or_3d_correct = 0
            while f_or_3d_correct == 0:
                flat_or_3d = my_file_dialog(19,0,0)
                if flat_or_3d == '':
                    print 'Load cancelled\n' 
                    return            
                if flat_or_3d == '3':
                    f_or_3d_correct = 1
                    create_3d_functional_data()
                elif flat_or_3d == 'm':
                    f_or_3d_correct = 1
                    create_2d_functional_data(data_to_load)
                
                else:
                    print '\nPlease type m if you want to merge the functional data with the current structural or 3 if you want to load the functional data as 3d blobs ...\n'


    #create an intermediate fsl merged overlay file for stats and structure and load this in with a predefined LUT
    def create_2d_functional_data(overlay_filename): 
        global file_to_load, ren, renWin, surf_min, surf_max, surf_num, func_data_loaded, data_to_load, vol, pos_colour_bar_generated, neg_colour_bar_generated, pos_scalarBar, neg_scalarBar, mpr_showing_2d, functional_2d_volume, functionalLut,volx,overlay, process_functional_input_for_2d

        
        
        functionalLut = []
        structural_filename = file_to_load
            
        volx = process_functional_input_for_2d(structural_filename, overlay_filename)

        if pos_colour_bar_generated == 1:
            ren.RemoveActor2D(pos_scalarBar)
        if neg_colour_bar_generated == 1:    
            ren.RemoveActor2D(neg_scalarBar)
            renWin.Render()
            
        processing.set_start_processing()
        ProgressTrackingThread().start()
            
        functional_2d_volume = volx.GetOutput()
        w = functional_2d_volume.GetDimensions()
        
        r = reshape(fromfile(get_path('func.lut'),dtype=float, count=-1, sep=','),(250,4))
        functionalLut = vtk.vtkWindowLevelLookupTable()
        functionalLut.SetNumberOfTableValues(250)
        for i in range(len(r)):
            functionalLut.SetTableValue(i,r[i][0],r[i][1],r[i][2],r[i][3])

        planeWidgetX.SetUserControlledLookupTable(1)
        planeWidgetY.SetUserControlledLookupTable(1)
        planeWidgetZ.SetUserControlledLookupTable(1)
        
        planeWidgetX.SetLookupTable(functionalLut)
        planeWidgetY.SetLookupTable(functionalLut)
        planeWidgetZ.SetLookupTable(functionalLut)
        planeWidgetX.SetWindowLevel(250,125)
        planeWidgetY.SetWindowLevel(250,125)
        planeWidgetZ.SetWindowLevel(250,125)
        
        planeWidgetX.SetInput(functional_2d_volume)
        planeWidgetY.SetInput(functional_2d_volume)
        planeWidgetZ.SetInput(functional_2d_volume)
        
        #no prepare the colour bars
        if (overlay_max > 0) and (overlay_max != maxval):
            r = reshape(fromfile(get_path('func.lut'),dtype=float, count=-1, sep=','),(250,4))
            pos_component_Lut = vtk.vtkWindowLevelLookupTable()
            pos_component_Lut.SetNumberOfTableValues(25)
            pos_component_Lut.SetRange(maxval, overlay_max)
            for i in range(25):
                pos_component_Lut.SetTableValue(i,r[i+200][0],r[i+200][1],r[i+200][2],r[i+200][3])        
            
            pos_scalarBar =  vtk.vtkScalarBarActor()
            pos_scalarBar.SetLookupTable(pos_component_Lut)
            pos_scalarBar.SetTitle('Positive')

            pos_scalarBar.GetTitleTextProperty().SetFontSize(24)
            pos_scalarBar.GetPositionCoordinate().SetCoordinateSystemToNormalizedViewport()
            pos_scalarBar.GetPositionCoordinate().SetValue(0.05,0.65)
            pos_scalarBar.SetWidth(0.06)
            pos_scalarBar.SetHeight(0.3)
            ren.AddActor2D(pos_scalarBar)
            pos_scalarBar.SetNumberOfLabels(5)
            pos_scalarBar.SetOrientationToVertical()
            pos_colour_bar_generated = 1
        
        if (overlay_min < 0) and (overlay_min != minval):
            r2 = reshape(fromfile(get_path('func.lut'),dtype=float, count=-1, sep=','),(250,4))
            neg_component_Lut = vtk.vtkWindowLevelLookupTable()
            neg_component_Lut.SetNumberOfTableValues(25)
            neg_component_Lut.SetRange(overlay_min, minval)
            for i in range(25):
                #have to reverse the order .. not 225+ but 250- because of requirements of scalarbar neg-to-more-neg
                neg_component_Lut.SetTableValue(i,r2[i+225][0],r2[i+225][1],r2[i+225][2],r2[i+225][3])        
            
            neg_scalarBar =  vtk.vtkScalarBarActor()
            neg_scalarBar.SetLookupTable(neg_component_Lut)
            neg_scalarBar.SetTitle('Negative')

            neg_scalarBar.GetTitleTextProperty().SetFontSize(24)
            neg_scalarBar.GetPositionCoordinate().SetCoordinateSystemToNormalizedViewport()
            neg_scalarBar.GetPositionCoordinate().SetValue(0.05,0.30)
            neg_scalarBar.SetWidth(0.06)
            neg_scalarBar.SetHeight(0.3)
            ren.AddActor2D(neg_scalarBar)
            neg_scalarBar.SetNumberOfLabels(5)
            neg_scalarBar.SetOrientationToVertical()
            neg_colour_bar_generated = 1
                    
        renWin.Render()
        resetPlanes()
        mpr_showing_2d = 1
        processing.set_fin_processing()
        
        print ' ... Completed 2d - merge ...\n'


    #create the functional data as multiple isosurfaces
    def create_3d_functional_data(): 
        global ren, renWin, surf_min, surf_max, surf_num, func_data_loaded, data_to_load, rMin, rMax, first_dipole_point
            
        num_bins = my_file_dialog(18,0,0)
        if num_bins == '':
            print 'Load cancelled\n' 
            return
        if num_bins == '0':
            print 'you asked for zero bins - Load cancelled\n' 
            return   
        bins_to_display = my_file_dialog(17,0,0)
        if bins_to_display == '':
            print 'Load cancelled' 
            return
        if bins_to_display == '0':
            print 'you asked for zero bins - Load cancelled\n' 
            return
        if bins_to_display == num_bins:
            bins_to_display = str(int(bins_to_display) - 1)
        if int(num_bins) > 10:
            num_bins = '10'
            print 'Number of bins currently restricted to maximum 10. Proceeding with 10 ...\n'
        if int(bins_to_display) >= int(num_bins):
            bins_to_display = str(int(num_bins) - 1)
        if data_to_load.endswith('.hdr'):
            print '\nA nifti (.nii.gz) volume is required\n'
            #volr = analyze2vtkImageData(data_to_load) 
            return
            
        elif data_to_load.endswith('.nii.gz'):
            volr = nifti2vtkImageData(data_to_load) 

        else:
            print '\nA nifti (.nii.gz) volume is required\n'
            return
        
        print '\n ... Loading functional data as multiple 3d isosurfaces ...\n'
        
        processing.set_start_processing()
        ProgressTrackingThread().start()
        
        vr = volr.GetOutput()
        vr.Update()
        
        rMin, rMax = vr.GetScalarRange()

        func_data_loaded = 1
        
        #colour tables
        
        pos_max_colors = []
        pos_max_colors.append((1, 0, 0,))
        pos_max_colors.append((1, 0.1, 0)) 
        pos_max_colors.append((1, 0.2, 0)) 
        pos_max_colors.append((1, 0.3, 0)) 
        pos_max_colors.append((1, 0.4, 0)) 
        pos_max_colors.append((1, 0.5, 0)) 
        pos_max_colors.append((1, 0.6, 0)) 
        pos_max_colors.append((1, 0.8, 0)) 
        pos_max_colors.append((1, 0.9, 0)) 
        pos_max_colors.append((1, 1, 0))
        
        pos_min_colors = []
        pos_min_colors.append((0, 0, 1,))
        pos_min_colors.append((0, 0.1, 1)) 
        pos_min_colors.append((0, 0.2, 1)) 
        pos_min_colors.append((0, 0.3, 1)) 
        pos_min_colors.append((0, 0.4, 1)) 
        pos_min_colors.append((0, 0.5, 1)) 
        pos_min_colors.append((0, 0.6, 1)) 
        pos_min_colors.append((0, 0.8, 1)) 
        pos_min_colors.append((0, 0.9, 1)) 
        pos_min_colors.append((0, 1, 1))
        
        #routines
        
        def get_surface(vr, value):
            global surf_min, surf_max, surf_num
            
            isoSurfaceExtractor = vtk.vtkContourFilter()
            isoSurfaceExtractor.SetInput(vr)
            isoSurfaceExtractor.SetValue(0, value)
            isoSurfaceExtractor.ComputeGradientsOn()
            isoSurfaceExtractor.UseScalarTreeOn()
            
            surfNormals = vtk.vtkPolyDataNormals()
            surfNormals.SetInput(isoSurfaceExtractor.GetOutput())
            surfNormals.SetFeatureAngle(60.0)
            
            surfMapper = vtk.vtkPolyDataMapper()
            surfMapper.SetInput(surfNormals.GetOutput())
            surfMapper.ScalarVisibilityOff()
            surfMapper.Update()
            
            surf = vtk.vtkActor()
            #surf.GetProperty().SetFrontfaceCulling(0)
            surf.GetProperty().SetLineWidth(0.005) 
            surf.SetMapper(surfMapper)
            
            return surf
        
        surf_min = []
        surf_max = []
        for i in range(int(num_bins)-int(bins_to_display),int(num_bins)):
            print 'Extracting contours %d/%d\n' %(i+1, int(num_bins))
            surf_max.append(get_surface(vr, rMax*(i*0.1)))
            surf_max[-1].GetProperty().SetColor(pos_max_colors[i])
            surf_max[-1].GetProperty().SetOpacity(0.1*i)
            surf_max[-1].GetProperty().SetOpacity(0.1*i)
            surf_max[-1].VisibilityOff()
            if rMin == 0:
                continue
            else:
                surf_min.append(get_surface(vr, rMin*(i*0.1)))
                surf_min[-1].GetProperty().SetColor(pos_min_colors[i])
                surf_min[-1].GetProperty().SetOpacity(0.1*i)
                surf_min[-1].VisibilityOff()
        
        # --- Add the Beamformer Actors
        for s in surf_min:
            ren.AddActor(s)
        for s in surf_max:
            ren.AddActor(s)
        surf_num = len(surf_max)
        surf_max[surf_num-1].VisibilityOn()
        
        if rMin == 0:
            pass
        else:
            surf_min[surf_num-1].VisibilityOn()

        processing.set_fin_processing()
        
        
        
        def myCallBack_BF(obj, event):
            global renWin, iact, currentActor, currentActor2, surf_num
            key=iact.GetKeySym()
            
            #for planes
            if key == 'X':
                surf_num -= 1
                if surf_num < 0:
                    surf_num = 0
                if func_data_visible == 0:
                    pass
                elif func_data_visible == 1:
                    surf_max[surf_num].VisibilityOn()
                    if rMin == 0:
                        pass
                    else:
                        surf_min[surf_num].VisibilityOn()

                elif func_data_visible == 2:
                    surf_max[surf_num].VisibilityOn()
                elif func_data_visible == 3:
                    if rMin == 0:
                        pass
                    else:
                        surf_min[surf_num].VisibilityOn()

            if key == 'Y':
                surf_num += 1
                if surf_num == len(surf_max)+1:
                    surf_num = len(surf_max)
                surf_max[surf_num-1].VisibilityOff()
                if rMin == 0:
                    pass
                else:            
                    surf_min[surf_num-1].VisibilityOff()
            
            renWin.Render()
            
        iact.AddObserver("KeyPressEvent",myCallBack_BF)
        return
        print ' ... Completed ...\n'
        

    ########  END Add functional data #############################################################










    ######## -- MPR Volume -- #############################################################
    # --------- Routine for displayng the 3d-MPR MRI data volume ------------


    #file_to_load = sys.argv[1]

    if file_to_load[-4:] == '.hdr':
        vol = analyze2vtkImageData(sys.argv[1]) 

    elif file_to_load[-7:] == '.nii.gz':
        vol = nifti2vtkImageData(file_to_load) 

    else:
        print 'A structural nifti (.nii.gz) or analyze (.hdr) volume is required\n'
        sys.exit()

    vol.Update()


    #get info for accurate placement of roi in slice coordinates
    d = vol.GetOutput()

    bounds = d.GetBounds()
    dims = d.GetDimensions()
    xspace = []
    yspace = []
    zspace = []
    xspace = Sci.linspace(bounds[0],bounds[1],dims[0]) 
    yspace = Sci.linspace(bounds[2],bounds[3],dims[1]) 
    zspace = Sci.linspace(bounds[4],bounds[5],dims[2]) 

    xMin, xMax, yMin, yMax, zMin, zMax = vol.GetOutput().GetWholeExtent()

    # An outline is shown for context.
    outline = vtk.vtkOutlineFilter()
    outline.SetInput(vol.GetOutput())

    outlineMapper = vtk.vtkPolyDataMapper()
    outlineMapper.SetInput(outline.GetOutput())

    outlineActor = vtk.vtkActor()
    outlineActor.SetMapper(outlineMapper)

    # The shared picker enables us to use 3 planes at one time
    # and gets the picking order right
    picker = vtk.vtkCellPicker()
    picker.SetTolerance(0.005)


    # The 3 image plane widgets are used to probe the dataset.
    #planeWidgetX = vtk.vtkImagePlaneWidget()
    planeWidgetX.DisplayTextOn()
    planeWidgetX.SetInput(vol.GetOutput())
    planeWidgetX.SetPlaneOrientationToXAxes()
    planeWidgetX.SetSliceIndex(x_slice_pos)
    planeWidgetX.SetPicker(picker)
    planeWidgetX.SetHandleSize(500)
    planeWidgetX.AddObserver("KeyPressEvent", myMouse_tracker)
    prop1 = planeWidgetX.GetPlaneProperty()
    prop1.SetColor(1, 0, 0)
    planeWidgetX.SetKeyPressActivation(0)

    planeWidgetY = vtk.vtkImagePlaneWidget()
    planeWidgetY.DisplayTextOn()
    planeWidgetY.SetInput(vol.GetOutput())
    planeWidgetY.SetPlaneOrientationToYAxes()
    planeWidgetY.SetSliceIndex(y_slice_pos)
    planeWidgetY.SetPicker(picker)
    planeWidgetY.AddObserver("LeftButtonPressEvent", myMouse_tracker)
    prop2 = planeWidgetY.GetPlaneProperty()
    prop2.SetColor(1, 1, 0)
    planeWidgetY.SetLookupTable(planeWidgetX.GetLookupTable())
    planeWidgetY.SetKeyPressActivation(0)

    original_LU_table = planeWidgetX.GetLookupTable()


    planeWidgetZ = vtk.vtkImagePlaneWidget()
    planeWidgetZ.DisplayTextOn()
    planeWidgetZ.SetInput(vol.GetOutput())
    planeWidgetZ.SetPlaneOrientationToZAxes()
    planeWidgetZ.SetSliceIndex(z_slice_pos)
    planeWidgetZ.SetPicker(picker)
    planeWidgetZ.AddObserver("LeftButtonPressEvent", myMouse_tracker)
    prop3 = planeWidgetZ.GetPlaneProperty()
    prop3.SetColor(0, 0, 1)
    planeWidgetZ.SetLookupTable(planeWidgetX.GetLookupTable())
    planeWidgetZ.SetKeyPressActivation(0)

    ######## END MPR Volume -- #############################################################





    ######## -- SETUP MAIN WINDOW, ACTORS AND INTERACTORS -- ###############################

    # Create the RenderWindow and Renderer
    ren = vtk.vtkRenderer()
    renWin = vtk.vtkRenderWindow()
    renWin.AddRenderer(ren)

    rent = vtk.vtkRenderer()
    renWint = vtk.vtkRenderWindow()
    renWint.AddRenderer(rent)


    # Add the outline actor to the renderer, set the background color and size
    #ren.AddActor(outlineActor)
    renWin.SetSize(600, 600)
    ren.SetBackground(0.0, 0.0, 0.0)

    picker1 = vtk.vtkCellPicker()    
    picker1.SetTolerance(0.005)

    # Set the interactor for the widgets
    iact = vtk.vtkRenderWindowInteractor()
    iact.SetRenderWindow(renWin)
    style = vtk.vtkInteractorStyleTrackballCamera()
    iact.SetInteractorStyle(style) 
    planeWidgetX.SetInteractor(iact)
    iact.SetPicker(picker1)
    planeWidgetX.SetWindowLevel(7880, 3030)


    planeWidgetX.On()
    planeWidgetY.SetInteractor(iact)
    planeWidgetY.SetWindowLevel(7880, 3030)

    planeWidgetY.On()
    planeWidgetZ.SetInteractor(iact)
    planeWidgetZ.SetWindowLevel(7880, 3030)

    planeWidgetZ.On()

    dipoleSphereActor = vtk.vtkActor()
    dipoleLineActor = vtk.vtkActor()

    #Actor for the selected position
    selected_pos_sphere = vtk.vtkSphereSource()
    selected_pos_sphere.SetRadius(7.0)
    selected_pos_sphere.SetCenter(0,0,0)
    Mapper_selected_pos= vtk.vtkPolyDataMapper()
    Mapper_selected_pos.SetInput(selected_pos_sphere.GetOutput())
    selected_pos_actor = vtk.vtkActor()
    selected_pos_actor.SetMapper(Mapper_selected_pos)
    selected_pos_actor.GetProperty().SetColor(0,1,1)
    ren.AddActor(selected_pos_actor)
    selected_pos_actor.VisibilityOff()


    # stuff for the boxwidget interactor

    #seed actor
    roi_seed = vtk.vtkSphereSource()
    roi_seed.SetRadius(15.0)
    roi_seed.SetCenter(88,250,250) 
    roiMapper_seed = vtk.vtkPolyDataMapper()
    roiMapper_seed.SetInput(roi_seed.GetOutput())
    roiActor_seed = vtk.vtkActor()
    roiActor_seed.SetMapper(roiMapper_seed)
    roiActor_seed.GetProperty().SetColor(1,1,0)
    ren.AddActor(roiActor_seed)

    boxWidget_seed = vtk.vtkBoxWidget()
    boxWidget_seed.SetInteractor(iact)
    boxWidget_seed.SetPlaceFactor(1.25)
    boxWidget_seed.SetProp3D(roiActor_seed)
    boxWidget_seed.PlaceWidget()
    boxWidget_seed.SetHandleSize(0.003)

    #target actor
    roi_target = vtk.vtkSphereSource()
    roi_target.SetRadius(15.0)
    roi_target.SetCenter(88,250,250) 
    roiMapper_target = vtk.vtkPolyDataMapper()
    roiMapper_target.SetInput(roi_target.GetOutput())
    roiActor_target = vtk.vtkActor()
    roiActor_target.SetMapper(roiMapper_target)
    roiActor_target.GetProperty().SetColor(1,0,0)
    ren.AddActor(roiActor_target)

    boxWidget_target = vtk.vtkBoxWidget()
    boxWidget_target.SetInteractor(iact)
    boxWidget_target.SetPlaceFactor(1.25)
    boxWidget_target.SetProp3D(roiActor_target)
    boxWidget_target.PlaceWidget()
    boxWidget_target.SetHandleSize(0.003)


    def myCallback2(widget, event_string):
        t = vtk.vtkTransform()
        boxWidget_seed.GetTransform(t)
        boxWidget_seed.GetProp3D().SetUserTransform(t)
        p = boxWidget_seed.GetProp3D().GetBounds()

    def myCallback3(widget, event_string):
        t = vtk.vtkTransform()
        boxWidget_target.GetTransform(t)
        boxWidget_target.GetProp3D().SetUserTransform(t)
        p = boxWidget_target.GetProp3D().GetBounds()
        
    boxWidget_seed.AddObserver("InteractionEvent", myCallback2)
    boxWidget_seed.On()
    boxWidget_target.AddObserver("InteractionEvent", myCallback3)
    boxWidget_target.On()

    #Adding text that describes the current x,y,z picked on the plane
    posTextMapper = vtk.vtkTextMapper()
    posTextMapper.SetInput("Data")
    pos_tprop = posTextMapper.GetTextProperty()
    pos_tprop.SetFontSize(12)
    pos_tprop.SetColor(1, 1, 0)
    xyz_textActor = vtk.vtkActor2D()
    xyz_textActor.SetMapper(posTextMapper)
    xyz_textActor.SetDisplayPosition(20,30)


    #Adding text that describes the current x,y,z picked on the plane
    mni_posTextMapper = vtk.vtkTextMapper()
    mni_posTextMapper.SetInput("no MNI")
    mni_pos_tprop = mni_posTextMapper.GetTextProperty()
    mni_pos_tprop.SetFontSize(12)
    mni_pos_tprop.SetColor(1, 1, 1)
    mni_textActor = vtk.vtkActor2D()
    mni_textActor.SetMapper(mni_posTextMapper)
    mni_textActor.SetDisplayPosition(100,30)

    #Adding text that describes the current x,y,z picked on the plane
    tal_posTextMapper = vtk.vtkTextMapper()
    tal_posTextMapper.SetInput("no TAL")
    tal_pos_tprop = tal_posTextMapper.GetTextProperty()
    tal_pos_tprop.SetFontSize(12)
    tal_pos_tprop.SetColor(1, 0, 0)
    tal_textActor = vtk.vtkActor2D()
    tal_textActor.SetMapper(tal_posTextMapper)
    tal_textActor.SetDisplayPosition(180,30)


    ren.AddActor2D(xyz_textActor)
    ren.AddActor2D(mni_textActor)
    ren.AddActor2D(tal_textActor)

    roiActor_seed.VisibilityOff()
    boxWidget_seed.Off()
    roiActor_target.VisibilityOff()
    boxWidget_target.Off()

    renWin.Render()
    renWin.SetPosition(220,0)


    ########## END INITAL SETUP of MAIN INTERACTORS, WINDOW ETC #####################################

    ##### -- KEY BINDINGS FOR MAIN WINDOW -- ####################################################
    ######## -- Setup main window functionality -- ###############################################################

    ttt= []
    ren3 = vtk.vtkRenderer()
    renWin3 = vtk.vtkRenderWindow()
    iren3 = vtk.vtkRenderWindowInteractor()
    act_x = vtk.vtkActor2D()
    act_y = vtk.vtkActor2D()
    act_z = vtk.vtkActor2D()
    meshActor = vtk.vtkActor()

    stuff=[]

    def mpr_sag_onoff():
        if planeWidgetX.GetTexturePlaneProperty().GetOpacity() == 0:
            planeWidgetX.GetTexturePlaneProperty().SetOpacity(1.0)
            planeWidgetX.TextureVisibilityOn()
        else:
            planeWidgetX.GetTexturePlaneProperty().SetOpacity(0)

    def mpr_cor_onoff():
        if planeWidgetY.GetTexturePlaneProperty().GetOpacity() == 0:
            planeWidgetY.GetTexturePlaneProperty().SetOpacity(1.0)
            planeWidgetY.TextureVisibilityOn()
        else:
            planeWidgetY.GetTexturePlaneProperty().SetOpacity(0)

    def mpr_axial_onoff():
        if planeWidgetZ.GetTexturePlaneProperty().GetOpacity() == 0:
            planeWidgetZ.GetTexturePlaneProperty().SetOpacity(1.0)
            planeWidgetZ.TextureVisibilityOn()
        else:
            planeWidgetZ.GetTexturePlaneProperty().SetOpacity(0)
                
    def mpr_edges_onoff():
        if planeWidgetY.GetPlaneProperty().GetOpacity() == 0:
            planeWidgetX.GetPlaneProperty().SetOpacity(1.0)
            planeWidgetY.GetPlaneProperty().SetOpacity(1.0)
            planeWidgetZ.GetPlaneProperty().SetOpacity(1.0)
        else:
            planeWidgetX.GetPlaneProperty().SetOpacity(0)
            planeWidgetY.GetPlaneProperty().SetOpacity(0)
            planeWidgetZ.GetPlaneProperty().SetOpacity(0)

                
    #Main window callback routine            
    def myCallBack(obj, event):
        global glyph_hs, my_mnorm_brain, mn_loaded, dipole_min_time, dipole_max_time, selected_pos_actor, planeWidgetX, planeWidgetY, planeWidgetZ, renWin, iact, ren, currentActor, currentActor2, surf_num, ttt, a, b, c, d, e, f, g, ortho_planes_on, ren3, renWin3, iren3, act_x, act_y, act_z, fiber_data_loaded, profileList, plotData, lineData, cortex_data_loaded, meshActor, menu_initialised, func_data_visible, func_data_loaded, surf_num, surf_max, surf_min, current_mpr_orient, fiber_group, fiber_group_counter, x_const, y_const, z_const, counter, a_fibers, rows, dipole_file_loaded, dipole_rows, dipole_transform, dipole_min_time, dipole_max_time, dipole_current_time, dipoleSphereActor, dipoleLineActor, dipole_mat, Sphere, SphereMapper, line, lineMapper, cortex_data, origActor, selectActor, planes, boxWidget, boxWidget2,  clipper, brain, triangles, vertices, polyData, first_dipole_point,x,y,stuff,functionalLut, vol, original_LU_table, functionalLut, functional_2d_volume, pos_scalarBar, pos_colour_bar_generated, resetPlanes, mpr_showing_2d, import_data_x_offset, dti_data_array, dti_x_const, dti_y_const, dti_z_const
        
        key=iact.GetKeySym()
        
        #add extra funtionality options by enabling CTRL - selecting
        if obj.GetControlKey():
            
            if key == 'Up': #place holder
                x = planeWidgetX.GetCurrentCursorPosition()
            
            if key == 'Down': #place holder
                pass
            
            if key == 'Left': # move dipole back to previous time-point
                dipole_current_time -=1
                if dipole_current_time < dipole_min_time:
                    print 'Already at the minimum time-point = %d' %dipole_current_time
                    dipole_current_time +=1
                else:
                    dipole_data = dipole_rows[dipole_rows[:,0] >= float(dipole_current_time), :][0]
                    dipole_mat = reshape(fromfile(dipole_transform, sep=' ') , (4,4))
                    coord1 = array([dipole_data[1]/100, dipole_data[2]/100, dipole_data[3]/100,1]).reshape(4,1)
                    coord2 = array([dipole_data[4]/100, dipole_data[5]/100, dipole_data[6]/100,1]).reshape(4,1)         
                    trans_coord1 = dot(dipole_mat, coord1).reshape(1,4)
                    trans_coord2 = dot(dipole_mat, coord2).reshape(1,4)
                    Sphere.SetCenter( -trans_coord1[0][0]+ar.fov[0]*ar.pixdim[0], trans_coord1[0][1], trans_coord1[0][2])
                    Sphere.SetRadius( dipole_data[7]/2 )
                    point1 = [-trans_coord1[0][0]+ar.fov[0]*ar.pixdim[0], trans_coord1[0][1], trans_coord1[0][2]]
                    point2 = [-trans_coord2[0][0]-trans_coord1[0][0]+ar.fov[0]*ar.pixdim[0], trans_coord2[0][1]+trans_coord1[0][1], trans_coord2[0][2]+trans_coord1[0][2]]
                    point2_rescale = add((subtract(point2,point1))/10,point1)
                    line.SetPoint1(point1)
                    line.SetPoint2(point2_rescale)         
                    print 'dipole at %d ms\n' %dipole_current_time
            
            if key == 'Right': # move dipole back to next time-point
                dipole_current_time +=1
                if dipole_current_time > dipole_max_time:
                    print 'Already at the maximum time-point = %d' %dipole_current_time
                    dipole_current_time -=1
                else:
                    dipole_data = dipole_rows[dipole_rows[:,0] >= float(dipole_current_time), :][0]
                    dipole_mat = reshape(fromfile(dipole_transform, sep=' ') , (4,4))
                    coord1 = array([dipole_data[1]/100, dipole_data[2]/100, dipole_data[3]/100,1]).reshape(4,1)
                    coord2 = array([dipole_data[4]/100, dipole_data[5]/100, dipole_data[6]/100,1]).reshape(4,1)         
                    trans_coord1 = dot(dipole_mat, coord1).reshape(1,4)
                    trans_coord2 = dot(dipole_mat, coord2).reshape(1,4)
                    Sphere.SetCenter( -trans_coord1[0][0]+ar.fov[0]*ar.pixdim[0], trans_coord1[0][1], trans_coord1[0][2])
                    Sphere.SetRadius( dipole_data[7]/2 )
                    point1 = [-trans_coord1[0][0]+ar.fov[0]*ar.pixdim[0], trans_coord1[0][1], trans_coord1[0][2]]
                    point2 = [-trans_coord2[0][0]-trans_coord1[0][0]+ar.fov[0]*ar.pixdim[0], trans_coord2[0][1]+trans_coord1[0][1], trans_coord2[0][2]+trans_coord1[0][2]]
                    point2_rescale = add((subtract(point2,point1))/10,point1)
                    line.SetPoint1(point1)
                    line.SetPoint2(point2_rescale)
                    print 'dipole at %d ms\n' %dipole_current_time
                            
            if key == '1': #interact with first fiber group loaded
                if fiber_group < 1:
                    print 'no fiber group 1 - load some fiber data!\n'
                
                elif profileList[fiber_group_counter[0][0]].GetVisibility() == 0:
                    for j in range (fiber_group_counter[0][0], fiber_group_counter[0][1]):
                        profileList[j].VisibilityOn()
                            
                elif profileList[fiber_group_counter[0][0]].GetVisibility() == 1:
                    for k in range (fiber_group_counter[0][0], fiber_group_counter[0][1]):
                        profileList[k].VisibilityOff()
        
            if key == '2': #interact with 2nd fiber group loaded
                if fiber_group < 2:
                    print 'no fiber group 2 - load some fiber data!\n'
                
                elif profileList[fiber_group_counter[1][0]].GetVisibility() == 0:
                    for j in range (fiber_group_counter[1][0], fiber_group_counter[1][1]):
                        profileList[j].VisibilityOn()
                            
                elif profileList[fiber_group_counter[1][0]].GetVisibility() == 1:
                    for k in range (fiber_group_counter[1][0], fiber_group_counter[1][1]):
                        profileList[k].VisibilityOff()
                        
            if key == '3': #interact with 3rd fiber group loaded
                if fiber_group < 3:
                    print 'no fiber group 3 - load some fiber data!\n'
                
                elif profileList[fiber_group_counter[2][0]].GetVisibility() == 0:
                    for j in range (fiber_group_counter[2][0], fiber_group_counter[2][1]):
                        profileList[j].VisibilityOn()
                            
                elif profileList[fiber_group_counter[2][0]].GetVisibility() == 1:
                    for k in range (fiber_group_counter[2][0], fiber_group_counter[2][1]):
                        profileList[k].VisibilityOff()
        
            if key == '4': #interact with 4th fiber group loaded
                if fiber_group < 4:
                    print 'no fiber group 4 - load some fiber data!\n'
                
                elif profileList[fiber_group_counter[3][0]].GetVisibility() == 0:
                    for j in range (fiber_group_counter[3][0], fiber_group_counter[3][1]):
                        profileList[j].VisibilityOn()
                            
                elif profileList[fiber_group_counter[3][0]].GetVisibility() == 1:
                    for k in range (fiber_group_counter[3][0], fiber_group_counter[3][1]):
                        profileList[k].VisibilityOff()  

            if key == '5': #interact with 5th fiber group loaded
                if fiber_group < 5:
                    print 'no fiber group 5 - load some fiber data!\n'
                
                elif profileList[fiber_group_counter[4][0]].GetVisibility() == 0:
                    for j in range (fiber_group_counter[4][0], fiber_group_counter[4][1]):
                        profileList[j].VisibilityOn()
                            
                elif profileList[fiber_group_counter[4][0]].GetVisibility() == 1:
                    for k in range (fiber_group_counter[4][0], fiber_group_counter[4][1]):
                        profileList[k].VisibilityOff()
        
            if key == '6': #interact with 6th fiber group loaded
                if fiber_group < 6:
                    print 'no fiber group 6 - load some fiber data!\n'
                
                elif profileList[fiber_group_counter[5][0]].GetVisibility() == 0:
                    for j in range (fiber_group_counter[5][0], fiber_group_counter[5][1]):
                        profileList[j].VisibilityOn()
                            
                elif profileList[fiber_group_counter[5][0]].GetVisibility() == 1:
                    for k in range (fiber_group_counter[5][0], fiber_group_counter[5][1]):
                        profileList[k].VisibilityOff()
            
            
            if key == '7': #place holder
                if mn_loaded == 0:
                    minNorm()
                else:
                    if my_mnorm_brain.GetVisibility() == 1:
                        my_mnorm_brain.SetVisibility(0)
                        renWin.Render()
                    else:
                        my_mnorm_brain.SetVisibility(1)
                        renWin.Render()
                    
                
            if key == '8': #place holder
                if coils_loaded == 0:
                    CoilPositions()
                else:
                    if glyph_coils.GetVisibility() == 1:
                        glyph_coils.SetVisibility(0)
                        renWin.Render()
                    else:
                        glyph_coils.SetVisibility(1)
                        renWin.Render()
                        
                        
            if key == '9': #place holder
                if headshape_loaded == 0:
                    HeadShape()
                else:
                    if glyph_hs.GetVisibility() == 1:
                        glyph_hs.SetVisibility(0)
                        renWin.Render()
                    else:
                        glyph_hs.SetVisibility(1)
                        renWin.Render()
            
            
            if key == 'h': 
                webbrowser.open(help_main, new=2)
            
            #TODO - make ctrl a b c d e f etc all fiber sub-groups which can be
                #   1.) made created from current visible selection / touching roi
                #   2.) if exists .. make visible / invisible
                #   3.) ? - allow append of current set with SHIFT-CTRL?
            if key == 'a': #add fibers on the screen to a stored group
                for j in range(len(profileList)):
                    if profileList[j].GetVisibility() == 1:
                        a_fibers.append(j)
            
            
            if key == 'b': #view the stored fiber group
                for j in a_fibers:
                    profileList[j].VisibilityOn()


            elif key == 'D':
                #create_dti_array
                if fiber_data_loaded == 0:
                    fn = my_file_dialog(3,0,0)
                    ####fn = '/Volumes/Untitled/ptq/c_Laud_and_cc500.out'
                    if fn == '':
                        print 'Load cancelled ..\n' 
                        return
                    dti_data_array, dti_x_const, dti_y_const, dti_z_const = create_dti_array(fn)
                    fiber_data_loaded = 1

                else:    

                    print 'fiber set already loaded ..\n'
                    #TODO - allow add second dataset?
                    
            elif key == 's':
                if fiber_data_loaded == 0:
                    print 'No fiber data loaded yet! .. \n'
                else:
                    x = planeWidgetX.GetCurrentCursorPosition()
                    y = planeWidgetY.GetCurrentCursorPosition()
                    z = planeWidgetZ.GetCurrentCursorPosition()
                    pick = iact.GetPicker()
                    r = iact.GetEventPosition()
                    s = r[0],r[1],0
                    pick.Pick(s, ren)
                    ppos = pick.GetPickPosition()
                    roi_seed.SetRadius(8)
                    roi_seed.SetCenter(ppos[0],ppos[1],ppos[2])
                    renWin.Render()
                    boxWidget_seed.SetProp3D(roiActor_seed)
                    boxWidget_seed.PlaceWidget()
     
            elif key == 'S':
                SeedVisibility()
        

            elif key == 't': #place holder
                if fiber_data_loaded == 0:
                    print 'No fiber data loaded yet! .. \n'
                else:
                    x = planeWidgetX.GetCurrentCursorPosition()
                    y = planeWidgetY.GetCurrentCursorPosition()
                    z = planeWidgetZ.GetCurrentCursorPosition()
                    pick = iact.GetPicker()
                    r = iact.GetEventPosition()
                    s = r[0],r[1],0
                    pick.Pick(s, ren)
                    ppos = pick.GetPickPosition()
                    roi_target.SetRadius(8)
                    roi_target.SetCenter(ppos[0],ppos[1],ppos[2])
                    renWin.Render()
                    boxWidget_target.SetProp3D(roiActor_target)
                    boxWidget_target.PlaceWidget() 
            
            elif key == 'T':
                TargetVisibility()


            elif key == 'B':
                CortexLoad()
                
        elif key == 'Delete':
            r = iact.GetEventPosition()
            s = r[0],r[1],0
            picker1.Pick(s, ren)
            t = picker1.GetActor()
            t.VisibilityOff()


        elif key == 'q': #quit app
            iact.TerminateApp()
            sys.exit()

            
        elif key == 'z': #toggle instructions on
            webbrowser.open(help_main, new=2)

        
        elif key == 'f':  #toggle func data visibility
            if func_data_loaded == 0:
                print 'no functional data loaded\n'
            else:
                if func_data_visible == 0:
                    func_data_visible = 1
                    surf_num = 5
                    for i in range(0,len(surf_max)-1):
                        surf_max[i].VisibilityOff()
                        if rMin == 0:
                            pass
                        else:
                            surf_min[i].VisibilityOff()
                    for i in range(len(surf_max)-1, len(surf_max)):
                        surf_max[i].VisibilityOn()
                        if rMin == 0:
                            pass
                        else:
                            surf_min[i].VisibilityOn()
                elif func_data_visible == 1:
                    for i in range(len(surf_max)-1, len(surf_max)):
                        surf_max[i].VisibilityOn()
                    for i in range(len(surf_max)):
                        if rMin == 0:
                            pass
                        else:
                            surf_min[i].VisibilityOff()
                        func_data_visible = 2
                elif func_data_visible == 2:
                    for i in range(len(surf_max)):
                        surf_max[i].VisibilityOff()
                    for i in range(len(surf_max)-1, len(surf_max)):
                        if rMin == 0:
                            pass
                        else:
                            surf_min[i].VisibilityOn()
                        func_data_visible = 3
                else:
                    for i in range(len(surf_max)):
                        surf_max[i].VisibilityOff()
                        if rMin == 0:
                            pass
                        else:
                            surf_min[i].VisibilityOff()
                        func_data_visible = 0
        
        
        elif key == 'M':
            if functional_2d_volume != []: #if a 2d_merge exists
                if mpr_showing_2d == 1:
                    print '\nswitching to structural view\n'
                    
                    #TODO:
                    # the following contains a lot of commented code which is intended to transfer the settings/
                    #rotations/positions of all 3 planes to the new set when toggling between functional and
                    #structural data
                    
                    ####Get the current settings / orientations of the plane so that they can be preserved on switch
                    ###currx1,curry1,currz1 = planeWidgetX.GetPoint1(), planeWidgetY.GetPoint1(), planeWidgetZ.GetPoint1()
                    ###currx2,curry2,currz2 = planeWidgetX.GetPoint2(), planeWidgetY.GetPoint2(), planeWidgetZ.GetPoint2()
                    ###orix1,oriy1,oriz1 = planeWidgetX.GetOrigin(), planeWidgetY.GetOrigin(), planeWidgetZ.GetOrigin()
                    
#                    ###n = planeWidgetX.GetNormal()
#                    ###o = planeWidgetX.GetOrigin()
#                    ###pxyz = [0,0,0]
#                    ###vtk.vtkPlane.ProjectPoint(xyz, o, n, pxyz)
#                    ###transform = vtk.vtkTransform()
#                    ###transform.Translate(xyz[0]-pxyz[0], xyz[1]-pxyz[1], xyz[2]-pxyz[2])
#                    ###p1 = transform.TransformPoint(pw.GetPoint1())
#                    ###p2 = transform.TransformPoint(pw.GetPoint2())
#                    ###o = transform.TransformPoint(o)
#
#                   ### pw.SetOrigin(o)               
#                   ###pw.SetPoint1(p1)
#                    ###pw.SetPoint2(p2)
#                    ###pw.UpdatePlacement()
                    
                    planeWidgetX.SetInput(vol.GetOutput())
                    planeWidgetX.SetLookupTable(original_LU_table)
                    planeWidgetX.SetWindowLevel(7880, 3030)
                    planeWidgetY.SetInput(vol.GetOutput())
                    planeWidgetY.SetLookupTable(planeWidgetX.GetLookupTable())
                    planeWidgetY.SetWindowLevel(7880, 3030)
                    planeWidgetZ.SetInput(vol.GetOutput())
                    planeWidgetZ.SetLookupTable(planeWidgetX.GetLookupTable())
                    planeWidgetZ.SetWindowLevel(7880, 3030)
                    planeWidgetX.SetUserControlledLookupTable(0)
                    planeWidgetY.SetUserControlledLookupTable(0)
                    planeWidgetZ.SetUserControlledLookupTable(0)
                    
                    ####set orientation to what it was in the other mode
                    ###planeWidgetX.SetPoint1(currx1)
                    ###planeWidgetY.SetPoint1(curry1)
                    ###planeWidgetZ.SetPoint1(currz1)
                    ###planeWidgetX.SetPoint2(currx2)
                    ###planeWidgetY.SetPoint2(curry2)
                    ###planeWidgetZ.SetPoint2(currz2)
                    ###
                    ###planeWidgetX.SetOrigin(orix1)
                    ###planeWidgetY.SetOrigin(oriy1)
                    ###planeWidgetZ.SetOrigin(oriz1)
                    ###planeWidgetX.UpdatePlacement() 
                    ###planeWidgetY.UpdatePlacement() 
                    ###planeWidgetZ.UpdatePlacement() 

                    if pos_colour_bar_generated == 1:
                        pos_scalarBar.VisibilityOff()
                    if neg_colour_bar_generated == 1:
                        neg_scalarBar.VisibilityOff()
                    mpr_showing_2d = 0
                    
                else:
                
                    print '\nswitching to 2d-merged functional view\n'
                    
                    ####Get the current settings / orientations of the plane so that they can be preserved on switch
                    ###currx1,curry1,currz1 = planeWidgetX.GetPoint1(), planeWidgetY.GetPoint1(), planeWidgetZ.GetPoint1()
                    ###currx2,curry2,currz2 = planeWidgetX.GetPoint2(), planeWidgetY.GetPoint2(), planeWidgetZ.GetPoint2()
                    ###orix1,oriy1,oriz1 = planeWidgetX.GetOrigin(), planeWidgetY.GetOrigin(), planeWidgetZ.GetOrigin()
                    ###
                    ###print planeWidgetX.GetPoint1()
                    ###print planeWidgetX.GetOrigin()
                    
                    
                    planeWidgetX.SetUserControlledLookupTable(1)
                    planeWidgetY.SetUserControlledLookupTable(1)
                    planeWidgetZ.SetUserControlledLookupTable(1)
                    
                    planeWidgetX.SetLookupTable(functionalLut)
                    planeWidgetY.SetLookupTable(functionalLut)
                    planeWidgetZ.SetLookupTable(functionalLut)
                    planeWidgetX.SetWindowLevel(250,125)
                    planeWidgetY.SetWindowLevel(250,125)
                    planeWidgetZ.SetWindowLevel(250,125)
                    
                    planeWidgetX.SetInput(functional_2d_volume)
                    planeWidgetY.SetInput(functional_2d_volume)
                    planeWidgetZ.SetInput(functional_2d_volume)

                    ###print planeWidgetX.GetPoint1()
                    ###print planeWidgetX.GetOrigin()
                    ###
                    ####set orientation to what it was in the other mode
                    ###planeWidgetX.SetPoint1(currx1)
                    ###planeWidgetY.SetPoint1(curry1)
                    ###planeWidgetZ.SetPoint1(currz1)
                    ###planeWidgetX.SetPoint2(currx2)
                    ###planeWidgetY.SetPoint2(curry2)
                    ###planeWidgetZ.SetPoint2(currz2)
                    ###
                    ###planeWidgetX.SetOrigin(orix1)
                    ###planeWidgetY.SetOrigin(oriy1)
                    ###planeWidgetZ.SetOrigin(oriz1)
                    ###planeWidgetX.UpdatePlacement() 
                    ###planeWidgetY.UpdatePlacement() 
                    ###planeWidgetZ.UpdatePlacement()                    
                    ###print planeWidgetX.GetPoint1()
                    ###print planeWidgetX.GetOrigin()

                    if pos_colour_bar_generated == 1:
                        pos_scalarBar.VisibilityOn()
                    if neg_colour_bar_generated == 1:
                        neg_scalarBar.VisibilityOn()
                    mpr_showing_2d = 1
        
        
        elif key == 'S': #toggle sagittal plane on / off
            mpr_sag_onoff()
            
        elif key == 'C': #toggle coronal plane on / off
            mpr_cor_onoff()

        elif key == 'A': #toggle axial plane on / off
            mpr_axial_onoff()

        elif key == 'j': #save ortho window to tiff file
            SaveOrthoToTif()
        
        elif key == 'J': #save main window to tiff file
            SaveMainToTif()

        elif key == 'x':
            OrthoCreate()
        
        elif key == 'L': #reset MPR planes to original views
            resetPlanes()
            ren.Render()


        elif key == 'c': #track fibers through roi(s)            
            TrackFibers()
                
                
        elif key == 'G': # All fibers off
            for u in range(len(profileList)):
                profileList[u].VisibilityOff()

        elif key == 'g': # All fibers visible
            for u in range(len(profileList)):
                profileList[u].VisibilityOn()                     

        elif key == 'b': # increase cortex opacity
            props = meshActor.GetProperty()
            op = props.GetOpacity()
            if op < 1.0:
                meshActor.GetProperty().SetOpacity(0.1+op)
        
        elif key == 'n': # decrease cortex opacity
            props = meshActor.GetProperty()
            op = props.GetOpacity()
            if op > 0.1:
                meshActor.GetProperty().SetOpacity(op-0.1)
        
        elif key =='v': #toggle cortex visibility on / off
            CortexVisibility()

        elif key == 'h':
            webbrowser.open(help_main, new=2)
        
        
        elif key == 'o': #place planes at pick point
            pick = iact.GetPicker()
            r = iact.GetEventPosition()
            s = r[0],r[1],0
            pick.Pick(s, ren)
            ppos = pick.GetPickPosition()
            
            planeWidgetX.SetPlaneOrientationToXAxes()
            planeWidgetY.SetPlaneOrientationToYAxes()
            planeWidgetZ.SetPlaneOrientationToZAxes()
                                    
            planeWidgetX.SetSlicePosition(ppos[0])
            planeWidgetY.SetSlicePosition(ppos[1])
            planeWidgetZ.SetSlicePosition(ppos[2])
            
            selected_pos_sphere.SetCenter(ppos[0],ppos[1],ppos[2])
            selected_pos_actor.VisibilityOn()
            
        elif key == 'm': #place holder
            if selected_pos_actor.GetVisibility() == 0:
                selected_pos_actor.VisibilityOn()
            else:
                selected_pos_actor.VisibilityOff()

        elif key == 't': #place holder  
            r = iact.GetEventPosition()
            s = r[0],r[1],0
            picker1.Pick(s, ren)
            t = picker1.GetActor()
            print t.GetBounds() 
            
        elif key == 'k': #place holder  
            print planeWidgetX.GetPoint1()
            print planeWidgetX.GetPoint2()
            pass
            
            
        elif key == 'K': #place holder 
            pass


        elif key =='d' : #toggle dipole actor on / off
            DipoleVisibility()
                 
        elif key =='6': #make picked object grey
            # TODO - make this take any colour
            currentActor = picker1.GetActor()
            props = currentActor.GetProperty()
            props.SetDiffuseColor(0.8,0.8,0.8)
            
        elif key =='7': #make picked object red
            currentActor = picker1.GetActor()
            props = currentActor.GetProperty()
            props.SetDiffuseColor(1,0,0)
            
        elif key =='8': #make picked object green
            currentActor = picker1.GetActor()
            props = currentActor.GetProperty()
            props.SetDiffuseColor(0,1,0)
            
        elif key =='9': #make picked object blue
            currentActor = picker1.GetActor()
            props = currentActor.GetProperty()
            props.SetDiffuseColor(0,0,1)
        
        elif key == 'F': #call load functional data routine
            load_functional_data()
            func_data_loaded = 1
            func_data_visible = 1     

        elif key == 'H': # cycle views Top, Bottom, Front, Back, Left, Right
            ttt = ren.GetActiveCamera()
            if current_mpr_orient == 0:
                #ttt.SetPosition(-90,145,1000)
                ttt.SetPosition(bounds[1]/2,bounds[3]/2,bounds[5]/2+750)
                ttt.SetViewUp(0,1,0)
                ttt.SetViewAngle(30)
                current_mpr_orient = 1
            elif current_mpr_orient == 1:
                #ttt.SetPosition(-90,145,-717)
                ttt.SetPosition(bounds[1]/2,bounds[3]/2,bounds[5]/2-750)
                ttt.SetViewUp(0,1,0)
                ttt.SetViewAngle(30)
                current_mpr_orient = 2
            elif current_mpr_orient == 2:
                #ttt.SetPosition(-90,1000,154)
                ttt.SetPosition(bounds[1]/2,bounds[3]/2+750,bounds[5]/2)
                ttt.SetViewUp(0,0,1)
                ttt.SetViewAngle(30)
                current_mpr_orient = 3
            elif current_mpr_orient == 3:
                #ttt.SetPosition(-90,-717,155)
                ttt.SetPosition(bounds[1]/2,bounds[3]/2-750,bounds[5]/2)
                ttt.SetViewUp(0,0,1)
                ttt.SetViewAngle(30)
                current_mpr_orient = 4
            elif current_mpr_orient == 4:
                #ttt.SetPosition(-775,145,155)
                ttt.SetPosition(bounds[1]/2-750,bounds[3]/2,bounds[5]/2)
                ttt.SetViewUp(0,0,1)
                ttt.SetViewAngle(30)
                current_mpr_orient = 5
            elif current_mpr_orient == 5:
                #ttt.SetPosition(1000,145,149)
                ttt.SetPosition(bounds[1]/2+750,bounds[3]/2,bounds[5]/2)
                ttt.SetViewUp(0,0,1)
                ttt.SetViewAngle(30)
                current_mpr_orient = 0           
        
        elif key == 'B': 
            mpr_edges_onoff()
        
        elif key == 'D':
            Dipole_Load()

        
        #Apply the changes by re-rendering the main window
        renWin.Render()
        
        
        
    ###END KEY PRESS EVENTS FOR MAIN WINDOW##
    
    tmp_menu_ref = os.read(ClientReceive,1024)
    #print 'tmp_menu_ref %s in main' %tmp_menu_ref
    
       
    iact.CreateTimer(100000)
    iact.Initialize()
    renWin.Render()
    iact.AddObserver("KeyPressEvent", myCallBack)
    iact.AddObserver("LeftButtonPressEvent", Menu_Events)
    iact.AddObserver("TimerEvent", Menu_Events)    
    planeWidgetX.AddObserver("InteractionEvent", myMouse_tracker)
    planeWidgetY.AddObserver("InteractionEvent", myMouse_tracker)
    planeWidgetZ.AddObserver("InteractionEvent", myMouse_tracker)
    iact.Start()


    ##############----- END MAIN VTK WINDOW -----################





#############################################################
#EVENT HANDLER FOR VALUES FROM MENU INTO VTK WINDOW
#############################################################

def Menu_Events(obj, event):
    global bounds, selected_pos_sphere, selected_pos_actor, to_mni_mat, picker1, dti_data_array, dipoleSphereActor, dipoleLineActor, fiber_data_loaded, dti_data_array, dti_x_const, dti_y_const, dti_z_const, func_data_loaded, func_data_visible, surf_num, surf_max, rMin, surf_min, tmp_menu_ref, mpr_sag_onoff, ren, current_mpr_orient, functional_2d_volume, planeWidgetX, planeWidgetY, planeWidgetZ, pos_colour_bar_generated, pos_scalarBar, neg_colour_bar_generated, neg_scalarBar, mpr_showing_2d
    #print tmp_menu_ref
    #print 'started obs'
    ####iact.DestroyTimer()
    #routine: on an action, check if any new args have been passed 
    def check_processing(tmp_menu_ref):
        try:
            f = open(tmp_menu_ref ,'r')
            t = f.readline()
            f.close
        except TypeError:
            return ''
        except IOError:
            return ''
        return t
    
    #routine: if new args found and processed, reset the logfile
    def end_processing(tmp_menu_ref):
        f = open(tmp_menu_ref,'w')
        f.write('No command waiting')
        f.close()
  
      
    #so now check if we have any commands waiting
    command_received = check_processing(tmp_menu_ref)
  
  
    #if null or nothing waiting ...
    if command_received == '':
        pass
        
    elif command_received == 'No command waiting':
        #print 'No command waiting'
        pass
    
    
    #else process the command ...
    
    elif command_received == 'STRUCT axial':
        mpr_axial_onoff()
        print '\naxial plane toggled ...\n'
        renWin.Render()
        end_processing(tmp_menu_ref)
        
    elif command_received == 'STRUCT sagittal':
        mpr_sag_onoff()
        print '\nsagittal plane toggled ...\n'
        renWin.Render()
        end_processing(tmp_menu_ref)
                
    elif command_received == 'STRUCT coronal':
        mpr_cor_onoff()
        print '\ncoronal plane toggled ...\n'
        renWin.Render()
        end_processing(tmp_menu_ref)
        
    elif command_received == 'STRUCT edges':
        mpr_edges_onoff()
        print '\nedges toggled ...\n'
        renWin.Render()
        end_processing(tmp_menu_ref)
        
    elif command_received == 'STRUCT zoom reset':
        print '\npress ''''r'''' in the main window to safely reset the zoom .. \n'
        
    elif command_received == 'STRUCT planes reset':
        resetPlanes()
        print '\nPlanes reset ...\n'
        renWin.Render()
        end_processing(tmp_menu_ref)
        
    elif command_received == 'STRUCT S view':
        ttt = ren.GetActiveCamera()
        ttt.SetPosition(bounds[1]/2,bounds[3]/2,bounds[5]/2+750)
        ttt.SetViewUp(0,1,0)
        ttt.SetViewAngle(30)
        current_mpr_orient = 1
        print '\nTop view ...\n'
        renWin.Render()
        end_processing(tmp_menu_ref)
                    
    elif command_received == 'STRUCT I view':
        ttt = ren.GetActiveCamera()
        ttt.SetPosition(bounds[1]/2,bounds[3]/2,bounds[5]/2-750)
        ttt.SetViewUp(0,1,0)
        ttt.SetViewAngle(30)
        current_mpr_orient = 2
        print '\nBottom view ...\n'
        renWin.Render()
        end_processing(tmp_menu_ref)
                
    elif command_received == 'STRUCT A view':
        ttt = ren.GetActiveCamera()
        ttt.SetPosition(bounds[1]/2,bounds[3]/2+750,bounds[5]/2)
        ttt.SetViewUp(0,0,1)
        ttt.SetViewAngle(30)
        current_mpr_orient = 3
        print '\nFront view ...\n'
        renWin.Render()
        end_processing(tmp_menu_ref)
                
    elif command_received == 'STRUCT P view':
        ttt = ren.GetActiveCamera()
        ttt.SetPosition(bounds[1]/2,bounds[3]/2-750,bounds[5]/2)
        ttt.SetViewUp(0,0,1)
        ttt.SetViewAngle(30)
        current_mpr_orient = 4
        print '\nBack view ...\n'
        renWin.Render()
        end_processing(tmp_menu_ref)
                
    elif command_received == 'STRUCT L view':
        ttt = ren.GetActiveCamera()
        ttt.SetPosition(bounds[1]/2-750,bounds[3]/2,bounds[5]/2)
        ttt.SetViewUp(0,0,1)
        ttt.SetViewAngle(30)
        current_mpr_orient = 5
        print '\nLeft view ...\n'
        renWin.Render()
        end_processing(tmp_menu_ref)
                
    elif command_received == 'STRUCT R view':
        ttt = ren.GetActiveCamera()
        ttt.SetPosition(bounds[1]/2+750,bounds[3]/2,bounds[5]/2)
        ttt.SetViewUp(0,0,1)
        ttt.SetViewAngle(30)
        current_mpr_orient = 0
        print '\nRight view ...\n'
        renWin.Render()
        end_processing(tmp_menu_ref)
        
    elif command_received == 'FUNC Load':
        load_functional_data()
        renWin.Render()
        end_processing(tmp_menu_ref)
        
    elif command_received == 'FUNC 2d switch':
        if functional_2d_volume != []: #if a 2d_merge exists
            if mpr_showing_2d == 1:
                print '\nswitching to structural view\n'
                planeWidgetX.SetInput(vol.GetOutput())
                planeWidgetX.SetLookupTable(original_LU_table)
                planeWidgetX.SetWindowLevel(7880, 3030)
                planeWidgetY.SetInput(vol.GetOutput())
                planeWidgetY.SetLookupTable(planeWidgetX.GetLookupTable())
                planeWidgetY.SetWindowLevel(7880, 3030)
                planeWidgetZ.SetInput(vol.GetOutput())
                planeWidgetZ.SetLookupTable(planeWidgetX.GetLookupTable())
                planeWidgetZ.SetWindowLevel(7880, 3030)
                planeWidgetX.SetUserControlledLookupTable(0)
                planeWidgetY.SetUserControlledLookupTable(0)
                planeWidgetZ.SetUserControlledLookupTable(0)
                if pos_colour_bar_generated == 1:
                    pos_scalarBar.VisibilityOff()
                if neg_colour_bar_generated == 1:
                    neg_scalarBar.VisibilityOff()
                resetPlanes()
                mpr_showing_2d = 0
                renWin.Render()
                end_processing(tmp_menu_ref)
            else:
                print '\nswitching to 2d-merged functional view\n'
                planeWidgetX.SetUserControlledLookupTable(1)
                planeWidgetY.SetUserControlledLookupTable(1)
                planeWidgetZ.SetUserControlledLookupTable(1)
                
                planeWidgetX.SetLookupTable(functionalLut)
                planeWidgetY.SetLookupTable(functionalLut)
                planeWidgetZ.SetLookupTable(functionalLut)
                planeWidgetX.SetWindowLevel(250,125)
                planeWidgetY.SetWindowLevel(250,125)
                planeWidgetZ.SetWindowLevel(250,125)
                
                planeWidgetX.SetInput(functional_2d_volume)
                planeWidgetY.SetInput(functional_2d_volume)
                planeWidgetZ.SetInput(functional_2d_volume)
                if pos_colour_bar_generated == 1:
                    pos_scalarBar.VisibilityOn()
                if neg_colour_bar_generated == 1:
                    neg_scalarBar.VisibilityOn()
                resetPlanes()
                mpr_showing_2d = 1
                renWin.Render()
                end_processing(tmp_menu_ref)
                
    elif command_received == 'FUNC 3d switch':
        if func_data_loaded == 0:
            print 'no functional data loaded\n'
        else:
            if func_data_visible == 0:
                func_data_visible = 1
                surf_num = 5
                for i in range(0,len(surf_max)-1):
                    surf_max[i].VisibilityOff()
                    if rMin == 0:
                        pass
                    else:
                        surf_min[i].VisibilityOff()
                for i in range(len(surf_max)-1, len(surf_max)):
                    surf_max[i].VisibilityOn()
                    if rMin == 0:
                        pass
                    else:
                        surf_min[i].VisibilityOn()
            elif func_data_visible == 1:
                for i in range(len(surf_max)-1, len(surf_max)):
                    surf_max[i].VisibilityOn()
                for i in range(len(surf_max)):
                    if rMin == 0:
                        pass
                    else:
                        surf_min[i].VisibilityOff()
                    func_data_visible = 2
            elif func_data_visible == 2:
                for i in range(len(surf_max)):
                    surf_max[i].VisibilityOff()
                for i in range(len(surf_max)-1, len(surf_max)):
                    if rMin == 0:
                        pass
                    else:
                        surf_min[i].VisibilityOn()
                    func_data_visible = 3
            else:
                for i in range(len(surf_max)):
                    surf_max[i].VisibilityOff()
                    if rMin == 0:
                        pass
                    else:
                        surf_min[i].VisibilityOff()
                    func_data_visible = 0
        
        renWin.Render()
        end_processing(tmp_menu_ref)
                        
                                        
    elif command_received == 'FUNC 3d UpThr':
        surf_num -= 1
        if surf_num < 0:
            surf_num = 0
        if func_data_visible == 0:
            pass
        elif func_data_visible == 1:
            surf_max[surf_num].VisibilityOn()
            if rMin == 0:
                pass
            else:
                surf_min[surf_num].VisibilityOn()

        elif func_data_visible == 2:
            surf_max[surf_num].VisibilityOn()
        elif func_data_visible == 3:
            if rMin == 0:
                pass
            else:
                surf_min[surf_num].VisibilityOn()
        
        renWin.Render()
        end_processing(tmp_menu_ref)

    elif command_received == 'FUNC 3d DownThr':
        surf_num += 1
        if surf_num == len(surf_max)+1:
            surf_num = len(surf_max)
        surf_max[surf_num-1].VisibilityOff()
        if rMin == 0:
            pass
        else:            
            surf_min[surf_num-1].VisibilityOff()
        renWin.Render()
        end_processing(tmp_menu_ref)


    elif command_received == 'DIP Load':
        Dipole_Load()
        renWin.Render()
        end_processing(tmp_menu_ref)

                            
    elif command_received == 'DIP visible':
        DipoleVisibility()
        renWin.Render()
        end_processing(tmp_menu_ref)
        
    elif command_received == 'DIP time':
        pass #todo
        
    elif command_received == 'CORTEX Load':
        CortexLoad()
        renWin.Render()
        end_processing(tmp_menu_ref)
        
    elif command_received == 'CORTEX Transparency':
        pass #todo
                
    elif command_received == 'CORTEX visible':
        CortexVisibility()
        renWin.Render()
        end_processing(tmp_menu_ref)
                
    elif command_received == 'OTHER ortho':
        OrthoCreate()
        renWin.Render()
        end_processing(tmp_menu_ref)
        
    elif command_received == 'OTHER tifmain':
        SaveMainToTif()
        renWin.Render()
        end_processing(tmp_menu_ref)
        
    elif command_received == 'OTHER tifortho':
        SaveOrthoToTif()
        renWin.Render()
        end_processing(tmp_menu_ref)

    elif command_received == 'OTHER exit':
        end_processing(tmp_menu_ref)
        sys.exit()
        
    elif command_received == 'OTHER marker':
        if selected_pos_actor.GetVisibility() == 0:
            selected_pos_actor.VisibilityOn()
        else:
            selected_pos_actor.VisibilityOff()
        renWin.Render()
        end_processing(tmp_menu_ref)

        
    elif command_received == 'OTHER help':
        global help_main
        webbrowser.open(help_main, new=2)
        
    elif command_received[-17:] == 'OTHER_applycoords':
        d = command_received.split(' ')
        print d
        x, y, z, mni_or_subj = int(d[0]), int(d[1]), int(d[2]), d[3]
        print '\nMoving planes to xyz %s = %d %d %d.. ' %(mni_or_subj, x, y, z)
        #got the values, now move the planes
        
        #if slice numbers
        if mni_or_subj == 'slice_number':
            planeWidgetX.SetPlaneOrientationToXAxes()
            planeWidgetY.SetPlaneOrientationToYAxes()
            planeWidgetZ.SetPlaneOrientationToZAxes()
            planeWidgetX.SetSliceIndex(x)
            planeWidgetY.SetSliceIndex(y)
            planeWidgetZ.SetSliceIndex(z)
            selected_pos_sphere.SetCenter(planeWidgetX.GetSlicePosition(), planeWidgetY.GetSlicePosition(), planeWidgetZ.GetSlicePosition())
            selected_pos_actor.VisibilityOn()
        
        #if subject mm
        elif mni_or_subj == 'subject_space(mm)':
            #fix for offset
            x = float(x) - srow_x[3]
            y = float(y) - srow_y[3]
            z = float(z) - srow_z[3]           
        
            #transform back from rotation +/ scaling
            back_transf_mat = array([[float(srow_x[0]), float(srow_x[1]), float(srow_x[2])],[float(srow_y[0]), float(srow_y[1]), float(srow_y[2])],[float(srow_z[0]), float(srow_z[1]), float(srow_z[2])]])
            new_val = dot(array([x,y,z]),linalg.inv(back_transf_mat))
            new_x_slice, new_y_slice, new_z_slice = new_val[0], new_val[1], new_val[2]
            planeWidgetX.SetPlaneOrientationToXAxes()
            planeWidgetY.SetPlaneOrientationToYAxes()
            planeWidgetZ.SetPlaneOrientationToZAxes()
            planeWidgetX.SetSliceIndex(int(new_x_slice))
            planeWidgetY.SetSliceIndex(int(new_y_slice))
            planeWidgetZ.SetSliceIndex(int(new_z_slice))
            selected_pos_sphere.SetCenter(planeWidgetX.GetSlicePosition(), planeWidgetY.GetSlicePosition(), planeWidgetZ.GetSlicePosition())
            selected_pos_actor.VisibilityOn()
            
        #if mni mm
        elif mni_or_subj == 'mni_space(mm)':
                        
            #fix for offset
            mni_coords_for_marker = array([x,y,z,1])
            mni_coords_for_marker = dot(linalg.inv(s_form),mni_coords_for_marker)
            mni_coords_for_marker = mni_coords_for_marker*array([2,2,2,1])
            mni_coords_for_marker = dot(linalg.inv(to_mni_mat),mni_coords_for_marker)
            mni_coords_for_marker = mni_coords_for_marker/array(list(ar.pixdim)+[1])                   
            new_x_slice, new_y_slice, new_z_slice = mni_coords_for_marker[0], mni_coords_for_marker[1], mni_coords_for_marker[2]
            planeWidgetX.SetPlaneOrientationToXAxes()
            planeWidgetY.SetPlaneOrientationToYAxes()
            planeWidgetZ.SetPlaneOrientationToZAxes()
            planeWidgetX.SetSliceIndex(int(new_x_slice))
            planeWidgetY.SetSliceIndex(int(new_y_slice))
            planeWidgetZ.SetSliceIndex(int(new_z_slice))
            selected_pos_sphere.SetCenter(planeWidgetX.GetSlicePosition(), planeWidgetY.GetSlicePosition(), planeWidgetZ.GetSlicePosition())
            selected_pos_actor.VisibilityOn()

        else:
            print '\nUnexpected value! - reposition planes process aborted.'

        renWin.Render()
        end_processing(tmp_menu_ref)
        
        
    elif command_received == 'FIBER Load':
        #create_dti_array
        if fiber_data_loaded == 0:
            fn = my_file_dialog(3,0,0)
            if fn == '':
                print 'Load cancelled ..\n' 
                return
            dti_data_array, dti_x_const, dti_y_const, dti_z_const = create_dti_array(fn)
            fiber_data_loaded = 1
        else:    
            print 'fiber set already loaded ..\n'
            #TODO - allow add second dataset?
        renWin.Render()
        end_processing(tmp_menu_ref)
            
    elif command_received == 'FIBER visibility all':
        if len(profileList) == 0:
            print '\nNo fiber groups created yet .. create a set with a seed or seed and target .. then try again.\n'
        else:
            if profileList[0].GetVisibility() == 1:
                for u in range(len(profileList)):
                    profileList[u].VisibilityOff()
            else:
                for u in range(len(profileList)):
                    profileList[u].VisibilityOn()
        renWin.Render()
        end_processing(tmp_menu_ref)
        
    elif command_received == 'FIBER seed':
        SeedVisibility()
        renWin.Render()
        end_processing(tmp_menu_ref)
        
    elif command_received == 'FIBER target':
        TargetVisibility()
        renWin.Render()
        end_processing(tmp_menu_ref)
        
    elif command_received == 'FIBER track':
        TrackFibers()
        end_processing(tmp_menu_ref)
        
    elif command_received == 'FIBER group1':
        pass
        
    elif command_received == 'FIBER group2':
        pass
        
    elif command_received == 'FIBER group3':
        pass
        
    elif command_received == 'FIBER group4':
        pass
        
    elif command_received == 'FIBER group5':
        pass
        
    elif command_received == 'FIBER group6':
        pass
        
    elif command_received == 'FIBER group7':
        pass
        
    elif command_received == 'FIBER group8':
        pass
        
    elif command_received[-14:] == 'COLOURselected':
        #get the colour
        cps = command_received.split('_')
        new_colour = cps[0]
        new_colour = new_colour[1:-1].split(',')
        r=float(new_colour[0])/255
        g=float(new_colour[1])/255
        b=float(new_colour[2])/255
        new_rgb = '(%f,%f,%f)' %(r,g,b)
        #print new_rgb
        #set the colour to selected objects
        currentActor = picker1.GetActor()
        if currentActor == 'None' or '':
            print '\nNo objects currently selected .. hover over an object with the mouse button and press ''''p'''' to select it ..\n'
        else:
            props = currentActor.GetProperty()
            props.SetDiffuseColor(r,g,b)
        renWin.Render()
        end_processing(tmp_menu_ref)

        
    elif command_received[-9:] == 'COLOURall':
        #get the colour
        cps = command_received.split('_')
        new_colour = cps[0]
        new_colour = new_colour[1:-1].split(',')
        r=float(new_colour[0])/255
        g=float(new_colour[1])/255
        b=float(new_colour[2])/255
        new_rgb = '(%f,%f,%f)' %(r,g,b)
        #print new_rgb
        #set the colour to all visible sub-objects
        if len(profileList) == 0:
            print '\nNo fiber groups to colour! - Load some fiber data first ..'
        else:
            for i in range(len(profileList)):
                if profileList[i].GetVisibility() == 1:
                    profileList[i].GetProperty().SetDiffuseColor(r,g,b)
        renWin.Render()
        end_processing(tmp_menu_ref)


    elif command_received[-22:] == 'load multi-marker file':
        load_multipoint_marker_file()
        
    elif command_received[-34:] == 'create multi-marker file template':
        create_multipoint_marker_file_template()
            
    else:
        print 'received unexpected command: %s' %command_received
        f = open(tmp_menu_ref,'w')
        f.write('No command waiting')
        f.close()

    iact.CreateTimer(100000)



    ##############----- END MENU HANDLER -----################

        





#############################################################
###THE MENU
#############################################################
def ynicDV3DMenu():
    global tmp_menu_ref, planeWidgetX, planeWidgetY, planeWidgetZ, renWin, iact, ren, currentActor, currentActor2, surf_num, ttt, a, b, c, d, e, f, g, ortho_planes_on, ren3, renWin3, iren3, act_x, act_y, act_z, fiber_data_loaded, profileList, plotData, lineData, cortex_data_loaded, meshActor, menu_initialised, func_data_visible, func_data_loaded, surf_num, surf_max, surf_min, current_mpr_orient, fiber_group, fiber_group_counter, x_const, y_const, z_const, counter, a_fibers, rows, dipole_file_loaded, dipole_rows, dipole_transform, dipole_min_time, dipole_max_time, dipole_current_time, dipoleSphereActor, dipoleLineActor, dipole_mat, Sphere, SphereMapper, line, lineMapper, cortex_data, origActor, selectActor, planes, boxWidget, boxWidget2,   clipper, brain, triangles, vertices, polyData, first_dipole_point,x,y,stuff,functionalLut, vol, original_LU_table, functionalLut, functional_2d_volume, pos_scalarBar, pos_colour_bar_generated, resetPlanes, mpr_showing_2d, import_data_x_offset, dti_data_array, dti_x_const, dti_y_const, dti_z_const, posTextMapper, mni_posTextMapper, process_functional_input_for_2d, xyz_textActor, neg_colour_bar_generated, pos_colour_bar_generated, pos_scalarBar, neg_scalarBar, resetPlanes
    
    def set_start_tmp_menufile():
        global filename
        fd, menu_tmp_filename = tempfile.mkstemp()
        os.write(fd, 'No command waiting')
        os.close(fd)
        return menu_tmp_filename
    
    def set_command_tmp_menufile(my_command_code):
        global tmp_menu_ref
        f = open(tmp_menu_ref,'w')
        f.write('%s' %my_command_code)
        f.close()
    
    tmp_menu_ref = set_start_tmp_menufile()
    os.write(ServerSend,tmp_menu_ref)
    #print tmp_menu_ref
        
    #the wx application
    class ynicDV3D_MenuApp(wx.App):
        def OnInit(self):
            wx.InitAllImageHandlers()
            self.main = Frame1(None)
            self.main.Show()
            self.SetTopWindow(self.main)
            return True

    #IDs
    [wxID_FRAME1, wxID_FRAME1BT_COLOUR_APPLYALL, wxID_FRAME1BT_COLOUR_APPLYSEL, 
     wxID_FRAME1BT_CORTEX_LOAD, wxID_FRAME1BT_CORTEX_ONOFF, 
     wxID_FRAME1BT_DIP_LOAD, wxID_FRAME1BT_DIP_VIS, wxID_FRAME1BT_FIBER_ALLONOFF, 
     wxID_FRAME1BT_FIBER_GRP1, wxID_FRAME1BT_FIBER_GRP2, wxID_FRAME1BT_FIBER_GRP3, 
     wxID_FRAME1BT_FIBER_GRP4, wxID_FRAME1BT_FIBER_GRP5, wxID_FRAME1BT_FIBER_GRP6, 
     wxID_FRAME1BT_FIBER_GRP7, wxID_FRAME1BT_FIBER_GRP8, wxID_FRAME1BT_FIBER_LOAD, 
     wxID_FRAME1BT_FIBER_SEEDONOFF, wxID_FRAME1BT_FIBER_TARGETONOFF, 
     wxID_FRAME1BT_FIBER_TRACKNOW, wxID_FRAME1BT_FUNC_3DCYCLE, 
     wxID_FRAME1BT_FUNC_LOAD, wxID_FRAME1BT_FUNC_SWITCH2D, 
     wxID_FRAME1BT_OTHER_HELP, wxID_FRAME1BT_OTHER_ORTHO, wxID_FRAME1BT_STRUCT_RESET_PLANES,
     wxID_FRAME1BT_OTHER_QUIT, wxID_FRAME1BT_OTHER_TIFMAIN, 
     wxID_FRAME1BT_OTHER_TIFORTHO, wxID_FRAME1BT_STRUCT_ANT_VIEW_SELECT, 
     wxID_FRAME1BT_STRUCT_AX, wxID_FRAME1BT_STRUCT_COR, 
     wxID_FRAME1BT_STRUCT_EDGES, wxID_FRAME1BT_STRUCT_INF_VIEW_SELECT, 
     wxID_FRAME1BT_STRUCT_L_VIEW_SELECT, wxID_FRAME1BT_STRUCT_POST_VIEW_SELECT, 
     wxID_FRAME1BT_STRUCT_RESET_ZM, wxID_FRAME1BT_STRUCT_R_VIEW_SELECT, 
     wxID_FRAME1BT_STRUCT_SAG, wxID_FRAME1BT_STRUCT_SUP_VIEW_SELECT, 
     wxID_FRAME1NOTEBOOK1, wxID_FRAME1PNL_COLOUR, wxID_FRAME1PNL_CORTEX, 
     wxID_FRAME1PNL_DIP, wxID_FRAME1PNL_FIBER, wxID_FRAME1PNL_MARKERS, wxID_FRAME1PNL_FUNC, 
     wxID_FRAME1PNL_OTHER, wxID_FRAME1PNL_STRUCT, wxID_FRAME1SPBT_CORTEX_TRANSP, 
     wxID_FRAME1SPBT_DIP_DIPTIME, wxID_FRAME1SPBT_FUNC_THRESHOLD3D, 
     wxID_FRAME1STATICBITMAP1, wxID_FRAME1STATICBITMAP2, wxID_FRAME1STATICBITMAP3, 
     wxID_FRAME1STATICBITMAP4, wxID_FRAME1STATICBITMAP5, 
     wxID_FRAME1STBOX_COLOUR_DISPSELECTED, wxID_FRAME1ST_COLOURS_SELECTED, 
     wxID_FRAME1ST_COLOUR_PICKINSTR, wxID_FRAME1ST_CORTEX_TRANSP, 
     wxID_FRAME1ST_DIP_DIPTIME, wxID_FRAME1ST_FIBER_GRPLABEL, 
     wxID_FRAME1ST_FIBER_POS_SEED, wxID_FRAME1ST_FIBER_POS_TARGET, 
     wxID_FRAME1ST_FIBER_TRACKING, wxID_FRAME1ST_FUNC_2D, wxID_FRAME1ST_FUNC_3D, 
     wxID_FRAME1ST_FUNC_3D_CYCLE, wxID_FRAME1ST_FUNC_SWITCH2D, 
     wxID_FRAME1ST_FUNC_THRESHOLD3D, wxID_FRAME1ST_OTHER_ORTHO, 
     wxID_FRAME1ST_OTHER_SAVETOTIF, wxID_FRAME1ST_STRUCT_VIEW_FROM, wxID_COLPICK,
     wxID_FRAME1RB_OTHER_COORD_SPACE, wxID_FRAME1SPINCTRL1_OTHER_X, wxID_OTHER_PICK_POS_MARKER,
     wxID_FRAME1SPINCTRL2_OTHER_Y, wxID_FRAME1SPINCTRL3_OTHER_Z, 
     wxID_FRAME1STATICTEXT1_OTHER_X, wxID_FRAME1STATICTEXT2_OTHER_Y, 
     wxID_FRAME1STATICTEXT3_OTHER_Z, wxID_FRAME1BT_OTHER_APPLY_COORDS,
     wxID_FRAME1STATICTEXT4_OTHER_PICK_POS, wxID_FRAME1SPINCTRL1_MARKERS_X,
     wxID_FRAME1SPINCTRL2_MARKERS_Y, wxID_FRAME1SPINCTRL3_MARKERS_Z,
     wxID_FRAME1STATICTEXT1_MARKERS_X, wxID_FRAME1STATICTEXT2_MARKERS_Y, 
     wxID_FRAME1STATICTEXT3_MARKERS_Z, wxID_FRAME1RB_MARKERS_COORD_SPACE,
     wxID_FRAME1SPINCTRL4_MARKERS_RADIUS, wxID_FRAME1STATICTEXT4_MARKERS_RADIUSLABEL,
     wxID_FRAME1BT_MARKERS_ADDSINGLEMARKER, wxID_FRAME1BT_MARKERS_ADDMULTIMARKER,
     wxID_FRAME1BT_MARKERS_MAKEMARKERTEMPLATE
    ] = [wx.NewId() for _init_ctrls in range(97)]
    
    wx.ID_ABOUT = 101
    wx.ID_EXIT  = 102
    BYSTATUS = 203
    
    #the wx frame
    class Frame1(wx.Frame):
        global OnMytestFromTopMenu, OnBt_STRUCT_axButton
        def _init_coll_notebook1_Pages(self, parent):

            def TimeToQuit(self, event):
                self.Close()

            def OnAbout(self, event):
                dlg = wx.MessageDialog(self, "This sample program shows off\n"
                                      "frames, menus, statusbars, and this\n"
                                      "message dialog.",
                                      "About Me", wx.OK | wx.ICON_INFORMATION)
                dlg.ShowModal()
                dlg.Destroy()

            def tellem(self, event):
                msg = wx.MessageDialog(self, "Log File Reporting GUI\n" +
                                            "Training Course Example\n" +
                                            "Well House Consultants\n",
                                            "About Message - wxPython",
                                            wx.OK | wx.ICON_INFORMATION)
                msg.ShowModal()
                msg.Destroy()

            parent.AddPage(imageId=-1, page=self.pnl_STRUCT, select=True,
                  text=u'Structural')
            parent.AddPage(imageId=-1, page=self.pnl_CORTEX, select=False,
                  text=u'Surface')
            parent.AddPage(imageId=-1, page=self.pnl_FUNC, select=False,
                  text=u'Functional')
            parent.AddPage(imageId=-1, page=self.pnl_DIP, select=False,
                  text=u'Dipoles')
            parent.AddPage(imageId=-1, page=self.pnl_FIBER, select=False,
                  text=u'Fiber')
            parent.AddPage(imageId=-1, page=self.pnl_COLOUR, select=False,
                  text=u'Colours')
            parent.AddPage(imageId=-1, page=self.pnl_MARKERS, select=False,
                  text=u'Markers')
            parent.AddPage(imageId=-1, page=self.pnl_OTHER, select=False,
                  text=u'Other')


            menu1 = wx.Menu()
            menu1.Append(wx.ID_ABOUT, "&About","More information about this program")
            menu1.AppendSeparator()
            menu1.Append(wx.ID_EXIT, "E&xit", "Terminate the program")

            menu2 = wx.Menu()
            menu2.Append(wx.ID_ABOUT, "&About","More information about this program")
            menu2.AppendSeparator()
            menu2.Append(wx.ID_EXIT, "E&xit", "Terminate the program")
            menu2.Append(BYSTATUS, "Analyse by Status", "Analyse current log data by status")

            menuBar = wx.MenuBar()
            menuBar.Append(menu1, "&File")
            menuBar.Append(menu2, "&Dipoles")
            self.SetMenuBar(menuBar)


            wx.EVT_MENU(self, wx.ID_ABOUT, OnAbout)
            wx.EVT_MENU(self, wx.ID_EXIT,  TimeToQuit)
            wx.EVT_MENU(self, BYSTATUS,  OnBt_STRUCT_axButton)

            #Bind(wx.EVT_MENU, self.EvtOnRunTest, fileMenu.Append(wx.NewId(), "Run &Test File", "Select a test to run."))





        def _init_ctrls(self, prnt):

            wx.Frame.__init__(self, id=wxID_FRAME1, name='', parent=prnt,
                  pos=wx.Point(0, 0), size=wx.Size(205, 666), style=wx.DEFAULT_FRAME_STYLE, title=u'ynicDV3D menu')
            self.SetClientSize(wx.Size(205, 644))
            
            #SETUP A NOTEBOOK OBJECT - MULTIPAGE TAB SEPARATED
            self.notebook1 = wx.Notebook(id=wxID_FRAME1NOTEBOOK1, name='notebook1',
                  parent=self, pos=wx.Point(0, 0), size=wx.Size(205, 584),
                  style=wx.NB_LEFT)
            
            
            #SETUP A PANEL ON EACH PAGE TO FIX OBJECTS TO 
            self.pnl_MARKERS = wx.Panel(id=wxID_FRAME1PNL_MARKERS, name=u'pnl_MARKERS',
                  parent=self.notebook1, pos=wx.Point(0, 0), size=wx.Size(165, 578),
                  style=wx.TAB_TRAVERSAL)

            self.pnl_OTHER = wx.Panel(id=wxID_FRAME1PNL_OTHER, name=u'pnl_OTHER',
                  parent=self.notebook1, pos=wx.Point(0, 0), size=wx.Size(165, 578),
                  style=wx.TAB_TRAVERSAL)

            self.pnl_FIBER = wx.Panel(id=wxID_FRAME1PNL_FIBER, name=u'pnl_FIBER',
                  parent=self.notebook1, pos=wx.Point(0, 0), size=wx.Size(165, 578),
                  style=wx.TAB_TRAVERSAL)

            self.pnl_FUNC = wx.Panel(id=wxID_FRAME1PNL_FUNC, name=u'pnl_FUNC',
                  parent=self.notebook1, pos=wx.Point(0, 0), size=wx.Size(165, 578),
                  style=wx.TAB_TRAVERSAL)

            self.pnl_STRUCT = wx.Panel(id=wxID_FRAME1PNL_STRUCT, name=u'pnl_STRUCT',
                  parent=self.notebook1, pos=wx.Point(0, 0), size=wx.Size(165, 578),
                  style=wx.TAB_TRAVERSAL)

            self.pnl_CORTEX = wx.Panel(id=wxID_FRAME1PNL_CORTEX, name=u'pnl_CORTEX',
                  parent=self.notebook1, pos=wx.Point(0, 0), size=wx.Size(165, 578),
                  style=wx.TAB_TRAVERSAL)

            self.pnl_COLOUR = wx.Panel(id=wxID_FRAME1PNL_COLOUR, name=u'pnl_COLOUR',
                  parent=self.notebook1, pos=wx.Point(0, 0), size=wx.Size(165, 578),
                  style=wx.TAB_TRAVERSAL)

            self.pnl_DIP = wx.Panel(id=wxID_FRAME1PNL_DIP, name=u'pnl_DIP',
                  parent=self.notebook1, pos=wx.Point(0, 0), size=wx.Size(165, 578),
                  style=wx.TAB_TRAVERSAL)


            
            
            #BITMAPS ON PANELS
            self.staticBitmap1 = wx.StaticBitmap(bitmap=wx.Bitmap(u'wxmenu/structural.jpg',
                  wx.BITMAP_TYPE_JPEG), id=wxID_FRAME1STATICBITMAP1,
                  name='staticBitmap1', parent=self.pnl_STRUCT, pos=wx.Point(8, 8),
                  size=wx.Size(140, 136), style=0)

            self.staticBitmap2 = wx.StaticBitmap(bitmap=wx.Bitmap(u'wxmenu/cortex.jpg',
                  wx.BITMAP_TYPE_JPEG), id=wxID_FRAME1STATICBITMAP2,
                  name='staticBitmap2', parent=self.pnl_CORTEX, pos=wx.Point(8, 8),
                  size=wx.Size(140, 134), style=0)

            self.staticBitmap3 = wx.StaticBitmap(bitmap=wx.Bitmap(u'wxmenu/func.jpg',
                  wx.BITMAP_TYPE_JPEG), id=wxID_FRAME1STATICBITMAP3,
                  name='staticBitmap3', parent=self.pnl_FUNC, pos=wx.Point(8, 8),
                  size=wx.Size(140, 141), style=0)

            self.staticBitmap4 = wx.StaticBitmap(bitmap=wx.Bitmap(u'wxmenu/dipole.jpg',
                  wx.BITMAP_TYPE_JPEG), id=wxID_FRAME1STATICBITMAP4,
                  name='staticBitmap4', parent=self.pnl_DIP, pos=wx.Point(8, 8),
                  size=wx.Size(140, 141), style=0)

            self.staticBitmap5 = wx.StaticBitmap(bitmap=wx.Bitmap(u'wxmenu/fiber.jpg',
                  wx.BITMAP_TYPE_JPEG), id=wxID_FRAME1STATICBITMAP5,
                  name='staticBitmap5', parent=self.pnl_FIBER, pos=wx.Point(8, 8),
                  size=wx.Size(140, 142), style=0)



            #MARKER FUNCTIONS
            
            #marker co-ordinates
            self.spinCtrl_MARKERS_X = wx.SpinCtrl(id=wxID_FRAME1SPINCTRL1_MARKERS_X, initial=0,
                  max=500, min=-500, name='spinCtrl1_MARKERS_X', parent=self.pnl_MARKERS,
                  pos=wx.Point(70, 180), size=wx.DefaultSize,
                  style=wx.SP_ARROW_KEYS | wx.SP_HORIZONTAL)

            self.spinCtrl_MARKERS_Y = wx.SpinCtrl(id=wxID_FRAME1SPINCTRL2_MARKERS_Y, initial=0,
                  max=500, min=-500, name='spinCtrl2_MARKERS_Y', parent=self.pnl_MARKERS,
                  pos=wx.Point(70, 210), size=wx.DefaultSize,
                  style=wx.SP_ARROW_KEYS)

            self.spinCtrl_MARKERS_Z = wx.SpinCtrl(id=wxID_FRAME1SPINCTRL3_MARKERS_Z, initial=0,
                  max=500, min=-500, name='spinCtrl3_MARKERS_z', parent=self.pnl_MARKERS,
                  pos=wx.Point(70, 240), size=wx.DefaultSize,
                  style=wx.SP_ARROW_KEYS)

            self.st_MARKERS_xlabel = wx.StaticText(id=wxID_FRAME1STATICTEXT1_MARKERS_X,
                  label='X', name='st_MARKERS_xlabel', parent=self.pnl_MARKERS,
                  pos=wx.Point(45, 185), size=wx.Size(16, 16), style=0)

            self.st_MARKERS_ylabel = wx.StaticText(id=wxID_FRAME1STATICTEXT2_MARKERS_Y,
                  label='Y', name='st_MARKERS_label', parent=self.pnl_MARKERS,
                  pos=wx.Point(45, 215), size=wx.Size(16, 16), style=0)

            self.st_MARKERS_zlabel = wx.StaticText(id=wxID_FRAME1STATICTEXT3_MARKERS_Z,
                  label='Z', name='st_MARKERS_zlabel', parent=self.pnl_MARKERS,
                  pos=wx.Point(45, 245), size=wx.Size(16, 16), style=0)

            self.rb_MARKERS_coord_space = wx.RadioBox(choices=['Slice Number','Subject mm', 'MNI mm'],
                  id=wxID_FRAME1RB_MARKERS_COORD_SPACE, label=u'Coordinates for marker are ...',
                  majorDimension=1, name=u'rb_MARKERS_coord_space',
                  parent=self.pnl_MARKERS, point=wx.Point(8, 80), size=wx.DefaultSize,
                  style=wx.RA_SPECIFY_COLS)

            self.st_MARKERS_radiuslabel = wx.StaticText(id=wxID_FRAME1STATICTEXT4_MARKERS_RADIUSLABEL,
                  label='Radius of \nmarker (mm)\ndefault = 2', name='st_MARKERS_radiuslabel', parent=self.pnl_MARKERS,
                  pos=wx.Point(15, 285), size=wx.Size(180, 48), style=0)
                  
            self.spinCtrl_MARKERS_radius = wx.SpinCtrl(id=wxID_FRAME1SPINCTRL4_MARKERS_RADIUS, initial=2,
                  max=500, min=-500, name='spinCtrl4_MARKERS_radius', parent=self.pnl_MARKERS,
                  pos=wx.Point(100, 300), size=wx.DefaultSize,
                  style=wx.SP_ARROW_KEYS)

            self.bt_MARKERS_singlemarkeradd = wx.Button(id=wxID_FRAME1BT_MARKERS_ADDSINGLEMARKER,
                  label=u' ', name=u'bt_MARKERS_singlemarkeradd',
                  parent=self.pnl_MARKERS, pos=wx.Point(0, 352), size=wx.Size(160,
                  20), style=0)
            self.bt_MARKERS_singlemarkeradd.Bind(wx.EVT_BUTTON,
                  self.OnBt_MARKERS_singlemarkeradd,
                  id=wxID_FRAME1BT_MARKERS_ADDSINGLEMARKER)


            self.bt_MARKERS_multimarkeradd = wx.Button(id=wxID_FRAME1BT_MARKERS_ADDMULTIMARKER,
                  label=u'Load a marker file' , name=u'bt_MARKERS_multimarkeradd',
                  parent=self.pnl_MARKERS, pos=wx.Point(0, 382), size=wx.Size(160,
                  20), style=0)
            self.bt_MARKERS_multimarkeradd.Bind(wx.EVT_BUTTON,
                  self.OnBt_MARKERS_multimarkeradd,
                  id=wxID_FRAME1BT_MARKERS_ADDMULTIMARKER)
                  

            self.bt_MARKERS_makemarkertemplate = wx.Button(id=wxID_FRAME1BT_MARKERS_MAKEMARKERTEMPLATE,
                  label=u'New marker file', name=u'bt_MARKERS_makemarkertemplate',
                  parent=self.pnl_MARKERS, pos=wx.Point(0, 412), size=wx.Size(160,
                  20), style=0)
            self.bt_MARKERS_makemarkertemplate.Bind(wx.EVT_BUTTON,
                  self.OnBt_MARKERS_makemarkertemplate,
                  id=wxID_FRAME1BT_MARKERS_MAKEMARKERTEMPLATE)

            
            #STRUCTRAL MPR FUNCTIONS
            
            #toggle sagittal on/off
            self.bt_STRUCT_sag = wx.Button(id=wxID_FRAME1BT_STRUCT_SAG,
                  label=u'Sagittal On/Off   (S)', name=u'bt_STRUCT_sag',
                  parent=self.pnl_STRUCT, pos=wx.Point(8, 216), size=wx.Size(144,
                  20), style=0)
            self.bt_STRUCT_sag.Bind(wx.EVT_BUTTON, self.OnBt_STRUCT_sagButton,
                  id=wxID_FRAME1BT_STRUCT_SAG)
            self.bt_STRUCT_sag.SetToolTipString(u'Clicking this button will turn the SAGITTAL plane on/off\nShift+s in the main window (S)')
            
                  #toggle axial on/off      
            self.bt_STRUCT_ax = wx.Button(id=wxID_FRAME1BT_STRUCT_AX,
                  label=u'Axial On/Off   (A)', name=u'bt_STRUCT_ax',
                  parent=self.pnl_STRUCT, pos=wx.Point(8, 176), size=wx.Size(144,
                  20), style=0)
            self.bt_STRUCT_ax.SetForegroundColour(wx.Colour(0, 0, 255))
            self.bt_STRUCT_ax.Enable(True)
#            self.bt_STRUCT_ax.Bind(wx.EVT_BUTTON, self.OnBt_STRUCT_axButton,
#                  id=wxID_FRAME1BT_STRUCT_AX)
            self.bt_STRUCT_ax.Bind(wx.EVT_BUTTON, OnBt_STRUCT_axButton,
                  id=wxID_FRAME1BT_STRUCT_AX)

            self.bt_STRUCT_ax.SetToolTipString(u'Clicking this button will turn the AXIAL plane on/off\nShift+a in the main window (A)')
            
            #toggle coronal on/off
            self.bt_STRUCT_cor = wx.Button(id=wxID_FRAME1BT_STRUCT_COR,
                  label=u'Coronal On/Off   (C)', name=u'bt_STRUCT_cor',
                  parent=self.pnl_STRUCT, pos=wx.Point(8, 256), size=wx.Size(144,
                  20), style=0)
            self.bt_STRUCT_cor.Bind(wx.EVT_BUTTON, self.OnBt_STRUCT_corButton,
                  id=wxID_FRAME1BT_STRUCT_COR)
            self.bt_STRUCT_cor.SetToolTipString(u'Clicking this button will turn the CORONAL plane on/off\nShift+c in the main window (C)')
            
            #toggle edges on/off
            self.bt_STRUCT_edges = wx.Button(id=wxID_FRAME1BT_STRUCT_EDGES,
                  label=u'Edges On/Off   (B)', name=u'bt_STRUCT_edges',
                  parent=self.pnl_STRUCT, pos=wx.Point(8, 296), size=wx.Size(144,
                  20), style=0)
            self.bt_STRUCT_edges.Bind(wx.EVT_BUTTON, self.OnBt_STRUCT_edgesButton,
                  id=wxID_FRAME1BT_STRUCT_EDGES)
            self.bt_STRUCT_edges.SetToolTipString(u'Clicking this button will turn the edges of the MRI planes on/off\nShift+b in the main window (B)')
            
            #reset zoom
            self.bt_STRUCT_reset_zoom = wx.Button(id=wxID_FRAME1BT_STRUCT_RESET_ZM,
                  label=u'RESET ZOOM  (r)', name=u'bt_STRUCT_reset_zoom',
                  parent=self.pnl_STRUCT, pos=wx.Point(8, 336), size=wx.Size(136,
                  20), style=0)
            self.bt_STRUCT_reset_zoom.Bind(wx.EVT_BUTTON, self.OnBt_STRUCT_resetZoomButton,
                  id=wxID_FRAME1BT_STRUCT_RESET_ZM)
            self.bt_STRUCT_reset_zoom.SetToolTipString(u'this button currently does nothing .. just a reminder.\nClick r in the main wondow to reset the zoom (r)')
            
            #reset planes
            self.bt_STRUCT_reset_planes = wx.Button(id=wxID_FRAME1BT_STRUCT_RESET_PLANES,
                  label=u'RESET PLANES  (L)', name=u'bt_STRUCT_reset_Planes',
                  parent=self.pnl_STRUCT, pos=wx.Point(8, 376), size=wx.Size(136,
                  20), style=0)
            self.bt_STRUCT_reset_planes.Bind(wx.EVT_BUTTON, self.OnBt_STRUCT_resetPlanesButton,
                  id=wxID_FRAME1BT_STRUCT_RESET_PLANES)
            self.bt_STRUCT_reset_planes.SetToolTipString(u'Clicking this button reset the orientation of the MRI planes \nShift+l in the main window (L)')
            
            #view from left
            self.bt_STRUCT_L_view_select = wx.Button(id=wxID_FRAME1BT_STRUCT_L_VIEW_SELECT,
                  label=u'Left', name=u'bt_STRUCT_L_view_select',
                  parent=self.pnl_STRUCT, pos=wx.Point(16, 452), size=wx.Size(64,
                  16), style=0)
            self.bt_STRUCT_L_view_select.Bind(wx.EVT_BUTTON,
                  self.OnBt_STRUCT_L_view_selectButton,
                  id=wxID_FRAME1BT_STRUCT_L_VIEW_SELECT)
            self.bt_STRUCT_L_view_select.SetToolTipString(u'Clicking this button will change the orientation so that you are viewing your data from the LEFT \nShift+h cycles through views in the folowing order: Top, Bottom, Front, Back, Left, Right (H)')
            
            #view from right
            self.bt_STRUCT_R_view_select = wx.Button(id=wxID_FRAME1BT_STRUCT_R_VIEW_SELECT,
                  label=u'Right', name=u'bt_STRUCT_R_view_select',
                  parent=self.pnl_STRUCT, pos=wx.Point(88, 452), size=wx.Size(64,
                  20), style=0)
            self.bt_STRUCT_R_view_select.Bind(wx.EVT_BUTTON,
                  self.OnBt_STRUCT_R_view_selectButton,
                  id=wxID_FRAME1BT_STRUCT_R_VIEW_SELECT)
            self.bt_STRUCT_R_view_select.SetToolTipString(u'Clicking this button will change the orientation so that you are viewing your data from the RIGHT \nShift+h cycles through views in the folowing order: Top, Bottom, Front, Back, Left, Right (H)')

            #view from top (superior)
            self.bt_STRUCT_Sup_view_select = wx.Button(id=wxID_FRAME1BT_STRUCT_SUP_VIEW_SELECT,
                  label=u'Top', name=u'bt_STRUCT_Sup_view_select',
                  parent=self.pnl_STRUCT, pos=wx.Point(16, 516), size=wx.Size(64,
                  20), style=0)
            self.bt_STRUCT_Sup_view_select.Bind(wx.EVT_BUTTON,
                  self.OnBt_STRUCT_Sup_view_selectButton,
                  id=wxID_FRAME1BT_STRUCT_SUP_VIEW_SELECT)
            self.bt_STRUCT_Sup_view_select.SetToolTipString(u'Clicking this button will change the orientation so that you are viewing your data from the TOP down \nShift+h cycles through views in the folowing order: Top, Bottom, Front, Back, Left, Right (H)')
            
            #view from bottom (inferior)
            self.bt_STRUCT_Inf_view_select = wx.Button(id=wxID_FRAME1BT_STRUCT_INF_VIEW_SELECT,
                  label=u'Bottom', name=u'bt_STRUCT_Inf_view_select',
                  parent=self.pnl_STRUCT, pos=wx.Point(88, 516), size=wx.Size(64,
                  20), style=0)
            self.bt_STRUCT_Inf_view_select.Bind(wx.EVT_BUTTON,
                  self.OnBt_STRUCT_Inf_view_selectButton,
                  id=wxID_FRAME1BT_STRUCT_INF_VIEW_SELECT)
            self.bt_STRUCT_Inf_view_select.SetToolTipString(u'Clicking this button will change the orientation so that you are viewing your data from the BOTTOM up \nShift+h cycles through views in the folowing order: Top, Bottom, Front, Back, Left, Right (H)')

            #view from front (anterior)
            self.bt_STRUCT_Ant_view_select = wx.Button(id=wxID_FRAME1BT_STRUCT_ANT_VIEW_SELECT,
                  label=u'Front', name=u'bt_STRUCT_Ant_view_select',
                  parent=self.pnl_STRUCT, pos=wx.Point(16, 484), size=wx.Size(64,
                  20), style=0)
            self.bt_STRUCT_Ant_view_select.Bind(wx.EVT_BUTTON,
                  self.OnBt_STRUCT_Ant_view_selectButton,
                  id=wxID_FRAME1BT_STRUCT_ANT_VIEW_SELECT)
            self.bt_STRUCT_Ant_view_select.SetToolTipString(u'Clicking this button will change the orientation so that you are viewing your data from the FRONT \nShift+h cycles through views in the folowing order: Top, Bottom, Front, Back, Left, Right (H)')

            #view from back (posterior)
            self.bt_STRUCT_Post_view_select = wx.Button(id=wxID_FRAME1BT_STRUCT_POST_VIEW_SELECT,
                  label=u'Back', name=u'bt_STRUCT_Post_view_select',
                  parent=self.pnl_STRUCT, pos=wx.Point(88, 484), size=wx.Size(64,
                  20), style=0)
            self.bt_STRUCT_Post_view_select.Bind(wx.EVT_BUTTON,
                  self.OnBt_STRUCT_Post_view_selectButton,
                  id=wxID_FRAME1BT_STRUCT_POST_VIEW_SELECT)
            self.bt_STRUCT_Post_view_select.SetToolTipString(u'Clicking this button will change the orientation so that you are viewing your data from the BACK \nShift+h cycles through views in the folowing order: Top, Bottom, Front, Back, Left, Right (H)')
            
            #label for view from options
            self.st_STRUCT_view_from = wx.StaticText(id=wxID_FRAME1ST_STRUCT_VIEW_FROM,
                  label=u'View From  ..(cycle with H)', name=u'st_STRUCT_view_from',
                  parent=self.pnl_STRUCT, pos=wx.Point(32, 412), size=wx.Size(96,
                  32), style=0)
            self.st_STRUCT_view_from.SetExtraStyle(0)
            self.st_STRUCT_view_from.Enable(False)
            self.st_STRUCT_view_from.SetAutoLayout(True)
            self.st_STRUCT_view_from.SetForegroundColour(wx.Colour(255, 0, 0))


            
            #CORTICAL SURFACE FUNCTIONS
            self.bt_CORTEX_load = wx.Button(id=wxID_FRAME1BT_CORTEX_LOAD,
                  label=u'Load  (Ctrl+B)', name=u'bt_CORTEX_load',
                  parent=self.pnl_CORTEX, pos=wx.Point(16, 176), size=wx.Size(136,
                  20), style=0)
            self.bt_CORTEX_load.Bind(wx.EVT_BUTTON, self.OnBt_CORTEX_loadButton,
                  id=wxID_FRAME1BT_CORTEX_LOAD)

            self.spbt_CORTEX_transp = wx.SpinButton(id=wxID_FRAME1SPBT_CORTEX_TRANSP,
                  name=u'spbt_CORTEX_transp', parent=self.pnl_CORTEX,
                  pos=wx.Point(136, 280), size=wx.Size(16, 32),
                  style=wx.SP_HORIZONTAL)
            self.spbt_CORTEX_transp.Bind(wx.EVT_SPIN, self.OnSpbt_CORTEX_transpSpin,
                  id=wxID_FRAME1SPBT_CORTEX_TRANSP)

            self.bt_CORTEX_OnOff = wx.Button(id=wxID_FRAME1BT_CORTEX_ONOFF,
                  label=u'Visible On/Off  (v)', name=u'bt_CORTEX_OnOff',
                  parent=self.pnl_CORTEX, pos=wx.Point(16, 232), size=wx.Size(136,
                  20), style=0)
            self.bt_CORTEX_OnOff.Bind(wx.EVT_BUTTON, self.OnBt_CORTEX_OnOffButton,
                  id=wxID_FRAME1BT_CORTEX_ONOFF)

            self.st_CORTEX_transp = wx.StaticText(id=wxID_FRAME1ST_CORTEX_TRANSP,
                  label=u'  Transparency   up (b) / down (n)',
                  name=u'st_CORTEX_transp', parent=self.pnl_CORTEX, pos=wx.Point(8,
                  280), size=wx.Size(112, 40), style=0)



            #FUNCTIONAL DATA FUNCTIONS
            self.bt_FUNC_load = wx.Button(id=wxID_FRAME1BT_FUNC_LOAD,
                  label=u'Load  (F)', name=u'bt_FUNC_load', parent=self.pnl_FUNC,
                  pos=wx.Point(24, 176), size=wx.Size(104, 20), style=0)
            self.bt_FUNC_load.Bind(wx.EVT_BUTTON, self.OnBt_FUNC_loadButton,
                  id=wxID_FRAME1BT_FUNC_LOAD)

            self.bt_FUNC_switch2d = wx.Button(id=wxID_FRAME1BT_FUNC_SWITCH2D,
                  label=u'Switch data  (M)', name=u'bt_FUNC_switch2d',
                  parent=self.pnl_FUNC, pos=wx.Point(16, 304), size=wx.Size(120,
                  20), style=0)
            self.bt_FUNC_switch2d.Bind(wx.EVT_BUTTON, self.OnBt_FUNC_switch2dButton,
                  id=wxID_FRAME1BT_FUNC_SWITCH2D)

            self.bt_FUNC_3dcycle = wx.Button(id=wxID_FRAME1BT_FUNC_3DCYCLE,
                  label=u'Cycle +/-/off  (f)', name=u'bt_FUNC_3dcycle',
                  parent=self.pnl_FUNC, pos=wx.Point(16, 424), size=wx.Size(128,
                  20), style=0)
            self.bt_FUNC_3dcycle.Bind(wx.EVT_BUTTON, self.OnBt_FUNC_3dcycleButton,
                  id=wxID_FRAME1BT_FUNC_3DCYCLE)

            self.st_FUNC_3d_cycle = wx.StaticText(id=wxID_FRAME1ST_FUNC_3D_CYCLE,
                  label=u'   Cycle +ve / -ve activation on/off  (f)  ',
                  name=u'st_FUNC_3d_cycle', parent=self.pnl_FUNC, pos=wx.Point(16,
                  384), size=wx.Size(136, 40), style=0)
            self.st_FUNC_3d_cycle.SetForegroundColour(wx.Colour(0, 0, 255))

            self.st_FUNC_2D = wx.StaticText(id=wxID_FRAME1ST_FUNC_2D,
                  label=u'2D MODE', name=u'st_FUNC_2D', parent=self.pnl_FUNC,
                  pos=wx.Point(16, 240), size=wx.Size(61, 16), style=0)
            self.st_FUNC_2D.SetForegroundColour(wx.Colour(255, 0, 0))

            self.st_FUNC_3D = wx.StaticText(id=wxID_FRAME1ST_FUNC_3D,
                  label=u'3D MODE', name=u'st_FUNC_3D', parent=self.pnl_FUNC,
                  pos=wx.Point(16, 360), size=wx.Size(61, 16), style=0)
            self.st_FUNC_3D.SetForegroundColour(wx.Colour(0, 0, 255))

            self.st_FUNC_threshold3d = wx.StaticText(id=wxID_FRAME1ST_FUNC_THRESHOLD3D,
                  label=u'    Threshold   up(X) / down(Y)',
                  name=u'st_FUNC_threshold3d', parent=self.pnl_FUNC,
                  pos=wx.Point(16, 470), size=wx.Size(104, 32), style=0)
            self.st_FUNC_threshold3d.SetForegroundColour(wx.Colour(0, 0, 255))

            self.spbt_FUNC_threshold3d = wx.SpinButton(id=wxID_FRAME1SPBT_FUNC_THRESHOLD3D,
                  name=u'spbt_FUNC_threshold3d', parent=self.pnl_FUNC,
                  pos=wx.Point(120, 472), size=wx.Size(16, 24),
                  style=wx.SP_HORIZONTAL)
            self.spbt_FUNC_threshold3d.Bind(wx.EVT_SPIN,
                  self.OnSpbt_FUNC_threshold3dSpin,
                  id=wxID_FRAME1SPBT_FUNC_THRESHOLD3D)
            self.spbt_FUNC_threshold3d.SetValue(1)


            self.st_FUNC_switch2d = wx.StaticText(id=wxID_FRAME1ST_FUNC_SWITCH2D,
                  label=u'    switch between functional/structural',
                  name=u'st_FUNC_switch2d', parent=self.pnl_FUNC, pos=wx.Point(16,
                  264), size=wx.Size(136, 32), style=wx.TE_MULTILINE)
            self.st_FUNC_switch2d.SetForegroundColour(wx.Colour(255, 0, 0))




            #DIPOLE FUNCTIONS
            self.bt_DIP_load = wx.Button(id=wxID_FRAME1BT_DIP_LOAD,
                  label=u'Load  (D)', name=u'bt_DIP_load', parent=self.pnl_DIP,
                  pos=wx.Point(16, 176), size=wx.Size(104, 20), style=0)
            self.bt_DIP_load.Bind(wx.EVT_BUTTON, self.OnBt_DIP_loadButton,
                  id=wxID_FRAME1BT_DIP_LOAD)

            self.bt_DIP_vis = wx.Button(id=wxID_FRAME1BT_DIP_VIS,
                  label=u'Visible On/Off  (d)', name=u'bt_DIP_vis',
                  parent=self.pnl_DIP, pos=wx.Point(16, 232), size=wx.Size(136, 20),
                  style=0)
            self.bt_DIP_vis.Bind(wx.EVT_BUTTON, self.OnBt_DIP_visButton,
                  id=wxID_FRAME1BT_DIP_VIS)

            self.st_DIP_diptime = wx.StaticText(id=wxID_FRAME1ST_DIP_DIPTIME,
                  label=u'Dipole at time ..    (Ctrl <-  /  ->)',
                  name=u'st_DIP_diptime', parent=self.pnl_DIP, pos=wx.Point(24,
                  280), size=wx.Size(112, 40), style=0)

            self.spbt_DIP_diptime = wx.SpinButton(id=wxID_FRAME1SPBT_DIP_DIPTIME,
                  name=u'spbt_DIP_diptime', parent=self.pnl_DIP, pos=wx.Point(136,
                  280), size=wx.Size(16, 24), style=wx.SP_HORIZONTAL)
            self.spbt_DIP_diptime.Bind(wx.EVT_SPIN, self.OnSpinButton_DIP_time,
                  id=wxID_FRAME1SPBT_DIP_DIPTIME)


    
            #MISC FUNCTIONS
            self.bt_OTHER_ortho = wx.Button(id=wxID_FRAME1BT_OTHER_ORTHO,
                  label=u'Create/update  (x)', name=u'bt_OTHER_ortho',
                  parent=self.pnl_OTHER, pos=wx.Point(16, 88), size=wx.Size(136,
                  20), style=0)
            self.bt_OTHER_ortho.Bind(wx.EVT_BUTTON, self.OnBt_OTHER_orthoButton,
                  id=wxID_FRAME1BT_OTHER_ORTHO)

            self.st_OTHER_ortho = wx.StaticText(id=wxID_FRAME1ST_OTHER_ORTHO,
                  label=u'Ortho views', name=u'st_OTHER_ortho',
                  parent=self.pnl_OTHER, pos=wx.Point(16, 64), size=wx.Size(75, 16),
                  style=0)

            self.st_OTHER_savetotif = wx.StaticText(id=wxID_FRAME1ST_OTHER_SAVETOTIF,
                  label=u'Save to .TIF', name=u'st_OTHER_savetotif',
                  parent=self.pnl_OTHER, pos=wx.Point(16, 136), size=wx.Size(73,
                  16), style=0)

            self.bt_OTHER_tifmain = wx.Button(id=wxID_FRAME1BT_OTHER_TIFMAIN,
                  label=u'Main window  ( J )', name=u'bt_OTHER_tifmain',
                  parent=self.pnl_OTHER, pos=wx.Point(16, 160), size=wx.Size(136,
                  20), style=0)
            self.bt_OTHER_tifmain.Bind(wx.EVT_BUTTON, self.OnBt_OTHER_tifmainButton,
                  id=wxID_FRAME1BT_OTHER_TIFMAIN)

            self.bt_OTHER_tifortho = wx.Button(id=wxID_FRAME1BT_OTHER_TIFORTHO,
                  label=u'Ortho window  ( j )', name=u'bt_OTHER_tifortho',
                  parent=self.pnl_OTHER, pos=wx.Point(16, 192), size=wx.Size(136,
                  20), style=0)
            self.bt_OTHER_tifortho.Bind(wx.EVT_BUTTON,
                  self.OnBt_OTHER_tiforthoButton, id=wxID_FRAME1BT_OTHER_TIFORTHO)


            self.bt_OTHER_help = wx.Button(id=wxID_FRAME1BT_OTHER_HELP,
                  label=u'Open HELP  (h)', name=u'bt_OTHER_help',
                  parent=self.pnl_OTHER, pos=wx.Point(16, 16), size=wx.Size(131,
                  20), style=0)
            self.bt_OTHER_help.Bind(wx.EVT_BUTTON, self.OnBt_OTHER_helpButton,
                  id=wxID_FRAME1BT_OTHER_HELP)


            self.rb_OTHER_coord_space = wx.RadioBox(choices=['Slice Number','Subject mm', 'MNI mm'],
                  id=wxID_FRAME1RB_OTHER_COORD_SPACE, label=u'Coordinates are ...',
                  majorDimension=1, name=u'rb_OTHER_coord_space',
                  parent=self.pnl_OTHER, point=wx.Point(8, 240), size=wx.DefaultSize,
                  style=wx.RA_SPECIFY_COLS)

            self.spinCtrl_OTHER_X = wx.SpinCtrl(id=wxID_FRAME1SPINCTRL1_OTHER_X, initial=0,
                  max=500, min=-500, name='spinCtrl1_OTHER_X', parent=self.pnl_OTHER,
                  pos=wx.Point(70, 340), size=wx.DefaultSize,
                  style=wx.SP_ARROW_KEYS | wx.SP_HORIZONTAL)

            self.spinCtrl_OTHER_Y = wx.SpinCtrl(id=wxID_FRAME1SPINCTRL2_OTHER_Y, initial=0,
                  max=500, min=-500, name='spinCtrl2_OTHER_Y', parent=self.pnl_OTHER,
                  pos=wx.Point(70, 370), size=wx.DefaultSize,
                  style=wx.SP_ARROW_KEYS)

            self.spinCtrl_OTHER_Z = wx.SpinCtrl(id=wxID_FRAME1SPINCTRL3_OTHER_Z, initial=0,
                  max=500, min=-500, name='spinCtrl3_OTHER_z', parent=self.pnl_OTHER,
                  pos=wx.Point(70, 400), size=wx.DefaultSize,
                  style=wx.SP_ARROW_KEYS)

            self.st_OTHER_xlabel = wx.StaticText(id=wxID_FRAME1STATICTEXT1_OTHER_X,
                  label='X', name='st_OTHER_xlabel', parent=self.pnl_OTHER,
                  pos=wx.Point(45, 345), size=wx.Size(16, 16), style=0)

            self.st_OTHER_ylabel = wx.StaticText(id=wxID_FRAME1STATICTEXT2_OTHER_Y,
                  label='Y', name='st_OTHER_label', parent=self.pnl_OTHER,
                  pos=wx.Point(45, 375), size=wx.Size(16, 16), style=0)

            self.st_OTHER_zlabel = wx.StaticText(id=wxID_FRAME1STATICTEXT3_OTHER_Z,
                  label='Z', name='st_OTHER_zlabel', parent=self.pnl_OTHER,
                  pos=wx.Point(45, 405), size=wx.Size(16, 16), style=0)

            self.bt_OTHER_apply_coords = wx.Button(id=wxID_FRAME1BT_OTHER_APPLY_COORDS,
                  label=u'Apply Co-Ords', name=u'bt_apply_coords',
                  parent=self.pnl_OTHER, pos=wx.Point(16, 440), size=wx.Size(131,
                  20), style=0)
            self.bt_OTHER_apply_coords.Bind(wx.EVT_BUTTON, self.OnBt_OTHER_apply_coords,
                  id=wxID_FRAME1BT_OTHER_APPLY_COORDS)
            
            self.st_OTHER_pick_pos_label = wx.StaticText(id=wxID_FRAME1STATICTEXT4_OTHER_PICK_POS,
                  label='Pick position marker', name='st_OTHER_pick_pos_label', parent=self.pnl_OTHER,
                  pos=wx.Point(16, 470), size=wx.DefaultSize, style=0)

            self.bt_OTHER_pick_pos_marker = wx.Button(id=wxID_OTHER_PICK_POS_MARKER,
                  label=u'Pick on/off  (m)', name=u'bt_pick_pos',
                  parent=self.pnl_OTHER, pos=wx.Point(16, 490), size=wx.Size(131,
                  20), style=0)
            self.bt_OTHER_pick_pos_marker.Bind(wx.EVT_BUTTON, self.OnBt_OTHER_pick_pos_marker,
                  id=wxID_OTHER_PICK_POS_MARKER)


            self.bt_OTHER_quit = wx.Button(id=wxID_FRAME1BT_OTHER_QUIT,
                  label=u'QUIT', name=u'bt_OTHER_quit', parent=self.pnl_OTHER,
                  pos=wx.Point(72, 534), size=wx.Size(75, 20), style=0)
            self.bt_OTHER_quit.Bind(wx.EVT_BUTTON, self.OnBt_OTHER_quitButton,
                  id=wxID_FRAME1BT_OTHER_QUIT)



            #FIBER FUNCTIONS
            self.bt_FIBER_load = wx.Button(id=wxID_FRAME1BT_FIBER_LOAD,
                  label=u'Load  (Ctrl + D)', name=u'bt_FIBER_load',
                  parent=self.pnl_FIBER, pos=wx.Point(24, 168), size=wx.Size(120,
                  20), style=0)
            self.bt_FIBER_load.Bind(wx.EVT_BUTTON, self.OnBt_FIBER_loadButton,
                  id=wxID_FRAME1BT_FIBER_LOAD)

            self.bt_FIBER_allonoff = wx.Button(id=wxID_FRAME1BT_FIBER_ALLONOFF,
                  label=u'All on/off  (G)', name=u'bt_FIBER_allonoff',
                  parent=self.pnl_FIBER, pos=wx.Point(24, 200), size=wx.Size(120,
                  20), style=0)
            self.bt_FIBER_allonoff.Bind(wx.EVT_BUTTON,
                  self.OnBt_FIBER_allonoffButton, id=wxID_FRAME1BT_FIBER_ALLONOFF)

            self.st_FIBER_tracking = wx.StaticText(id=wxID_FRAME1ST_FIBER_TRACKING,
                  label=u'Tracking', name=u'st_FIBER_tracking',
                  parent=self.pnl_FIBER, pos=wx.Point(48, 248), size=wx.Size(68,
                  19), style=0)
            self.st_FIBER_tracking.SetForegroundColour(wx.Colour(255, 0, 0))
            self.st_FIBER_tracking.SetFont(wx.Font(16, wx.SWISS, wx.NORMAL,
                  wx.NORMAL, False, u'Lucida Grande'))

            self.bt_FIBER_seedonoff = wx.Button(id=wxID_FRAME1BT_FIBER_SEEDONOFF,
                  label=u'Seed On/Off (Ctrl+S)', name=u'bt_FIBER_seedonoff',
                  parent=self.pnl_FIBER, pos=wx.Point(0, 272), size=wx.Size(160,
                  20), style=0)
            self.bt_FIBER_seedonoff.SetForegroundColour(wx.Colour(255, 0, 0))
            self.bt_FIBER_seedonoff.SetFont(wx.Font(12, wx.SWISS, wx.NORMAL,
                  wx.NORMAL, False, u'Lucida Grande'))
            self.bt_FIBER_seedonoff.SetExtraStyle(1)
            self.bt_FIBER_seedonoff.SetBackgroundColour(wx.Colour(221, 221, 221))
            self.bt_FIBER_seedonoff.Bind(wx.EVT_BUTTON,
                  self.OnBt_FIBER_seedonoffButton,
                  id=wxID_FRAME1BT_FIBER_SEEDONOFF)

            self.bt_FIBER_targetonoff = wx.Button(id=wxID_FRAME1BT_FIBER_TARGETONOFF,
                  label=u'Target On/Off (Ctrl+T)', name=u'bt_FIBER_targetonoff',
                  parent=self.pnl_FIBER, pos=wx.Point(0, 352), size=wx.Size(160,
                  20), style=0)
            self.bt_FIBER_targetonoff.Bind(wx.EVT_BUTTON,
                  self.OnBt_FIBER_targetonoffButton,
                  id=wxID_FRAME1BT_FIBER_TARGETONOFF)

            self.bt_FIBER_tracknow = wx.Button(id=wxID_FRAME1BT_FIBER_TRACKNOW,
                  label=u'TRACK NOW  (c)', name=u'bt_FIBER_tracknow',
                  parent=self.pnl_FIBER, pos=wx.Point(0, 440), size=wx.Size(160,
                  20), style=0)
            self.bt_FIBER_tracknow.Bind(wx.EVT_BUTTON,
                  self.OnBt_FIBER_tracknowButton, id=wxID_FRAME1BT_FIBER_TRACKNOW)

            self.st_FIBER_pos_seed = wx.StaticText(id=wxID_FRAME1ST_FIBER_POS_SEED,
                  label=u'To position the seed point and press Ctrl+s  in main window',
                  name=u'st_FIBER_pos_seed', parent=self.pnl_FIBER, pos=wx.Point(8,
                  296), size=wx.Size(160, 56), style=wx.TE_MULTILINE)
            self.st_FIBER_pos_seed.SetForegroundColour(wx.Colour(255, 0, 0))

            self.st_FIBER_pos_target = wx.StaticText(id=wxID_FRAME1ST_FIBER_POS_TARGET,
                  label=u'To position a target point and press Ctrl+t  in main window',
                  name=u'st_FIBER_pos_target', parent=self.pnl_FIBER,
                  pos=wx.Point(8, 376), size=wx.Size(152, 64),
                  style=wx.TE_MULTILINE)
            self.st_FIBER_pos_target.SetForegroundColour(wx.Colour(255, 0, 0))

            self.bt_FIBER_grp1 = wx.Button(id=wxID_FRAME1BT_FIBER_GRP1, label=u'1',
                  name=u'bt_FIBER_grp1', parent=self.pnl_FIBER, pos=wx.Point(8,
                  512), size=wx.Size(32, 20), style=0)
            self.bt_FIBER_grp1.Bind(wx.EVT_BUTTON, self.OnBt_FIBER_grp1Button,
                  id=wxID_FRAME1BT_FIBER_GRP1)

            self.bt_FIBER_grp2 = wx.Button(id=wxID_FRAME1BT_FIBER_GRP2, label=u'2',
                  name=u'bt_FIBER_grp2', parent=self.pnl_FIBER, pos=wx.Point(48,
                  512), size=wx.Size(32, 20), style=0)
            self.bt_FIBER_grp2.Bind(wx.EVT_BUTTON, self.OnBt_FIBER_grp2Button,
                  id=wxID_FRAME1BT_FIBER_GRP2)

            self.bt_FIBER_grp3 = wx.Button(id=wxID_FRAME1BT_FIBER_GRP3, label=u'3',
                  name=u'bt_FIBER_grp3', parent=self.pnl_FIBER, pos=wx.Point(88,
                  512), size=wx.Size(32, 20), style=0)
            self.bt_FIBER_grp3.Bind(wx.EVT_BUTTON, self.OnBt_FIBER_grp3Button,
                  id=wxID_FRAME1BT_FIBER_GRP3)

            self.bt_FIBER_grp4 = wx.Button(id=wxID_FRAME1BT_FIBER_GRP4, label=u'4',
                  name=u'bt_FIBER_grp4', parent=self.pnl_FIBER, pos=wx.Point(128,
                  512), size=wx.Size(32, 20), style=0)
            self.bt_FIBER_grp4.Bind(wx.EVT_BUTTON, self.OnBt_FIBER_grp4Button,
                  id=wxID_FRAME1BT_FIBER_GRP4)

            self.bt_FIBER_grp5 = wx.Button(id=wxID_FRAME1BT_FIBER_GRP5, label=u'5',
                  name=u'bt_FIBER_grp5', parent=self.pnl_FIBER, pos=wx.Point(8,
                  544), size=wx.Size(32, 20), style=0)
            self.bt_FIBER_grp5.Bind(wx.EVT_BUTTON, self.OnBt_FIBER_grp5Button,
                  id=wxID_FRAME1BT_FIBER_GRP5)

            self.bt_FIBER_grp6 = wx.Button(id=wxID_FRAME1BT_FIBER_GRP6, label=u'6',
                  name=u'bt_FIBER_grp6', parent=self.pnl_FIBER, pos=wx.Point(48,
                  544), size=wx.Size(32, 20), style=0)
            self.bt_FIBER_grp6.Bind(wx.EVT_BUTTON, self.OnBt_FIBER_grp6Button,
                  id=wxID_FRAME1BT_FIBER_GRP6)

            self.bt_FIBER_grp7 = wx.Button(id=wxID_FRAME1BT_FIBER_GRP7, label=u'7',
                  name=u'bt_FIBER_grp7', parent=self.pnl_FIBER, pos=wx.Point(88,
                  544), size=wx.Size(32, 20), style=0)
            self.bt_FIBER_grp7.Bind(wx.EVT_BUTTON, self.OnBt_FIBER_grp7Button,
                  id=wxID_FRAME1BT_FIBER_GRP7)

            self.bt_FIBER_grp8 = wx.Button(id=wxID_FRAME1BT_FIBER_GRP8, label=u'8',
                  name=u'bt_FIBER_grp8', parent=self.pnl_FIBER, pos=wx.Point(128,
                  544), size=wx.Size(32, 20), style=0)
            self.bt_FIBER_grp8.Bind(wx.EVT_BUTTON, self.OnBt_FIBER_grp8Button,
                  id=wxID_FRAME1BT_FIBER_GRP8)

            self.st_FIBER_grpLabel = wx.StaticText(id=wxID_FRAME1ST_FIBER_GRPLABEL,
                  label=u'Fiber group On/Off', name=u'st_FIBER_grpLabel',
                  parent=self.pnl_FIBER, pos=wx.Point(8, 488), size=wx.Size(122,
                  16), style=0)
            self.st_FIBER_grpLabel.SetForegroundColour(wx.Colour(0, 0, 255))



            #COLOUR FUNCTIONS
            self.stbox_COLOUR_dispselected = wx.StaticBox(id=wxID_FRAME1STBOX_COLOUR_DISPSELECTED,
                  label=u'', name=u'stbox_COLOUR_dispselected',
                  parent=self.pnl_COLOUR, pos=wx.Point(-24, 321), size=wx.Size(200,
                  50), style=0)
            self.stbox_COLOUR_dispselected.SetBackgroundColour(wx.Colour(221, 221,
                  221))

            self.st_COLOURS_selected = wx.StaticText(id=wxID_FRAME1ST_COLOURS_SELECTED,
                  label=u'Selected Colour', name=u'st_COLOURS_selected',
                  parent=self.pnl_COLOUR, pos=wx.Point(24, 336), size=wx.Size(121,
                  18), style=0)
            self.st_COLOURS_selected.SetFont(wx.Font(15, wx.SWISS, wx.NORMAL,
                  wx.BOLD, False, u'Lucida Grande'))

            self.bt_COLOUR_applysel = wx.Button(id=wxID_FRAME1BT_COLOUR_APPLYSEL,
                  label=u'Apply to selected', name=u'bt_COLOUR_applysel',
                  parent=self.pnl_COLOUR, pos=wx.Point(16, 408), size=wx.Size(136,
                  20), style=0)
            self.bt_COLOUR_applysel.Bind(wx.EVT_BUTTON,
                  self.OnBt_COLOUR_applyselButton,
                  id=wxID_FRAME1BT_COLOUR_APPLYSEL)

            self.bt_COLOUR_applyall = wx.Button(id=wxID_FRAME1BT_COLOUR_APPLYALL,
                  label=u'Apply to all', name=u'bt_COLOUR_applyall',
                  parent=self.pnl_COLOUR, pos=wx.Point(16, 456), size=wx.Size(136,
                  20), style=0)
            self.bt_COLOUR_applyall.Bind(wx.EVT_BUTTON,
                  self.OnBt_COLOUR_applyallButton,
                  id=wxID_FRAME1BT_COLOUR_APPLYALL)

            self.st_COLOUR_pickinstr = wx.StaticText(id=wxID_FRAME1ST_COLOUR_PICKINSTR,
                  label=u'Pick a colour by double clicking in the colour window above',
                  name=u'st_COLOUR_pickinstr', parent=self.pnl_COLOUR,
                  pos=wx.Point(24, 232), size=wx.Size(120, 72),
                  style=wx.TE_MULTILINE)

            self.palette = PyPalette(self.pnl_COLOUR, id=wxID_COLPICK)
            self.palette.Bind(wx.EVT_LEFT_DCLICK, self.OnColourPick)

            self._init_coll_notebook1_Pages(self.notebook1)

        def __init__(self, parent):
            self._init_ctrls(parent)
        
        
        ##########################################
        #functionality - bind to main window

        
        ### TEST
        def OnMytestFromTopMenu(*args, **kwargs):
            print 'received top menu !!'
        
        
        #MARKERS
        def OnBt_MARKERS_singlemarkeradd(self, event):
            set_command_tmp_menufile('add marker')
            #print 'sent L view'
            
        def OnBt_MARKERS_multimarkeradd(self, event):
            set_command_tmp_menufile('load multi-marker file')
        
        def OnBt_MARKERS_makemarkertemplate(self, event):
            set_command_tmp_menufile('create multi-marker file template')
            
                            
        #STRUCTURAL
        #views
        def OnBt_L_view_selectButton(self, event):
            set_command_tmp_menufile('STRUCT L view')
            #print 'sent L view'
            
        def OnBt_R_view_selectButton(self, event):
            set_command_tmp_menufile('STRUCT R view')
            #print 'sent R view'
            
        def OnBt_S_view_selectButton(self, event):
            set_command_tmp_menufile('STRUCT S view')
            #print 'sent S view'

        def OnBt_I_view_selectButton(self, event):
            set_command_tmp_menufile('STRUCT I view')
            #print 'sent I view'

        def OnBt_A_view_selectButton(self, event):
            set_command_tmp_menufile('STRUCT A view')
            #print 'sent A view'

        def OnBt_P_view_selectButton(self, event):
            set_command_tmp_menufile('STRUCT P view')
            #print 'sent P view'
        
        #planes
        def OnBt_STRUCT_axButton(*args, **kwargs):
            set_command_tmp_menufile('STRUCT axial')
            #print 'sent axial'

        def OnBt_STRUCT_sagButton(self, event):
            set_command_tmp_menufile('STRUCT sagittal')
            #print 'sent sagittal'

        def OnBt_STRUCT_corButton(self, event):
            set_command_tmp_menufile('STRUCT coronal')
            #print 'sent coronal'

        def OnBt_STRUCT_edgesButton(self, event):
            set_command_tmp_menufile('STRUCT edges')
            #print 'sent edges'
            
        def OnBt_STRUCT_resetZoomButton(self, event):
            set_command_tmp_menufile('STRUCT zoom reset')
            #print 'sent reset'

        def OnBt_STRUCT_resetPlanesButton(self, event):
            set_command_tmp_menufile('STRUCT planes reset')
            #print 'plane reset'

        def OnBt_STRUCT_L_view_selectButton(self, event):
            set_command_tmp_menufile('STRUCT L view')
            #print 'sent L view'
            
        def OnBt_STRUCT_R_view_selectButton(self, event):
            set_command_tmp_menufile('STRUCT R view')
            #print 'sent R view'

        def OnBt_STRUCT_Sup_view_selectButton(self, event):
            set_command_tmp_menufile('STRUCT S view')
            #print 'sent S view'

        def OnBt_STRUCT_Inf_view_selectButton(self, event):
            set_command_tmp_menufile('STRUCT I view')
            #print 'sent I view'

        def OnBt_STRUCT_Ant_view_selectButton(self, event):
            set_command_tmp_menufile('STRUCT A view')
            #print 'sent A view'

        def OnBt_STRUCT_Post_view_selectButton(self, event):
            set_command_tmp_menufile('STRUCT P view')
            #print 'sent P view'


        #FUNCTIONAL
        #load
        def OnBt_FUNC_loadButton(self, event):
            set_command_tmp_menufile('FUNC Load')
            #print 'sent func load'
                    
        #switch in 2d mode
        def OnBt_FUNC_switch2dButton(self, event):
            set_command_tmp_menufile('FUNC 2d switch')
            #print 'sent func 2d switch'

        #switch in 3d mode
        def OnBt_FUNC_3dcycleButton(self, event):
            set_command_tmp_menufile('FUNC 3d switch')
            #print 'sent func 3d switch'

        #threshold TODO up/down capture
        def OnSpbt_FUNC_threshold3dSpin(self, event):
            print '\nThreshold higher ..\n' 
            if self.spbt_FUNC_threshold3d.GetValue() == 2:
                set_command_tmp_menufile('FUNC 3d UpThr')
                print '\nThreshold higher ..\n'
            else:
                set_command_tmp_menufile('FUNC 3d DownThr')
                print '\nThreshold lower ..\n'
            self.spbt_FUNC_threshold3d.SetValue(1)


        
        #DIPOLE
        #load
        def OnBt_DIP_loadButton(self, event):
            set_command_tmp_menufile('DIP Load')
            #print 'sent dipole load'
            
        #visible on / off
        def OnBt_DIP_visButton(self, event):
            set_command_tmp_menufile('DIP visible')
            #print 'sent dipole visible'
        
        #timepoint displayed TODO
        def OnSpinButton_DIP_time(self, event):
            set_command_tmp_menufile('DIP time')
            #print 'sent dipole time'
        
        #CORTEX
        #load
        def OnBt_CORTEX_loadButton(self, event):
            set_command_tmp_menufile('CORTEX Load')
            #print 'sent cortex load'
        
        #transparency TODO up/down capture               
        def OnSpbt_CORTEX_transpSpin(self, event):
            set_command_tmp_menufile('CORTEX Transparency')
            #print 'sent cortex Transparency'
            
        #visible on / off
        def OnBt_CORTEX_OnOffButton(self, event):
            set_command_tmp_menufile('CORTEX visible')
            #print 'sent CORTEX visible'
        
        
        #OTHER
        #create ortho views
        def OnBt_OTHER_orthoButton(self, event):
            set_command_tmp_menufile('OTHER ortho')
            #print 'sent other ortho'        
        
        #main window save to tif
        def OnBt_OTHER_tifmainButton(self, event):
            set_command_tmp_menufile('OTHER tifmain')
            #print 'sent other tifmain' 
        
        #ortho window save to tif
        def OnBt_OTHER_tiforthoButton(self, event):
            set_command_tmp_menufile('OTHER tifortho')
            #print 'sent other tifortho'
        
        #quit    
        def OnBt_OTHER_quitButton(self, event):
            set_command_tmp_menufile('OTHER exit')
            #print 'sent other exit'
            sys.exit()
        
        #help
        def OnBt_OTHER_helpButton(self, event):
            set_command_tmp_menufile('OTHER help')
            #print 'sent other help'
        
        #apply coordinates to planes TODO
        def OnBt_OTHER_apply_coords(self, event):
            x = self.spinCtrl_OTHER_X.GetValue()
            y = self.spinCtrl_OTHER_Y.GetValue()
            z = self.spinCtrl_OTHER_Z.GetValue()
            MNI_or_INDIV = self.rb_OTHER_coord_space.GetSelection()
            if MNI_or_INDIV == 0:
                MNI_or_INDIV = 'slice_number'
            elif MNI_or_INDIV == 1:
                MNI_or_INDIV = 'subject_space(mm)'
            else:
                MNI_or_INDIV = 'mni_space(mm)'
            set_command_tmp_menufile('%d %d %d %s OTHER_applycoords' %(x,y,z,MNI_or_INDIV))
            #print 'sent %d %d %d %s OTHER_applycoords' %(x,y,z,MNI_or_INDIV)


        #picked position marker on/off
        def OnBt_OTHER_pick_pos_marker(self, event):
            set_command_tmp_menufile('OTHER marker')
            #print 'sent other marker'

            
        #FIBERS
        #load
        def OnBt_FIBER_loadButton(self, event):
            set_command_tmp_menufile('FIBER Load')
            #print 'sent fiber load'
        
        #all fibers on/off
        def OnBt_FIBER_allonoffButton(self, event):
            set_command_tmp_menufile('FIBER visibility all')
            #print 'sent fiber all visile'
        
        #seed on/off
        def OnBt_FIBER_seedonoffButton(self, event):
            set_command_tmp_menufile('FIBER seed')
            #print 'sent fiber seed visile'
        
        #target on/off
        def OnBt_FIBER_targetonoffButton(self, event):
            set_command_tmp_menufile('FIBER target')
            #print 'sent fiber target visile'
        
        #track fibers through seed and target
        def OnBt_FIBER_tracknowButton(self, event):
            set_command_tmp_menufile('FIBER track')
            #print 'sent fiber track'

        #fiber grp 1 on /off
        def OnBt_FIBER_grp1Button(self, event):
            set_command_tmp_menufile('FIBER group1')
            myLog = open('/tmp/myfilenamehere','w')
            myLog.write('function')
            myLog.close()
            #print 'sent fiber group1'

        #fiber grp 2 on /off
        def OnBt_FIBER_grp2Button(self, event):
            set_command_tmp_menufile('FIBER group2')
            #print 'sent fiber group2'

        #fiber grp 3 on /off
        def OnBt_FIBER_grp3Button(self, event):
            set_command_tmp_menufile('FIBER group3')
            #print 'sent fiber group3'

        #fiber grp 4 on /off
        def OnBt_FIBER_grp4Button(self, event):
            set_command_tmp_menufile('FIBER group4')
            #print 'sent fiber group4'

        #fiber grp 5 on /off
        def OnBt_FIBER_grp5Button(self, event):
            set_command_tmp_menufile('FIBER group5')
            #print 'sent fiber group5'

        #fiber grp 6 on /off
        def OnBt_FIBER_grp6Button(self, event):
            set_command_tmp_menufile('FIBER group6')
            #print 'sent fiber group6'
   
        #fiber grp 7 on /off
        def OnBt_FIBER_grp7Button(self, event):
            set_command_tmp_menufile('FIBER group7')
            #print 'sent fiber group7'

        #fiber grp 8 on /off
        def OnBt_FIBER_grp8Button(self, event):
            set_command_tmp_menufile('FIBER group8')
            #print 'sent fiber group8'

        #COLOUR
        #apply selected colour to picked object 
        def OnBt_COLOUR_applyselButton(self, event):
            current_colour = self.stbox_COLOUR_dispselected.GetBackgroundColour()
            print 'colour = = = %s' %current_colour
            set_command_tmp_menufile('%s_COLOURselected' %current_colour)

        #apply selected colour to all objects 
        def OnBt_COLOUR_applyallButton(self, event):
            current_colour = self.stbox_COLOUR_dispselected.GetBackgroundColour()
            print 'colour = = = %s' %current_colour
            set_command_tmp_menufile('%s_COLOURall' %current_colour)
        
        def OnColourPick(self, event):
            dlg = wx.ColourDialog(self)
            # Ensure the full colour dialog is displayed, 
            # not the abbreviated version.
            dlg.GetColourData().SetChooseFull(True)
            if dlg.ShowModal() == wx.ID_OK:
                # If the user selected OK, then the dialog's wx.ColourData will
                # contain valid information. Fetch the data ...
                data = dlg.GetColourData()
                # ... then do something with it. The actual colour data will be
                # returned as a three-tuple (r, g, b) in this particular case.
                print('You selected: %s\n' % str(data.GetColour().Get()))
                selected_colour = data.GetColour().Get()
            dlg.Destroy()
            selected_colour = ((selected_colour[0],selected_colour[1],selected_colour[2]))
            print selected_colour
            self.stbox_COLOUR_dispselected.SetBackgroundColour(selected_colour)
            w = self.stbox_COLOUR_dispselected.GetBackgroundColour()
            
    def main():
        application = ynicDV3D_MenuApp(0)
        application.MainLoop()

    if __name__ == '__main__':
        main()


    ##############----- END MENU -----################



#setup communication pipe for the two processes
ServerReceive,ClientSend = os.pipe()
ClientReceive, ServerSend = os.pipe()


pid = os.fork()
if pid == 0:  # in child
    ynicDV3DMainWindow()    

else: # in parent
    ynicDV3DMenu()

