Beispiel #1
0
 def __call__(self, *args, **kwargs):
     """Check that all arguments are present
        and load all tracks that are given as paths
        instead of track objects. Also checks for
        direct calls with generators."""
     # Initialization #
     generator_call   = False # Special switch for direct generator calls
     found_args       = {}    # Will contain a set of parameters extracted
     found_tracks     = {}    # Will contain a set of track parameters extracted
     found_generators = {}    # Will contain a set of FeatureStream
     extra_args       = {}    # Will contain a set of parameters computed
     all_tracks       = []    # Will contain all single tracks sent
     tracks_to_close  = []    # Will contain single tracks to close
     virtual_tracks   = []    # Will contain the results tracks
     rest_of_fields   = []    # Will contain variable output fields when required
     ### Parse arguments ###
     for p in self.input_args:
         if p['key'] in kwargs: value = kwargs[p['key']]
         elif len(args) >= p['position']: value = args[p['position']-1]
         elif 'default' in p: value = p['default']
         elif p.get('optional'): continue
         else: raise Exception("The argument '%s' is missing for the manipulation '%s'." \
                               % (p['key'], self.short_name))
         # Cast it if it's not the right type #
         if not isinstance(value, p['type']): value = p['type'](value)
         # Add it to the dict #
         found_args[p['key']] = value
     ### Parse tracks ###
     for t in self.input_tracks:
         if t['key'] in kwargs: value = kwargs[t['key']]
         elif len(args) >= t['position']: value = args[t['position']-1]
         elif 'default' in t: value = t['default']
         elif t.get('optional'): continue
         else: raise Exception("The argument '%s' is missing for the manipulation '%s'." \
                               % (t['key'], self.short_name))
         # Check is track collection #
         if t.get('kind') == 'many':
             if not is_list(value):
                 message = "The track collection '%s' for the manipulation '%s' is not a list: %s"
                 raise Exception(message % (t['key'], self.short_name, value))
         # Don't modify the input list #
         if t.get('kind') == 'many': value = value[:]
         # Check for generator case #
         if is_gen(value): generator_call = True
         if t.get('kind') == 'many' and is_gen(value[0]): generator_call = True
         if generator_call:
             found_tracks[t['key']] = value
             continue
         # Check is path #
         if isinstance(value, basestring):
             value = track.load(value, readonly=True)
             tracks_to_close.append(value)
         if t.get('kind') == 'many':
             for i,_ in enumerate(value):
                 if isinstance(value[i], basestring):
                     value[i] = track.load(value[i], readonly=True)
                     tracks_to_close.append(value[i])
         # Add to the list of all tracks #
         if t.get('kind') == 'many': all_tracks += [x for x in value]
         else:                       all_tracks += [value]
         # Track collection must be combined #
         if t.get('kind') == 'many':
             value = TrackCollection(value, self.fields_collapse, self.chroms_collapse)
         # Variable fields case (track collection must collapse fields) #
         if t['fields'][-1] == '...':
             first_fields = t['fields'][:-1]
             rest_of_fields = [f for f in value.fields if f not in first_fields]
             value.fields = first_fields + rest_of_fields
         # Specific fields case #
         else: value.fields = t['fields']
         # What about track SimpleTrack case #
         pass #TODO
         # Add it to the dict #
         found_tracks[t['key']] = value
     # Check for generator case #
     if generator_call: return self.from_generator(found_tracks, found_args, args, kwargs)
     # Collapse chromosomes #
     if not self.chroms_collapse: chromosomes = all_tracks[0].chromosomes
     else: chromosomes = collapse(self.chroms_collapse, [t.chromosomes for t in all_tracks])
     # Multiple output tracks disabled #
     t = self.output_tracks[0]
     # Make a new virtual track #
     vtrack = VirtualTrack()
     # Output chromosome metadata #
     for chrom in chromosomes:
         vtrack.chrmeta[chrom] = {'length': max([i.chrmeta[chrom]['length'] for i in all_tracks])}
     # Output attributes #
     if t.get('datatype'): vtrack.datatype = t['datatype']
     # Output name #
     vtrack.name = self.long_name + ' on ' + andify_strings([i.name for i in all_tracks])
     ### Iterate on chromosomes ###
     for chrom in chromosomes:
         # Get special input arguments #
         for p in self.input_meta:
             if p['kind'] == 'chrom_len':
                 extra_args[p['key']] = vtrack.chrmeta[chrom]['length']
         # Call read on tracks #
         for k,input_track in found_tracks.items():
             if is_list(input_track): found_generators[k] = [i.read(chrom) for i in input_track]
             else:                    found_generators[k] = input_track.read(chrom)
         # What about track collapse and recursion #
         pass #TODO
         # Final argument list #
         final_args = {}
         for d in (found_args, found_generators, extra_args): final_args.update(d)
         # Call generate #
         data = self.generate(**final_args)
         # Variable fields case #
         if t['fields'][-1] == '...': fields = t['fields'][:-1] + rest_of_fields
         else:                        fields = t['fields']
         # Make a FeatureStream #
         stream = FeatureStream(data, fields)
         # Add it to the virtual track #
         vtrack.write(chrom, stream)
     # Close tracks later #
     vtrack.tracks_to_close = tracks_to_close
     # Add it #
     virtual_tracks.append(vtrack)
     # Return one virutal track or list of virtual tracks #
     return len(virtual_tracks) == 1 and virtual_tracks[0] or virtual_tracks
