Attempts to cleanly stop the ``Piper`` instance. A ``Piper`` is 
        "started" if its  ``NuMap`` instance is "started". Non-parallel 
        ``Pipers`` do not have to be started or stopped. An ``NuMap`` instance
        can be stopped by triggering its stopping procedure and retrieving 
        results from the ``NuMaps`` end tasks. Because neither the ``Piper`` nor
        the ``NuMap`` "knows" which tasks i.e. ``Pipers`` are the end tasks 
        they have to be specified::
        
            end_task_ids = [0, 1]    # A list of NuMap task ids
            piper_instance.stop(ends =end_task_ids)        
        
        results in::
        
            NuMap_instance.stop(ends =[0,1])
            
        If the ``Piper`` did not finish processing the data before the 
        stop method is called the "forced" argument has to be ``True``::
        
            piper_instance.stop(forced =True, ends =end_task_ids)
            
        If the ``Piper`` (and consequently ``NuMap``) is part of a ``Dagger`` 
        graph the ``Dagger.stop`` method should be called instead. See: 
        ``NuMap.stop`` and ``Dagger.stop``.
        
        # verify this:
        # If "forced" is set ``True`` but the ends ``NuMap`` argument is not
        # given. The ``NuMap`` instance will not try to retrieve any results and
        # will not call the ``NuMap._stop`` method.
        
        Arguments:
        
          - forced(``bool``) [default: ``False``] The ``Piper`` will be forced 
            to stop the ``NuMap`` instance.
            
        Additional keyworded arguments are passed to the ``Piper.imap`` 
        instance.

def stop(self, forced=False, **kwargs):
        """
        Attempts to cleanly stop the ``Piper`` instance. A ``Piper`` is 
        "started" if its  ``NuMap`` instance is "started". Non-parallel 
        ``Pipers`` do not have to be started or stopped. An ``NuMap`` instance
        can be stopped by triggering its stopping procedure and retrieving 
        results from the ``NuMaps`` end tasks. Because neither the ``Piper`` nor
        the ``NuMap`` "knows" which tasks i.e. ``Pipers`` are the end tasks 
        they have to be specified::
        
            end_task_ids = [0, 1]    # A list of NuMap task ids
            piper_instance.stop(ends =end_task_ids)        
        
        results in::
        
            NuMap_instance.stop(ends =[0,1])
            
        If the ``Piper`` did not finish processing the data before the 
        stop method is called the "forced" argument has to be ``True``::
        
            piper_instance.stop(forced =True, ends =end_task_ids)
            
        If the ``Piper`` (and consequently ``NuMap``) is part of a ``Dagger`` 
        graph the ``Dagger.stop`` method should be called instead. See: 
        ``NuMap.stop`` and ``Dagger.stop``.
        
        # verify this:
        # If "forced" is set ``True`` but the ends ``NuMap`` argument is not
        # given. The ``NuMap`` instance will not try to retrieve any results and
        # will not call the ``NuMap._stop`` method.
        
        Arguments:
        
          - forced(``bool``) [default: ``False``] The ``Piper`` will be forced 
            to stop the ``NuMap`` instance.
            
        Additional keyworded arguments are passed to the ``Piper.imap`` 
        instance.
            
        """
        # ends valid only if forced specified.
        if not self.started:
            self.log.error('Piper %s has not yet been started.' % self)
            raise PiperError('Piper %s has not yet been started.' % self)
        elif not self.finished and not forced:
            msg = 'Piper %s has not finished. Use forced =True' % self
            self.log.error(msg)
            raise PiperError(msg)
        else:
            # started and (finished or forced)
            if hasattr(self.imap, 'stop'):
                self.imap.stop(forced=forced, **kwargs)
            self.started = False
            self.log.debug('Piper %s stops (finished: %s)' % \
                          (self, self.finished))