dbdicom 0.2.1__py3-none-any.whl → 0.2.3__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of dbdicom might be problematic. Click here for more details.

Files changed (50) hide show
  1. dbdicom/__init__.py +4 -3
  2. dbdicom/create.py +34 -97
  3. dbdicom/dro.py +174 -0
  4. dbdicom/ds/dataset.py +29 -3
  5. dbdicom/ds/types/mr_image.py +18 -7
  6. dbdicom/extensions/__init__.py +10 -0
  7. dbdicom/{wrappers → extensions}/dipy.py +191 -205
  8. dbdicom/extensions/elastix.py +503 -0
  9. dbdicom/extensions/matplotlib.py +107 -0
  10. dbdicom/extensions/numpy.py +271 -0
  11. dbdicom/{wrappers → extensions}/scipy.py +130 -31
  12. dbdicom/{wrappers → extensions}/skimage.py +1 -1
  13. dbdicom/extensions/sklearn.py +243 -0
  14. dbdicom/extensions/vreg.py +1390 -0
  15. dbdicom/external/dcm4che/bin/emf2sf +57 -57
  16. dbdicom/manager.py +70 -36
  17. dbdicom/pipelines.py +66 -0
  18. dbdicom/record.py +266 -43
  19. dbdicom/types/instance.py +17 -3
  20. dbdicom/types/series.py +1900 -404
  21. dbdicom/utils/image.py +152 -21
  22. dbdicom/utils/vreg.py +327 -135
  23. dbdicom-0.2.3.dist-info/METADATA +88 -0
  24. {dbdicom-0.2.1.dist-info → dbdicom-0.2.3.dist-info}/RECORD +27 -41
  25. {dbdicom-0.2.1.dist-info → dbdicom-0.2.3.dist-info}/WHEEL +1 -1
  26. dbdicom/external/__pycache__/__init__.cpython-310.pyc +0 -0
  27. dbdicom/external/__pycache__/__init__.cpython-37.pyc +0 -0
  28. dbdicom/external/dcm4che/__pycache__/__init__.cpython-310.pyc +0 -0
  29. dbdicom/external/dcm4che/__pycache__/__init__.cpython-37.pyc +0 -0
  30. dbdicom/external/dcm4che/bin/__pycache__/__init__.cpython-310.pyc +0 -0
  31. dbdicom/external/dcm4che/bin/__pycache__/__init__.cpython-37.pyc +0 -0
  32. dbdicom/external/dcm4che/lib/linux-x86/libclib_jiio.so +0 -0
  33. dbdicom/external/dcm4che/lib/linux-x86-64/libclib_jiio.so +0 -0
  34. dbdicom/external/dcm4che/lib/linux-x86-64/libopencv_java.so +0 -0
  35. dbdicom/external/dcm4che/lib/solaris-sparc/libclib_jiio.so +0 -0
  36. dbdicom/external/dcm4che/lib/solaris-sparc/libclib_jiio_vis.so +0 -0
  37. dbdicom/external/dcm4che/lib/solaris-sparc/libclib_jiio_vis2.so +0 -0
  38. dbdicom/external/dcm4che/lib/solaris-sparcv9/libclib_jiio.so +0 -0
  39. dbdicom/external/dcm4che/lib/solaris-sparcv9/libclib_jiio_vis.so +0 -0
  40. dbdicom/external/dcm4che/lib/solaris-sparcv9/libclib_jiio_vis2.so +0 -0
  41. dbdicom/external/dcm4che/lib/solaris-x86/libclib_jiio.so +0 -0
  42. dbdicom/external/dcm4che/lib/solaris-x86-64/libclib_jiio.so +0 -0
  43. dbdicom/wrappers/__init__.py +0 -7
  44. dbdicom/wrappers/elastix.py +0 -855
  45. dbdicom/wrappers/numpy.py +0 -119
  46. dbdicom/wrappers/sklearn.py +0 -151
  47. dbdicom/wrappers/vreg.py +0 -273
  48. dbdicom-0.2.1.dist-info/METADATA +0 -276
  49. {dbdicom-0.2.1.dist-info → dbdicom-0.2.3.dist-info}/LICENSE +0 -0
  50. {dbdicom-0.2.1.dist-info → dbdicom-0.2.3.dist-info}/top_level.txt +0 -0
dbdicom/record.py CHANGED
@@ -1,10 +1,14 @@
1
1
  # Importing annotations to handle or sign in import type hints
