Package glue :: Package segmentdb :: Module logic
[hide private]
[frames] | no frames]

Source Code for Module glue.segmentdb.logic

  1  # 
  2  # Copyright (C) 2009  Larne Pekowsky 
  3  # 
  4  # This program is free software; you can redistribute it and/or modify it 
  5  # under the terms of the GNU General Public License as published by the 
  6  # Free Software Foundation; either version 3 of the License, or (at your 
  7  # option) any later version. 
  8  # 
  9  # This program is distributed in the hope that it will be useful, but 
 10  # WITHOUT ANY WARRANTY; without even the implied warranty of 
 11  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General 
 12  # Public License for more details. 
 13  # 
 14  # You should have received a copy of the GNU General Public License along 
 15  # with this program; if not, write to the Free Software Foundation, Inc., 
 16  # 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA. 
 17   
 18   
 19  # 
 20  # ============================================================================= 
 21  # 
 22  #                                   Preamble 
 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  # "enum" indicating operation 
 56  INTERSECT = 'intersect' 
 57  UNION     = 'union' 
 58  DIFF      = 'diff' 
 59   
 60   
 61   
62 -def run_file_operation(outdoc, filenames, use_segment_table, operation, preserve = True):
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 # load up the files into individual documents 77 xmldocs = [ligolw_add.ligolw_add(ligolw.Document(), [fname]) for fname in filenames] 78 79 80 # Get the list of dinstinct segment_definers across all docs 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 # For each unique segment definer, find the intersection 93 for ifo, name, version in segment_definers: 94 if operation == INTERSECT: 95 # If I were feeling especially functional-ist I'd write this 96 # with reduce() 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 # Add a segment definer for the result 115 seg_def_id = add_to_segment_definer(outdoc, proc_id, ifo, name, version) 116 117 # Add the segments 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 # If we're preserving, also load up everything into the output document. 124 if preserve: 125 # Add them to the output document 126 list(map(lambda x: outdoc.appendChild(x.childNodes[0]), xmldocs)) 127 128 # Merge the ligolw elements and tables 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 # Start with a segment covering all of time, then 157 # intersect with each of the fields of interest 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 # Add a segment definer and segments 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