summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEdoardo Pasca <edo.paskino@gmail.com>2019-10-28 15:02:06 +0000
committerGitHub <noreply@github.com>2019-10-28 15:02:06 +0000
commitdbbf15e7147df613032c8fb230f57a2027e57b4e (patch)
tree1b8c060edee2c1661c868b1c0ab9aed71b1d830c
parent4a76f6b9a024016112811106e48af7720fdb9798 (diff)
downloadframework-dbbf15e7147df613032c8fb230f57a2027e57b4e.tar.gz
framework-dbbf15e7147df613032c8fb230f57a2027e57b4e.tar.bz2
framework-dbbf15e7147df613032c8fb230f57a2027e57b4e.tar.xz
framework-dbbf15e7147df613032c8fb230f57a2027e57b4e.zip
defines shape for a subset slice (#410)
* defines shape for a subset slice closes #408 * fix subset for AcquisitionData * add future imports (#411) * override the dimension parameter, set angles to None by default (#412) * defines shape for a subset slice * fix subset for AcquisitionData * added initial unittest for subset * added .gitignore * adds unittest for subset, fix subset for AcquisitionData * reverted change of behaviour of as_array * removed empty line
-rw-r--r--.gitignore66
-rwxr-xr-xWrappers/Python/ccpi/framework/framework.py41
-rw-r--r--Wrappers/Python/test/test_subset.py141
3 files changed, 234 insertions, 14 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..acac237
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,66 @@
+# =========================
+# Operating System Files
+# =========================
+
+# OSX
+# =========================
+
+.DS_Store
+.AppleDouble
+.LSOverride
+
+# Thumbnails
+._*
+
+# Files that might appear on external disk
+.Spotlight-V100
+.Trashes
+
+# Directories potentially created on remote AFP share
+.AppleDB
+.AppleDesktop
+Network Trash Folder
+Temporary Items
+.apdisk
+
+# Windows
+# =========================
+
+# Windows image file caches
+Thumbs.db
+ehthumbs.db
+
+# Folder config file
+Desktop.ini
+
+# Recycle Bin used on file shares
+$RECYCLE.BIN/
+
+# Windows Installer files
+*.cab
+*.msi
+*.msm
+*.msp
+
+# Windows shortcuts
+*.lnk
+
+# User-specific files
+*.o
+*.a
+*.dll
+*.so
+*.h5
+*.pyd
+*.pyc
+*.tmp
+*.nxs
+
+# Common editor backups
+~$*
+*~
+*.bak
+\#*
+.#*
+
+
diff --git a/Wrappers/Python/ccpi/framework/framework.py b/Wrappers/Python/ccpi/framework/framework.py
index 627e6d2..c30c436 100755
--- a/Wrappers/Python/ccpi/framework/framework.py
+++ b/Wrappers/Python/ccpi/framework/framework.py
@@ -110,6 +110,8 @@ class ImageGeometry(object):
if order != [i for i in range(len(dim_labels))]:
# resort
self.shape = tuple([shape[i] for i in order])
+ else:
+ self.shape = tuple(order)
self.dimension_labels = labels
def get_order_by_label(self, dimension_labels, default_dimension_labels):
@@ -316,12 +318,12 @@ class AcquisitionGeometry(object):
if not reduce(lambda x,y: (y in allowed_labels) and x, labels , True):
raise ValueError('Requested axis are not possible. Expected {},\ngot {}'.format(
allowed_labels,labels))
- if len(labels) != len(dim_labels):
- raise ValueError('Wrong number of labels. Expected {} got {}'.format(len(dim_labels), len(labels)))
order = self.get_order_by_label(labels, dim_labels)
if order != [i for i in range(len(dim_labels))]:
# resort
self.shape = tuple([shape[i] for i in order])
+ else:
+ self.shape = tuple(order)
self.dimension_labels = labels
def get_order_by_label(self, dimension_labels, default_dimension_labels):
@@ -447,7 +449,6 @@ class DataContainer(object):
raise ValueError('Unknown dimension {0}. Should be one of'.format(dimension_label,
self.dimension_labels.values()))
-
def as_array(self, dimensions=None):
'''Returns the DataContainer as Numpy Array
@@ -1199,20 +1200,24 @@ class AcquisitionData(DataContainer):
def subset(self, dimensions=None, **kw):
'''returns a subset of the AcquisitionData and regenerates the geometry'''
+ # # Check that this is actually a resorting
+ # if dimensions is not None and \
+ # (len(dimensions) != len(self.shape) ):
+ # raise ValueError('Please specify the slice on the axis/axes you want to cut away, or the same amount of axes for resorting')
+
+ # requested_labels = kw.get('dimension_labels', None)
+ # if requested_labels is not None:
+ # allowed_labels = [AcquisitionGeometry.CHANNEL,
+ # AcquisitionGeometry.ANGLE,
+ # AcquisitionGeometry.VERTICAL,
+ # AcquisitionGeometry.HORIZONTAL]
+ # if not reduce(lambda x,y: (y in allowed_labels) and x, requested_labels , True):
+ # raise ValueError('Requested axis are not possible. Expected {},\ngot {}'.format(
+ # allowed_labels,requested_labels))
# Check that this is actually a resorting
if dimensions is not None and \
(len(dimensions) != len(self.shape) ):
raise ValueError('Please specify the slice on the axis/axes you want to cut away, or the same amount of axes for resorting')
-
- requested_labels = kw.get('dimension_labels', None)
- if requested_labels is not None:
- allowed_labels = [AcquisitionGeometry.CHANNEL,
- AcquisitionGeometry.ANGLE,
- AcquisitionGeometry.VERTICAL,
- AcquisitionGeometry.HORIZONTAL]
- if not reduce(lambda x,y: (y in allowed_labels) and x, requested_labels , True):
- raise ValueError('Requested axis are not possible. Expected {},\ngot {}'.format(
- allowed_labels,requested_labels))
out = super(AcquisitionData, self).subset(dimensions, **kw)
if out.number_of_dimensions > 1:
@@ -1226,6 +1231,14 @@ class AcquisitionData(DataContainer):
pixel_size_v = 1
dist_source_center = self.geometry.dist_source_center
dist_center_detector = self.geometry.dist_center_detector
+
+ # update the angles if necessary
+ sliceme = kw.get(AcquisitionGeometry.ANGLE, None)
+ if sliceme is not None:
+ angles = numpy.asarray([ self.geometry.angles[sliceme] ] , numpy.float32)
+ else:
+ angles = self.geometry.angles.copy()
+
for key in out.dimension_labels.keys():
if out.dimension_labels[key] == AcquisitionGeometry.CHANNEL:
channels = self.geometry.channels
@@ -1243,7 +1256,7 @@ class AcquisitionData(DataContainer):
out.geometry = AcquisitionGeometry(geom_type=self.geometry.geom_type,
dimension=dim,
- angles=self.geometry.angles,
+ angles=angles,
pixel_num_h=pixel_num_h,
pixel_size_h = pixel_size_h,
pixel_num_v = pixel_num_v,
diff --git a/Wrappers/Python/test/test_subset.py b/Wrappers/Python/test/test_subset.py
new file mode 100644
index 0000000..dd017fb
--- /dev/null
+++ b/Wrappers/Python/test/test_subset.py
@@ -0,0 +1,141 @@
+# -*- coding: utf-8 -*-
+# CCP in Tomographic Imaging (CCPi) Core Imaging Library (CIL).
+
+# Copyright 2017 UKRI-STFC
+# Copyright 2017 University of Manchester
+
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+
+# http://www.apache.org/licenses/LICENSE-2.0
+
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+import sys
+import unittest
+import numpy
+from ccpi.framework import DataContainer
+from ccpi.framework import ImageData
+from ccpi.framework import AcquisitionData
+from ccpi.framework import ImageGeometry
+from ccpi.framework import AcquisitionGeometry
+from timeit import default_timer as timer
+
+class TestSubset(unittest.TestCase):
+ def setUp(self):
+ self.ig = ImageGeometry(1,2,3,channels=4)
+ angles = numpy.asarray([90.,0.,-90.], dtype=numpy.float32)
+
+ self.ag = AcquisitionGeometry('cone', 'edo', pixel_num_h=20, pixel_num_v=2, angles=angles,
+ dist_source_center = 312.2,
+ dist_center_detector = 123.,
+ channels=4 )
+
+ def test_ImageDataAllocate1a(self):
+ data = self.ig.allocate()
+ default_dimension_labels = [ImageGeometry.CHANNEL, ImageGeometry.VERTICAL,
+ ImageGeometry.HORIZONTAL_Y, ImageGeometry.HORIZONTAL_X]
+ self.assertTrue( default_dimension_labels == list(data.dimension_labels.values()) )
+ def test_ImageDataAllocate1b(self):
+ data = self.ig.allocate()
+ default_dimension_labels = [ImageGeometry.CHANNEL, ImageGeometry.VERTICAL,
+ ImageGeometry.HORIZONTAL_Y, ImageGeometry.HORIZONTAL_X]
+ self.assertTrue( data.shape == (4,3,2,1))
+
+ def test_ImageDataAllocate2a(self):
+ non_default_dimension_labels = [ ImageGeometry.HORIZONTAL_X, ImageGeometry.VERTICAL,
+ ImageGeometry.HORIZONTAL_Y, ImageGeometry.CHANNEL]
+ data = self.ig.allocate(dimension_labels=non_default_dimension_labels)
+ self.assertTrue( non_default_dimension_labels == list(data.dimension_labels.values()) )
+
+ def test_ImageDataAllocate2b(self):
+ non_default_dimension_labels = [ ImageGeometry.HORIZONTAL_X, ImageGeometry.VERTICAL,
+ ImageGeometry.HORIZONTAL_Y, ImageGeometry.CHANNEL]
+ data = self.ig.allocate(dimension_labels=non_default_dimension_labels)
+ self.assertTrue( data.shape == (1,3,2,4))
+
+ def test_AcquisitionDataAllocate1a(self):
+ data = self.ag.allocate()
+ default_dimension_labels = [AcquisitionGeometry.CHANNEL ,
+ AcquisitionGeometry.ANGLE , AcquisitionGeometry.VERTICAL ,
+ AcquisitionGeometry.HORIZONTAL]
+ self.assertTrue( default_dimension_labels == list(data.dimension_labels.values()) )
+
+ def test_AcquisitionDataAllocate1b(self):
+ data = self.ag.allocate()
+ default_dimension_labels = [AcquisitionGeometry.CHANNEL ,
+ AcquisitionGeometry.ANGLE , AcquisitionGeometry.VERTICAL ,
+ AcquisitionGeometry.HORIZONTAL]
+
+ self.assertTrue( data.shape == (4,3,2,20))
+
+ def test_AcquisitionDataAllocate2a(self):
+ non_default_dimension_labels = [AcquisitionGeometry.CHANNEL, AcquisitionGeometry.HORIZONTAL,
+ AcquisitionGeometry.VERTICAL, AcquisitionGeometry.ANGLE]
+ data = self.ag.allocate(dimension_labels=non_default_dimension_labels)
+
+
+ self.assertTrue( non_default_dimension_labels == list(data.dimension_labels.values()) )
+
+ def test_AcquisitionDataAllocate2b(self):
+ non_default_dimension_labels = [AcquisitionGeometry.CHANNEL, AcquisitionGeometry.HORIZONTAL,
+ AcquisitionGeometry.VERTICAL, AcquisitionGeometry.ANGLE]
+ data = self.ag.allocate(dimension_labels=non_default_dimension_labels)
+ self.assertTrue( data.shape == (4,20,2,3))
+
+ def test_AcquisitionDataSubset1a(self):
+ non_default_dimension_labels = [AcquisitionGeometry.CHANNEL, AcquisitionGeometry.HORIZONTAL,
+ AcquisitionGeometry.VERTICAL, AcquisitionGeometry.ANGLE]
+ data = self.ag.allocate(dimension_labels=non_default_dimension_labels)
+ #self.assertTrue( data.shape == (4,20,2,3))
+ sub = data.subset(vertical = 0)
+ self.assertTrue( sub.shape == (4,20,3))
+
+ def test_AcquisitionDataSubset1b(self):
+ non_default_dimension_labels = [AcquisitionGeometry.CHANNEL, AcquisitionGeometry.HORIZONTAL,
+ AcquisitionGeometry.VERTICAL, AcquisitionGeometry.ANGLE]
+ data = self.ag.allocate(dimension_labels=non_default_dimension_labels)
+ #self.assertTrue( data.shape == (4,20,2,3))
+ sub = data.subset(channel = 0)
+ self.assertTrue( sub.shape == (20,2,3))
+ def test_AcquisitionDataSubset1c(self):
+ non_default_dimension_labels = [AcquisitionGeometry.CHANNEL, AcquisitionGeometry.HORIZONTAL,
+ AcquisitionGeometry.VERTICAL, AcquisitionGeometry.ANGLE]
+ data = self.ag.allocate(dimension_labels=non_default_dimension_labels)
+ #self.assertTrue( data.shape == (4,20,2,3))
+ sub = data.subset(horizontal = 0)
+ self.assertTrue( sub.shape == (4,2,3))
+ def test_AcquisitionDataSubset1d(self):
+ non_default_dimension_labels = [AcquisitionGeometry.CHANNEL, AcquisitionGeometry.HORIZONTAL,
+ AcquisitionGeometry.VERTICAL, AcquisitionGeometry.ANGLE]
+ data = self.ag.allocate(dimension_labels=non_default_dimension_labels)
+ #self.assertTrue( data.shape == (4,20,2,3))
+ sliceme = 1
+ sub = data.subset(angle = sliceme)
+ #print (sub.shape , sub.dimension_labels)
+ self.assertTrue( sub.shape == (4,20,2) )
+ self.assertTrue( sub.geometry.angles[0] == data.geometry.angles[sliceme])
+ def test_AcquisitionDataSubset1e(self):
+ non_default_dimension_labels = [AcquisitionGeometry.CHANNEL, AcquisitionGeometry.HORIZONTAL,
+ AcquisitionGeometry.VERTICAL, AcquisitionGeometry.ANGLE]
+ data = self.ag.allocate(dimension_labels=non_default_dimension_labels)
+ #self.assertTrue( data.shape == (4,20,2,3))
+ sliceme = 1
+ sub = data.subset(angle = sliceme)
+ self.assertTrue( sub.geometry.angles[0] == data.geometry.angles[sliceme])
+ def test_AcquisitionDataSubset1f(self):
+
+ data = self.ag.allocate()
+ #self.assertTrue( data.shape == (4,20,2,3))
+ sliceme = 1
+ sub = data.subset(angle = sliceme)
+ self.assertTrue( sub.geometry.angles[0] == data.geometry.angles[sliceme])
+
+
+
+
+ \ No newline at end of file