def METHOD_NAME(args):
  assert args in [[], ["--verbose"]]
  if (len(args) != 0):
    cout = sys.stdout
  else:
    cout = null_out()
  edge_list_bonds = [(0,1),(0,4),(1,2),(2,3),(3,4)]
  bond_list = [
    (("C1*", "C2*"), 1.529),
    (("C1*", "O4*"), 1.412),
    (("C2*", "C3*"), 1.526),
    (("C3*", "C4*"), 1.520),
    (("C4*", "O4*"), 1.449)]
  angle_list = [
    (("C1*", "C2*", "C3*"), 101.3),
    (("C2*", "C3*", "C4*"), 102.3),
    (("C3*", "C4*", "O4*"), 104.2),
    (("C4*", "O4*", "C1*"), 110.0)]
  sites_cart, geo_manager = cctbx.geometry_restraints.manager \
    .construct_non_crystallographic_conserving_bonds_and_angles(
      sites_cart=sites_cart_3p,
      edge_list_bonds=edge_list_bonds,
      edge_list_angles=[])
  for bond_atom_names,distance_ideal in bond_list:
    i,j = [atom_names.index(atom_name) for atom_name in bond_atom_names]
    bond_params = geo_manager.bond_params_table[i][j]
    assert approx_equal(bond_params.distance_ideal, distance_ideal, eps=1.e-2)
    bond_params.distance_ideal = distance_ideal
    bond_params.weight = 1/0.02**2
  assert geo_manager.angle_proxies is None
  geo_manager.angle_proxies = cctbx.geometry_restraints.shared_angle_proxy()
  for angle_atom_names,angle_ideal in angle_list:
    i_seqs = [atom_names.index(atom_name) for atom_name in angle_atom_names]
    geo_manager.angle_proxies.append(cctbx.geometry_restraints.angle_proxy(
      i_seqs=i_seqs,
      angle_ideal=angle_ideal,
      weight=1/3**2))
  geo_manager.show_sorted(
    site_labels=atom_names, sites_cart=sites_cart, f=cout)
  def lbfgs(sites_cart):
    for i_lbfgs_restart in range(3):
      minimized = cctbx.geometry_restraints.lbfgs.lbfgs(
        sites_cart=sites_cart,
        geometry_restraints_manager=geo_manager)
      assert is_below_limit(value=minimized.final_target_value, limit=1e-10)
    return minimized
  lbfgs(sites_cart=sites_cart_3p)
  lbfgs(sites_cart=sites_cart_2p)
  conformer_counts = [0] * 4
  sites_cart = sites_cart.deep_copy()
  mt = flex.mersenne_twister(seed=0)
  for i_trial in range(20):
    while True:
      for i in range(sites_cart.size()):
        sites_cart[i] = mt.random_double_point_on_sphere()
      try:
        lbfgs(sites_cart=sites_cart)
      except RuntimeError as e:
        if (not str(e).startswith(
              "Bond distance > max_reasonable_bond_distance: ")):
          raise
      else:
        break
    rmsd_list = flex.double()
    for reference_sites in [
          sites_cart_3p,
          sites_cart_2p,
          sites_cart_a,
          sites_cart_b]:
      sup = scitbx.math.superpose.least_squares_fit(
        reference_sites=reference_sites,
        other_sites=sites_cart)
      rmsd = reference_sites.rms_difference(sup.other_sites_best_fit())
      rmsd_list.append(rmsd)
    oline = " ".join(["%.3f" % rmsd for rmsd in rmsd_list])
    print(oline, file=cout)
    assert is_below_limit(min(rmsd_list), 1e-3)
    conformer_counts[flex.min_index(rmsd_list)] += 1
  print("conformer_counts:", conformer_counts)
  #
  if (libtbx.env.has_module("iotbx")):
    import iotbx.pdb.hierarchy
    hierarchy = iotbx.pdb.hierarchy.root()
    model = iotbx.pdb.hierarchy.model(id="")
    chain = iotbx.pdb.hierarchy.chain(id="A")
    model.append_chain(chain)
    hierarchy.append_model(model)
    #
    sites_cart_pentagon = pentagon_sites_cart()
    for i_stack,sites_cart in enumerate([
          sites_cart_3p,
          sites_cart_2p,
          sites_cart_a,
          sites_cart_b]):
      atom_group = iotbx.pdb.hierarchy.atom_group(resname="  U", altloc="")
      sup = scitbx.math.superpose.least_squares_fit(
        reference_sites=sites_cart_pentagon,
        other_sites=sites_cart)
      sites_cart_out = sup.other_sites_best_fit()
      for site_label,site_cart in zip(atom_names, sites_cart_out):
        atom = iotbx.pdb.hierarchy.atom()
        atom.name = " %-3s" % site_label
        atom.xyz = matrix.col(site_cart) + matrix.col((0,0,i_stack*1.5))
        atom.occ = 1
        atom.b = 20
        atom.element = " " + site_label[0]
        atom_group.append_atom(atom)
      residue_group = iotbx.pdb.hierarchy.residue_group(
        resseq="%4d" % (i_stack+1), icode=" ")
      residue_group.append_atom_group(atom_group)
      chain.append_residue_group(residue_group)
    hierarchy.atoms().reset_serial()
    pdb_str = hierarchy.as_pdb_string(append_end=True)
    file_name = "puckers.pdb"
    print("Writing file:", file_name)
    open(file_name, "w").write("""\