-
Notifications
You must be signed in to change notification settings - Fork 2
/
default_config.ini
193 lines (191 loc) · 10.7 KB
/
default_config.ini
1
2
3
4
5
6
7
8
9
10
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
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
# Configuration for MOMO. You can edit this configuration file, or run MOMO.py
# with the -c (--config) flag, providing your own. You can provide any of the
# below arguments in your own file, but not all are needed, as the program will
# default to useful values if they are missing from the config. However, the
# sections need to be present either way.
[positional]
# mapfile - A json file used to map study classes and numbers with keywords.
# Needs a very specific layout and can be created using make_mapping_json.py.
mapfile: ./MCMapping.json
# network - A .pth file used to load an all-in-one pytorch neural network.
network: ./eval_network_all.pth
# networkscript - A .py script which holds the necessary function and class
# definitions. Required because torch.load cannot properly load all models if
# the original source files are unavailable, due to serialization issues.
# Only function definitions in here (or MOMO.py/MOMO_Backbone.py) are available
# for use. Dynamic imports are wonky with relative paths, so just put your
# script in this folder and enter its name without extension here.
# If you provide no or an invalid script, the config parser returns nothing
# and assumes you have made no custom script.
networkscript: TransferNet_script
# known_metas - This list of tuples contains all the DICOM metadata tags that
# MOMO will attempt to match. The first object is its name, the second object
# is a tuple which identifies the unique key of the desired metadata. The third
# object is another such tuple, and is required if the desired piece of
# metadata is itself split into several subfields. The fields "Procedure Code",
# "Study Description" and "Series Modality" should always exist and they are
# critical fields, meaning that MOMO requires some input for them in order to
# function.
known_metas = [("Procedure Code", ("0x0008", "0x1032"), ("0x0008", "0x0100")),
("Study Description", ("0x0008", "0x1030")),
("Series Description", ("0x0008", "0x103e")),
("Series Modality", ("0x0008", "0x0060")),
("Series Bodysite", ("0x0018", "0x0015")),
("Requested Procedure", ("0x0032", "0x1064"), ("0x0008", "0x0104")),
("Performed Procedure", ("0x0040", "0x0254")),
("Protocol Name", ("0x0018", "0x1030"))]
[optional]
# verbose - Warning, this is *very* verbose.
verbose: True
# local - If True, assumes all the files to check are already on disk and in
# data_root. If False, will download files using the Download function. Since
# it is unclear what kind of data storage (GEPACS, etc.) anyone uses, you will
# have to edit the Download() function manually for this to work.
local: True
# split_mode - If True, expects two dictionaries, "mapfiles" and "networks",
# mapped such that e.g. mapfiles = {"CT": "./CT_only.json"}. Every legal
# modality should have an equivalent mapping which a network can use, and a
# network which trained on just the classes in the modality.
split_mode: True
[keywordargs]
# mapfiles - Expects a dictionary (see above).
mapfiles = {"CT": "./CT_only.json",
"XA": "./XA_only.json",
"CR": "./CR_only.json",
"MR": "./MR_only.json",
"US": "./US_only.json",
"MRPET": "./MR_only.json",
"PT": "./CT_only.json"}
# networks - Expects a dictionary (see above).
networks = {"CT": "./DenseNet_CT_only.pth",
"XA": "./ResNet_XA_only.pth",
"CR": "./DenseNet_CR_only.pth",
"MR": "./DenseNet_MR_only.pth",
"US": "./DenseNet_US_only.pth",
"MRPET": "./DenseNet_MR_only.pth",
"PT": "./DenseNet_CT_only.pth"}
# custom representation - If True, expects a python function which takes as
# input a list of series file names (so a list of strings, which are valid
# paths), and returns a tensor representation that either the default network
# can use, or the custom network can use:
# tensor_representation = representation(list_of_series_file_names)
# The function must be defined in your custom network script.
custom_representation = False
# custom predictor - If True, expects a function 'predictor' in your custom
# network script that does:
# prediction, probability = predictor(tensor_representation)
# Probability should be between 0 and 1 and prediction should be an integer
# that the mapping json can turn into a string ("0" => "CTAB", etc.).
custom_predictor = False
# vote_rules - Expects a list of rules that apply to specific classes. The
## rules follow a simple syntax which the program can interpret.
# "a+b=c" <=> if a and b in list, replace all a and b with c (more additions are allowed, but only one = sign)
## Example: "CTAB+CTT=CTTA" (If your study contains abdominal and thorax CTs,
## its a CT Thorax+Abdomen)
# "a-b=c" <=> if a and not b in list, replace all a and b with c (more subs allowed, but only one = sign)
## Rule 1 and 2 may be concatenated infinitely as "a+b-c+d=e", but cannot start with a "-"-sign
# "a>b" <=> if a and b in list, replace all b with a (only one argument is allowed on each side)
## Example: "CTSH>CTS" (If there is votes for a CT Skull and Neck and a CT
## Skull, then its clearly a CT Skull and Neck overall still)
# "a!" <=> if a in list, a is absolute (only one argument is allowed)
## Example: "CTH!" (If there is ANY votes for CT Heart, because there was maybe
## a fullbody CT, a thorax CT, a topogram and a single Heart CT, it is
## definitely a Heart CT, because that is the really relevant thing)
## Any vote of rtype "!" will cause the voting process to exit, votes being the results of the applied rule
# "a!+b" <=> if a and b in list, a is absolute (more additions are allowed, but only one absolute value)
# "a!-b" <=> if a and not b in list, a is absolute (more subtractions are allowed, but only one absolute value)
## Rule 5 and 6 may be concatenated infinitely as "a!+b-c+d-e"
## This class does not check whether the rules contain valid strings, that one is up to the user!
## All rules will be applied in the order they are entered in. If any rules interact, be aware of this.
## Application of any remaining rules is skipped if a rule with an absolute target is found to apply.
vote_rules = ["CTT+CTAB=CTTA",
"CTTA>CTAB",
"CTTA>CTT",
"CTH!",
"CTSH>CTS",
"CTS+CTGE=CTS",
"CTSH+CTGE=CTGE",
"KHWS+KBWS+KLWS=KWS",
"MRH+MRB+MRL=MRWS",
"MRWS>MRH",
"MRWS>MRB",
"MRWS>MRL",
"MRSH>MRS",
"MRPWB!",
"MRPSH>MRPS",
"MRWB!",
"MRPAB>MRA",
"MRPAB>MRBE",
"MRPM>MRM",
"MRPOE>MROE",
"MRPUE>MRUE",
"MRPETWS>MRWS",
"MRPSH>MRSH",
"MRPS>MRS",
"MRPTH>MRTH",
"MRPWB>MRWB",
"PCTH!",
"PCTGK!",
"PCTSH>PCTSC",
"PCTH>CTT",
"PCTOE>CTOE",
"PCTUE>CTUE",
"PCTSH>CTSH",
"PCTSC>CTS"]
# network_vote_rules - Boolean. If set to True, allows the network predictions
# to be treated as regular (weighted) votes and makes them subject to
# vote_rules. If false, simply counts them without modifications.
# Generally, vote rules decrease correct predictions, but increase slightly
# wrong predictions (when applied to per-series network predictions), purely
# through statistical effects. As such, they are disabled by default.
network_vote_rules = False
# remapped_modalities - Mostly meant for debugging or experiments, this kwarg
# should be a dictionary, mapped like: {"replaced_modality": "new_modality"}.
# For example, you might want to treat all digital radiography as computed
# radiography, because your system contains only one of the two, but they are
# virtually the same for clinical purposes.
remapped_modalities = {"DX": "CR"}
# minmatchlength - The substring matcher that attempts to find keywords
# according to our mapping in the studies it predicts, has a minimum length set
# for matches. This depends on what data we predict with (study descriptions
# should have stricter requirements, as they are more powerful), and what type
# of match we find (exact matches have smaller minimums because they should
# rarely be coincidental. The first value in the tuple corresponds to minimum
# length of a substring matching one keyword exactly, the second value to the
# minimum length of a substring matching one keyword partially.
minmatch_length = {"Study": (4, 6), "Series": (3, 6)}
# blacklist - Some series, such as a topogram, or a patient protocol, are
# either unhelpful or even actively harmful in determining the correct region
# with a neural network. The blacklist is a list of substrings which lead to a
# series being excluded from network predictions if they are present in the
# series description.
blacklist = ["localizer", "patient", "protocol", "dosis", "report", "topogram", "scout", "screen", "save", "scoring", "evidence", "document", "result", "text"]
# reduce_blacklist - Some descriptions are uniquely problematic for substring
# matching, because they are common matching occurences in a series description
# without providing any information (imaging axis descriptions specifically
# have things like "coronar" or "craniospinal" in there which cause false
# predictions). Any item on this list is removed from the string before matching.
reduce_blacklist = ["untersuchung", "planungs", "craniospinaleachse", "ueberpruefung", "kontrolle", "befund"]
# ssm_prios - The substring matcher itself also has a way of prioritizing
# results. Even if there is longer matches, a priority match will be returned
# if it was found. For example "CT Heart Vessels" would match "Heart" and
# "Vessels". Despite Vessels being the longer match, the study is clearly a CT
# of the Heart, and not just any random blood vessel CT.
# The ssm_prios are a list of procedure codes. As the substring matcher exits
# when a match was found to be a priority, the order of the list imposes an
# implicit hierarchy. This is rarely important, as far as I know.
ssm_prios = ["CTH", "PCTH"]
# no_network - If set to True (or any value that does not evaluate to False),
# disables network contributions to predictions
no_network = False
# netw_conf_threshold - Disabled by default. If set, must be between 0 and 1,
# and any network prediction with a confidence below the threshold has its
# weight set to zero, thereby preventing it from voting.
netw_conf_threshold = 0.15
# a12-weights - Algorithm 12 merges votes from metadata, the neural network and
# StringMatcher results for the study descrption. Since the latter is one
# entry, it must be properly weighted. We do this by pretending there is
# n_series study_description entries each getting a vote, and scale those votes
# with a value gmw (good match weight) or wmw (weak match weight).
a12_gmw = 1.5
a12_wmw = 0.5