Beispiel #2
0
 def fields(self):
     return collapse(self.fields_collapse, [t.fields for t in self.tracks])
Beispiel #3
0
 def chromosomes(self):
     if not hasattr(self.tracks[0], "chromosomes"): return []
     chroms = collapse(self.chroms_collapse, [t.chromosomes for t in self.tracks])
     chroms.sort(key=natural_sort)
     return chroms
Beispiel #4
0
 def __call__(self, *args, **kwargs):
     """Check that all arguments are present
        and load all tracks that are given as paths
        instead of track objects. Also checks for
        direct calls with generators."""
     # Initialization #
     generator_call = False  # Special switch for direct generator calls
     found_args = {}  # Will contain a set of parameters extracted
     found_tracks = {}  # Will contain a set of track parameters extracted
     found_generators = {}  # Will contain a set of FeatureStream
     extra_args = {}  # Will contain a set of parameters computed
     all_tracks = []  # Will contain all single tracks sent
     tracks_to_close = []  # Will contain single tracks to close
     virtual_tracks = []  # Will contain the results tracks
     rest_of_fields = [
     ]  # Will contain variable output fields when required
     ### Parse arguments ###
     for p in self.input_args:
         if p['key'] in kwargs: value = kwargs[p['key']]
         elif len(args) >= p['position']: value = args[p['position'] - 1]
         elif 'default' in p: value = p['default']
         elif p.get('optional'): continue
         else:                raise Exception("The argument '%s' is missing for the manipulation '%s'." \
                             % (p['key'], self.short_name))
         # Cast it if it's not the right type #
         if not isinstance(value, p['type']): value = p['type'](value)
         # Add it to the dict #
         found_args[p['key']] = value
     ### Parse tracks ###
     for t in self.input_tracks:
         if t['key'] in kwargs: value = kwargs[t['key']]
         elif len(args) >= t['position']: value = args[t['position'] - 1]
         elif 'default' in t: value = t['default']
         elif t.get('optional'): continue
         else:                raise Exception("The argument '%s' is missing for the manipulation '%s'." \
                             % (t['key'], self.short_name))
         # Check is track collection #
         if t.get('kind') == 'many':
             if not is_list(value):
                 message = "The track collection '%s' for the manipulation '%s' is not a list: %s"
                 raise Exception(message %
                                 (t['key'], self.short_name, value))
         # Don't modify the input list #
         if t.get('kind') == 'many': value = value[:]
         # Check for generator case #
         if is_gen(value): generator_call = True
         if t.get('kind') == 'many' and is_gen(value[0]):
             generator_call = True
         if generator_call:
             found_tracks[t['key']] = value
             continue
         # Check is path #
         if isinstance(value, basestring):
             value = track.load(value, readonly=True)
             tracks_to_close.append(value)
         if t.get('kind') == 'many':
             for i, _ in enumerate(value):
                 if isinstance(value[i], basestring):
                     value[i] = track.load(value[i], readonly=True)
                     tracks_to_close.append(value[i])
         # Add to the list of all tracks #
         if t.get('kind') == 'many': all_tracks += [x for x in value]
         else: all_tracks += [value]
         # Track collection must be combined #
         if t.get('kind') == 'many':
             value = TrackCollection(value, self.fields_collapse,
                                     self.chroms_collapse)
         # Variable fields case (track collection must collapse fields) #
         if t['fields'][-1] == '...':
             first_fields = t['fields'][:-1]
             rest_of_fields = [
                 f for f in value.fields if f not in first_fields
             ]
             value.fields = first_fields + rest_of_fields
         # Specific fields case #
         else:
             value.fields = t['fields']
         # What about track SimpleTrack case #
         pass  #TODO
         # Add it to the dict #
         found_tracks[t['key']] = value
     # Check for generator case #
     if generator_call:
         return self.from_generator(found_tracks, found_args, args, kwargs)
     # Collapse chromosomes #
     if not self.chroms_collapse: chromosomes = all_tracks[0].chromosomes
     else:
         chromosomes = collapse(self.chroms_collapse,
                                [t.chromosomes for t in all_tracks])
     # Multiple output tracks disabled #
     t = self.output_tracks[0]
     # Make a new virtual track #
     vtrack = VirtualTrack()
     # Output chromosome metadata #
     for chrom in chromosomes:
         vtrack.chrmeta[chrom] = {
             'length': max([i.chrmeta[chrom]['length'] for i in all_tracks])
         }
     # Output attributes #
     if t.get('datatype'): vtrack.datatype = t['datatype']
     # Output name #
     vtrack.name = self.long_name + ' on ' + andify_strings(
         [i.name for i in all_tracks])
     ### Iterate on chromosomes ###
     for chrom in chromosomes:
         # Get special input arguments #
         for p in self.input_meta:
             if p['kind'] == 'chrom_len':
                 extra_args[p['key']] = vtrack.chrmeta[chrom]['length']
         # Call read on tracks #
         for k, input_track in found_tracks.items():
             if is_list(input_track):
                 found_generators[k] = [i.read(chrom) for i in input_track]
             else:
                 found_generators[k] = input_track.read(chrom)
         # What about track collapse and recursion #
         pass  #TODO
         # Final argument list #
         final_args = {}
         for d in (found_args, found_generators, extra_args):
             final_args.update(d)
         # Call generate #
         data = self.generate(**final_args)
         # Variable fields case #
         if t['fields'][-1] == '...':
             fields = t['fields'][:-1] + rest_of_fields
         else:
             fields = t['fields']
         # Make a FeatureStream #
         stream = FeatureStream(data, fields)
         # Add it to the virtual track #
         vtrack.write(chrom, stream)
     # Close tracks later #
     vtrack.tracks_to_close = tracks_to_close
     # Add it #
     virtual_tracks.append(vtrack)
     # Return one virutal track or list of virtual tracks #
     return len(virtual_tracks) == 1 and virtual_tracks[0] or virtual_tracks
Beispiel #5
0
 def fields(self):
     return collapse(self.fields_collapse, [t.fields for t in self.tracks])
Beispiel #6
0
 def chromosomes(self):
     if not hasattr(self.tracks[0], "chromosomes"): return []
     chroms = collapse(self.chroms_collapse,
                       [t.chromosomes for t in self.tracks])
     chroms.sort(key=natural_sort)
     return chroms