Run the function for each phase in the pipeline.

        Parameters
        ----------
        assert_optimizer_pickle_matches
        data_name
        func
            A function that takes a phase and prior results, returning results for that phase

        Returns
        -------
        results: ResultsCollection
            A collection of results

def run_function(self, func, data_name=None, assert_optimizer_pickle_matches=True):
        """
        Run the function for each phase in the pipeline.

        Parameters
        ----------
        assert_optimizer_pickle_matches
        data_name
        func
            A function that takes a phase and prior results, returning results for that phase

        Returns
        -------
        results: ResultsCollection
            A collection of results
        """
        results = ResultsCollection()
        for i, phase in enumerate(self.phases):
            logger.info("Running Phase {} (Number {})".format(phase.optimizer.phase_name, i))
            if assert_optimizer_pickle_matches:
                assert_optimizer_pickle_matches_for_phase(phase)
            save_optimizer_for_phase(phase)
            self.save_metadata(phase, data_name)
            results.add(phase.phase_name, func(phase, results))
        return results