2
2
  from __future__ import annotations
3
3
 
4
+ import os
5
+ import datetime
6
+
4
7
  # Import packages
5
8
  import numpy as np
6
9
  import pandas as pd
7
10
  import dbdicom.ds.dataset as dbdataset
11
+ from dbdicom.ds import MRImage
8
12
  from dbdicom.utils.files import export_path
9
13
 
10
14
 
@@ -15,12 +19,14 @@ class Record():
15
19
 
16
20
  def __init__(self, create, manager, uid='Database', key=None, **kwargs):
17
21
 
22
+ self._logfile = None
18
23
  self._key = key
19
24
  self._mute = False
20
25
  self.uid = uid
21
26
  self.attributes = kwargs
22
27
  self.manager = manager
23
28
  self.new = create
29
+
24
30
 
25
31
  def __eq__(self, other):
26
32
  if other is None:
@@ -34,13 +40,13 @@ class Record():
34
40
  return self.get_values(attributes)
35
41
 
36
42
  def __setattr__(self, attribute, value):
37
- if attribute in ['_key','_mute', 'uid', 'manager', 'attributes', 'new']:
43
+ if attribute in ['_key','_mute', 'uid', 'manager', 'attributes', 'new', '_logfile']:
38
44
  self.__dict__[attribute] = value
39
45
  else:
40
- self.set_values([attribute], [value])
46
+ self._set_values([attribute], [value])
41
47
 
42
48
  def __setitem__(self, attributes, values):
43
- self.set_values(attributes, values)
49
+ self._set_values(attributes, values)
44
50
 
45
51
  def loc(self):
46
52
  return self.manager._loc(self.name, self.uid)
@@ -86,7 +92,80 @@ class Record():
86
92
  def dialog(self):
87
93
  return self.manager.dialog
88
94
 
95
+ def set_log(self, filepath:str=None):
96
+ """Set a new file for logging.
97
+
98
+ Args:
99
+ filepath: full path to a log file. If not provided the current log file is removed. Alternatively the value 'Default' can be assigned, in which case a standard file at the same location of the database is automatically opened. Defaults to None.
100
+
101
+ Raises:
102
+ FileNotFoundError: if the log file cannot be written to.
103
+
104
+ See also:
105
+ `log`
106
+
107
+ Examples:
108
+
109
+ Set a new log file:
110
+
111
+ >>> record.set_log('path/to/logfile')
112
+
113
+ and start logging:
114
+
115
+ >>> record.log('Starting new calculation...)
116
+
117
+ Alternatively, start a new log at the default location:
118
+
119
+ >>> record.set_log('Default')
120
+ """
121
+ if filepath is None:
122
+ self._logfile = None
123
+ return
124
+ if filepath == 'Default':
125
+ # Use default log name
126
+ self._logfile = os.path.join(self.manager.path, "activity_log.txt")
127
+ else:
128
+ self._logfile = filepath
129
+ try:
130
+ file = open(self._logfile, 'a')
131
+ file.write(str(datetime.datetime.now())[0:19] + "Starting a new log..")
132
+ file.close()
133
+ except:
134
+ msg = 'Cannot write to log ' + self._logfile
135
+ raise FileNotFoundError(msg)
136
+
137
+ def log(self, message:str):
138
+ """Write an entry in the log file.
139
+
140
+ If no logfile is set, this function only writes a message in the terminal.
141
+
142
+ Args:
143
+ message (str): text message to be written in the log file. The function automatically includes some timing information so this does not need to be included in the message.
144
+
145
+ Raises:
146
+ FileNotFoundError: if the log file cannot be written to.
89
147
 
148
+ See also:
149
+ `set_log`
150
+
151
+ Examples:
152
+ Set a default file for logging and write a first message:
153
+
154
+ >>> record.set_log('Default')
155
+ >>> record.log('Starting new calculation...)
156
+ """
157
+
158
+ self.message(message)
159
+ if self._logfile is None:
160
+ return
161
+ try:
162
+ file = open(self._logfile, 'a')
163
+ file.write("\n"+str(datetime.datetime.now())[0:19] + ": " + message)
164
+ file.close()
165
+ except:
166
+ msg = 'Cannot write to log ' + self._logfile
167
+ raise FileNotFoundError(msg)
168
+
90
169
 
91
170
  # Properties
