parameters: (self, library, props)
docstring: library, props
          Given a Library and the list of Propery evaluators,
          optimize the library.
          The library is modified in place by removing building blocks
          (sidechains) that are not likely to pass the property
          criteria.
docstring_summary: library, props
          Given a Library and the list of Propery evaluators,
          optimize the library.
          The library is modified in place by removing building blocks
          (sidechains) that are not likely to pass the property
          criteria.
docstring_tokens: library props Given a Library and the list of Propery evaluators optimize the library . The library is modified in place by removing building blocks ( sidechains ) that are not likely to pass the property criteria .
function: def optimize(self, library, props):
          """library, props
          Given a Library and the list of Propery evaluators,
          optimize the library.
          The library is modified in place by removing building blocks
          (sidechains) that are not likely to pass the property
          criteria.
          """
          # attempt to generate report like glare application
          print ("------- PARAMETERS: --------------")
          print ("GOOODNESS THRESHOLD : %s%%"%(self.desiredFinalGoodness * 100))
          print ("MIN PARTITION SIZE : %s"%self.numPartitions)
          if self.initialFraction is None or self.initialFraction > 0.999:
              print ("INITIAL FRACTION TO KEEP : AUTOMATIC")
          else:
              print ("INITIAL FRACTION TO KEEP : %s%%"%(self.initialFraction*100))
          print ("Actual SIZE : %s = %s"%(
              " x ".join([str(len(rg.sidechains)) for rg in library.rgroups]),
              reduce(operator.mul, [len(rg.sidechains) for rg in library.rgroups])
          ))
              
          running_total = 0.0
          Gt = self.desiredFinalGoodness
  
          for iteration in range(1, self.maxIterations+1):
              # chunk of the total library into smaller more manageable sets
              #  and run combinatorial analysis on the sub libraries
              #  each of these records the number of times a sidechain is used
              #  in a successful enumeration which is then used to prune the
              #  library at the end
              #
              for rg in library.rgroups:
                  rg.randomize()
                  
              good = total = 0.0
              chunked_libs =  library.chunk(self.numPartitions)
              # for each chunk, do the combinatorial check to see
              #  if reagents make good products
              for libidx, chunk in enumerate(chunked_libs):
                  g,t = chunk.evaluate(props)
                  good += g
                  total += t
              running_total += total
              Gi = good/total # current goodness
                  
              if Gi < 1e-12:
                  # I think we're done here :)
                  fraction = 0.0
              elif iteration == 1:
                  G0 = Gi # Goodness at first iteration
  
                  # the first time, use the initalFraction or a "good enough"
                  #  value
                  if self.initialFraction is not None:
                      fraction = K0 = self.initialFraction
                  else:
                      # auto choose the fraction based on the current good percentage
                      #  and the desired 
                      fraction = K0 = min(-1.1 * ( Gt - G0) + 1.2,
                                          0.9)
              else:
                  # the second time, gradually eliminate reagents slowing
                  #  down as the number of iterations increases
                  #  see equation (5) in reference
                  if abs(Gt-G0) < 1e-4:
                      Ki = 1.0
                  else:
                      Ki = (1.0 - K0) * (Gi - G0) / (Gt - G0) + K0;
                  fraction = min(1.0, Ki)
  
              # prune the library to keep the highest occurring sidechains
              #  note that even if all sidechains are acceptable,
              #  some will always get pruned
              
              max_size = float(max([len(rg.sidechains) for rg in library.rgroups]))
              for rg in library.rgroups:
                  scale = 1.0
                  if self.rgroupScale is not None:
                      # scale differently size rgroups via equation (6)  in paper
                      numSidechains = len(rg.sidechains)
                      numer = 1.0
                      denom = 1.0 + math.exp(-self.rgroupScale *
                                             ((numSidechains/max_size) - 0.5))
                      scale = numer/denom
                  fraction_to_reject = (1.0 - fraction) * scale
                  # keep the best fraction...
                  rg.prune(1.0 - fraction_to_reject)
                  
              print ("-------------- ITERATION : %s ----------------------"%iteration)
              print ("GOODNESS      : %s%%"%(Gi * 100))
              print ("NUMBER EVAL   : %s"%(total))
              print ("CUMUL EVAL    : %s"%(running_total))
              print ("KEPT IN STEP  : %s%%"%(fraction*100.))
              if not iteration:
                  print ("GOODNESS THRESHOLD : %s"%self.desiredFinalGoodness)
                  print ("MIN PARTITION SIZE : %s"%self.numPartitions)
                  print ("INITIAL FRACTION TO KEEP : ")
                  if self.fractionToKeep > 0.999:
                      print ("AUTOMATIC")
                  else:
                      print ("%s%%"%self.fractionToKeep)
  
              print ("Actual SIZE : %s = %s"%(
                  " x ".join([str(len(rg.sidechains)) for rg in library.rgroups]),
                  reduce(operator.mul, [len(rg.sidechains) for rg in library.rgroups])
              ))
              print ("EFFECTIVENESS : %s%%"%(library.effectiveness()*100.))
  
              # stopping criteria
              if iteration and Gi < 1e-12:
                  return
              elif abs(Gi - self.desiredFinalGoodness) < 0.001 or \
                   Gi > self.desiredFinalGoodness:
                  return
