def __load(self): """ Explicitly load CASM project into memory. """ if self._ptr is None: self._api = API() if self.verbose: streamptr = self._api.stdout() else: streamptr = self._api.nullstream() if self.verbose: errstreamptr = self._api.stderr() else: errstreamptr = self._api.nullstream() self._ptr = self._api.primclex_new(self.path, streamptr, streamptr, errstreamptr)
class Project(object): """The Project class contains information about a CASM project Attributes ---------- path: str Path to project root directory name: str Project name settings: casm.project.ProjectSettings instance Contains project settings dir: casm.project.DirectoryStructure instance Provides file and directory locations within the project prim: casm.project.Prim instance Represents the primitive crystal structure composition_axes: casm.project.CompositionAxes Currently selected composition axes all_composition_axes: dict(str:casm.project.CompositionAxes) Dict containing name:CompositionAxes pairs, including both standard and custom composition axes casm_exe: str The casm CLI executable to use when necessary verbose: bool How much to print to stdout """ def __init__(self, path=None, casm_exe=None, verbose=True): """ Construct a CASM Project representation. Arguments ---------- path: str, optional, default=None Path to project root directory. Default=None uses project containing current working directory casm_exe: str, optional, default=None CASM executable to use for command line interface. Default uses $CASM if it exists in the environment, else "casm". verbose: bool, optional, default=True How much to print to stdout """ # will hold a ctypes.c_void_p when loading CASM project into memory self._ptr = None # will keep a casm.API instance self._api = None # set path to this CASM project if project_path(path) is None: if path is None: raise Exception("No CASM project found using " + os.getcwd()) else: raise Exception("No CASM project found using " + path) # set executable name if casm_exe is None: if "CASM" in os.environ: casm_exe = os.environ["CASM"] else: casm_exe = "casm" self.path = project_path(path) self.__refresh() self.casm_exe = casm_exe self.verbose = verbose self.all_composition_axes = {} if os.path.exists(self.dir.composition_axes()): with open(self.dir.composition_axes(), 'r') as f: data = json.load(f) if "standard_axes" in data: for key, val in data["standard_axes"].iteritems(): self.all_composition_axes[key] = CompositionAxes( key, val) if "custom_axes" in data: for key, val in data["custom_axes"].iteritems(): self.all_composition_axes[key] = CompositionAxes( key, val) self.composition_axes = self.all_composition_axes[ data["current_axes"]] def __del__(self): self.__unload() def __load(self): """ Explicitly load CASM project into memory. """ if self._ptr is None: self._api = API() if self.verbose: streamptr = self._api.stdout() else: streamptr = self._api.nullstream() if self.verbose: errstreamptr = self._api.stderr() else: errstreamptr = self._api.nullstream() self._ptr = self._api.primclex_new(self.path, streamptr, streamptr, errstreamptr) def __unload(self): """ Explicitly unload CASM project from memory. """ if self._ptr is not None: self._api.primclex_delete(self._ptr) self._ptr = None def __refresh(self): """ Reload self.settings and self.dir Use this after adding or modifying files in the CASM project but no special call to refresh PrimClex properties is required """ self.dir = DirectoryStructure(self.path) self.settings = ProjectSettings(self.path) self._prim = None @property def prim(self): if self._prim is None: self._prim = Prim(self) return self._prim @property def name(self): return self.settings.data['name'] def refresh(self, read_settings=False, read_composition=False, read_chem_ref=False, read_configs=False, clear_clex=False): """ Refresh PrimClex properties to reflect changes to CASM project files. """ if read_settings: self.dir = DirectoryStructure(self.path) self.settings = ProjectSettings(self.path) if self._ptr is not None: self._api.primclex_refresh(self.data(), read_settings, read_composition, read_chem_ref, read_configs, clear_clex) def data(self): """ Returns a 'ctypes.c_void_p' that points to a CASM project. (PrimClex) """ self.__load() return self._ptr def command(self, args): """ Execute a command via the c api. Args: args: A string containing the command to be executed. Ex: "select --set-on -o /abspath/to/my_selection" Returns: (stdout, stderr, returncode): The result of running the command via the command line iterface """ return self._command_via_capi(args) def _command_via_capi(self, args): """ Execute a command via the c api. Args: args: A string containing the command to be executed. Ex: "select --set-on -o /abspath/to/my_selection" Returns: (stdout, stderr, returncode): The result of running the command via the command line iterface """ # this also ensures self._api is not None data = self.data() # construct stringstream objects to capture stdout, debug, stderr ss = self._api.ostringstream_new() ss_debug = self._api.ostringstream_new() ss_err = self._api.ostringstream_new() res = self._api(args, self.data(), self.path, ss, ss_debug, ss_err) # copy strings and delete stringstreams stdout = self._api.ostringstream_to_str(ss) self._api.ostringstream_delete(ss) self._api.ostringstream_delete(ss_debug) stderr = self._api.ostringstream_to_str(ss_err) self._api.ostringstream_delete(ss_err) self.__refresh() return (stdout, stderr, res)
class Project(object): """The Project class contains information about a CASM project Attributes ---------- path: str Path to project root directory settings: casm.project.ProjectSettings instance Contains project settings dir: casm.project.DirectoryStructure instance Provides file and directory locations within the project casm_exe: str The casm CLI executable to use when necessary verbose: bool How much to print to stdout """ def __init__(self, path=None, casm_exe=None, verbose=True): """ Construct a CASM Project representation. Arguments ---------- path: str, optional, default=None Path to project root directory. Default=None uses project containing current working directory casm_exe: str, optional, default=None CASM executable to use for command line interface. Default uses $CASM if it exists in the environment, else "casm". verbose: bool, optional, default=True How much to print to stdout """ # will hold a ctypes.c_void_p when loading CASM project into memory self._ptr = None # will keep a casm.API instance self._api = None # set path to this CASM project if project_path(path) is None: if path is None: raise Exception("No CASM project found using " + os.getcwd()) else: raise Exception("No CASM project found using " + path) # set executable name if casm_exe is None: if "CASM" in os.environ: casm_exe = os.environ["CASM"] else: casm_exe = "casm" self.path = project_path(path) self.__refresh() self.casm_exe = casm_exe self.verbose = verbose def __del__(self): self.__unload() def __load(self): """ Explicitly load CASM project into memory. """ if self._ptr is None: self._api = API() if self.verbose: streamptr = self._api.stdout() else: streamptr = self._api.nullstream() if self.verbose: errstreamptr = self._api.stderr() else: errstreamptr = self._api.nullstream() self._ptr = self._api.primclex_new(self.path, streamptr, streamptr, errstreamptr) def __unload(self): """ Explicitly unload CASM project from memory. """ if self._ptr is not None: self._api.primclex_delete(self._ptr) self._ptr = None def __refresh(self): """ Reload self.settings and self.dir Use this after adding or modifying files in the CASM project but no special call to refresh PrimClex properties is required """ self.dir = DirectoryStructure(self.path) self.settings = ProjectSettings(self.path) def refresh( self, read_settings=False, read_composition=False, read_chem_ref=False, read_configs=False, clear_clex=False ): """ Refresh PrimClex properties to reflect changes to CASM project files. """ if read_settings: self.dir = DirectoryStructure(self.path) self.settings = ProjectSettings(self.path) if self._ptr is not None: self._api.primclex_refresh( self.data(), read_settings, read_composition, read_chem_ref, read_configs, clear_clex ) def data(self): """ Returns a 'ctypes.c_void_p' that points to a CASM project. (PrimClex) """ self.__load() return self._ptr def command(self, args): """ Execute a command via the c api. Args: args: A string containing the command to be executed. Ex: "select --set-on -o /abspath/to/my_selection" Returns: (stdout, stderr, returncode): The result of running the command via the command line iterface """ return self._command_via_capi(args) def _command_via_capi(self, args): """ Execute a command via the c api. Args: args: A string containing the command to be executed. Ex: "select --set-on -o /abspath/to/my_selection" Returns: (stdout, stderr, returncode): The result of running the command via the command line iterface """ # this also ensures self._api is not None data = self.data() # construct stringstream objects to capture stdout, debug, stderr ss = self._api.ostringstream_new() ss_debug = self._api.ostringstream_new() ss_err = self._api.ostringstream_new() res = self._api(args, self.data(), self.path, ss, ss_debug, ss_err) # copy strings and delete stringstreams stdout = self._api.ostringstream_to_str(ss) self._api.ostringstream_delete(ss) self._api.ostringstream_delete(ss_debug) stderr = self._api.ostringstream_to_str(ss_err) self._api.ostringstream_delete(ss_err) self.__refresh() return (stdout, stderr, res)