92
171
 
@@ -100,7 +179,7 @@ class Record():
100
179
  Example:
101
180
  Print a summary of a database:
102
181
 
103
- >>> database = db.database_hollywood()
182
+ >>> database = db.dro.database_hollywood()
104
183
  >>> database.print()
105
184
  ---------- DATABASE --------------
106
185
  Location: In memory
@@ -212,7 +291,7 @@ class Record():
212
291
  Populate the series with a numpy array and verify that it is now no longer empty:
213
292
 
214
293
  >>> zeros = np.zeros((3, 2, 128, 128))
215
- >>> series.set_ndarray(zeros)
294
+ >>> series.set_pixel_values(zeros)
216
295
  >>> print(series.empty())
217
296
  False
218
297
  """
@@ -327,7 +406,7 @@ class Record():
327
406
  Example:
328
407
  Find the patients of a given database:
329
408
 
330
- >>> database = db.database_hollywood()
409
+ >>> database = db.dro.database_hollywood()
331
410
  >>> patients = database.children()
332
411
  >>> print([p.PatientName for p in patients])
333
412
  ['James Bond', 'Scarface']
@@ -368,7 +447,7 @@ class Record():
368
447
  Example:
369
448
  Retrieve a study from a database, and find all other studies performed on the same patient:
370
449
 
371
- >>> database = db.database_hollywood()
450
+ >>> database = db.dro.database_hollywood()
372
451
  >>> study = database.studies()[0]
373
452
  >>> print([s.StudyDescription for s in study.siblings()])
374
453
  ['Xray']
@@ -402,7 +481,7 @@ class Record():
402
481
  Example:
403
482
  Find all series in a database, and print their labels:
404
483
 
405
- >>> database = db.database_hollywood()
484
+ >>> database = db.dro.database_hollywood()
406
485
  >>> series_list = database.series()
407
486
  >>> print([s.label() for s in series_list])
408
487
  ['Series 001 [Localizer]', 'Series 002 [T2w]', 'Series 001 [Chest]', 'Series 002 [Head]', 'Series 001 [Localizer]', 'Series 002 [T2w]', 'Series 001 [Chest]', 'Series 002 [Head]']
@@ -447,7 +526,7 @@ class Record():
447
526
  Example:
448
527
  Find all studies in a database:
449
528
 
450
- >>> database = db.database_hollywood()
529
+ >>> database = db.dro.database_hollywood()
451
530
  >>> studies_list = database.studies()
452
531
  >>> print([s.label() for s in studies_list])
453
532
  ['Study MRI [19821201]', 'Study Xray [19821205]', 'Study MRI [19850105]', 'Study Xray [19850106]']
@@ -486,7 +565,7 @@ class Record():
486
565
  Example:
487
566
  Find all patients in a database:
488
567
 
489
- >>> database = db.database_hollywood()
568
+ >>> database = db.dro.database_hollywood()
490
569
  >>> patients_list = database.patients()
491
570
  >>> print([s.label() for s in patients_list])
492
571
  ['Patient James Bond', 'Patient Scarface']
@@ -906,8 +985,6 @@ class Record():
906
985
  return self
907
986
 
908
987
 
909
-
910
-
911
988
  def copy_to(self, parent, **kwargs):
912
989
  """Return a copy of the record under another parent.
913
990
 
@@ -1385,6 +1462,7 @@ class Record():
1385
1462
  My message:
1386
1463
  """
1387
1464
  self._mute = True
1465
+ self.status.muted = True
1388
1466
 
1389
1467
  def unmute(self):
1390
1468
  """Allow the object from sending status updates to the user
@@ -1415,6 +1493,7 @@ class Record():
1415
1493
  Hello World
