text: # 2013.10.10 11:42:06 EDT
  #Embedded file name: ../utils/extractAtomic.py
  """
  Created on Wed Aug  7 20:54:17 2013
  
  @author: proto
  """
  from collections import Counter
  
  def extractMolecules(action, site1, site2, chemicalArray, differentiateDimers=False):
      """
      this method goes through the chemicals in a given array 'chemicalArray'
      and extracts its atomic patterns into two arrays:
          those elements that are contained in [site1,site2] will be put in the
          reactionCenter set. The rest will    be placed in the context set.
          The entire system will be put into the atomicPatterns dictionary
      Keyword arguments:
      site1,site2 -- where the action takes place
      chemicalArray -- the list of species we will be extracting atomic patters 
      from
      """
      atomicPatterns = {}
      reactionCenter = set()
      context = set()
      reactionCenterC = Counter()
      contextC = Counter()
      for reactant in chemicalArray:
          ta, tr, tc = reactant.extractAtomicPatterns(action, site1, site2,differentiateDimers)
          atomicPatterns.update(ta)
          for element in tr:
              reactionCenter.add(element)
  
          for element in tc:
              context.add(element)
  
          reactionCenterC.update(tr)
          contextC.update(tc)
  
      return (atomicPatterns, reactionCenterC, contextC)
  
  
  def solveWildcards(atomicArray):
      """
      When you have a wildcard '+' as a bond configuration, this method allows you
      to go through the list of atomic elements and find which patterns the '+'
      can potentially resolve to
      """
      standinArray = {}
      for wildcard in [ x for x in atomicArray if '+' in x ]:
          for atomic in [ x for x in atomicArray if '+' not in x and len(atomicArray[x].molecules) > 1 ]:
              if atomicArray[wildcard].molecules[0].name in [ x.name for x in atomicArray[atomic].molecules ]:
                  if wildcard not in standinArray:
                      standinArray[wildcard] = []
                  standinArray[wildcard].append(atomicArray[atomic])
  
      atomicArray.update(standinArray)
  
  
  def getMapping(mapp, site):
      for mapping in mapp:
          if site in mapping:
              return [ x for x in mapping if x != site ][0]
  
  
  def extractTransformations(rules, differentiateDimers=False):
      """
      goes through the list of rules and extracts its reactioncenter,context and product
      atomic patterns per transformation action
      """
      atomicArray = {}
      transformationCenter = []
      transformationContext = []
      productElements = []
      actionName = []
      index = 0
      label = []
      for rule, _, reationRate, reactionSymbol in rules:
          index += 1
          for action in rule.actions:
              atomic, reactionCenter, context = extractMolecules(action.action, action.site1, action.site2, rule.reactants, differentiateDimers)
              transformationCenter.append(reactionCenter)
              transformationContext.append(context)
              atomicArray.update(atomic)
              productSites = [getMapping(rule.mapping, action.site1), getMapping(rule.mapping, action.site2)]
              atomic, rc, _ = extractMolecules(action.action, productSites[0], productSites[1], rule.products, differentiateDimers)
              productElements.append(rc)
              atomicArray.update(atomic)
              actionName.append('%i-%s' % (index, action.action))
              r = '+'.join([str(x) for x in rule.reactants])
              p = '+'.join([str(x) for x in rule.products])
              label.append('->'.join([r, p, '%i-%s' % (index, action.action)]))
  
      solveWildcards(atomicArray)
      return (atomicArray, transformationCenter, transformationContext, productElements, actionName, label)
  
  
  if __name__ == "__main__":
      import readBNGXML
      _, rules, _ = readBNGXML.parseXML('output48.xml')
      for idx, rule in enumerate(rules):
          tatomicArray, ttransformationCenter, ttransformationContext, \
              tproductElements, tactionNames, tlabelArray = extractTransformations(
                  [rule], True)
          if rule[0].label == '_reverse_v7':
              print str(rule[0])
              print ttransformationContext
              print tproductElements
              raise Exception
  