diff --git a/pyproject.toml b/pyproject.toml index f10e4d0..9a63ce3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -5,7 +5,8 @@ requires = ['flit_core>=3.4,<4'] [project] authors = [ {name = 'Sebastiaan P. Huber', email = 'mail@sphuber.net'}, - {name = 'Adam Grofe', email = 'v-adamgrofe@microsoft.com'} + {name = 'Adam Grofe', email = 'adamgrofe@microsoft.com'}, + {name = 'Conrad Johnston', email = 'conrad.johnston@microsoft.com'} ] classifiers = [ 'Development Status :: 3 - Alpha', @@ -20,19 +21,18 @@ classifiers = [ 'Topic :: Scientific/Engineering' ] dependencies = [ - 'aiida-core[atomic_tools]~=2.5', + 'aiida-core[atomic_tools]~=2.6', 'aiida-shell>=0.5.3', - 'dill', 'numpy', 'pint', - 'pyscf[geomopt]~=2.2,<2.4' + 'pyscf[geomopt] ~= 2.7' ] dynamic = ['description', 'version'] keywords = ['aiida', 'workflows', 'pyscf'] license = {file = 'LICENSE.txt'} name = 'aiida-pyscf' readme = 'README.md' -requires-python = '>=3.9' +requires-python = '>=3.9,<3.12' [project.entry-points.'aiida.calculations'] 'pyscf.base' = 'aiida_pyscf.calculations.base:PyscfCalculation' @@ -51,7 +51,7 @@ pre-commit = [ tests = [ 'packaging', 'pgtest~=1.3,>=1.3.1', - 'pytest~=7.2', + 'pytest~=8.3', 'pytest-regressions' ] diff --git a/src/aiida_pyscf/calculations/templates/results.py.j2 b/src/aiida_pyscf/calculations/templates/results.py.j2 index a9a70f8..024efd3 100644 --- a/src/aiida_pyscf/calculations/templates/results.py.j2 +++ b/src/aiida_pyscf/calculations/templates/results.py.j2 @@ -1,7 +1,7 @@ # Section: Results def write_results_and_exit(results): - import dill import json + import pickle import sys results['timings']['total'] = time.perf_counter() - time_start @@ -11,11 +11,8 @@ def write_results_and_exit(results): {% if results.pickle_model %} with open('{{ results.filename_model }}', 'wb') as handle: - # Need to unset the ``_chkfile`` attribute as it contains an open file handle which cannot be unpickled. - mean_field_run._chkfile = None - # Need to unset the ``opt`` attribute as it contains ctypes objects containing pointers which cannot be pickled. - mean_field_run.opt = None - dill.dump(mean_field_run, handle) + pickle.dump(mean_field_run, handle) + {% endif %} sys.exit(0) diff --git a/src/aiida_pyscf/parsers/base.py b/src/aiida_pyscf/parsers/base.py index ec57dce..d7d72ea 100644 --- a/src/aiida_pyscf/parsers/base.py +++ b/src/aiida_pyscf/parsers/base.py @@ -4,8 +4,8 @@ import json import pathlib +import pickle -import dill import numpy from aiida.engine import ExitCode from aiida.orm import ArrayData, Dict, FolderData, SinglefileData, TrajectoryData @@ -54,11 +54,11 @@ def parse(self, retrieved_temporary_folder: str | None = None, **kwargs): # noq try: with retrieved.open(PyscfCalculation.FILENAME_MODEL, 'rb') as handle: - model = dill.load(handle) + model = pickle.load(handle) except FileNotFoundError: if parameters.get('results', {}).get('pickle_model', True): self.logger.warning(f'The pickled model file `{PyscfCalculation.FILENAME_MODEL}` could not be read.') - except dill.UnpicklingError: + except pickle.UnpicklingError: self.logger.warning(f'The pickled model file `{PyscfCalculation.FILENAME_MODEL}` could not be unpickled.') else: self.out('model', PickledData(model)) diff --git a/tests/calculations/test_base/test_checkpoint.pyr b/tests/calculations/test_base/test_checkpoint.pyr index af93197..84105bd 100644 --- a/tests/calculations/test_base/test_checkpoint.pyr +++ b/tests/calculations/test_base/test_checkpoint.pyr @@ -14,8 +14,8 @@ def main(): # Section: Results def write_results_and_exit(results): - import dill import json + import pickle import sys results['timings']['total'] = time.perf_counter() - time_start @@ -24,14 +24,10 @@ def main(): json.dump(results, handle) with open('model.pickle', 'wb') as handle: - # Need to unset the ``_chkfile`` attribute as it contains an open file handle which cannot be unpickled. - mean_field_run._chkfile = None - # Need to unset the ``opt`` attribute as it contains ctypes objects containing pointers which cannot be pickled. - mean_field_run.opt = None - dill.dump(mean_field_run, handle) + pickle.dump(mean_field_run, handle) - sys.exit(0) + sys.exit(0) # Section: Structure definition from pyscf import gto structure = gto.Mole() diff --git a/tests/calculations/test_base/test_default.pyr b/tests/calculations/test_base/test_default.pyr index 448ce84..65b6942 100644 --- a/tests/calculations/test_base/test_default.pyr +++ b/tests/calculations/test_base/test_default.pyr @@ -14,8 +14,8 @@ def main(): # Section: Results def write_results_and_exit(results): - import dill import json + import pickle import sys results['timings']['total'] = time.perf_counter() - time_start @@ -24,14 +24,10 @@ def main(): json.dump(results, handle) with open('model.pickle', 'wb') as handle: - # Need to unset the ``_chkfile`` attribute as it contains an open file handle which cannot be unpickled. - mean_field_run._chkfile = None - # Need to unset the ``opt`` attribute as it contains ctypes objects containing pointers which cannot be pickled. - mean_field_run.opt = None - dill.dump(mean_field_run, handle) + pickle.dump(mean_field_run, handle) - sys.exit(0) + sys.exit(0) # Section: Structure definition from pyscf import gto structure = gto.Mole() diff --git a/tests/calculations/test_base/test_parameters_cubegen_parameters0_.pyr b/tests/calculations/test_base/test_parameters_cubegen_parameters0_.pyr index 65f8683..68ffdff 100644 --- a/tests/calculations/test_base/test_parameters_cubegen_parameters0_.pyr +++ b/tests/calculations/test_base/test_parameters_cubegen_parameters0_.pyr @@ -14,8 +14,8 @@ def main(): # Section: Results def write_results_and_exit(results): - import dill import json + import pickle import sys results['timings']['total'] = time.perf_counter() - time_start @@ -24,14 +24,10 @@ def main(): json.dump(results, handle) with open('model.pickle', 'wb') as handle: - # Need to unset the ``_chkfile`` attribute as it contains an open file handle which cannot be unpickled. - mean_field_run._chkfile = None - # Need to unset the ``opt`` attribute as it contains ctypes objects containing pointers which cannot be pickled. - mean_field_run.opt = None - dill.dump(mean_field_run, handle) + pickle.dump(mean_field_run, handle) - sys.exit(0) + sys.exit(0) # Section: Structure definition from pyscf import gto structure = gto.Mole() diff --git a/tests/calculations/test_base/test_parameters_cubegen_parameters1_.pyr b/tests/calculations/test_base/test_parameters_cubegen_parameters1_.pyr index 4c53af2..2657a5b 100644 --- a/tests/calculations/test_base/test_parameters_cubegen_parameters1_.pyr +++ b/tests/calculations/test_base/test_parameters_cubegen_parameters1_.pyr @@ -14,8 +14,8 @@ def main(): # Section: Results def write_results_and_exit(results): - import dill import json + import pickle import sys results['timings']['total'] = time.perf_counter() - time_start @@ -24,14 +24,10 @@ def main(): json.dump(results, handle) with open('model.pickle', 'wb') as handle: - # Need to unset the ``_chkfile`` attribute as it contains an open file handle which cannot be unpickled. - mean_field_run._chkfile = None - # Need to unset the ``opt`` attribute as it contains ctypes objects containing pointers which cannot be pickled. - mean_field_run.opt = None - dill.dump(mean_field_run, handle) + pickle.dump(mean_field_run, handle) - sys.exit(0) + sys.exit(0) # Section: Structure definition from pyscf import gto structure = gto.Mole() diff --git a/tests/calculations/test_base/test_parameters_cubegen_parameters2_.pyr b/tests/calculations/test_base/test_parameters_cubegen_parameters2_.pyr index ee5ee85..3d7edbd 100644 --- a/tests/calculations/test_base/test_parameters_cubegen_parameters2_.pyr +++ b/tests/calculations/test_base/test_parameters_cubegen_parameters2_.pyr @@ -14,8 +14,8 @@ def main(): # Section: Results def write_results_and_exit(results): - import dill import json + import pickle import sys results['timings']['total'] = time.perf_counter() - time_start @@ -24,14 +24,10 @@ def main(): json.dump(results, handle) with open('model.pickle', 'wb') as handle: - # Need to unset the ``_chkfile`` attribute as it contains an open file handle which cannot be unpickled. - mean_field_run._chkfile = None - # Need to unset the ``opt`` attribute as it contains ctypes objects containing pointers which cannot be pickled. - mean_field_run.opt = None - dill.dump(mean_field_run, handle) + pickle.dump(mean_field_run, handle) - sys.exit(0) + sys.exit(0) # Section: Structure definition from pyscf import gto structure = gto.Mole() diff --git a/tests/calculations/test_base/test_parameters_cubegen_parameters3_.pyr b/tests/calculations/test_base/test_parameters_cubegen_parameters3_.pyr index 0024f46..e118d7e 100644 --- a/tests/calculations/test_base/test_parameters_cubegen_parameters3_.pyr +++ b/tests/calculations/test_base/test_parameters_cubegen_parameters3_.pyr @@ -14,8 +14,8 @@ def main(): # Section: Results def write_results_and_exit(results): - import dill import json + import pickle import sys results['timings']['total'] = time.perf_counter() - time_start @@ -24,14 +24,10 @@ def main(): json.dump(results, handle) with open('model.pickle', 'wb') as handle: - # Need to unset the ``_chkfile`` attribute as it contains an open file handle which cannot be unpickled. - mean_field_run._chkfile = None - # Need to unset the ``opt`` attribute as it contains ctypes objects containing pointers which cannot be pickled. - mean_field_run.opt = None - dill.dump(mean_field_run, handle) + pickle.dump(mean_field_run, handle) - sys.exit(0) + sys.exit(0) # Section: Structure definition from pyscf import gto structure = gto.Mole() diff --git a/tests/calculations/test_base/test_parameters_fcidump.pyr b/tests/calculations/test_base/test_parameters_fcidump.pyr index c8862c3..23bef76 100644 --- a/tests/calculations/test_base/test_parameters_fcidump.pyr +++ b/tests/calculations/test_base/test_parameters_fcidump.pyr @@ -14,8 +14,8 @@ def main(): # Section: Results def write_results_and_exit(results): - import dill import json + import pickle import sys results['timings']['total'] = time.perf_counter() - time_start @@ -24,14 +24,10 @@ def main(): json.dump(results, handle) with open('model.pickle', 'wb') as handle: - # Need to unset the ``_chkfile`` attribute as it contains an open file handle which cannot be unpickled. - mean_field_run._chkfile = None - # Need to unset the ``opt`` attribute as it contains ctypes objects containing pointers which cannot be pickled. - mean_field_run.opt = None - dill.dump(mean_field_run, handle) + pickle.dump(mean_field_run, handle) - sys.exit(0) + sys.exit(0) # Section: Structure definition from pyscf import gto structure = gto.Mole() diff --git a/tests/calculations/test_base/test_parameters_hessian.pyr b/tests/calculations/test_base/test_parameters_hessian.pyr index 0bd2703..1afbac2 100644 --- a/tests/calculations/test_base/test_parameters_hessian.pyr +++ b/tests/calculations/test_base/test_parameters_hessian.pyr @@ -14,8 +14,8 @@ def main(): # Section: Results def write_results_and_exit(results): - import dill import json + import pickle import sys results['timings']['total'] = time.perf_counter() - time_start @@ -24,14 +24,10 @@ def main(): json.dump(results, handle) with open('model.pickle', 'wb') as handle: - # Need to unset the ``_chkfile`` attribute as it contains an open file handle which cannot be unpickled. - mean_field_run._chkfile = None - # Need to unset the ``opt`` attribute as it contains ctypes objects containing pointers which cannot be pickled. - mean_field_run.opt = None - dill.dump(mean_field_run, handle) + pickle.dump(mean_field_run, handle) - sys.exit(0) + sys.exit(0) # Section: Structure definition from pyscf import gto structure = gto.Mole() diff --git a/tests/calculations/test_base/test_parameters_mean_field.pyr b/tests/calculations/test_base/test_parameters_mean_field.pyr index 99b622d..fc5fe88 100644 --- a/tests/calculations/test_base/test_parameters_mean_field.pyr +++ b/tests/calculations/test_base/test_parameters_mean_field.pyr @@ -14,8 +14,8 @@ def main(): # Section: Results def write_results_and_exit(results): - import dill import json + import pickle import sys results['timings']['total'] = time.perf_counter() - time_start @@ -24,14 +24,10 @@ def main(): json.dump(results, handle) with open('model.pickle', 'wb') as handle: - # Need to unset the ``_chkfile`` attribute as it contains an open file handle which cannot be unpickled. - mean_field_run._chkfile = None - # Need to unset the ``opt`` attribute as it contains ctypes objects containing pointers which cannot be pickled. - mean_field_run.opt = None - dill.dump(mean_field_run, handle) + pickle.dump(mean_field_run, handle) - sys.exit(0) + sys.exit(0) # Section: Structure definition from pyscf import gto structure = gto.Mole() diff --git a/tests/calculations/test_base/test_parameters_mean_field_localize_orbitals.pyr b/tests/calculations/test_base/test_parameters_mean_field_localize_orbitals.pyr index 060da34..6d35fd6 100644 --- a/tests/calculations/test_base/test_parameters_mean_field_localize_orbitals.pyr +++ b/tests/calculations/test_base/test_parameters_mean_field_localize_orbitals.pyr @@ -14,8 +14,8 @@ def main(): # Section: Results def write_results_and_exit(results): - import dill import json + import pickle import sys results['timings']['total'] = time.perf_counter() - time_start @@ -24,14 +24,10 @@ def main(): json.dump(results, handle) with open('model.pickle', 'wb') as handle: - # Need to unset the ``_chkfile`` attribute as it contains an open file handle which cannot be unpickled. - mean_field_run._chkfile = None - # Need to unset the ``opt`` attribute as it contains ctypes objects containing pointers which cannot be pickled. - mean_field_run.opt = None - dill.dump(mean_field_run, handle) + pickle.dump(mean_field_run, handle) - sys.exit(0) + sys.exit(0) # Section: Structure definition from pyscf import gto structure = gto.Mole() diff --git a/tests/calculations/test_base/test_parameters_optimizer.pyr b/tests/calculations/test_base/test_parameters_optimizer.pyr index b8ea31c..4871c94 100644 --- a/tests/calculations/test_base/test_parameters_optimizer.pyr +++ b/tests/calculations/test_base/test_parameters_optimizer.pyr @@ -14,8 +14,8 @@ def main(): # Section: Results def write_results_and_exit(results): - import dill import json + import pickle import sys results['timings']['total'] = time.perf_counter() - time_start @@ -24,14 +24,10 @@ def main(): json.dump(results, handle) with open('model.pickle', 'wb') as handle: - # Need to unset the ``_chkfile`` attribute as it contains an open file handle which cannot be unpickled. - mean_field_run._chkfile = None - # Need to unset the ``opt`` attribute as it contains ctypes objects containing pointers which cannot be pickled. - mean_field_run.opt = None - dill.dump(mean_field_run, handle) + pickle.dump(mean_field_run, handle) - sys.exit(0) + sys.exit(0) # Section: Structure definition from pyscf import gto structure = gto.Mole() diff --git a/tests/calculations/test_base/test_parameters_pickle_model.pyr b/tests/calculations/test_base/test_parameters_pickle_model.pyr index 7f03730..cbc8558 100644 --- a/tests/calculations/test_base/test_parameters_pickle_model.pyr +++ b/tests/calculations/test_base/test_parameters_pickle_model.pyr @@ -14,8 +14,8 @@ def main(): # Section: Results def write_results_and_exit(results): - import dill import json + import pickle import sys results['timings']['total'] = time.perf_counter() - time_start @@ -25,7 +25,6 @@ def main(): sys.exit(0) - # Section: Structure definition from pyscf import gto structure = gto.Mole() diff --git a/tests/calculations/test_base/test_parameters_structure.pyr b/tests/calculations/test_base/test_parameters_structure.pyr index d1107c8..cd7eb84 100644 --- a/tests/calculations/test_base/test_parameters_structure.pyr +++ b/tests/calculations/test_base/test_parameters_structure.pyr @@ -14,8 +14,8 @@ def main(): # Section: Results def write_results_and_exit(results): - import dill import json + import pickle import sys results['timings']['total'] = time.perf_counter() - time_start @@ -24,14 +24,10 @@ def main(): json.dump(results, handle) with open('model.pickle', 'wb') as handle: - # Need to unset the ``_chkfile`` attribute as it contains an open file handle which cannot be unpickled. - mean_field_run._chkfile = None - # Need to unset the ``opt`` attribute as it contains ctypes objects containing pointers which cannot be pickled. - mean_field_run.opt = None - dill.dump(mean_field_run, handle) + pickle.dump(mean_field_run, handle) - sys.exit(0) + sys.exit(0) # Section: Structure definition from pyscf import gto structure = gto.Mole() diff --git a/tests/parsers/fixtures/base/model_valid/aiida.out b/tests/parsers/fixtures/base/model_valid/aiida.out index df54e87..b1d53b7 100644 --- a/tests/parsers/fixtures/base/model_valid/aiida.out +++ b/tests/parsers/fixtures/base/model_valid/aiida.out @@ -1,6 +1,6 @@ -converged SCF energy = -107.500603311882 +converged SCF energy = -107.882375574486 --------------- RHF gradients --------------- x y z -0 N -0.0000000000 -0.0000000000 -0.0139867876 -1 N 0.0000000000 0.0000000000 0.0139867876 +0 N -1.6236784581 0.0000000000 0.0000000000 +1 N 1.6236784581 -0.0000000000 -0.0000000000 ---------------------------------------------- diff --git a/tests/parsers/fixtures/base/model_valid/model.pickle b/tests/parsers/fixtures/base/model_valid/model.pickle index 8ac4c8d..d0dbaa1 100644 Binary files a/tests/parsers/fixtures/base/model_valid/model.pickle and b/tests/parsers/fixtures/base/model_valid/model.pickle differ diff --git a/tests/parsers/fixtures/base/model_valid/results.json b/tests/parsers/fixtures/base/model_valid/results.json index b510be0..990ab38 100644 --- a/tests/parsers/fixtures/base/model_valid/results.json +++ b/tests/parsers/fixtures/base/model_valid/results.json @@ -1 +1 @@ -{"mean_field": {"is_converged": true}} +{"timings": {"mean_field": 1.470824640000501, "total": 1.8824531299978844}, "mean_field": {"is_converged": true, "total_energy": -107.88237557448636, "forces": [[1.623678458070622, -3.4176827611007896e-17, -5.142126036397646e-19], [-1.6236784580706132, 3.4176827611003403e-17, 5.142126036398054e-19]], "molecular_orbitals": {"energies": [-15.810645505938895, -15.810577922503473, -1.0107325201009896, -0.9868371812252065, -0.361871486289105, -0.3358060054007162, -0.335806005400715, -0.15378168325421276, -0.15378168325421246, -0.11613780565825099, 0.19550741122997056, 0.2452470642031226, 0.4631816876555856, 0.463181687655586, 0.48652884967963145, 0.4865288496796321, 0.5409516491819545, 0.5454150477087832, 0.5454150477087847, 0.5495541829976925, 0.6054289055182531, 0.6054289055182537, 0.856025492082369, 0.9032311480142234, 0.9032311480142284, 0.9863706858235386, 0.9863706858235435, 1.1521564057499971, 1.1829750201996279, 1.3377593149108744, 2.569682822219137, 2.5696828222191392, 2.57094134411617, 2.5709413441161706, 2.591862059955579, 2.5918620599555795, 2.5978335614966297, 2.6254948183268487, 2.625494818326852, 2.6433822153829927], "labels": ["0 N 1s ", "0 N 2s ", "0 N 3s ", "0 N 4s ", "0 N 2px ", "0 N 2py ", "0 N 2pz ", "0 N 3px ", "0 N 3py ", "0 N 3pz ", "0 N 3dxy ", "0 N 3dyz ", "0 N 3dz^2 ", "0 N 3dxz ", "0 N 3dx2-y2", "0 N 4dxy ", "0 N 4dyz ", "0 N 4dz^2 ", "0 N 4dxz ", "0 N 4dx2-y2", "1 N 1s ", "1 N 2s ", "1 N 3s ", "1 N 4s ", "1 N 2px ", "1 N 2py ", "1 N 2pz ", "1 N 3px ", "1 N 3py ", "1 N 3pz ", "1 N 3dxy ", "1 N 3dyz ", "1 N 3dz^2 ", "1 N 3dxz ", "1 N 3dx2-y2", "1 N 4dxy ", "1 N 4dyz ", "1 N 4dz^2 ", "1 N 4dxz ", "1 N 4dx2-y2"], "occupations": [2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]}}} diff --git a/tests/test_integration/test_pyscf_base_geometry_optimization.csv b/tests/test_integration/test_pyscf_base_geometry_optimization.csv index a7ab8cf..0b07c86 100644 --- a/tests/test_integration/test_pyscf_base_geometry_optimization.csv +++ b/tests/test_integration/test_pyscf_base_geometry_optimization.csv @@ -1,10 +1,10 @@ ,cell,positions,forces,total_energy,mo_energies -0,0,-9.7050863540394009e-16,4.6954902279503998e-15,-2039.8853743663999,-550.86280025027997 -1,0,-1.3585628030588e-14,-4.0141380435427002e-14,,-34.375426862456003 -2,0,0.14564171835594,2.2269701395494002,,-16.629598134599 -3,0,-4.4202075207958997e-15,8.7828630648273999e-16,,-12.323304634735999 -4,0,0.75805955516659995,0.64803113397732004,,-10.637428057751 -5,0,-0.49023685916527998,-1.1134850697745999,,16.200273277781999 -6,0,4.322127333997e-15,-5.5737765344331997e-15,,19.796075801491 -7,0,-0.75805955516655998,-0.64803113397734002,, -8,0,-0.49023685916535997,-1.1134850697747001,, +0,0,9.2454334534319001e-16,5.1421984712133999e-16,-2039.8853743663999,-550.86280025027997 +1,0,-2.0981529224280001e-14,3.4075571836296002e-14,,-34.375426862456003 +2,0,0.14564171835584,2.226970139549,,-16.629598134599 +3,0,3.1504975930679e-15,-5.9334106870606003e-15,,-12.323304634735999 +4,0,0.75805955516654999,0.64803113397734002,,-10.637428057751 +5,0,-0.49023685916542997,-1.1134850697747001,,16.200273277781999 +6,0,-3.2418990053028002e-15,5.4191908399392998e-15,,19.796075801491 +7,0,-0.75805955516661006,-0.64803113397722001,, +8,0,-0.49023685916540999,-1.1134850697747001,, diff --git a/tests/test_integration/test_pyscf_base_mean_field.csv b/tests/test_integration/test_pyscf_base_mean_field.csv index a908ff4..810bc15 100644 --- a/tests/test_integration/test_pyscf_base_mean_field.csv +++ b/tests/test_integration/test_pyscf_base_mean_field.csv @@ -1,10 +1,10 @@ ,forces,total_energy,mo_energies -0,7.0032013139647002e-15,-2039.8853743663999,-550.86280025027997 -1,4.2460660193918997e-14,,-34.375426862456003 +0,9.4886849325137992e-15,-2039.8853743663999,-550.86280025027997 +1,1.6056552174170998e-14,,-34.375426862456003 2,2.2269701395492998,,-16.629598134599 -3,-1.4382859546291e-15,,-12.323304634735999 -4,0.64803113397729994,,-10.637428057751 +3,-8.1286555240245e-15,,-12.323304634735999 +4,0.64803113397737,,-10.637428057751 5,-1.1134850697747001,,16.200273277781999 -6,-5.5649153593354002e-15,,19.796075801491 -7,-0.64803113397731005,, +6,-1.3600294084894e-15,,19.796075801491 +7,-0.64803113397735002,, 8,-1.1134850697747001,,