def __init__(self, tmOverrides=None, tpOverrides=None, seed=42, verbosity=0):
    # Initialize Layer 4 temporal memory
    params = dict(self.DEFAULT_TM_PARAMS)
    params.update(tmOverrides or {})
    self._checkParams(params)
    self.tm = InspectGeneralTemporalMemory(**params)

    # Initialize Layer 3 temporal pooler
    params = dict(self.DEFAULT_TP_PARAMS)
    params["inputDimensions"] = [self.tm.connections.numberOfCells()]
    params["potentialRadius"] = self.tm.connections.numberOfCells()
    params.update(tpOverrides or {})
    self._checkParams(params)
    self.tp = TemporalPooler(**params)
# Temporal pooler cell [column c, cell i] corresponds to input
# c * cellsPerCol + i

print "Initializing Temporal Pooler"
l3NumColumns = 512
l3NumActiveColumnsPerInhArea = 20
l3InputSize = tm.numberOfCols*tm.cellsPerColumn
l3sp = TemporalPooler(
      inputDimensions  = [l3InputSize],
      columnDimensions = [l3NumColumns],
      potentialRadius  = l3InputSize,
      globalInhibition = True,
      numActiveColumnsPerInhArea=l3NumActiveColumnsPerInhArea,
      synPermInactiveDec=0,
      synPermActiveInc=0.001,
      synPredictedInc = 0.5,
      boostStrength=0.0,
      seed=4,
      potentialPct=0.9,
      stimulusThreshold = 2,
      useBurstingRule = False,
      synPermConnected = 0.3,
      initConnectedPct=0.2,
      spVerbosity=0
    )

print "Layer 3 Temporal Pooler parameters:"
l3sp.printParameters()

#######################################################################
#
# Step 4: Train temporal pooler (layer 3) to form stable and distinct
                           == universe.wSensor * 199 * len(agents)):
    print "Test successful!!"
else:
    print "Test unsuccessful"

print "Training TP on sequences"

l3NumColumns = 512
l3NumActiveColumnsPerInhArea = 20
tp = TemporalPooler(inputDimensions=[tm.connections.numberOfCells()],
                    columnDimensions=[l3NumColumns],
                    potentialRadius=tm.connections.numberOfCells(),
                    globalInhibition=True,
                    numActiveColumnsPerInhArea=l3NumActiveColumnsPerInhArea,
                    synPermInactiveDec=0,
                    synPermActiveInc=0.001,
                    synPredictedInc=0.5,
                    maxBoost=1.0,
                    seed=4,
                    potentialPct=0.9,
                    stimulusThreshold=2,
                    useBurstingRule=False,
                    minPctActiveDutyCycle=0.1,
                    synPermConnected=0.3,
                    initConnectedPct=0.2,
                    spVerbosity=0)

