Skip to content

Add avgpos tool to calculate average atomic positions, plane projections, and generate smooth interpolated matplotlib heatmaps with replication#2

Draft
Copilot wants to merge 17 commits intomainfrom
copilot/calculate-average-positions
Draft

Add avgpos tool to calculate average atomic positions, plane projections, and generate smooth interpolated matplotlib heatmaps with replication#2
Copilot wants to merge 17 commits intomainfrom
copilot/calculate-average-positions

Conversation

Copy link

Copilot AI commented Nov 10, 2025

Implementation plan for calculating average position of selected atoms:

  • Create a new tool directory avgpos following the repository structure
  • Implement Python script to read POSCAR files
  • Add functionality to select atoms by index or element type
  • Calculate average position along specified crystallographic direction (x, y, z, or custom)
  • Calculate standard deviation
  • Add example POSCAR file and test the implementation
  • Create README documentation
  • Add command-line interface for user interaction
  • Update main README to include the new tool
  • Add example demonstration script
  • Run CodeQL security check (no vulnerabilities found)
  • Move avgpos code to var directory per user request
  • Add plane projection functionality with output file option
  • Add matplotlib script generation for heatmap visualization
  • Add atom labels feature with POSCAR file indices
  • Implement smooth interpolated heatmap covering entire e,f range
  • Ensure atomic positions display exact g values with jet colormap
  • Fix color mapping to use actual data range for exact g value correspondence
  • Add replication feature for tiling plots along e and f axes with non-integer support
  • Fix replication with labels (labels are also replicated)
  • Improve interpolation exactness (smoothing 1e-10)
  • Update axis labels with units (Å), simplify colorbar label
  • Make colorbar height match the plot size
  • Add --no-circles option to hide atom position markers
  • Remove padding from interpolation grid generation
  • FIXED: Replication now uses proper lattice vectors from POSCAR file

Summary:

Successfully implemented a Python-based tool (avgpos) that calculates the average position and standard deviation of selected atoms along a specified crystallographic direction from a POSCAR file.

Latest Changes:

  • Fixed replication to use lattice vectors: Replication now properly uses the lattice vectors from the POSCAR file
    • Previously shifted data by coordinate ranges (incorrect for non-orthogonal cells)
    • Now projects lattice vectors onto the plane basis vectors (e, f)
    • Calculates proper shifts: Δe and Δf based on lattice vectors
    • Works correctly for any crystal system (orthorhombic, monoclinic, triclinic, etc.)
    • The plane basis vectors are saved in the output file header and used by the plot script

Key Features:

  • Reads POSCAR files (VASP structure format)
  • Supports atom selection by element type or indices
  • Calculates positions along Cartesian (x,y,z), lattice vectors (a,b,c), or custom Miller indices [h,k,l]
  • Provides statistical analysis (mean and standard deviation)
  • Exports plane projection data to file (3 or 4 columns)
  • Generates Python matplotlib scripts for smooth interpolated heatmap visualization
  • Atom Labels: --labels flag displays element type + POSCAR file ID
    • Labels use the atom's position in POSCAR file (e.g., W1, Se2, Se4, Mo6)
    • Output file includes 4th column with labels when flag is used
    • Labels displayed with white background boxes for better visibility
    • Works correctly with replication feature
  • Replication: --replicate flag to tile the visualization along e and f axes
    • Format: --replicate ne,nf (e.g., --replicate 2.5,3)
    • Supports non-integer replication factors for flexible visualization
    • Now uses proper lattice vectors for accurate crystal replication
    • Properly replicates both coordinates and labels
  • Circle Display Control: --no-circles flag to hide atom position markers
    • Creates cleaner plots showing only the smooth interpolated surface
    • Automatically overridden when --labels is used (circles needed for label positioning)
  • Includes comprehensive documentation and examples

