def getresults(self, filepath, frame, resolution=None, surface=False, center=False): """ Get cached results for the given parameters. **Parameters:** `filepath` : absolute path of the input file `frame` : the frame number `resolution` : resolution of the used discretization `surface` : query calculation results for surface-based cavities `center` : query calculation results for center-based cavities **Returns:** A :class:`core.data.Results` object if cached results exist, else `None` """ inputfile = File.open(filepath) # TODO: error handling resultfile = None results = None if isinstance(inputfile, core.file.ResultFile): resultfile = inputfile elif filepath in self.cache: resultfile = self.cache[filepath] if resultfile is not None: if resolution is None: resolutions = sorted(resultfile.info.resolutions())[::-1] resolution = 64 for res in resolutions: if resultfile.info[res].domains[frame] is not None: resolution = res break results = resultfile.getresults(frame, resolution) if results is None: if resolution is None: resolution = 64 results = data.Results(filepath, frame, resolution, inputfile.getatoms(frame), None, None, None) return results
def calculatedframes(self, filepath, resolution, surface=False, center=False): """ Query the cache if it contains results for the given parameters. **Parameters:** `filepath` : absolute path of the input file `resolution` : resolution of the used discretization `surface` : query calculation results for surface-based cavities `center` : query calculation results for center-based cavities **Returns:** A :class:`core.data.TimestampList` containing the dates of the calculation or `None`. """ info = None inputfile = File.open(filepath) # TODO: error handling if isinstance(inputfile, core.file.ResultFile): info = inputfile.info else: if filepath in self.cache: cf = self.cache[filepath] info = cf.info if info is not None: if surface: return info[resolution].surface_cavities elif center: return info[resolution].center_cavities else: return info[resolution].domains else: return data.TimestampList(inputfile.info.num_frames)
def calculate(self, calcsettings): """ Calculate (or load from the cache) all results for the given settings. **Parameters:** `calcsettings` : :class:`CalculationSettings` object **Returns:** A list of list of :class:`core.data.Results` objects. The outer list contains an entry for each entry in `calcsettings.filenames`; the inner list has a `Results` entry for each frame specified in `calcsettings.frames`. """ allresults = [] for filename, frames in calcsettings.datasets.iteritems(): filepath = core.file.get_abspath(filename) fileprefix = os.path.basename(filename).rsplit(".", 1)[0] if calcsettings.exportdir is not None: exportdir = core.file.get_abspath(calcsettings.exportdir) # replace asterisks with directories dirlist = os.path.dirname(filepath).split("/") while "*" in exportdir: i = exportdir.rindex("*") exportdir = os.path.join(exportdir[:i], dirlist.pop() + exportdir[i+1:]) if (calcsettings.exporthdf5 or calcsettings.exporttext) \ and not os.path.exists(exportdir): os.makedirs(exportdir) else: exportdir = os.path.dirname(filepath) if calcsettings.exporthdf5: efpath = os.path.join(exportdir, fileprefix + ".hdf5") efpath = core.file.get_abspath(efpath) # copy atoms into HDF5 file exportfile = core.file.HDF5File.fromInputFile(efpath, filepath) # use HDF5 file as input filepath = efpath fileresults = [] if frames[0] == -1: inputfile = File.open(filepath) frames = range(inputfile.info.num_frames) last_frame = False for frame in frames: # calculate single frame if frame is frames[-1]: last_frame = True frameresult = self.calculateframe( filepath, frame, calcsettings.resolution, calcsettings.cutoff_radii, domains=calcsettings.domains, surface=calcsettings.surface_cavities, center=calcsettings.center_cavities, gyration_tensor_parameters=calcsettings.gyration_tensor, recalculate=calcsettings.recalculate, last_frame=last_frame) # export to text file if calcsettings.exporttext: fmt = os.path.join(exportdir, fileprefix) + "-{property}-{frame:06d}.txt" if frameresult.atoms is not None: frameresult.atoms.totxt(fmt.format(property='{property}', frame=frame+1)) if frameresult.domains is not None: try: frameresult.domains.totxt(fmt.format(property='domain_{property}', frame=frame+1)) except ValueError as e: logger.warn(e.message) logger.warn('The export of domain information could not be finished.') if frameresult.surface_cavities is not None: frameresult.surface_cavities.totxt(fmt.format(property='surface_cavities_{property}', frame=frame+1)) if frameresult.center_cavities is not None: frameresult.center_cavities.totxt(fmt.format(property='center_cavities_{property}', frame=frame+1)) # TODO: try/except # gather results fileresults.append(frameresult) allresults.append(fileresults) return allresults
def calculateframe(self, filepath, frame, resolution, cutoff_radii=None, domains=False, surface=False, center=False, atoms=None, gyration_tensor_parameters=False, recalculate=False, last_frame=True): """ Get results for the given parameters. They are either loaded from the cache or calculated. **Parameters:** `filepath` : absolute path of the input file `frame` : the frame number `resolution` : resolution of the used discretization `domains` : calculate cavitiy domains `cutoff_radii` : dict that maps element symbols to cutoff radii `surface` : calculate surface-based cavities `center` : calculate center-based cavities `gyration_tensor_parameters` : gyration tensor parameters will be calculated for cavities (they are always calculated for cavity domains) `recalculate` : results will be calculated even if cached results exists **Returns:** A :class:`core.data.Results` object. """ # always recalculate if gyration tensor parameters shall be computed for center or surface based cavities recalculate = recalculate or (gyration_tensor_parameters and (center or surface)) message.progress(0) inputfile = File.open(filepath) # TODO: error handling if isinstance(inputfile, core.file.ResultFile): resultfile = inputfile else: resultfile = self.cache[filepath] try: results = resultfile.getresults(frame, resolution) except Exception as e: logger.debug("error in resultfile.getresults: {}".format(e)) results = None if atoms is None: atoms = inputfile.getatoms(frame) atoms.radii = cutoff_radii volume = atoms.volume if results is None: results = data.Results(filepath, frame, resolution, atoms, None, None, None) if recalculate: results.domains = None results.surface_cavities = None results.center_cavities = None if not ((domains and results.domains is None) or (surface and results.surface_cavities is None) or (center and results.center_cavities is None)): message.print_message("Reusing results") else: cachepath = os.path.join(self.cachedir, 'discretization_cache.hdf5') discretization_cache = DiscretizationCache(cachepath) discretization = discretization_cache.get_discretization(volume, resolution) atom_discretization = AtomDiscretization(atoms, discretization) message.progress(10) if (domains and results.domains is None) \ or (surface and results.surface_cavities is None): # CavityCalculation depends on DomainCalculation message.print_message("Calculating domains") domain_calculation = DomainCalculation(discretization, atom_discretization) if domain_calculation.critical_domains: logger.warn('Found {:d} critical domains in file {}, frame {:d}. Domain indices: {}'.format( len(domain_calculation.critical_domains), os.path.basename(filepath), frame, domain_calculation.critical_domains )) message.log('Found {:d} critical domains in file {}, frame {:d}'.format( len(domain_calculation.critical_domains), os.path.basename(filepath), frame + 1, )) if results.domains is None: results.domains = data.Domains(domain_calculation) message.progress(40) if surface and results.surface_cavities is None: message.print_message("Calculating surface-based cavities") cavity_calculation = CavityCalculation(domain_calculation, use_surface_points=True, gyration_tensor_parameters=gyration_tensor_parameters) results.surface_cavities = data.Cavities(cavity_calculation) message.progress(70) if center and results.center_cavities is None: message.print_message("Calculating center-based cavities") domain_calculation = FakeDomainCalculation(discretization, atom_discretization, results) cavity_calculation = CavityCalculation(domain_calculation, use_surface_points=False, gyration_tensor_parameters=gyration_tensor_parameters) results.center_cavities = data.Cavities(cavity_calculation) resultfile.addresults(results, overwrite=recalculate) message.progress(100) message.print_message("Calculation finished") if last_frame: message.finish() return results
def calculate(self, calcsettings): """ Calculate (or load from the cache) all results for the given settings. **Parameters:** `calcsettings` : :class:`CalculationSettings` object **Returns:** A list of list of :class:`core.data.Results` objects. The outer list contains an entry for each entry in `calcsettings.filenames`; the inner list has a `Results` entry for each frame specified in `calcsettings.frames`. """ allresults = [] for filename, frames in calcsettings.datasets.iteritems(): filepath = core.file.get_abspath(filename) fileprefix = os.path.basename(filename).rsplit(".", 1)[0] if calcsettings.exportdir is not None: exportdir = core.file.get_abspath(calcsettings.exportdir) # replace asterisks with directories dirlist = os.path.dirname(filepath).split("/") while "*" in exportdir: i = exportdir.rindex("*") exportdir = os.path.join(exportdir[:i], dirlist.pop() + exportdir[i + 1:]) if (calcsettings.exporthdf5 or calcsettings.exporttext) \ and not os.path.exists(exportdir): os.makedirs(exportdir) else: exportdir = os.path.dirname(filepath) if calcsettings.exporthdf5: efpath = os.path.join(exportdir, fileprefix + ".hdf5") efpath = core.file.get_abspath(efpath) # copy atoms into HDF5 file exportfile = core.file.HDF5File.fromInputFile(efpath, filepath) # use HDF5 file as input filepath = efpath fileresults = [] if frames[0] == -1: inputfile = File.open(filepath) frames = range(inputfile.info.num_frames) last_frame = False for frame in frames: # calculate single frame if frame is frames[-1]: last_frame = True frameresult = self.calculateframe( filepath, frame, calcsettings.resolution, calcsettings.cutoff_radii, domains=calcsettings.domains, surface=calcsettings.surface_cavities, center=calcsettings.center_cavities, gyration_tensor_parameters=calcsettings.gyration_tensor, recalculate=calcsettings.recalculate, last_frame=last_frame) # export to text file if calcsettings.exporttext: fmt = os.path.join( exportdir, fileprefix) + "-{property}-{frame:06d}.txt" if frameresult.atoms is not None: frameresult.atoms.totxt( fmt.format(property='{property}', frame=frame + 1)) if frameresult.domains is not None: try: frameresult.domains.totxt( fmt.format(property='domain_{property}', frame=frame + 1)) except ValueError as e: logger.warn(e.message) logger.warn( 'The export of domain information could not be finished.' ) if frameresult.surface_cavities is not None: frameresult.surface_cavities.totxt( fmt.format(property='surface_cavities_{property}', frame=frame + 1)) if frameresult.center_cavities is not None: frameresult.center_cavities.totxt( fmt.format(property='center_cavities_{property}', frame=frame + 1)) # TODO: try/except # gather results fileresults.append(frameresult) allresults.append(fileresults) return allresults
def calculateframe(self, filepath, frame, resolution, cutoff_radii=None, domains=False, surface=False, center=False, atoms=None, gyration_tensor_parameters=False, recalculate=False, last_frame=True): """ Get results for the given parameters. They are either loaded from the cache or calculated. **Parameters:** `filepath` : absolute path of the input file `frame` : the frame number `resolution` : resolution of the used discretization `domains` : calculate cavitiy domains `cutoff_radii` : dict that maps element symbols to cutoff radii `surface` : calculate surface-based cavities `center` : calculate center-based cavities `gyration_tensor_parameters` : gyration tensor parameters will be calculated for cavities (they are always calculated for cavity domains) `recalculate` : results will be calculated even if cached results exists **Returns:** A :class:`core.data.Results` object. """ # always recalculate if gyration tensor parameters shall be computed for center or surface based cavities recalculate = recalculate or (gyration_tensor_parameters and (center or surface)) message.progress(0) inputfile = File.open(filepath) # TODO: error handling if isinstance(inputfile, core.file.ResultFile): resultfile = inputfile else: resultfile = self.cache[filepath] try: results = resultfile.getresults(frame, resolution) except Exception as e: logger.debug("error in resultfile.getresults: {}".format(e)) results = None if atoms is None: atoms = inputfile.getatoms(frame) atoms.radii = cutoff_radii volume = atoms.volume if results is None: results = data.Results(filepath, frame, resolution, atoms, None, None, None) if recalculate: results.domains = None results.surface_cavities = None results.center_cavities = None if not ((domains and results.domains is None) or (surface and results.surface_cavities is None) or (center and results.center_cavities is None)): message.print_message("Reusing results") else: cachepath = os.path.join(self.cachedir, 'discretization_cache.hdf5') discretization_cache = DiscretizationCache(cachepath) with DiscretizationCache(cachepath) as discretization_cache: discretization = discretization_cache.get_discretization( volume, resolution) atom_discretization = AtomDiscretization(atoms, discretization) message.progress(10) if (domains and results.domains is None) \ or (surface and results.surface_cavities is None): # CavityCalculation depends on DomainCalculation message.print_message("Calculating domains") domain_calculation = DomainCalculation(discretization, atom_discretization) if domain_calculation.critical_domains: logger.warn( 'Found {:d} critical domains in file {}, frame {:d}. Domain indices: {}' .format(len(domain_calculation.critical_domains), os.path.basename(filepath), frame, domain_calculation.critical_domains)) message.log( 'Found {:d} critical domains in file {}, frame {:d}'. format( len(domain_calculation.critical_domains), os.path.basename(filepath), frame + 1, )) if results.domains is None: results.domains = data.Domains(domain_calculation) message.progress(40) if surface and results.surface_cavities is None: message.print_message("Calculating surface-based cavities") cavity_calculation = CavityCalculation( domain_calculation, use_surface_points=True, gyration_tensor_parameters=gyration_tensor_parameters) results.surface_cavities = data.Cavities(cavity_calculation) message.progress(70) if center and results.center_cavities is None: message.print_message("Calculating center-based cavities") domain_calculation = FakeDomainCalculation( discretization, atom_discretization, results) cavity_calculation = CavityCalculation( domain_calculation, use_surface_points=False, gyration_tensor_parameters=gyration_tensor_parameters) results.center_cavities = data.Cavities(cavity_calculation) resultfile.addresults(results, overwrite=recalculate) message.progress(100) message.print_message("Calculation finished") if last_frame: message.finish() return results