print "Testing TM on sequences"
sequences = generateSequences(10, agents, verbosity=1)
stats = feedTMTP(tm, tp, sequences=sequences, verbosity=2)
class SensorimotorExperimentRunner(object):
  DEFAULT_TM_PARAMS = {
    # These should be decent for most experiments, shouldn't need to override
    # these too often. Might want to increase cellsPerColumn for capacity
    # experiments.
    "cellsPerColumn": 8,
    "initialPermanence": 0.5,
    "connectedPermanence": 0.6,
    "permanenceIncrement": 0.1,
    "permanenceDecrement": 0.02,

    # We will force client to override these
    "columnDimensions": "Sorry",
    "minThreshold": "Sorry",
    "maxNewSynapseCount": "Sorry",
    "activationThreshold": "Sorry",
  }

  DEFAULT_TP_PARAMS = {
    # Need to check these parameters and find stable values that will be
    # consistent across most experiments.
    "synPermInactiveDec": 0,   # TODO: Check we can use class default here.
    "synPermActiveInc": 0.001, # TODO: Check we can use class default here.
    "synPredictedInc": 0.5,  # TODO: Why so high??
    "initConnectedPct": 0.2,  # TODO: need to check impact of this for pooling

    # We will force client to override these
    "numActiveColumnsPerInhArea": "Sorry",
  }

  def __init__(self, tmOverrides=None, tpOverrides=None, seed=42, verbosity=0):
    # Initialize Layer 4 temporal memory
    params = dict(self.DEFAULT_TM_PARAMS)
    params.update(tmOverrides or {})
    self._checkParams(params)
    self.tm = InspectGeneralTemporalMemory(**params)

    # Initialize Layer 3 temporal pooler
    params = dict(self.DEFAULT_TP_PARAMS)
    params["inputDimensions"] = [self.tm.connections.numberOfCells()]
    params["potentialRadius"] = self.tm.connections.numberOfCells()
    params.update(tpOverrides or {})
    self._checkParams(params)
    self.tp = TemporalPooler(**params)


  def _checkParams(self, params):
    for k,v in params.iteritems():
      if v == "Sorry":
        raise RuntimeError("Param "+k+" must be specified")


  def feedLayers(self, sequences, tmLearn, tpLearn=None, verbosity=0):
    """
    Feed the given set of sequences to the HTM algorithms.

    @param tmLearn:   (bool)      Either False, or True
    @param tpLearn:   (None,bool) Either None, False, or True. If None,
                                  temporal pooler will be skipped.
    """
    self.tm.clearHistory()

    for s,seq in enumerate(sequences):
      self.tm.reset()
      if verbosity>=2: print "\nSequence:",s

      for i in xrange(len(seq[0])):
        sensorPattern = seq[0][i]
        sensorimotorPattern = seq[2][i]

        # Feed the TM
        self.tm.compute(sensorPattern,
                  activeExternalCells=sensorimotorPattern,
                  formInternalConnections=False,
                  learn=tmLearn)

        # If requested, feed the TP
        if tpLearn is not None:
          tpInputVector, burstingColumns, correctlyPredictedCells = (
              self.formatInputForTP())
          activeArray = numpy.zeros(self.tp.getNumColumns())

          self.tp.compute(tpInputVector, learn=True, activeArray=activeArray,
                       burstingColumns=burstingColumns,
                       predictedCells=correctlyPredictedCells)

          if verbosity >= 2:
            print "L3 Active Cells \n",self.formatRow(activeArray.nonzero()[0],
                                                 formatString="%4d")


    if verbosity >= 2:
      print self.tm.prettyPrintHistory(verbosity=verbosity)
      print

    return self.tm.getStatistics()


  def generateSequences(self, length, agents, verbosity=0):
    """
    Generate sequences of the given length for each of the agents.

    Returns a list containing one tuple for each agent. Each tuple contains
    (sensorSequence, motorSequence, and sensorimotorSequence) as returned by
    the agent's generateSensorimotorSequence() method.

    """
    sequences = []
    for agent in agents:
      if verbosity > 0:
        print "\nGenerating sequence for world:",str(agent.world)
      sequences.append(
          agent.generateSensorimotorSequence(length, verbosity=verbosity)
      )

    return sequences


  def formatInputForTP(self):
    """
    Given an instance of the TM, format the information we need to send to the
    TP.
    """
    # all currently active cells in layer 4
    tpInputVector = numpy.zeros(
                  self.tm.connections.numberOfCells()).astype(realDType)
    tpInputVector[list(self.tm.activeCells)] = 1

    # bursting columns in layer 4
    burstingColumns = numpy.zeros(
      self.tm.connections.numberOfColumns()).astype(realDType)
    burstingColumns[list(self.tm.unpredictedActiveColumnsList[-1])] = 1

    # correctly predicted cells in layer 4
    correctlyPredictedCells = numpy.zeros(
      self.tm.connections.numberOfCells()).astype(realDType)
    correctlyPredictedCells[list(self.tm.predictedActiveCellsList[-1])] = 1

    return (tpInputVector, burstingColumns, correctlyPredictedCells)


  def formatRow(self, x, formatString = "%d", rowSize = 700):
    """
    Utility routine for pretty printing large vectors
    """
    s = ''
    for c,v in enumerate(x):
      if c > 0 and c % 7 == 0:
        s += ' '
      if c > 0 and c % rowSize == 0:
        s += '\n'
      s += formatString % v
    s += ' '
    return s
# c * cellsPerCol + i

print "Initializing Temporal Pooler"
l3NumColumns = 512
l3NumActiveColumnsPerInhArea = 20
l3InputSize = tm.numberOfCols*tm.cellsPerColumn
l3sp = TemporalPooler(
      inputDimensions  = [l3InputSize],
      columnDimensions = [l3NumColumns],
      potentialRadius  = l3InputSize,
      globalInhibition = True,
      numActiveColumnsPerInhArea=l3NumActiveColumnsPerInhArea,
      synPermInactiveDec=0,
      synPermActiveInc=0.001,
      synPredictedInc = 0.5,
      maxBoost=1.0,
      seed=4,
      potentialPct=0.9,
      stimulusThreshold = 2,
      useBurstingRule = False,
      minPctActiveDutyCycle = 0.1,
      synPermConnected = 0.3,
      initConnectedPct=0.2,
      spVerbosity=0
    )

print "Layer 3 Temporal Pooler parameters:"
l3sp.printParameters()

#######################################################################
#