class_docstr: This evaluator sequences evaluations in a way that is friendly for
  caching intermediate computations. Each evaluation defines sub-analyses
  to run, and all subanalysis are run at the same time then the cache is
  cleared
class_docstr_tok: ["This","evaluator","sequences","evaluations","in","a","way","that","is","friendly","for","caching","intermediate","computations",".","Each","evaluation","defines","sub-analyses","to","run",",","and","all","subanalysis","are","run","at","the","same","time","then","the","cache","is","cleared"]
docstr: Computes metrics for one subject. Instead of iterating through the
  metrics in order, this method first identifies sub-analyses that should
  be run together (for caching reasons) and iterates through the
  sub-analyses in sequence, calculating the metrics for each
  sub-analysis together
  
  :param subject_id:
  :param data: data dictionary passed to each evaluation
  :param interp_orders: metadata for the data dictionary
         [currently not used]
  :return: a list of pandas.DataFrame objects
docstr_tok: ["Computes","metrics","for","one","subject",".","Instead","of","iterating","through","the","metrics","in","order",",","this","method","first","identifies","sub-analyses","that","should","be","run","together","(","for","caching","reasons",")","and","iterates","through","the","sub-analyses","in","sequence",",","calculating","the","metrics","for","each","sub-analysis","together",":","param","subject_id",":",":","param","data",":","data","dictionary","passed","to","each","evaluation",":","param","interp_orders",":","metadata","for","the","data","dictionary","[","currently","not","used","]",":","return",":","a","list","of","pandas.DataFrame","objects"]
code: def evaluate_next(self, subject_id, data, interp_orders):
      """
      Computes metrics for one subject. Instead of iterating through the
      metrics in order, this method first identifies sub-analyses that should
      be run together (for caching reasons) and iterates through the
      sub-analyses in sequence, calculating the metrics for each
      sub-analysis together
  
      :param subject_id:
      :param data: data dictionary passed to each evaluation
      :param interp_orders: metadata for the data dictionary
             [currently not used]
      :return: a list of pandas.DataFrame objects
      """
      # First go through evaluations to find those with subanalyses
      evaluations = {"normal": [], "subanalyses": []}
      for evl in self.evaluations:
          if hasattr(evl, "subanalyses"):
              sub = evl.subanalyses(subject_id, data)
              evaluations["subanalyses"].extend([(evl, s) for s in sub])
          else:
              evaluations["normal"].append(evl)
  
      # Run normal evaluations
      metrics = []
      for evaluation in evaluations["normal"]:
          metrics += evaluation(subject_id, data)
  
      # group sub-analysis evaluations by subanalysis
      def keyfunc(sub):
          return str(sub[1])
  
      tasks = sorted(evaluations["subanalyses"], key=keyfunc)
      tasksets = groupby(tasks, keyfunc)
      # run grouped evaluations
      for _, evaluationset in tasksets:
          for evaluation, sub in evaluationset:
              metrics += evaluation(subject_id, data, sub)
          cache.clear()
      return metrics
  
imports: from __future__ import absolute_import, division, print_function
  import itertools
  from itertools import groupby
  from collections import defaultdict
  import pandas
  from niftynet.engine.application_factory import EvaluationFactory
  from niftynet.utilities.util_common import cache
label_desc: Use image node_id 1 for calling the CachedSubanalysisEvaluator obj's underlying member method code with example usage: obj.evaluate_next(subject_id, data, interp_orders) and returns: metrics, str