function_tokens: def optimize ( self , library , props ) : # attempt to generate report like glare application print ( "------- PARAMETERS: --------------" ) print ( "GOOODNESS THRESHOLD : %s%%" % ( self . desiredFinalGoodness * 100 ) ) print ( "MIN PARTITION SIZE : %s" % self . numPartitions ) if self . initialFraction is None or self . initialFraction > 0.999 : print ( "INITIAL FRACTION TO KEEP : AUTOMATIC" ) else : print ( "INITIAL FRACTION TO KEEP : %s%%" % ( self . initialFraction * 100 ) ) print ( "Actual SIZE : %s = %s" % ( " x " . join ( [ str ( len ( rg . sidechains ) ) for rg in library . rgroups ] ) , reduce ( operator . mul , [ len ( rg . sidechains ) for rg in library . rgroups ] ) ) ) running_total = 0.0 Gt = self . desiredFinalGoodness for iteration in range ( 1 , self . maxIterations + 1 ) : # chunk of the total library into smaller more manageable sets #  and run combinatorial analysis on the sub libraries #  each of these records the number of times a sidechain is used #  in a successful enumeration which is then used to prune the #  library at the end # for rg in library . rgroups : rg . randomize ( ) good = total = 0.0 chunked_libs = library . chunk ( self . numPartitions ) # for each chunk, do the combinatorial check to see #  if reagents make good products for libidx , chunk in enumerate ( chunked_libs ) : g , t = chunk . evaluate ( props ) good += g total += t running_total += total Gi = good / total # current goodness if Gi < 1e-12 : # I think we're done here :) fraction = 0.0 elif iteration == 1 : G0 = Gi # Goodness at first iteration # the first time, use the initalFraction or a "good enough" #  value if self . initialFraction is not None : fraction = K0 = self . initialFraction else : # auto choose the fraction based on the current good percentage #  and the desired  fraction = K0 = min ( - 1.1 * ( Gt - G0 ) + 1.2 , 0.9 ) else : # the second time, gradually eliminate reagents slowing #  down as the number of iterations increases #  see equation (5) in reference if abs ( Gt - G0 ) < 1e-4 : Ki = 1.0 else : Ki = ( 1.0 - K0 ) * ( Gi - G0 ) / ( Gt - G0 ) + K0 fraction = min ( 1.0 , Ki ) # prune the library to keep the highest occurring sidechains #  note that even if all sidechains are acceptable, #  some will always get pruned max_size = float ( max ( [ len ( rg . sidechains ) for rg in library . rgroups ] ) ) for rg in library . rgroups : scale = 1.0 if self . rgroupScale is not None : # scale differently size rgroups via equation (6)  in paper numSidechains = len ( rg . sidechains ) numer = 1.0 denom = 1.0 + math . exp ( - self . rgroupScale * ( ( numSidechains / max_size ) - 0.5 ) ) scale = numer / denom fraction_to_reject = ( 1.0 - fraction ) * scale # keep the best fraction... rg . prune ( 1.0 - fraction_to_reject ) print ( "-------------- ITERATION : %s ----------------------" % iteration ) print ( "GOODNESS      : %s%%" % ( Gi * 100 ) ) print ( "NUMBER EVAL   : %s" % ( total ) ) print ( "CUMUL EVAL    : %s" % ( running_total ) ) print ( "KEPT IN STEP  : %s%%" % ( fraction * 100. ) ) if not iteration : print ( "GOODNESS THRESHOLD : %s" % self . desiredFinalGoodness ) print ( "MIN PARTITION SIZE : %s" % self . numPartitions ) print ( "INITIAL FRACTION TO KEEP : " ) if self . fractionToKeep > 0.999 : print ( "AUTOMATIC" ) else : print ( "%s%%" % self . fractionToKeep ) print ( "Actual SIZE : %s = %s" % ( " x " . join ( [ str ( len ( rg . sidechains ) ) for rg in library . rgroups ] ) , reduce ( operator . mul , [ len ( rg . sidechains ) for rg in library . rgroups ] ) ) ) print ( "EFFECTIVENESS : %s%%" % ( library . effectiveness ( ) * 100. ) ) # stopping criteria if iteration and Gi < 1e-12 : return elif abs ( Gi - self . desiredFinalGoodness ) < 0.001 or Gi > self . desiredFinalGoodness : return