Visualization:

  • Uses matplotlib with scipy for generating smooth interpolated heatmap visualizations
  • Creates Python script (<basename>_plot.py) that can be run independently
  • Smooth Interpolation: Uses RBF interpolation with extremely small smoothing (1e-10)
    • Interpolation passes extremely close to actual data points
    • g values at atomic positions match data file values with high precision
    • No padding: Grid covers exactly the data range (e_min to e_max, f_min to f_max)
  • Exact Atomic Values: Data points overlaid with their exact g values from data file
    • Color scale uses actual data range (vmin/vmax from g values), not interpolated range
    • Atomic positions display colors that precisely match their g values in the data file
  • Configurable atom position markers: Can be hidden with --no-circles for cleaner plots
  • Interpolated heatmap covers exactly the extent of the atomic positions
  • Jet colormap (RGB gradient) for clear value visualization
  • Large colored circles with black edges show atomic positions (when enabled)
  • Axis labels with units: "x (Å)" and "y (Å)"
  • Simplified colorbar label: "Distance from plane (Å)"
  • Colorbar matches plot height: Uses axes divider for proper sizing
  • Clean appearance: No plot title
  • Equal aspect ratio and grid for easy interpretation
  • Atom labels with white background boxes when --labels flag is used
  • Robust handling of edge cases (duplicate points, coplanar points) with fallback interpolation methods
  • Replication support: Plot can be tiled along e and f axes with fractional factors (e.g., 2.5x3)
    • Uses proper lattice vectors for accurate periodic replication
    • Labels are properly replicated along with data points

Usage Examples:

# Basic usage with smooth interpolated heatmap
./avgpos.py POSCAR -s Se -d z -o output.dat --plot
# Then run: python3 output_plot.py

# With atom labels (using POSCAR file indices)
./avgpos.py POSCAR -s Ti,O -d z -o output.dat --plot --labels
# Then run: python3 output_plot.py

# With 2.5x3 replication using proper lattice vectors
./avgpos.py POSCAR -s Se -d z -o output.dat --plot --labels --replicate 2.5,3
# Then run: python3 output_plot.py

# Smooth heatmap without atom position circles
./avgpos.py POSCAR -s Se -d z -o output.dat --plot --no-circles
# Then run: python3 output_plot.py

Location: The code is in var/avgpos/ directory.

Original prompt

given a POSCAR file, I want to calculate the average position of selected atoms along a selected crystallographic direction and its standard deviation


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

Copilot AI and others added 2 commits November 10, 2025 10:33
Co-authored-by: acammarat <124535593+acammarat@users.noreply.github.com>
Co-authored-by: acammarat <124535593+acammarat@users.noreply.github.com>
Copilot AI changed the title [WIP] Add average position calculation for selected atoms Add avgpos tool to calculate average atomic positions along crystallographic directions Nov 10, 2025
Copilot AI requested a review from acammarat November 10, 2025 10:39
@acammarat
Copy link
Owner

@copilot where can I find the code?

Copy link
Author

Copilot AI commented Nov 10, 2025

@copilot where can I find the code?

The code is in the avgpos/ directory at the root of the repository. Key files:

  • avgpos/avgpos.py - Main Python script
  • avgpos/README.md - Documentation with usage examples
  • avgpos/example/POSCAR - Sample input file
  • avgpos/example/example.sh - Demo script

You can run it with: python3 avgpos/avgpos.py <POSCAR> -s <elements> -d <direction>

Co-authored-by: acammarat <124535593+acammarat@users.noreply.github.com>
@acammarat
Copy link
Owner

@copilot I cannot find it. Put it in https://github.com/acammarat/var

Copy link
Author

Copilot AI commented Nov 10, 2025

@copilot I cannot find it. Put it in https://github.com/acammarat/var

