def setStageFinished(self, index, clientURI, save_state = True,
                         checking_pipeline_status = False):

        s = self.stages[index]
        
        # since we want to use refcounting (where a 'reference' is an
        # unsatisfied dependency of a stage and 'collection' is
        # adding to the set of runnable stages) to determine whether a stage's
        # prerequisites have run, we make it an error for the same stage
        # to finish more than once (alternately, we could merely avoid
        # decrementing counts of previously finished stages, but
        # this choice should expose bugs sooner)
        if s.isFinished():
            raise ValueError("Already finished stage %d" % index)
        
        # this function can be called when a pipeline is restarted, and 
        # we go through all stages and set the finished ones to... finished... :-)
        # in that case, we can not remove the stage from the list of running
        # jobs, because there is none.

        if checking_pipeline_status:
            logger.log(SUBDEBUG, "Already finished stage " + str(index))
            s.status = "finished"
        else:
            logger.info("Finished Stage " + str(index) + ": " + str(self.stages[index]))
            self.removeFromRunning(index, clientURI, new_status = "finished")
            # run any potential hooks now that the stage has finished:
            for f in s.finished_hooks:
                f()
        self.num_finished_stages += 1
        # write out the (index, hash) pairs to disk.  We don't actually need the indices
        # for anything (in fact, the restart code in skip_completed_stages is resilient 
        # against an arbitrary renumbering of stages), but a human-readable log is somewhat useful.
        self.finished_stages_fh.write("%d,%s\n" % (index, self.stages[index].getHash()))
        self.finished_stages_fh.flush()
        for i in self.G.successors(index):
            self.unfinished_pred_counts[i] -= 1
            if self.checkIfRunnable(i):
                self.enqueue(i)
Returns data list if successful
dataset/ETHPy150Open Mouse-Imaging-Centre/pydpiper/pydpiper/pipeline.py/Pipeline.setStageFinished--crossover with--dataset/ETHPy150Open glue-viz/glue/glue/dialogs/data_wizard/qt/tests/test_data_wizard.py/test_data_wizard_normal