destinations.py 4.98 KB
Newer Older
Mark Hymers's avatar
Mark Hymers committed
1
2
3
4
5
6
7
8
#!/usr/bin/python3

# Module containing classes which support the process incoming
# routines

from os.path import join
import re

9
10
from yias.utils import makedirs_chmod

Mark Hymers's avatar
Mark Hymers committed
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
__all__ = []

class Destination(object):
    """Destination information for images - base class

    This class demonstrates which should be implemented by
    subclasses.  This class rejects all series."""

    # The following variables must be set by subclasses
    """Directory to put raw files into"""
    raw_dir = ''
    """Directory to put anonymous files into

    (can be None if anonymous files are not supported)"""
    anon_dir = ''

    """Mode to use for raw directories"""
    mode_raw_dir   = 0o700
    """Mode to use for raw files"""
    mode_raw_file  = 0o400

    """Mode to use for anonymous directories"""
    mode_anon_dir  = 0o755
    """Mode to use for anonymous files"""
    mode_anon_file = 0o444

    def for_us(self, patientid, studydesc):
        """
        Should the study with description studydesc be given to us?
        """
        return False

43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
    def get_raw_directory(self, patientid, studydesc):
        """
        Return the raw directory to use based on a patient ID and study
        description.  This is preferred to direct use of raw_dir as it allows
        the class to partition data in an appropriate way (e.g. based on
        whether it will be anonymised.

        This routine may return None if no raw directory is configured.
        """
        return None

    def get_anon_directory(self, patientid, studydesc):
        """
        Return the anonymous directory to use based on a patient ID and study
        description.  This is preferred to direct use of anon_dir as it allows
        the class to partition data in an appropriate way if necessary.

        Note that this routine will return None if the study should not be
        anonymised or no anonymous directory is set
        """
        return None

Mark Hymers's avatar
Mark Hymers committed
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
    def anonymise(self, patientid, studydesc):
        """
        Should a study which was given to us be anonymised
        """
        return False

    def ensure_directories(self):
        """
        Ensure that any directories which are needed exist
        """
        return

__all__.append('Destination')


class RawAndAnonDestination(Destination):
Mark Hymers's avatar
Mark Hymers committed
81
82
83
    regex_patient = re.compile(r'^[EeRr]\d+$')
    regex_study   = re.compile(r'^[CcPp]\d+[Aa]?([-:]\w+)?$')
    regex_anon    = re.compile(r'^[CcPp]\d+[Aa]([-:]\w+)?$')
Mark Hymers's avatar
Mark Hymers committed
84
85
    anon_extra_studies = ['STRUCTURAL', 'T1ONLY', 'T1LONG']

86
    def __init__(self, basedir=None, anon_dir=None, raw_dir=None, **kwargs):
Mark Hymers's avatar
Mark Hymers committed
87
88
89
        self.anon_dir = anon_dir or join(basedir, 'anon')
        self.raw_dir = raw_dir or join(basedir, 'raw')

90
91
92
93
        # If the user provides us with a separate directory for
        # non-anonymised files, store that
        self.raw_not_anon_dir = kwargs.get('raw_not_anon_dir', join(basedir, 'raw_not_anon'))

Mark Hymers's avatar
Mark Hymers committed
94
95
96
97
98
    def for_us(self, patientid, studydesc):
        if self.regex_patient.search(patientid) and \
           self.regex_study.search(studydesc):
               return True

99
100
101
102
        if self.regex_patient.search(patientid) and \
           studydesc in self.anon_extra_studies:
               return True

Mark Hymers's avatar
Mark Hymers committed
103
104
        return False

105
106
107
108
109
110
111
112
113
114
115
116
    def get_raw_directory(self, patientid, studydesc):
        if self.anonymise(patientid, studydesc):
            return self.raw_dir

        return self.raw_not_anon_dir

    def get_anon_directory(self, patientid, studydesc):
        if self.anonymise(patientid, studydesc):
            return self.anon_dir

        return None

Mark Hymers's avatar
Mark Hymers committed
117
118
119
120
121
122
123
124
125
    def anonymise(self, patientid, studydesc):
        if self.regex_anon.search(studydesc):
            return True
        if studydesc in self.anon_extra_studies:
            return True

        return False

    def ensure_directories(self):
126
127
128
        makedirs_chmod(self.anon_dir,         mode=self.mode_anon_dir, exist_ok=True)
        makedirs_chmod(self.raw_dir,          mode=self.mode_raw_dir,  exist_ok=True)
        makedirs_chmod(self.raw_not_anon_dir, mode=self.mode_raw_dir,  exist_ok=True)
Mark Hymers's avatar
Mark Hymers committed
129
130
131
132
133
134
135
136
137
138
139

__all__.append('RawAndAnonDestination')


class RawOnlyDestination(Destination):
    mode_anon_dir  = None
    mode_anon_file = None

    mode_raw_dir   = 0o700
    mode_raw_file  = 0o400

140
    def __init__(self, basedir=None, anon_dir=None, raw_dir=None, **kwargs):
Mark Hymers's avatar
Mark Hymers committed
141
142
143
144
145
146
147
148
149
        # Note that we don't use basedir in this routine unless
        # raw_dir is not specified
        # Ignore anon_dir
        self.raw_dir = raw_dir or join(basedir, 'raw')

    def for_us(self, patientid, studydesc):
        # We'll take anything!
        return True

150
151
152
153
154
155
156
    def get_raw_directory(self, patientid, studydesc):
        return self.raw_dir

    def get_anon_directory(self, patientid, studydesc):
        # We don't anonymise anything
        return None

Mark Hymers's avatar
Mark Hymers committed
157
    def anonymise(self, patientid, studydesc):
158
        # We don't anonymise anything
Mark Hymers's avatar
Mark Hymers committed
159
160
161
        return False

    def ensure_directories(self):
162
        makedirs_chmod(self.raw_dir,  mode=self.mode_raw_dir,  exist_ok=True)
Mark Hymers's avatar
Mark Hymers committed
163
164

__all__.append('RawAndAnonDestination')