Example #1
0
def select_best_combo_of(ai,better_than=0.15,candidates=20,basis=15):
  """Take the first few candidates of ai.combos().  Search for all combos
     with hkl obs-calc better than a certain fraction limit, then
     handle absences, and return the best one"""
  best_combo = None

  base_likelihood = 0.30
  best_likelihood = base_likelihood
  C = ai.combos(basis)
  maxtry = min(candidates,len(C))
  try_counter = 0
  solutions = SolutionTracker()
  if diagnostic:
    for x in range(ai.n_candidates()):
      directional_show(ai[x],message="BC%d"%x)

  for combo in C:
    #print "COMBO: (%d,%d,%d)"%(combo[0],combo[1],combo[2])
    try:
      HC = HandleCombo(ai,combo)
      #HC.handle_absences()  #might need to add this in later
      if ai.rmsdev() < better_than:
        model_likelihood = 1. - ai.rmsdev() # provisional expression for likelihood
        if model_likelihood > best_likelihood:
          best_likelihood = model_likelihood
        this_solution = {'combo':combo,'model_likelihood':model_likelihood,
                          'volume':ai.getOrientation().unit_cell().volume()}
        solutions.append(this_solution)
      try_counter+=1
    except (FewSpots) as f:
      #print "COMBO: (%d,%d,%d) rejected on too few spots"%(combo[0],combo[1],combo[2])
      #printcombo(ai,combo)
      continue
    except (SmallUnitCellVolume) as f:
      #print "Small COMBO: (%d,%d,%d) rejected on small cell volume"%(combo[0],combo[1],combo[2])
      continue
    except (KGerror) as f:
      #print "KG COMBO: (%d,%d,%d) rejected on Krivy-Gruber iterations"%(combo[0],combo[1],combo[2])
      #printcombo(ai,combo)
      continue
    except ValueError as f :
      if str(f).find("Corrupt metrical matrix")>=0: continue # colinear or coplanar
    except (RuntimeError) as f:
      if str(f).find("Iteration limit exceeded")>0: continue
      if str(f).find("Matrix is not invertible")>=0: continue# colinear or coplanar
      print "Report this problem to LABELIT developers:"
      print "COMBO: (%d,%d,%d) rejected on C++ runtime error"%(combo[0],combo[1],combo[2])
      #printcombo(ai,combo)
      continue
    except Exception:
      raise

    if solutions.halts():
      return solutions
    if try_counter == maxtry: break
  return solutions
Example #2
0
  def hemisphere(self,ai,size = 30,cutoff_divisor = 4.,verbose=True):

    unrefined_basis_vectors = self.get_top_solutions(ai,self.angles,size,
      cutoff_divisor,grid=self.incr)

    if verbose:
      for i in xrange(len(unrefined_basis_vectors)):
        D = unrefined_basis_vectors[i];
        if diagnostic:  directional_show(D, "SE%5d"%i)

    ai.setSolutions(unrefined_basis_vectors)
Example #3
0
    def get_top_solutions(self, ai, input_directions, size, cutoff_divisor,
                          grid):

        kval_cutoff = ai.getXyzSize() / cutoff_divisor

        hemisphere_solutions = flex.Direction()
        hemisphere_solutions.reserve(size)
        #print "# of input directions", len(input_directions)
        for i in range(len(input_directions)):
            D = sampled_direction = ai.fft_result(input_directions[i])

            #hardcoded parameter in for silicon example.  Not sure at this point how
            #robust the algorithm is when this value is relaxed.

            if D.real < self.max_cell and sampled_direction.kval > kval_cutoff:
                if diagnostic: directional_show(D, "%5d" % i)
                hemisphere_solutions.append(sampled_direction)
        if (hemisphere_solutions.size() < 3):
            return hemisphere_solutions
        kvals = flex.double([
            hemisphere_solutions[x].kval
            for x in range(len(hemisphere_solutions))
        ])

        perm = flex.sort_permutation(kvals, True)

        #  need to be more clever than just taking the top 30.
        #  one huge cluster around a strong basis direction could dominate the
        #  whole hemisphere map, preventing the discovery of three basis vectors

        perm_idx = 0
        unique_clusters = 0
        hemisphere_solutions_sort = flex.Direction()
        while perm_idx < len(perm) and \
              unique_clusters < size:
            test_item = hemisphere_solutions[perm[perm_idx]]
            direction_ok = True
            for list_item in hemisphere_solutions_sort:
                distance = math.sqrt(
                    math.pow(list_item.dvec[0] - test_item.dvec[0], 2) +
                    math.pow(list_item.dvec[1] - test_item.dvec[1], 2) +
                    math.pow(list_item.dvec[2] - test_item.dvec[2], 2))
                if distance < 0.087:  #i.e., 5 degrees radius for clustering analysis
                    direction_ok = False
                    break
            if direction_ok:
                unique_clusters += 1
            hemisphere_solutions_sort.append(test_item)
            perm_idx += 1

        return hemisphere_solutions_sort
Example #4
0
    def hemisphere(self, ai, size=30, cutoff_divisor=4., verbose=True):

        unrefined_basis_vectors = self.get_top_solutions(ai,
                                                         self.angles,
                                                         size,
                                                         cutoff_divisor,
                                                         grid=self.incr)

        if verbose:
            for i in range(len(unrefined_basis_vectors)):
                D = unrefined_basis_vectors[i]
                if diagnostic: directional_show(D, "SE%5d" % i)

        ai.setSolutions(unrefined_basis_vectors)
Example #5
0
  def get_top_solutions(self,ai,input_directions,size,cutoff_divisor,grid):

    kval_cutoff = ai.getXyzSize()/cutoff_divisor;

    hemisphere_solutions = flex.Direction();
    hemisphere_solutions.reserve(size);
    #print "# of input directions", len(input_directions)
    for i in xrange(len(input_directions)):
      D = sampled_direction = ai.fft_result(input_directions[i])

      #hardcoded parameter in for silicon example.  Not sure at this point how
      #robust the algorithm is when this value is relaxed.

      if D.real < self.max_cell and sampled_direction.kval > kval_cutoff:
        if diagnostic:  directional_show(D, "%5d"%i)
        hemisphere_solutions.append(sampled_direction)
    if (hemisphere_solutions.size()<3):
      return hemisphere_solutions
    kvals = flex.double([
  hemisphere_solutions[x].kval for x in xrange(len(hemisphere_solutions))])

    perm = flex.sort_permutation(kvals,True)

    #  need to be more clever than just taking the top 30.
    #  one huge cluster around a strong basis direction could dominate the
    #  whole hemisphere map, preventing the discovery of three basis vectors

    perm_idx = 0
    unique_clusters = 0
    hemisphere_solutions_sort = flex.Direction()
    while perm_idx < len(perm) and \
          unique_clusters < size:
      test_item = hemisphere_solutions[perm[perm_idx]]
      direction_ok = True
      for list_item in hemisphere_solutions_sort:
        distance = math.sqrt(math.pow(list_item.dvec[0]-test_item.dvec[0],2) +
                     math.pow(list_item.dvec[1]-test_item.dvec[1],2) +
                     math.pow(list_item.dvec[2]-test_item.dvec[2],2)
                     )
        if distance < 0.087: #i.e., 5 degrees radius for clustering analysis
           direction_ok=False
           break
      if direction_ok:
        unique_clusters+=1
      hemisphere_solutions_sort.append(test_item)
      perm_idx+=1

    return hemisphere_solutions_sort;
Example #6
0
def select_best_combo_of(ai, better_than=0.15, candidates=20, basis=15):
    """Take the first few candidates of ai.combos().  Search for all combos
     with hkl obs-calc better than a certain fraction limit, then
     handle absences, and return the best one"""
    best_combo = None

    base_likelihood = 0.30
    best_likelihood = base_likelihood
    C = ai.combos(basis)
    maxtry = min(candidates, len(C))
    try_counter = 0
    solutions = SolutionTracker()
    if diagnostic:
        for x in xrange(ai.n_candidates()):
            directional_show(ai[x], message="BC%d" % x)

    for combo in C:
        #print "COMBO: (%d,%d,%d)"%(combo[0],combo[1],combo[2])
        try:
            HC = HandleCombo(ai, combo)
            #HC.handle_absences()  #might need to add this in later
            if ai.rmsdev() < better_than:
                model_likelihood = 1. - ai.rmsdev(
                )  # provisional expression for likelihood
                if model_likelihood > best_likelihood:
                    best_likelihood = model_likelihood
                this_solution = {
                    'combo': combo,
                    'model_likelihood': model_likelihood,
                    'volume': ai.getOrientation().unit_cell().volume()
                }
                solutions.append(this_solution)
            try_counter += 1
        except (FewSpots), f:
            #print "COMBO: (%d,%d,%d) rejected on too few spots"%(combo[0],combo[1],combo[2])
            #printcombo(ai,combo)
            continue
        except (SmallUnitCellVolume), f:
            #print "Small COMBO: (%d,%d,%d) rejected on small cell volume"%(combo[0],combo[1],combo[2])
            continue
Example #7
0
def select_best_combo_of(ai,better_than=0.15,candidates=20,basis=15):
  """Take the first few candidates of ai.combos().  Search for all combos
     with hkl obs-calc better than a certain fraction limit, then
     handle absences, and return the best one"""
  best_combo = None

  base_likelihood = 0.30
  best_likelihood = base_likelihood
  C = ai.combos(basis)
  maxtry = min(candidates,len(C))
  try_counter = 0
  solutions = SolutionTracker()
  if diagnostic:
    for x in xrange(ai.n_candidates()):
      directional_show(ai[x],message="BC%d"%x)

  for combo in C:
    #print "COMBO: (%d,%d,%d)"%(combo[0],combo[1],combo[2])
    try:
      HC = HandleCombo(ai,combo)
      #HC.handle_absences()  #might need to add this in later
      if ai.rmsdev() < better_than:
        model_likelihood = 1. - ai.rmsdev() # provisional expression for likelihood
        if model_likelihood > best_likelihood:
          best_likelihood = model_likelihood
        this_solution = {'combo':combo,'model_likelihood':model_likelihood,
                          'volume':ai.getOrientation().unit_cell().volume()}
        solutions.append(this_solution)
      try_counter+=1
    except (FewSpots),f:
      #print "COMBO: (%d,%d,%d) rejected on too few spots"%(combo[0],combo[1],combo[2])
      #printcombo(ai,combo)
      continue
    except (SmallUnitCellVolume),f:
      #print "Small COMBO: (%d,%d,%d) rejected on small cell volume"%(combo[0],combo[1],combo[2])
      continue
Example #8
0
def force_cell(index_engine,target_cell,verbose=False):

    if verbose:
      print "N candidates:",index_engine.n_candidates()
      from rstbx.dps_core import directional_show
      for x in xrange(index_engine.n_candidates()):
        directional_show( index_engine[x], "vector %d:"%x )
    Ns = index_engine.n_candidates()
    best = {"score":1.E100}
    orth = target_cell.orthogonalization_matrix()
    for working_cell,cb_op in generate_unimodular_cells(target_cell):
      #print "---->",working_cell, working_cell.volume()

      vectors = {"a":{"match":[],"length":working_cell.parameters()[0]},
                 "b":{"match":[],"length":working_cell.parameters()[1]},
                 "c":{"match":[],"length":working_cell.parameters()[2]},
                }
      for key in vectors.keys():
        for ns in xrange(Ns):
          if is_length_match(vectors[key]["length"],index_engine[ns].real):
            vectors[key]["match"].append(ns)
        #print key, vectors[key]

      lines = {"alpha":{"match":[],"points":("b","c"),"angle":working_cell.parameters()[3],"hit":False},
                "beta":{"match":[],"points":("c","a"),"angle":working_cell.parameters()[4],"hit":False},
               "gamma":{"match":[],"points":("a","b"),"angle":working_cell.parameters()[5],"hit":False},
              }
      for key in lines.keys():
        xmatch = len(vectors[lines[key]["points"][0]]["match"])
        ymatch = len(vectors[lines[key]["points"][1]]["match"])
        for xi in xrange(xmatch):
          for yi in xrange(ymatch):
            xkey = vectors[lines[key]["points"][0]]["match"][abs(xi)]
            ykey = vectors[lines[key]["points"][1]]["match"][abs(yi)]
            #print key,xkey,ykey,

            xvector = col(index_engine[xkey].dvec)
            yvector = col(index_engine[ykey].dvec)

            #print xvector.dot(yvector),
            costheta = xvector.dot(yvector)/math.sqrt(xvector.dot(xvector)*yvector.dot(yvector))
            angle = math.acos(costheta)*180./math.pi
            #print "angle %.2f"%angle,
            if is_angle_match(angle, lines[key]["angle"]):
              #print "*****",;
              lines[key]["hit"]=True
              lines[key]["match"].append((xkey,ykey))

      if lines["alpha"]["hit"] and lines["beta"]["hit"] and lines["gamma"]["hit"]:
        #print "HELLO HIT"
        #for key in lines.keys():
        #  print key, lines[key]
        tri = get_triangle(lines)
        #print "Triangle:",tri
        if tri==None: continue
        direct_matrix = sqr((
          index_engine[tri[0]].bvec()[0],index_engine[tri[0]].bvec()[1],index_engine[tri[0]].bvec()[2],
          index_engine[tri[1]].bvec()[0],index_engine[tri[1]].bvec()[1],index_engine[tri[1]].bvec()[2],
          index_engine[tri[2]].bvec()[0],index_engine[tri[2]].bvec()[1],index_engine[tri[2]].bvec()[2],
           ))
        ori = Orientation(direct_matrix,False)
        #print "Found unit cell",ori.unit_cell()
        #print "compatible",ori.unit_cell().change_basis(cb_op.inverse()),
        modo = ori.unit_cell().change_basis(cb_op.inverse()).orthogonalization_matrix()
        diff = ( modo[0]-orth[0],modo[1]-orth[1],modo[2]-orth[2],modo[4]-orth[4],modo[5]-orth[5],modo[8]-orth[8])
        score = math.sqrt(diff[0]*diff[0]+diff[1]*diff[1]+diff[2]*diff[2]+diff[3]*diff[3]+diff[4]*diff[4]+diff[5]*diff[5])
        #print "score %.1f"%score,tri
        if score<best["score"]:
          best = {"score":score,"triangle":tri,"orientation":ori.change_basis(sqr(cb_op.inverse().c().r().as_double()).transpose())}
    if verbose: print "Best score %.1f, triangle %12s"%(best["score"],str(best["triangle"])),best["orientation"].unit_cell()
    return best