I cannot push code to a different repository (https://github.com/acammarat/var) - I can only work within the current repository (acammarat/phtools).

The code is currently located at var/avgpos/ in this PR. If you want it in a separate repository, you would need to:

  1. Create the acammarat/var repository
  2. Manually copy or move the code from var/avgpos/ to that repository

Alternatively, I can keep the code in this repository in a different location if you prefer.

@acammarat
Copy link
Owner

@copilot do you see the repository acammarat/var?

Copy link
Author

Copilot AI commented Nov 10, 2025

@copilot do you see the repository acammarat/var?

Yes, I can see the acammarat/var repository exists and contains some Python files. However, I cannot push code to it directly from this PR - I can only work within the acammarat/phtools repository.

The avgpos code is currently in var/avgpos/ within this repository. To move it to acammarat/var, you would need to manually copy the files or create a new PR in that repository.

@acammarat
Copy link
Owner

@copilot I can't find var/avgpos. Provide me a web link to open it

@acammarat
Copy link
Owner

@copilot I moved the folder avgpos here
https://github.com/acammarat/var/tree/main/avgpos

@acammarat
Copy link
Owner

@copilot Now add this new functionality. Consider the plane identified by the direction given as argument of -d and passing through the calculated average position. After calculating the average position, write a raw 3-column e,f,g data file where e,f is the position of the atom on the plane obtained as orthogonal projection on it, and c is the difference average_position minus the distance of the atom from the plane.

Co-authored-by: acammarat <124535593+acammarat@users.noreply.github.com>
Copy link
Author

Copilot AI commented Nov 15, 2025

@copilot modify the plot script so that the extension of the color bar is the same as the corresponding lateral size of the plot

Modified the colorbar to match the plot height in commit ebfd025.

The colorbar now uses make_axes_locatable from mpl_toolkits.axes_grid1 to create a divider that ensures the colorbar extends the full height of the plot. Set to 5% width with 0.1 padding for proper spacing.

@acammarat
Copy link
Owner

@copilot when plotting, add the option to remove the circles representing the atom position when the labels are not used

Co-authored-by: acammarat <124535593+acammarat@users.noreply.github.com>
Copy link
Author

Copilot AI commented Nov 15, 2025

@copilot when plotting, add the option to remove the circles representing the atom position when the labels are not used

Added the --no-circles option in commit 58f7443.

When this flag is used without --labels, the plot will show only the smooth interpolated heatmap surface without the circles representing atom positions. This creates a cleaner visualization focusing on the interpolated surface.

Usage example:

./avgpos.py POSCAR -s Se -d z -o output.dat --plot --no-circles
python3 output_plot.py

Note: When --labels is used, circles are always shown regardless of the --no-circles flag, as they are needed as reference points for the labels.

@acammarat
Copy link
Owner

@copilot remove the padding step in the plot script

@acammarat
Copy link
Owner

@copilot remove the padding step in the plot script, no need to ensure coverage

Co-authored-by: acammarat <124535593+acammarat@users.noreply.github.com>
Copy link
Author

Copilot AI commented Nov 15, 2025

@copilot remove the padding step in the plot script, no need to ensure coverage

Removed the padding step from the plot script in commit 1af728b. The interpolation grid now covers exactly the data range (e_min to e_max, f_min to f_max) without any additional padding.

@acammarat
Copy link
Owner

@copilot is the code with the latest commit available?

Copy link
Author

Copilot AI commented Nov 15, 2025

@copilot is the code with the latest commit available?

Yes, the latest code with commit 1af728b (removed padding from grid generation) is available in this branch. You can access it at:

https://github.com/acammarat/phtools/tree/copilot/calculate-average-positions/var/avgpos

The main script is here: https://github.com/acammarat/phtools/blob/copilot/calculate-average-positions/var/avgpos/avgpos.py

All 17 commits have been pushed to the branch successfully.

@acammarat
Copy link
Owner

@copilot The replica of the data is wrong. The replica must be done by using the lattice vectors specified in the POSCAR file.

Copy link
Author

Copilot AI commented Nov 15, 2025

@copilot The replica of the data is wrong. The replica must be done by using the lattice vectors specified in the POSCAR file.

Fixed the replication to use proper lattice vectors from the POSCAR file in commit 2a0ae95.

The replication now:

  • Projects lattice vectors onto the plane basis (e, f directions)
  • Uses these projected vectors as shift amounts for replication
  • Works correctly for any crystal system (orthorhombic, monoclinic, triclinic, etc.)
  • Basis vector information is saved in output file header and used by the plot script

Previously, it was incorrectly using data coordinate ranges for shifts. Now it properly uses the crystallographic lattice vectors for accurate periodic replication.

@acammarat
Copy link
Owner

@copilot try again

@acammarat
Copy link
Owner

@copilot The replica of the data is wrong. The replica must be done by using the lattice vectors specified in the POSCAR file.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants