code: def get_sources(self, plate, plate_value, sources=None):
          
          if sources is None:
              sources = []
          
          if self.sources:
              for si, source in enumerate(self.sources):
                  if len(source.streams) == 1 and None in source.streams:
                      sources.append(source.streams[None])
                  elif plate_value in source.streams:
                      sources.append(source.streams[plate_value])
                  else:
                      # # TODO - determine whether this should raise an exception or not, or even log a warning
                      # logging.warn("{} with value {} not valid for source {}"
                      #              .format(plate, plate_value, source))
                      pass
          
          if not plate.is_root:
              # Populate with sources defined on parent plate
              parent_plate_value = tuple(pv for pv in plate_value if pv[0] != plate.meta_data_id)
              sources = self.get_sources(plate.parent, parent_plate_value, sources)
          
          # sources.extend(self.get_global_sources())
          
          return sources
docs: Gets the source streams for a given plate value on a plate.
          Also populates with source streams that are valid for the parent plates of this plate,
          with the appropriate meta-data for the parent plate.
  
          :param plate: The plate being operated on
          :param plate_value: The specific plate value of interest
          :param sources: The currently found sources (for recursion)
          :return: The appropriate source streams
          :type plate: Plate
          :type plate_value: tuple
          :type sources: list[Stream] | None