def ammo_file(self): """ Gets Ammunition Details from the Project tarfile and convert to BytesIO """ return BytesIO( get_file_from_archive(self.filename.value, filename_only( self.ammo_details.value)).read())
def tree_item(self): """ Returns a tuple containing the value of the property and the icon to use in a wx.TreeCtrl :return: :rtype: """ if self.name.endswith("method"): return filename_only(self.value), 3 elif self.name == "Ammunition Details": return "Ammunition Details", 7
def store_new(self, filename=None): """ Save the Project to a file :param filename: The filename to save the Project as :type filename: str :return: The filename the Project was saved as :rtype: str """ if filename: self.filename.value = filename self.date_modified.value = datetime.datetime.now().timestamp() with tarfile.open(filename, mode="w") as project_file: # Sort the experiments self._experiments.sort(key=lambda expr: expr.name) # Add the Experiment files for experiment in self._experiments: project_file.add(experiment["filename"], filename_only(experiment["filename"])) # Add the info file to the archive info_json = json.dumps(self.project_info_dict, indent=4).encode("utf-8") tarinfo = tarfile.TarInfo('info.json') tarinfo.size = len(info_json) project_file.addfile(tarinfo=tarinfo, fileobj=BytesIO(info_json)) # Add the Method and Ammo Details to the archive project_file.add(self.method.value, filename_only(self.method.value)) project_file.add(self.ammo_details.value, filename_only(self.ammo_details.value)) return self.filename.value
def filename(self): """ Only for properties of type `dir`. Returns just the filename of the value of the property :return: :rtype: str """ if self.type == dir: return filename_only(self.value) else: return NotImplemented
def _load_experiments(self): """ Load the experiments from file """ for filename in self.experiment_file_list: # self._experiment_objects.append(Experiment.load(filename)) # Get Experiment tarfile from the Project tarfile and convert to BytesIO expr_tarfile = BytesIO( get_file_from_archive(str(self.filename.value), filename_only(filename)).read()) # Load the Experiment expr = Experiment.Experiment.load(expr_tarfile) # Add the Experiment to the list of Experiment objects self._experiment_objects.append(expr)
def store(self, filename=None): """ Save the Project to a file :param filename: :type filename: :return: :rtype: """ if filename: self.filename.value = filename self.date_modified.value = time_now() if any((self.expr is None, self.tic is None, self.peak_list is None, self.intensity_matrix is None, self.gcms_data is None)): raise ValueError("Must call 'Experiment.run()' before 'store()'") # Write experiment, tic and peak list to temporary directory with tempfile.TemporaryDirectory() as tmp: self.gcms_data.dump(os.path.join(tmp, "gcms_data.dat")) self.intensity_matrix.dump( os.path.join(tmp, "intensity_matrix.dat")) self.tic.write(os.path.join(tmp, "tic.dat"), formatting=False) store_peaks(self.peak_list, os.path.join(tmp, "peaks.dat"), 3) store_expr(os.path.join(tmp, "experiment.expr"), self.expr) with tarfile.open(self.filename.value, mode="w") as experiment_file: # # Add the method files # for method in self._method_files: # experiment_file.add(method) experiment_data = { "name": str(self.name), "user": str(self.user), "device": str(self.device), "date_created": float(self.date_created), "date_modified": float(self.date_modified), "description": str(self.description), "version": "1.0.0", "method": str(self.method), "original_filename": str(self.original_filename), "original_filetype": int(self.original_filetype), "identification_performed": self.identification_performed, "ident_audit_record": None, } if self.identification_performed: experiment_data["ident_audit_record"] = dict( self.ident_audit_record) store_peaks(self.ident_peaks, os.path.join(tmp, "ident_peaks.dat"), 3) experiment_file.add(os.path.join(tmp, "ident_peaks.dat"), arcname="ident_peaks.dat") # Add the info file to the archive info_json = json.dumps(experiment_data, indent=4).encode("utf-8") tarinfo = tarfile.TarInfo('info.json') tarinfo.size = len(info_json) experiment_file.addfile(tarinfo=tarinfo, fileobj=BytesIO(info_json)) # Add the method to the archive experiment_file.add(self.method.value, arcname=filename_only(self.method.value)) # Add the experiment, tic, intrnsity_matrix, gcms_data and peak list experiment_file.add(os.path.join(tmp, "experiment.expr"), arcname="experiment.expr") experiment_file.add(os.path.join(tmp, "tic.dat"), arcname="tic.dat") experiment_file.add(os.path.join(tmp, "peaks.dat"), arcname="peaks.dat") experiment_file.add(os.path.join(tmp, "gcms_data.dat"), arcname="gcms_data.dat") experiment_file.add(os.path.join(tmp, "intensity_matrix.dat"), arcname="intensity_matrix.dat") return self.filename
def store(self, filename=None, remove_alignment=False, resave_experiments=False, remove_consolidate=False): """ Save the project :param filename: The filename to save the Project as :type filename: str, optional :param remove_alignment: Whether to remove the alignment data from the file. Default False :type remove_alignment: bool, optional :param resave_experiments: Whether the experiments should be resaved. Default False :type resave_experiments: bool, optional :param remove_consolidate: Whether to remove the Consolidate data. Default False :type remove_consolidate: bool, optional :return: The filename of the saved project :rtype: str """ # 1. Extract the project tarfile to a temporary directory # 2. Move any files that were changed to a timestamped folder # 3. In that folder, create a file called "user" containing the username of the user who made the change # 4. In the same folder, create a file called "device" containing the hostname of the device # 5. Save the changed files to the temporary directory # 6. Tar the contents of the temporary directory over the project file # 7. Get rid of the temporary directory if filename: self.filename.value = filename if remove_alignment: print(f"Removing Alignment data from {self.filename}") self.alignment_performed = False elif remove_consolidate: print(f"Removing Consolidate data from {self.filename}") self.consolidate_performed = False else: print(f"Saving changes as {self.filename}") # Set date modified value self.date_modified.value = datetime.datetime.now().timestamp() # One of the files has been changed with tempfile.TemporaryDirectory() as tempdir: tarfile.open(self.filename.value, mode="r").extractall(tempdir) tempdir_p = pathlib.Path(tempdir) if not (tempdir_p / "changes").is_dir(): (tempdir_p / "changes").mkdir() timestamp_dir = tempdir_p / "changes" / datetime.datetime.fromtimestamp( self.date_modified.value).strftime("%Y%m%d %H%M%S") timestamp_dir.mkdir() # The user and device who made the changes user, device = watchdog.user_info() (timestamp_dir / "user").write_text(user) (timestamp_dir / "device").write_text(device) if resave_experiments: # Move old experiment objects to timestamp_dir for expr_obj, expr_filename in zip(self.experiment_objects, self.experiment_file_list): expr_filename = filename_only(expr_filename) shutil.move(tempdir_p / expr_filename, timestamp_dir / expr_filename) expr_obj.store(tempdir_p / expr_filename) if self.method_unsaved: shutil.copy2(tempdir_p / filename_only(self.method.value), timestamp_dir / filename_only(self.method.value)) print("Saving new Method") self.method_data.save_method(tempdir_p / filename_only(self.method.value)) # TODO: Add the new method file and change copy2 above to move print(self.ammo_details_unsaved) if self.ammo_details_unsaved: shutil.move( tempdir_p / filename_only(self.ammo_details.value), timestamp_dir / filename_only(self.ammo_details.value)) self.ammo_data.store(tempdir_p / filename_only(self.ammo_details.value)) shutil.move(tempdir_p / "info.json", timestamp_dir / "info.json") if remove_alignment: # Move the alignment files to the timestamp_dir for fname in { "alignment_area.csv", "alignment_rt.csv", "alignment_ms.json", "alignment_rt.json", "alignment_area.json" }: try: shutil.move(tempdir_p / fname, timestamp_dir / fname) except FileNotFoundError: pass elif remove_consolidate: # Move the consolidate files to the timestamp_dir try: shutil.move(tempdir_p / "consolidate.json", timestamp_dir / "consolidate.json") except FileNotFoundError: pass # Add the info file to the archive info_json = json.dumps(self.project_info_dict, indent=4) (tempdir_p / "info.json").write_text(info_json) if self.consolidate_performed: # Add the consolidate data file to the archive # for peak in self.consolidated_peaks: # for hit in peak.hits: # print(hit.reference_data) # print(hit.reference_data.mass_spec) # print(hit.reference_data.__dict__(recursive=True)["mass_spec"]) # print("^^^^^") # TODO: flag to show consolidated_peaks has been changed consolidate_json = json.dumps(self.consolidated_peaks, indent=4, cls=ConsolidateEncoder) (tempdir_p / "consolidate.json").write_text(consolidate_json) # Tar the contents of the temporary directory over the project file with tarfile.open(self.filename.value, mode="w") as project_file: project_file.add(tempdir_p, arcname="") # Mark as saved self.mark_all_saved() return self.filename.value