1416
1494
  """
1417
1495
  self._mute = False
1496
+ self.status.muted = False
1418
1497
 
1419
1498
  def type(self):
1420
1499
  return self.__class__.__name__
@@ -1436,8 +1515,8 @@ class Record():
1436
1515
  return self.manager._extract(self.keys())
1437
1516
  #return self.manager.register.loc[self.keys(),:]
1438
1517
 
1439
- def instances(self, sort=True, sortby=None, **kwargs):
1440
- inst = self.manager.instances(keys=self.keys(), sort=sort, sortby=sortby, **kwargs)
1518
+ def instances(self, sort=True, sortby=None, select={}, **kwargs):
1519
+ inst = self.manager.instances(keys=self.keys(), sort=sort, sortby=sortby, select=select, **kwargs)
1441
1520
  return [self.record('Instance', uid, key) for key, uid in inst.items()]
1442
1521
 
1443
1522
  def images(self, sort=True, sortby=None, **kwargs):
@@ -1529,21 +1608,26 @@ class Record():
1529
1608
  self.manager._write_df()
1530
1609
 
1531
1610
 
1532
-
1533
-
1534
-
1535
-
1536
1611
  def new_instance(self, dataset=None, **kwargs):
1537
1612
  attr = {**kwargs, **self.attributes}
1538
1613
  uid, key = self.manager.new_instance(parent=self.uid, dataset=dataset, **attr)
1539
1614
  return self.record('Instance', uid, key, **attr)
1540
1615
 
1541
- def set_values(self, attributes, values):
1616
+ def _set_values(self, attributes, values):
1542
1617
  keys = self.keys()
1543
1618
  self._key = self.manager.set_values(attributes, values, keys)
1544
1619
 
1545
1620
  def get_values(self, attributes):
1546
1621
  return self.manager.get_values(attributes, self.keys())
1622
+
1623
+ def init_dataset(self, dtype='mri'):
1624
+ if dtype=='mri':
1625
+ ds = MRImage()
1626
+ else: # dummy option for now
1627
+ ds = MRImage()
1628
+ for a in self.attributes:
1629
+ ds.set_values(a, self.attributes[a])
1630
+ return ds
1547
1631
 
1548
1632
  def get_dataset(self):
1549
1633
  ds = self.manager.get_dataset(self.uid, self.keys())
@@ -1552,8 +1636,6 @@ class Record():
1552
1636
  def set_dataset(self, dataset):
1553
1637
  self.manager.set_dataset(self.uid, dataset, self.keys())
1554
1638
 
1555
-
1556
-
1557
1639
  def read_dataframe(*args, **kwargs):
1558
1640
  return read_dataframe(*args, **kwargs)
1559
1641
 
@@ -1582,14 +1664,55 @@ class Record():
1582
1664
  #
1583
1665
 
1584
1666
 
1585
- def copy_to(records, target):
1667
+ def copy_to(records:list, parent:Record):
1668
+ """Copy a list of records to a new parent.
1669
+
1670
+ Args:
1671
+ records (list): list of Records of the same type
1672
+ parent (Record): location for the copies.
1673
+
1674
+ See also:
1675
+ `copy`
1676
+ `move_to`
1677
+
1678
+ Example:
1679
+
1680
+ Consider the hollywood demo database:
1681
+
1682
+ >>> database = db.dro.database_hollywood()
1683
+
1684
+ There are currently two MRI studies in the database:
1685
+
1686
+ >>> MRIs = database.studies(StudyDescription='MRI)
1687
+ >>> len(MRIs)
1688
+ 2
1689
+
1690
+ Create a new patient and copy the MRI studies there:
1691
+
1692
+ >>> tarantino = database.new_patient(PatientName='Tarantino')
1693
+ >>> db.copy_to(MRIs, tarantino)
1694
+ >>> tarantino_MRIs = tarantino.studies()
1695
+ >>> len(tarantino_MRIs)
1696
+ 2
1697
+
1698
+ Note that all header information is automatically updated:
1699
+
1700
+ >>> tarantino_MRIs[0].PatientName
1701
+ Tarantino
1702
+
1703
+ Since the studies were copied, the originals remained and the total number of studies in the database has increased:
1704
+
1705
+ >>> MRIs = database.studies(StudyDescription='MRI)
1706
+ >>> len(MRIs)
1707
+ 4
1708
+ """
1586
1709
  if not isinstance(records, list):
1587
- return records.copy_to(target)
1710
+ return records.copy_to(parent)
1588
1711
  copy = []
1589
- desc = target.label()
1712
+ desc = parent.label()
1590
1713
  for r, record in enumerate(records):
1591
- record.status.progress(r+1, len(records), 'Copying ' + desc)
1592
- copy_record = record.copy_to(target)
1714
+ record.progress(r+1, len(records), 'Copying ' + desc)
1715
+ copy_record = record.copy_to(parent)
1593
1716
  if isinstance(copy_record, list):
1594
1717
  copy += copy_record
1595
1718
  else:
@@ -1597,9 +1720,55 @@ def copy_to(records, target):
1597
1720
  record.status.hide()
1598
1721
  return copy
1599
1722
 
1600
- def move_to(records, target):
1601
- #if type(records) is np.ndarray:
1602
- # records = records.tolist()
1723
+ def move_to(records:list, target:Record):
1724
+ """Move a list of records to a new parent.
1725
+
1726
+ Args:
1727
+ records (list): list of Records of the same type
1728
+ parent (Record): location for the copies.
1729
+
1730
+ See also:
1731
+ `copy`
1732
+ `copy_to`
1733
+
1734
+ Example:
1735
+
1736
+ Consider the hollywood demo database:
1737
+
1738
+ >>> database = db.dro.database_hollywood()
1739
+
1740
+ There are currently two MRI studies in the database:
1741
+
1742
+ >>> MRIs = database.studies(StudyDescription='MRI)
1743
+ >>> len(MRIs)
1744
+ 2
1745
+
1746
+ Create a new patient and move the MRI studies there:
1747
+
1748
+ >>> tarantino = database.new_patient(PatientName='Tarantino')
1749
+ >>> db.copy_to(MRIs, tarantino)
1750
+ >>> tarantino_MRIs = tarantino.studies()
1751
+ >>> len(tarantino_MRIs)
1752
+ 2
1753
+
1754
+ Note that all header information is automatically updated:
1755
+
1756
+ >>> tarantino_MRIs[0].PatientName
1757
+ Tarantino
1758
+
1759
+ Since the studies were moved, the total number of studies in the database has stayed the same:
1760
+
1761
+ >>> MRIs = database.studies(StudyDescription='MRI)
1762
+ >>> len(MRIs)
1763
+ 2
1764
+
1765
+ And the original patients do not have any MRI studies left:
1766
+
1767
+ >>> jb = database.patients(PatientName = 'James Bond')
1768
+ >>> MRIs = jb[0].studies(StudyDescription='MRI')
1769
+ >>> len(MRIs)
1770
+ 0
1771
+ """
1603
1772
  if not isinstance(records, list):
1604
1773
  records = [records]
1605
1774
  mgr = records[0].manager
@@ -1607,7 +1776,7 @@ def move_to(records, target):
1607
1776
  mgr.move_to(uids, target.uid, **target.attributes)
1608
1777
  return records
1609
1778
 
1610
- def group(records, into=None, inplace=False):
1779
+ def group(records:list, into:Record=None, inplace=False)->Record:
1611
1780
  if not isinstance(records, list):
1612
1781
  records = [records]
1613
1782
  if into is None:
@@ -1618,17 +1787,69 @@ def group(records, into=None, inplace=False):
1618
1787
  copy_to(records, into)
1619
1788
  return into
1620
1789
 
1621
- def merge(records, into=None, inplace=False):
1790
+ def merge(records:list, into:Record=None, inplace=False)->Record:
1791
+ """Merge a list of records into a single new record.
1792
+
1793
+ Args:
1794
+ records (list): list of Records of the same type
1795
+ into (Record, optional): location for the merged series. If None is provided, the merged series is created in the parent of the first record in the list. Defaults to None.
1796
+ inplace (bool, optional): If set to True, the original series will be removed and only the merged series retain. If set to False the original series will contine to exist. Default is False.
1797
+
1798
+ Returns:
1799
+ new_record (Record): the merged record.
1800
+
1801
+ See also:
1802
+ `copy`
1803
+ `copy_to`
1804
+
1805
+ Example:
1806
+
1807
+ The first patient in the hollywood demo database currently has two studies
1808
+
1809
+ >>> database = db.dro.database_hollywood()
1810
+ >>> jb = database.patients(PatientName = 'James Bond')[0]
1811
+ >>> len(jb.studies())
1812
+ 2
1813
+
1814
+ If we merge them together, the patient now has three studies, the original MRI and Xray studies, and the new merged study:
1815
+
1816
+ >>> new_study = db.merge(jb.studies())
1817
+ >>> len(jb.studies())
1818
+ 3
1819
+ >>> jb.StudyDescription
1820
+ ['MRI', 'New Study', 'Xray']
1821
+
1822
+ Since the original MRI and Xray studies had two series each, the new study now has 2+2=4 series:
1823
+
1824
+ >>> len(new_study.series())
1825
+ 4
1826
+
1827
+ We have used here the default setting of ``inplace=False``, so the original series are preserved. To see what happens with ``inplace=True``, lets merge all 3 studies of the patient:
1828
+
1829
+ >>> single_jb_study = db.merge(jb.studies(), inplace=True)
1830
+
1831
+ Since we have merged in place, the original 3 studies have been removed and there is now only one study left.
1832
+
1833
+ >>> len(jb.studies())
1834
+ 1
1835
+
1836
+ The new study now groups the 8 series that were in the original 3 studies:
1837
+
1838
+ >>> len(single_jb_study.series())
1839
+ 8
1840
+ """
1622
1841
  if not isinstance(records, list):
1623
1842
  records = [records]
1624
1843
  children = []
1625
1844
  for record in records:
1626
1845
  children += record.children()
1627
- new_series = group(children, into=into, inplace=inplace)
1846
+ new_record = group(children, into=into, inplace=inplace)
1628
1847
  if inplace:
1629
1848
  for record in records:
1630
1849
  record.remove()
1631
- return new_series
1850
+ return new_record
1851
+
1852
+
1632
1853
 
1633
1854
 
1634
1855
  #
@@ -1637,11 +1858,18 @@ def merge(records, into=None, inplace=False):
1637
1858
 
1638
1859
 
1639
1860
 
1640
-
1641
- def read_dataframe(record, tags):
1861
+ def read_dataframe(record, tags, select={}, **filters):
1642
1862
  if set(tags) <= set(record.manager.columns):
1643
- return record.register()[tags]
1644
- instances = record.instances()
1863
+ df = record.register()[tags]
1864
+ filters = {**select, **filters}
1865
+ for f in filters:
1866
+ if f in df:
1867
+ if isinstance(filters[f], np.ndarray):
1868
+ df = df[df[f].isin(filters[f])]
1869
+ else:
1870
+ df = df[df[f] == filters[f]]
1871
+ return df
1872
+ instances = record.instances(select=select, **filters)
1645
1873
  return _read_dataframe_from_instance_array_values(instances, tags)
1646
1874
 
1647
1875
 
@@ -1662,9 +1890,4 @@ def _read_dataframe_from_instance_array_values(instances, tags):
1662
1890
  indices.append(index)
1663
1891
  data.append(values)
1664
1892
  instance.progress(i+1, len(instances), 'Reading dataframe..')
1665
- return pd.DataFrame(data, index=indices, columns=tags)
1666
-
1667
-
1668
-
1669
-
1670
-
1893
+ return pd.DataFrame(data, index=indices, columns=tags)
dbdicom/types/instance.py CHANGED
@@ -46,10 +46,13 @@ class Instance(Record):
46
46
  ds = self.get_dataset()
47
47
  return ds.get_pixel_array()
48
48
 
49
- def set_array(self, array):
49
+ def set_array(self, array): # obsolete
50
+ self.set_pixel_array(array)
51
+
52
+ def set_pixel_values(self, array):
50
53
  self.set_pixel_array(array)
51
54
 
52
- def set_pixel_array(self, array):
55
+ def set_pixel_array(self, array): # make private
53
56
  ds = self.get_dataset()
54
57
  if ds is None:
55
58
  ds = new_dataset('MRImage')
@@ -137,6 +140,17 @@ class Instance(Record):
137
140
  width = self.WindowWidth,
138
141
  center = self.WindowCenter,
139
142
  )
143
+
144
+ def set_affine(self, affine):
145
+ p = image.dismantle_affine_matrix(affine)
146
+ self.read()
147
+ self.SpacingBetweenSlices = p['SpacingBetweenSlices']
148
+ self.SliceThickness = p['SpacingBetweenSlices']
149
+ self.PixelSpacing = p['PixelSpacing']
150
+ self.ImageOrientationPatient = p['ImageOrientationPatient']
151
+ self.ImagePositionPatient = p['ImagePositionPatient']
152
+ self.SliceLocation = np.dot(p['ImagePositionPatient'], p['slice_cosine'])
153
+ self.clear()
140
154
 
141
155
 
142
156
  def map_to(source, target):
@@ -179,7 +193,7 @@ def map_to(source, target):
179
193
 
180
194
  return result
181
195
 
182
-
196
+ # Obsolete
183
197
  def map_mask_to(record, target):
184
198
  """Map non-zero image pixels onto a target image.
185
199
  Overwrite pixel values in the target"""