Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion conda_env.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: vt
name: voxToolv2
channels: !!python/tuple
- !!python/unicode
'defaults'
Expand Down
47 changes: 34 additions & 13 deletions model/scan.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@
import interpolator
import re

# added by Joel
import scipy.spatial.distance
import scipy.ndimage
#

log = logging.getLogger()


Expand Down Expand Up @@ -157,8 +162,10 @@ def get_center(self):


class Contact(object):
scale = (1.0, 1.0, 1.0)

def __init__(self, point_mask, contact_label,
lead_location, lead_group):
lead_location, lead_group,):
self.point_mask = point_mask.copy()
self.label = contact_label
self.lead_location = lead_location
Expand All @@ -175,8 +182,10 @@ def center(self):
return np.round(self.point_mask.get_center(), 1)

@property
def center_str(self):
return '({:.1f}, {:.1f}, {:.1f})'.format(*self.point_mask.get_center())
def center_str(self,ct=None):
tpl = '({:.1f}, {:.1f}, {:.1f})'
pos = np.divide(self.center,self.scale)
return tpl.format(*pos.tolist())

@property
def lead_location_str(self):
Expand All @@ -196,9 +205,6 @@ def __contains__(self, coordinate):
def center(self):
return np.round(self._center,1)

@property
def center_str(self):
return '({:.1f}, {:.1f}, {:.1f})'.format(*self._center)


class Lead(object):
Expand Down Expand Up @@ -546,10 +552,24 @@ def _load_scan(self, img_file):
self.filename = img_file
log.debug("Loading {}".format(img_file))
img = nib.load(self.filename)
self.data = img.get_data().squeeze()

#Changes CT scan resolution to account for slice thickness, effectively sets z dimension to equal x and y.
#On saving and loading, then uses self.img_zoom to put coordinates in native resolution.
#Coordinates in the contact list are still given in the resized resolution.

img_shape = np.array(img.shape)
Contact.scale = self.img_zoom = np.reciprocal(1.0*img_shape)*np.max(img_shape)
self.data = scipy.ndimage.zoom(img.get_data().squeeze(), self.img_zoom)

self.brainmask = np.zeros(img.get_data().shape, bool)
self.affine = img.affine[:3,:]

def upsample(self,coordinate):
return np.multiply(coordinate,self.img_zoom)

def downsample(self,coordinate):
return np.divide(coordinate,self.img_zoom)

def add_mask(self, filename):
mask = nib.load(filename).get_data()
self.brainmask = mask
Expand Down Expand Up @@ -581,14 +601,15 @@ def to_dict(self,include_bipolar=False):
lead_loc=contact.lead_location,
coordinate_spaces=dict(
ct_voxel=dict(
raw=list(contact.center.astype(int))
raw=(np.rint(self.downsample(contact.center).astype(int)).tolist()
)
)
))
)))
if include_bipolar:
pairs = [{'atlases':{},
'info':{},
'coordinate_spaces':{'ct_voxel':{'raw':list((0.5*(c1.center+c2.center)).astype(int))}},
'coordinate_spaces':{'ct_voxel':{
'raw':list(np.rint(self.downsample(0.5*(c1.center+c2.center))).astype(int))}},
'names':(lead.label+c1.label,lead.label+c2.label) }
for (c1, c2) in self.calculate_pairs(lead)]
else:
Expand Down Expand Up @@ -617,15 +638,15 @@ def to_vox_mom(self,fname,include_bipolar=False):
ltype = lead.type_
dims = lead.dimensions
for contact in sorted(lead.contacts.keys(),cmp=lambda x,y: cmp(int(x),int(y))):
voxel = np.rint(lead.contacts[contact].center)
voxel = np.rint(self.downsample(lead.contacts[contact].center)).astype(int)
contact_name = lead.label+contact
csv_out += "%s\t%s\t%s\t%s\t%s\t%s %s\n"%(
contact_name,voxel[0],voxel[1],voxel[2],ltype,dims[0],dims[1]
)
if include_bipolar:
pairs = self.calculate_pairs(lead)
for pair in pairs:
voxel = np.rint((pair[0].center+pair[1].center)/2)
voxel = np.rint(np.divide((pair[0].center+pair[1].center)/2,self.img_zoom)).astype(int)
pair_name = '{lead.label}{pair[0].label}-{lead.label}{pair[1].label}'.format(lead=lead,pair=pair)
csv_out += "%s\t%s\t%s\t%s\t%s\t%s %s\n"%(
pair_name,voxel[0],voxel[1],voxel[2],ltype,dims[0],dims[1])
Expand Down Expand Up @@ -668,7 +689,7 @@ def get_dimensions(lead):
self.set_leads(labels, types, dimensions, radii, spacings)
for i, lead_label in enumerate(labels):
for contact in leads[lead_label]['contacts']:
coordinates = contact['coordinate_spaces']['ct_voxel']['raw']
coordinates = self.upsample(contact['coordinate_spaces']['ct_voxel']['raw'])
point_mask = PointMask.proximity_mask(self._points, coordinates, radii[i])
group = contact['lead_group']
loc = contact['lead_loc']
Expand Down
6 changes: 3 additions & 3 deletions view/pyloc.py
Original file line number Diff line number Diff line change
Expand Up @@ -243,8 +243,8 @@ def select_coordinate(self, coordinate, do_center=True, allow_seed=True):
self.view.contact_panel.set_chosen_leads(self.ct.get_leads())
self.display_seed_contact()
else:
self.view.update_ras(self.selected_coordinate)
log.info("Selected coordinate {}".format(self.selected_coordinate))
self.view.update_ras(self.ct.downsample(self.selected_coordinate))
log.info("Selected coordinate {}".format(self.ct.downsample(self.selected_coordinate)))
else:
log.info("No coordinate selected")
self.view.update_cloud('_selected')
Expand Down Expand Up @@ -287,7 +287,7 @@ def add_selection(self):
if not self.confirm("Dimensions {} are outside of lead dimensions {}. "
"Are you sure you want to continue?".format(lead_location, lead.dimensions)):
return

self.ct.add_selection_to_lead(lead_label, contact_label, lead_location, self.lead_group)
self.view.contact_panel.set_chosen_leads(self.ct.get_leads())
self.ct.clear_selection()
Expand Down