code: def learn(self):
      
      self.setLearning(True)
  
      for obj in self.objects:
        self.sendReset()
  
        previousLocation = [None] * self.numColumns
        displacement = [0., 0.]
        features = obj["features"]
        numOfFeatures = len(features)
  
        # Randomize touch sequences
        touchSequence = np.random.permutation(numOfFeatures)
  
        for sensation in xrange(numOfFeatures):
          for col in xrange(self.numColumns):
            # Shift the touch sequence for each column
            colSequence = np.roll(touchSequence, col)
            feature = features[colSequence[sensation]]
            # Move the sensor to the center of the object
            locationOnObject = np.array([feature["top"] + feature["height"] / 2.,
                                         feature["left"] + feature["width"] / 2.])
            # Calculate displacement from previous location
            if previousLocation[col] is not None:
              displacement = locationOnObject - previousLocation[col]
            previousLocation[col] = locationOnObject
  
            # learn each pattern multiple times
            activeColumns = self.featureSDR[col][feature["name"]]
            for _ in xrange(self.numLearningPoints):
              # Sense feature at location
              self.motorInput[col].addDataToQueue(displacement)
              self.sensorInput[col].addDataToQueue(activeColumns, False, 0)
              # Only move to the location on the first sensation.
              displacement = [0, 0]
  
        self.network.run(numOfFeatures * self.numLearningPoints)
  
        # update L2 representations for the object
        self.learnedObjects[obj["name"]] = self.getL2Representations()
docs: Learn all objects on every column. Each column will learn all the features
      of every object and store the the object's L2 representation to be later
      used in the inference stage