### Argument Parser Setup for Protein Inclusion Tool Source: https://weria-pezeshkian.github.io/TS2CG_python_documentation/_modules/Tools/inclusion_updater.html This function sets up an argument parser for the protein inclusion tool using Python's `argparse` module. It defines command-line arguments for specifying directories, protein types, placement parameters, and output options. Use this to configure the tool's behavior via the command line. ```python [docs] def INU(args: List[str]) -> None: """Main entry point for protein inclusion tool""" parser = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter) parser.add_argument('-p', '--point-dir', type=Path, default="point", help='Path to membrane point directory (default: point/)' parser.add_argument('-t', '--type-id', type=int, required=False, help='Specify which protein type to add into the membrane ' parser.add_argument('-r', '--radius', type=float, required=True, help='Exclusion radius for protein placement (point to point distance)') parser.add_argument('-c', '--curvature', type=float, help='Target curvature for placement (optional)') parser.add_argument('-n', '--num-proteins', type=int, help='Number of proteins to place (optional)') parser.add_argument('-k', '--k-factor', type=float, default=1.0, help='Scaling factor for curvature preference strength (default: 1.0)') parser.add_argument('-l', '--leaflet', choices=['both', 'inner', 'outer'], default='both', help='Which membrane leaflet(s) to modify (default: both)') parser.add_argument('-o', '--output', type=Path, help='Output directory (defaults to input directory)') parser.add_argument('--seed', type=int, help='Random seed for reproducibility') args = parser.parse_args(args) logging.basicConfig(level=logging.INFO) if args.num_proteins is None and args.curvature is not None: logger.warning( "Curvature preference specified without number of proteins to place. " "This will attempt to place proteins at all valid points, which may not be desired. " "Consider specifying -N/--num-proteins to limit the number of proteins placed." ) # setup numpy random number generator global rng rng = np.random.default_rng(args.seed) try: ``` -------------------------------- ### Get All Protein Inclusions - Python Source: https://weria-pezeshkian.github.io/TS2CG_python_documentation/_modules/PointClass/point.html Retrieves all recorded protein inclusions as a list of dictionaries. ```python def get_all(self) -> List[dict]: """Get all points with protein inclusions.""" return [p for p in self.points] ``` -------------------------------- ### Get Points by Domain Source: https://weria-pezeshkian.github.io/TS2CG_python_documentation/PointClass.html Retrieves the coordinates of all points belonging to a specific domain ID. ```python membrane.get_points_by_domain(_domain_id = _domain_id_) ``` -------------------------------- ### Get Center Points for Domain Assignment Source: https://weria-pezeshkian.github.io/TS2CG_python_documentation/_modules/Tools/circular_domains.html Helper function to determine the center points for domain assignment, combining points from inclusions of a specific type and explicitly provided dummy points. ```python def _get_centers(membrane,Type,dummys): from_type=[inc["point_id"] for inc in membrane.inclusions.get_by_type(Type)] from_dummy=dummys.strip().split(",") to_set=list(set(from_type+from_dummy)) return list(filter(None,to_set)) ``` -------------------------------- ### Get All Excluded Points - Python Source: https://weria-pezeshkian.github.io/TS2CG_python_documentation/_modules/PointClass/point.html Retrieves a list of point IDs that are marked for exclusion. ```python def get_all(self) -> List[int]: """Get all excluded points.""" return [p['point_id'] for p in self.points] ``` -------------------------------- ### Get All Protein Inclusions Source: https://weria-pezeshkian.github.io/TS2CG_python_documentation/PointClass.html Retrieves a list of all points with protein inclusions, including their type and orientation. ```python inclusion.get_all() ``` -------------------------------- ### Get Nearby Points in Both Leaflets Source: https://weria-pezeshkian.github.io/TS2CG_python_documentation/inclusion_updater.html Finds points within a specified radius in both membrane leaflets from a given point. Useful for checking proximity constraints. ```python Tools.inclusion_updater.get_nearby_points_both_leaflets(_membrane : Point_, _leaflet : str_, _point_idx : int_, _radius : float_) → Dict[str, ndarray] ``` -------------------------------- ### Get Points by Domain ID Source: https://weria-pezeshkian.github.io/TS2CG_python_documentation/_modules/PointClass/point.html The `get_points_by_domain` method retrieves the coordinates of all points belonging to a specified domain ID. It uses a boolean mask to filter the coordinates. ```python def get_points_by_domain(self, domain_id: int) -> np.ndarray: """Get coordinates of all points in a specific domain.""" mask = self.domain_ids == domain_id return self.coordinates[mask] ``` -------------------------------- ### Main Entry Point for Domain Placer Tool Source: https://weria-pezeshkian.github.io/TS2CG_python_documentation/_modules/Tools/dir_visualizer.html Sets up the argument parser for the Domain Placer tool, including the main description. ```python import argparse def VIS(args) -> None: """Main entry point for Domain Placer tool""" parser = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter) ``` -------------------------------- ### Get All Excluded Points Source: https://weria-pezeshkian.github.io/TS2CG_python_documentation/PointClass.html Retrieves a list of all point IDs that have exclusions. ```python exclusion.get_all() ``` -------------------------------- ### VIS() - Main Entry Point Source: https://weria-pezeshkian.github.io/TS2CG_python_documentation/dir_visualizer.html The main entry point for the Domain Placer tool, which is part of the Directory Visualizer (VIS) implementation. ```APIDOC ## VIS() ### Description Main entry point for the Domain Placer tool. ### Method N/A (Function Call) ### Endpoint N/A ### Parameters #### Path Parameters N/A #### Query Parameters N/A #### Request Body N/A ### Request Example ```python Tools.dir_visualizer.VIS(_args_) ``` ### Response #### Success Response (200) None #### Response Example N/A ``` -------------------------------- ### Domain Placer Main Entry Point Source: https://weria-pezeshkian.github.io/TS2CG_python_documentation/domain_placer.html Main entry point for the Domain Placer tool. Accepts a list of string arguments. ```python Tools.domain_placer.DOP(_args : List[str]_) → None ``` -------------------------------- ### Point Class Initialization Source: https://weria-pezeshkian.github.io/TS2CG_python_documentation/PointClass.html Demonstrates how to initialize and use the Point class for membrane manipulation. ```APIDOC ## Point Class ### Description A class representing a membrane structure with inclusions and exclusions. Can be initialized from a point folder or built from scratch. ### Method `__init__` ### Endpoint `PointClass.point.Point(_path : str | Path_) ### Parameters #### Path Parameters - **_path** (str | Path_) - Required - The path to the point folder. ### Request Example ```python # Create bilayer membrane = Point.create_empty() membrane.add_membrane_points(coordinates, normals) ``` ### Response #### Success Response (200) - **membrane** (Point) - An instance of the Point class representing the membrane structure. #### Response Example ```json { "membrane": "" } ``` ``` -------------------------------- ### Domain Placer Main Entry Point Source: https://weria-pezeshkian.github.io/TS2CG_python_documentation/_modules/Tools/circular_domains.html The main function 'DAI' parses command-line arguments to configure and execute the domain placement process. It handles membrane initialization, center identification, circular domain application, and saving updated membrane data. Errors during execution are logged. ```python import argparse import logging from typing import List def DAI(args: List[str]) -> None: """Main entry point for Domain Placer tool""" parser = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter) parser.add_argument('-p','--point_dir',default="point/",help="Specify the path to the point folder") parser.add_argument('-r','--radius',default=1,type=float,help="The radius around a protein in which domains should be changed.") parser.add_argument('-t','--type',default=0,type=int,help="The protein type around which domains should be changed.") parser.add_argument('-d','--Domain',default=1,type=int,help="The domain number that should be set around the protein.") parser.add_argument('-l','--leaflet',default="both",help="Choose which membrane leaflet to alter. Default is both") parser.add_argument('-dummy','--dummy',default="",help="Create a dummy protein to place a circular domain around it. Excepts pointids like 3,7,22") parser.add_argument('-pd','--path_distance',default=False,type=bool,help="Slower execution, but needed for higher curvature membranes to assign the domain to only one membrane part") parser.add_argument('-pdP','--path_distance_percentile',default=100.0,type=float,help="Manipulates neighbors in path distance, tests have shown that 10 works well") args = parser.parse_args(args) logging.basicConfig(level=logging.INFO) try: membrane = Point(args.point_dir) centers=_get_centers(membrane, args.type,args.dummy) circular_domains(membrane=membrane,radius=args.radius,pointid=centers,domain=args.Domain, layer=args.leaflet,path_dist=args.path_distance,percent=args.path_distance_percentile) output_dir = args.point_dir membrane.save(output_dir) logger.info(f"Updated membrane domains in {output_dir}") except Exception as e: logger.error(f"Error: {e}") raise ``` -------------------------------- ### Create Backup Directory Source: https://weria-pezeshkian.github.io/TS2CG_python_documentation/_modules/PointClass/point.html Creates a backup of the current directory by appending hashes to the directory name until a unique name is found. Copies the entire directory tree to the backup location. ```python def _create_backup(self): """ Create a backup of the point folder. If #folder# exists, creates ##folder##, etc. """ def get_backup_path(n_hashes: int) -> Path: """Generate backup path with specified number of hashes.""" hashes = '#' * n_hashes return self.path.parent / f"{hashes}{self.path.name}{hashes}" # Start with one hash on each side n_hashes = 1 backup_path = get_backup_path(n_hashes) # Keep incrementing hashes until we find a non-existing path while backup_path.exists(): n_hashes += 1 backup_path = get_backup_path(n_hashes) shutil.copytree(self.path, backup_path) logger.info(f"Created backup at: {backup_path}") return backup_path ``` -------------------------------- ### Get Protein Inclusions by Type Source: https://weria-pezeshkian.github.io/TS2CG_python_documentation/PointClass.html Retrieves a list of all protein inclusions matching a specific type ID. ```python inclusion.get_by_type(_type_id = _type_id_) ``` -------------------------------- ### Get Protein Inclusions by Type - Python Source: https://weria-pezeshkian.github.io/TS2CG_python_documentation/_modules/PointClass/point.html Filters and returns protein inclusions matching a specific type ID. ```python def get_by_type(self, type_id: int) -> List[dict]: """Get all inclusions of a specific type.""" return [p for p in self.points if p['type_id'] == type_id] ``` -------------------------------- ### Point Class Initialization Source: https://weria-pezeshkian.github.io/TS2CG_python_documentation/_modules/PointClass/point.html Initializes the Point class from a specified folder path. ```APIDOC ## Point Class Initialization ### Description Initialize point class from a point folder. ### Method #### `__init__(self, path: Union[str, Path])` - **Description**: Initializes the Point class by loading data from the specified path. - **Parameters**: - **path** (Union[str, Path]) - Required - Path to the point folder. - **Raises**: - **FileNotFoundError**: If the specified point folder does not exist. ``` -------------------------------- ### Domain Placer Tool (DOP) Source: https://weria-pezeshkian.github.io/TS2CG_python_documentation/_modules/Tools/domain_placer.html The main entry point for the Domain Placer tool, handling argument parsing, initialization, domain assignment, and output generation. ```APIDOC ## DOP (Domain Placer Tool) ### Description Main entry point for the Domain Placer tool. It parses command-line arguments, sets up logging, initializes the membrane and lipid data, assigns domains based on curvature, and saves the updated membrane and input files. ### Method Command-line execution ### Endpoint N/A (Command-line tool) ### Parameters #### Command-line Arguments - **-p, --point-dir** (Path) - Optional - Path to membrane point directory (default: point/) - **-i, --input** (Path) - Optional - Path to lipid specification file (default: domain_input.txt) - **-l, --layer** (choices: 'both', 'inner', 'outer') - Optional - Which membrane layer(s) to modify (default: both) - **-k, --k-factor** (float) - Optional - Scaling factor for curvature preference strength (default: 1.0) - **-o, --output** (Path) - Optional - Output directory (defaults to input directory) - **-ni, --new-input** (Path) - Optional - Path for output input.str file (default: input_DOP.str) - **-oi, --old-input** (Path) - Optional - Path to existing input.str to preserve additional sections - **--seed** (int) - Optional - Random seed for reproducibility ### Request Example ```bash python -m domain_placer -i lipids.txt -p ./membrane_data --seed 42 ``` ### Response #### Success Response - **Output Files**: Updated membrane data saved to the specified output directory. - **Input File**: A new input.str file is created with domain assignments. - **Logs**: Informational messages about processing steps and results are printed to the console. #### Response Example ``` INFO:root:Created input file: input_DOP.str INFO:root:Updated membrane domains in ./membrane_data ``` ### Error Handling - **Exception Handling**: Catches and logs general exceptions during execution, printing an error message. ``` -------------------------------- ### Get Points Near Existing Proteins Source: https://weria-pezeshkian.github.io/TS2CG_python_documentation/inclusion_updater.html Identifies points that are too close to existing proteins in any leaflet. Helps in avoiding steric clashes. ```python Tools.inclusion_updater.get_points_near_existing_proteins(_membrane : Point_, _radius : float_) → Dict[str, Set[int]] ``` -------------------------------- ### Domain Placer (DOP) Main Entry Point Source: https://weria-pezeshkian.github.io/TS2CG_python_documentation/domain_placer.html The main entry point for the Domain Placer tool, which orchestrates the domain placement process. ```APIDOC ## Tools.domain_placer.DOP ### Description Main entry point for Domain Placer tool. ### Method N/A (CLI Tool) ### Endpoint N/A (CLI Tool) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example N/A ### Response #### Success Response (200) None #### Response Example None ``` -------------------------------- ### Parse Command-Line Arguments for Domain Placer Source: https://weria-pezeshkian.github.io/TS2CG_python_documentation/_modules/Tools/domain_placer.html Sets up argument parsing for the Domain Placer tool using argparse. Defines options for input directories, lipid specifications, layer selection, curvature factor, output paths, and random seed. ```python def DOP(args: List[str]) -> None: """Main entry point for Domain Placer tool""" parser = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter) parser.add_argument('-p', '--point-dir', type=Path, default="point", help='Path to membrane point directory (default: point/)' parser.add_argument('-i', '--input', type=Path, default="domain_input.txt", help='Path to lipid specification file (default: domain_input.txt)') parser.add_argument('-l', '--layer', choices=['both', 'inner', 'outer'], default='both', help='Which membrane layer(s) to modify (default: both)') parser.add_argument('-k', '--k-factor', type=float, default=1.0, help='Scaling factor for curvature preference strength (default: 1.0)') parser.add_argument('-o', '--output', type=Path, help='Output directory (defaults to input directory)') parser.add_argument('-ni', '--new-input', type=Path, default="input_DOP.str", help='Path for output input.str file (default: input.str)') parser.add_argument('-oi', '--old-input', type=Path, help='Path to existing input.str to preserve additional sections') parser.add_argument('--seed', type=int, help='Random seed for reproducibility') args = parser.parse_args(args) logging.basicConfig(level=logging.INFO) # setup numpy random number generator global rng rng = np.random.default_rng(args.seed) try: membrane = Point(args.point_dir) lipids = parse_lipid_file(args.input) assign_domains(membrane, lipids, args.layer, args.k_factor) write_input_str(lipids, args.new_input, args.old_input) logger.info(f"Created input file: {args.new_input}") output_dir = args.output or args.point_dir membrane.save(output_dir) logger.info(f"Updated membrane domains in {output_dir}") except Exception as e: logger.error(f"Error: {e}") raise ``` -------------------------------- ### Initialize Point Class - Python Source: https://weria-pezeshkian.github.io/TS2CG_python_documentation/_modules/PointClass/point.html Initializes the point class by loading data from a specified folder path. Raises FileNotFoundError if the path does not exist. ```python def __init__(self, path: Union[str, Path]): """ Initialize point class from a point folder. Args: path: Path to the point folder """ self.path = Path(path) if not self.path.exists(): raise FileNotFoundError(f"Point folder not found: {self.path}") self._load_data() ``` -------------------------------- ### Find Nodes within Radius Source: https://weria-pezeshkian.github.io/TS2CG_python_documentation/_modules/Tools/circular_domains.html Identifies nodes within a specified radius from a starting index using a distance matrix. This is a simpler approach than Dijkstra's for direct distance checks. ```python def _within_radius(distance_matrix,start_index,radius): reachable_nodes=[] for i,value in enumerate(distance_matrix[start_index]): if value <= radius: reachable_nodes.append(i) return reachable_nodes ``` -------------------------------- ### INU Main Entry Point Source: https://weria-pezeshkian.github.io/TS2CG_python_documentation/inclusion_updater.html The main function for the protein inclusion tool. It takes a list of strings as arguments. ```python Tools.inclusion_updater.INU(_args : List[str]_) → None ``` -------------------------------- ### Run Inclusion Updater (INU) CLI Source: https://weria-pezeshkian.github.io/TS2CG_python_documentation/inclusion_updater.html Command-line usage for the Inclusion Updater tool. Specify parameters like placement point, target curvature, and output file. ```bash TS2CG INU -p point -t 0 -r 2 -N 10 -c 0.1 -o point_new -l both ``` -------------------------------- ### DAI Main Entry Point Source: https://weria-pezeshkian.github.io/TS2CG_python_documentation/circular_domains.html The main entry point for the Domain Placer tool (DAI). ```APIDOC ## Tools.circular_domains.DAI ### Description Main entry point for Domain Placer tool. ### Method `Tools.circular_domains.DAI(_args : List[str]_) → None` ``` -------------------------------- ### Load and Wrap Membrane in Python Source: https://weria-pezeshkian.github.io/TS2CG_python_documentation/_modules/Tools/inclusion_updater.html Loads a membrane from a specified directory and wraps it within periodic boundary conditions. Ensure the 'Point' class and 'pbc_wrap' function are imported. ```python from membrane import Point from mdtools.structure.periodic import pbc_wrap # Load membrane membrane = Point(args.point_dir) # wrap membrane inside box membrane = pbc_wrap(membrane) ``` -------------------------------- ### Execute Data Visualization with Error Handling Source: https://weria-pezeshkian.github.io/TS2CG_python_documentation/_modules/Tools/dir_visualizer.html This Python code snippet demonstrates the execution of a data visualization process after parsing command-line arguments. It initializes a `Point` object, retrieves point IDs for coloring, and calls a `draw_folder` function. It includes a try-except block to catch and log any errors during execution, ensuring robust operation. ```python args = parser.parse_args(args) logging.basicConfig(level=logging.INFO) if args.save_figure=="": filename=None else: filename=args.save_figure try: membrane = Point(args.point_dir) pointids=_get_centers(membrane,args.color1,args.color2,args.color3) draw_folder(membrane=membrane,layer=args.leaflet,pointid=pointids,domain=args.Domain,save=filename,step=args.step,Proteins=args.Protein) except Exception as e: logger.error(f"Error: {e}") raise ``` -------------------------------- ### Create Empty Membrane with Point Class Source: https://weria-pezeshkian.github.io/TS2CG_python_documentation/PointClass.html Use `Point.create_empty()` to initialize an empty membrane structure. Then, use `add_membrane_points()` to add coordinates and normals. ```python membrane = Point.create_empty() membrane.add_membrane_points(coordinates, normals) ``` -------------------------------- ### Create Empty Point Instance Source: https://weria-pezeshkian.github.io/TS2CG_python_documentation/PointClass.html Creates an empty Point instance, with an option to specify box dimensions and whether it's a monolayer. ```python Point.create_empty(_box = _box_, _monolayer = _monolayer_) ``` -------------------------------- ### Point Class Methods Source: https://weria-pezeshkian.github.io/TS2CG_python_documentation/PointClass.html Provides methods for creating Point instances, adding lipids and membrane points, and saving membrane structures. ```APIDOC ## Point Class Methods ### Methods #### create_empty(_box_, monolayer=False) Create an empty Point instance. Args: box: Tuple of (x, y, z) box dimensions monolayer: If True, only creates outer membrane layer #### add_lipids(coordinates: ndarray, normals: ndarray, domain_ids: ndarray | None = None, areas: ndarray | None = None, bilayer_spacing: float = 4.0) Convenience method to add lipids to the membrane. Adds points to both leaflets offset by bilayer_spacing along the normal vectors. Args: coordinates: nx3 array of midplane lipid positions normals: nx3 array of normal vectors domain_ids: Array of domain IDs (optional) areas: Array of point areas (optional) bilayer_spacing: Distance between inner and outer leaflets in nm (default=4.0, only used for bilayers) #### add_membrane_points(coordinates: ndarray, normals: ndarray | None = None, domain_ids: ndarray | None = None, areas: ndarray | None = None, bilayer_spacing: float = 4.0) Add points to membrane layer(s) with proper bilayer spacing. Args: coordinates: Nx3 array of point coordinates (midplane coordinates) normals: Nx3 array of normal vectors (optional) domain_ids: Array of domain IDs (optional) areas: Array of point areas (optional) bilayer_spacing: Distance between leaflets in nm (default=4.0, only used for bilayers) #### save(_output_path: str | Path | None = None) Save membrane structure to files. Args: output_path: Path where to save the point folder. If None, saves to original location. Backup is only created if saving to the original location. #### update_domains(_domain_ids: ndarray | None = None) Update domain assignments for membrane layer(s). For bilayers, updates both leaflets. For monolayers, updates only the outer leaflet. Args: domain_ids: New domain assignments as numpy array ``` -------------------------------- ### Create Monolayer Membrane Source: https://weria-pezeshkian.github.io/TS2CG_python_documentation/PointClass.html Initializes an empty membrane structure designated as a monolayer. ```python monolayer = Point.create_empty(monolayer=True) monolayer.add_membrane_points(coordinates, normals) ``` -------------------------------- ### Place Proteins on Membrane in Python Source: https://weria-pezeshkian.github.io/TS2CG_python_documentation/_modules/Tools/inclusion_updater.html Places proteins onto the membrane based on provided arguments such as type ID, radius, number of proteins, target curvature, k-factor, and leaflet. Requires the 'place_proteins' function. ```python results = place_proteins( membrane=membrane, type_id=args.type_id, radius=args.radius, num_proteins=args.num_proteins, target_curvature=args.curvature, k_factor=args.k_factor, leaflet=args.leaflet ) ``` -------------------------------- ### Inclusion Updater (INU) CLI Usage Source: https://weria-pezeshkian.github.io/TS2CG_python_documentation/inclusion_updater.html Provides the command-line interface usage for the INU tool, including available options. ```APIDOC ## Inclusion Updater (INU) CLI Usage ### Description This section describes the command-line interface for the Inclusion Updater (INU) tool, used for updating protein inclusions in a membrane. It reads input definitions and places new inclusions. ### Usage ```bash TS2CG INU -p point -t 0 -r 2 -N 10 -c 0.1 -o point_new -l both ``` ### Options - `-p` (point): Specifies the input point file. - `-t` (0): Sets a parameter (value 0). - `-r` (2): Sets a parameter (value 2). - `-N` (10): Sets the number of proteins to 10. - `-c` (0.1): Sets a curvature parameter to 0.1. - `-o` (point_new): Specifies the output file name. - `-l` (both): Specifies the leaflet ('both', 'inner', or 'outer'). ``` -------------------------------- ### Tools.inclusion_updater.INU Source: https://weria-pezeshkian.github.io/TS2CG_python_documentation/inclusion_updater.html Main entry point for the protein inclusion tool. ```APIDOC ## Tools.inclusion_updater.INU ### Description Main entry point for the protein inclusion tool. This function orchestrates the process of updating protein inclusions within the membrane based on provided arguments. ### Method `INU(_args : List[str]_)` ### Parameters - `_args` (List[str]): A list of strings representing the command-line arguments passed to the tool. ``` -------------------------------- ### CLI Tool: inclusion_updater Source: https://weria-pezeshkian.github.io/TS2CG_python_documentation/_modules/Tools/inclusion_updater.html Command-line interface for placing protein inclusions in a membrane. ```APIDOC ## CLI Tool: inclusion_updater ### Description CLI tool to place protein inclusions in membrane. Reads input.str for protein definitions and places new inclusions in the membrane. ### Usage ```bash TS2CG INU -p point -t 0 -r 2 -N 10 -c 0.1 -o point_new -l both ``` ### Parameters - **-p point** (point): Specifies the starting point for placing inclusions. - **-t 0** (temperature): Temperature parameter. - **-r 2** (radius): Radius parameter. - **-N 10** (num_proteins): Number of proteins to place. - **-c 0.1** (curvature): Target curvature for placement. - **-o point_new** (output): Output file or identifier. - **-l both** (leaflet): Specifies which leaflet(s) to place proteins in ('inner', 'outer', or 'both'). ``` -------------------------------- ### Load Membrane File - Python Source: https://weria-pezeshkian.github.io/TS2CG_python_documentation/_modules/PointClass/point.html Loads data from a specified membrane definition file path. Returns a numpy array or None if the file cannot be parsed. ```python def _load_membrane_file(self, file_path: Path) -> Optional[np.ndarray]: """ Load membrane definition file. ``` -------------------------------- ### Create Empty Membrane Instance Source: https://weria-pezeshkian.github.io/TS2CG_python_documentation/_modules/PointClass/point.html Creates an empty membrane instance, optionally for a monolayer. ```APIDOC ## POST /create_empty ### Description Creates an empty membrane instance. ### Method POST ### Endpoint /create_empty ### Parameters #### Request Body - **box** (tuple) - Required - Tuple of (x, y, z) box dimensions. - **monolayer** (bool) - Optional - If True, only creates the outer membrane layer. Defaults to False. ### Request Example ```json { "box": [100, 100, 100], "monolayer": false } ``` ### Response #### Success Response (200) - **instance_id** (string) - Identifier for the newly created empty membrane instance. #### Response Example ```json { "instance_id": "mem-12345" } ``` ``` -------------------------------- ### Define Command-Line Arguments with argparse Source: https://weria-pezeshkian.github.io/TS2CG_python_documentation/_modules/Tools/dir_visualizer.html This snippet defines various command-line arguments for a Python script using the `argparse` module. It includes options for specifying directories, colors, plotting steps, highlighting points by ID or domain, showing proteins, and saving figures. Use this for scripts requiring flexible user input via the command line. ```python parser.add_argument('-p','--point_dir',default="point/",help="Specify the path to the point folder") parser.add_argument('-l','--leaflet',default="both",help="Choose which membrane leaflet to alter. Default is both") parser.add_argument('-S','--step',default=1,type=int,help="Only plot every nth point") parser.add_argument('-c1','--color1',default="",help="Highlights points in the visualization by point id. Excepts pointids like 3,7,22") parser.add_argument('-c2','--color2',default="",help="Highlights points in the visualization by point id. Excepts pointids like 3,7,22") parser.add_argument('-c3','--color3',default="",help="Highlights points in the visualization by point id. Excepts pointids like 3,7,22") parser.add_argument('-d','--Domain',default=False,action='store_true',help="Highlights points by domain, (up to 15 different domains are supported)") parser.add_argument('-P','--Protein',default=False,action='store_true',help="Shows proteins (up to 10 types are supported)") parser.add_argument('-s','--save_figure',default="",type=str,help="If path is outputfilename is provided, a figure will be saved") args = parser.parse_args(args) ``` -------------------------------- ### Tools.inclusion_updater.pbc_wrap Source: https://weria-pezeshkian.github.io/TS2CG_python_documentation/inclusion_updater.html Wraps membrane coordinates into the primary simulation box using periodic boundary conditions. ```APIDOC ## Tools.inclusion_updater.pbc_wrap ### Description Applies periodic boundary conditions to wrap the coordinates of the membrane points back into the primary simulation box. ### Method `pbc_wrap(_membrane_)` ### Parameters - `_membrane` (Point): The membrane object whose coordinates need to be wrapped. ``` -------------------------------- ### Create Empty Membrane Instance Source: https://weria-pezeshkian.github.io/TS2CG_python_documentation/_modules/PointClass/point.html Factory method to create an empty membrane instance. Initializes outer and inner membranes, and modification trackers. Sets box dimensions and monolayer status. ```python instance = cls.__new__(cls) instance.path = None instance.box = box instance.monolayer = monolayer # Initialize outer membrane (always present) instance.outer = cls.Membrane.create_empty() # Initialize inner membrane only for bilayers instance.inner = None if monolayer else cls.Membrane.create_empty() # Initialize modifications instance.inclusions = cls.Inclusion() instance.exclusions = cls.Exclusion() return instance ``` -------------------------------- ### Log Protein Placement Results in Python Source: https://weria-pezeshkian.github.io/TS2CG_python_documentation/_modules/Tools/inclusion_updater.html Logs the total number of proteins placed and the count per leaflet. Requires a logger object and the 'results' dictionary from the 'place_proteins' function. ```python total_placed = sum(results.values()) logger.info(f"Successfully placed {total_placed} of protein type {args.type_id}:") for leaflet, count in results.items(): if count > 0: logger.info(f" {leaflet} leaflet: {count} proteins") ``` -------------------------------- ### Load Membrane Data from File Source: https://weria-pezeshkian.github.io/TS2CG_python_documentation/_modules/PointClass/point.html Loads membrane data from a file, handling potential missing files and parsing box dimensions if it's an 'OuterBM.dat' file. Skips a specified number of rows based on the file type. ```python def load(self, file_path: Path): """ Load membrane data from a file. Returns None if file doesn't exist. """ if not file_path.exists(): logger.info(f"Membrane file {file_path.name} not found") return None try: # Read the first few lines to check for Box information with open(file_path) as f: first_lines = [next(f) for _ in range(4)] # Store box dimensions if this is OuterBM.dat if "OuterBM" in file_path.name: self.box = self._parse_box_line(first_lines[0]) skiprows = 4 else: skiprows = 3 return loadtxt_fix(file_path, skiprows).T except Exception as e: logger.warning(f"Error loading {file_path.name}: {e}") return None ``` -------------------------------- ### PBC Wrap Membrane Coordinates Source: https://weria-pezeshkian.github.io/TS2CG_python_documentation/inclusion_updater.html Wraps membrane coordinates into the primary box using Periodic Boundary Conditions (PBC). Ensures coordinates stay within simulation box limits. ```python Tools.inclusion_updater.pbc_wrap(_membrane_) ``` -------------------------------- ### Create Empty Membrane Layer Source: https://weria-pezeshkian.github.io/TS2CG_python_documentation/PointClass.html Creates an empty membrane layer object. ```python Membrane.create_empty() ``` -------------------------------- ### Protein Placement Logic in Membrane Source: https://weria-pezeshkian.github.io/TS2CG_python_documentation/_modules/Tools/inclusion_updater.html This function handles the iterative placement of proteins into a membrane model. It determines available points, calculates placement weights based on curvature, and updates point availability after each placement. Use this for simulating protein distribution with curvature-aware placement. ```python available_points = { 'outer': set(membrane.outer.ids) - excluded_by_existing['outer'] if leaflet in ['both', 'outer'] else set(), 'inner': (set(membrane.inner.ids) - excluded_by_existing['inner'] if not membrane.monolayer and leaflet in ['both', 'inner'] else set()) } total_proteins = num_proteins if num_proteins else len(membrane.outer.ids) results = {'outer': 0, 'inner': 0} logger.info(f"Attempting to place {total_proteins} of protein type {type_id}") logger.info(f"Available points for placement:") for l, points in available_points.items(): if points: logger.info(f" {l} leaflet: {len(points)} points") logger.info(f"Radius: {radius:.1f} nm" + (f", Target curvature: {target_curvature:.3f}" if target_curvature is not None else "")) placed = 0 while placed < total_proteins: # Determine valid leaflets (those with available points) valid_leaflets = [] if leaflet in ['both', 'outer'] and available_points['outer']: valid_leaflets.append('outer') if leaflet in ['both', 'inner'] and available_points['inner']: valid_leaflets.append('inner') if not valid_leaflets: logger.info("No more valid points available for placement") break # Randomly choose leaflet current_leaflet = rng.choice(valid_leaflets) membrane_layer = membrane.outer if current_leaflet == 'outer' else membrane.inner # Get valid indices for current leaflet valid_indices = np.array(list(available_points[current_leaflet])) # Calculate weights based on curvature preference curvatures = membrane_layer.mean_curvature[valid_indices] if current_leaflet == 'inner': curvatures = -curvatures # Flip curvature for inner leaflet weights = calculate_curvature_weights( curvatures, target_curvature, k_factor ) # Choose placement point chosen_idx = rng.choice(valid_indices, p=weights) # Add protein inclusion membrane.inclusions.add_protein( type_id=type_id, point_id=chosen_idx ) # Update available points accounting for exclusion radius in both leaflets nearby = get_nearby_points_both_leaflets( membrane, current_leaflet, chosen_idx, radius ) # Update available points for both leaflets for leaflet_name, excluded in nearby.items(): available_points[leaflet_name] -= set(excluded) placed += 1 results[current_leaflet] += 1 logger.debug(f"Placed protein at point {chosen_idx} in {current_leaflet} leaflet") return results ``` -------------------------------- ### Function: pbc_wrap Source: https://weria-pezeshkian.github.io/TS2CG_python_documentation/_modules/Tools/inclusion_updater.html Wraps membrane coordinates into the primary box using periodic boundary conditions. ```APIDOC ## Function: pbc_wrap ### Description Wrap membrane coordinates into the primary box. ### Method ```python def pbc_wrap(membrane: Point) -> Point ``` ### Parameters - **membrane** (Point): The membrane object with coordinates to wrap. ``` -------------------------------- ### Initialize Membrane Layer from Data Source: https://weria-pezeshkian.github.io/TS2CG_python_documentation/_modules/PointClass/point.html The `Membrane` class constructor initializes a membrane layer from raw numpy array data. It processes the data to extract properties like IDs, coordinates, normals, and curvatures. ```python def __init__(self, data: np.ndarray): """Initialize membrane layer from raw data.""" self._process_data(data) ``` -------------------------------- ### Lipid Specification File Format Source: https://weria-pezeshkian.github.io/TS2CG_python_documentation/_modules/Tools/domain_placer.html Describes the format for the domain_input.txt file used to specify lipid types, percentages, and properties. ```APIDOC ## Domain Input File Format ### Description This file defines the specifications for different lipid types within a membrane domain, including their distribution percentages and physical properties like curvature preference and density. ### File Format Each line represents a lipid specification, with columns separated by spaces. Lines starting with a semicolon (`;`) are treated as comments. ### Columns - **domain_id** (integer) - Identifier for the domain the lipid belongs to. - **name** (string) - The name or type of the lipid (e.g., POPC, POPG). - **percentage** (float) - The desired percentage of this lipid in the domain. The sum of percentages for all lipids must be close to 1.0. - **curvature** (float) - The preferred local curvature of the membrane for this lipid. - **density** (float) - The density of the lipid. ### Example ``` ; domain lipid percentage c0 density 0 POPC .5 0.179 0.64 2 POPG .5 0.629 0.64 ``` ``` -------------------------------- ### Load Membrane Data - Python Source: https://weria-pezeshkian.github.io/TS2CG_python_documentation/_modules/PointClass/point.html Loads membrane and modification data from files within the point folder. Handles outer and inner membranes, and inclusions/exclusions. ```python def _load_data(self): """Load all data from the point folder.""" try: # Try to load outer membrane (required) outer_data = self._load_membrane_file(self.path / "OuterBM.dat") if outer_data is None: raise FileNotFoundError("OuterBM.dat can not be parsed!") # Set monolayer flag based on presence of InnerBM.dat inner_data = self._load_membrane_file(self.path / "InnerBM.dat") self.monolayer = inner_data is None # Create membrane instances self.outer = self.Membrane(outer_data) self.inner = None if self.monolayer else self.Membrane(inner_data) # Load modifications data inc_data = self._load_modification_file("IncData.dat") exc_data = self._load_modification_file("ExcData.dat") self.inclusions = self.Inclusion(inc_data) self.exclusions = self.Exclusion(exc_data) except Exception as e: logger.error("Failed to load membrane data", exc_info=True) raise ``` -------------------------------- ### Point.Membrane Class Source: https://weria-pezeshkian.github.io/TS2CG_python_documentation/PointClass.html Manages a membrane layer with associated properties, including adding points, calculating curvature, and retrieving points by domain. ```APIDOC ## Point.Membrane Class ### Description Represents a membrane layer with associated properties. ### Methods #### add_points(coordinates: ndarray, normals: ndarray | None = None, domain_ids: ndarray | None = None, areas: ndarray | None = None) Add points to the membrane layer. Args: coordinates: Nx3 array of point coordinates normals: Nx3 array of normal vectors (optional) domain_ids: Array of domain IDs (optional) areas: Array of point areas (optional) #### create_empty() Create an empty membrane layer. #### gaussian_curvature() -> ndarray Calculate Gaussian curvature for all points. #### get_points_by_domain(domain_id: int) -> ndarray Get coordinates of all points in a specific domain. ### Properties #### mean_curvature -> ndarray Calculate mean curvature for all points. ``` -------------------------------- ### Write Input String File Source: https://weria-pezeshkian.github.io/TS2CG_python_documentation/domain_placer.html Writes the input.str file required for TS2CG, preserving comments and sections from an existing file, except for the [Lipids List]. ```APIDOC ## Tools.domain_placer.write_input_str ### Description Write input.str file for TS2CG, preserving all comments and sections except [Lipids List]. Maintains exact formatting of the original file. ### Method N/A (Function) ### Endpoint N/A (Function) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example N/A ### Response #### Success Response (200) None #### Response Example None ### Arguments - **lipids** (Sequence[LipidSpec]): A sequence of lipid specifications to write. - **output_file** (Path): The path to the output file (input.str). - **old_input** (Path | None, optional): Path to an existing input file to preserve formatting and comments (None by default). ``` -------------------------------- ### Error Handling in Python Script Source: https://weria-pezeshkian.github.io/TS2CG_python_documentation/_modules/Tools/inclusion_updater.html Catches and logs any exceptions that occur during the membrane and protein placement process. Re-raises the exception after logging. ```python except Exception as e: logger.error(f"Error: {e}") raise ``` -------------------------------- ### Write Simulation Input File Source: https://weria-pezeshkian.github.io/TS2CG_python_documentation/domain_placer.html Writes the 'input.str' file for TS2CG simulations. This function preserves comments and sections from an old input file, only modifying the '[Lipids List]' section. ```python Tools.domain_placer.write_input_str(_lipids : Sequence[LipidSpec]_, _output_file : Path_, _old_input : Path | None = None_) → None ``` -------------------------------- ### Calculate Curvature Weights Source: https://weria-pezeshkian.github.io/TS2CG_python_documentation/inclusion_updater.html Calculates Boltzmann weights based on curvature preference. Requires curvature data and a target curvature value. ```python Tools.inclusion_updater.calculate_curvature_weights(_curvatures : ndarray_, _target_curvature : float | None_, _k_factor : float_) → ndarray ``` -------------------------------- ### Wrap Membrane Coordinates Source: https://weria-pezeshkian.github.io/TS2CG_python_documentation/_modules/Tools/inclusion_updater.html Wraps the coordinates of membrane components (outer and inner leaflets) into the primary simulation box using the minimum image convention. This is essential for periodic boundary conditions. ```python def pbc_wrap(membrane): """Wrap membrane coordinates into the primary box""" box = membrane.box membrane.outer.coordinates = membrane.outer.coordinates - box * np.round(membrane.outer.coordinates / box) if not membrane.monolayer: membrane.inner.coordinates = membrane.inner.coordinates - box * np.round(membrane.inner.coordinates / box) return membrane ``` -------------------------------- ### Draw Lipid Domains in 3D Source: https://weria-pezeshkian.github.io/TS2CG_python_documentation/_modules/Tools/dir_visualizer.html Visualizes lipid distribution in 3D, differentiating between outer and inner monolayers, assigned domains, and specific points. Supports saving the plot or displaying it fullscreen. ```python from PointClass.point import Point import numpy as np import matplotlib.pyplot as plt def draw_folder(membrane: Point, pointid: list, domain: bool, layer: str = "both",save=None,step=1,Proteins=False) -> None: """Assign lipids to domains based on curvature preferences""" layers = [membrane.outer] if membrane.monolayer or layer.lower() == "outer": layers = [membrane.outer] layer_names=["Outer"] layer_colors=["#0072B2"] elif layer.lower() == "inner": layers = [membrane.inner] layer_names=["Inner"] layer_colors=["#E69F00"] else: layers = [membrane.outer, membrane.inner] layer_names=["Outer","Inner"] layer_colors=["#0072B2","#E69F00"] fig = plt.figure() ax = fig.add_subplot(111, projection='3d') colorblind_1=["#009E73","#CC79A7","#56B4E9"] colorblind_2=['#332288', '#88CCEE', '#DDCC77', '#117733', '#882255','#CC6677', '#999999', '#F0E442', '#44AA99', '#AA4499','#D55E00', '#999933', '#66CCEE', '#882299', '#DD4499'] second_run=False for i,layer in enumerate(layers): if not domain: x,y,z=layer.coordinates[:,0],layer.coordinates[:,1],layer.coordinates[:,2] ax.scatter(x[::step],y[::step],z[::step],s=50,label=layer_names[i],c=layer_colors[i]) else: for k in range(0,16): reduced=layer.get_points_by_domain(domain_id=k) if not reduced.size == 0: x,y,z=reduced[:,0],reduced[:,1],reduced[:,2] if not second_run: ax.scatter(x[::step],y[::step],z[::step],s=50,label=f"Domain {k}",c=colorblind_2[k]) else: ax.scatter(x[::step],y[::step],z[::step],s=50,c=colorblind_2[k]) labels=["c1","c2","c3"] for j,collection in enumerate(pointid): x=layer.coordinates[:,0][collection] y=layer.coordinates[:,1][collection] z=layer.coordinates[:,2][collection] if not x.size == 0: if not second_run: ax.scatter(x,y,z,s=500,c=colorblind_1[j]) else: ax.scatter(x,y,z,s=500,label=labels[j],c=colorblind_1[j]) second_run=True if Proteins: markers = ['D', 'd', 'p', '*', '+', 'x', 'h', 'H', '1', 'X'] for i in range(len(markers)): ids=[Protein["point_id"] for Protein in membrane.inclusions.get_by_type(i)] if not len(ids) == 0: x=layers[0].coordinates[:,0][ids] y=layers[0].coordinates[:,1][ids] z=layers[0].coordinates[:,2][ids] ax.scatter(x,y,z,s=1000,label=f"Protein Type {i}",c="black",marker=markers[i]) ax.legend( markerscale=1, # Make legend markers larger labelspacing=1.5, # Increase space between legend labels fontsize=16, # Increase font size of legend labels handlelength=2, # Make marker lines longer handleheight=2, # Increase the height of the markers borderpad=1.5 # Increase padding around the legend ) if save is not None: plt.savefig(save) else: make_fullscreen() plt.show() ``` -------------------------------- ### Place Proteins in Membrane Source: https://weria-pezeshkian.github.io/TS2CG_python_documentation/inclusion_updater.html Places proteins into the membrane according to specified constraints. Allows setting protein type, radius, number, and curvature preferences. ```python Tools.inclusion_updater.place_proteins(_membrane : Point_, _type_id : int_, _radius : float_, _num_proteins : int | None = None_, _target_curvature : float | None = None_, _k_factor : float = 1.0_, _leaflet : str = 'both'_) → Dict[str, int] ```