rtp-connect 1.1 → 1.2
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.rdoc +30 -19
- data/COPYING +674 -674
- data/Gemfile +3 -0
- data/Gemfile.lock +35 -0
- data/README.rdoc +12 -6
- data/lib/rtp-connect.rb +24 -22
- data/lib/rtp-connect/constants.rb +57 -57
- data/lib/rtp-connect/control_point.rb +176 -86
- data/lib/rtp-connect/dose_tracking.rb +222 -0
- data/lib/rtp-connect/extended_field.rb +56 -26
- data/lib/rtp-connect/field.rb +163 -43
- data/lib/rtp-connect/logging.rb +155 -158
- data/lib/rtp-connect/methods.rb +3 -4
- data/lib/rtp-connect/plan.rb +136 -52
- data/lib/rtp-connect/plan_to_dcm.rb +503 -0
- data/lib/rtp-connect/prescription.rb +71 -23
- data/lib/rtp-connect/record.rb +18 -2
- data/lib/rtp-connect/ruby_extensions.rb +90 -81
- data/lib/rtp-connect/site_setup.rb +78 -28
- data/lib/rtp-connect/version.rb +5 -5
- data/rakefile.rb +29 -0
- data/rtp-connect.gemspec +29 -0
- metadata +105 -53
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
rtp-connect (1.1)
|
5
|
+
|
6
|
+
GEM
|
7
|
+
remote: http://www.rubygems.org/
|
8
|
+
specs:
|
9
|
+
dicom (0.9.3)
|
10
|
+
diff-lcs (1.1.3)
|
11
|
+
metaclass (0.0.1)
|
12
|
+
mocha (0.12.0)
|
13
|
+
metaclass (~> 0.0.1)
|
14
|
+
rake (0.9.2.2)
|
15
|
+
rspec (2.11.0)
|
16
|
+
rspec-core (~> 2.11.0)
|
17
|
+
rspec-expectations (~> 2.11.0)
|
18
|
+
rspec-mocks (~> 2.11.0)
|
19
|
+
rspec-core (2.11.0)
|
20
|
+
rspec-expectations (2.11.1)
|
21
|
+
diff-lcs (~> 1.1.3)
|
22
|
+
rspec-mocks (2.11.1)
|
23
|
+
yard (0.8.2.1)
|
24
|
+
|
25
|
+
PLATFORMS
|
26
|
+
x86-mingw32
|
27
|
+
|
28
|
+
DEPENDENCIES
|
29
|
+
bundler (>= 1.0.0)
|
30
|
+
dicom (>= 0.9.3)
|
31
|
+
mocha (>= 0.10.5)
|
32
|
+
rake (>= 0.9.2.2)
|
33
|
+
rspec (>= 2.9.0)
|
34
|
+
rtp-connect!
|
35
|
+
yard (>= 0.8.2)
|
data/README.rdoc
CHANGED
@@ -26,23 +26,29 @@ external dependencies.
|
|
26
26
|
=== Read, modify and write
|
27
27
|
|
28
28
|
# Read file:
|
29
|
-
rtp = Plan.read(
|
29
|
+
rtp = Plan.read('some_file.rtp')
|
30
30
|
# Extract the Patient's Name:
|
31
31
|
name = rtp.patient_last_name
|
32
32
|
# Modify the Patient's Name:
|
33
|
-
rtp.patient_last_name =
|
33
|
+
rtp.patient_last_name = 'Anonymous'
|
34
34
|
# Write to file:
|
35
|
-
rtp.write(
|
35
|
+
rtp.write('new_file.rtp')
|
36
36
|
|
37
37
|
=== Create a new Plan Definition Record from scratch
|
38
38
|
|
39
39
|
# Create the instance:
|
40
40
|
rtp = Plan.new
|
41
41
|
# Set the Patient's ID attribute:
|
42
|
-
rtp.patient_id =
|
42
|
+
rtp.patient_id = '12345'
|
43
43
|
# Export the instance to an RTP string (with CRC):
|
44
44
|
output = rtp.to_s
|
45
45
|
|
46
|
+
=== Convert an RTP file to DICOM:
|
47
|
+
|
48
|
+
p = Plan.read('some_file.rtp')
|
49
|
+
dcm = p.to_dcm
|
50
|
+
dcm.write('rtplan.dcm')
|
51
|
+
|
46
52
|
=== Log settings
|
47
53
|
|
48
54
|
# Change the log level so that only error messages are displayed:
|
@@ -69,7 +75,7 @@ automatically printed to the screen. A useful hack to avoid this effect is
|
|
69
75
|
to append ";0" after a command.
|
70
76
|
|
71
77
|
Example:
|
72
|
-
rtp = Plan.read(
|
78
|
+
rtp = Plan.read('some_file.rtp') ;0
|
73
79
|
|
74
80
|
|
75
81
|
== RESOURCES
|
@@ -89,6 +95,7 @@ Example:
|
|
89
95
|
* Treatment field [FIELD_DEF]
|
90
96
|
* Extended treatment field [EXTENDED_FIELD_DEF]
|
91
97
|
* Control point record [CONTROL_PT_DEF]
|
98
|
+
* Dose tracking record [DOSE_DEF]
|
92
99
|
|
93
100
|
=== Unsupported records
|
94
101
|
|
@@ -96,7 +103,6 @@ Example:
|
|
96
103
|
* Document based treatment field [PDF_FIELD_DEF]
|
97
104
|
* Multileaf collimator [MLC_DEF]
|
98
105
|
* MLC shape [MLC_SHAPE_DEF]
|
99
|
-
* Dose tracking record [DOSE_DEF]
|
100
106
|
* Dose action points [DOSE_ACTION]
|
101
107
|
|
102
108
|
If you encounter an RTP file with an unsupported record type, please contact me.
|
data/lib/rtp-connect.rb
CHANGED
@@ -1,23 +1,25 @@
|
|
1
|
-
# Loads the files that are used by the RTPConnect library.
|
2
|
-
|
3
|
-
# Logging:
|
4
|
-
require_relative 'rtp-connect/logging'
|
5
|
-
# Super classes:
|
6
|
-
require_relative 'rtp-connect/record'
|
7
|
-
# Core library:
|
8
|
-
require_relative 'rtp-connect/plan'
|
9
|
-
require_relative 'rtp-connect/
|
10
|
-
require_relative 'rtp-connect/
|
11
|
-
require_relative 'rtp-connect/
|
12
|
-
require_relative 'rtp-connect/
|
13
|
-
require_relative 'rtp-connect/
|
14
|
-
|
15
|
-
require_relative 'rtp-connect/
|
16
|
-
#
|
17
|
-
require_relative 'rtp-connect/
|
18
|
-
|
19
|
-
require_relative 'rtp-connect/
|
20
|
-
require_relative 'rtp-connect/
|
21
|
-
|
22
|
-
|
1
|
+
# Loads the files that are used by the RTPConnect library.
|
2
|
+
|
3
|
+
# Logging:
|
4
|
+
require_relative 'rtp-connect/logging'
|
5
|
+
# Super classes:
|
6
|
+
require_relative 'rtp-connect/record'
|
7
|
+
# Core library:
|
8
|
+
require_relative 'rtp-connect/plan'
|
9
|
+
require_relative 'rtp-connect/plan_to_dcm'
|
10
|
+
require_relative 'rtp-connect/prescription'
|
11
|
+
require_relative 'rtp-connect/site_setup'
|
12
|
+
require_relative 'rtp-connect/field'
|
13
|
+
require_relative 'rtp-connect/extended_field'
|
14
|
+
require_relative 'rtp-connect/control_point'
|
15
|
+
require_relative 'rtp-connect/dose_tracking'
|
16
|
+
# Extensions to the Ruby library:
|
17
|
+
require_relative 'rtp-connect/ruby_extensions'
|
18
|
+
# Module settings:
|
19
|
+
require_relative 'rtp-connect/version'
|
20
|
+
require_relative 'rtp-connect/constants'
|
21
|
+
require_relative 'rtp-connect/methods'
|
22
|
+
require_relative 'rtp-connect/variables'
|
23
|
+
|
24
|
+
# Load the CSV library:
|
23
25
|
require 'csv'
|
@@ -1,58 +1,58 @@
|
|
1
|
-
module RTP
|
2
|
-
|
3
|
-
# The seed value used in the RTPConnect implementation of the CCITT algorithm.
|
4
|
-
CRC_SEED = 0x0521
|
5
|
-
|
6
|
-
# The table & values used in the RTPConnect implementation of the CCITT algorithm.
|
7
|
-
CRC_TABLE = [
|
8
|
-
0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241,
|
9
|
-
0xC601, 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1, 0xC481, 0x0440,
|
10
|
-
0xCC01, 0x0CC0, 0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81, 0x0E40,
|
11
|
-
0x0A00, 0xCAC1, 0xCB81, 0x0B40, 0xC901, 0x09C0, 0x0880, 0xC841,
|
12
|
-
0xD801, 0x18C0, 0x1980, 0xD941, 0x1B00, 0xDBC1, 0xDA81, 0x1A40,
|
13
|
-
0x1E00, 0xDEC1, 0xDF81, 0x1F40, 0xDD01, 0x1DC0, 0x1C80, 0xDC41,
|
14
|
-
0x1400, 0xD4C1, 0xD581, 0x1540, 0xD701, 0x17C0, 0x1680, 0xD641,
|
15
|
-
0xD201, 0x12C0, 0x1380, 0xD341, 0x1100, 0xD1C1, 0xD081, 0x1040,
|
16
|
-
0xF001, 0x30C0, 0x3180, 0xF141, 0x3300, 0xF3C1, 0xF281, 0x3240,
|
17
|
-
0x3600, 0xF6C1, 0xF781, 0x3740, 0xF501, 0x35C0, 0x3480, 0xF441,
|
18
|
-
0x3C00, 0xFCC1, 0xFD81, 0x3D40, 0xFF01, 0x3FC0, 0x3E80, 0xFE41,
|
19
|
-
0xFA01, 0x3AC0, 0x3B80, 0xFB41, 0x3900, 0xF9C1, 0xF881, 0x3840,
|
20
|
-
0x2800, 0xE8C1, 0xE981, 0x2940, 0xEB01, 0x2BC0, 0x2A80, 0xEA41,
|
21
|
-
0xEE01, 0x2EC0, 0x2F80, 0xEF41, 0x2D00, 0xEDC1, 0xEC81, 0x2C40,
|
22
|
-
0xE401, 0x24C0, 0x2580, 0xE541, 0x2700, 0xE7C1, 0xE681, 0x2640,
|
23
|
-
0x2200, 0xE2C1, 0xE381, 0x2340, 0xE101, 0x21C0, 0x2080, 0xE041,
|
24
|
-
0xA001, 0x60C0, 0x6180, 0xA141, 0x6300, 0xA3C1, 0xA281, 0x6240,
|
25
|
-
0x6600, 0xA6C1, 0xA781, 0x6740, 0xA501, 0x65C0, 0x6480, 0xA441,
|
26
|
-
0x6C00, 0xACC1, 0xAD81, 0x6D40, 0xAF01, 0x6FC0, 0x6E80, 0xAE41,
|
27
|
-
0xAA01, 0x6AC0, 0x6B80, 0xAB41, 0x6900, 0xA9C1, 0xA881, 0x6840,
|
28
|
-
0x7800, 0xB8C1, 0xB981, 0x7940, 0xBB01, 0x7BC0, 0x7A80, 0xBA41,
|
29
|
-
0xBE01, 0x7EC0, 0x7F80, 0xBF41, 0x7D00, 0xBDC1, 0xBC81, 0x7C40,
|
30
|
-
0xB401, 0x74C0, 0x7580, 0xB541, 0x7700, 0xB7C1, 0xB681, 0x7640,
|
31
|
-
0x7200, 0xB2C1, 0xB381, 0x7340, 0xB101, 0x71C0, 0x7080, 0xB041,
|
32
|
-
0x5000, 0x90C1, 0x9181, 0x5140, 0x9301, 0x53C0, 0x5280, 0x9241,
|
33
|
-
0x9601, 0x56C0, 0x5780, 0x9741, 0x5500, 0x95C1, 0x9481, 0x5440,
|
34
|
-
0x9C01, 0x5CC0, 0x5D80, 0x9D41, 0x5F00, 0x9FC1, 0x9E81, 0x5E40,
|
35
|
-
0x5A00, 0x9AC1, 0x9B81, 0x5B40, 0x9901, 0x59C0, 0x5880, 0x9841,
|
36
|
-
0x8801, 0x48C0, 0x4980, 0x8941, 0x4B00, 0x8BC1, 0x8A81, 0x4A40,
|
37
|
-
0x4E00, 0x8EC1, 0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80, 0x8C41,
|
38
|
-
0x4400, 0x84C1, 0x8581, 0x4540, 0x8701, 0x47C0, 0x4680, 0x8641,
|
39
|
-
0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040
|
40
|
-
]
|
41
|
-
|
42
|
-
# Pairs of RTPConnect keywords and parse method names.
|
43
|
-
PARSE_METHOD = {
|
44
|
-
"PLAN_DEF" => :plan_definition,
|
45
|
-
"RX_DEF" => :prescription_site,
|
46
|
-
"SITE_SETUP_DEF" => :site_setup,
|
47
|
-
"SIM_DEF" => :simulation_field,
|
48
|
-
"FIELD_DEF" => :treatment_field,
|
49
|
-
"EXTENDED_FIELD_DEF" => :extended_treatment_field,
|
50
|
-
"PDF_FIELD_DEF" => :document_based_treatment_field,
|
51
|
-
"MLC_DEF" => :multileaf_collimator,
|
52
|
-
"CONTROL_PT_DEF" => :control_point,
|
53
|
-
"MLC_SHAPE_DEF" => :mlc_shape,
|
54
|
-
"DOSE_DEF" => :dose_tracking,
|
55
|
-
"DOSE_ACTION" => :dose_action,
|
56
|
-
}
|
57
|
-
|
1
|
+
module RTP
|
2
|
+
|
3
|
+
# The seed value used in the RTPConnect implementation of the CCITT algorithm.
|
4
|
+
CRC_SEED = 0x0521
|
5
|
+
|
6
|
+
# The table & values used in the RTPConnect implementation of the CCITT algorithm.
|
7
|
+
CRC_TABLE = [
|
8
|
+
0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241,
|
9
|
+
0xC601, 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1, 0xC481, 0x0440,
|
10
|
+
0xCC01, 0x0CC0, 0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81, 0x0E40,
|
11
|
+
0x0A00, 0xCAC1, 0xCB81, 0x0B40, 0xC901, 0x09C0, 0x0880, 0xC841,
|
12
|
+
0xD801, 0x18C0, 0x1980, 0xD941, 0x1B00, 0xDBC1, 0xDA81, 0x1A40,
|
13
|
+
0x1E00, 0xDEC1, 0xDF81, 0x1F40, 0xDD01, 0x1DC0, 0x1C80, 0xDC41,
|
14
|
+
0x1400, 0xD4C1, 0xD581, 0x1540, 0xD701, 0x17C0, 0x1680, 0xD641,
|
15
|
+
0xD201, 0x12C0, 0x1380, 0xD341, 0x1100, 0xD1C1, 0xD081, 0x1040,
|
16
|
+
0xF001, 0x30C0, 0x3180, 0xF141, 0x3300, 0xF3C1, 0xF281, 0x3240,
|
17
|
+
0x3600, 0xF6C1, 0xF781, 0x3740, 0xF501, 0x35C0, 0x3480, 0xF441,
|
18
|
+
0x3C00, 0xFCC1, 0xFD81, 0x3D40, 0xFF01, 0x3FC0, 0x3E80, 0xFE41,
|
19
|
+
0xFA01, 0x3AC0, 0x3B80, 0xFB41, 0x3900, 0xF9C1, 0xF881, 0x3840,
|
20
|
+
0x2800, 0xE8C1, 0xE981, 0x2940, 0xEB01, 0x2BC0, 0x2A80, 0xEA41,
|
21
|
+
0xEE01, 0x2EC0, 0x2F80, 0xEF41, 0x2D00, 0xEDC1, 0xEC81, 0x2C40,
|
22
|
+
0xE401, 0x24C0, 0x2580, 0xE541, 0x2700, 0xE7C1, 0xE681, 0x2640,
|
23
|
+
0x2200, 0xE2C1, 0xE381, 0x2340, 0xE101, 0x21C0, 0x2080, 0xE041,
|
24
|
+
0xA001, 0x60C0, 0x6180, 0xA141, 0x6300, 0xA3C1, 0xA281, 0x6240,
|
25
|
+
0x6600, 0xA6C1, 0xA781, 0x6740, 0xA501, 0x65C0, 0x6480, 0xA441,
|
26
|
+
0x6C00, 0xACC1, 0xAD81, 0x6D40, 0xAF01, 0x6FC0, 0x6E80, 0xAE41,
|
27
|
+
0xAA01, 0x6AC0, 0x6B80, 0xAB41, 0x6900, 0xA9C1, 0xA881, 0x6840,
|
28
|
+
0x7800, 0xB8C1, 0xB981, 0x7940, 0xBB01, 0x7BC0, 0x7A80, 0xBA41,
|
29
|
+
0xBE01, 0x7EC0, 0x7F80, 0xBF41, 0x7D00, 0xBDC1, 0xBC81, 0x7C40,
|
30
|
+
0xB401, 0x74C0, 0x7580, 0xB541, 0x7700, 0xB7C1, 0xB681, 0x7640,
|
31
|
+
0x7200, 0xB2C1, 0xB381, 0x7340, 0xB101, 0x71C0, 0x7080, 0xB041,
|
32
|
+
0x5000, 0x90C1, 0x9181, 0x5140, 0x9301, 0x53C0, 0x5280, 0x9241,
|
33
|
+
0x9601, 0x56C0, 0x5780, 0x9741, 0x5500, 0x95C1, 0x9481, 0x5440,
|
34
|
+
0x9C01, 0x5CC0, 0x5D80, 0x9D41, 0x5F00, 0x9FC1, 0x9E81, 0x5E40,
|
35
|
+
0x5A00, 0x9AC1, 0x9B81, 0x5B40, 0x9901, 0x59C0, 0x5880, 0x9841,
|
36
|
+
0x8801, 0x48C0, 0x4980, 0x8941, 0x4B00, 0x8BC1, 0x8A81, 0x4A40,
|
37
|
+
0x4E00, 0x8EC1, 0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80, 0x8C41,
|
38
|
+
0x4400, 0x84C1, 0x8581, 0x4540, 0x8701, 0x47C0, 0x4680, 0x8641,
|
39
|
+
0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040
|
40
|
+
]
|
41
|
+
|
42
|
+
# Pairs of RTPConnect keywords and parse method names.
|
43
|
+
PARSE_METHOD = {
|
44
|
+
"PLAN_DEF" => :plan_definition,
|
45
|
+
"RX_DEF" => :prescription_site,
|
46
|
+
"SITE_SETUP_DEF" => :site_setup,
|
47
|
+
"SIM_DEF" => :simulation_field,
|
48
|
+
"FIELD_DEF" => :treatment_field,
|
49
|
+
"EXTENDED_FIELD_DEF" => :extended_treatment_field,
|
50
|
+
"PDF_FIELD_DEF" => :document_based_treatment_field,
|
51
|
+
"MLC_DEF" => :multileaf_collimator,
|
52
|
+
"CONTROL_PT_DEF" => :control_point,
|
53
|
+
"MLC_SHAPE_DEF" => :mlc_shape,
|
54
|
+
"DOSE_DEF" => :dose_tracking,
|
55
|
+
"DOSE_ACTION" => :dose_action,
|
56
|
+
}
|
57
|
+
|
58
58
|
end
|
@@ -2,10 +2,9 @@ module RTP
|
|
2
2
|
|
3
3
|
# The ControlPoint class.
|
4
4
|
#
|
5
|
-
#
|
6
|
-
#
|
7
|
-
#
|
8
|
-
# * Children: MLCShape
|
5
|
+
# @note Relations:
|
6
|
+
# * Parent: Field
|
7
|
+
# * Children: none
|
9
8
|
#
|
10
9
|
class ControlPoint < Record
|
11
10
|
|
@@ -51,60 +50,58 @@ module RTP
|
|
51
50
|
|
52
51
|
# Creates a new ControlPoint by parsing a RTPConnect string line.
|
53
52
|
#
|
54
|
-
#
|
55
|
-
#
|
56
|
-
#
|
57
|
-
#
|
53
|
+
# @param [#to_s] string the control point definition record string line
|
54
|
+
# @param [Record] parent a record which is used to determine the proper parent of this instance
|
55
|
+
# @return [ControlPoint] the created ControlPoint instance
|
56
|
+
# @raise [ArgumentError] if given a string containing an invalid number of elements
|
58
57
|
#
|
59
58
|
def self.load(string, parent)
|
60
59
|
# Get the quote-less values:
|
61
60
|
values = string.to_s.values
|
62
61
|
raise ArgumentError, "Invalid argument 'string': Expected exactly 233 elements, got #{values.length}." unless values.length == 233
|
63
|
-
|
62
|
+
cp = self.new(parent)
|
64
63
|
# Assign the values to attributes:
|
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
|
-
return
|
64
|
+
cp.keyword = values[0]
|
65
|
+
cp.field_id = values[1]
|
66
|
+
cp.mlc_type = values[2]
|
67
|
+
cp.mlc_leaves = values[3]
|
68
|
+
cp.total_control_points = values[4]
|
69
|
+
cp.control_pt_number = values[5]
|
70
|
+
cp.mu_convention = values[6]
|
71
|
+
cp.monitor_units = values[7]
|
72
|
+
cp.wedge_position = values[8]
|
73
|
+
cp.energy = values[9]
|
74
|
+
cp.doserate = values[10]
|
75
|
+
cp.ssd = values[11]
|
76
|
+
cp.scale_convention = values[12]
|
77
|
+
cp.gantry_angle = values[13]
|
78
|
+
cp.gantry_dir = values[14]
|
79
|
+
cp.collimator_angle = values[15]
|
80
|
+
cp.collimator_dir = values[16]
|
81
|
+
cp.field_x_mode = values[17]
|
82
|
+
cp.field_x = values[18]
|
83
|
+
cp.collimator_x1 = values[19]
|
84
|
+
cp.collimator_x2 = values[20]
|
85
|
+
cp.field_y_mode = values[21]
|
86
|
+
cp.field_y = values[22]
|
87
|
+
cp.collimator_y1 = values[23]
|
88
|
+
cp.collimator_y2 = values[24]
|
89
|
+
cp.couch_vertical = values[25]
|
90
|
+
cp.couch_lateral = values[26]
|
91
|
+
cp.couch_longitudinal = values[27]
|
92
|
+
cp.couch_angle = values[28]
|
93
|
+
cp.couch_dir = values[29]
|
94
|
+
cp.couch_pedestal = values[30]
|
95
|
+
cp.couch_ped_dir = values[31]
|
96
|
+
cp.mlc_lp_a = [*values[32..131]]
|
97
|
+
cp.mlc_lp_b = [*values[132..231]]
|
98
|
+
cp.crc = values[232]
|
99
|
+
return cp
|
101
100
|
end
|
102
101
|
|
103
102
|
# Creates a new ControlPoint.
|
104
103
|
#
|
105
|
-
#
|
106
|
-
#
|
107
|
-
# * <tt>parent</tt> -- A Record which is used to determine the proper parent of this instance.
|
104
|
+
# @param [Record] parent a record which is used to determine the proper parent of this instance
|
108
105
|
#
|
109
106
|
def initialize(parent)
|
110
107
|
# Child:
|
@@ -117,7 +114,13 @@ module RTP
|
|
117
114
|
@mlc_lp_b = Array.new(100)
|
118
115
|
end
|
119
116
|
|
120
|
-
#
|
117
|
+
# Checks for equality.
|
118
|
+
#
|
119
|
+
# Other and self are considered equivalent if they are
|
120
|
+
# of compatible types and their attributes are equivalent.
|
121
|
+
#
|
122
|
+
# @param other an object to be compared with self.
|
123
|
+
# @return [Boolean] true if self and other are considered equivalent
|
121
124
|
#
|
122
125
|
def ==(other)
|
123
126
|
if other.respond_to?(:to_control_point)
|
@@ -127,23 +130,39 @@ module RTP
|
|
127
130
|
|
128
131
|
alias_method :eql?, :==
|
129
132
|
|
130
|
-
# As of now,
|
131
|
-
#
|
132
|
-
#
|
133
|
+
# As of now, gives an empty array. However, by definition, this record may
|
134
|
+
# have an mlc shape record as child, but this is not implemented yet.
|
135
|
+
#
|
136
|
+
# @return [Array] an emtpy array
|
133
137
|
#
|
134
138
|
def children
|
135
139
|
#return [@mlc_shape]
|
136
140
|
return Array.new
|
137
141
|
end
|
138
142
|
|
139
|
-
#
|
143
|
+
# Computes a hash code for this object.
|
144
|
+
#
|
145
|
+
# @note Two objects with the same attributes will have the same hash code.
|
146
|
+
#
|
147
|
+
# @return [Fixnum] the object's hash code
|
140
148
|
#
|
141
149
|
def hash
|
142
150
|
state.hash
|
143
151
|
end
|
144
152
|
|
145
|
-
#
|
146
|
-
#
|
153
|
+
# Gives the index of this ControlPoint
|
154
|
+
# (i.e. its index among the control points belonging to the parent Field).
|
155
|
+
#
|
156
|
+
# @return [Fixnum] the control point's index
|
157
|
+
#
|
158
|
+
def index
|
159
|
+
@parent.control_points.index(self)
|
160
|
+
end
|
161
|
+
|
162
|
+
# Collects the values (attributes) of this instance.
|
163
|
+
#
|
164
|
+
# @note The CRC is not considered part of the actual values and is excluded.
|
165
|
+
# @return [Array<String>] an array of attributes (in the same order as they appear in the RTP string)
|
147
166
|
#
|
148
167
|
def values
|
149
168
|
return [
|
@@ -186,13 +205,17 @@ module RTP
|
|
186
205
|
|
187
206
|
# Returns self.
|
188
207
|
#
|
208
|
+
# @return [ControlPoint] self
|
209
|
+
#
|
189
210
|
def to_control_point
|
190
211
|
self
|
191
212
|
end
|
192
213
|
|
193
|
-
#
|
214
|
+
# Encodes the ControlPoint object + any hiearchy of child objects,
|
194
215
|
# to a properly formatted RTPConnect ascii string.
|
195
216
|
#
|
217
|
+
# @return [String] an RTP string with a single or multiple lines/records
|
218
|
+
#
|
196
219
|
def to_s
|
197
220
|
str = encode
|
198
221
|
if children
|
@@ -205,34 +228,36 @@ module RTP
|
|
205
228
|
|
206
229
|
alias :to_str :to_s
|
207
230
|
|
208
|
-
# Sets the
|
209
|
-
#
|
210
|
-
# === Notes
|
231
|
+
# Sets the mlc_lp_a attribute.
|
211
232
|
#
|
212
|
-
# As opposed to the ordinary (string) attributes, this attribute
|
213
|
-
#
|
233
|
+
# @note As opposed to the ordinary (string) attributes, this attribute
|
234
|
+
# contains an array holding all 100 MLC leaf 'A' string values.
|
235
|
+
# @param [Array<nil, #to_s>] array the new attribute values
|
214
236
|
#
|
215
237
|
def mlc_lp_a=(array)
|
216
238
|
array = array.to_a
|
217
239
|
raise ArgumentError, "Invalid argument 'array'. Expected length 100, got #{array.length}." unless array.length == 100
|
218
|
-
@mlc_lp_a = array.collect! {|e| e && e.to_s}
|
240
|
+
@mlc_lp_a = array.collect! {|e| e && e.to_s.strip}
|
219
241
|
end
|
220
242
|
|
221
|
-
# Sets the
|
243
|
+
# Sets the mlc_lp_b attribute.
|
222
244
|
#
|
223
|
-
#
|
224
|
-
#
|
225
|
-
#
|
226
|
-
# contains an array holding all 100 MLC leaf 'A' string values.
|
245
|
+
# @note As opposed to the ordinary (string) attributes, this attribute
|
246
|
+
# contains an array holding all 100 MLC leaf 'B' string values.
|
247
|
+
# @param [Array<nil, #to_s>] array the new attribute values
|
227
248
|
#
|
228
249
|
def mlc_lp_b=(array)
|
229
250
|
array = array.to_a
|
230
251
|
raise ArgumentError, "Invalid argument 'array'. Expected length 100, got #{array.length}." unless array.length == 100
|
231
|
-
@mlc_lp_b = array.collect! {|e| e && e.to_s}
|
252
|
+
@mlc_lp_b = array.collect! {|e| e && e.to_s.strip}
|
232
253
|
end
|
233
254
|
|
234
255
|
# Sets the keyword attribute.
|
235
256
|
#
|
257
|
+
# @note Since only a specific string is accepted, this is more of an argument check than a traditional setter method
|
258
|
+
# @param [#to_s] value the new attribute value
|
259
|
+
# @raise [ArgumentError] if given an unexpected keyword
|
260
|
+
#
|
236
261
|
def keyword=(value)
|
237
262
|
value = value.to_s.upcase
|
238
263
|
raise ArgumentError, "Invalid keyword. Expected 'CONTROL_PT_DEF', got #{value}." unless value == "CONTROL_PT_DEF"
|
@@ -241,186 +266,248 @@ module RTP
|
|
241
266
|
|
242
267
|
# Sets the field_id attribute.
|
243
268
|
#
|
269
|
+
# @param [nil, #to_s] value the new attribute value
|
270
|
+
#
|
244
271
|
def field_id=(value)
|
245
272
|
@field_id = value && value.to_s
|
246
273
|
end
|
247
274
|
|
248
275
|
# Sets the mlc_type attribute.
|
249
276
|
#
|
277
|
+
# @param [nil, #to_s] value the new attribute value
|
278
|
+
#
|
250
279
|
def mlc_type=(value)
|
251
280
|
@mlc_type = value && value.to_s
|
252
281
|
end
|
253
282
|
|
254
283
|
# Sets the mlc_leaves attribute.
|
255
284
|
#
|
285
|
+
# @param [nil, #to_s] value the new attribute value
|
286
|
+
#
|
256
287
|
def mlc_leaves=(value)
|
257
|
-
@mlc_leaves = value && value.to_s
|
288
|
+
@mlc_leaves = value && value.to_s.strip
|
258
289
|
end
|
259
290
|
|
260
291
|
# Sets the total_control_points attribute.
|
261
292
|
#
|
293
|
+
# @param [nil, #to_s] value the new attribute value
|
294
|
+
#
|
262
295
|
def total_control_points=(value)
|
263
|
-
@total_control_points = value && value.to_s
|
296
|
+
@total_control_points = value && value.to_s.strip
|
264
297
|
end
|
265
298
|
|
266
299
|
# Sets the control_pt_number attribute.
|
267
300
|
#
|
301
|
+
# @param [nil, #to_s] value the new attribute value
|
302
|
+
#
|
268
303
|
def control_pt_number=(value)
|
269
|
-
@control_pt_number = value && value.to_s
|
304
|
+
@control_pt_number = value && value.to_s.strip
|
270
305
|
end
|
271
306
|
|
272
307
|
# Sets the mu_convention attribute.
|
273
308
|
#
|
309
|
+
# @param [nil, #to_s] value the new attribute value
|
310
|
+
#
|
274
311
|
def mu_convention=(value)
|
275
312
|
@mu_convention = value && value.to_s
|
276
313
|
end
|
277
314
|
|
278
315
|
# Sets the monitor_units attribute.
|
279
316
|
#
|
317
|
+
# @param [nil, #to_s] value the new attribute value
|
318
|
+
#
|
280
319
|
def monitor_units=(value)
|
281
320
|
@monitor_units = value && value.to_s
|
282
321
|
end
|
283
322
|
|
284
323
|
# Sets the wedge_position attribute.
|
285
324
|
#
|
325
|
+
# @param [nil, #to_s] value the new attribute value
|
326
|
+
#
|
286
327
|
def wedge_position=(value)
|
287
328
|
@wedge_position = value && value.to_s
|
288
329
|
end
|
289
330
|
|
290
331
|
# Sets the energy attribute.
|
291
332
|
#
|
333
|
+
# @param [nil, #to_s] value the new attribute value
|
334
|
+
#
|
292
335
|
def energy=(value)
|
293
336
|
@energy = value && value.to_s
|
294
337
|
end
|
295
338
|
|
296
339
|
# Sets the doserate attribute.
|
297
340
|
#
|
341
|
+
# @param [nil, #to_s] value the new attribute value
|
342
|
+
#
|
298
343
|
def doserate=(value)
|
299
|
-
@doserate = value && value.to_s
|
344
|
+
@doserate = value && value.to_s.strip
|
300
345
|
end
|
301
346
|
|
302
347
|
# Sets the ssd attribute.
|
303
348
|
#
|
349
|
+
# @param [nil, #to_s] value the new attribute value
|
350
|
+
#
|
304
351
|
def ssd=(value)
|
305
352
|
@ssd = value && value.to_s
|
306
353
|
end
|
307
354
|
|
308
355
|
# Sets the scale_convention attribute.
|
309
356
|
#
|
357
|
+
# @param [nil, #to_s] value the new attribute value
|
358
|
+
#
|
310
359
|
def scale_convention=(value)
|
311
360
|
@scale_convention = value && value.to_s
|
312
361
|
end
|
313
362
|
|
314
363
|
# Sets the gantry_angle attribute.
|
315
364
|
#
|
365
|
+
# @param [nil, #to_s] value the new attribute value
|
366
|
+
#
|
316
367
|
def gantry_angle=(value)
|
317
|
-
@gantry_angle = value && value.to_s
|
368
|
+
@gantry_angle = value && value.to_s.strip
|
318
369
|
end
|
319
370
|
|
320
371
|
# Sets the gantry_dir attribute.
|
321
372
|
#
|
373
|
+
# @param [nil, #to_s] value the new attribute value
|
374
|
+
#
|
322
375
|
def gantry_dir=(value)
|
323
376
|
@gantry_dir = value && value.to_s
|
324
377
|
end
|
325
378
|
|
326
379
|
# Sets the collimator_angle attribute.
|
327
380
|
#
|
381
|
+
# @param [nil, #to_s] value the new attribute value
|
382
|
+
#
|
328
383
|
def collimator_angle=(value)
|
329
|
-
@collimator_angle = value && value.to_s
|
384
|
+
@collimator_angle = value && value.to_s.strip
|
330
385
|
end
|
331
386
|
|
332
387
|
# Sets the collimator_dir attribute.
|
333
388
|
#
|
389
|
+
# @param [nil, #to_s] value the new attribute value
|
390
|
+
#
|
334
391
|
def collimator_dir=(value)
|
335
392
|
@collimator_dir = value && value.to_s
|
336
393
|
end
|
337
394
|
|
338
395
|
# Sets the field_x_mode attribute.
|
339
396
|
#
|
397
|
+
# @param [nil, #to_s] value the new attribute value
|
398
|
+
#
|
340
399
|
def field_x_mode=(value)
|
341
400
|
@field_x_mode = value && value.to_s
|
342
401
|
end
|
343
402
|
|
344
403
|
# Sets the field_x attribute.
|
345
404
|
#
|
405
|
+
# @param [nil, #to_s] value the new attribute value
|
406
|
+
#
|
346
407
|
def field_x=(value)
|
347
|
-
@field_x = value && value.to_s
|
408
|
+
@field_x = value && value.to_s.strip
|
348
409
|
end
|
349
410
|
|
350
411
|
# Sets the collimator_x1 attribute.
|
351
412
|
#
|
413
|
+
# @param [nil, #to_s] value the new attribute value
|
414
|
+
#
|
352
415
|
def collimator_x1=(value)
|
353
|
-
@collimator_x1 = value && value.to_s
|
416
|
+
@collimator_x1 = value && value.to_s.strip
|
354
417
|
end
|
355
418
|
|
356
419
|
# Sets the collimator_x2 attribute.
|
357
420
|
#
|
421
|
+
# @param [nil, #to_s] value the new attribute value
|
422
|
+
#
|
358
423
|
def collimator_x2=(value)
|
359
|
-
@collimator_x2 = value && value.to_s
|
424
|
+
@collimator_x2 = value && value.to_s.strip
|
360
425
|
end
|
361
426
|
|
362
427
|
# Sets the field_y_mode attribute.
|
363
428
|
#
|
429
|
+
# @param [nil, #to_s] value the new attribute value
|
430
|
+
#
|
364
431
|
def field_y_mode=(value)
|
365
432
|
@field_y_mode = value && value.to_s
|
366
433
|
end
|
367
434
|
|
368
435
|
# Sets the field_y attribute.
|
369
436
|
#
|
437
|
+
# @param [nil, #to_s] value the new attribute value
|
438
|
+
#
|
370
439
|
def field_y=(value)
|
371
|
-
@field_y = value && value.to_s
|
440
|
+
@field_y = value && value.to_s.strip
|
372
441
|
end
|
373
442
|
|
374
443
|
# Sets the collimator_y1 attribute.
|
375
444
|
#
|
445
|
+
# @param [nil, #to_s] value the new attribute value
|
446
|
+
#
|
376
447
|
def collimator_y1=(value)
|
377
|
-
@collimator_y1 = value && value.to_s
|
448
|
+
@collimator_y1 = value && value.to_s.strip
|
378
449
|
end
|
379
450
|
|
380
451
|
# Sets the collimator_y2 attribute.
|
381
452
|
#
|
453
|
+
# @param [nil, #to_s] value the new attribute value
|
454
|
+
#
|
382
455
|
def collimator_y2=(value)
|
383
|
-
@collimator_y2 = value && value.to_s
|
456
|
+
@collimator_y2 = value && value.to_s.strip
|
384
457
|
end
|
385
458
|
|
386
459
|
# Sets the couch_vertical attribute.
|
387
460
|
#
|
461
|
+
# @param [nil, #to_s] value the new attribute value
|
462
|
+
#
|
388
463
|
def couch_vertical=(value)
|
389
|
-
@couch_vertical = value && value.to_s
|
464
|
+
@couch_vertical = value && value.to_s.strip
|
390
465
|
end
|
391
466
|
|
392
467
|
# Sets the couch_lateral attribute.
|
393
468
|
#
|
469
|
+
# @param [nil, #to_s] value the new attribute value
|
470
|
+
#
|
394
471
|
def couch_lateral=(value)
|
395
|
-
@couch_lateral = value && value.to_s
|
472
|
+
@couch_lateral = value && value.to_s.strip
|
396
473
|
end
|
397
474
|
|
398
475
|
# Sets the couch_longitudinal attribute.
|
399
476
|
#
|
477
|
+
# @param [nil, #to_s] value the new attribute value
|
478
|
+
#
|
400
479
|
def couch_longitudinal=(value)
|
401
|
-
@couch_longitudinal = value && value.to_s
|
480
|
+
@couch_longitudinal = value && value.to_s.strip
|
402
481
|
end
|
403
482
|
|
404
483
|
# Sets the couch_angle attribute.
|
405
484
|
#
|
485
|
+
# @param [nil, #to_s] value the new attribute value
|
486
|
+
#
|
406
487
|
def couch_angle=(value)
|
407
|
-
@couch_angle = value && value.to_s
|
488
|
+
@couch_angle = value && value.to_s.strip
|
408
489
|
end
|
409
490
|
|
410
491
|
# Sets the couch_dir attribute.
|
411
492
|
#
|
493
|
+
# @param [nil, #to_s] value the new attribute value
|
494
|
+
#
|
412
495
|
def couch_dir=(value)
|
413
496
|
@couch_dir = value && value.to_s
|
414
497
|
end
|
415
498
|
|
416
499
|
# Sets the couch_pedestal attribute.
|
417
500
|
#
|
501
|
+
# @param [nil, #to_s] value the new attribute value
|
502
|
+
#
|
418
503
|
def couch_pedestal=(value)
|
419
|
-
@couch_pedestal = value && value.to_s
|
504
|
+
@couch_pedestal = value && value.to_s.strip
|
420
505
|
end
|
421
506
|
|
422
507
|
# Sets the couch_ped_dir attribute.
|
423
508
|
#
|
509
|
+
# @param [nil, #to_s] value the new attribute value
|
510
|
+
#
|
424
511
|
def couch_ped_dir=(value)
|
425
512
|
@couch_ped_dir = value && value.to_s
|
426
513
|
end
|
@@ -429,7 +516,10 @@ module RTP
|
|
429
516
|
private
|
430
517
|
|
431
518
|
|
432
|
-
#
|
519
|
+
# Collects the attributes of this instance.
|
520
|
+
#
|
521
|
+
# @note The CRC is not considered part of the attributes of interest and is excluded
|
522
|
+
# @return [Array<String>] an array of attributes
|
433
523
|
#
|
434
524
|
alias_method :state, :values
|
435
525
|
|