|
3 | 3 | import collections |
4 | 4 | import copy |
5 | 5 | import functools |
| 6 | +import json |
6 | 7 | from enum import Enum |
7 | 8 | from pathlib import Path |
8 | 9 | from textwrap import indent |
@@ -834,6 +835,75 @@ def classlist_script(name, classlist): |
834 | 835 | + "\n)" |
835 | 836 | ) |
836 | 837 |
|
| 838 | + def save(self, path: Union[str, Path], filename: str = "project"): |
| 839 | + """Save a project to a JSON file. |
| 840 | +
|
| 841 | + Parameters |
| 842 | + ---------- |
| 843 | + path : str or Path |
| 844 | + The path in which the project will be written. |
| 845 | + filename : str |
| 846 | + The name of the generated project file. |
| 847 | +
|
| 848 | + """ |
| 849 | + json_dict = {} |
| 850 | + for field in self.model_fields: |
| 851 | + attr = getattr(self, field) |
| 852 | + |
| 853 | + if field == "data": |
| 854 | + |
| 855 | + def make_data_dict(item): |
| 856 | + return { |
| 857 | + "name": item.name, |
| 858 | + "data": item.data.tolist(), |
| 859 | + "data_range": item.data_range, |
| 860 | + "simulation_range": item.simulation_range, |
| 861 | + } |
| 862 | + |
| 863 | + json_dict["data"] = [make_data_dict(data) for data in attr] |
| 864 | + |
| 865 | + elif field == "custom_files": |
| 866 | + |
| 867 | + def make_custom_file_dict(item): |
| 868 | + return { |
| 869 | + "name": item.name, |
| 870 | + "filename": item.filename, |
| 871 | + "language": item.language, |
| 872 | + "path": str(item.path), |
| 873 | + } |
| 874 | + |
| 875 | + json_dict["custom_files"] = [make_custom_file_dict(file) for file in attr] |
| 876 | + |
| 877 | + elif isinstance(attr, ClassList): |
| 878 | + json_dict[field] = [item.model_dump() for item in attr] |
| 879 | + else: |
| 880 | + json_dict[field] = attr |
| 881 | + |
| 882 | + file = Path(path, f"{filename.removesuffix('.json')}.json") |
| 883 | + file.write_text(json.dumps(json_dict)) |
| 884 | + |
| 885 | + @classmethod |
| 886 | + def load(cls, path: Union[str, Path]) -> "Project": |
| 887 | + """Load a project from file. |
| 888 | +
|
| 889 | + Parameters |
| 890 | + ---------- |
| 891 | + path : str or Path |
| 892 | + The path to the project file. |
| 893 | +
|
| 894 | + """ |
| 895 | + input = Path(path).read_text() |
| 896 | + model_dict = json.loads(input) |
| 897 | + for i in range(0, len(model_dict["data"])): |
| 898 | + if model_dict["data"][i]["name"] == "Simulation": |
| 899 | + model_dict["data"][i]["data"] = np.empty([0, 3]) |
| 900 | + del model_dict["data"][i]["data_range"] |
| 901 | + else: |
| 902 | + data = model_dict["data"][i]["data"] |
| 903 | + model_dict["data"][i]["data"] = np.array(data) |
| 904 | + |
| 905 | + return cls.model_validate(model_dict) |
| 906 | + |
837 | 907 | def _classlist_wrapper(self, class_list: ClassList, func: Callable): |
838 | 908 | """Defines the function used to wrap around ClassList routines to force revalidation. |
839 | 909 |
|
|
0 commit comments