### Execute Example Workflow Source: https://github.com/mosaics-nih/mosaics/blob/main/_autodocs/configuration.md Run an example workflow for membrane thickness calculation using MPI. This command executes the compiled program with specific input files. ```bash cd examples/membrane_thickness mpirun -np 1 ../../build/membrane_thickness \ -f trajectory.gro \ -r reference.gro \ -param params.txt \ -o test_output.txt ``` -------------------------------- ### Verify MPI Installation Source: https://github.com/mosaics-nih/mosaics/blob/main/_autodocs/configuration.md Check your MPI installation by verifying the mpirun command and its version to resolve MPI initialization runtime errors. ```bash # Verify MPI installation which mpirun mpirun --version ``` -------------------------------- ### Param::get_param Usage Example Source: https://github.com/mosaics-nih/mosaics/blob/main/_autodocs/api-reference/index-param.md Demonstrates how to instantiate and use the Param class's get_param method. This example shows the expected file structure for primary and secondary parameter files and how to call the method with appropriate arguments. ```cpp // Main parameter file: POPE /path/to/pope_atoms.txt POPC /path/to/popc_atoms.txt // Secondary file (pope_atoms.txt): PO4, C4A PO4, C4B // Usage: Param param; param.get_param("lipids.txt", 2, 1, 2); // param.num_lip_t = 2 // param.sec_size_z() = 2 ``` -------------------------------- ### Install MOSAICS using install_commands script Source: https://github.com/mosaics-nih/mosaics/blob/main/README.md This snippet shows the commands to install MOSAICS using the provided install_commands script. Ensure you have a C++ compiler and MPI support. ```bash cd MOSAICS mkdir build export MPI_CPP_COMP="mpic++" export CPP_COMP="g++" sh install_commands ``` -------------------------------- ### Install MPI Development Packages Source: https://github.com/mosaics-nih/mosaics/blob/main/_autodocs/configuration.md Install MPI development packages for your system to resolve missing MPI header compilation errors. ```bash # Install MPI development packages apt-get install libopenmpi-dev # Ubuntu/Debian yum install openmpi-devel # CentOS/RHEL brew install open-mpi # macOS ``` -------------------------------- ### Install MOSAICS using CMake Source: https://github.com/mosaics-nih/mosaics/blob/main/README.md This snippet demonstrates how to install MOSAICS using CMake. This method requires a C++ compiler with MPI support. ```bash cd MOSAICS mkdir build cmake src/MosAT/programs/ -S . -B build/ cmake --build build/ ``` -------------------------------- ### Atom Selection Language Examples Source: https://github.com/mosaics-nih/mosaics/blob/main/_autodocs/api-reference/atom-selection.md Demonstrates various ways to select atoms using the selection language, including ranges, names, and logical combinations. ```text id 1-10 # Atoms 1-10 resi 1-50 and resn ALA # Residues 1-50 that are alanine atom CA or atom C # CA or C atoms not segid PRO # Everything except protein (resi 1-10 or resi 20-30) and resn GLY ``` -------------------------------- ### Execute MPI Program with mpirun Source: https://github.com/mosaics-nih/mosaics/blob/main/_autodocs/api-reference/mpi-parallel.md Example of running an MPI program on a specified number of processes using mpirun. ```bash mpirun -np 4 ./program # Run on 4 processes ``` -------------------------------- ### GROMACS matrix Usage Example Source: https://github.com/mosaics-nih/mosaics/blob/main/_autodocs/types.md Illustrates setting up a rectangular and a triclinic periodic box using the `matrix` type, specifying dimensions and offsets. ```cpp matrix box; // Rectangular box (diagonal elements): box[XX][XX] = 10.0; // X dimension (nm) box[YY][YY] = 10.0; // Y dimension (nm) box[ZZ][ZZ] = 10.0; // Z dimension (nm) // Off-diagonal: 0 // Non-rectangular box (triclinic): box[YY][XX] = 0.5; // Y offset in X direction box[ZZ][XX] = 0.5; // Z offset in X direction box[ZZ][YY] = 0.5; // Z offset in Y direction ``` -------------------------------- ### Atom Selection Syntax Examples Source: https://github.com/mosaics-nih/mosaics/blob/main/_autodocs/configuration.md Illustrates the syntax for selecting atoms and residues within trajectory data. Supports ranges, names, and logical grouping for complex selections. ```cpp id 1-100 # Atom numbers 1-100 resi 1-50 # Residues 1-50 resn ALA # Alanine residues atom CA # Alpha carbons (resi 1-10) or (resi 20-30) # Grouping with logical operators ``` -------------------------------- ### Compile MPI Program with mpic++ Source: https://github.com/mosaics-nih/mosaics/blob/main/_autodocs/api-reference/mpi-parallel.md Example of compiling a C++ MPI program using the mpic++ wrapper, specifying include paths. ```bash mpic++ -I./src/headers program.cpp -o program ``` -------------------------------- ### Run Membrane Thickness Analysis Source: https://github.com/mosaics-nih/mosaics/blob/main/_autodocs/00-START-HERE.md Example command to run the membrane_thickness analysis program. It specifies input trajectory, reference, parameter files, output file, and bin size. ```bash mpirun -np 8 membrane_thickness \ -f trajectory.gro \ -r reference.gro \ -param lipids.txt \ -o thickness.txt \ -bin 0.01 ``` -------------------------------- ### Example Usage of get_index Source: https://github.com/mosaics-nih/mosaics/blob/main/_autodocs/api-reference/index-param.md Demonstrates how to instantiate the Index class and use the get_index method to load data from an index file. The loaded data is stored in parallel vectors for strings, integers, and doubles. ```cpp Index idx; idx.get_index("atom_selection.ndx"); // idx.index_s contains string data // idx.index_i contains parsed int values // idx.index_d contains parsed double values ``` -------------------------------- ### Common MOSAICS MPI Initialization Pattern Source: https://github.com/mosaics-nih/mosaics/blob/main/_autodocs/api-reference/mpi-parallel.md Illustrates the typical setup for MPI applications within the MOSAICS framework, including initialization, rank/size retrieval, and finalization. Ensure MPI is initialized before use and finalized afterward. ```cpp int world_rank = 0; int world_size = 1; MPI_Init(&argc, &argv); MPI_Comm_rank(MPI_COMM_WORLD, &world_rank); MPI_Comm_size(MPI_COMM_WORLD, &world_size); // ... do work ... MPI_Finalize(); ``` -------------------------------- ### GROMACS rvec Usage Example Source: https://github.com/mosaics-nih/mosaics/blob/main/_autodocs/types.md Demonstrates initializing `rvec` for atomic positions and velocities, and accessing its components using index constants. ```cpp rvec position = {1.5, 2.0, 3.5}; // Atomic coordinates (nm) rvec velocity = {0.001, 0.002, 0.003}; // Velocity (nm/ps) // Access components double x = position[XX]; // or position[0] double y = position[YY]; // or position[1] double z = position[ZZ]; // or position[2] ``` -------------------------------- ### Param::get_column_sec_s Usage Example Source: https://github.com/mosaics-nih/mosaics/blob/main/_autodocs/api-reference/index-param.md Provides an example of how to use the get_column_sec_s method to retrieve atom names from a secondary parameter file. It assumes a specific lipid type index (e.g., POPC at index 1) and a column index (e.g., 0 for atom names). ```cpp // Get atom names from POPC definition vector atoms = param.get_column_sec_s(1, 0); // Assumes POPC is at index 1 ``` -------------------------------- ### Build MOSAICS with CMake Source: https://github.com/mosaics-nih/mosaics/blob/main/_autodocs/configuration.md Use this method for building the project with CMake. Ensure you have CMake 3.10+, a C++11 compliant compiler, and an MPI compiler wrapper installed. ```bash cd MOSAICS mkdir build cd build cmake .. -DCMAKE_CXX_COMPILER=mpic++ cmake --build . ``` -------------------------------- ### Initialize program_variables Source: https://github.com/mosaics-nih/mosaics/blob/main/_autodocs/types.md Provides a function to initialize a `program_variables` struct with default values. This ensures that essential parameters have sensible starting points before analysis begins. ```cpp void initialize_program_variables(program_variables *p) { p->stride = 1; p->start_frame = 0; p->end_frame = -1; p->leaflet = 1; p->APS = 0.005; // ... set all defaults ... } ``` -------------------------------- ### Setting Thread Count with MPI Source: https://github.com/mosaics-nih/mosaics/blob/main/_autodocs/configuration.md Set the number of parallel processes using the mpirun command. This example launches 8 parallel processes. ```bash mpirun -np 8 ./program # 8 parallel processes ``` -------------------------------- ### MOSAICS Project Directory Structure Source: https://github.com/mosaics-nih/mosaics/blob/main/_autodocs/README.md Overview of the MOSAICS project's file and directory organization, highlighting key components like source code, headers, examples, and scripts. ```text MOSAICS/ ├── src/ │ ├── MosAT/ │ │ ├── programs/ ← 69 analysis programs (*.cpp) │ │ └── program_variables/ ← Per-program parameters (*.h) │ ├── headers/ │ │ ├── traj.h [trajectory.md] │ │ ├── index.h, param.h [index-param.md] │ │ ├── grid.h, grid_3d.h [grid.md] │ │ ├── atom_select.h [atom-selection.md] │ │ ├── leaflet_finder.h [analysis-utilities.md] │ │ ├── parallel.h [mpi-parallel.md] │ │ ├── command_line_args.h [command-line.md] │ │ └── ... (30+ more) │ ├── gmx_lib/ ← GROMACS utilities │ ├── xdr/ ← Binary format readers │ └── other_tools/ ← Non-MPI programs ├── examples/ ← Sample workflows ├── scripts/ ← Utility scripts ├── README.md ← Quick start └── LICENSE ← BSD-3-clause ``` -------------------------------- ### MosAT Program Development Template Source: https://github.com/mosaics-nih/mosaics/blob/main/_autodocs/analysis-programs.md This C++ code structure outlines the essential components for developing a new MosAT analysis program. It includes necessary headers, MPI setup, argument parsing, frame processing loop, data collection, and output generation. ```cpp #include "headers/traj.h" #include "headers/grid.h" #include int main(int argc, char *argv[]) { MPI_Init(&argc, &argv); int world_rank, world_size; MPI_Comm_rank(MPI_COMM_WORLD, &world_rank); MPI_Comm_size(MPI_COMM_WORLD, &world_size); // Parse arguments // Initialize system // Create grid for(int frame = world_rank; frame < num_frames; frame += world_size) { // Read frame // Accumulate analysis } // Collect grid data if(world_rank == 0) { // Write output } MPI_Finalize(); return 0; } ``` -------------------------------- ### start_input_arguments Source: https://github.com/mosaics-nih/mosaics/blob/main/_autodocs/api-reference/command-line.md Prints a program description with automatic line wrapping, conditionally based on the presence of the '-h' flag. ```APIDOC ## start_input_arguments ### Description Prints program description with automatic line wrapping. Only prints if the `-h` flag is present in `argv`. Formats the description to approximately 130 characters per line and prefixes it with "Description: ". ### Signature ```cpp void start_input_arguments(int argc, const char *argv[], string description) ``` ### Parameters #### Path Parameters - **argc** (int) - Required - Argument count. - **argv** (const char**) - Required - Argument array. - **description** (string) - Required - Program description text (space-separated words). ### Returns void ### Example ```cpp string desc = "This program analyzes membrane thickness by computing " "distances between opposing leaflet atoms and projecting " "results onto a 2D grid for spatially resolved statistics."; start_input_arguments(argc, argv, desc); ``` ### Output Example ``` Description: This program analyzes membrane thickness by computing distances between opposing leaflet atoms and projecting results onto a 2D grid for spatially resolved statistics. ``` ``` -------------------------------- ### Initialize Grid Dimensions and Bin Sizes Source: https://github.com/mosaics-nih/mosaics/blob/main/_autodocs/api-reference/grid.md Sets up the grid's physical boundaries and bin dimensions. This method calculates the number of grid cells and allocates internal storage for data accumulation. ```cpp void initialize(double min_x, double max_x, double min_y, double max_y, double bin_x, double bin_y) ``` -------------------------------- ### Selecting Proteins by Segment ID or Chain Source: https://github.com/mosaics-nih/mosaics/blob/main/_autodocs/api-reference/atom-selection.md Provides examples of using segment IDs or chain identifiers to select protein atoms. ```text // Use segid or chain selection // Example: "segid PRO" or "chain A" ``` -------------------------------- ### Grid::initialize Source: https://github.com/mosaics-nih/mosaics/blob/main/_autodocs/api-reference/grid.md Sets up grid dimensions and bin sizes based on provided physical boundaries and bin sizes. It calculates the number of grid cells in each dimension and allocates the necessary internal data structures, initializing them to zero. ```APIDOC ## Grid::initialize ### Description Sets up grid dimensions and bin sizes. ### Method void initialize(double min_x, double max_x, double min_y, double max_y, double bin_x, double bin_y) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Parameters - **min_x** (double) - Minimum X coordinate - **max_x** (double) - Maximum X coordinate - **min_y** (double) - Minimum Y coordinate - **max_y** (double) - Maximum Y coordinate - **bin_x** (double) - Bin width in X direction - **bin_y** (double) - Bin width in Y direction ### Response None ### Behavior - Calculates grid dimensions: `num_g_x = (max_x - min_x) / bin_x` - Allocates internal vectors for rho, count, rho_frame, count_frame - Initializes all values to 0 ``` -------------------------------- ### Binding Event Structure Source: https://github.com/mosaics-nih/mosaics/blob/main/_autodocs/types.md Defines a structure to track binding events between two atoms, including the start and end frames, and the total duration. ```cpp struct BindingEvent { int atom1; int atom2; int frame_start; int frame_end; int duration; }; ``` -------------------------------- ### collect_vector_d Source: https://github.com/mosaics-nih/mosaics/blob/main/_autodocs/api-reference/mpi-parallel.md Gathers double vectors from all ranks to rank 0, where they are summed. This function synchronizes all ranks using MPI barriers at the start and end. ```APIDOC ## Function: collect_vector_d ### Description Gathers double vectors from all ranks to rank 0. Non-rank-0 ranks send their vector to rank 0, which then accumulates (sums) the data from each rank. MPI barriers are used at the start and end for synchronization. ### Signature ```cpp void collect_vector_d(int world_size, int world_rank, vector &data_vec) ``` ### Parameters #### Path Parameters - **world_size** (int) - Required - Total MPI ranks. - **world_rank** (int) - Required - Current MPI rank. - **data_vec** (vector&) - Required - Input vector on all ranks; on rank 0, this vector will contain the accumulated sum from all ranks. ### Returns void ### Behavior - Non-rank-0 ranks send their `data_vec` to rank 0. - Rank 0 receives `data_vec` from each rank and sums them into its own `data_vec`. - MPI barriers are used at the start and end for synchronization. ### MPI Operations MPI_Send, MPI_Recv, MPI_Barrier ### Example ```cpp vector local_data = {1.0, 2.0, 3.0}; collect_vector_d(world_size, world_rank, local_data); if(world_rank == 0) { // local_data now contains the sum of local_data from all ranks. } ``` ``` -------------------------------- ### Selecting Solvents (Water and Ions) Source: https://github.com/mosaics-nih/mosaics/blob/main/_autodocs/api-reference/atom-selection.md Shows how to select water molecules or specific ions using residue names. ```text // Select water or ion atoms // Example: "resn SOL" for water molecules // "resn NA+ or resn CL-" for ions ``` -------------------------------- ### Index::get_index Source: https://github.com/mosaics-nih/mosaics/blob/main/_autodocs/api-reference/index-param.md Reads a comma-separated index file into memory, parsing values into string, integer, and double vectors. Lines starting with '#' are ignored as comments. ```APIDOC ## Index::get_index ### Description Reads comma-separated index file into memory. The file format supports comma-separated values and comments (lines starting with '#'). Values are parsed into three parallel vectors: string, int, and double. ### Method `void Index::get_index(string my_index_file_name)` ### Parameters #### Path Parameters * **my_index_file_name** (string) - Required - Path to index file ### Returns void ### Example ```cpp Index idx; idx.get_index("atom_selection.ndx"); // idx.index_s contains string data // idx.index_i contains parsed int values // idx.index_d contains parsed double values ``` ``` -------------------------------- ### Compile and Verify Single Program Source: https://github.com/mosaics-nih/mosaics/blob/main/_autodocs/configuration.md Compile a single program using CMake and verify its build output. Check the executable size and its dynamic library dependencies. ```bash cd build cmake .. && cmake --build . ls -lh membrane_thickness ldd ./membrane_thickness ``` -------------------------------- ### Basic Compilation with MPI Source: https://github.com/mosaics-nih/mosaics/blob/main/_autodocs/configuration.md Compiles the membrane_thickness program using mpic++ with specified include paths and optimization flags. ```bash cd build mpic++ -I../src/headers -I../src/gmx_lib -I../src/xdr/include \ -std=c++11 -O3 \ ../src/MosAT/programs/membrane_thickness.cpp \ ../src/gmx_lib/*.cpp ../src/xdr/src/*.c \ -o membrane_thickness ``` -------------------------------- ### Typical HPC Cluster Execution Source: https://github.com/mosaics-nih/mosaics/blob/main/_autodocs/analysis-programs.md This command demonstrates a typical execution of a MosAT analysis program on an HPC cluster using MPI. It specifies input files, output prefix, grid bin size, and sampling stride. ```bash mpirun -np 16 ./membrane_thickness \ -f trajectory.gro \ -r reference.gro \ -param lipids.txt \ -o thickness.txt \ -bin 0.01 \ -stride 1 ``` -------------------------------- ### Avoid Silent Errors by Validating Argument Type Source: https://github.com/mosaics-nih/mosaics/blob/main/_autodocs/api-reference/command-line.md This example shows a pitfall where argument type validation is skipped, leading to silent errors as non-numeric strings are converted to 0. ```cpp // BAD: Silently returns 0 if string isn't a number int val = atoi(argv[i+1]); // "abc" becomes 0 ``` -------------------------------- ### Enable 64-bit File Offset Support Source: https://github.com/mosaics-nih/mosaics/blob/main/_autodocs/configuration.md Use the -m64 flag and -D_FILE_OFFSET_BITS=64 to ensure 64-bit support and avoid file offset errors during compilation. ```bash # Ensure 64-bit support gcc -m64 -D_FILE_OFFSET_BITS=64 ``` -------------------------------- ### Analysis Parameters Arguments Source: https://github.com/mosaics-nih/mosaics/blob/main/_autodocs/api-reference/command-line.md Specifies command-line arguments for setting analysis parameters such as frame stride, start/end frames, and bin width. ```cpp // -stride: frame interval (integer) // -b: start frame (integer) // -e: end frame (integer) // -bin: bin width (float) // Example: // program -stride 2 -b 10 -e 100 -bin 0.1 ``` -------------------------------- ### check_float Source: https://github.com/mosaics-nih/mosaics/blob/main/_autodocs/api-reference/command-line.md Validates if a given string represents a valid floating-point number. It enforces specific rules for format, including starting and ending with digits, and having exactly one decimal point. ```APIDOC ## check_float ### Description Validates if string represents a valid floating-point number. ### Signature ```cpp int check_float(string name) ``` ### Parameters #### Path Parameters - **name** (string) - Required - String to validate ### Returns `int`: - `1`: Valid float - `0`: Invalid float ### Validation Rules - Must start and end with digit (or +/- at start, digit at end) - Must contain exactly one decimal point - Must have at least 2 digits total - No characters other than digits, decimal, +/- ### Accepts - "3.14", "-3.14", "+3.14" - "0.5", "100.0", "-0.001" ### Rejects - "3" (no decimal) - "3.14.15" (multiple decimals) - ".5" (no leading digit) - "3." (no trailing digit) - "abc.de" ### Example ```cpp int valid = check_float("3.14"); // Returns 1 valid = check_float("-2.5e10"); // Returns 0 (scientific notation) valid = check_float("42"); // Returns 0 (no decimal) ``` ``` -------------------------------- ### Check MPI Initialization Status Source: https://github.com/mosaics-nih/mosaics/blob/main/_autodocs/api-reference/mpi-parallel.md Verify if the MPI environment has been initialized. If not, set default world rank and size. ```cpp int mpi_initialized = 0; MPI_Initialized(&mpi_initialized); if(!mpi_initialized) { // Not in MPI environment world_rank = 0; world_size = 1; } ``` -------------------------------- ### analyze_pdb_file Source: https://github.com/mosaics-nih/mosaics/blob/main/_autodocs/api-reference/trajectory.md Analyzes a PDB trajectory file structure to extract frame metadata, including atom count, frame count, and byte offsets for each frame start. This function is MPI-aware. ```APIDOC ## analyze_pdb_file ### Description Analyzes a PDB trajectory file structure to extract frame metadata, including atom count, frame count, and byte offsets for each frame start. It counts atoms from ATOM records and frames from ENDMDL records. ### Function Signature ```cpp void analyze_pdb_file(FILE **in_file, int *num_atoms, int *frames, int world_rank, string in_file_name, vector &pos, int64_t *filesize) ``` ### Parameters #### Input/Output Parameters - **in_file** (FILE**) - Open file pointer to PDB file. - **num_atoms** (int*) - Output: atom count in first frame. - **frames** (int*) - Output: frame count (number of ENDMDL). - **pos** (vector&) - Output: frame starting positions. - **filesize** (int64_t*) - Output: total file size. #### Input Parameters - **world_rank** (int) - MPI rank. - **in_file_name** (string) - Path for logging. ### Behavior - Scans first frame to count atoms (via ATOM records). - Counts ENDMDL records to determine frame boundaries. - MPI broadcast of counts to all ranks. ``` -------------------------------- ### Grid Parameters Arguments Source: https://github.com/mosaics-nih/mosaics/blob/main/_autodocs/api-reference/command-line.md Defines command-line arguments for setting grid parameters, including minimum and maximum values for X and Y axes. ```cpp // -xmin: grid X minimum (float) // -xmax: grid X maximum (float) // -ymin: grid Y minimum (float) // -ymax: grid Y maximum (float) // Example: // program -xmin 0 -xmax 10 -ymin 0 -ymax 10 ``` -------------------------------- ### Dynamic Frame Distribution for Load Balancing Source: https://github.com/mosaics-nih/mosaics/blob/main/_autodocs/api-reference/mpi-parallel.md Distribute frames dynamically among MPI ranks to handle uneven workloads. This calculation determines the starting frame and the number of frames for each rank, accounting for remainders. ```cpp // Uneven distribution: some frames take longer int frames_per_rank_base = num_frames / world_size; int extra_frames = num_frames % world_size; int start_frame = world_rank * frames_per_rank_base + min(world_rank, extra_frames); int my_num_frames = frames_per_rank_base + (world_rank < extra_frames ? 1 : 0); ``` -------------------------------- ### Usage of String Vector Type Aliases Source: https://github.com/mosaics-nih/mosaics/blob/main/_autodocs/types.md Demonstrates how to initialize and use the defined string vector type aliases for 1D and 2D string collections. ```cpp sv1d lipid_names = {"POPE", "POPC", "DLPC"}; sv2d lipid_definitions = { {"POPE", "PO4"}, {"POPC", "P"} }; ``` -------------------------------- ### Get MPI Rank and World Size Source: https://github.com/mosaics-nih/mosaics/blob/main/_autodocs/api-reference/mpi-parallel.md Retrieves the current process's rank and the total number of processes in the MPI communicator. This is fundamental for any MPI application to understand its context within the parallel execution. ```cpp int world_rank; int world_size; MPI_Comm_rank(MPI_COMM_WORLD, &world_rank); MPI_Comm_size(MPI_COMM_WORLD, &world_size); ``` -------------------------------- ### Stack Allocation for Small Data Source: https://github.com/mosaics-nih/mosaics/blob/main/_autodocs/configuration.md Demonstrates stack allocation for small, fixed-size data structures. Suitable for buffers and coordinate arrays where size is known at compile time. ```cpp char buffer[200]; // 200 bytes rvec r[100]; // 100 coordinates (1.2 KB) ``` -------------------------------- ### Print Program Description with Line Wrapping Source: https://github.com/mosaics-nih/mosaics/blob/main/_autodocs/api-reference/command-line.md Use this function to display a program's description, automatically wrapping text to a specified line width. It only prints if the `-h` flag is present in the arguments. ```cpp void start_input_arguments(int argc, const char *argv[], string description) ``` ```cpp string desc = "This program analyzes membrane thickness by computing " "distances between opposing leaflet atoms and projecting " "results onto a 2D grid for spatially resolved statistics."; start_input_arguments(argc, argv, desc); ``` -------------------------------- ### analyze_gro_file Source: https://github.com/mosaics-nih/mosaics/blob/main/_autodocs/api-reference/trajectory.md Analyzes a GRO trajectory file to extract frame metadata, including atom count, frame count, and byte offsets for each frame start. This function is MPI-aware and designed for efficient analysis without loading full coordinates. ```APIDOC ## analyze_gro_file ### Description Analyzes a GRO trajectory file to extract frame metadata without loading full coordinates. It identifies frame boundaries and stores their starting positions for potential random access. ### Function Signature ```cpp void analyze_gro_file(FILE **in_file, int *num_atoms, int *frames, int world_rank, string in_file_name, vector &pos, int64_t *filesize) ``` ### Parameters #### Input/Output Parameters - **in_file** (FILE**) - Open file pointer to GRO file. - **num_atoms** (int*) - Output: total atom count in system. - **frames** (int*) - Output: total frame count. - **pos** (vector&) - Output: byte offsets of each frame start. - **filesize** (int64_t*) - Output: total file size in bytes. #### Input Parameters - **world_rank** (int) - MPI rank (output only printed on rank 0). - **in_file_name** (string) - Path to trajectory file for logging. ### Behavior - Rank 0 reads file sequentially to identify frame boundaries. - Stores seek position before each frame for later random access. - Broadcasts frame count and atom count to all ranks. - Prints analysis progress to stdout on rank 0. ### Example ```cpp FILE *gro_file = fopen64("trajectory.gro", "r"); int num_atoms = 0, frames = 0; vector frame_positions; int64_t file_size = 0; analyze_gro_file(&gro_file, &num_atoms, &frames, world_rank, "trajectory.gro", frame_positions, &file_size); ``` ``` -------------------------------- ### Collect Double Vectors to Rank 0 Source: https://github.com/mosaics-nih/mosaics/blob/main/_autodocs/api-reference/mpi-parallel.md Gathers double-precision vectors from all MPI ranks and accumulates them on rank 0. Non-rank-0 processes send their data, while rank 0 sums received data. Synchronization barriers are used at the start and end. ```cpp void collect_vector_d(int world_size, int world_rank, vector &data_vec) ``` ```cpp vector local_data = {1.0, 2.0, 3.0}; collect_vector_d(world_size, world_rank, local_data); if(world_rank == 0) { // local_data contains sum from all ranks // global_data[i] = rank0_data[i] + rank1_data[i] + ... } ``` -------------------------------- ### Write Custom Analysis Script Source: https://github.com/mosaics-nih/mosaics/blob/main/_autodocs/README.md A C++ template for writing custom analysis scripts using Mosaics and MPI. It includes necessary headers for trajectory and grid operations, and outlines the basic MPI initialization and finalization structure. ```cpp #include "headers/traj.h" #include "headers/grid.h" #include int main() { MPI_Init(&argc, &argv); // ... read trajectory, create grid ... // ... loop frames: load frame, analyze, accumulate ... // ... collect_grid_d(world_size, world_rank, grid) ... // ... rank 0: write output ... MPI_Finalize(); } ``` -------------------------------- ### Check Trajectory File Format Source: https://github.com/mosaics-nih/mosaics/blob/main/_autodocs/configuration.md Use the 'file' command to inspect the format of your trajectory file and ensure it is compatible with MOSAICS. ```bash # Check trajectory file format file trajectory.gro # Should indicate ASCII text or binary (XTC/TRR) ``` -------------------------------- ### Validate Float String Source: https://github.com/mosaics-nih/mosaics/blob/main/_autodocs/api-reference/command-line.md Validates if a string represents a valid floating-point number according to specific rules. It must start and end with a digit, contain exactly one decimal point, and have at least two digits in total. Rejects scientific notation. ```cpp int check_float(string name) ``` **Parameters:** | Parameter | |-----------| | name | string | String to validate | **Returns:** `int`: - `1`: Valid float - `0`: Invalid float **Validation Rules:** - Must start and end with digit (or +/- at start, digit at end) - Must contain exactly one decimal point - Must have at least 2 digits total - No characters other than digits, decimal, +/- **Accepts:** - "3.14", "-3.14", "+3.14" - "0.5", "100.0", "-0.001" **Rejects:** - "3" (no decimal) - "3.14.15" (multiple decimals) - ".5" (no leading digit) - "3." (no trailing digit) - "abc.de" **Example:** ```cpp int valid = check_float("3.14"); // Returns 1 valid = check_float("-2.5e10"); // Returns 0 (scientific notation) valid = check_float("42"); // Returns 0 (no decimal) ``` ``` -------------------------------- ### Analyze PDB Trajectory File Source: https://github.com/mosaics-nih/mosaics/blob/main/_autodocs/api-reference/trajectory.md Analyzes a PDB trajectory file to count atoms and frames, and to record frame starting positions. It scans the first frame for atom records and ENDMDL records for frame boundaries. MPI broadcast of counts is performed. ```cpp void analyze_pdb_file(FILE **in_file, int *num_atoms, int *frames, int world_rank, string in_file_name, vector &pos, int64_t *filesize) ``` -------------------------------- ### Selection Arguments Source: https://github.com/mosaics-nih/mosaics/blob/main/_autodocs/api-reference/command-line.md Specifies command-line arguments for defining atom selections, including two primary selections and an index file. ```cpp // -sel1: first atom selection // -sel2: second atom selection // -selindex: index file for selections // Example: // program -sel1 "id 1-50" -sel2 "resn ALA" ``` -------------------------------- ### Analyze GRO Trajectory File Source: https://github.com/mosaics-nih/mosaics/blob/main/_autodocs/api-reference/trajectory.md Analyzes a GRO trajectory file to extract frame metadata and byte offsets. Use this to get frame counts and atom counts without loading full coordinates. Requires MPI rank and file path for logging. ```cpp void analyze_gro_file(FILE **in_file, int *num_atoms, int *frames, int world_rank, string in_file_name, vector &pos, int64_t *filesize) ``` ```cpp FILE *gro_file = fopen64("trajectory.gro", "r"); int num_atoms = 0, frames = 0; vector frame_positions; int64_t file_size = 0; analyze_gro_file(&gro_file, &num_atoms, &frames, world_rank, "trajectory.gro", frame_positions, &file_size); ``` -------------------------------- ### Grid-Point Parallelization with MPI Gather Source: https://github.com/mosaics-nih/mosaics/blob/main/_autodocs/api-reference/mpi-parallel.md This snippet illustrates grid-point parallelization where each MPI rank is responsible for a subset of the grid's X-coordinates. It shows how to create a local grid, process atoms that fall within the rank's X-range, and then use `gather_grid_d_gp` to collect the local grids into a global grid on rank 0. ```cpp int total_grid_x = 100; int grid_x_per_rank = total_grid_x / world_size; // Each rank creates local grid vector> local_grid(grid_y, vector(grid_x_per_rank, 0.0)); // Each rank only fills its X columns int my_start_x = world_rank * grid_x_per_rank; int my_end_x = (world_rank+1) * grid_x_per_rank; // Process atoms, add to appropriate grid points for(auto& atom : atoms) { if(atom.x >= my_start_x && atom.x < my_end_x) { // This rank handles this grid point int local_x = atom.x - my_start_x; int global_y = atom.y; local_grid[global_y][local_x] += atom.contribution; } } // Gather to rank 0 vector dims_per_rank(world_size, grid_x_per_rank); vector> global_grid(grid_y, vector(total_grid_x, 0.0)); gather_grid_d_gp(world_size, world_rank, grid_x_per_rank, total_grid_x, grid_y, dims_per_rank, local_grid, global_grid); ``` -------------------------------- ### MPI-Aware Help Check Source: https://github.com/mosaics-nih/mosaics/blob/main/_autodocs/api-reference/command-line.md All MPI ranks call this function, but only rank 0 prints help messages. This ensures consistent behavior across distributed processes. ```cpp // All ranks call these, but only rank 0 prints int help_needed = check_help(argc, argv); if(help_needed && world_rank == 0) { start_input_arguments(argc, argv, description); } ``` -------------------------------- ### MOSAICS Project Navigation Structure Source: https://github.com/mosaics-nih/mosaics/blob/main/_autodocs/INDEX.md Illustrates the hierarchical structure of the MOSAICS project documentation, showing the main README file and its relationship to other overview, configuration, data type, analysis program, and API reference files. ```markdown README.md (START HERE) ├── overview.md (Project description) ├── configuration.md (Build & runtime) ├── types.md (Data type reference) ├── analysis-programs.md (Program catalog) └── api-reference/ ├── trajectory.md (File I/O) ├── index-param.md (Parameter files) ├── grid.md (Spatial binning) ├── atom-selection.md (Atom queries) ├── analysis-utilities.md (Core algorithms) ├── mpi-parallel.md (Distributed computing) └── command-line.md (Argument parsing) ``` -------------------------------- ### Usage of Integer Vector Type Aliases Source: https://github.com/mosaics-nih/mosaics/blob/main/_autodocs/types.md Shows how to initialize 1D integer vectors for atom indices and 2D integer vectors for contact maps. ```cpp iv1d atom_indices = {1, 2, 5, 10}; iv2d contact_map = vector(n_atoms, iv1d(n_atoms, 0)); ``` -------------------------------- ### Template Program Structure for Custom Analysis Source: https://github.com/mosaics-nih/mosaics/blob/main/_autodocs/00-START-HERE.md Basic C++ structure for a custom MOSAICS analysis program. It includes necessary headers, MPI initialization, and placeholders for argument parsing, trajectory reading, grid creation, analysis loop, result collection, and output writing. ```cpp #include "headers/traj.h" #include "headers/grid.h" #include int main(int argc, char *argv[]) { MPI_Init(&argc, &argv); // ... parse arguments (api-reference/command-line.md) ... // ... read trajectory (api-reference/trajectory.md) ... // ... create grid (api-reference/grid.md) ... // ... loop frames: read, analyze, accumulate ... // ... collect results (api-reference/mpi-parallel.md) ... // ... write output (rank 0 only) ... MPI_Finalize(); } ``` -------------------------------- ### macOS Compatibility Header Source: https://github.com/mosaics-nih/mosaics/blob/main/_autodocs/configuration.md This C++ preprocessor directive ensures compatibility on macOS by defining `off64_t` and `fopen64` to their standard `off_t` and `fopen` equivalents. It allows source code to compile without modification on both Linux and macOS. ```cpp #ifdef __APPLE__ # define off64_t off_t # define fopen64 fopen #endif ``` -------------------------------- ### Platform-Specific File Offset Definition Source: https://github.com/mosaics-nih/mosaics/blob/main/_autodocs/types.md Provides compatibility for 'off64_t' and 'fopen64' between Linux and macOS systems. ```cpp #ifdef __APPLE__ #define off64_t off_t #define fopen64 fopen #endif ``` -------------------------------- ### Index Class Method Signature: display_index Source: https://github.com/mosaics-nih/mosaics/blob/main/_autodocs/api-reference/index-param.md Provides the signature for the display_index method, which prints all data stored within the index to standard output. ```cpp void Index::display_index() ``` -------------------------------- ### MOSAICS Core Components Overview Source: https://github.com/mosaics-nih/mosaics/blob/main/_autodocs/overview.md Outlines the primary modules within the MOSAICS architecture, including trajectory handling, parameter file parsing, grid systems, and analysis utilities. ```c++ // Trajectory Module (traj.h) // Reads trajectory files in multiple formats (GRO, XTC, TRR, PDB) // Manages atomic coordinates and system properties // Interfaces with GROMACS XDR utilities for binary format support // Index/Parameter Files (index.h, param.h) // Reads complex parameter files with multiple data types // Supports selection lists and atom specifications // Hierarchical parameter structure for lipid types and atom selections // Grid System (grid.h, grid_3d.h, grid_lt.h) // 2D and 3D spatial grids for binned analysis // Support for different data types (double, int) // MPI-aware grid data collection and distribution // Analysis Utilities // Leaflet Finder (leaflet_finder.h): Identifies upper/lower membrane leaflets // Protein Finder (protein_finder.h): Locates protein atoms in system // Solvent Finder (sol_finder.h): Identifies solvent molecules // Atom Selection (atom_select.h): Complex atom selection syntax // Binding Events (binding_events.h): Tracks molecular binding interactions // MPI Support (parallel.h, vector_mpi.h, command_line_args_mpi.h) // Distributed workload management // Grid data collection across ranks // Vector data gathering and broadcasting ``` -------------------------------- ### check_help Source: https://github.com/mosaics-nih/mosaics/blob/main/_autodocs/api-reference/command-line.md Checks for the presence of the `-h` flag in the command-line arguments to display help information. ```APIDOC ## check_help ### Description Checks if `-h` flag is present in command line arguments. ### Signature ```cpp int check_help(int argc, const char *argv[]) ``` ### Parameters #### Path Parameters - **argc** (int) - Required - Argument count - **argv** (const char**) - Required - Argument array ### Returns `int`: - `1`: `-h` found - `0`: `-h` not found ### Usage ```cpp if(check_help(argc, argv)) { printf("Usage: program [options]\n"); print_options(); exit(EXIT_SUCCESS); } ``` ``` -------------------------------- ### Trajectory File Arguments Source: https://github.com/mosaics-nih/mosaics/blob/main/_autodocs/api-reference/command-line.md Defines common command-line arguments for specifying input trajectory files, output files, and reference structures. ```cpp // -f: input trajectory file // -o: output file // -r: reference structure // Example: // program -f trajectory.gro -o output.txt -r reference.gro ``` -------------------------------- ### Set Compiler Flags for Build Source: https://github.com/mosaics-nih/mosaics/blob/main/_autodocs/configuration.md Define compiler flags for C++ and linker. '-march=native' optimizes for the current CPU architecture, and '-O3' enables aggressive optimization. ```bash export CXXFLAGS="-march=native -O3" export LDFLAGS="-L/usr/local/lib" ``` -------------------------------- ### Print Arguments on Rank 0 Only Source: https://github.com/mosaics-nih/mosaics/blob/main/_autodocs/api-reference/command-line.md Use this pattern to print program parameters only from the root process (rank 0) to avoid redundant output in parallel applications. ```cpp if(world_rank == 0) { printf("\nProgram Parameters:\n"); printf(" Input file: %s\n", in_file); printf(" Output file: %s\n", out_file); printf(" Stride: %d\n", stride); printf(" Bin width: %f\n", bin_width); printf("\n"); } ``` -------------------------------- ### Usage of Double Vector Type Aliases Source: https://github.com/mosaics-nih/mosaics/blob/main/_autodocs/types.md Illustrates the initialization of 1D double vectors for coordinates and 2D double vectors for grid data. ```cpp dv1d coordinates = {1.0, 2.0, 3.0}; dv2d grid_data = vector(ny, dv1d(nx, 0.0)); // ny x nx grid ``` -------------------------------- ### Usage of GROMACS Index Constants Source: https://github.com/mosaics-nih/mosaics/blob/main/_autodocs/types.md Shows how to use the `XX`, `YY`, and `ZZ` constants to access elements of `rvec` and `matrix` for clarity and convenience. ```cpp rvec r = {1.0, 2.0, 3.0}; double x = r[XX]; // Same as r[0] double z = r[ZZ]; // Same as r[2] matrix box; box[XX][XX] = 10.0; // X box dimension ``` -------------------------------- ### Correct Pattern for Argument Parsing and Validation Source: https://github.com/mosaics-nih/mosaics/blob/main/_autodocs/api-reference/command-line.md This is the recommended pattern for parsing command-line arguments, ensuring existence, validating type, and performing actions in a rank-aware manner. ```cpp // GOOD: Check existence, validate type, rank-aware if(i+1 >= argc || !check_int(argv[i+1])) { if(world_rank == 0) { printf("Error: invalid stride argument\n"); } MPI_Finalize(); exit(EXIT_FAILURE); } int stride = atoi(argv[++i]); if(world_rank == 0) { printf("Stride: %d\n", stride); } ``` -------------------------------- ### MPI-Aware Argument Parsing Pattern Source: https://github.com/mosaics-nih/mosaics/blob/main/_autodocs/api-reference/command-line.md A common pattern for parsing command-line arguments in MPI applications. It includes checking for help flags and parsing integer and float parameters. ```cpp // Check help if(check_help(argc, argv)) { if(world_rank == 0) { start_input_arguments(argc, argv, program_description); // Print option descriptions... } MPI_Finalize(); exit(EXIT_SUCCESS); } // Parse arguments (loop through argv) for(int i = 1; i < argc; i++) { if(strcmp(argv[i], "-f") == 0) { if(check_int(argv[i+1])) { my_int_param = atoi(argv[++i]); } else { printf("Error: -f requires integer argument\n"); MPI_Finalize(); exit(EXIT_FAILURE); } } else if(strcmp(argv[i], "-x") == 0) { if(check_float(argv[i+1])) { my_float_param = atof(argv[++i]); } } } ``` -------------------------------- ### Bind MPI Processes to CPUs Source: https://github.com/mosaics-nih/mosaics/blob/main/_autodocs/configuration.md Bind MPI processes to specific CPU cores using OpenMPI for improved performance and reduced overhead. Use '--bind-to core' for core-level binding. ```bash mpirun -np 8 --bind-to core ./program ``` -------------------------------- ### MosAT Framework Parallelization Pattern Source: https://github.com/mosaics-nih/mosaics/blob/main/_autodocs/README.md Illustrates the MPI-based parallelization strategy for the MosAT framework, where trajectory frames are distributed across ranks for processing and results are aggregated. ```text Rank 0: Read trajectory metadata, broadcast to all All: Each rank processes its frame subset Accumulates local grid/histogram Rank 0: Receives and sums all local results Writes final output ``` -------------------------------- ### Index Class Method Signature: get_column_i Source: https://github.com/mosaics-nih/mosaics/blob/main/_autodocs/api-reference/index-param.md Provides the signature for the get_column_i method, used to extract a specific column of integer data from the index. Values are converted using atoi. ```cpp vector Index::get_column_i(int num_columns, int column) ``` -------------------------------- ### Index::display_index Source: https://github.com/mosaics-nih/mosaics/blob/main/_autodocs/api-reference/index-param.md Prints all index data currently loaded in memory to standard output. Each value is printed on a new line. ```APIDOC ## Index::display_index ### Description Prints all index data stored in memory to standard output. Each individual value is displayed on a separate line. ### Method `void Index::display_index()` ### Parameters None ### Returns void ### Output Each value on separate line (via printf) ``` -------------------------------- ### Convert Integer to String (C++11) Source: https://github.com/mosaics-nih/mosaics/blob/main/_autodocs/api-reference/command-line.md Converts an integer to its string representation using `std::to_string`, available since C++11. ```cpp int i = 42; string s = to_string(i); // C++11 ``` -------------------------------- ### Index Class Method Signature: get_index Source: https://github.com/mosaics-nih/mosaics/blob/main/_autodocs/api-reference/index-param.md Provides the signature for the get_index method, which reads a comma-separated index file into memory. ```cpp void Index::get_index(string my_index_file_name) ``` -------------------------------- ### Include Base Directory for Headers Source: https://github.com/mosaics-nih/mosaics/blob/main/CMakeLists.txt Sets the base directory for locating header files, essential for resolving include paths across the project. ```cmake include_directories(src/) ``` -------------------------------- ### Avoid Crashing by Checking Argument Existence Source: https://github.com/mosaics-nih/mosaics/blob/main/_autodocs/api-reference/command-line.md This code demonstrates a common mistake where argument existence is not checked, potentially leading to a crash if the argument is missing. ```cpp // BAD: Crashes if argv[i+1] doesn't exist int val = atoi(argv[i+1]); ``` -------------------------------- ### Index Class Method Signature: get_column_s Source: https://github.com/mosaics-nih/mosaics/blob/main/_autodocs/api-reference/index-param.md Provides the signature for the get_column_s method, used to extract a specific column of string data from the index. ```cpp vector Index::get_column_s(int num_columns, int column) ``` -------------------------------- ### Selecting Membrane Lipids by Atom Name Source: https://github.com/mosaics-nih/mosaics/blob/main/_autodocs/api-reference/atom-selection.md Illustrates how to define a list of atom names for membrane lipids and then use this list to filter trajectory atoms. ```cpp // Typically in parameter files // Select specific atom names in lipid sv1d atom_names = {"PO4", "C4A", "C4B"}; // Headgroup + tails // Then filter trajectory atoms matching these names ``` -------------------------------- ### Param::get_param Method Signature Source: https://github.com/mosaics-nih/mosaics/blob/main/_autodocs/api-reference/index-param.md Declares the signature for the get_param method, which is responsible for reading primary and secondary parameter files. This method takes the main parameter file name and details about column configurations as input. ```cpp void Param::get_param(string my_param_file_name, int my_num_col, int my_file_col, int my_num_col_secondary) ``` -------------------------------- ### Analyze Membrane Thickness Source: https://github.com/mosaics-nih/mosaics/blob/main/_autodocs/README.md Use this command to analyze membrane thickness from a trajectory file. Specify input files, output file, bin size, and stride for the analysis. ```bash mpirun -np 8 membrane_thickness \ -f trajectory.xtc \ -r reference.gro \ -param lipid_types.txt \ -o thickness.txt \ -bin 0.01 \ -stride 1 ```