From dbfd17cd6e69a246b52299865d71162ada871e53 Mon Sep 17 00:00:00 2001 From: Yuchen Xiao Date: Wed, 23 Sep 2026 21:30:57 -0400 Subject: [PATCH 1/7] feat: allow add structure from code string --- .../apps/refinebase/parametric_model.py | 253 ++- .../apps/refinebase/refinement_session.py | 135 +- tests/data/C60.gr | 1999 +++++++++++++++++ tests/data/c60xyz.txt | 60 + tests/helper.py | 88 +- tests/test_parametric_model.py | 4 +- 6 files changed, 2465 insertions(+), 74 deletions(-) create mode 100644 tests/data/C60.gr create mode 100644 tests/data/c60xyz.txt diff --git a/src/diffpy/apps/refinebase/parametric_model.py b/src/diffpy/apps/refinebase/parametric_model.py index 277c49e..71ce304 100644 --- a/src/diffpy/apps/refinebase/parametric_model.py +++ b/src/diffpy/apps/refinebase/parametric_model.py @@ -1,5 +1,6 @@ import logging import re +from functools import wraps from pathlib import Path import networkx as nx @@ -10,7 +11,11 @@ from diffpy.srfit.pdf.pdfgenerator import PDFGenerator from diffpy.srfit.structure import constrain_as_space_group from diffpy.srfit.structure.diffpyparset import DiffpyStructureParSet -from diffpy.srfit.structure.objcrystparset import ObjCrystCrystalParSet +from diffpy.srfit.structure.objcrystparset import ( + ObjCrystCrystalParSet, + ObjCrystMolAtomParSet, + ObjCrystMoleculeParSet, +) from diffpy.structure.parsers import get_parser # NOTE: MCP server prefers logging for output @@ -245,61 +250,24 @@ def evaluate(self): class ParametricModelPDF(ParametricModel): # NOTE: qmin, qmax, stype(scattering type) are meta handled # throughout the loaded profile in the refinement session - def __init__( - self, - name, - structure_file_path=None, - from_model_name=None, - library="Diffpy", - ): + def __init__(self, name, structure, spacegroup_symbol="P1"): + """ + Create a ParametricModelPDF instance from a structure object. + + structure can be a raw diffpy.structure/pyobjcryst structure, or + an existing DiffpyStructureParSet/ObjCrystCrystalParSet phase + (e.g. shared from another ParametricModelPDF). + """ super().__init__(name=name) self.calc_obj = PDFGenerator(name) - # NOTE: Certain space groups require dual origin handling. - DUAL_ORIGIN_SG_NUMBERS = { - 48, - 50, - 59, - 68, - 70, - 85, - 86, - 88, - 125, - 126, - 129, - 130, - 133, - 134, - 137, - 138, - 141, - 142, - 201, - 203, - 222, - 224, - 227, - 228, - } - if structure_file_path is not None: - stru_parser = get_parser("auto") - structure = stru_parser.parse( - Path(structure_file_path).read_text() - ) - sg = getattr(stru_parser, "spacegroup", None) - self.space_group_symbol = sg.short_name if sg is not None else "P1" - if sg.number in DUAL_ORIGIN_SG_NUMBERS or library == "ObjCryst": - structure = loadCrystal(structure_file_path) - self.calc_obj.setStructure(structure) - else: - self.calc_obj.setStructure(structure) - elif from_model_name is not None: - self.calc_obj.setPhase(from_model_name.calc_obj.phase) - self.space_group_symbol = from_model_name.space_group_symbol + if isinstance( + structure, (DiffpyStructureParSet, ObjCrystCrystalParSet) + ): + # already a phase parset: share it instead of rewrapping it + self.calc_obj.setPhase(structure) else: - raise ValueError( - "Either structure_file or from_model must be provided." - ) + self.calc_obj.setStructure(structure) + self.space_group_symbol = spacegroup_symbol self.sgpar_names = [] self._rebuild_graph() @@ -421,6 +389,85 @@ def constrain_symmetry(self, spacegroup_symbol=None, use_uiso=True): "constrained_or_constant" ] = True + def check_molecule_or_molatom(func): + @wraps(func) # preserves name, docstring, signature metadata + def wrapper(self, *args, **kwargs): + if not ( + isinstance(self.calc_obj.phase, ObjCrystMoleculeParSet) + or isinstance(self.calc_obj.phase, ObjCrystMolAtomParSet) + ): + logging.warning( + "The method %s is only applicable to " + "ObjCrystMoleculeParSet or " + "ObjCrystMolAtomParSet phases.", + func.__name__, + ) + return None + else: + return func(self, *args, **kwargs) + + return wrapper + + @check_molecule_or_molatom + def add_bond_length_parameter( + self, name, atom1, atom2, value=None, const=None + ): + phase = self.calc_obj.phase + phase.addBondLengthParameter(name, atom1, atom2, value, const) + self._rebuild_graph() + + @check_molecule_or_molatom + def add_bond_angle_parameter( + self, + name, + atom1, + atom2, + atom3, + value=None, + const=None, + ): + phase = self.calc_obj.phase + phase.addBondAngleParameter(name, atom1, atom2, atom3, value, const) + self._rebuild_graph() + + @check_molecule_or_molatom + def add_dihedral_angle_parameter( + self, + name, + atom1, + atom2, + atom3, + atom4, + value=None, + const=None, + ): + phase = self.calc_obj.phase + phase.addDihedralAngleParameter( + name, atom1, atom2, atom3, atom4, value, const + ) + self._rebuild_graph() + + @check_molecule_or_molatom + def restrain_bond_length_parameter( + self, par, length, sigma, delta, scaled=False + ): + phase = self.calc_obj.phase + phase.restrainBondLengthParameter(par, length, sigma, delta, scaled) + + @check_molecule_or_molatom + def restrain_bond_angle_parameter( + self, par, angle, sigma, delta, scaled=False + ): + phase = self.calc_obj.phase + phase.restrainBondAngleParameter(par, angle, sigma, delta, scaled) + + @check_molecule_or_molatom + def restrain_dihedral_angle_parameter( + self, par, angle, sigma, delta, scaled=False + ): + phase = self.calc_obj.phase + phase.restrainDihedralAngleParameter(par, angle, sigma, delta, scaled) + def _rebuild_graph(self): old_graph = self._graph self._graph = nx.DiGraph() @@ -443,3 +490,103 @@ def residual(self): yobs = self.calc_obj.profile.ypar.value dyobs = self.calc_obj.profile.dypar.value return (ycalc - yobs) / dyobs + + +# NOTE: certain space groups require dual origin handling. +DUAL_ORIGIN_SG_NUMBERS = { + 48, + 50, + 59, + 68, + 70, + 85, + 86, + 88, + 125, + 126, + 129, + 130, + 133, + 134, + 137, + 138, + 141, + 142, + 201, + 203, + 222, + 224, + 227, + 228, +} + + +def create_pdf_model_from_file(name, structure_file_path, library="Diffpy"): + """Create a ParametricModelPDF by parsing a structure file.""" + stru_parser = get_parser("auto") + structure = stru_parser.parse(Path(structure_file_path).read_text()) + sg = getattr(stru_parser, "spacegroup", None) + spacegroup_symbol = sg.short_name if sg is not None else "P1" + if ( + sg is not None and sg.number in DUAL_ORIGIN_SG_NUMBERS + ) or library == "ObjCryst": + structure = loadCrystal(structure_file_path) + return ParametricModelPDF( + name, structure, spacegroup_symbol=spacegroup_symbol + ) + + +def create_pdf_model_from_model(name, from_model): + """Create a ParametricModelPDF sharing the phase of from_model.""" + return ParametricModelPDF( + name, + from_model.calc_obj.phase, + spacegroup_symbol=from_model.space_group_symbol, + ) + + +def create_pdf_model_from_code( + name, code, structure_name="structure", spacegroup_symbol="P1" +): + """Create a ParametricModelPDF by executing code that builds a structure. + + The code must assign the structure/crystal object to a variable named + structure_name (default "structure") in its local namespace. + """ + global_namespace = {} + local_namespace = {} + exec(code, global_namespace, local_namespace) + if structure_name not in local_namespace: + raise ValueError( + f"Structure named {structure_name} not found in the executed code." + ) + structure = local_namespace[structure_name] + if not type(structure).__module__.startswith("pyobjcryst"): + if "spacegroup_symbol" not in local_namespace: + logging.warning( + "diffpy.structure.Structure doesn't contain spacegroup " + "information. Please provide the 'spacegroup_symbol' " + "variable explicitly in the executed code or the default " + f"'spacegroup_symbol' {spacegroup_symbol} will be used." + ) + spacegroup_symbol = local_namespace.get( + "spacegroup_symbol", spacegroup_symbol + ) + else: + crystal = ( + structure.GetCrystal() + if hasattr(structure, "GetCrystal") + else structure + ) + if hasattr(crystal, "GetSpaceGroup"): + spacegroup_symbol = crystal.GetSpaceGroup().GetName() + else: + logging.warning( + "Could not determine a space group for the structure named " + f"{structure_name}. The default 'spacegroup_symbol' " + f"{spacegroup_symbol} will be used." + ) + + return ParametricModelPDF( + name, structure, spacegroup_symbol=spacegroup_symbol + ) diff --git a/src/diffpy/apps/refinebase/refinement_session.py b/src/diffpy/apps/refinebase/refinement_session.py index 4576e78..08d3f8a 100644 --- a/src/diffpy/apps/refinebase/refinement_session.py +++ b/src/diffpy/apps/refinebase/refinement_session.py @@ -130,9 +130,7 @@ def set_profile_calculation_points(self, profile_name: str, x): profile = self.profiles_dict[profile_name] profile.set_calculation_points(x) - def add_equation_model( - self, model_name: str, equation_str=None, from_model_name=None - ): + def add_equation_model(self, model_name: str, equation_str=None): from diffpy.apps.refinebase.parametric_model import ( ParametricModelEquation, ) @@ -141,14 +139,6 @@ def add_equation_model( raise ValueError(f"Model with ID {model_name} already exists.") if equation_str is not None: model = ParametricModelEquation(model_name, equation_str) - elif from_model_name is not None: - if from_model_name not in self.models_dict: - raise ValueError( - f"Model with ID {from_model_name} does not exist." - ) - model = ParametricModelEquation( - model_name, from_model_name=from_model_name - ) else: raise ValueError( "Either equation_str or from_model must be provided." @@ -160,18 +150,21 @@ def add_pdf_model( model_name: str, structure_file_path=None, from_model_name=None, + code=None, library="Diffpy", ): from diffpy.apps.refinebase.parametric_model import ( - ParametricModelPDF, + create_pdf_model_from_code, + create_pdf_model_from_file, + create_pdf_model_from_model, ) if model_name in self.models_dict: raise ValueError(f"Model with ID {model_name} already exists.") if structure_file_path is not None: - pdf_model = ParametricModelPDF( + pdf_model = create_pdf_model_from_file( model_name, - structure_file_path=structure_file_path, + structure_file_path, library=library, ) elif from_model_name is not None: @@ -179,14 +172,17 @@ def add_pdf_model( raise ValueError( f"Model with ID {from_model_name} does not exist." ) - pdf_model = ParametricModelPDF( + from_model = self.models_dict[from_model_name] + pdf_model = create_pdf_model_from_model( model_name, - from_model_name=self.models_dict[from_model_name], - library=library, + from_model, ) + elif code is not None: + pdf_model = create_pdf_model_from_code(model_name, code) else: raise ValueError( - "Either structure_file_path or from_model must be provided." + "Either structure_file_path, from_model_name, or code " + "must be provided." ) self.models_dict[model_name] = pdf_model @@ -304,6 +300,109 @@ def constrain_pdf_model_space_group_symmetry( ) model.constrain_symmetry(space_group) + def _get_pdf_model(self, model_name): + if model_name not in self.models_dict: + raise ValueError(f"Model with ID {model_name} does not exist.") + model = self.models_dict[model_name] + if not isinstance(model, ParametricModelPDF): + raise ValueError( + f"Model '{model_name}' is not a ParametricModelPDF instance." + ) + return model + + def _get_scatterer(self, model, atom_index): + return model.calc_obj.phase.getScatterers()[atom_index] + + @check_model_exists + def add_pdf_bond_length_parameter( + self, + model_name, + name, + atom1_index, + atom2_index, + value=None, + const=None, + ): + model = self._get_pdf_model(model_name) + atom1 = self._get_scatterer(model, atom1_index) + atom2 = self._get_scatterer(model, atom2_index) + model.add_bond_length_parameter( + name, atom1, atom2, value=value, const=const + ) + + @check_model_exists + def add_pdf_bond_angle_parameter( + self, + model_name, + name, + atom1_index, + atom2_index, + atom3_index, + value=None, + const=None, + ): + model = self._get_pdf_model(model_name) + atom1 = self._get_scatterer(model, atom1_index) + atom2 = self._get_scatterer(model, atom2_index) + atom3 = self._get_scatterer(model, atom3_index) + model.add_bond_angle_parameter( + name, atom1, atom2, atom3, value=value, const=const + ) + + @check_model_exists + def add_pdf_dihedral_angle_parameter( + self, + model_name, + name, + atom1_index, + atom2_index, + atom3_index, + atom4_index, + value=None, + const=None, + ): + model = self._get_pdf_model(model_name) + atom1 = self._get_scatterer(model, atom1_index) + atom2 = self._get_scatterer(model, atom2_index) + atom3 = self._get_scatterer(model, atom3_index) + atom4 = self._get_scatterer(model, atom4_index) + model.add_dihedral_angle_parameter( + name, + atom1, + atom2, + atom3, + atom4, + value=value, + const=const, + ) + + def restrain_pdf_bond_length_parameter( + self, variable_name, length, sigma, delta, scaled=False + ): + model = self._get_pdf_model(variable_name.split(".")[0]) + par = self.get_variable(variable_name)["obj"] + return model.restrain_bond_length_parameter( + par, length, sigma, delta, scaled=scaled + ) + + def restrain_pdf_bond_angle_parameter( + self, variable_name, angle, sigma, delta, scaled=False + ): + model = self._get_pdf_model(variable_name.split(".")[0]) + par = self.get_variable(variable_name)["obj"] + return model.restrain_bond_angle_parameter( + par, angle, sigma, delta, scaled=scaled + ) + + def restrain_pdf_dihedral_angle_parameter( + self, variable_name, angle, sigma, delta, scaled=False + ): + model = self._get_pdf_model(variable_name.split(".")[0]) + par = self.get_variable(variable_name)["obj"] + return model.restrain_dihedral_angle_parameter( + par, angle, sigma, delta, scaled=scaled + ) + def set_variables_value(self, name_value_dict): for variable_name, value in name_value_dict.items(): variable = self.get_variable(variable_name)["obj"] diff --git a/tests/data/C60.gr b/tests/data/C60.gr new file mode 100644 index 0000000..d015b9d --- /dev/null +++ b/tests/data/C60.gr @@ -0,0 +1,1999 @@ + 1.000000e-002 1.894260e+004 8.536912e+000 + 2.000000e-002 3.772272e+004 1.675464e+001 + 3.000000e-002 5.617755e+004 2.434705e+001 + 4.000000e-002 7.414385e+004 3.103361e+001 + 5.000000e-002 9.145791e+004 3.657098e+001 + 6.000000e-002 1.079561e+005 4.076327e+001 + 7.000000e-002 1.234755e+005 4.347065e+001 + 8.000000e-002 1.378555e+005 4.461615e+001 + 9.000000e-002 1.509396e+005 4.419097e+001 + 1.000000e-001 1.625776e+005 4.225878e+001 + 1.100000e-001 1.726287e+005 3.896113e+001 + 1.200000e-001 1.809643e+005 3.452824e+001 + 1.300000e-001 1.874722e+005 2.930697e+001 + 1.400000e-001 1.920600e+005 2.383587e+001 + 1.500000e-001 1.946585e+005 1.902762e+001 + 1.600000e-001 1.952258e+005 1.638514e+001 + 1.700000e-001 1.937504e+005 1.723828e+001 + 1.800000e-001 1.902538e+005 2.094617e+001 + 1.900000e-001 1.847926e+005 2.582197e+001 + 2.000000e-001 1.774602e+005 3.069799e+001 + 2.100000e-001 1.683863e+005 3.493789e+001 + 2.200000e-001 1.577369e+005 3.818417e+001 + 2.300000e-001 1.457120e+005 4.023614e+001 + 2.400000e-001 1.325429e+005 4.100325e+001 + 2.500000e-001 1.184878e+005 4.048837e+001 + 2.600000e-001 1.038270e+005 3.878377e+001 + 2.700000e-001 8.885653e+004 3.607536e+001 + 2.800000e-001 7.388159e+004 3.265653e+001 + 2.900000e-001 5.920896e+004 2.895580e+001 + 3.000000e-001 4.513929e+004 2.557279e+001 + 3.100000e-001 3.195916e+004 2.326275e+001 + 3.200000e-001 1.993340e+004 2.270262e+001 + 3.300000e-001 9.297645e+003 2.402850e+001 + 3.400000e-001 2.517043e+002 2.670812e+001 + 3.500000e-001 -7.046274e+003 2.996591e+001 + 3.600000e-001 -1.248447e+004 3.314959e+001 + 3.700000e-001 -1.600078e+004 3.580905e+001 + 3.800000e-001 -1.758475e+004 3.766190e+001 + 3.900000e-001 -1.727796e+004 3.855493e+001 + 4.000000e-001 -1.517287e+004 3.844112e+001 + 4.100000e-001 -1.141006e+004 3.736925e+001 + 4.200000e-001 -6.173989e+003 3.548194e+001 + 4.300000e-001 3.126408e+002 3.302011e+001 + 4.400000e-001 7.795703e+003 3.033101e+001 + 4.500000e-001 1.599747e+004 2.786765e+001 + 4.600000e-001 2.462518e+004 2.614265e+001 + 4.700000e-001 3.338004e+004 2.558220e+001 + 4.800000e-001 4.196639e+004 2.631236e+001 + 4.900000e-001 5.010074e+004 2.807912e+001 + 5.000000e-001 5.752033e+004 3.040568e+001 + 5.100000e-001 6.399094e+004 3.280443e+001 + 5.200000e-001 6.931374e+004 3.488602e+001 + 5.300000e-001 7.333084e+004 3.638107e+001 + 5.400000e-001 7.592949e+004 3.713103e+001 + 5.500000e-001 7.704472e+004 3.707615e+001 + 5.600000e-001 7.666028e+004 3.624777e+001 + 5.700000e-001 7.480809e+004 3.476520e+001 + 5.800000e-001 7.156590e+004 3.283546e+001 + 5.900000e-001 6.705361e+004 3.075143e+001 + 6.000000e-001 6.142812e+004 2.887649e+001 + 6.100000e-001 5.487708e+004 2.759254e+001 + 6.200000e-001 4.761168e+004 2.719280e+001 + 6.300000e-001 3.985885e+004 2.775707e+001 + 6.400000e-001 3.185305e+004 2.911213e+001 + 6.500000e-001 2.382798e+004 3.092008e+001 + 6.600000e-001 1.600861e+004 3.280949e+001 + 6.700000e-001 8.603690e+003 3.446217e+001 + 6.800000e-001 1.798989e+003 3.564602e+001 + 6.900000e-001 -4.248345e+003 3.621989e+001 + 7.000000e-001 -9.414296e+003 3.612981e+001 + 7.100000e-001 -1.361113e+004 3.540484e+001 + 7.200000e-001 -1.678913e+004 3.415408e+001 + 7.300000e-001 -1.893683e+004 3.256366e+001 + 7.400000e-001 -2.007990e+004 3.088879e+001 + 7.500000e-001 -2.027862e+004 2.943093e+001 + 7.600000e-001 -1.962413e+004 2.848585e+001 + 7.700000e-001 -1.823367e+004 2.826030e+001 + 7.800000e-001 -1.624501e+004 2.879264e+001 + 7.900000e-001 -1.381022e+004 2.993744e+001 + 8.000000e-001 -1.108914e+004 3.142871e+001 + 8.100000e-001 -8.242848e+003 3.297014e+001 + 8.200000e-001 -5.427209e+003 3.430074e+001 + 8.300000e-001 -2.786985e+003 3.522605e+001 + 8.400000e-001 -4.505475e+002 3.562775e+001 + 8.500000e-001 1.474503e+003 3.546437e+001 + 8.600000e-001 2.904712e+003 3.476932e+001 + 8.700000e-001 3.783006e+003 3.364815e+001 + 8.800000e-001 4.079739e+003 3.227359e+001 + 8.900000e-001 3.792539e+003 3.087378e+001 + 9.000000e-001 2.944995e+003 2.970558e+001 + 9.100000e-001 1.584281e+003 2.900505e+001 + 9.200000e-001 -2.221585e+002 2.892054e+001 + 9.300000e-001 -2.390679e+003 2.945951e+001 + 9.400000e-001 -4.826074e+003 3.048692e+001 + 9.500000e-001 -7.426548e+003 3.177713e+001 + 9.600000e-001 -1.008880e+004 3.308207e+001 + 9.700000e-001 -1.271298e+004 3.418261e+001 + 9.800000e-001 -1.520728e+004 3.491556e+001 + 9.900000e-001 -1.749203e+004 3.518420e+001 + 1.000000e+000 -1.950295e+004 3.496061e+001 + 1.010000e+000 -2.119365e+004 3.428473e+001 + 1.020000e+000 -2.253705e+004 3.326127e+001 + 1.030000e+000 -2.352587e+004 3.205297e+001 + 1.040000e+000 -2.417195e+004 3.086606e+001 + 1.050000e+000 -2.450472e+004 2.992162e+001 + 1.060000e+000 -2.456860e+004 2.940961e+001 + 1.070000e+000 -2.441978e+004 2.943504e+001 + 1.080000e+000 -2.412218e+004 2.998252e+001 + 1.090000e+000 -2.374319e+004 3.092307e+001 + 1.100000e+000 -2.334901e+004 3.205863e+001 + 1.110000e+000 -2.300012e+004 3.317633e+001 + 1.120000e+000 -2.274696e+004 3.408973e+001 + 1.130000e+000 -2.262602e+004 3.466189e+001 + 1.140000e+000 -2.265661e+004 3.481545e+001 + 1.150000e+000 -2.283852e+004 3.453561e+001 + 1.160000e+000 -2.315052e+004 3.386939e+001 + 1.170000e+000 -2.355002e+004 3.292196e+001 + 1.180000e+000 -2.397379e+004 3.184827e+001 + 1.190000e+000 -2.433983e+004 3.083629e+001 + 1.200000e+000 -2.455020e+004 3.007749e+001 + 1.210000e+000 -2.449497e+004 2.972463e+001 + 1.220000e+000 -2.405678e+004 2.984857e+001 + 1.230000e+000 -2.311625e+004 3.041549e+001 + 1.240000e+000 -2.155763e+004 3.129943e+001 + 1.250000e+000 -1.927474e+004 3.232188e+001 + 1.260000e+000 -1.617677e+004 3.329646e+001 + 1.270000e+000 -1.219380e+004 3.406274e+001 + 1.280000e+000 -7.281746e+003 3.450578e+001 + 1.290000e+000 -1.426424e+003 3.456517e+001 + 1.300000e+000 5.353299e+003 3.423792e+001 + 1.310000e+000 1.300359e+004 3.357747e+001 + 1.320000e+000 2.143502e+004 3.268925e+001 + 1.330000e+000 3.052330e+004 3.172090e+001 + 1.340000e+000 4.011144e+004 3.084406e+001 + 1.350000e+000 5.001319e+004 3.022499e+001 + 1.360000e+000 6.001786e+004 2.998663e+001 + 1.370000e+000 6.989613e+004 3.017416e+001 + 1.380000e+000 7.940690e+004 3.074129e+001 + 1.390000e+000 8.830476e+004 3.156592e+001 + 1.400000e+000 9.634796e+004 3.248562e+001 + 1.410000e+000 1.033065e+005 3.333545e+001 + 1.420000e+000 1.089699e+005 3.397637e+001 + 1.430000e+000 1.131552e+005 3.431197e+001 + 1.440000e+000 1.157129e+005 3.429651e+001 + 1.450000e+000 1.165335e+005 3.393732e+001 + 1.460000e+000 1.155517e+005 3.329331e+001 + 1.470000e+000 1.127495e+005 3.246956e+001 + 1.480000e+000 1.081579e+005 3.160617e+001 + 1.490000e+000 1.018568e+005 3.085890e+001 + 1.500000e+000 9.397351e+004 3.037054e+001 + 1.510000e+000 8.467901e+004 3.023745e+001 + 1.520000e+000 7.418359e+004 3.048283e+001 + 1.530000e+000 6.273046e+004 3.105034e+001 + 1.540000e+000 5.058849e+004 3.182166e+001 + 1.550000e+000 3.804397e+004 3.264849e+001 + 1.560000e+000 2.539181e+004 3.338471e+001 + 1.570000e+000 1.292640e+004 3.391040e+001 + 1.580000e+000 9.324659e+002 3.414606e+001 + 1.590000e+000 -1.032371e+004 3.405958e+001 + 1.600000e+000 -2.060241e+004 3.366803e+001 + 1.610000e+000 -2.969773e+004 3.303553e+001 + 1.620000e+000 -3.744356e+004 3.226681e+001 + 1.630000e+000 -4.371828e+004 3.149482e+001 + 1.640000e+000 -4.844778e+004 3.086063e+001 + 1.650000e+000 -5.160696e+004 3.048597e+001 + 1.660000e+000 -5.321946e+004 3.044401e+001 + 1.670000e+000 -5.335573e+004 3.073938e+001 + 1.680000e+000 -5.212953e+004 3.130742e+001 + 1.690000e+000 -4.969303e+004 3.203302e+001 + 1.700000e+000 -4.623056e+004 3.277968e+001 + 1.710000e+000 -4.195148e+004 3.341732e+001 + 1.720000e+000 -3.708218e+004 3.384262e+001 + 1.730000e+000 -3.185775e+004 3.399118e+001 + 1.740000e+000 -2.651345e+004 3.384328e+001 + 1.750000e+000 -2.127643e+004 3.342493e+001 + 1.760000e+000 -1.635786e+004 3.280502e+001 + 1.770000e+000 -1.194593e+004 3.208780e+001 + 1.780000e+000 -8.199741e+003 3.139938e+001 + 1.790000e+000 -5.244581e+003 3.086724e+001 + 1.800000e+000 -3.168440e+003 3.059416e+001 + 1.810000e+000 -2.020100e+003 3.063315e+001 + 1.820000e+000 -1.808732e+003 3.097326e+001 + 1.830000e+000 -2.505021e+003 3.154317e+001 + 1.840000e+000 -4.043733e+003 3.223079e+001 + 1.850000e+000 -6.327610e+003 3.290983e+001 + 1.860000e+000 -9.232409e+003 3.346398e+001 + 1.870000e+000 -1.261287e+004 3.380437e+001 + 1.880000e+000 -1.630935e+004 3.387977e+001 + 1.890000e+000 -2.015489e+004 3.368128e+001 + 1.900000e+000 -2.398235e+004 3.324260e+001 + 1.910000e+000 -2.763139e+004 3.263625e+001 + 1.920000e+000 -3.095504e+004 3.196515e+001 + 1.930000e+000 -3.382552e+004 3.134828e+001 + 1.940000e+000 -3.613910e+004 3.090016e+001 + 1.950000e+000 -3.781995e+004 3.070667e+001 + 1.960000e+000 -3.882263e+004 3.080398e+001 + 1.970000e+000 -3.913334e+004 3.116913e+001 + 1.980000e+000 -3.876966e+004 3.172677e+001 + 1.990000e+000 -3.777912e+004 3.236890e+001 + 2.000000e+000 -3.623635e+004 3.297900e+001 + 2.010000e+000 -3.423919e+004 3.345338e+001 + 2.020000e+000 -3.190378e+004 3.371619e+001 + 2.030000e+000 -2.935888e+004 3.372806e+001 + 2.040000e+000 -2.673975e+004 3.348978e+001 + 2.050000e+000 -2.418170e+004 3.304171e+001 + 2.060000e+000 -2.181368e+004 3.245910e+001 + 2.070000e+000 -1.975215e+004 3.184267e+001 + 2.080000e+000 -1.809551e+004 3.130354e+001 + 2.090000e+000 -1.691922e+004 3.094301e+001 + 2.100000e+000 -1.627198e+004 3.083044e+001 + 2.110000e+000 -1.617298e+004 3.098624e+001 + 2.120000e+000 -1.661042e+004 3.137671e+001 + 2.130000e+000 -1.754133e+004 3.192337e+001 + 2.140000e+000 -1.889271e+004 3.252238e+001 + 2.150000e+000 -2.056396e+004 3.306660e+001 + 2.160000e+000 -2.243051e+004 3.346419e+001 + 2.170000e+000 -2.434853e+004 3.365152e+001 + 2.180000e+000 -2.616043e+004 3.360041e+001 + 2.190000e+000 -2.770115e+004 3.332081e+001 + 2.200000e+000 -2.880478e+004 3.285934e+001 + 2.210000e+000 -2.931139e+004 3.229376e+001 + 2.220000e+000 -2.907375e+004 3.172265e+001 + 2.230000e+000 -2.796370e+004 3.124982e+001 + 2.240000e+000 -2.587791e+004 3.096450e+001 + 2.250000e+000 -2.274285e+004 3.092145e+001 + 2.260000e+000 -1.851867e+004 3.112748e+001 + 2.270000e+000 -1.320195e+004 3.153992e+001 + 2.280000e+000 -6.827173e+003 3.207790e+001 + 2.290000e+000 5.331845e+002 3.264141e+001 + 2.300000e+000 8.769898e+003 3.313144e+001 + 2.310000e+000 1.773958e+004 3.346649e+001 + 2.320000e+000 2.726851e+004 3.359357e+001 + 2.330000e+000 3.715753e+004 3.349423e+001 + 2.340000e+000 4.718792e+004 3.318618e+001 + 2.350000e+000 5.712802e+004 3.272107e+001 + 2.360000e+000 6.674025e+004 3.217802e+001 + 2.370000e+000 7.578854e+004 3.165261e+001 + 2.380000e+000 8.404559e+004 3.124092e+001 + 2.390000e+000 9.130001e+004 3.102066e+001 + 2.400000e+000 9.736293e+004 3.103352e+001 + 2.410000e+000 1.020738e+005 3.127504e+001 + 2.420000e+000 1.053055e+005 3.169600e+001 + 2.430000e+000 1.069680e+005 3.221493e+001 + 2.440000e+000 1.070113e+005 3.273647e+001 + 2.450000e+000 1.054266e+005 3.316982e+001 + 2.460000e+000 1.022469e+005 3.344323e+001 + 2.470000e+000 9.754515e+004 3.351356e+001 + 2.480000e+000 9.143232e+004 3.337115e+001 + 2.490000e+000 8.405373e+004 3.304053e+001 + 2.500000e+000 7.558448e+004 3.257735e+001 + 2.510000e+000 6.622409e+004 3.206119e+001 + 2.520000e+000 5.619045e+004 3.158376e+001 + 2.530000e+000 4.571340e+004 3.123297e+001 + 2.540000e+000 3.502800e+004 3.107511e+001 + 2.550000e+000 2.436792e+004 3.113963e+001 + 2.560000e+000 1.395894e+004 3.141205e+001 + 2.570000e+000 4.012956e+003 3.183791e+001 + 2.580000e+000 -5.277477e+003 3.233601e+001 + 2.590000e+000 -1.374381e+004 3.281597e+001 + 2.600000e+000 -2.124531e+004 3.319499e+001 + 2.610000e+000 -2.767189e+004 3.341067e+001 + 2.620000e+000 -3.294590e+004 3.342912e+001 + 2.630000e+000 -3.702294e+004 3.324881e+001 + 2.640000e+000 -3.989157e+004 3.290041e+001 + 2.650000e+000 -4.157215e+004 3.244293e+001 + 2.660000e+000 -4.211469e+004 3.195570e+001 + 2.670000e+000 -4.159601e+004 3.152611e+001 + 2.680000e+000 -4.011617e+004 3.123379e+001 + 2.690000e+000 -3.779450e+004 3.113406e+001 + 2.700000e+000 -3.476520e+004 3.124513e+001 + 2.710000e+000 -3.117276e+004 3.154388e+001 + 2.720000e+000 -2.716738e+004 3.197173e+001 + 2.730000e+000 -2.290048e+004 3.244845e+001 + 2.740000e+000 -1.852044e+004 3.288879e+001 + 2.750000e+000 -1.416879e+004 3.321762e+001 + 2.760000e+000 -9.976722e+003 3.338128e+001 + 2.770000e+000 -6.062300e+003 3.335439e+001 + 2.780000e+000 -2.528149e+003 3.314273e+001 + 2.790000e+000 5.401825e+002 3.278225e+001 + 2.800000e+000 3.075250e+003 3.233439e+001 + 2.810000e+000 5.028130e+003 3.187743e+001 + 2.820000e+000 6.368275e+003 3.149384e+001 + 2.830000e+000 7.082845e+003 3.125488e+001 + 2.840000e+000 7.175599e+003 3.120545e+001 + 2.850000e+000 6.665416e+003 3.135379e+001 + 2.860000e+000 5.584531e+003 3.166963e+001 + 2.870000e+000 3.976570e+003 3.209176e+001 + 2.880000e+000 1.894464e+003 3.254183e+001 + 2.890000e+000 -6.016664e+002 3.294008e+001 + 2.900000e+000 -3.446603e+003 3.321900e+001 + 2.910000e+000 -6.572024e+003 3.333325e+001 + 2.920000e+000 -9.908355e+003 3.326541e+001 + 2.930000e+000 -1.338644e+004 3.302786e+001 + 2.940000e+000 -1.693901e+004 3.266102e+001 + 2.950000e+000 -2.050192e+004 3.222795e+001 + 2.960000e+000 -2.401520e+004 3.180502e+001 + 2.970000e+000 -2.742382e+004 3.146913e+001 + 2.980000e+000 -3.067839e+004 3.128285e+001 + 2.990000e+000 -3.373550e+004 3.128099e+001 + 3.000000e+000 -3.655809e+004 3.146257e+001 + 3.010000e+000 -3.911559e+004 3.179130e+001 + 3.020000e+000 -4.138395e+004 3.220425e+001 + 3.030000e+000 -4.334571e+004 3.262569e+001 + 3.040000e+000 -4.498983e+004 3.298160e+001 + 3.050000e+000 -4.631164e+004 3.321207e+001 + 3.060000e+000 -4.731266e+004 3.327989e+001 + 3.070000e+000 -4.800042e+004 3.317517e+001 + 3.080000e+000 -4.838820e+004 3.291641e+001 + 3.090000e+000 -4.849479e+004 3.254792e+001 + 3.100000e+000 -4.834411e+004 3.213367e+001 + 3.110000e+000 -4.796481e+004 3.174745e+001 + 3.120000e+000 -4.738975e+004 3.146003e+001 + 3.130000e+000 -4.665542e+004 3.132515e+001 + 3.140000e+000 -4.580116e+004 3.136778e+001 + 3.150000e+000 -4.486839e+004 3.157844e+001 + 3.160000e+000 -4.389957e+004 3.191564e+001 + 3.170000e+000 -4.293717e+004 3.231555e+001 + 3.180000e+000 -4.202249e+004 3.270542e+001 + 3.190000e+000 -4.119442e+004 3.301716e+001 + 3.200000e+000 -4.048816e+004 3.319835e+001 + 3.210000e+000 -3.993392e+004 3.321962e+001 + 3.220000e+000 -3.955571e+004 3.307832e+001 + 3.230000e+000 -3.937018e+004 3.279871e+001 + 3.240000e+000 -3.938562e+004 3.242861e+001 + 3.250000e+000 -3.960112e+004 3.203257e+001 + 3.260000e+000 -4.000605e+004 3.168158e+001 + 3.270000e+000 -4.057975e+004 3.144029e+001 + 3.280000e+000 -4.129157e+004 3.135391e+001 + 3.290000e+000 -4.210125e+004 3.143824e+001 + 3.300000e+000 -4.295967e+004 3.167616e+001 + 3.310000e+000 -4.380994e+004 3.202173e+001 + 3.320000e+000 -4.458882e+004 3.241061e+001 + 3.330000e+000 -4.522855e+004 3.277311e+001 + 3.340000e+000 -4.565881e+004 3.304676e+001 + 3.350000e+000 -4.580900e+004 3.318607e+001 + 3.360000e+000 -4.561064e+004 3.316887e+001 + 3.370000e+000 -4.499987e+004 3.299899e+001 + 3.380000e+000 -4.391983e+004 3.270563e+001 + 3.390000e+000 -4.232312e+004 3.233929e+001 + 3.400000e+000 -4.017388e+004 3.196433e+001 + 3.410000e+000 -3.744974e+004 3.164836e+001 + 3.420000e+000 -3.414332e+004 3.144969e+001 + 3.430000e+000 -3.026336e+004 3.140538e+001 + 3.440000e+000 -2.583535e+004 3.152298e+001 + 3.450000e+000 -2.090164e+004 3.177898e+001 + 3.460000e+000 -1.552099e+004 3.212436e+001 + 3.470000e+000 -9.767611e+003 3.249528e+001 + 3.480000e+000 -3.729625e+003 3.282575e+001 + 3.490000e+000 2.492926e+003 3.305908e+001 + 3.500000e+000 8.790536e+003 3.315663e+001 + 3.510000e+000 1.504705e+004 3.310301e+001 + 3.520000e+000 2.114277e+004 3.290801e+001 + 3.530000e+000 2.695771e+004 3.260515e+001 + 3.540000e+000 3.237497e+004 3.224687e+001 + 3.550000e+000 3.728404e+004 3.189660e+001 + 3.560000e+000 4.158396e+004 3.161792e+001 + 3.570000e+000 4.518622e+004 3.146245e+001 + 3.580000e+000 4.801732e+004 3.145911e+001 + 3.590000e+000 5.002085e+004 3.160766e+001 + 3.600000e+000 5.115910e+004 3.187894e+001 + 3.610000e+000 5.141404e+004 3.222155e+001 + 3.620000e+000 5.078777e+004 3.257279e+001 + 3.630000e+000 4.930230e+004 3.287065e+001 + 3.640000e+000 4.699874e+004 3.306429e+001 + 3.650000e+000 4.393593e+004 3.312174e+001 + 3.660000e+000 4.018855e+004 3.303414e+001 + 3.670000e+000 3.584478e+004 3.281683e+001 + 3.680000e+000 3.100364e+004 3.250712e+001 + 3.690000e+000 2.577199e+004 3.215891e+001 + 3.700000e+000 2.026147e+004 3.183418e+001 + 3.710000e+000 1.458533e+004 3.159216e+001 + 3.720000e+000 8.855412e+003 3.147776e+001 + 3.730000e+000 3.179206e+003 3.151207e+001 + 3.740000e+000 -2.342727e+003 3.168774e+001 + 3.750000e+000 -7.619033e+003 3.197077e+001 + 3.760000e+000 -1.256939e+004 3.230812e+001 + 3.770000e+000 -1.712590e+004 3.263866e+001 + 3.780000e+000 -2.123391e+004 3.290455e+001 + 3.790000e+000 -2.485240e+004 3.306071e+001 + 3.800000e+000 -2.795386e+004 3.308153e+001 + 3.810000e+000 -3.052366e+004 3.296425e+001 + 3.820000e+000 -3.255907e+004 3.272920e+001 + 3.830000e+000 -3.406794e+004 3.241690e+001 + 3.840000e+000 -3.506708e+004 3.208205e+001 + 3.850000e+000 -3.558047e+004 3.178463e+001 + 3.860000e+000 -3.563749e+004 3.157913e+001 + 3.870000e+000 -3.527100e+004 3.150373e+001 + 3.880000e+000 -3.451570e+004 3.157209e+001 + 3.890000e+000 -3.340652e+004 3.177048e+001 + 3.900000e+000 -3.197738e+004 3.206091e+001 + 3.910000e+000 -3.026021e+004 3.238948e+001 + 3.920000e+000 -2.828428e+004 3.269717e+001 + 3.930000e+000 -2.607595e+004 3.293049e+001 + 3.940000e+000 -2.365875e+004 3.305013e+001 + 3.950000e+000 -2.105379e+004 3.303657e+001 + 3.960000e+000 -1.828047e+004 3.289276e+001 + 3.970000e+000 -1.535742e+004 3.264351e+001 + 3.980000e+000 -1.230363e+004 3.233196e+001 + 3.990000e+000 -9.139647e+003 3.201299e+001 + 4.000000e+000 -5.888761e+003 3.174407e+001 + 4.010000e+000 -2.578120e+003 3.157464e+001 + 4.020000e+000 7.603290e+002 3.153614e+001 + 4.030000e+000 4.089169e+003 3.163524e+001 + 4.040000e+000 7.365153e+003 3.185250e+001 + 4.050000e+000 1.053923e+004 3.214673e+001 + 4.060000e+000 1.355695e+004 3.246381e+001 + 4.070000e+000 1.635938e+004 3.274727e+001 + 4.080000e+000 1.888431e+004 3.294816e+001 + 4.090000e+000 2.106798e+004 3.303278e+001 + 4.100000e+000 2.284704e+004 3.298751e+001 + 4.110000e+000 2.416090e+004 3.282055e+001 + 4.120000e+000 2.495411e+004 3.256071e+001 + 4.130000e+000 2.517900e+004 3.225314e+001 + 4.140000e+000 2.479814e+004 3.195234e+001 + 4.150000e+000 2.378674e+004 3.171276e+001 + 4.160000e+000 2.213478e+004 3.157855e+001 + 4.170000e+000 1.984874e+004 3.157453e+001 + 4.180000e+000 1.695290e+004 3.170084e+001 + 4.190000e+000 1.349002e+004 3.193300e+001 + 4.200000e+000 9.521462e+003 3.222741e+001 + 4.210000e+000 5.126580e+003 3.253036e+001 + 4.220000e+000 4.014739e+002 3.278827e+001 + 4.230000e+000 -4.542974e+003 3.295688e+001 + 4.240000e+000 -9.583693e+003 3.300802e+001 + 4.250000e+000 -1.458859e+004 3.293367e+001 + 4.260000e+000 -1.942024e+004 3.274690e+001 + 4.270000e+000 -2.393986e+004 3.247997e+001 + 4.280000e+000 -2.801166e+004 3.217950e+001 + 4.290000e+000 -3.150718e+004 3.189903e+001 + 4.300000e+000 -3.430961e+004 3.168955e+001 + 4.310000e+000 -3.631787e+004 3.158974e+001 + 4.320000e+000 -3.745038e+004 3.161793e+001 + 4.330000e+000 -3.764819e+004 3.176819e+001 + 4.340000e+000 -3.687755e+004 3.201174e+001 + 4.350000e+000 -3.513170e+004 3.230322e+001 + 4.360000e+000 -3.243177e+004 3.258987e+001 + 4.370000e+000 -2.882681e+004 3.282137e+001 + 4.380000e+000 -2.439288e+004 3.295819e+001 + 4.390000e+000 -1.923120e+004 3.297762e+001 + 4.400000e+000 -1.346550e+004 3.287692e+001 + 4.410000e+000 -7.238429e+003 3.267364e+001 + 4.420000e+000 -7.074540e+002 3.240298e+001 + 4.430000e+000 5.959936e+003 3.211249e+001 + 4.440000e+000 1.259135e+004 3.185417e+001 + 4.450000e+000 1.901484e+004 3.167520e+001 + 4.460000e+000 2.506431e+004 3.160865e+001 + 4.470000e+000 3.058473e+004 3.166659e+001 + 4.480000e+000 3.543706e+004 3.183751e+001 + 4.490000e+000 3.950256e+004 3.208900e+001 + 4.500000e+000 4.268659e+004 3.237458e+001 + 4.510000e+000 4.492142e+004 3.264298e+001 + 4.520000e+000 4.616826e+004 3.284736e+001 + 4.530000e+000 4.641826e+004 3.295301e+001 + 4.540000e+000 4.569244e+004 3.294249e+001 + 4.550000e+000 4.404071e+004 3.281811e+001 + 4.560000e+000 4.153978e+004 3.260143e+001 + 4.570000e+000 3.829025e+004 3.233012e+001 + 4.580000e+000 3.441286e+004 3.205206e+001 + 4.590000e+000 3.004406e+004 3.181728e+001 + 4.600000e+000 2.533111e+004 3.166880e+001 + 4.610000e+000 2.042687e+004 3.163402e+001 + 4.620000e+000 1.548439e+004 3.171901e+001 + 4.630000e+000 1.065163e+004 3.190726e+001 + 4.640000e+000 6.066433e+003 3.216332e+001 + 4.650000e+000 1.851910e+003 3.244026e+001 + 4.660000e+000 -1.887543e+003 3.268868e+001 + 4.670000e+000 -5.069484e+003 3.286548e+001 + 4.680000e+000 -7.635799e+003 3.294076e+001 + 4.690000e+000 -9.554138e+003 3.290223e+001 + 4.700000e+000 -1.081836e+004 3.275687e+001 + 4.710000e+000 -1.144801e+004 3.252988e+001 + 4.720000e+000 -1.148677e+004 3.226086e+001 + 4.730000e+000 -1.100012e+004 3.199752e+001 + 4.740000e+000 -1.007215e+004 3.178746e+001 + 4.750000e+000 -8.801700e+003 3.166924e+001 + 4.760000e+000 -7.298050e+003 3.166463e+001 + 4.770000e+000 -5.676267e+003 3.177400e+001 + 4.780000e+000 -4.052393e+003 3.197638e+001 + 4.790000e+000 -2.538710e+003 3.223395e+001 + 4.800000e+000 -1.239217e+003 3.249984e+001 + 4.810000e+000 -2.455256e+002 3.272692e+001 + 4.820000e+000 3.666792e+002 3.287602e+001 + 4.830000e+000 5.404874e+002 3.292204e+001 + 4.840000e+000 2.398064e+002 3.285762e+001 + 4.850000e+000 -5.494671e+002 3.269414e+001 + 4.860000e+000 -1.819183e+003 3.245996e+001 + 4.870000e+000 -3.539583e+003 3.219613e+001 + 4.880000e+000 -5.660811e+003 3.194967e+001 + 4.890000e+000 -8.115228e+003 3.176533e+001 + 4.900000e+000 -1.082042e+004 3.167700e+001 + 4.910000e+000 -1.368277e+004 3.170087e+001 + 4.920000e+000 -1.660144e+004 3.183199e+001 + 4.930000e+000 -1.947264e+004 3.204544e+001 + 4.940000e+000 -2.219387e+004 3.230165e+001 + 4.950000e+000 -2.466819e+004 3.255431e+001 + 4.960000e+000 -2.680811e+004 3.275892e+001 + 4.970000e+000 -2.853908e+004 3.288036e+001 + 4.980000e+000 -2.980242e+004 3.289827e+001 + 4.990000e+000 -3.055755e+004 3.281006e+001 + 5.000000e+000 -3.078343e+004 3.263114e+001 + 5.010000e+000 -3.047917e+004 3.239263e+001 + 5.020000e+000 -2.966385e+004 3.213652e+001 + 5.030000e+000 -2.837543e+004 3.190869e+001 + 5.040000e+000 -2.666893e+004 3.175064e+001 + 5.050000e+000 -2.461389e+004 3.169147e+001 + 5.060000e+000 -2.229124e+004 3.174191e+001 + 5.070000e+000 -1.978976e+004 3.189207e+001 + 5.080000e+000 -1.720215e+004 3.211365e+001 + 5.090000e+000 -1.462106e+004 3.236584e+001 + 5.100000e+000 -1.213508e+004 3.260339e+001 + 5.110000e+000 -9.824964e+003 3.278468e+001 + 5.120000e+000 -7.760229e+003 3.287875e+001 + 5.130000e+000 -5.996202e+003 3.286990e+001 + 5.140000e+000 -4.571740e+003 3.276005e+001 + 5.150000e+000 -3.507641e+003 3.256832e+001 + 5.160000e+000 -2.805859e+003 3.232815e+001 + 5.170000e+000 -2.449518e+003 3.208198e+001 + 5.180000e+000 -2.403759e+003 3.187410e+001 + 5.190000e+000 -2.617360e+003 3.174249e+001 + 5.200000e+000 -3.025073e+003 3.171136e+001 + 5.210000e+000 -3.550575e+003 3.178617e+001 + 5.220000e+000 -4.109923e+003 3.195252e+001 + 5.230000e+000 -4.615344e+003 3.217928e+001 + 5.240000e+000 -4.979236e+003 3.242498e+001 + 5.250000e+000 -5.118180e+003 3.264578e+001 + 5.260000e+000 -4.956818e+003 3.280322e+001 + 5.270000e+000 -4.431423e+003 3.287049e+001 + 5.280000e+000 -3.493019e+003 3.283648e+001 + 5.290000e+000 -2.109912e+003 3.270734e+001 + 5.300000e+000 -2.695166e+002 3.250554e+001 + 5.310000e+000 2.020578e+003 3.226635e+001 + 5.320000e+000 4.732380e+003 3.203225e+001 + 5.330000e+000 7.818106e+003 3.184549e+001 + 5.340000e+000 1.121161e+004 3.174028e+001 + 5.350000e+000 1.483059e+004 3.173591e+001 + 5.360000e+000 1.857949e+004 3.183285e+001 + 5.370000e+000 2.235294e+004 3.201263e+001 + 5.380000e+000 2.603972e+004 3.224183e+001 + 5.390000e+000 2.952690e+004 3.247882e+001 + 5.400000e+000 3.270424e+004 3.268156e+001 + 5.410000e+000 3.546838e+004 3.281493e+001 + 5.420000e+000 3.772699e+004 3.285631e+001 + 5.430000e+000 3.940241e+004 3.279901e+001 + 5.440000e+000 4.043480e+004 3.265315e+001 + 5.450000e+000 4.078469e+004 3.244411e+001 + 5.460000e+000 4.043469e+004 3.220860e+001 + 5.470000e+000 3.939045e+004 3.198860e+001 + 5.480000e+000 3.768070e+004 3.182398e+001 + 5.490000e+000 3.535647e+004 3.174492e+001 + 5.500000e+000 3.248940e+004 3.176586e+001 + 5.510000e+000 2.916931e+004 3.188251e+001 + 5.520000e+000 2.550111e+004 3.207285e+001 + 5.530000e+000 2.160106e+004 3.230171e+001 + 5.540000e+000 1.759262e+004 3.252777e+001 + 5.550000e+000 1.360209e+004 3.271115e+001 + 5.560000e+000 9.754063e+003 3.282022e+001 + 5.570000e+000 6.166961e+003 3.283657e+001 + 5.580000e+000 2.948834e+003 3.275776e+001 + 5.590000e+000 1.935212e+002 3.259758e+001 + 5.600000e+000 -2.022632e+003 3.238398e+001 + 5.610000e+000 -3.643408e+003 3.215460e+001 + 5.620000e+000 -4.634585e+003 3.195052e+001 + 5.630000e+000 -4.984978e+003 3.180884e+001 + 5.640000e+000 -4.706623e+003 3.175556e+001 + 5.650000e+000 -3.834087e+003 3.180031e+001 + 5.660000e+000 -2.422947e+003 3.193439e+001 + 5.670000e+000 -5.474944e+002 3.213267e+001 + 5.680000e+000 1.702245e+003 3.235872e+001 + 5.690000e+000 4.224056e+003 3.257199e+001 + 5.700000e+000 6.907510e+003 3.273502e+001 + 5.710000e+000 9.638211e+003 3.281982e+001 + 5.720000e+000 1.230216e+004 3.281214e+001 + 5.730000e+000 1.479006e+004 3.271361e+001 + 5.740000e+000 1.700141e+004 3.254141e+001 + 5.750000e+000 1.884824e+004 3.232565e+001 + 5.760000e+000 2.025830e+004 3.210448e+001 + 5.770000e+000 2.117768e+004 3.191767e+001 + 5.780000e+000 2.157268e+004 3.179926e+001 + 5.790000e+000 2.143090e+004 3.177097e+001 + 5.800000e+000 2.076150e+004 3.183776e+001 + 5.810000e+000 1.959470e+004 3.198687e+001 + 5.820000e+000 1.798043e+004 3.219053e+001 + 5.830000e+000 1.598627e+004 3.241156e+001 + 5.840000e+000 1.369473e+004 3.261052e+001 + 5.850000e+000 1.120000e+004 3.275266e+001 + 5.860000e+000 8.604328e+003 3.281366e+001 + 5.870000e+000 6.014039e+003 3.278338e+001 + 5.880000e+000 3.535519e+003 3.266728e+001 + 5.890000e+000 1.271191e+003 3.248560e+001 + 5.900000e+000 -6.843159e+002 3.227020e+001 + 5.910000e+000 -2.247668e+003 3.205933e+001 + 5.920000e+000 -3.349884e+003 3.189101e+001 + 5.930000e+000 -3.938830e+003 3.179599e+001 + 5.940000e+000 -3.981069e+003 3.179164e+001 + 5.950000e+000 -3.463007e+003 3.187847e+001 + 5.960000e+000 -2.391303e+003 3.204004e+001 + 5.970000e+000 -7.925331e+002 3.224642e+001 + 5.980000e+000 1.287855e+003 3.246016e+001 + 5.990000e+000 3.787262e+003 3.264331e+001 + 6.000000e+000 6.628253e+003 3.276404e+001 + 6.010000e+000 9.721359e+003 3.280178e+001 + 6.020000e+000 1.296829e+004 3.275035e+001 + 6.030000e+000 1.626537e+004 3.261886e+001 + 6.040000e+000 1.950716e+004 3.243026e+001 + 6.050000e+000 2.259006e+004 3.221773e+001 + 6.060000e+000 2.541570e+004 3.201916e+001 + 6.070000e+000 2.789425e+004 3.187050e+001 + 6.080000e+000 2.994718e+004 3.179893e+001 + 6.090000e+000 3.150969e+004 3.181749e+001 + 6.100000e+000 3.253258e+004 3.192242e+001 + 6.110000e+000 3.298345e+004 3.209400e+001 + 6.120000e+000 3.284747e+004 3.230062e+001 + 6.130000e+000 3.212732e+004 3.250500e+001 + 6.140000e+000 3.084268e+004 3.267102e+001 + 6.150000e+000 2.902911e+004 3.276995e+001 + 6.160000e+000 2.673642e+004 3.278499e+001 + 6.170000e+000 2.402664e+004 3.271385e+001 + 6.180000e+000 2.097161e+004 3.256902e+001 + 6.190000e+000 1.765038e+004 3.237582e+001 + 6.200000e+000 1.414651e+004 3.216836e+001 + 6.210000e+000 1.054523e+004 3.198380e+001 + 6.220000e+000 6.930780e+003 3.185562e+001 + 6.230000e+000 3.383921e+003 3.180731e+001 + 6.240000e+000 -2.036920e+001 3.184757e+001 + 6.250000e+000 -3.214799e+003 3.196864e+001 + 6.260000e+000 -6.141318e+003 3.214790e+001 + 6.270000e+000 -8.752238e+003 3.235252e+001 + 6.280000e+000 -1.101092e+004 3.254575e+001 + 6.290000e+000 -1.289201e+004 3.269361e+001 + 6.300000e+000 -1.438126e+004 3.277060e+001 + 6.310000e+000 -1.547497e+004 3.276369e+001 + 6.320000e+000 -1.617907e+004 3.267434e+001 + 6.330000e+000 -1.650791e+004 3.251818e+001 + 6.340000e+000 -1.648286e+004 3.232255e+001 + 6.350000e+000 -1.613081e+004 3.212213e+001 + 6.360000e+000 -1.548250e+004 3.195294e+001 + 6.370000e+000 -1.457096e+004 3.184576e+001 + 6.380000e+000 -1.342999e+004 3.182023e+001 + 6.390000e+000 -1.209283e+004 3.188084e+001 + 6.400000e+000 -1.059095e+004 3.201608e+001 + 6.410000e+000 -8.953125e+003 3.220086e+001 + 6.420000e+000 -7.204827e+003 3.240151e+001 + 6.430000e+000 -5.367804e+003 3.258220e+001 + 6.440000e+000 -3.460002e+003 3.271129e+001 + 6.450000e+000 -1.495728e+003 3.276659e+001 + 6.460000e+000 5.139370e+002 3.273880e+001 + 6.470000e+000 2.560535e+003 3.263294e+001 + 6.480000e+000 4.637466e+003 3.246749e+001 + 6.490000e+000 6.739134e+003 3.227150e+001 + 6.500000e+000 8.860037e+003 3.207980e+001 + 6.510000e+000 1.099388e+004 3.192694e+001 + 6.520000e+000 1.313278e+004 3.184079e+001 + 6.530000e+000 1.526652e+004 3.183711e+001 + 6.540000e+000 1.738207e+004 3.191633e+001 + 6.550000e+000 1.946324e+004 3.206356e+001 + 6.560000e+000 2.149058e+004 3.225161e+001 + 6.570000e+000 2.344151e+004 3.244643e+001 + 6.580000e+000 2.529067e+004 3.261341e+001 + 6.590000e+000 2.701059e+004 3.272346e+001 + 6.600000e+000 2.857240e+004 3.275773e+001 + 6.610000e+000 2.994687e+004 3.271056e+001 + 6.620000e+000 3.110546e+004 3.259030e+001 + 6.630000e+000 3.202150e+004 3.241796e+001 + 6.640000e+000 3.267138e+004 3.222389e+001 + 6.650000e+000 3.303573e+004 3.204268e+001 + 6.660000e+000 3.310042e+004 3.190711e+001 + 6.670000e+000 3.285751e+004 3.184190e+001 + 6.680000e+000 3.230600e+004 3.185891e+001 + 6.690000e+000 3.145224e+004 3.195476e+001 + 6.700000e+000 3.031024e+004 3.211151e+001 + 6.710000e+000 2.890156e+004 3.230037e+001 + 6.720000e+000 2.725499e+004 3.248731e+001 + 6.730000e+000 2.540591e+004 3.263927e+001 + 6.740000e+000 2.339540e+004 3.272989e+001 + 6.750000e+000 2.126909e+004 3.274372e+001 + 6.760000e+000 1.907583e+004 3.267862e+001 + 6.770000e+000 1.686622e+004 3.254604e+001 + 6.780000e+000 1.469102e+004 3.236919e+001 + 6.790000e+000 1.259948e+004 3.217932e+001 + 6.800000e+000 1.063783e+004 3.201042e+001 + 6.810000e+000 8.847699e+003 3.189310e+001 + 6.820000e+000 7.264766e+003 3.184878e+001 + 6.830000e+000 5.917599e+003 3.188546e+001 + 6.840000e+000 4.826719e+003 3.199610e+001 + 6.850000e+000 4.003948e+003 3.216011e+001 + 6.860000e+000 3.452070e+003 3.234752e+001 + 6.870000e+000 3.164796e+003 3.252469e+001 + 6.880000e+000 3.127066e+003 3.266044e+001 + 6.890000e+000 3.315640e+003 3.273128e+001 + 6.900000e+000 3.699996e+003 3.272519e+001 + 6.910000e+000 4.243458e+003 3.264344e+001 + 6.920000e+000 4.904554e+003 3.250035e+001 + 6.930000e+000 5.638511e+003 3.232104e+001 + 6.940000e+000 6.398868e+003 3.213728e+001 + 6.950000e+000 7.139117e+003 3.198209e+001 + 6.960000e+000 7.814326e+003 3.188364e+001 + 6.970000e+000 8.382688e+003 3.185993e+001 + 6.980000e+000 8.806920e+003 3.191512e+001 + 6.990000e+000 9.055484e+003 3.203880e+001 + 7.000000e+000 9.103573e+003 3.220807e+001 + 7.010000e+000 8.933841e+003 3.239214e+001 + 7.020000e+000 8.536834e+003 3.255815e+001 + 7.030000e+000 7.911140e+003 3.267700e+001 + 7.040000e+000 7.063234e+003 3.272820e+001 + 7.050000e+000 6.007039e+003 3.270313e+001 + 7.060000e+000 4.763226e+003 3.260632e+001 + 7.070000e+000 3.358291e+003 3.245474e+001 + 7.080000e+000 1.823431e+003 3.227504e+001 + 7.090000e+000 1.932904e+002 3.209920e+001 + 7.100000e+000 -1.495390e+003 3.195888e+001 + 7.110000e+000 -3.205160e+003 3.187963e+001 + 7.120000e+000 -4.899224e+003 3.187590e+001 + 7.130000e+000 -6.542743e+003 3.194817e+001 + 7.140000e+000 -8.104011e+003 3.208289e+001 + 7.150000e+000 -9.555477e+003 3.225524e+001 + 7.160000e+000 -1.087457e+004 3.243403e+001 + 7.170000e+000 -1.204430e+004 3.258747e+001 + 7.180000e+000 -1.305362e+004 3.268875e+001 + 7.190000e+000 -1.389757e+004 3.272049e+001 + 7.200000e+000 -1.457711e+004 3.267740e+001 + 7.210000e+000 -1.509882e+004 3.256713e+001 + 7.220000e+000 -1.547431e+004 3.240899e+001 + 7.230000e+000 -1.571949e+004 3.223088e+001 + 7.240000e+000 -1.585371e+004 3.206458e+001 + 7.250000e+000 -1.589876e+004 3.194015e+001 + 7.260000e+000 -1.587784e+004 3.188025e+001 + 7.270000e+000 -1.581451e+004 3.189580e+001 + 7.280000e+000 -1.573168e+004 3.198370e+001 + 7.290000e+000 -1.565063e+004 3.212759e+001 + 7.300000e+000 -1.559021e+004 3.230108e+001 + 7.310000e+000 -1.556611e+004 3.247293e+001 + 7.320000e+000 -1.559031e+004 3.261271e+001 + 7.330000e+000 -1.567080e+004 3.269611e+001 + 7.340000e+000 -1.581130e+004 3.270883e+001 + 7.350000e+000 -1.601140e+004 3.264888e+001 + 7.360000e+000 -1.626669e+004 3.252679e+001 + 7.370000e+000 -1.656919e+004 3.236398e+001 + 7.380000e+000 -1.690784e+004 3.218924e+001 + 7.390000e+000 -1.726917e+004 3.203383e+001 + 7.400000e+000 -1.763803e+004 3.192589e+001 + 7.410000e+000 -1.799837e+004 3.188510e+001 + 7.420000e+000 -1.833403e+004 3.191881e+001 + 7.430000e+000 -1.862956e+004 3.202060e+001 + 7.440000e+000 -1.887092e+004 3.217158e+001 + 7.450000e+000 -1.904616e+004 3.234423e+001 + 7.460000e+000 -1.914594e+004 3.250756e+001 + 7.470000e+000 -1.916392e+004 3.263279e+001 + 7.480000e+000 -1.909708e+004 3.269820e+001 + 7.490000e+000 -1.894578e+004 3.269264e+001 + 7.500000e+000 -1.871375e+004 3.261728e+001 + 7.510000e+000 -1.840789e+004 3.248532e+001 + 7.520000e+000 -1.803793e+004 3.231995e+001 + 7.530000e+000 -1.761600e+004 3.215050e+001 + 7.540000e+000 -1.715606e+004 3.200739e+001 + 7.550000e+000 -1.667333e+004 3.191657e+001 + 7.560000e+000 -1.618357e+004 3.189459e+001 + 7.570000e+000 -1.570248e+004 3.194533e+001 + 7.580000e+000 -1.524497e+004 3.205922e+001 + 7.590000e+000 -1.482461e+004 3.221523e+001 + 7.600000e+000 -1.445307e+004 3.238503e+001 + 7.610000e+000 -1.413965e+004 3.253828e+001 + 7.620000e+000 -1.389099e+004 3.264807e+001 + 7.630000e+000 -1.371080e+004 3.269542e+001 + 7.640000e+000 -1.359981e+004 3.267231e+001 + 7.650000e+000 -1.355580e+004 3.258292e+001 + 7.660000e+000 -1.357377e+004 3.244293e+001 + 7.670000e+000 -1.364620e+004 3.227699e+001 + 7.680000e+000 -1.376347e+004 3.211462e+001 + 7.690000e+000 -1.391429e+004 3.198506e+001 + 7.700000e+000 -1.408624e+004 3.191185e+001 + 7.710000e+000 -1.426632e+004 3.190832e+001 + 7.720000e+000 -1.444151e+004 3.197493e+001 + 7.730000e+000 -1.459934e+004 3.209924e+001 + 7.740000e+000 -1.472840e+004 3.225838e+001 + 7.750000e+000 -1.481881e+004 3.242358e+001 + 7.760000e+000 -1.486258e+004 3.256545e+001 + 7.770000e+000 -1.485390e+004 3.265915e+001 + 7.780000e+000 -1.478934e+004 3.268853e+001 + 7.790000e+000 -1.466793e+004 3.264869e+001 + 7.800000e+000 -1.449111e+004 3.254668e+001 + 7.810000e+000 -1.426265e+004 3.240040e+001 + 7.820000e+000 -1.398834e+004 3.223567e+001 + 7.830000e+000 -1.367576e+004 3.208189e+001 + 7.840000e+000 -1.333386e+004 3.196682e+001 + 7.850000e+000 -1.297255e+004 3.191139e+001 + 7.860000e+000 -1.260223e+004 3.192567e+001 + 7.870000e+000 -1.223335e+004 3.200685e+001 + 7.880000e+000 -1.187594e+004 3.213983e+001 + 7.890000e+000 -1.153921e+004 3.230029e+001 + 7.900000e+000 -1.123118e+004 3.245932e+001 + 7.910000e+000 -1.095836e+004 3.258875e+001 + 7.920000e+000 -1.072553e+004 3.266600e+001 + 7.930000e+000 -1.053562e+004 3.267780e+001 + 7.940000e+000 -1.038961e+004 3.262227e+001 + 7.950000e+000 -1.028659e+004 3.250918e+001 + 7.960000e+000 -1.022389e+004 3.235840e+001 + 7.970000e+000 -1.019721e+004 3.219661e+001 + 7.980000e+000 -1.020094e+004 3.205276e+001 + 7.990000e+000 -1.022844e+004 3.195286e+001 + 8.000000e+000 -1.027238e+004 3.191512e+001 + 8.010000e+000 -1.032509e+004 3.194633e+001 + 8.020000e+000 -1.037896e+004 3.204056e+001 + 8.030000e+000 -1.042674e+004 3.218039e+001 + 8.040000e+000 -1.046191e+004 3.234034e+001 + 8.050000e+000 -1.047892e+004 3.249174e+001 + 8.060000e+000 -1.047339e+004 3.260786e+001 + 8.070000e+000 -1.044233e+004 3.266852e+001 + 8.080000e+000 -1.038415e+004 3.266334e+001 + 8.090000e+000 -1.029874e+004 3.259340e+001 + 8.100000e+000 -1.018735e+004 3.247096e+001 + 8.110000e+000 -1.005252e+004 3.231758e+001 + 8.120000e+000 -9.897849e+003 3.216048e+001 + 8.130000e+000 -9.727824e+003 3.202785e+001 + 8.140000e+000 -9.547510e+003 3.194372e+001 + 8.150000e+000 -9.362282e+003 3.192342e+001 + 8.160000e+000 -9.177534e+003 3.197052e+001 + 8.170000e+000 -8.998388e+003 3.207620e+001 + 8.180000e+000 -8.829426e+003 3.222099e+001 + 8.190000e+000 -8.674467e+003 3.237862e+001 + 8.200000e+000 -8.536368e+003 3.252094e+001 + 8.210000e+000 -8.416894e+003 3.262292e+001 + 8.220000e+000 -8.316639e+003 3.266690e+001 + 8.230000e+000 -8.235010e+003 3.264540e+001 + 8.240000e+000 -8.170266e+003 3.256229e+001 + 8.250000e+000 -8.119629e+003 3.243219e+001 + 8.260000e+000 -8.079429e+003 3.227801e+001 + 8.270000e+000 -8.045308e+003 3.212721e+001 + 8.280000e+000 -8.012452e+003 3.200691e+001 + 8.290000e+000 -7.975842e+003 3.193895e+001 + 8.300000e+000 -7.930517e+003 3.193568e+001 + 8.310000e+000 -7.871838e+003 3.199756e+001 + 8.320000e+000 -7.795729e+003 3.211305e+001 + 8.330000e+000 -7.698890e+003 3.226097e+001 + 8.340000e+000 -7.578977e+003 3.241460e+001 + 8.350000e+000 -7.434731e+003 3.254660e+001 + 8.360000e+000 -7.266053e+003 3.263384e+001 + 8.370000e+000 -7.074025e+003 3.266126e+001 + 8.380000e+000 -6.860871e+003 3.262426e+001 + 8.390000e+000 -6.629863e+003 3.252941e+001 + 8.400000e+000 -6.385178e+003 3.239337e+001 + 8.410000e+000 -6.131705e+003 3.224020e+001 + 8.420000e+000 -5.874821e+003 3.209722e+001 + 8.430000e+000 -5.620143e+003 3.199023e+001 + 8.440000e+000 -5.373262e+003 3.193867e+001 + 8.450000e+000 -5.139483e+003 3.195188e+001 + 8.460000e+000 -4.923569e+003 3.202727e+001 + 8.470000e+000 -4.729516e+003 3.215086e+001 + 8.480000e+000 -4.560357e+003 3.230007e+001 + 8.490000e+000 -4.418013e+003 3.244803e+001 + 8.500000e+000 -4.303192e+003 3.256851e+001 + 8.510000e+000 -4.215343e+003 3.264045e+001 + 8.520000e+000 -4.152671e+003 3.265147e+001 + 8.530000e+000 -4.112205e+003 3.259979e+001 + 8.540000e+000 -4.089921e+003 3.249454e+001 + 8.550000e+000 -4.080918e+003 3.235423e+001 + 8.560000e+000 -4.079624e+003 3.220372e+001 + 8.570000e+000 -4.080047e+003 3.206995e+001 + 8.580000e+000 -4.076037e+003 3.197711e+001 + 8.590000e+000 -4.061555e+003 3.194209e+001 + 8.600000e+000 -4.030947e+003 3.197121e+001 + 8.610000e+000 -3.979195e+003 3.205896e+001 + 8.620000e+000 -3.902139e+003 3.218916e+001 + 8.630000e+000 -3.796668e+003 3.233811e+001 + 8.640000e+000 -3.660860e+003 3.247911e+001 + 8.650000e+000 -3.494075e+003 3.258726e+001 + 8.660000e+000 -3.296982e+003 3.264371e+001 + 8.670000e+000 -3.071540e+003 3.263877e+001 + 8.680000e+000 -2.820912e+003 3.257345e+001 + 8.690000e+000 -2.549338e+003 3.245923e+001 + 8.700000e+000 -2.261947e+003 3.231622e+001 + 8.710000e+000 -1.964540e+003 3.216983e+001 + 8.720000e+000 -1.663342e+003 3.204633e+001 + 8.730000e+000 -1.364734e+003 3.196808e+001 + 8.740000e+000 -1.074980e+003 3.194931e+001 + 8.750000e+000 -7.999615e+002 3.199337e+001 + 8.760000e+000 -5.449243e+002 3.209201e+001 + 8.770000e+000 -3.142606e+002 3.222712e+001 + 8.780000e+000 -1.113252e+002 3.237421e+001 + 8.790000e+000 6.170143e+001 3.250703e+001 + 8.800000e+000 2.038975e+002 3.260220e+001 + 8.810000e+000 3.156294e+002 3.264319e+001 + 8.820000e+000 3.985247e+002 3.262303e+001 + 8.830000e+000 4.553893e+002 3.254535e+001 + 8.840000e+000 4.900748e+002 3.242380e+001 + 8.850000e+000 5.072998e+002 3.227984e+001 + 8.860000e+000 5.124344e+002 3.213910e+001 + 8.870000e+000 5.112583e+002 3.202689e+001 + 8.880000e+000 5.097012e+002 3.196356e+001 + 8.890000e+000 5.135797e+002 3.196061e+001 + 8.900000e+000 5.283399e+002 3.201845e+001 + 8.910000e+000 5.588187e+002 3.212634e+001 + 8.920000e+000 6.090338e+002 3.226452e+001 + 8.930000e+000 6.820103e+002 3.240805e+001 + 8.940000e+000 7.796540e+002 3.253138e+001 + 8.950000e+000 9.026734e+002 3.261287e+001 + 8.960000e+000 1.050557e+003 3.263841e+001 + 8.970000e+000 1.221601e+003 3.260371e+001 + 8.980000e+000 1.412999e+003 3.251491e+001 + 8.990000e+000 1.620964e+003 3.238764e+001 + 9.000000e+000 1.840911e+003 3.224440e+001 + 9.010000e+000 2.067660e+003 3.211076e+001 + 9.020000e+000 2.295673e+003 3.201080e+001 + 9.030000e+000 2.519298e+003 3.196268e+001 + 9.040000e+000 2.733023e+003 3.197511e+001 + 9.050000e+000 2.931717e+003 3.204568e+001 + 9.060000e+000 3.110856e+003 3.216133e+001 + 9.070000e+000 3.266719e+003 3.230098e+001 + 9.080000e+000 3.396546e+003 3.243951e+001 + 9.090000e+000 3.498656e+003 3.255235e+001 + 9.100000e+000 3.572509e+003 3.261977e+001 + 9.110000e+000 3.618726e+003 3.263013e+001 + 9.120000e+000 3.639049e+003 3.258177e+001 + 9.130000e+000 3.636257e+003 3.248322e+001 + 9.140000e+000 3.614034e+003 3.235183e+001 + 9.150000e+000 3.576797e+003 3.221088e+001 + 9.160000e+000 3.529493e+003 3.208559e+001 + 9.170000e+000 3.477374e+003 3.199858e+001 + 9.180000e+000 3.425761e+003 3.196564e+001 + 9.190000e+000 3.379807e+003 3.199269e+001 + 9.200000e+000 3.344265e+003 3.207464e+001 + 9.210000e+000 3.323279e+003 3.219637e+001 + 9.220000e+000 3.320205e+003 3.233576e+001 + 9.230000e+000 3.337469e+003 3.246782e+001 + 9.240000e+000 3.376463e+003 3.256920e+001 + 9.250000e+000 3.437493e+003 3.262224e+001 + 9.260000e+000 3.519780e+003 3.261781e+001 + 9.270000e+000 3.621501e+003 3.255682e+001 + 9.280000e+000 3.739888e+003 3.245002e+001 + 9.290000e+000 3.871360e+003 3.231625e+001 + 9.300000e+000 4.011703e+003 3.217929e+001 + 9.310000e+000 4.156265e+003 3.206371e+001 + 9.320000e+000 4.300187e+003 3.199042e+001 + 9.330000e+000 4.438626e+003 3.197273e+001 + 9.340000e+000 4.566991e+003 3.201376e+001 + 9.350000e+000 4.681160e+003 3.210586e+001 + 9.360000e+000 4.777678e+003 3.223212e+001 + 9.370000e+000 4.853927e+003 3.236965e+001 + 9.380000e+000 4.908250e+003 3.249388e+001 + 9.390000e+000 4.940044e+003 3.258291e+001 + 9.400000e+000 4.949794e+003 3.262124e+001 + 9.410000e+000 4.939063e+003 3.260232e+001 + 9.420000e+000 4.910433e+003 3.252954e+001 + 9.430000e+000 4.867395e+003 3.241573e+001 + 9.440000e+000 4.814207e+003 3.228099e+001 + 9.450000e+000 4.755703e+003 3.214932e+001 + 9.460000e+000 4.697088e+003 3.204441e+001 + 9.470000e+000 4.643708e+003 3.198525e+001 + 9.480000e+000 4.600809e+003 3.198260e+001 + 9.490000e+000 4.573311e+003 3.203681e+001 + 9.500000e+000 4.565579e+003 3.213784e+001 + 9.510000e+000 4.581232e+003 3.226722e+001 + 9.520000e+000 4.622974e+003 3.240158e+001 + 9.530000e+000 4.692466e+003 3.251701e+001 + 9.540000e+000 4.790245e+003 3.259320e+001 + 9.550000e+000 4.915691e+003 3.261694e+001 + 9.560000e+000 5.067045e+003 3.258420e+001 + 9.570000e+000 5.241471e+003 3.250078e+001 + 9.580000e+000 5.435177e+003 3.238138e+001 + 9.590000e+000 5.643565e+003 3.224711e+001 + 9.600000e+000 5.861426e+003 3.212195e+001 + 9.610000e+000 6.083157e+003 3.202846e+001 + 9.620000e+000 6.303003e+003 3.198358e+001 + 9.630000e+000 6.515294e+003 3.199544e+001 + 9.640000e+000 6.714693e+003 3.206175e+001 + 9.650000e+000 6.896423e+003 3.217027e+001 + 9.660000e+000 7.056471e+003 3.230123e+001 + 9.670000e+000 7.191761e+003 3.243106e+001 + 9.680000e+000 7.300289e+003 3.253673e+001 + 9.690000e+000 7.381204e+003 3.259970e+001 + 9.700000e+000 7.434852e+003 3.260909e+001 + 9.710000e+000 7.462755e+003 3.256335e+001 + 9.720000e+000 7.467548e+003 3.247055e+001 + 9.730000e+000 7.452861e+003 3.234704e+001 + 9.740000e+000 7.423166e+003 3.221472e+001 + 9.750000e+000 7.383571e+003 3.209725e+001 + 9.760000e+000 7.339601e+003 3.201584e+001 + 9.770000e+000 7.296952e+003 3.198526e+001 + 9.780000e+000 7.261234e+003 3.201100e+001 + 9.790000e+000 7.237714e+003 3.208824e+001 + 9.800000e+000 7.231084e+003 3.220278e+001 + 9.810000e+000 7.245234e+003 3.233382e+001 + 9.820000e+000 7.283066e+003 3.245786e+001 + 9.830000e+000 7.346352e+003 3.255297e+001 + 9.840000e+000 7.435628e+003 3.260253e+001 + 9.850000e+000 7.550149e+003 3.259799e+001 + 9.860000e+000 7.687887e+003 3.254025e+001 + 9.870000e+000 7.845597e+003 3.243947e+001 + 9.880000e+000 8.018918e+003 3.231343e+001 + 9.890000e+000 8.202534e+003 3.218454e+001 + 9.900000e+000 8.390366e+003 3.207590e+001 + 9.910000e+000 8.575812e+003 3.200715e+001 + 9.920000e+000 8.751991e+003 3.199076e+001 + 9.930000e+000 8.912017e+003 3.202964e+001 + 9.940000e+000 9.049269e+003 3.211655e+001 + 9.950000e+000 9.157655e+003 3.223557e+001 + 9.960000e+000 9.231854e+003 3.236517e+001 + 9.970000e+000 9.267531e+003 3.248218e+001 + 9.980000e+000 9.261518e+003 3.256598e+001 + 9.990000e+000 9.211946e+003 3.260196e+001 + 1.000000e+001 9.118325e+003 3.258395e+001 + 1.001000e+001 8.981582e+003 3.251520e+001 + 1.002000e+001 8.804027e+003 3.240781e+001 + 1.003000e+001 8.589282e+003 3.228075e+001 + 1.004000e+001 8.342150e+003 3.215667e+001 + 1.005000e+001 8.068440e+003 3.205787e+001 + 1.006000e+001 7.774758e+003 3.200222e+001 + 1.007000e+001 7.468263e+003 3.199983e+001 + 1.008000e+001 7.156404e+003 3.205103e+001 + 1.009000e+001 6.846652e+003 3.214635e+001 + 1.010000e+001 6.546228e+003 3.226840e+001 + 1.011000e+001 6.261839e+003 3.239517e+001 + 1.012000e+001 5.999448e+003 3.250409e+001 + 1.013000e+001 5.764062e+003 3.257601e+001 + 1.014000e+001 5.559563e+003 3.259844e+001 + 1.015000e+001 5.388588e+003 3.256757e+001 + 1.016000e+001 5.252452e+003 3.248889e+001 + 1.017000e+001 5.151123e+003 3.237624e+001 + 1.018000e+001 5.083255e+003 3.224959e+001 + 1.019000e+001 5.046263e+003 3.213152e+001 + 1.020000e+001 5.036449e+003 3.204330e+001 + 1.021000e+001 5.049170e+003 3.200091e+001 + 1.022000e+001 5.079031e+003 3.201201e+001 + 1.023000e+001 5.120116e+003 3.207444e+001 + 1.024000e+001 5.166225e+003 3.217672e+001 + 1.025000e+001 5.211123e+003 3.230023e+001 + 1.026000e+001 5.248780e+003 3.242276e+001 + 1.027000e+001 5.273604e+003 3.252256e+001 + 1.028000e+001 5.280648e+003 3.258215e+001 + 1.029000e+001 5.265786e+003 3.259119e+001 + 1.030000e+001 5.225861e+003 3.254822e+001 + 1.031000e+001 5.158779e+003 3.246083e+001 + 1.032000e+001 5.063570e+003 3.234445e+001 + 1.033000e+001 4.940394e+003 3.221972e+001 + 1.034000e+001 4.790513e+003 3.210895e+001 + 1.035000e+001 4.616206e+003 3.203213e+001 + 1.036000e+001 4.420661e+003 3.200318e+001 + 1.037000e+001 4.207821e+003 3.202729e+001 + 1.038000e+001 3.982210e+003 3.209995e+001 + 1.039000e+001 3.748742e+003 3.220781e+001 + 1.040000e+001 3.512516e+003 3.233130e+001 + 1.041000e+001 3.278611e+003 3.244828e+001 + 1.042000e+001 3.051890e+003 3.253806e+001 + 1.043000e+001 2.836817e+003 3.258492e+001 + 1.044000e+001 2.637295e+003 3.258078e+001 + 1.045000e+001 2.456539e+003 3.252645e+001 + 1.046000e+001 2.296968e+003 3.243153e+001 + 1.047000e+001 2.160154e+003 3.231278e+001 + 1.048000e+001 2.046785e+003 3.219132e+001 + 1.049000e+001 1.956688e+003 3.208892e+001 + 1.050000e+001 1.888870e+003 3.202408e+001 + 1.051000e+001 1.841607e+003 3.200855e+001 + 1.052000e+001 1.812549e+003 3.204508e+001 + 1.053000e+001 1.798855e+003 3.212688e+001 + 1.054000e+001 1.797342e+003 3.223898e+001 + 1.055000e+001 1.804646e+003 3.236110e+001 + 1.056000e+001 1.817377e+003 3.247143e+001 + 1.057000e+001 1.832278e+003 3.255048e+001 + 1.058000e+001 1.846367e+003 3.258448e+001 + 1.059000e+001 1.857059e+003 3.256757e+001 + 1.060000e+001 1.862266e+003 3.250282e+001 + 1.061000e+001 1.860474e+003 3.240163e+001 + 1.062000e+001 1.850778e+003 3.228192e+001 + 1.063000e+001 1.832899e+003 3.216502e+001 + 1.064000e+001 1.807156e+003 3.207194e+001 + 1.065000e+001 1.774421e+003 3.201950e+001 + 1.066000e+001 1.736039e+003 3.201722e+001 + 1.067000e+001 1.693725e+003 3.206540e+001 + 1.068000e+001 1.649449e+003 3.215515e+001 + 1.069000e+001 1.605307e+003 3.227009e+001 + 1.070000e+001 1.563382e+003 3.238950e+001 + 1.071000e+001 1.525617e+003 3.249210e+001 + 1.072000e+001 1.493686e+003 3.255983e+001 + 1.073000e+001 1.468887e+003 3.258091e+001 + 1.074000e+001 1.452048e+003 3.255174e+001 + 1.075000e+001 1.443465e+003 3.247752e+001 + 1.076000e+001 1.442858e+003 3.237134e+001 + 1.077000e+001 1.449366e+003 3.225203e+001 + 1.078000e+001 1.461567e+003 3.214089e+001 + 1.079000e+001 1.477527e+003 3.205794e+001 + 1.080000e+001 1.494883e+003 3.201820e+001 + 1.081000e+001 1.510942e+003 3.202885e+001 + 1.082000e+001 1.522804e+003 3.208785e+001 + 1.083000e+001 1.527502e+003 3.218434e+001 + 1.084000e+001 1.522144e+003 3.230079e+001 + 1.085000e+001 1.504060e+003 3.241626e+001 + 1.086000e+001 1.470947e+003 3.251023e+001 + 1.087000e+001 1.420994e+003 3.256621e+001 + 1.088000e+001 1.352996e+003 3.257448e+001 + 1.089000e+001 1.266445e+003 3.253370e+001 + 1.090000e+001 1.161588e+003 3.245107e+001 + 1.091000e+001 1.039455e+003 3.234118e+001 + 1.092000e+001 9.018595e+002 3.222356e+001 + 1.093000e+001 7.513590e+002 3.211925e+001 + 1.094000e+001 5.911837e+002 3.204706e+001 + 1.095000e+001 4.251363e+002 3.202009e+001 + 1.096000e+001 2.574633e+002 3.204316e+001 + 1.097000e+001 9.270381e+001 3.211199e+001 + 1.098000e+001 -6.447751e+001 3.221394e+001 + 1.099000e+001 -2.094684e+002 3.233054e+001 + 1.100000e+001 -3.378891e+002 3.244089e+001 + 1.101000e+001 -4.457690e+002 3.252546e+001 + 1.102000e+001 -5.297107e+002 3.256942e+001 + 1.103000e+001 -5.870365e+002 3.256519e+001 + 1.104000e+001 -6.159103e+002 3.251359e+001 + 1.105000e+001 -6.154290e+002 3.242374e+001 + 1.106000e+001 -5.856808e+002 3.231153e+001 + 1.107000e+001 -5.277664e+002 3.219693e+001 + 1.108000e+001 -4.437822e+002 3.210051e+001 + 1.109000e+001 -3.367658e+002 3.203968e+001 + 1.110000e+001 -2.106054e+002 3.202547e+001 + 1.111000e+001 -6.991542e+001 3.206039e+001 + 1.112000e+001 8.011574e+001 3.213799e+001 + 1.113000e+001 2.339014e+002 3.224408e+001 + 1.114000e+001 3.856486e+002 3.235949e+001 + 1.115000e+001 5.295601e+002 3.246359e+001 + 1.116000e+001 6.600372e+002 3.253800e+001 + 1.117000e+001 7.718772e+002 3.256971e+001 + 1.118000e+001 8.604570e+002 3.255326e+001 + 1.119000e+001 9.218971e+002 3.249161e+001 + 1.120000e+001 9.531975e+002 3.239565e+001 + 1.121000e+001 9.523435e+002 3.228236e+001 + 1.122000e+001 9.183739e+002 3.217196e+001 + 1.123000e+001 8.514125e+002 3.208429e+001 + 1.124000e+001 7.526590e+002 3.203521e+001 + 1.125000e+001 6.243412e+002 3.203362e+001 + 1.126000e+001 4.696301e+002 3.207973e+001 + 1.127000e+001 2.925213e+002 3.216506e+001 + 1.128000e+001 9.768722e+001 3.227407e+001 + 1.129000e+001 -1.096945e+002 3.238711e+001 + 1.130000e+001 -3.241289e+002 3.248406e+001 + 1.131000e+001 -5.400016e+002 3.254782e+001 + 1.132000e+001 -7.517785e+002 3.256729e+001 + 1.133000e+001 -9.542008e+002 3.253914e+001 + 1.134000e+001 -1.142466e+003 3.246837e+001 + 1.135000e+001 -1.312391e+003 3.236747e+001 + 1.136000e+001 -1.460549e+003 3.225433e+001 + 1.137000e+001 -1.584376e+003 3.214916e+001 + 1.138000e+001 -1.682243e+003 3.207089e+001 + 1.139000e+001 -1.753494e+003 3.203369e+001 + 1.140000e+001 -1.798446e+003 3.204428e+001 + 1.141000e+001 -1.818347e+003 3.210065e+001 + 1.142000e+001 -1.815311e+003 3.219246e+001 + 1.143000e+001 -1.792212e+003 3.230302e+001 + 1.144000e+001 -1.752552e+003 3.241248e+001 + 1.145000e+001 -1.700315e+003 3.250138e+001 + 1.146000e+001 -1.639793e+003 3.255412e+001 + 1.147000e+001 -1.575420e+003 3.256150e+001 + 1.148000e+001 -1.511588e+003 3.252233e+001 + 1.149000e+001 -1.452481e+003 3.244353e+001 + 1.150000e+001 -1.401915e+003 3.233901e+001 + 1.151000e+001 -1.363194e+003 3.222733e+001 + 1.152000e+001 -1.338998e+003 3.212848e+001 + 1.153000e+001 -1.331290e+003 3.206028e+001 + 1.154000e+001 -1.341255e+003 3.203507e+001 + 1.155000e+001 -1.369277e+003 3.205738e+001 + 1.156000e+001 -1.414942e+003 3.212304e+001 + 1.157000e+001 -1.477076e+003 3.222005e+001 + 1.158000e+001 -1.553813e+003 3.233082e+001 + 1.159000e+001 -1.642688e+003 3.243551e+001 + 1.160000e+001 -1.740757e+003 3.251557e+001 + 1.161000e+001 -1.844726e+003 3.255694e+001 + 1.162000e+001 -1.951095e+003 3.255247e+001 + 1.163000e+001 -2.056316e+003 3.250301e+001 + 1.164000e+001 -2.156932e+003 3.241729e+001 + 1.165000e+001 -2.249726e+003 3.231047e+001 + 1.166000e+001 -2.331847e+003 3.220156e+001 + 1.167000e+001 -2.400922e+003 3.211009e+001 + 1.168000e+001 -2.455147e+003 3.205258e+001 + 1.169000e+001 -2.493349e+003 3.203944e+001 + 1.170000e+001 -2.515024e+003 3.207300e+001 + 1.171000e+001 -2.520346e+003 3.214706e+001 + 1.172000e+001 -2.510144e+003 3.224811e+001 + 1.173000e+001 -2.485856e+003 3.235788e+001 + 1.174000e+001 -2.449458e+003 3.245678e+001 + 1.175000e+001 -2.403373e+003 3.252731e+001 + 1.176000e+001 -2.350356e+003 3.255713e+001 + 1.177000e+001 -2.293379e+003 3.254109e+001 + 1.178000e+001 -2.235498e+003 3.248206e+001 + 1.179000e+001 -2.179726e+003 3.239045e+001 + 1.180000e+001 -2.128910e+003 3.228247e+001 + 1.181000e+001 -2.085611e+003 3.217738e+001 + 1.182000e+001 -2.052009e+003 3.209404e+001 + 1.183000e+001 -2.029816e+003 3.204750e+001 + 1.184000e+001 -2.020218e+003 3.204620e+001 + 1.185000e+001 -2.023834e+003 3.209029e+001 + 1.186000e+001 -2.040710e+003 3.217167e+001 + 1.187000e+001 -2.070323e+003 3.227552e+001 + 1.188000e+001 -2.111625e+003 3.238315e+001 + 1.189000e+001 -2.163099e+003 3.247539e+001 + 1.190000e+001 -2.222835e+003 3.253598e+001 + 1.191000e+001 -2.288624e+003 3.255434e+001 + 1.192000e+001 -2.358065e+003 3.252733e+001 + 1.193000e+001 -2.428669e+003 3.245976e+001 + 1.194000e+001 -2.497979e+003 3.236355e+001 + 1.195000e+001 -2.563668e+003 3.225576e+001 + 1.196000e+001 -2.623649e+003 3.215564e+001 + 1.197000e+001 -2.676155e+003 3.208119e+001 + 1.198000e+001 -2.719811e+003 3.204588e+001 + 1.199000e+001 -2.753690e+003 3.205607e+001 + 1.200000e+001 -2.777335e+003 3.210982e+001 + 1.201000e+001 -2.790774e+003 3.219728e+001 + 1.202000e+001 -2.794502e+003 3.230257e+001 + 1.203000e+001 -2.789447e+003 3.240677e+001 + 1.204000e+001 -2.776910e+003 3.249136e+001 + 1.205000e+001 -2.758498e+003 3.254148e+001 + 1.206000e+001 -2.736033e+003 3.254838e+001 + 1.207000e+001 -2.711463e+003 3.251094e+001 + 1.208000e+001 -2.686756e+003 3.243577e+001 + 1.209000e+001 -2.663804e+003 3.233616e+001 + 1.210000e+001 -2.644328e+003 3.222981e+001 + 1.211000e+001 -2.629791e+003 3.213573e+001 + 1.212000e+001 -2.621327e+003 3.207088e+001 + 1.213000e+001 -2.619681e+003 3.204699e+001 + 1.214000e+001 -2.625177e+003 3.206834e+001 + 1.215000e+001 -2.637699e+003 3.213096e+001 + 1.216000e+001 -2.656696e+003 3.222340e+001 + 1.217000e+001 -2.681214e+003 3.232893e+001 + 1.218000e+001 -2.709938e+003 3.242863e+001 + 1.219000e+001 -2.741262e+003 3.250483e+001 + 1.220000e+001 -2.773369e+003 3.254417e+001 + 1.221000e+001 -2.804324e+003 3.253980e+001 + 1.222000e+001 -2.832177e+003 3.249257e+001 + 1.223000e+001 -2.855060e+003 3.241082e+001 + 1.224000e+001 -2.871295e+003 3.230901e+001 + 1.225000e+001 -2.879480e+003 3.220526e+001 + 1.226000e+001 -2.878577e+003 3.211816e+001 + 1.227000e+001 -2.867979e+003 3.206343e+001 + 1.228000e+001 -2.847551e+003 3.205096e+001 + 1.229000e+001 -2.817661e+003 3.208297e+001 + 1.230000e+001 -2.779182e+003 3.215353e+001 + 1.231000e+001 -2.733469e+003 3.224977e+001 + 1.232000e+001 -2.682314e+003 3.235432e+001 + 1.233000e+001 -2.627879e+003 3.244850e+001 + 1.234000e+001 -2.572610e+003 3.251563e+001 + 1.235000e+001 -2.519133e+003 3.254397e+001 + 1.236000e+001 -2.470139e+003 3.252861e+001 + 1.237000e+001 -2.428263e+003 3.247229e+001 + 1.238000e+001 -2.395957e+003 3.238497e+001 + 1.239000e+001 -2.375376e+003 3.228211e+001 + 1.240000e+001 -2.368260e+003 3.218205e+001 + 1.241000e+001 -2.375842e+003 3.210274e+001 + 1.242000e+001 -2.398766e+003 3.205852e+001 + 1.243000e+001 -2.437036e+003 3.205738e+001 + 1.244000e+001 -2.489980e+003 3.209946e+001 + 1.245000e+001 -2.556256e+003 3.217703e+001 + 1.246000e+001 -2.633872e+003 3.227598e+001 + 1.247000e+001 -2.720246e+003 3.237851e+001 + 1.248000e+001 -2.812286e+003 3.246634e+001 + 1.249000e+001 -2.906499e+003 3.252399e+001 + 1.250000e+001 -2.999113e+003 3.254137e+001 + 1.251000e+001 -3.086228e+003 3.251552e+001 + 1.252000e+001 -3.163961e+003 3.245103e+001 + 1.253000e+001 -3.228608e+003 3.235928e+001 + 1.254000e+001 -3.276799e+003 3.225656e+001 + 1.255000e+001 -3.305644e+003 3.216120e+001 + 1.256000e+001 -3.312865e+003 3.209036e+001 + 1.257000e+001 -3.296912e+003 3.205682e+001 + 1.258000e+001 -3.257045e+003 3.206665e+001 + 1.259000e+001 -3.193393e+003 3.211796e+001 + 1.260000e+001 -3.106981e+003 3.220137e+001 + 1.261000e+001 -2.999719e+003 3.230174e+001 + 1.262000e+001 -2.874358e+003 3.240105e+001 + 1.263000e+001 -2.734415e+003 3.248165e+001 + 1.264000e+001 -2.584060e+003 3.252935e+001 + 1.265000e+001 -2.427981e+003 3.253585e+001 + 1.266000e+001 -2.271227e+003 3.250007e+001 + 1.267000e+001 -2.119025e+003 3.242836e+001 + 1.268000e+001 -1.976596e+003 3.233340e+001 + 1.269000e+001 -1.848959e+003 3.223207e+001 + 1.270000e+001 -1.740745e+003 3.214249e+001 + 1.271000e+001 -1.656017e+003 3.208082e+001 + 1.272000e+001 -1.598109e+003 3.205819e+001 + 1.273000e+001 -1.569491e+003 3.207868e+001 + 1.274000e+001 -1.571656e+003 3.213847e+001 + 1.275000e+001 -1.605052e+003 3.222664e+001 + 1.276000e+001 -1.669044e+003 3.232725e+001 + 1.277000e+001 -1.761914e+003 3.242227e+001 + 1.278000e+001 -1.880905e+003 3.249485e+001 + 1.279000e+001 -2.022302e+003 3.253225e+001 + 1.280000e+001 -2.181546e+003 3.252797e+001 + 1.281000e+001 -2.353383e+003 3.248282e+001 + 1.282000e+001 -2.532040e+003 3.240479e+001 + 1.283000e+001 -2.711417e+003 3.230769e+001 + 1.284000e+001 -2.885296e+003 3.220881e+001 + 1.285000e+001 -3.047559e+003 3.212588e+001 + 1.286000e+001 -3.192396e+003 3.207385e+001 + 1.287000e+001 -3.314510e+003 3.206213e+001 + 1.288000e+001 -3.409304e+003 3.209280e+001 + 1.289000e+001 -3.473038e+003 3.216019e+001 + 1.290000e+001 -3.502968e+003 3.225204e+001 + 1.291000e+001 -3.497434e+003 3.235177e+001 + 1.292000e+001 -3.455929e+003 3.244157e+001 + 1.293000e+001 -3.379107e+003 3.250555e+001 + 1.294000e+001 -3.268768e+003 3.253251e+001 + 1.295000e+001 -3.127792e+003 3.251778e+001 + 1.296000e+001 -2.960037e+003 3.246402e+001 + 1.297000e+001 -2.770205e+003 3.238073e+001 + 1.298000e+001 -2.563681e+003 3.228269e+001 + 1.299000e+001 -2.346339e+003 3.218737e+001 + 1.300000e+001 -2.124346e+003 3.211190e+001 + 1.301000e+001 -1.903947e+003 3.206991e+001 + 1.302000e+001 -1.691249e+003 3.206898e+001 + 1.303000e+001 -1.492022e+003 3.210921e+001 + 1.304000e+001 -1.311498e+003 3.218322e+001 + 1.305000e+001 -1.154206e+003 3.227755e+001 + 1.306000e+001 -1.023821e+003 3.237522e+001 + 1.307000e+001 -9.230540e+002 3.245883e+001 + 1.308000e+001 -8.535732e+002 3.251360e+001 + 1.309000e+001 -8.159603e+002 3.252997e+001 + 1.310000e+001 -8.097089e+002 3.250512e+001 + 1.311000e+001 -8.332593e+002 3.244349e+001 + 1.312000e+001 -8.840689e+002 3.235598e+001 + 1.313000e+001 -9.587155e+002 3.225813e+001 + 1.314000e+001 -1.053029e+003 3.216744e+001 + 1.315000e+001 -1.162247e+003 3.210024e+001 + 1.316000e+001 -1.281186e+003 3.206867e+001 + 1.317000e+001 -1.404422e+003 3.207845e+001 + 1.318000e+001 -1.526482e+003 3.212773e+001 + 1.319000e+001 -1.642021e+003 3.220752e+001 + 1.320000e+001 -1.746000e+003 3.230334e+001 + 1.321000e+001 -1.833842e+003 3.239801e+001 + 1.322000e+001 -1.901573e+003 3.247468e+001 + 1.323000e+001 -1.945931e+003 3.251985e+001 + 1.324000e+001 -1.964455e+003 3.252564e+001 + 1.325000e+001 -1.955536e+003 3.249108e+001 + 1.326000e+001 -1.918445e+003 3.242230e+001 + 1.327000e+001 -1.853323e+003 3.233146e+001 + 1.328000e+001 -1.761144e+003 3.223472e+001 + 1.329000e+001 -1.643655e+003 3.214940e+001 + 1.330000e+001 -1.503290e+003 3.209087e+001 + 1.331000e+001 -1.343059e+003 3.206972e+001 + 1.332000e+001 -1.166432e+003 3.208977e+001 + 1.333000e+001 -9.772090e+002 3.214732e+001 + 1.334000e+001 -7.793844e+002 3.223188e+001 + 1.335000e+001 -5.770135e+002 3.232818e+001 + 1.336000e+001 -3.740854e+002 3.241898e+001 + 1.337000e+001 -1.744045e+002 3.248818e+001 + 1.338000e+001 1.851391e+001 3.252364e+001 + 1.339000e+001 2.015315e+002 3.251918e+001 + 1.340000e+001 3.719559e+002 3.247564e+001 + 1.341000e+001 5.275894e+002 3.240072e+001 + 1.342000e+001 6.667583e+002 3.230768e+001 + 1.343000e+001 7.883209e+002 3.221309e+001 + 1.344000e+001 8.916577e+002 3.213389e+001 + 1.345000e+001 9.766450e+002 3.208436e+001 + 1.346000e+001 1.043613e+003 3.207346e+001 + 1.347000e+001 1.093295e+003 3.210310e+001 + 1.348000e+001 1.126766e+003 3.216784e+001 + 1.349000e+001 1.145377e+003 3.225590e+001 + 1.350000e+001 1.150688e+003 3.235141e+001 + 1.351000e+001 1.144404e+003 3.243731e+001 + 1.352000e+001 1.128314e+003 3.249840e+001 + 1.353000e+001 1.104232e+003 3.252399e+001 + 1.354000e+001 1.073953e+003 3.250965e+001 + 1.355000e+001 1.039212e+003 3.245794e+001 + 1.356000e+001 1.001657e+003 3.237803e+001 + 1.357000e+001 9.628291e+002 3.228408e+001 + 1.358000e+001 9.241504e+002 3.219284e+001 + 1.359000e+001 8.869214e+002 3.212069e+001 + 1.360000e+001 8.523234e+002 3.208065e+001 + 1.361000e+001 8.214265e+002 3.207993e+001 + 1.362000e+001 7.951986e+002 3.211861e+001 + 1.363000e+001 7.745165e+002 3.218958e+001 + 1.364000e+001 7.601753e+002 3.227996e+001 + 1.365000e+001 7.528950e+002 3.237347e+001 + 1.366000e+001 7.533238e+002 3.245344e+001 + 1.367000e+001 7.620366e+002 3.250576e+001 + 1.368000e+001 7.795285e+002 3.252127e+001 + 1.369000e+001 8.062035e+002 3.249730e+001 + 1.370000e+001 8.423590e+002 3.243813e+001 + 1.371000e+001 8.881671e+002 3.235422e+001 + 1.372000e+001 9.436543e+002 3.226048e+001 + 1.373000e+001 1.008681e+003 3.217366e+001 + 1.374000e+001 1.082921e+003 3.210938e+001 + 1.375000e+001 1.165851e+003 3.207924e+001 + 1.376000e+001 1.256735e+003 3.208867e+001 + 1.377000e+001 1.354626e+003 3.213591e+001 + 1.378000e+001 1.458374e+003 3.221230e+001 + 1.379000e+001 1.566637e+003 3.230401e+001 + 1.380000e+001 1.677912e+003 3.239457e+001 + 1.381000e+001 1.790568e+003 3.246787e+001 + 1.382000e+001 1.902894e+003 3.251099e+001 + 1.383000e+001 2.013152e+003 3.251640e+001 + 1.384000e+001 2.119634e+003 3.248319e+001 + 1.385000e+001 2.220730e+003 3.241727e+001 + 1.386000e+001 2.314989e+003 3.233030e+001 + 1.387000e+001 2.401183e+003 3.223775e+001 + 1.388000e+001 2.478364e+003 3.215618e+001 + 1.389000e+001 2.545913e+003 3.210029e+001 + 1.390000e+001 2.603580e+003 3.208018e+001 + 1.391000e+001 2.651503e+003 3.209944e+001 + 1.392000e+001 2.690221e+003 3.215452e+001 + 1.393000e+001 2.720661e+003 3.223538e+001 + 1.394000e+001 2.744114e+003 3.232739e+001 + 1.395000e+001 2.762184e+003 3.241407e+001 + 1.396000e+001 2.776731e+003 3.248003e+001 + 1.397000e+001 2.789786e+003 3.251367e+001 + 1.398000e+001 2.803468e+003 3.250912e+001 + 1.399000e+001 2.819877e+003 3.246723e+001 + 1.400000e+001 2.840993e+003 3.239541e+001 + 1.401000e+001 2.868570e+003 3.230639e+001 + 1.402000e+001 2.904032e+003 3.221603e+001 + 1.403000e+001 2.948385e+003 3.214052e+001 + 1.404000e+001 3.002133e+003 3.209350e+001 + 1.405000e+001 3.065223e+003 3.208344e+001 + 1.406000e+001 3.137005e+003 3.211215e+001 + 1.407000e+001 3.216216e+003 3.217433e+001 + 1.408000e+001 3.300998e+003 3.225870e+001 + 1.409000e+001 3.388936e+003 3.235002e+001 + 1.410000e+001 3.477130e+003 3.243199e+001 + 1.411000e+001 3.562286e+003 3.249008e+001 + 1.412000e+001 3.640840e+003 3.251409e+001 + 1.413000e+001 3.709088e+003 3.249984e+001 + 1.414000e+001 3.763347e+003 3.244988e+001 + 1.415000e+001 3.800106e+003 3.237305e+001 + 1.416000e+001 3.816196e+003 3.228297e+001 + 1.417000e+001 3.808944e+003 3.219571e+001 + 1.418000e+001 3.776317e+003 3.212694e+001 + 1.419000e+001 3.717053e+003 3.208906e+001 + 1.420000e+001 3.630761e+003 3.208893e+001 + 1.421000e+001 3.517991e+003 3.212652e+001 + 1.422000e+001 3.380273e+003 3.219495e+001 + 1.423000e+001 3.220112e+003 3.228181e+001 + 1.424000e+001 3.040950e+003 3.237148e+001 + 1.425000e+001 2.847082e+003 3.244796e+001 + 1.426000e+001 2.643535e+003 3.249776e+001 + 1.427000e+001 2.435912e+003 3.251212e+001 + 1.428000e+001 2.230209e+003 3.248858e+001 + 1.429000e+001 2.032602e+003 3.243132e+001 + 1.430000e+001 1.849218e+003 3.235045e+001 + 1.431000e+001 1.685901e+003 3.226034e+001 + 1.432000e+001 1.547981e+003 3.217708e+001 + 1.433000e+001 1.440041e+003 3.211564e+001 + 1.434000e+001 1.365719e+003 3.208710e+001 + 1.435000e+001 1.327529e+003 3.209663e+001 + 1.436000e+001 1.326721e+003 3.214242e+001 + 1.437000e+001 1.363182e+003 3.221612e+001 + 1.438000e+001 1.435392e+003 3.230440e+001 + 1.439000e+001 1.540425e+003 3.239141e+001 + 1.440000e+001 1.674008e+003 3.246167e+001 + 1.441000e+001 1.830633e+003 3.250280e+001 + 1.442000e+001 2.003714e+003 3.250759e+001 + 1.443000e+001 2.185802e+003 3.247526e+001 + 1.444000e+001 2.368826e+003 3.241151e+001 + 1.445000e+001 2.544372e+003 3.232764e+001 + 1.446000e+001 2.703983e+003 3.223855e+001 + 1.447000e+001 2.839464e+003 3.216018e+001 + 1.448000e+001 2.943192e+003 3.210662e+001 + 1.449000e+001 3.008406e+003 3.208756e+001 + 1.450000e+001 3.029480e+003 3.210641e+001 + 1.451000e+001 3.002147e+003 3.215969e+001 + 1.452000e+001 2.923696e+003 3.223769e+001 + 1.453000e+001 2.793096e+003 3.232634e+001 + 1.454000e+001 2.611073e+003 3.240976e+001 + 1.455000e+001 2.380119e+003 3.247314e+001 + 1.456000e+001 2.104432e+003 3.250533e+001 + 1.457000e+001 1.789803e+003 3.250072e+001 + 1.458000e+001 1.443422e+003 3.246015e+001 + 1.459000e+001 1.073652e+003 3.239080e+001 + 1.460000e+001 6.897374e+002 3.230496e+001 + 1.461000e+001 3.014855e+002 3.221789e+001 + 1.462000e+001 -8.108057e+001 3.214521e+001 + 1.463000e+001 -4.480806e+002 3.209999e+001 + 1.464000e+001 -7.901352e+002 3.209040e+001 + 1.465000e+001 -1.098709e+003 3.211813e+001 + 1.466000e+001 -1.366423e+003 3.217807e+001 + 1.467000e+001 -1.587336e+003 3.225935e+001 + 1.468000e+001 -1.757158e+003 3.234731e+001 + 1.469000e+001 -1.873422e+003 3.242624e+001 + 1.470000e+001 -1.935575e+003 3.248216e+001 + 1.471000e+001 -1.945004e+003 3.250526e+001 + 1.472000e+001 -1.904989e+003 3.249152e+001 + 1.473000e+001 -1.820580e+003 3.244341e+001 + 1.474000e+001 -1.698416e+003 3.236944e+001 + 1.475000e+001 -1.546472e+003 3.228274e+001 + 1.476000e+001 -1.373762e+003 3.219877e+001 + 1.477000e+001 -1.190001e+003 3.213261e+001 + 1.478000e+001 -1.005237e+003 3.209617e+001 + 1.479000e+001 -8.294732e+002 3.209604e+001 + 1.480000e+001 -6.722901e+002 3.213218e+001 + 1.481000e+001 -5.424817e+002 3.219798e+001 + 1.482000e+001 -4.477248e+002 3.228150e+001 + 1.483000e+001 -3.942905e+002 3.236772e+001 + 1.484000e+001 -3.868091e+002 3.244126e+001 + 1.485000e+001 -4.281001e+002 3.248912e+001 + 1.486000e+001 -5.190709e+002 3.250292e+001 + 1.487000e+001 -6.586908e+002 3.248026e+001 + 1.488000e+001 -8.440400e+002 3.242519e+001 + 1.489000e+001 -1.070432e+003 3.234744e+001 + 1.490000e+001 -1.331604e+003 3.226084e+001 + 1.491000e+001 -1.619970e+003 3.218086e+001 + 1.492000e+001 -1.926920e+003 3.212188e+001 + 1.493000e+001 -2.243166e+003 3.209455e+001 + 1.494000e+001 -2.559106e+003 3.210379e+001 + 1.495000e+001 -2.865202e+003 3.214789e+001 + 1.496000e+001 -3.152355e+003 3.221879e+001 + 1.497000e+001 -3.412256e+003 3.230368e+001 + 1.498000e+001 -3.637711e+003 3.238732e+001 + 1.499000e+001 -3.822915e+003 3.245484e+001 + 1.500000e+001 -3.963668e+003 3.249433e+001 + 1.501000e+001 -4.057535e+003 3.249888e+001 + 1.502000e+001 -4.103921e+003 3.246774e+001 + 1.503000e+001 -4.104086e+003 3.240643e+001 + 1.504000e+001 -4.061074e+003 3.232581e+001 + 1.505000e+001 -3.979579e+003 3.224023e+001 + 1.506000e+001 -3.865743e+003 3.216500e+001 + 1.507000e+001 -3.726894e+003 3.211368e+001 + 1.508000e+001 -3.571243e+003 3.209552e+001 + 1.509000e+001 -3.407542e+003 3.211380e+001 + 1.510000e+001 -3.244730e+003 3.216515e+001 + 1.511000e+001 -3.091565e+003 3.224022e+001 + 1.512000e+001 -2.956271e+003 3.232548e+001 + 1.513000e+001 -2.846208e+003 3.240565e+001 + 1.514000e+001 -2.767580e+003 3.246652e+001 + 1.515000e+001 -2.725191e+003 3.249737e+001 + 1.516000e+001 -2.722259e+003 3.249280e+001 + 1.517000e+001 -2.760301e+003 3.245368e+001 + 1.518000e+001 -2.839080e+003 3.238693e+001 + 1.519000e+001 -2.956630e+003 3.230438e+001 + 1.520000e+001 -3.109351e+003 3.222074e+001 + 1.521000e+001 -3.292169e+003 3.215100e+001 + 1.522000e+001 -3.498754e+003 3.210773e+001 + 1.523000e+001 -3.721792e+003 3.209874e+001 + 1.524000e+001 -3.953287e+003 3.212562e+001 + 1.525000e+001 -4.184899e+003 3.218345e+001 + 1.526000e+001 -4.408287e+003 3.226174e+001 + 1.527000e+001 -4.615448e+003 3.234639e+001 + 1.528000e+001 -4.799040e+003 3.242226e+001 + 1.529000e+001 -4.952682e+003 3.247594e+001 + 1.530000e+001 -5.071200e+003 3.249798e+001 + 1.531000e+001 -5.150826e+003 3.248456e+001 + 1.532000e+001 -5.189340e+003 3.243807e+001 + 1.533000e+001 -5.186141e+003 3.236676e+001 + 1.534000e+001 -5.142252e+003 3.228326e+001 + 1.535000e+001 -5.060260e+003 3.220249e+001 + 1.536000e+001 -4.944185e+003 3.213894e+001 + 1.537000e+001 -4.799298e+003 3.210407e+001 + 1.538000e+001 -4.631885e+003 3.210417e+001 + 1.539000e+001 -4.448967e+003 3.213918e+001 + 1.540000e+001 -4.258005e+003 3.220271e+001 + 1.541000e+001 -4.066574e+003 3.228325e+001 + 1.542000e+001 -3.882048e+003 3.236633e+001 + 1.543000e+001 -3.711294e+003 3.243713e+001 + 1.544000e+001 -3.560389e+003 3.248315e+001 + 1.545000e+001 -3.434377e+003 3.249631e+001 + 1.546000e+001 -3.337072e+003 3.247434e+001 + 1.547000e+001 -3.270917e+003 3.242115e+001 + 1.548000e+001 -3.236904e+003 3.234615e+001 + 1.549000e+001 -3.234553e+003 3.226267e+001 + 1.550000e+001 -3.261967e+003 3.218561e+001 + 1.551000e+001 -3.315930e+003 3.212884e+001 + 1.552000e+001 -3.392079e+003 3.210258e+001 + 1.553000e+001 -3.485111e+003 3.211158e+001 + 1.554000e+001 -3.589037e+003 3.215414e+001 + 1.555000e+001 -3.697455e+003 3.222252e+001 + 1.556000e+001 -3.803851e+003 3.230435e+001 + 1.557000e+001 -3.901883e+003 3.238497e+001 + 1.558000e+001 -3.985675e+003 3.245004e+001 + 1.559000e+001 -4.050069e+003 3.248808e+001 + 1.560000e+001 -4.090855e+003 3.249243e+001 + 1.561000e+001 -4.104947e+003 3.246238e+001 + 1.562000e+001 -4.090518e+003 3.240326e+001 + 1.563000e+001 -4.047063e+003 3.232554e+001 + 1.564000e+001 -3.975413e+003 3.224305e+001 + 1.565000e+001 -3.877687e+003 3.217055e+001 + 1.566000e+001 -3.757175e+003 3.212107e+001 + 1.567000e+001 -3.618187e+003 3.210355e+001 + 1.568000e+001 -3.465838e+003 3.212111e+001 + 1.569000e+001 -3.305807e+003 3.217052e+001 + 1.570000e+001 -3.144071e+003 3.224280e+001 + 1.571000e+001 -2.986621e+003 3.232490e+001 + 1.572000e+001 -2.839183e+003 3.240213e+001 + 1.573000e+001 -2.706947e+003 3.246078e+001 + 1.574000e+001 -2.594324e+003 3.249053e+001 + 1.575000e+001 -2.504737e+003 3.248619e+001 + 1.576000e+001 -2.440455e+003 3.244857e+001 + 1.577000e+001 -2.402483e+003 3.238434e+001 + 1.578000e+001 -2.390507e+003 3.230490e+001 + 1.579000e+001 -2.402899e+003 3.222441e+001 + 1.580000e+001 -2.436783e+003 3.215729e+001 + 1.581000e+001 -2.488154e+003 3.211562e+001 + 1.582000e+001 -2.552059e+003 3.210692e+001 + 1.583000e+001 -2.622805e+003 3.213272e+001 + 1.584000e+001 -2.694221e+003 3.218829e+001 + 1.585000e+001 -2.759927e+003 3.226354e+001 + 1.586000e+001 -2.813622e+003 3.234490e+001 + 1.587000e+001 -2.849373e+003 3.241785e+001 + 1.588000e+001 -2.861881e+003 3.246945e+001 + 1.589000e+001 -2.846728e+003 3.249064e+001 + 1.590000e+001 -2.800582e+003 3.247773e+001 + 1.591000e+001 -2.721363e+003 3.243304e+001 + 1.592000e+001 -2.608341e+003 3.236449e+001 + 1.593000e+001 -2.462191e+003 3.228427e+001 + 1.594000e+001 -2.284974e+003 3.220670e+001 + 1.595000e+001 -2.080068e+003 3.214569e+001 + 1.596000e+001 -1.852028e+003 3.211226e+001 + 1.597000e+001 -1.606407e+003 3.211243e+001 + 1.598000e+001 -1.349525e+003 3.214611e+001 + 1.599000e+001 -1.088204e+003 3.220717e+001 + 1.600000e+001 -8.294805e+002 3.228452e+001 + 1.601000e+001 -5.803096e+002 3.236426e+001 + 1.602000e+001 -3.472677e+002 3.243217e+001 + 1.603000e+001 -1.362731e+002 3.247622e+001 + 1.604000e+001 4.766698e+001 3.248868e+001 + 1.605000e+001 2.006705e+002 3.246740e+001 + 1.606000e+001 3.201461e+002 3.241616e+001 + 1.607000e+001 4.049039e+002 3.234405e+001 + 1.608000e+001 4.552046e+002 3.226390e+001 + 1.609000e+001 4.727469e+002 3.219003e+001 + 1.610000e+001 4.605916e+002 3.213573e+001 + 1.611000e+001 4.230265e+002 3.211080e+001 + 1.612000e+001 3.653782e+002 3.211972e+001 + 1.613000e+001 2.937780e+002 3.216085e+001 + 1.614000e+001 2.148924e+002 3.222668e+001 + 1.615000e+001 1.356305e+002 3.230532e+001 + 1.616000e+001 6.284027e+001 3.238264e+001 + 1.617000e+001 3.006936e+000 3.244489e+001 + 1.618000e+001 -3.803210e+001 3.248105e+001 + 1.619000e+001 -5.534471e+001 3.248479e+001 + 1.620000e+001 -4.512156e+001 3.245548e+001 + 1.621000e+001 -4.844392e+000 3.239832e+001 + 1.622000e+001 6.660269e+001 3.232344e+001 + 1.623000e+001 1.688838e+002 3.224417e+001 + 1.624000e+001 3.002260e+002 3.217470e+001 + 1.625000e+001 4.574982e+002 3.212755e+001 + 1.626000e+001 6.363507e+002 3.211123e+001 + 1.627000e+001 8.314087e+002 3.212868e+001 + 1.628000e+001 1.036513e+003 3.217669e+001 + 1.629000e+001 1.244996e+003 3.224655e+001 + 1.630000e+001 1.449982e+003 3.232565e+001 + 1.631000e+001 1.644697e+003 3.239984e+001 + 1.632000e+001 1.822778e+003 3.245593e+001 + 1.633000e+001 1.978563e+003 3.248403e+001 + 1.634000e+001 2.107354e+003 3.247921e+001 + 1.635000e+001 2.205636e+003 3.244235e+001 + 1.636000e+001 2.271247e+003 3.237996e+001 + 1.637000e+001 2.303489e+003 3.230312e+001 + 1.638000e+001 2.303173e+003 3.222550e+001 + 1.639000e+001 2.272601e+003 3.216102e+001 + 1.640000e+001 2.215479e+003 3.212128e+001 + 1.641000e+001 2.136766e+003 3.211347e+001 + 1.642000e+001 2.042471e+003 3.213897e+001 + 1.643000e+001 1.939398e+003 3.219312e+001 + 1.644000e+001 1.834856e+003 3.226611e+001 + 1.645000e+001 1.736342e+003 3.234481e+001 + 1.646000e+001 1.651215e+003 3.241516e+001 + 1.647000e+001 1.586373e+003 3.246469e+001 + 1.648000e+001 1.547942e+003 3.248468e+001 + 1.649000e+001 1.541004e+003 3.247166e+001 + 1.650000e+001 1.569363e+003 3.242794e+001 + 1.651000e+001 1.635358e+003 3.236125e+001 + 1.652000e+001 1.739753e+003 3.228344e+001 + 1.653000e+001 1.881675e+003 3.220839e+001 + 1.654000e+001 2.058638e+003 3.214955e+001 + 1.655000e+001 2.266624e+003 3.211753e+001 + 1.656000e+001 2.500237e+003 3.211809e+001 + 1.657000e+001 2.752916e+003 3.215111e+001 + 1.658000e+001 3.017193e+003 3.221056e+001 + 1.659000e+001 3.285003e+003 3.228567e+001 + 1.660000e+001 3.548008e+003 3.236297e+001 + 1.661000e+001 3.797947e+003 3.242867e+001 + 1.662000e+001 4.026972e+003 3.247114e+001 + 1.663000e+001 4.227979e+003 3.248293e+001 + 1.664000e+001 4.394907e+003 3.246200e+001 + 1.665000e+001 4.522989e+003 3.241206e+001 + 1.666000e+001 4.608954e+003 3.234196e+001 + 1.667000e+001 4.651169e+003 3.226416e+001 + 1.668000e+001 4.649707e+003 3.219256e+001 + 1.669000e+001 4.606349e+003 3.214001e+001 + 1.670000e+001 4.524510e+003 3.211600e+001 + 1.671000e+001 4.409101e+003 3.212484e+001 + 1.672000e+001 4.266324e+003 3.216488e+001 + 1.673000e+001 4.103418e+003 3.222885e+001 + 1.674000e+001 3.928354e+003 3.230517e+001 + 1.675000e+001 3.749511e+003 3.238018e+001 + 1.676000e+001 3.575322e+003 3.244052e+001 + 1.677000e+001 3.413931e+003 3.247552e+001 + 1.678000e+001 3.272858e+003 3.247906e+001 + 1.679000e+001 3.158687e+003 3.245053e+001 + 1.680000e+001 3.076803e+003 3.239501e+001 + 1.681000e+001 3.031178e+003 3.232232e+001 + 1.682000e+001 3.024214e+003 3.224540e+001 + 1.683000e+001 3.056659e+003 3.217802e+001 + 1.684000e+001 3.127595e+003 3.213229e+001 + 1.685000e+001 3.234491e+003 3.211646e+001 + 1.686000e+001 3.373328e+003 3.213336e+001 + 1.687000e+001 3.538793e+003 3.217989e+001 + 1.688000e+001 3.724521e+003 3.224761e+001 + 1.689000e+001 3.923380e+003 3.232430e+001 + 1.690000e+001 4.127798e+003 3.239623e+001 + 1.691000e+001 4.330095e+003 3.245064e+001 + 1.692000e+001 4.522827e+003 3.247791e+001 + 1.693000e+001 4.699113e+003 3.247328e+001 + 1.694000e+001 4.852936e+003 3.243760e+001 + 1.695000e+001 4.979412e+003 3.237717e+001 + 1.696000e+001 5.074991e+003 3.230273e+001 + 1.697000e+001 5.137621e+003 3.222752e+001 + 1.698000e+001 5.166821e+003 3.216503e+001 + 1.699000e+001 5.163705e+003 3.212650e+001 + 1.700000e+001 5.130918e+003 3.211887e+001 + 1.701000e+001 5.072514e+003 3.214351e+001 + 1.702000e+001 4.993769e+003 3.219590e+001 + 1.703000e+001 4.900938e+003 3.226655e+001 + 1.704000e+001 4.800964e+003 3.234276e+001 + 1.705000e+001 4.701169e+003 3.241090e+001 + 1.706000e+001 4.608912e+003 3.245890e+001 + 1.707000e+001 4.531255e+003 3.247831e+001 + 1.708000e+001 4.474640e+003 3.246574e+001 + 1.709000e+001 4.444592e+003 3.242344e+001 + 1.710000e+001 4.445458e+003 3.235889e+001 + 1.711000e+001 4.480211e+003 3.228356e+001 + 1.712000e+001 4.550295e+003 3.221088e+001 + 1.713000e+001 4.655559e+003 3.215389e+001 + 1.714000e+001 4.794246e+003 3.212286e+001 + 1.715000e+001 4.963063e+003 3.212336e+001 + 1.716000e+001 5.157312e+003 3.215528e+001 + 1.717000e+001 5.371095e+003 3.221280e+001 + 1.718000e+001 5.597562e+003 3.228551e+001 + 1.719000e+001 5.829208e+003 3.236036e+001 + 1.720000e+001 6.058206e+003 3.242401e+001 + 1.721000e+001 6.276743e+003 3.246518e+001 + 1.722000e+001 6.477371e+003 3.247666e+001 + 1.723000e+001 6.653331e+003 3.245645e+001 + 1.724000e+001 6.798863e+003 3.240814e+001 + 1.725000e+001 6.909459e+003 3.234031e+001 + 1.726000e+001 6.982068e+003 3.226499e+001 + 1.727000e+001 7.015245e+003 3.219566e+001 + 1.728000e+001 7.009215e+003 3.214475e+001 + 1.729000e+001 6.965877e+003 3.212145e+001 + 1.730000e+001 6.888726e+003 3.212994e+001 + 1.731000e+001 6.782709e+003 3.216865e+001 + 1.732000e+001 6.654011e+003 3.223054e+001 + 1.733000e+001 6.509790e+003 3.230443e+001 + 1.734000e+001 6.357864e+003 3.237707e+001 + 1.735000e+001 6.206369e+003 3.243555e+001 + 1.736000e+001 6.063397e+003 3.246953e+001 + 1.737000e+001 5.936637e+003 3.247305e+001 + 1.738000e+001 5.833030e+003 3.244553e+001 + 1.739000e+001 5.758454e+003 3.239185e+001 + 1.740000e+001 5.717451e+003 3.232153e+001 + 1.741000e+001 5.713015e+003 3.224709e+001 + 1.742000e+001 5.746442e+003 3.218184e+001 + 1.743000e+001 5.817253e+003 3.213752e+001 + 1.744000e+001 5.923200e+003 3.212212e+001 + 1.745000e+001 6.060338e+003 3.213840e+001 + 1.746000e+001 6.223181e+003 3.218338e+001 + 1.747000e+001 6.404922e+003 3.224889e+001 + 1.748000e+001 6.597716e+003 3.232313e+001 + 1.749000e+001 6.792998e+003 3.239282e+001 + 1.750000e+001 6.981855e+003 3.244558e+001 + 1.751000e+001 7.155395e+003 3.247210e+001 + 1.752000e+001 7.305133e+003 3.246775e+001 + 1.753000e+001 7.423354e+003 3.243333e+001 + 1.754000e+001 7.503449e+003 3.237493e+001 + 1.755000e+001 7.540204e+003 3.230291e+001 + 1.756000e+001 7.530037e+003 3.223011e+001 + 1.757000e+001 7.471154e+003 3.216956e+001 + 1.758000e+001 7.363648e+003 3.213216e+001 + 1.759000e+001 7.209498e+003 3.212464e+001 + 1.760000e+001 7.012504e+003 3.214834e+001 + 1.761000e+001 6.778136e+003 3.219892e+001 + 1.762000e+001 6.513314e+003 3.226723e+001 + 1.763000e+001 6.226120e+003 3.234097e+001 + 1.764000e+001 5.925471e+003 3.240699e+001 + 1.765000e+001 5.620741e+003 3.245359e+001 + 1.766000e+001 5.321375e+003 3.247256e+001 + 1.767000e+001 5.036491e+003 3.246060e+001 + 1.768000e+001 4.774495e+003 3.241986e+001 + 1.769000e+001 4.542734e+003 3.235756e+001 + 1.770000e+001 4.347183e+003 3.228478e+001 + 1.771000e+001 4.192196e+003 3.221448e+001 + 1.772000e+001 4.080323e+003 3.215928e+001 + 1.773000e+001 4.012209e+003 3.212912e+001 + 1.774000e+001 3.986571e+003 3.212941e+001 + 1.775000e+001 4.000255e+003 3.216007e+001 + 1.776000e+001 4.048383e+003 3.221549e+001 + 1.777000e+001 4.124562e+003 3.228566e+001 + 1.778000e+001 4.221172e+003 3.235797e+001 + 1.779000e+001 4.329698e+003 3.241951e+001 + 1.780000e+001 4.441103e+003 3.245941e+001 + 1.781000e+001 4.546230e+003 3.247065e+001 + 1.782000e+001 4.636202e+003 3.245129e+001 + 1.783000e+001 4.702817e+003 3.240478e+001 + 1.784000e+001 4.738908e+003 3.233937e+001 + 1.785000e+001 4.738669e+003 3.226671e+001 + 1.786000e+001 4.697909e+003 3.219977e+001 + 1.787000e+001 4.614248e+003 3.215059e+001 + 1.788000e+001 4.487227e+003 3.212803e+001 + 1.789000e+001 4.318337e+003 3.213614e+001 + 1.790000e+001 4.110964e+003 3.217341e+001 + 1.791000e+001 3.870244e+003 3.223307e+001 + 1.792000e+001 3.602851e+003 3.230433e+001 + 1.793000e+001 3.316705e+003 3.237443e+001 + 1.794000e+001 3.020632e+003 3.243087e+001 + 1.795000e+001 2.723975e+003 3.246369e+001 + 1.796000e+001 2.436185e+003 3.246712e+001 + 1.797000e+001 2.166405e+003 3.244059e+001 + 1.798000e+001 1.923054e+003 3.238881e+001 + 1.799000e+001 1.713454e+003 3.232099e+001 + 1.800000e+001 1.543489e+003 3.224919e+001 + 1.801000e+001 1.417331e+003 3.218628e+001 + 1.802000e+001 1.337237e+003 3.214357e+001 + 1.803000e+001 1.303424e+003 3.212877e+001 + 1.804000e+001 1.314035e+003 3.214453e+001 + 1.805000e+001 1.365197e+003 3.218797e+001 + 1.806000e+001 1.451156e+003 3.225121e+001 + 1.807000e+001 1.564512e+003 3.232285e+001 + 1.808000e+001 1.696510e+003 3.239008e+001 + 1.809000e+001 1.837407e+003 3.244094e+001 + 1.810000e+001 1.976879e+003 3.246646e+001 + 1.811000e+001 2.104456e+003 3.246216e+001 + 1.812000e+001 2.209975e+003 3.242883e+001 + 1.813000e+001 2.284019e+003 3.237238e+001 + 1.814000e+001 2.318334e+003 3.230283e+001 + 1.815000e+001 2.306201e+003 3.223257e+001 + 1.816000e+001 2.242746e+003 3.217421e+001 + 1.817000e+001 2.125178e+003 3.213823e+001 + 1.818000e+001 1.952939e+003 3.213114e+001 + 1.819000e+001 1.727768e+003 3.215418e+001 + 1.820000e+001 1.453664e+003 3.220317e+001 + 1.821000e+001 1.136757e+003 3.226923e+001 + 1.822000e+001 7.850872e+002 3.234049e+001 + 1.823000e+001 4.083056e+002 3.240422e+001 + 1.824000e+001 1.729998e+001 3.244911e+001 + 1.825000e+001 -3.762312e+002 3.246727e+001 + 1.826000e+001 -7.602444e+002 3.245551e+001 + 1.827000e+001 -1.122836e+003 3.241594e+001 + 1.828000e+001 -1.452724e+003 3.235557e+001 + 1.829000e+001 -1.739717e+003 3.228512e+001 + 1.830000e+001 -1.975134e+003 3.221716e+001 + 1.831000e+001 -2.152171e+003 3.216388e+001 + 1.832000e+001 -2.266200e+003 3.213487e+001 + 1.833000e+001 -2.314977e+003 3.213535e+001 + 1.834000e+001 -2.298754e+003 3.216521e+001 + 1.835000e+001 -2.220302e+003 3.221901e+001 + 1.836000e+001 -2.084822e+003 3.228703e+001 + 1.837000e+001 -1.899764e+003 3.235707e+001 + 1.838000e+001 -1.674558e+003 3.241662e+001 + 1.839000e+001 -1.420256e+003 3.245516e+001 + 1.840000e+001 -1.149118e+003 3.246589e+001 + 1.841000e+001 -8.741401e+002 3.244696e+001 + 1.842000e+001 -6.085561e+002 3.240172e+001 + 1.843000e+001 -3.653253e+002 3.233818e+001 + 1.844000e+001 -1.566306e+002 3.226765e+001 + 1.845000e+001 6.594699e+000 3.220270e+001 + 1.846000e+001 1.150918e+002 3.215500e+001 + 1.847000e+001 1.616366e+002 3.213312e+001 + 1.848000e+001 1.413210e+002 3.214100e+001 + 1.849000e+001 5.174310e+001 3.217718e+001 + 1.850000e+001 -1.069000e+002 3.223508e+001 + 1.851000e+001 -3.318206e+002 3.230427e+001 + 1.852000e+001 -6.177507e+002 3.237235e+001 + 1.853000e+001 -9.571472e+002 3.242722e+001 + 1.854000e+001 -1.340486e+003 3.245919e+001 + 1.855000e+001 -1.756633e+003 3.246265e+001 + 1.856000e+001 -2.193274e+003 3.243704e+001 + 1.857000e+001 -2.637391e+003 3.238691e+001 + 1.858000e+001 -3.075761e+003 3.232115e+001 + 1.859000e+001 -3.495463e+003 3.225147e+001 + 1.860000e+001 -3.884370e+003 3.219032e+001 + 1.861000e+001 -4.231601e+003 3.214867e+001 + 1.862000e+001 -4.527933e+003 3.213402e+001 + 1.863000e+001 -4.766130e+003 3.214897e+001 + 1.864000e+001 -4.941212e+003 3.219077e+001 + 1.865000e+001 -5.050613e+003 3.225182e+001 + 1.866000e+001 -5.094261e+003 3.232112e+001 + 1.867000e+001 -5.074548e+003 3.238625e+001 + 1.868000e+001 -4.996217e+003 3.243566e+001 + 1.869000e+001 -4.866145e+003 3.246061e+001 + 1.870000e+001 -4.693058e+003 3.245675e+001 + 1.871000e+001 -4.487170e+003 3.242481e+001 + 1.872000e+001 -4.259773e+003 3.237045e+001 + 1.873000e+001 -4.022786e+003 3.230334e+001 + 1.874000e+001 -3.788289e+003 3.223545e+001 + 1.875000e+001 -3.568059e+003 3.217894e+001 + 1.876000e+001 -3.373118e+003 3.214398e+001 + 1.877000e+001 -3.213324e+003 3.213685e+001 + 1.878000e+001 -3.097010e+003 3.215881e+001 + 1.879000e+001 -3.030686e+003 3.220585e+001 + 1.880000e+001 -3.018826e+003 3.226943e+001 + 1.881000e+001 -3.063723e+003 3.233811e+001 + 1.882000e+001 -3.165450e+003 3.239962e+001 + 1.883000e+001 -3.321891e+003 3.244304e+001 + 1.884000e+001 -3.528870e+003 3.246071e+001 + 1.885000e+001 -3.780349e+003 3.244955e+001 + 1.886000e+001 -4.068701e+003 3.241157e+001 + 1.887000e+001 -4.385038e+003 3.235351e+001 + 1.888000e+001 -4.719579e+003 3.228569e+001 + 1.889000e+001 -5.062049e+003 3.222022e+001 + 1.890000e+001 -5.402088e+003 3.216885e+001 + 1.891000e+001 -5.729652e+003 3.214082e+001 + 1.892000e+001 -6.035396e+003 3.214118e+001 + 1.893000e+001 -6.311018e+003 3.216981e+001 + 1.894000e+001 -6.549555e+003 3.222150e+001 + 1.895000e+001 -6.745619e+003 3.228690e+001 + 1.896000e+001 -6.895566e+003 3.235426e+001 + 1.897000e+001 -6.997591e+003 3.241155e+001 + 1.898000e+001 -7.051746e+003 3.244863e+001 + 1.899000e+001 -7.059892e+003 3.245896e+001 + 1.900000e+001 -7.025568e+003 3.244077e+001 + 1.901000e+001 -6.953808e+003 3.239728e+001 + 1.902000e+001 -6.850903e+003 3.233624e+001 + 1.903000e+001 -6.724112e+003 3.226850e+001 + 1.904000e+001 -6.581351e+003 3.220619e+001 + 1.905000e+001 -6.430862e+003 3.216050e+001 + 1.906000e+001 -6.280878e+003 3.213965e+001 + 1.907000e+001 -6.139303e+003 3.214740e+001 + 1.908000e+001 -6.013408e+003 3.218232e+001 + 1.909000e+001 -5.909569e+003 3.223804e+001 + 1.910000e+001 -5.833046e+003 3.230452e+001 + 1.911000e+001 -5.787812e+003 3.236983e+001 + 1.912000e+001 -5.776441e+003 3.242232e+001 + 1.913000e+001 -5.800057e+003 3.245271e+001 + 1.914000e+001 -5.858340e+003 3.245565e+001 + 1.915000e+001 -5.949591e+003 3.243065e+001 + 1.916000e+001 -6.070849e+003 3.238215e+001 + 1.917000e+001 -6.218049e+003 3.231877e+001 + 1.918000e+001 -6.386229e+003 3.225179e+001 + 1.919000e+001 -6.569754e+003 3.219322e+001 + 1.920000e+001 -6.762556e+003 3.215358e+001 + 1.921000e+001 -6.958395e+003 3.214001e+001 + 1.922000e+001 -7.151096e+003 3.215496e+001 + 1.923000e+001 -7.334787e+003 3.219569e+001 + 1.924000e+001 -7.504106e+003 3.225481e+001 + 1.925000e+001 -7.654378e+003 3.232167e+001 + 1.926000e+001 -7.781760e+003 3.238430e+001 + 1.927000e+001 -7.883335e+003 3.243157e+001 + 1.928000e+001 -7.957172e+003 3.245512e+001 + 1.929000e+001 -8.002341e+003 3.245081e+001 + 1.930000e+001 -8.018881e+003 3.241943e+001 + 1.931000e+001 -8.007735e+003 3.236656e+001 + 1.932000e+001 -7.970650e+003 3.230158e+001 + 1.933000e+001 -7.910054e+003 3.223609e+001 + 1.934000e+001 -7.828904e+003 3.218182e+001 + 1.935000e+001 -7.730536e+003 3.214854e+001 + 1.936000e+001 -7.618497e+003 3.214226e+001 + 1.937000e+001 -7.496391e+003 3.216408e+001 + 1.938000e+001 -7.367730e+003 3.221003e+001 + 1.939000e+001 -7.235808e+003 3.227180e+001 + 1.940000e+001 -7.103584e+003 3.233827e+001 + 1.941000e+001 -6.973608e+003 3.239757e+001 + 1.942000e+001 -6.847959e+003 3.243918e+001 + 1.943000e+001 -6.728221e+003 3.245573e+001 + 1.944000e+001 -6.615483e+003 3.244435e+001 + 1.945000e+001 -6.510360e+003 3.240705e+001 + 1.946000e+001 -6.413048e+003 3.235046e+001 + 1.947000e+001 -6.323379e+003 3.228463e+001 + 1.948000e+001 -6.240903e+003 3.222132e+001 + 1.949000e+001 -6.164971e+003 3.217188e+001 + 1.950000e+001 -6.094818e+003 3.214521e+001 + 1.951000e+001 -6.029642e+003 3.214614e+001 + 1.952000e+001 -5.968679e+003 3.217445e+001 + 1.953000e+001 -5.911258e+003 3.222501e+001 + 1.954000e+001 -5.856841e+003 3.228870e+001 + 1.955000e+001 -5.805051e+003 3.235407e+001 + 1.956000e+001 -5.755671e+003 3.240948e+001 + 1.957000e+001 -5.708634e+003 3.244510e+001 + 1.958000e+001 -5.663987e+003 3.245466e+001 + 1.959000e+001 -5.621847e+003 3.243650e+001 + 1.960000e+001 -5.582342e+003 3.239385e+001 + 1.961000e+001 -5.545553e+003 3.233427e+001 + 1.962000e+001 -5.511441e+003 3.226836e+001 + 1.963000e+001 -5.479794e+003 3.220789e+001 + 1.964000e+001 -5.450165e+003 3.216373e+001 + 1.965000e+001 -5.421839e+003 3.214381e+001 + 1.966000e+001 -5.393804e+003 3.215173e+001 + 1.967000e+001 -5.364747e+003 3.218601e+001 + 1.968000e+001 -5.333068e+003 3.224044e+001 + 1.969000e+001 -5.296922e+003 3.230520e+001 + 1.970000e+001 -5.254274e+003 3.236869e+001 + 1.971000e+001 -5.202974e+003 3.241960e+001 + 1.972000e+001 -5.140855e+003 3.244893e+001 + 1.973000e+001 -5.065835e+003 3.245153e+001 + 1.974000e+001 -4.976028e+003 3.242698e+001 + 1.975000e+001 -4.869854e+003 3.237962e+001 + 1.976000e+001 -4.746151e+003 3.231788e+001 + 1.977000e+001 -4.604263e+003 3.225276e+001 + 1.978000e+001 -4.444126e+003 3.219591e+001 + 1.979000e+001 -4.266319e+003 3.215754e+001 + 1.980000e+001 -4.072094e+003 3.214456e+001 + 1.981000e+001 -3.863382e+003 3.215930e+001 + 1.982000e+001 -3.642757e+003 3.219906e+001 + 1.983000e+001 -3.413375e+003 3.225662e+001 + 1.984000e+001 -3.178885e+003 3.232162e+001 + 1.985000e+001 -2.943306e+003 3.238241e+001 + 1.986000e+001 -2.710888e+003 3.242820e+001 + 1.987000e+001 -2.485948e+003 3.245088e+001 + 1.988000e+001 -2.272705e+003 3.244648e+001 + 1.989000e+001 -2.075097e+003 3.241579e+001 + 1.990000e+001 -1.896621e+003 3.236427e+001 + 1.991000e+001 -1.740167e+003 3.230107e+001 + 1.992000e+001 -1.607884e+003 3.223747e+001 + 1.993000e+001 -1.501069e+003 3.218487e+001 + 1.994000e+001 -1.420087e+003 3.215273e+001 + 1.995000e+001 -1.364332e+003 3.214685e+001 + 1.996000e+001 -1.332228e+003 3.216827e+001 + 1.997000e+001 -1.321270e+003 3.221309e+001 + 1.998000e+001 -1.328107e+003 3.227321e+001 + 1.999000e+001 -1.348668e+003 3.233782e+001 diff --git a/tests/data/c60xyz.txt b/tests/data/c60xyz.txt new file mode 100644 index 0000000..8fd1cff --- /dev/null +++ b/tests/data/c60xyz.txt @@ -0,0 +1,60 @@ +3.451266498 0.685000000 0.000000000 +3.451266498 -0.685000000 0.000000000 +-3.451266498 0.685000000 0.000000000 +-3.451266498 -0.685000000 0.000000000 +0.685000000 0.000000000 3.451266498 +-0.685000000 0.000000000 3.451266498 +0.685000000 0.000000000 -3.451266498 +-0.685000000 0.000000000 -3.451266498 +0.000000000 3.451266498 0.685000000 +0.000000000 3.451266498 -0.685000000 +0.000000000 -3.451266498 0.685000000 +0.000000000 -3.451266498 -0.685000000 +3.003809890 1.409000000 1.171456608 +3.003809890 1.409000000 -1.171456608 +3.003809890 -1.409000000 1.171456608 +3.003809890 -1.409000000 -1.171456608 +-3.003809890 1.409000000 1.171456608 +-3.003809890 1.409000000 -1.171456608 +-3.003809890 -1.409000000 1.171456608 +-3.003809890 -1.409000000 -1.171456608 +1.409000000 1.171456608 3.003809890 +1.409000000 -1.171456608 3.003809890 +-1.409000000 1.171456608 3.003809890 +-1.409000000 -1.171456608 3.003809890 +1.409000000 1.171456608 -3.003809890 +1.409000000 -1.171456608 -3.003809890 +-1.409000000 1.171456608 -3.003809890 +-1.409000000 -1.171456608 -3.003809890 +1.171456608 3.003809890 1.409000000 +-1.171456608 3.003809890 1.409000000 +1.171456608 3.003809890 -1.409000000 +-1.171456608 3.003809890 -1.409000000 +1.171456608 -3.003809890 1.409000000 +-1.171456608 -3.003809890 1.409000000 +1.171456608 -3.003809890 -1.409000000 +-1.171456608 -3.003809890 -1.409000000 +2.580456608 0.724000000 2.279809890 +2.580456608 0.724000000 -2.279809890 +2.580456608 -0.724000000 2.279809890 +2.580456608 -0.724000000 -2.279809890 +-2.580456608 0.724000000 2.279809890 +-2.580456608 0.724000000 -2.279809890 +-2.580456608 -0.724000000 2.279809890 +-2.580456608 -0.724000000 -2.279809890 +0.724000000 2.279809890 2.580456608 +0.724000000 -2.279809890 2.580456608 +-0.724000000 2.279809890 2.580456608 +-0.724000000 -2.279809890 2.580456608 +0.724000000 2.279809890 -2.580456608 +0.724000000 -2.279809890 -2.580456608 +-0.724000000 2.279809890 -2.580456608 +-0.724000000 -2.279809890 -2.580456608 +2.279809890 2.580456608 0.724000000 +-2.279809890 2.580456608 0.724000000 +2.279809890 2.580456608 -0.724000000 +-2.279809890 2.580456608 -0.724000000 +2.279809890 -2.580456608 0.724000000 +-2.279809890 -2.580456608 0.724000000 +2.279809890 -2.580456608 -0.724000000 +-2.279809890 -2.580456608 -0.724000000 \ No newline at end of file diff --git a/tests/helper.py b/tests/helper.py index ed2087f..3ae5417 100644 --- a/tests/helper.py +++ b/tests/helper.py @@ -9,7 +9,7 @@ FitRecipe, Profile, ) -from diffpy.srfit.pdf import PDFGenerator, PDFParser +from diffpy.srfit.pdf import DebyePDFGenerator, PDFGenerator, PDFParser from diffpy.srfit.structure import constrainAsSpaceGroup from diffpy.structure.parsers import getParser @@ -258,3 +258,89 @@ def run_nanoparticle_example(): name: par.value for name, par in recipe._parameters.items() } return diffpy_pv_dict + + +def run_c60_example(): + from pyobjcryst.crystal import Crystal + from pyobjcryst.molecule import Molecule + from pyobjcryst.scatteringpower import ScatteringPowerAtom + + c60xyz_path = Path(__file__).parent / "data" / "C60xyz.txt" + c60xyz = c60xyz_path.read_text() + + c = Crystal(1, 1, 1, "P1") + c.SetName("c60frame") + # put a molecule inside the box + molecule = Molecule(c, "c60") + c.AddScatterer(molecule) + molecule.AddAtom(0, 0, 0, None, "center") + # Create the scattering power object for the carbon atoms + sp = ScatteringPowerAtom("C", "C") + c.AddScatteringPower(sp) + sp.SetBiso(0.25) + # Add the other atoms. They will be named C1, C2, ..., C60. + for i, l in enumerate(c60xyz.strip().splitlines()): # noqa: E741 + x, y, z = map(float, l.split()) + molecule.AddAtom(x, y, z, sp, "C%i" % (i + 1)) + profile = Profile() + profile.loadtxt(str(Path(__file__).parent / "data" / "C60.gr")) + profile.set_calculation_range(xmin=1.2, xmax=8) + generator = DebyePDFGenerator("G") + generator.setStructure(molecule) + generator.setQmin(0.68) + generator.setQmax(22) + contribution = FitContribution("bucky") + contribution.add_profile_generator(generator) + contribution.set_profile(profile, xname="r") + recipe = FitRecipe() + recipe.add_contribution(contribution) + c60 = generator.phase + + # First, the isotropic thermal displacement factor. + Biso = recipe.create_new_variable("Biso") + for atom in c60.getScatterers(): + # We have defined a 'center' atom that is a dummy, which means that it + # has no scattering power. It is only used as a reference point for + # our bond length. We don't want to constrain it. + if not atom.isDummy(): + recipe.add_constraint(atom.Biso, Biso) + # We need to let the molecule expand. If we were modeling it as a crystal, + # we could let the unit cell expand. For instruction purposes, we use a + # Molecule to model C60, and molecules have different modeling options than + # crystals. To make the molecule expand from a central point, we will + # constrain the distance from each atom to a dummy center atom that was + # created with the molecule, and allow that distance to vary. (We could + # also let the nearest-neighbor bond lengths vary, but that would be much + # more difficult to set up.) + center = c60.center + # Create a new Parameter that represents the radius of the molecule. Note + # that we don't give it an initial value. Since the variable is being + # directly constrained to further below, its initial value will be inferred + # from the constraint. + radius = recipe.create_new_variable("radius") + for i, atom in enumerate(c60.getScatterers()): + + if atom.isDummy(): + continue + + # This creates a Parameter that moves the second atom according to the + # bond length. Note that each Parameter needs a unique name. + par = c60.addBondLengthParameter("rad%i" % i, center, atom) + recipe.add_constraint(par, radius) + + # Add the correlation term, scale. The scale is too short to effectively + # determine qdamp. + recipe.add_variable(generator.delta2, 2) + recipe.add_variable(generator.scale, 1.3e4) + leastsq(recipe.residual, recipe.get_values()) + + diffpy_pv_dict = { + name: par.value for name, par in recipe._parameters.items() + } + return diffpy_pv_dict + + +if __name__ == "__main__": + diffpy_pv_dict = run_c60_example() + # diffpy_pv_dict = run_ni_example() + print(diffpy_pv_dict) diff --git a/tests/test_parametric_model.py b/tests/test_parametric_model.py index 5c690a1..f0e074a 100644 --- a/tests/test_parametric_model.py +++ b/tests/test_parametric_model.py @@ -6,7 +6,7 @@ from diffpy.apps.refinebase.parametric_model import ( ParametricModelEquation, ParametricModelFunction, - ParametricModelPDF, + create_pdf_model_from_file, ) from diffpy.srfit.fitbase import ( Profile, @@ -70,7 +70,7 @@ def test_parametric_pdf_model_parameters(): parser.parse_file(profile_path) profile.load_parsed_data(parser) profile.set_calculation_range(xmax=20) - pdf_model = ParametricModelPDF( + pdf_model = create_pdf_model_from_file( "ni", structure_file_path=str(_DATA_DIR / "Ni.cif") ) parameter_names = [ From 9a7d1c55904b8359b748034f8c064ba9f2d61006 Mon Sep 17 00:00:00 2001 From: Yuchen Xiao Date: Sat, 26 Sep 2026 12:49:28 -0400 Subject: [PATCH 2/7] feat: support molecule PDF refinement --- .../apps/refinebase/parametric_model.py | 108 ++++++---- .../apps/refinebase/refinement_session.py | 197 +++++++++--------- tests/data/c60xyz.txt | 2 +- tests/data/make_c60.py | 21 ++ tests/helper.py | 49 ++--- tests/test_refinement_session.py | 60 +++++- 6 files changed, 266 insertions(+), 171 deletions(-) create mode 100644 tests/data/make_c60.py diff --git a/src/diffpy/apps/refinebase/parametric_model.py b/src/diffpy/apps/refinebase/parametric_model.py index 71ce304..d61535c 100644 --- a/src/diffpy/apps/refinebase/parametric_model.py +++ b/src/diffpy/apps/refinebase/parametric_model.py @@ -8,6 +8,7 @@ from diffpy.srfit.fitbase import FitContribution from diffpy.srfit.fitbase.parameter import Parameter, ParameterProxy +from diffpy.srfit.pdf.debyepdfgenerator import DebyePDFGenerator from diffpy.srfit.pdf.pdfgenerator import PDFGenerator from diffpy.srfit.structure import constrain_as_space_group from diffpy.srfit.structure.diffpyparset import DiffpyStructureParSet @@ -35,19 +36,19 @@ def _construct_parameter_graph( self, parameterset, prefix="", old_graph=None ): parent_name = f"{prefix}{parameterset.name}" - self._graph.add_node(parent_name, parameter=parameterset) + self._graph.add_node(parent_name, obj=parameterset) for par in parameterset._iter_local_parameters(regexp=re.compile("")): par_node_id = f"{parent_name}.{par.name}" if not old_graph or par_node_id not in old_graph.nodes: self._graph.add_node( par_node_id, - parameter=par, + obj=par, constrained_or_constant=False, ) else: self._graph.add_node( par_node_id, - parameter=par, + obj=par, constrained_or_constant=old_graph.nodes[par_node_id][ "constrained_or_constant" ], @@ -59,7 +60,7 @@ def _construct_parameter_graph( # obj is handled as unconstrained by default self._graph.add_node( child_name, - parameter=None, + obj=None, constrained_or_constant=False, ) self._graph.add_edge(parent_name, child_name) @@ -105,7 +106,7 @@ def register_submodel(self, submodel, symbol=None): if f"{self.name}.{submodel.name}" not in self._graph.nodes: self._graph.add_node( symbol, - parameter=None, + obj=submodel, constrained_or_constant=False, ) self._graph.add_edge(self.name, symbol) @@ -119,29 +120,23 @@ def register_submodel(self, submodel, symbol=None): @property def parameters(self): return { - par_node_id: self._graph.nodes[par_node_id]["parameter"] + par_node_id: self._graph.nodes[par_node_id]["obj"] for par_node_id in self._graph.nodes - if isinstance( - self._graph.nodes[par_node_id]["parameter"], Parameter - ) + if isinstance(self._graph.nodes[par_node_id]["obj"], Parameter) } @property def independent_parameters(self): return { - par_node_id: self._graph.nodes[par_node_id]["parameter"] + par_node_id: self._graph.nodes[par_node_id]["obj"] for par_node_id in self._graph.nodes - if isinstance( - self._graph.nodes[par_node_id]["parameter"], Parameter - ) + if isinstance(self._graph.nodes[par_node_id]["obj"], Parameter) and not ( ( - hasattr( - self._graph.nodes[par_node_id]["parameter"], "const" - ) - and self._graph.nodes[par_node_id]["parameter"].const + hasattr(self._graph.nodes[par_node_id]["obj"], "const") + and self._graph.nodes[par_node_id]["obj"].const ) - or self._graph.nodes[par_node_id]["parameter"].constrained + or self._graph.nodes[par_node_id]["obj"].constrained # NOTE: this is a workaround for the constraints not reflected # in par.constrained or self._graph.nodes[par_node_id]["constrained_or_constant"] @@ -250,7 +245,7 @@ def evaluate(self): class ParametricModelPDF(ParametricModel): # NOTE: qmin, qmax, stype(scattering type) are meta handled # throughout the loaded profile in the refinement session - def __init__(self, name, structure, spacegroup_symbol="P1"): + def __init__(self, name, structure, spacegroup_symbol="P1", finite=False): """ Create a ParametricModelPDF instance from a structure object. @@ -259,7 +254,11 @@ def __init__(self, name, structure, spacegroup_symbol="P1"): (e.g. shared from another ParametricModelPDF). """ super().__init__(name=name) - self.calc_obj = PDFGenerator(name) + + if not finite: + self.calc_obj = PDFGenerator(name) + else: + self.calc_obj = DebyePDFGenerator(name) if isinstance( structure, (DiffpyStructureParSet, ObjCrystCrystalParSet) ): @@ -410,42 +409,66 @@ def wrapper(self, *args, **kwargs): @check_molecule_or_molatom def add_bond_length_parameter( - self, name, atom1, atom2, value=None, const=None + self, + par_name, + atom1, + atom2, + value=None, + const=None, + parent_node_name=None, ): phase = self.calc_obj.phase - phase.addBondLengthParameter(name, atom1, atom2, value, const) - self._rebuild_graph() + par = phase.addBondLengthParameter( + par_name, atom1, atom2, value, const + ) + new_node_name = f"{parent_node_name}.{par_name}" + self._graph.add_node( + new_node_name, obj=par, constrained_or_constant=False + ) + self._graph.add_edge(parent_node_name, new_node_name) @check_molecule_or_molatom def add_bond_angle_parameter( self, - name, + par_name, atom1, atom2, atom3, value=None, const=None, + parent_node_name=None, ): phase = self.calc_obj.phase - phase.addBondAngleParameter(name, atom1, atom2, atom3, value, const) - self._rebuild_graph() + par = phase.addBondAngleParameter( + par_name, atom1, atom2, atom3, value, const + ) + new_node_name = f"{parent_node_name}.{par_name}" + self._graph.add_node( + new_node_name, obj=par, constrained_or_constant=False + ) + self._graph.add_edge(parent_node_name, new_node_name) @check_molecule_or_molatom def add_dihedral_angle_parameter( self, - name, + par_name, atom1, atom2, atom3, atom4, value=None, const=None, + parent_node_name=None, ): phase = self.calc_obj.phase - phase.addDihedralAngleParameter( - name, atom1, atom2, atom3, atom4, value, const + par = phase.addDihedralAngleParameter( + par_name, atom1, atom2, atom3, atom4, value, const ) - self._rebuild_graph() + new_node_name = f"{parent_node_name}.{par_name}" + self._graph.add_node( + new_node_name, obj=par, constrained_or_constant=False + ) + self._graph.add_edge(parent_node_name, new_node_name) @check_molecule_or_molatom def restrain_bond_length_parameter( @@ -521,7 +544,9 @@ def residual(self): } -def create_pdf_model_from_file(name, structure_file_path, library="Diffpy"): +def create_pdf_model_from_file( + name, structure_file_path, library="Diffpy", finite=False +): """Create a ParametricModelPDF by parsing a structure file.""" stru_parser = get_parser("auto") structure = stru_parser.parse(Path(structure_file_path).read_text()) @@ -532,7 +557,7 @@ def create_pdf_model_from_file(name, structure_file_path, library="Diffpy"): ) or library == "ObjCryst": structure = loadCrystal(structure_file_path) return ParametricModelPDF( - name, structure, spacegroup_symbol=spacegroup_symbol + name, structure, spacegroup_symbol=spacegroup_symbol, finite=finite ) @@ -546,21 +571,26 @@ def create_pdf_model_from_model(name, from_model): def create_pdf_model_from_code( - name, code, structure_name="structure", spacegroup_symbol="P1" + name, + code, + spacegroup_symbol="P1", + global_namespace={}, + local_structure_name="structure", + finite=False, ): """Create a ParametricModelPDF by executing code that builds a structure. The code must assign the structure/crystal object to a variable named structure_name (default "structure") in its local namespace. """ - global_namespace = {} local_namespace = {} exec(code, global_namespace, local_namespace) - if structure_name not in local_namespace: + if local_structure_name not in local_namespace: raise ValueError( - f"Structure named {structure_name} not found in the executed code." + f"Structure named {local_structure_name} not " + "found in the executed code." ) - structure = local_namespace[structure_name] + structure = local_namespace[local_structure_name] if not type(structure).__module__.startswith("pyobjcryst"): if "spacegroup_symbol" not in local_namespace: logging.warning( @@ -583,10 +613,10 @@ def create_pdf_model_from_code( else: logging.warning( "Could not determine a space group for the structure named " - f"{structure_name}. The default 'spacegroup_symbol' " + f"{local_structure_name}. The default 'spacegroup_symbol' " f"{spacegroup_symbol} will be used." ) return ParametricModelPDF( - name, structure, spacegroup_symbol=spacegroup_symbol + name, structure, spacegroup_symbol=spacegroup_symbol, finite=finite ) diff --git a/src/diffpy/apps/refinebase/refinement_session.py b/src/diffpy/apps/refinebase/refinement_session.py index 08d3f8a..9676be8 100644 --- a/src/diffpy/apps/refinebase/refinement_session.py +++ b/src/diffpy/apps/refinebase/refinement_session.py @@ -1,7 +1,6 @@ import uuid from collections import OrderedDict from collections.abc import Callable -from functools import wraps import numpy from scipy.optimize import leastsq @@ -24,28 +23,6 @@ def __init__(self): self.profiles_dict = OrderedDict() self.models_dict = OrderedDict() - def check_profile_exists(method): - @wraps(method) - def wrapper(self, *args, **kwargs): - profile_name = args[0] if args else kwargs.get("profile_name") - if profile_name not in self.profiles_dict: - raise ValueError( - f"Profile with ID {profile_name} does not exist." - ) - return method(self, *args, **kwargs) - - return wrapper - - def check_model_exists(method): - @wraps(method) - def wrapper(self, *args, **kwargs): - model_name = args[0] if args else kwargs.get("model_name") - if model_name not in self.models_dict: - raise ValueError(f"Model with ID {model_name} does not exist.") - return method(self, *args, **kwargs) - - return wrapper - def add_profile_from_file( self, profile_path: str, @@ -100,21 +77,18 @@ def add_profile_from_arrays( profile._dyname = dyname self.profiles_dict[profile_name] = profile - @check_profile_exists def remove_profile(self, profile_name: str): + self._get_profile(profile_name) del self.profiles_dict[profile_name] - @check_profile_exists def check_profile_meta(self, profile_name: str): - profile = self.profiles_dict[profile_name] + profile = self._get_profile(profile_name) return profile.meta - @check_profile_exists def update_profile_meta(self, profile_name: str, meta: dict): - profile = self.profiles_dict[profile_name] + profile = self._get_profile(profile_name) profile.meta.update(meta) - @check_profile_exists def set_profile_calculation_range( self, profile_name: str, @@ -122,12 +96,11 @@ def set_profile_calculation_range( xmax=None, dx=None, ): - profile = self.profiles_dict[profile_name] + profile = self._get_profile(profile_name) profile.set_calculation_range(xmin, xmax, dx) - @check_profile_exists def set_profile_calculation_points(self, profile_name: str, x): - profile = self.profiles_dict[profile_name] + profile = self._get_profile(profile_name) profile.set_calculation_points(x) def add_equation_model(self, model_name: str, equation_str=None): @@ -152,6 +125,9 @@ def add_pdf_model( from_model_name=None, code=None, library="Diffpy", + global_namespace={}, + local_structure_name="structure", + finite=False, ): from diffpy.apps.refinebase.parametric_model import ( create_pdf_model_from_code, @@ -166,6 +142,7 @@ def add_pdf_model( model_name, structure_file_path, library=library, + finite=finite, ) elif from_model_name is not None: if from_model_name not in self.models_dict: @@ -178,7 +155,13 @@ def add_pdf_model( from_model, ) elif code is not None: - pdf_model = create_pdf_model_from_code(model_name, code) + pdf_model = create_pdf_model_from_code( + model_name, + code, + global_namespace=global_namespace, + local_structure_name=local_structure_name, + finite=finite, + ) else: raise ValueError( "Either structure_file_path, from_model_name, or code " @@ -228,36 +211,18 @@ def combine_models( child_model = self.models_dict[child_model_name] parent_model.register_submodel(child_model) - @check_model_exists def set_model_equation(self, model_name: str, equation: str): - model = self.models_dict[model_name] - if not isinstance(model, ParametricModelEquation): - raise ValueError( - f"Model '{model_name}' is not a " - "ParametricModelEquation instance." - ) + model = self._get_equation_model(model_name) model.set_equation(equation) - @check_model_exists def set_model_residual_equation( self, model_name: str, residual_equation: str ): - model = self.models_dict[model_name] - if not isinstance(model, ParametricModelEquation): - raise ValueError( - f"Model '{model_name}' is not a " - "ParametricModelEquation instance." - ) + model = self._get_equation_model(model_name) model.set_residual_equation(residual_equation) - @check_model_exists def get_model_residual_equation(self, model_name: str) -> str: - model = self.models_dict[model_name] - if not isinstance(model, ParametricModelEquation): - raise ValueError( - f"Model '{model_name}' is not a " - "ParametricModelEquation instance." - ) + model = self._get_equation_model(model_name) return model.get_residual_equation() def set_model_profile(self, model_name: str, profile_name: str): @@ -271,109 +236,138 @@ def set_model_profile(self, model_name: str, profile_name: str): profile = self.profiles_dict[profile_name] model.set_profile(profile) - @check_model_exists def get_model_residual(self, model_name: str): - model = self.models_dict[model_name] + model = self._get_model(model_name) if not hasattr(model, "residual"): raise ValueError( f"Model '{model_name}' does not have a residual method." ) return model.residual() - @check_model_exists def get_model_evaluation(self, model_name: str): - model = self.models_dict[model_name] + model = self._get_model(model_name) if not hasattr(model, "evaluate"): raise ValueError( f"Model '{model_name}' does not have an evaluate method." ) return model.evaluate() - @check_model_exists def constrain_pdf_model_space_group_symmetry( self, model_name, space_group=None ): - model = self.models_dict[model_name] - if not isinstance(model, ParametricModelPDF): - raise ValueError( - f"Model '{model_name}' is not a ParametricModel instance." - ) + model = self._get_pdf_model(model_name) model.constrain_symmetry(space_group) - def _get_pdf_model(self, model_name): + def _get_model(self, model_name): if model_name not in self.models_dict: raise ValueError(f"Model with ID {model_name} does not exist.") - model = self.models_dict[model_name] + return self.models_dict[model_name] + + def _get_pdf_model(self, model_name): + model = self._get_model(model_name) if not isinstance(model, ParametricModelPDF): raise ValueError( f"Model '{model_name}' is not a ParametricModelPDF instance." ) return model - def _get_scatterer(self, model, atom_index): - return model.calc_obj.phase.getScatterers()[atom_index] + def _get_equation_model(self, model_name): + model = self._get_model(model_name) + if not isinstance(model, ParametricModelEquation): + raise ValueError( + f"Model '{model_name}' is not a " + "ParametricModelEquation instance." + ) + return model + + def _get_profile(self, profile_name): + if profile_name not in self.profiles_dict: + raise ValueError(f"Profile with ID {profile_name} does not exist.") + return self.profiles_dict[profile_name] + + def _get_object(self, obj_name): + obj_name_splitted = obj_name.split(".") + model = self._get_pdf_model(obj_name_splitted[0]) + if obj_name not in model._graph.nodes: + raise ValueError( + f"Object with ID {obj_name} does not exist " + f"in the model {model.name}." + ) + return model._graph.nodes[obj_name]["obj"] - @check_model_exists def add_pdf_bond_length_parameter( self, model_name, - name, - atom1_index, - atom2_index, + par_name, + obj1_name, + obj2_name, value=None, const=None, ): model = self._get_pdf_model(model_name) - atom1 = self._get_scatterer(model, atom1_index) - atom2 = self._get_scatterer(model, atom2_index) + atom1 = self._get_object(obj1_name) + atom2 = self._get_object(obj2_name) + parent_node_name = ".".join(obj1_name.split(".")[:-1]) model.add_bond_length_parameter( - name, atom1, atom2, value=value, const=const + par_name, + atom1, + atom2, + value=value, + const=const, + parent_node_name=parent_node_name, ) - @check_model_exists def add_pdf_bond_angle_parameter( self, model_name, - name, - atom1_index, - atom2_index, - atom3_index, + par_name, + obj1_name, + obj2_name, + obj3_name, value=None, const=None, ): model = self._get_pdf_model(model_name) - atom1 = self._get_scatterer(model, atom1_index) - atom2 = self._get_scatterer(model, atom2_index) - atom3 = self._get_scatterer(model, atom3_index) + atom1 = self._get_object(obj1_name) + atom2 = self._get_object(obj2_name) + atom3 = self._get_object(obj3_name) + parent_node_name = ".".join(obj1_name.split(".")[:-1]) model.add_bond_angle_parameter( - name, atom1, atom2, atom3, value=value, const=const + par_name, + atom1, + atom2, + atom3, + value=value, + const=const, + parent_node_name=parent_node_name, ) - @check_model_exists def add_pdf_dihedral_angle_parameter( self, model_name, - name, - atom1_index, - atom2_index, - atom3_index, - atom4_index, + par_name, + obj1_name, + obj2_name, + obj3_name, + obj4_name, value=None, const=None, ): model = self._get_pdf_model(model_name) - atom1 = self._get_scatterer(model, atom1_index) - atom2 = self._get_scatterer(model, atom2_index) - atom3 = self._get_scatterer(model, atom3_index) - atom4 = self._get_scatterer(model, atom4_index) + atom1 = self._get_object(obj1_name) + atom2 = self._get_object(obj2_name) + atom3 = self._get_object(obj3_name) + atom4 = self._get_object(obj4_name) + parent_node_name = ".".join(obj1_name.split(".")[:-1]) model.add_dihedral_angle_parameter( - name, + par_name, atom1, atom2, atom3, atom4, value=value, const=const, + parent_node_name=parent_node_name, ) def restrain_pdf_bond_length_parameter( @@ -434,6 +428,14 @@ def get_variable(self, variable_name): "obj": variable_obj, } + def get_model_obj(self, model_name, obj_name): + model = self._get_model(model_name) + if obj_name not in model._graph.nodes: + raise ValueError( + f"Object '{obj_name}' not found inside model '{model_name}'." + ) + return model._graph.nodes[obj_name]["obj"] + def _solve( self, name, @@ -489,10 +491,7 @@ def _solve( continue recipe.add_variable(var, name=variable_names[i]) - recipe.fix("all") - for variable_name in variable_names: - recipe.free(variable_name) - # least_squares(recipe.residual, recipe.getValues(), x_scale="jac") + recipe.free("all") leastsq(recipe.residual, recipe.getValues()) # NOTE: non-scalar value will raise error in `get_results_string` try: diff --git a/tests/data/c60xyz.txt b/tests/data/c60xyz.txt index 8fd1cff..ba9e102 100644 --- a/tests/data/c60xyz.txt +++ b/tests/data/c60xyz.txt @@ -57,4 +57,4 @@ 2.279809890 -2.580456608 0.724000000 -2.279809890 -2.580456608 0.724000000 2.279809890 -2.580456608 -0.724000000 --2.279809890 -2.580456608 -0.724000000 \ No newline at end of file +-2.279809890 -2.580456608 -0.724000000 diff --git a/tests/data/make_c60.py b/tests/data/make_c60.py new file mode 100644 index 0000000..9aa3bc7 --- /dev/null +++ b/tests/data/make_c60.py @@ -0,0 +1,21 @@ +from pyobjcryst.crystal import Crystal +from pyobjcryst.molecule import Molecule +from pyobjcryst.scatteringpower import ScatteringPowerAtom +from pathlib import Path + +c60xyz = Path(c60xyz_path).read_text() + +c = Crystal(1, 1, 1, "P1") +c.SetName("c60frame") +# put a molecule inside the box +molecule = Molecule(c, "c60") +c.AddScatterer(molecule) +molecule.AddAtom(0, 0, 0, None, "center") +# Create the scattering power object for the carbon atoms +sp = ScatteringPowerAtom("C", "C") +c.AddScatteringPower(sp) +sp.SetBiso(0.25) +# Add the other atoms. They will be named C1, C2, ..., C60. +for i, l in enumerate(c60xyz.strip().splitlines()): # noqa: E741 + x, y, z = map(float, l.split()) + molecule.AddAtom(x, y, z, sp, "C%i" % (i + 1)) diff --git a/tests/helper.py b/tests/helper.py index 3ae5417..dfa5974 100644 --- a/tests/helper.py +++ b/tests/helper.py @@ -13,10 +13,12 @@ from diffpy.srfit.structure import constrainAsSpaceGroup from diffpy.structure.parsers import getParser +_DATA_DIR = Path(__file__).parent / "data" + def run_ni_example(): - structure_path = str(Path(__file__).parent / "data" / "Ni.cif") - profile_path = str(Path(__file__).parent / "data" / "Ni.gr") + structure_path = str(_DATA_DIR / "Ni.cif") + profile_path = str(_DATA_DIR / "Ni.gr") initial_pv_dict = { "s0": 0.4, "qdamp": 0.04, @@ -126,14 +128,12 @@ def run_ni_example(): def run_multi_contribution_example(): - ciffile_ni = str(Path(__file__).parent / "data" / "Ni.cif") - ciffile_si = str(Path(__file__).parent / "data" / "si.cif") - xdata_ni = str(Path(__file__).parent / "data" / "ni-q27r60-xray.gr") - ndata_ni = str(Path(__file__).parent / "data" / "ni-q27r100-neutron.gr") - xdata_si = str(Path(__file__).parent / "data" / "si-q27r60-xray.gr") - xdata_sini = str( - Path(__file__).parent / "data" / "si90ni10-q27r60-xray.gr" - ) + ciffile_ni = str(_DATA_DIR / "Ni.cif") + ciffile_si = str(_DATA_DIR / "si.cif") + xdata_ni = str(_DATA_DIR / "ni-q27r60-xray.gr") + ndata_ni = str(_DATA_DIR / "ni-q27r100-neutron.gr") + xdata_si = str(_DATA_DIR / "si-q27r60-xray.gr") + xdata_sini = str(_DATA_DIR / "si90ni10-q27r60-xray.gr") def makeProfile(datafile): profile = Profile() @@ -261,27 +261,14 @@ def run_nanoparticle_example(): def run_c60_example(): - from pyobjcryst.crystal import Crystal - from pyobjcryst.molecule import Molecule - from pyobjcryst.scatteringpower import ScatteringPowerAtom - - c60xyz_path = Path(__file__).parent / "data" / "C60xyz.txt" - c60xyz = c60xyz_path.read_text() - - c = Crystal(1, 1, 1, "P1") - c.SetName("c60frame") - # put a molecule inside the box - molecule = Molecule(c, "c60") - c.AddScatterer(molecule) - molecule.AddAtom(0, 0, 0, None, "center") - # Create the scattering power object for the carbon atoms - sp = ScatteringPowerAtom("C", "C") - c.AddScatteringPower(sp) - sp.SetBiso(0.25) - # Add the other atoms. They will be named C1, C2, ..., C60. - for i, l in enumerate(c60xyz.strip().splitlines()): # noqa: E741 - x, y, z = map(float, l.split()) - molecule.AddAtom(x, y, z, sp, "C%i" % (i + 1)) + global_namespace = {"c60xyz_path": str(_DATA_DIR / "C60xyz.txt")} + local_namespace = {} + exec( + (Path(__file__).parent / "data" / "make_c60.py").read_text(), + global_namespace, + local_namespace, + ) + molecule = local_namespace["molecule"] profile = Profile() profile.loadtxt(str(Path(__file__).parent / "data" / "C60.gr")) profile.set_calculation_range(xmin=1.2, xmax=8) diff --git a/tests/test_refinement_session.py b/tests/test_refinement_session.py index d72c7e5..f578e95 100644 --- a/tests/test_refinement_session.py +++ b/tests/test_refinement_session.py @@ -5,6 +5,7 @@ run_multi_contribution_example, run_nanoparticle_example, run_ni_example, + run_c60_example, ) from diffpy.apps.refinebase.refinement_session import RefinementSession @@ -320,7 +321,7 @@ def test_refine_nanoparticle_example(): "pdf.phase.Pb0.Uiso": 0.5 / 8 / numpy.pi**2, } ) - refined_parameters = session.solve( + session.solve( profile_names=["pb"], model_names=["main"], variable_names=[ @@ -350,3 +351,60 @@ def test_refine_nanoparticle_example(): refined_parameters["Biso_0"], rtol=1e-2, ) + + +def test_refine_c60_example(): + make_c60_py = (_DATA_DIR / "make_c60.py").read_text() + session = RefinementSession() + session.add_profile_from_file( + profile_path=str(_DATA_DIR / "C60.gr"), profile_name="c60", xname="r" + ) + session.set_profile_calculation_range(profile_name="c60", xmin=1.2, xmax=8) + session.update_profile_meta( + profile_name="c60", meta={"qmin": 0.68, "qmax": 22.0} + ) + session.add_pdf_model( + model_name="pdf", + code=make_c60_py, + local_structure_name="molecule", # The structure name in 'code' + global_namespace={"c60xyz_path": str(_DATA_DIR / "C60xyz.txt")}, + finite=True, + ) + for i in range(1, 61): + # Agent can do iteration outside of the MCP server + session.add_pdf_bond_length_parameter( + model_name="pdf", + par_name=f"rad{i}", + obj1_name="pdf.phase.center", + obj2_name=f"pdf.phase.C{i}", + ) + + session.models_dict["pdf"].independent_parameters["pdf.phase.C1.x"] + initial_radius = session.get_variable("pdf.phase.rad1")["value"] + initial_biso = session.get_variable("pdf.phase.C1.Biso")["value"] + biso_constraints = {f"pdf.phase.C{i}.Biso": "biso" for i in range(1, 61)} + radius_constraints = {f"pdf.phase.rad{i}": "radius" for i in range(1, 61)} + variable_constraints = {**radius_constraints, **biso_constraints} + session.set_variables_value({"pdf.delta2": 2, "pdf.scale": 1.3e4}) + session.solve( + profile_names=["c60"], + model_names=["pdf"], + constraints=[ + {"radius": initial_radius, "biso": initial_biso}, + variable_constraints, + ], + variable_names=["radius", "biso", "pdf.delta2", "pdf.scale"], + ) + refined_parameters = run_c60_example() + name_to_cmi_name = { + "pdf.delta2": "delta2", + "pdf.scale": "scale", + "radius": "radius", + "biso": "Biso", + } + for name, cmi_name in name_to_cmi_name.items(): + assert numpy.isclose( + session.get_variable(name)["value"], + refined_parameters[cmi_name], + rtol=1e-2, + ) From 426e8b3584205bbfc7c9c780ee980c7d35c76040 Mon Sep 17 00:00:00 2001 From: Yuchen Xiao Date: Sat, 26 Sep 2026 14:10:32 -0400 Subject: [PATCH 3/7] feat: support soft bounds and generator run in parallel --- .../apps/refinebase/parametric_model.py | 51 +++++++++++++++++-- .../apps/refinebase/refinement_server.py | 10 ++-- .../apps/refinebase/refinement_session.py | 29 +++++++---- tests/data/{make_c60.py => make_c60.txt} | 3 +- tests/helper.py | 2 +- tests/test_refinement_session.py | 43 +++++++++++++++- 6 files changed, 113 insertions(+), 25 deletions(-) rename tests/data/{make_c60.py => make_c60.txt} (99%) diff --git a/src/diffpy/apps/refinebase/parametric_model.py b/src/diffpy/apps/refinebase/parametric_model.py index d61535c..1047425 100644 --- a/src/diffpy/apps/refinebase/parametric_model.py +++ b/src/diffpy/apps/refinebase/parametric_model.py @@ -4,6 +4,7 @@ from pathlib import Path import networkx as nx +import numpy from pyobjcryst import loadCrystal from diffpy.srfit.fitbase import FitContribution @@ -245,7 +246,14 @@ def evaluate(self): class ParametricModelPDF(ParametricModel): # NOTE: qmin, qmax, stype(scattering type) are meta handled # throughout the loaded profile in the refinement session - def __init__(self, name, structure, spacegroup_symbol="P1", finite=False): + def __init__( + self, + name, + structure, + spacegroup_symbol="P1", + finite=False, + run_parallel=True, + ): """ Create a ParametricModelPDF instance from a structure object. @@ -269,6 +277,25 @@ def __init__(self, name, structure, spacegroup_symbol="P1", finite=False): self.space_group_symbol = spacegroup_symbol self.sgpar_names = [] self._rebuild_graph() + if run_parallel: + try: + import multiprocessing + from multiprocessing import Pool + + import psutil + except ImportError: + print( + "\nYou don't appear to have the " + "necessary packages for parallelization" + ) + syst_cores = multiprocessing.cpu_count() + cpu_percent = psutil.cpu_percent() + avail_cores = numpy.floor( + (100 - cpu_percent) / (100.0 / syst_cores) + ) + ncpu = int(numpy.max([1, avail_cores])) + pool = Pool(processes=ncpu) + self.calc_obj.parallel(ncpu=ncpu, mapfunc=pool.map) def _hide_dependent_parameters(self, use_uiso=True): if use_uiso: @@ -545,7 +572,11 @@ def residual(self): def create_pdf_model_from_file( - name, structure_file_path, library="Diffpy", finite=False + name, + structure_file_path, + library="Diffpy", + finite=False, + run_parallel=True, ): """Create a ParametricModelPDF by parsing a structure file.""" stru_parser = get_parser("auto") @@ -557,16 +588,21 @@ def create_pdf_model_from_file( ) or library == "ObjCryst": structure = loadCrystal(structure_file_path) return ParametricModelPDF( - name, structure, spacegroup_symbol=spacegroup_symbol, finite=finite + name, + structure, + spacegroup_symbol=spacegroup_symbol, + finite=finite, + run_parallel=run_parallel, ) -def create_pdf_model_from_model(name, from_model): +def create_pdf_model_from_model(name, from_model, run_parallel=True): """Create a ParametricModelPDF sharing the phase of from_model.""" return ParametricModelPDF( name, from_model.calc_obj.phase, spacegroup_symbol=from_model.space_group_symbol, + run_parallel=run_parallel, ) @@ -577,6 +613,7 @@ def create_pdf_model_from_code( global_namespace={}, local_structure_name="structure", finite=False, + run_parallel=True, ): """Create a ParametricModelPDF by executing code that builds a structure. @@ -618,5 +655,9 @@ def create_pdf_model_from_code( ) return ParametricModelPDF( - name, structure, spacegroup_symbol=spacegroup_symbol, finite=finite + name, + structure, + spacegroup_symbol=spacegroup_symbol, + finite=finite, + run_parallel=run_parallel, ) diff --git a/src/diffpy/apps/refinebase/refinement_server.py b/src/diffpy/apps/refinebase/refinement_server.py index 8823104..f25a42c 100644 --- a/src/diffpy/apps/refinebase/refinement_server.py +++ b/src/diffpy/apps/refinebase/refinement_server.py @@ -468,8 +468,8 @@ async def solve( "and the second dict is variable-constraint_equation pair." ), ] = None, - restraints: Annotated[ - list[str], "List of restraints to apply during the refinement" + bounds: Annotated[ + dict, "Dictionary of bounds for variables or equations" ] = None, name: Annotated[str, "Name of the refinement session"] = None, weights: Annotated[ @@ -498,8 +498,8 @@ async def solve( constraints : list[dict], optional First dict is new_variable-initial value pair, and the second dict is variable-constraint_equation pair. - restraints : list[str], optional - List of restraints to apply during the refinement. + bounds : dict, optional + Dictionary of bounds for variables or equations. name : str, optional Name of the refinement session. weights : list[float], optional @@ -526,7 +526,7 @@ async def solve( variable_names, residual_equations=residual_equations, constraints=constraints, - restraints=restraints, + bounds=bounds, name=name, weights=weights, metas=metas, diff --git a/src/diffpy/apps/refinebase/refinement_session.py b/src/diffpy/apps/refinebase/refinement_session.py index 9676be8..c443a8a 100644 --- a/src/diffpy/apps/refinebase/refinement_session.py +++ b/src/diffpy/apps/refinebase/refinement_session.py @@ -56,7 +56,6 @@ def add_profile_from_arrays( self, xarray, yarray, - dx=None, dy=None, profile_name: str = None, xname: str = "x", @@ -68,7 +67,7 @@ def add_profile_from_arrays( if profile_name is None: profile_name = str(uuid.uuid4()) profile = Profile() - profile.setObservedProfile(xarray, yarray, dx=dx, dy=dy) + profile.setObservedProfile(xobs=xarray, yobs=yarray, dyobs=dy) profile.xpar.name = xname profile._xname = xname profile.ypar.name = yname @@ -443,19 +442,19 @@ def _solve( models, variable_names, constraints=None, - restraints=None, + bounds=None, weights=None, residual_equations=None, metas=None, - verbose_iterations=0, ): - # NOTE: restraints to be implemented recipe = FitRecipe() self.recipes_dict[name] = recipe if weights is None: weights = numpy.ones(len(profiles)) if residual_equations is None: residual_equations = ["chiv"] * len(profiles) + if bounds is None: + bounds = {} if metas is not None: for i in range(len(metas)): profiles[i].meta.update(metas[i]) @@ -490,7 +489,15 @@ def _solve( if var in recipe._parameters.values(): continue recipe.add_variable(var, name=variable_names[i]) - + for eq_or_var_name, arg_dict in bounds.items(): + lb = arg_dict.get("lower_bound", -numpy.inf) + ub = arg_dict.get("upper_bound", numpy.inf) + unc = arg_dict.get("uncertainty", 1) + scaled = arg_dict.get("scaled", False) + eq_or_var_name = eq_or_var_name.replace(".", "_") + recipe.add_soft_bounds( + eq_or_var_name, lb, ub, sig=unc, scaled=scaled + ) recipe.free("all") leastsq(recipe.residual, recipe.getValues()) # NOTE: non-scalar value will raise error in `get_results_string` @@ -507,12 +514,11 @@ def solve( variable_names=[], residual_equations=None, constraints=None, - restraints=None, + bounds=None, name=uuid.uuid4(), weights=None, metas=None, include_sgpars=False, - verbose_iterations=0, ): profiles = [] for profile_name in profile_names: @@ -551,11 +557,10 @@ def solve( variable_names=variable_names, residual_equations=residual_equations, constraints=constraints, - restraints=restraints, + bounds=bounds, name=name, weights=weights, metas=metas, - verbose_iterations=verbose_iterations, ) def plot(self): @@ -563,7 +568,9 @@ def plot(self): for id, recipe in self.recipes_dict.items(): recipe.plot_recipe() - def clear(self): + def clear( + self, + ): self.profiles_dict.clear() self.models_dict.clear() self.recipes_dict.clear() diff --git a/tests/data/make_c60.py b/tests/data/make_c60.txt similarity index 99% rename from tests/data/make_c60.py rename to tests/data/make_c60.txt index 9aa3bc7..7532723 100644 --- a/tests/data/make_c60.py +++ b/tests/data/make_c60.txt @@ -1,7 +1,8 @@ +from pathlib import Path + from pyobjcryst.crystal import Crystal from pyobjcryst.molecule import Molecule from pyobjcryst.scatteringpower import ScatteringPowerAtom -from pathlib import Path c60xyz = Path(c60xyz_path).read_text() diff --git a/tests/helper.py b/tests/helper.py index dfa5974..f54a0ed 100644 --- a/tests/helper.py +++ b/tests/helper.py @@ -264,7 +264,7 @@ def run_c60_example(): global_namespace = {"c60xyz_path": str(_DATA_DIR / "C60xyz.txt")} local_namespace = {} exec( - (Path(__file__).parent / "data" / "make_c60.py").read_text(), + (Path(__file__).parent / "data" / "make_c60.txt").read_text(), global_namespace, local_namespace, ) diff --git a/tests/test_refinement_session.py b/tests/test_refinement_session.py index f578e95..b1713fb 100644 --- a/tests/test_refinement_session.py +++ b/tests/test_refinement_session.py @@ -2,10 +2,10 @@ import numpy from helper import ( + run_c60_example, run_multi_contribution_example, run_nanoparticle_example, run_ni_example, - run_c60_example, ) from diffpy.apps.refinebase.refinement_session import RefinementSession @@ -13,6 +13,45 @@ _DATA_DIR = Path(__file__).parent / "data" +def test_restraint(): + xarray = numpy.linspace(0, 10, 100) + yarray = 2 * xarray + session = RefinementSession() + session.add_profile_from_arrays( + profile_name="linear", xarray=xarray, yarray=yarray + ) + session.add_equation_model(model_name="linear_model", equation_str="m*x") + session.set_variables_value( + { + "linear_model.m": 1, + } + ) + session._solve( + name="linear_upper_bound", + profiles=[session.profiles_dict["linear"]], + models=[session.models_dict["linear_model"]], + variable_names=["linear_model.m"], + bounds={"linear_model.m": {"upper_bound": 1.8, "uncertainty": 1e-4}}, + ) + assert numpy.isclose( + session.get_variable("linear_model.m")["value"], + 1.8, + rtol=1e-2, + ) + session._solve( + name="linear_lower_bound", + profiles=[session.profiles_dict["linear"]], + models=[session.models_dict["linear_model"]], + variable_names=["linear_model.m"], + bounds={"linear_model.m": {"lower_bound": 2.2, "uncertainty": 1e-4}}, + ) + assert numpy.isclose( + session.get_variable("linear_model.m")["value"], + 2.2, + rtol=1e-2, + ) + + def test_refine_sine(sine_profile): # C1: Refinement session without additional calculator or functions session = RefinementSession() @@ -354,7 +393,7 @@ def test_refine_nanoparticle_example(): def test_refine_c60_example(): - make_c60_py = (_DATA_DIR / "make_c60.py").read_text() + make_c60_py = (_DATA_DIR / "make_c60.txt").read_text() session = RefinementSession() session.add_profile_from_file( profile_path=str(_DATA_DIR / "C60.gr"), profile_name="c60", xname="r" From a3a44cbf074e318cb308ee92dcb5a0e06d0c76fd Mon Sep 17 00:00:00 2001 From: Yuchen Xiao Date: Sat, 26 Sep 2026 14:34:15 -0400 Subject: [PATCH 4/7] feat: support fetching cif files --- news/misc_functionalities.rst | 25 ++++++ requirements/conda.txt | 2 + .../apps/refinebase/refinement_server.py | 19 +++++ src/diffpy/apps/refinebase/util.py | 80 +++++++++++++++++++ 4 files changed, 126 insertions(+) create mode 100644 news/misc_functionalities.rst create mode 100644 src/diffpy/apps/refinebase/util.py diff --git a/news/misc_functionalities.rst b/news/misc_functionalities.rst new file mode 100644 index 0000000..06f6a02 --- /dev/null +++ b/news/misc_functionalities.rst @@ -0,0 +1,25 @@ +**Added:** + +* Add generator parallelism. +* Add soft bounds. +* add a tool to download cif file from database. + +**Changed:** + +* + +**Deprecated:** + +* + +**Removed:** + +* + +**Fixed:** + +* + +**Security:** + +* diff --git a/requirements/conda.txt b/requirements/conda.txt index 38287db..9262811 100644 --- a/requirements/conda.txt +++ b/requirements/conda.txt @@ -8,3 +8,5 @@ diffpy.srreal diffpy.structure networkx mcp[cli] +mp-api +pymatgen diff --git a/src/diffpy/apps/refinebase/refinement_server.py b/src/diffpy/apps/refinebase/refinement_server.py index f25a42c..c2c0fec 100644 --- a/src/diffpy/apps/refinebase/refinement_server.py +++ b/src/diffpy/apps/refinebase/refinement_server.py @@ -11,6 +11,7 @@ from mcp.server.mcpserver.exceptions import ToolError from diffpy.apps.refinebase.refinement_session import RefinementSession +from diffpy.apps.refinebase.util import * session = RefinementSession() mcp = MCPServer("diffpy.apps") @@ -56,6 +57,24 @@ async def refinement_playbook(): return f.read() +@mcp.tool() +@tool_errors +async def download_mp_cifs_tool( + query: Annotated[str, "Query for the Materials Project structures"], + start_index: Annotated[int, "Start index of the structures to download"], + end_index: Annotated[int, "End index of the structures to download"], + output_dir: Annotated[str, "Directory to save the CIF files"] = "mp_cifs", + api_key: Annotated[str | None, "Materials Project API key"] = None, +) -> list[str]: + """Download a consecutive range of Materials Project structures as CIF files.""" + return [ + str(path) + for path in download_mp_cifs( + query, start_index, end_index, output_dir, api_key + ) + ] + + @mcp.tool() @tool_errors async def add_profile_from_file( diff --git a/src/diffpy/apps/refinebase/util.py b/src/diffpy/apps/refinebase/util.py new file mode 100644 index 0000000..134a17b --- /dev/null +++ b/src/diffpy/apps/refinebase/util.py @@ -0,0 +1,80 @@ +from __future__ import annotations + +import os +from pathlib import Path + +from mp_api.client import MPRester +from pymatgen.io.cif import CifWriter + + +def download_mp_cifs( + query: str, + start_index: int, + end_index: int, + output_dir: str | Path = "mp_cifs", + api_key: str | None = None, +) -> list[Path]: + """ + Download a consecutive range of Materials Project structures as CIF files. + + Parameters + ---------- + query + One of: + - Materials Project ID: "mp-149" + - Formula: "SiO2" or "LiNbO3" + - Chemical system: "Li-Ti-Nb-O" + start_index, end_index + Zero-based inclusive indices in the returned MP result list. + output_dir + Directory in which CIF files will be written. + api_key + Materials Project API key. If omitted, reads MP_API_KEY from + the environment. + + Returns + ------- + list[Path] + Paths of the CIF files written. + """ + if start_index < 0 or end_index < start_index: + raise ValueError("Require 0 <= start_index <= end_index.") + + api_key = api_key or os.environ["MP_API_KEY"] + output_dir = Path(output_dir) + output_dir.mkdir(parents=True, exist_ok=True) + + with MPRester(api_key) as mpr: + if query.startswith("mp-"): + docs = mpr.materials.summary.search( + material_ids=[query], + fields=["material_id", "structure"], + ) + elif "-" in query: + # Example: "Li-Ti-Nb-O" + docs = mpr.materials.summary.search( + chemsys=query, + fields=["material_id", "structure"], + ) + else: + # Example: "SiO2" or "LiNbO3" + docs = mpr.materials.summary.search( + formula=[query], + fields=["material_id", "structure"], + ) + + if end_index >= len(docs): + raise IndexError( + f"Requested index {end_index}, but MP returned only " + f"{len(docs)} structure(s)." + ) + + written_files = [] + + for index in range(start_index, end_index + 1): + doc = docs[index] + filename = output_dir / f"{index:04d}_{doc.material_id}.cif" + CifWriter(doc.structure).write_file(filename) + written_files.append(filename) + + return written_files From d821b56837bf29c5e9b8a3917f400f02c4a0cda4 Mon Sep 17 00:00:00 2001 From: Yuchen Xiao Date: Sat, 26 Sep 2026 14:39:13 -0400 Subject: [PATCH 5/7] chore: clean tests --- tests/helper.py | 6 ------ 1 file changed, 6 deletions(-) diff --git a/tests/helper.py b/tests/helper.py index f54a0ed..9bead23 100644 --- a/tests/helper.py +++ b/tests/helper.py @@ -325,9 +325,3 @@ def run_c60_example(): name: par.value for name, par in recipe._parameters.items() } return diffpy_pv_dict - - -if __name__ == "__main__": - diffpy_pv_dict = run_c60_example() - # diffpy_pv_dict = run_ni_example() - print(diffpy_pv_dict) From 0934630b67d77de5c629d346c7e440ef6f79bb97 Mon Sep 17 00:00:00 2001 From: Yuchen Xiao Date: Sat, 26 Sep 2026 16:59:38 -0400 Subject: [PATCH 6/7] feat: add hard bounds --- src/diffpy/apps/refinebase/refinement_server.py | 6 ++++-- .../apps/refinebase/refinement_session.py | 17 +++++++++++------ tests/test_refinement_session.py | 8 +++++++- 3 files changed, 22 insertions(+), 9 deletions(-) diff --git a/src/diffpy/apps/refinebase/refinement_server.py b/src/diffpy/apps/refinebase/refinement_server.py index c2c0fec..9de7dc0 100644 --- a/src/diffpy/apps/refinebase/refinement_server.py +++ b/src/diffpy/apps/refinebase/refinement_server.py @@ -11,7 +11,7 @@ from mcp.server.mcpserver.exceptions import ToolError from diffpy.apps.refinebase.refinement_session import RefinementSession -from diffpy.apps.refinebase.util import * +from diffpy.apps.refinebase.util import download_mp_cifs session = RefinementSession() mcp = MCPServer("diffpy.apps") @@ -66,7 +66,9 @@ async def download_mp_cifs_tool( output_dir: Annotated[str, "Directory to save the CIF files"] = "mp_cifs", api_key: Annotated[str | None, "Materials Project API key"] = None, ) -> list[str]: - """Download a consecutive range of Materials Project structures as CIF files.""" + """ + Download a consecutive range of Materials Project structures as CIF files. + """ return [ str(path) for path in download_mp_cifs( diff --git a/src/diffpy/apps/refinebase/refinement_session.py b/src/diffpy/apps/refinebase/refinement_session.py index c443a8a..4de0540 100644 --- a/src/diffpy/apps/refinebase/refinement_session.py +++ b/src/diffpy/apps/refinebase/refinement_session.py @@ -492,12 +492,17 @@ def _solve( for eq_or_var_name, arg_dict in bounds.items(): lb = arg_dict.get("lower_bound", -numpy.inf) ub = arg_dict.get("upper_bound", numpy.inf) - unc = arg_dict.get("uncertainty", 1) - scaled = arg_dict.get("scaled", False) - eq_or_var_name = eq_or_var_name.replace(".", "_") - recipe.add_soft_bounds( - eq_or_var_name, lb, ub, sig=unc, scaled=scaled - ) + use_soft_bounds = arg_dict.get("use_soft_bounds", True) + if use_soft_bounds: + uncertainty = arg_dict.get("uncertainty", 1) + scaled = arg_dict.get("scaled", False) + eq_or_var_name = eq_or_var_name.replace(".", "_") + recipe.add_soft_bounds( + eq_or_var_name, lb, ub, sig=uncertainty, scaled=scaled + ) + else: + par = self.get_variable(eq_or_var_name)["obj"] + par.bound_range(lb, ub) recipe.free("all") leastsq(recipe.residual, recipe.getValues()) # NOTE: non-scalar value will raise error in `get_results_string` diff --git a/tests/test_refinement_session.py b/tests/test_refinement_session.py index b1713fb..6db9bd3 100644 --- a/tests/test_refinement_session.py +++ b/tests/test_refinement_session.py @@ -13,7 +13,9 @@ _DATA_DIR = Path(__file__).parent / "data" -def test_restraint(): +def test_bonds(): + # C1: Create a soft bound with an upper limit and high penalty + # Expect the variable to be constrained by the upper bound xarray = numpy.linspace(0, 10, 100) yarray = 2 * xarray session = RefinementSession() @@ -38,6 +40,8 @@ def test_restraint(): 1.8, rtol=1e-2, ) + # C2: Create a soft bound with a lower limit and high penalty + # Expect the variable to be constrained by the lower bound session._solve( name="linear_lower_bound", profiles=[session.profiles_dict["linear"]], @@ -50,6 +54,8 @@ def test_restraint(): 2.2, rtol=1e-2, ) + # NOTE: hard bounds are defined but not used by diffpy.srfit + # Skip testing hard bounds. def test_refine_sine(sine_profile): From c3036dcb7f2c58ec34021eec4709a024e0fae90e Mon Sep 17 00:00:00 2001 From: Yuchen Xiao Date: Sat, 26 Sep 2026 17:08:01 -0400 Subject: [PATCH 7/7] chore: add interface in the server --- requirements/conda.txt | 2 +- .../apps/refinebase/refinement_server.py | 35 +++++++++++++++++-- 2 files changed, 34 insertions(+), 3 deletions(-) diff --git a/requirements/conda.txt b/requirements/conda.txt index 9262811..9a93f82 100644 --- a/requirements/conda.txt +++ b/requirements/conda.txt @@ -8,5 +8,5 @@ diffpy.srreal diffpy.structure networkx mcp[cli] -mp-api +mp-api pymatgen diff --git a/src/diffpy/apps/refinebase/refinement_server.py b/src/diffpy/apps/refinebase/refinement_server.py index 9de7dc0..82940a0 100644 --- a/src/diffpy/apps/refinebase/refinement_server.py +++ b/src/diffpy/apps/refinebase/refinement_server.py @@ -102,7 +102,6 @@ async def add_profile_from_file( async def add_profile_from_arrays( xarray: Annotated[list, "X-values of the profile"], yarray: Annotated[list, "Y-values of the profile"], - dx: Annotated[list, "Uncertainties in the x-values"] = None, dy: Annotated[list, "Uncertainties in the y-values"] = None, profile_name: Annotated[str, "Unique name for the profile"] = None, xname: Annotated[str, "Name of the x-axis for the profile"] = "x", @@ -113,7 +112,6 @@ async def add_profile_from_arrays( session.add_profile_from_arrays( xarray, yarray, - dx=dx, dy=dy, profile_name=profile_name, xname=xname, @@ -203,6 +201,21 @@ async def add_pdf_model( from_model_name: Annotated[ str, "Name of the existing model to base the new model on" ] = None, + code: Annotated[ + str, "Code that builds a structure to base the new model on" + ] = None, + library: Annotated[ + str, "Structure library to use ('Diffpy' or 'ObjCryst')" + ] = "Diffpy", + global_namespace: Annotated[ + dict, "Global namespace to execute 'code' in" + ] = {}, + local_structure_name: Annotated[ + str, "Name of the structure variable assigned by 'code'" + ] = "structure", + finite: Annotated[ + bool, "Whether to use DebyePDFGenerator instead of PDFGenerator" + ] = False, ) -> str: """ Add a structure-file-based parametric model to the refinement session. @@ -214,6 +227,16 @@ async def add_pdf_model( structure_file_path : str, optional Path to the structure file. from_model_name : str, optional + code : str, optional + Code that builds a structure to base the new model on. + library : str, optional + Structure library to use ('Diffpy' or 'ObjCryst'). + global_namespace : dict, optional + Global namespace to execute 'code' in. + local_structure_name : str, optional + Name of the structure variable assigned by 'code'. + finite : bool, optional + Whether to use DebyePDFGenerator instead of PDFGenerator. Notes ----- @@ -221,11 +244,19 @@ async def add_pdf_model( existing computation object. For example, when the same phase's signal is observed in multiple profiles, 'from_model_name' allows the refinement backend to modify the same structure across multiple profiles. + + Exactly one of 'structure_file_path', 'from_model_name', or 'code' + must be provided. """ session.add_pdf_model( model_name=model_name, structure_file_path=structure_file_path, from_model_name=from_model_name, + code=code, + library=library, + global_namespace=global_namespace, + local_structure_name=local_structure_name, + finite=finite, ) return f"Model {model_name} added successfully."