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 Utility methods for doing logical operations on sets of segments
30 """
31
32
33 import sys
34 import os
35
36 import glue.segments
37
38 from glue.ligolw import ligolw
39 from glue.ligolw import table
40 from glue.ligolw import lsctables
41
42 from glue.ligolw.utils import ligolw_add
43
44 from glue.segmentdb.segmentdb_utils import add_to_segment_definer
45 from glue.segmentdb.segmentdb_utils import add_to_segment
46 from glue.segmentdb.segmentdb_utils import add_to_segment_summary
47 from glue.segmentdb.segmentdb_utils import find_segments
48
49 from glue import git_version
50 __date__ = git_version.date
51 __version__ = git_version.id
52 __author__ = "Larne Pekowsky <lppekows@physics.syr.edu>"
53
54
55
56 INTERSECT = 'intersect'
57 UNION = 'union'
58 DIFF = 'diff'
59
60
61
63 """
64 Performs an operation (intersect or union) across a set of files.
65 That is, given a set of files each with segment definers DMT-FLAG1,
66 DMT-FLAG2 etc the result is a file where
67
68 DMT-FLAG1 = (file 1's DMT-FLAG1 operation file 2's DMT-FLAG1 operation ...)
69 DMT-FLAG2 = (file 1's DMT-FLAG2 operation file 2's DMT-FLAG2 operation ...)
70
71 etc
72 """
73
74 proc_id = lsctables.ProcessTable.get_table(outdoc)[0].process_id
75
76
77 xmldocs = [ligolw_add.ligolw_add(ligolw.Document(), [fname]) for fname in filenames]
78
79
80
81 segment_definers = {}
82
83 def register_definer(seg_def):
84 key = (seg_def.ifos, seg_def.name, seg_def.version)
85 segment_definers[key] = True
86 return key
87
88 for xmldoc in xmldocs:
89 seg_def_table = lsctables.SegmentDefTable.get_table(xmldoc)
90 list(map (register_definer, seg_def_table))
91
92
93 for ifo, name, version in segment_definers:
94 if operation == INTERSECT:
95
96
97 result = glue.segments.segmentlist([glue.segments.segment(-glue.segments.infinity(), glue.segments.infinity())])
98 for xmldoc in xmldocs:
99 result &= find_segments(xmldoc, '%s:%s:%d' % (ifo, name, version), use_segment_table)
100 elif operation == UNION:
101 result = glue.segments.segmentlist([])
102
103 for xmldoc in xmldocs:
104 result |= find_segments(xmldoc, '%s:%s:%d' % (ifo, name, version), use_segment_table)
105 elif operation == DIFF:
106 result = find_segments(xmldocs[0], '%s:%s:%d' % (ifo, name, version), use_segment_table)
107
108 for xmldoc in xmldocs[1:]:
109 result -= find_segments(xmldoc, '%s:%s:%d' % (ifo, name, version), use_segment_table)
110 else:
111 raise NameError ("%s is not a known operation (intersect, union or diff)" % operation)
112
113
114
115 seg_def_id = add_to_segment_definer(outdoc, proc_id, ifo, name, version)
116
117
118 if use_segment_table:
119 add_to_segment(outdoc, proc_id, seg_def_id, result)
120 else:
121 add_to_segment_summary(outdoc, proc_id, seg_def_id, result)
122
123
124 if preserve:
125
126 list(map(lambda x: outdoc.appendChild(x.childNodes[0]), xmldocs))
127
128
129 ligolw_add.merge_ligolws(outdoc)
130 ligolw_add.merge_compatible_tables(outdoc)
131
132 return outdoc, abs(result)
133
134
135
136 -def run_segment_operation(outdoc, filenames, segments, use_segment_table, operation, result_name = 'RESULT', preserve = True):
137 """
138 Performs an operation (intersect or union) across a set of segments.
139 That is, given a set of files each with segment definers DMT-FLAG1,
140 DMT-FLAG2 etc and a list of segments DMT-FLAG1,DMT-FLAG1 this returns
141
142 RESULT = (table 1's DMT-FLAG1 union table 2's DMT-FLAG1 union ...)
143 operation
144 (table 1's DMT-FLAG2 union table 2's DMT-FLAG2 union ...)
145 operation
146 etc
147 """
148
149 proc_id = lsctables.ProcessTable.get_table(outdoc)[0].process_id
150
151 if preserve:
152 indoc = ligolw_add.ligolw_add(outdoc, filenames)
153 else:
154 indoc = ligolw_add.ligolw_add(ligolw.Document(), filenames)
155
156
157
158 keys = segments.split(',')
159
160 if operation == INTERSECT:
161 sgmntlist = glue.segments.segmentlist([glue.segments.segment(-glue.segments.infinity(), glue.segments.infinity())])
162
163 for key in keys:
164 sgmntlist &= find_segments(indoc, key, use_segment_table)
165
166 elif operation == UNION:
167 sgmntlist = glue.segments.segmentlist([])
168
169 for key in keys:
170 sgmntlist |= find_segments(indoc, key, use_segment_table)
171 elif operation == DIFF:
172 sgmntlist = find_segments(indoc, keys[0], use_segment_table)
173
174 for key in keys[1:]:
175 sgmntlist -= find_segments(indoc, key, use_segment_table)
176 else:
177 raise NameError("%s is not a known operation (intersect, union or diff)" % operation)
178
179
180
181 seg_def_id = add_to_segment_definer(outdoc, proc_id, '', result_name, 1)
182
183 if use_segment_table:
184 add_to_segment(outdoc, proc_id, seg_def_id, sgmntlist)
185 else:
186 add_to_segment_summary(outdoc, proc_id, seg_def_id, sgmntlist)
187
188 return outdoc, abs(sgmntlist)
189