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