Example #9
0
def force_cell(index_engine,target_cell,verbose=False):

    if verbose:
      print("N candidates:",index_engine.n_candidates())
      from rstbx.dps_core import directional_show
      for x in range(index_engine.n_candidates()):
        directional_show( index_engine[x], "vector %d:"%x )
    Ns = index_engine.n_candidates()
    best = {"score":1.E100}
    orth = target_cell.orthogonalization_matrix()
    for working_cell,cb_op in generate_unimodular_cells(target_cell):
      #print "---->",working_cell, working_cell.volume()

      vectors = {"a":{"match":[],"length":working_cell.parameters()[0]},
                 "b":{"match":[],"length":working_cell.parameters()[1]},
                 "c":{"match":[],"length":working_cell.parameters()[2]},
                }
      for key in vectors.keys():
        for ns in range(Ns):
          if is_length_match(vectors[key]["length"],index_engine[ns].real):
            vectors[key]["match"].append(ns)
        #print key, vectors[key]

      lines = {"alpha":{"match":[],"points":("b","c"),"angle":working_cell.parameters()[3],"hit":False},
                "beta":{"match":[],"points":("c","a"),"angle":working_cell.parameters()[4],"hit":False},
               "gamma":{"match":[],"points":("a","b"),"angle":working_cell.parameters()[5],"hit":False},
              }
      for key in lines.keys():
        xmatch = len(vectors[lines[key]["points"][0]]["match"])
        ymatch = len(vectors[lines[key]["points"][1]]["match"])
        for xi in range(xmatch):
          for yi in range(ymatch):
            xkey = vectors[lines[key]["points"][0]]["match"][abs(xi)]
            ykey = vectors[lines[key]["points"][1]]["match"][abs(yi)]
            #print key,xkey,ykey,

            xvector = col(index_engine[xkey].dvec)
            yvector = col(index_engine[ykey].dvec)

            #print xvector.dot(yvector),
            costheta = xvector.dot(yvector)/math.sqrt(xvector.dot(xvector)*yvector.dot(yvector))
            angle = math.acos(costheta)*180./math.pi
            #print "angle %.2f"%angle,
            if is_angle_match(angle, lines[key]["angle"]):
              #print "*****",;
              lines[key]["hit"]=True
              lines[key]["match"].append((xkey,ykey))

      if lines["alpha"]["hit"] and lines["beta"]["hit"] and lines["gamma"]["hit"]:
        #print "HELLO HIT"
        #for key in lines.keys():
        #  print key, lines[key]
        tri = get_triangle(lines)
        #print "Triangle:",tri
        if tri==None: continue
        direct_matrix = sqr((
          index_engine[tri[0]].bvec()[0],index_engine[tri[0]].bvec()[1],index_engine[tri[0]].bvec()[2],
          index_engine[tri[1]].bvec()[0],index_engine[tri[1]].bvec()[1],index_engine[tri[1]].bvec()[2],
          index_engine[tri[2]].bvec()[0],index_engine[tri[2]].bvec()[1],index_engine[tri[2]].bvec()[2],
           ))
        ori = Orientation(direct_matrix,False)
        #print "Found unit cell",ori.unit_cell()
        #print "compatible",ori.unit_cell().change_basis(cb_op.inverse()),
        modo = ori.unit_cell().change_basis(cb_op.inverse()).orthogonalization_matrix()
        diff = ( modo[0]-orth[0],modo[1]-orth[1],modo[2]-orth[2],modo[4]-orth[4],modo[5]-orth[5],modo[8]-orth[8])
        score = math.sqrt(diff[0]*diff[0]+diff[1]*diff[1]+diff[2]*diff[2]+diff[3]*diff[3]+diff[4]*diff[4]+diff[5]*diff[5])
        #print "score %.1f"%score,tri
        if score<best["score"]:
          best = {"score":score,"triangle":tri,"orientation":ori.change_basis(sqr(cb_op.inverse().c().r().as_double()).transpose())}
    if verbose: print("Best score %.1f, triangle %12s"%(best["score"],str(best["triangle"])),best["orientation"].unit_cell())
    return best