dichromatic-map 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. dichromatic_map-0.1.0/CONTRIBUTING.md +83 -0
  2. dichromatic_map-0.1.0/LICENSE +18 -0
  3. dichromatic_map-0.1.0/MANIFEST.in +5 -0
  4. dichromatic_map-0.1.0/PKG-INFO +189 -0
  5. dichromatic_map-0.1.0/README.md +169 -0
  6. dichromatic_map-0.1.0/docs/en/README.md +551 -0
  7. dichromatic_map-0.1.0/docs/en/development.md +406 -0
  8. dichromatic_map-0.1.0/docs/images/gui-overview.png +0 -0
  9. dichromatic_map-0.1.0/docs/zh/README.md +486 -0
  10. dichromatic_map-0.1.0/docs/zh/development.md +375 -0
  11. dichromatic_map-0.1.0/main.py +16 -0
  12. dichromatic_map-0.1.0/pyproject.toml +36 -0
  13. dichromatic_map-0.1.0/scripts/run_tests.py +62 -0
  14. dichromatic_map-0.1.0/setup.cfg +4 -0
  15. dichromatic_map-0.1.0/src/dichromatic_map/__init__.py +14 -0
  16. dichromatic_map-0.1.0/src/dichromatic_map/__main__.py +88 -0
  17. dichromatic_map-0.1.0/src/dichromatic_map/cells.py +287 -0
  18. dichromatic_map-0.1.0/src/dichromatic_map/compute.py +257 -0
  19. dichromatic_map-0.1.0/src/dichromatic_map/crystal.py +524 -0
  20. dichromatic_map-0.1.0/src/dichromatic_map/matching.py +294 -0
  21. dichromatic_map-0.1.0/src/dichromatic_map/state.py +130 -0
  22. dichromatic_map-0.1.0/src/dichromatic_map/strain.py +479 -0
  23. dichromatic_map-0.1.0/src/dichromatic_map/ui/__init__.py +15 -0
  24. dichromatic_map-0.1.0/src/dichromatic_map/ui/controls.py +902 -0
  25. dichromatic_map-0.1.0/src/dichromatic_map/ui/plot.py +731 -0
  26. dichromatic_map-0.1.0/src/dichromatic_map/ui/resources/icons/chevron-down.svg +3 -0
  27. dichromatic_map-0.1.0/src/dichromatic_map/ui/resources/icons/chevron-up.svg +3 -0
  28. dichromatic_map-0.1.0/src/dichromatic_map/ui/resources/theme.qss +168 -0
  29. dichromatic_map-0.1.0/src/dichromatic_map/ui/window.py +2210 -0
  30. dichromatic_map-0.1.0/src/dichromatic_map.egg-info/PKG-INFO +189 -0
  31. dichromatic_map-0.1.0/src/dichromatic_map.egg-info/SOURCES.txt +44 -0
  32. dichromatic_map-0.1.0/src/dichromatic_map.egg-info/dependency_links.txt +1 -0
  33. dichromatic_map-0.1.0/src/dichromatic_map.egg-info/entry_points.txt +2 -0
  34. dichromatic_map-0.1.0/src/dichromatic_map.egg-info/requires.txt +12 -0
  35. dichromatic_map-0.1.0/src/dichromatic_map.egg-info/top_level.txt +1 -0
  36. dichromatic_map-0.1.0/tests/conftest.py +9 -0
  37. dichromatic_map-0.1.0/tests/core/__init__.py +1 -0
  38. dichromatic_map-0.1.0/tests/core/helpers.py +35 -0
  39. dichromatic_map-0.1.0/tests/core/test_counts.py +147 -0
  40. dichromatic_map-0.1.0/tests/core/test_geometry.py +231 -0
  41. dichromatic_map-0.1.0/tests/core/test_matching.py +127 -0
  42. dichromatic_map-0.1.0/tests/core/test_strain.py +235 -0
  43. dichromatic_map-0.1.0/tests/core/test_vectors.py +103 -0
  44. dichromatic_map-0.1.0/tests/gui/conftest.py +182 -0
  45. dichromatic_map-0.1.0/tests/gui/test_workflows.py +507 -0
  46. dichromatic_map-0.1.0/tests/packaging/test_distribution.py +228 -0
@@ -0,0 +1,83 @@
1
+ # Contributing to DichromaticMap
2
+
3
+ Bug reports, documentation improvements and code contributions are welcome.
4
+ This is a volunteer-developed project. External donations are not currently
5
+ accepted.
6
+
7
+ ## Report a problem or request a feature
8
+
9
+ Open a [GitHub issue](https://github.com/Yazhuo-Liu/DichromaticMap/issues) or
10
+ email [yliu3500@gatech.edu](mailto:yliu3500@gatech.edu).
11
+
12
+ For a bug report, include:
13
+
14
+ - The DichromaticMap version or commit, Python version and operating system.
15
+ - The relevant settings: lattice, tilt axis, misorientation, visible layers,
16
+ Near-CSL method and parameters, and worker count when applicable.
17
+ - A small reproducible example or numbered GUI steps.
18
+ - The expected result and the actual result, including any error message.
19
+ - A screenshot or exported figure when it helps explain a display problem.
20
+
21
+ For a numerical discrepancy, include the input values, units and reference
22
+ result or calculation used for comparison. For a feature request, explain the
23
+ intended task and the behavior that would help accomplish it.
24
+
25
+ ## Propose a change
26
+
27
+ Submit a [pull request](https://github.com/Yazhuo-Liu/DichromaticMap/pulls), or
28
+ email a description of the change and a patch or repository link to
29
+ [yliu3500@gatech.edu](mailto:yliu3500@gatech.edu). An issue or email can also be
30
+ used to discuss a substantial algorithm or API change before implementation.
31
+
32
+ Keep each contribution focused and describe the problem, the resulting
33
+ behavior and how it was checked. For code changes:
34
+
35
+ - Preserve scientific conventions, including units, layer identity, coordinate
36
+ frames, strain definitions and numerical tolerances. Explain any intended
37
+ change to those conventions and provide a reference or derivation.
38
+ - Add or update meaningful tests for changed behavior. Numerical changes should
39
+ cover representative geometries and relevant boundary cases; GUI changes
40
+ should cover the affected interaction or state transition.
41
+ - Update the English and Chinese user guides when usage or results change, and
42
+ the implementation documents when algorithms or conventions change.
43
+ - Run the relevant test suites and report the results in the pull request,
44
+ including any checks that could not be run.
45
+
46
+ Algorithm descriptions are available in the
47
+ [English implementation details](docs/en/development.md) and
48
+ [中文开发细节](docs/zh/development.md).
49
+
50
+ ## Install and run the tests
51
+
52
+ From the repository root, install the editable package with its test and GUI
53
+ requirements:
54
+
55
+ ```bash
56
+ python -m pip install -e ".[test,gui]"
57
+ python scripts/run_tests.py
58
+ ```
59
+
60
+ Run individual suites when working on a specific part of the project:
61
+
62
+ ```bash
63
+ python scripts/run_tests.py --suite core
64
+ python scripts/run_tests.py --suite gui
65
+ python scripts/run_tests.py --suite packaging
66
+ ```
67
+
68
+ The `core` suite checks numerical behavior and does not depend on the GUI.
69
+ The `gui` suite requires PySide6 and PyQtGraph and uses Qt's `offscreen`
70
+ platform, so it does not require a display server. The `packaging` suite checks
71
+ the distributable package and keeps build artifacts in temporary directories.
72
+ The default command runs all suites.
73
+
74
+ Tests remain in the source repository for contributors; they are not installed
75
+ with the end-user wheel. Keep generated build artifacts out of contributions.
76
+
77
+ ## 中文说明
78
+
79
+ 问题反馈请使用 [GitHub Issues](https://github.com/Yazhuo-Liu/DichromaticMap/issues)
80
+ 或邮件 [yliu3500@gatech.edu](mailto:yliu3500@gatech.edu),并提供版本、平台、复现步骤、
81
+ 预期与实际结果。贡献可提交 PR,也可邮件发送修改说明及补丁或仓库链接。
82
+ 涉及算法的修改请说明科学依据,补充相关测试,并同步中英文文档。
83
+ 本项目由志愿开发维护,暂不接受外部捐赠。
@@ -0,0 +1,18 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Yazhuo Liu
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
6
+ associated documentation files (the "Software"), to deal in the Software without restriction, including
7
+ without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the
9
+ following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be included in all copies or substantial
12
+ portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
15
+ LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO
16
+ EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
17
+ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
18
+ USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,5 @@
1
+ include main.py
2
+ include CONTRIBUTING.md
3
+ include scripts/run_tests.py
4
+ recursive-include tests *.py
5
+ recursive-include docs *.md *.png
@@ -0,0 +1,189 @@
1
+ Metadata-Version: 2.4
2
+ Name: dichromatic-map
3
+ Version: 0.1.0
4
+ Summary: Layer-resolved cubic tilt grain-boundary dichromatic patterns
5
+ License-Expression: MIT
6
+ Requires-Python: >=3.10
7
+ Description-Content-Type: text/markdown
8
+ License-File: LICENSE
9
+ Requires-Dist: numpy
10
+ Provides-Extra: gui
11
+ Requires-Dist: PySide6; extra == "gui"
12
+ Requires-Dist: pyqtgraph; extra == "gui"
13
+ Provides-Extra: test
14
+ Requires-Dist: pytest>=8; extra == "test"
15
+ Requires-Dist: build>=1.2; extra == "test"
16
+ Requires-Dist: setuptools>=77.0.3; extra == "test"
17
+ Requires-Dist: wheel; extra == "test"
18
+ Requires-Dist: packaging>=22; extra == "test"
19
+ Dynamic: license-file
20
+
21
+ # DichromaticMap
22
+
23
+ [English user guide](docs/en/README.md) · [中文使用手册](docs/zh/README.md)
24
+
25
+ DichromaticMap provides a Python library and an interactive viewer for
26
+ layer-resolved FCC/BCC tilt grain-boundary dichromatic patterns. Use it to
27
+ inspect two overlaid grains, identify coincidence sites, measure crystal
28
+ vectors, count atoms in selected cells and explore common cells under uniform
29
+ strain.
30
+
31
+ ## Features
32
+
33
+ - FCC/BCC lattices with ⟨100⟩, ⟨110⟩, ⟨111⟩, ⟨112⟩ and custom integer tilt axes.
34
+ - Independent grain/layer visibility, grain-boundary side filtering and
35
+ display rotation.
36
+ - Same-layer exact coincidence-site lattice (CSL) detection and local near-pair
37
+ matching.
38
+ - Vector measurements in both grain coordinate frames, including axial
39
+ periodic images.
40
+ - Manual common cells with separate G1/G2 atom counts and optional uniform
41
+ strain fitting.
42
+ - Automatic homogeneous-strain common-cell search and PNG export.
43
+ - NumPy-based numerical functions usable independently of the viewer.
44
+
45
+ Coordinates and distances use the reference lattice constant a₀ as their unit.
46
+ Local matching preserves the atom positions. Strain operations impose a
47
+ geometric deformation; they do not perform atomic relaxation or minimize
48
+ elastic energy. A manually selected polygon alone does not establish crystal
49
+ periodicity.
50
+
51
+ ## Install and launch
52
+
53
+ Requires Python 3.10 or later. Download the project, open its root directory,
54
+ and install the library with its viewer:
55
+
56
+ ```bash
57
+ python -m pip install ".[gui]"
58
+ python -m dichromatic_map
59
+ ```
60
+
61
+ The viewer uses PySide6 and PyQtGraph. For numerical calculations only, install
62
+ with `python -m pip install .`; the numerical library requires only NumPy.
63
+
64
+ ```bash
65
+ python -m dichromatic_map --lattice BCC --axis 100
66
+ python -m dichromatic_map --axis "1 -1 3" --workers 4
67
+ python -m dichromatic_map --angle 22 --save pattern.png
68
+ python -m dichromatic_map --help
69
+ ```
70
+
71
+ `dichromatic-map` is an equivalent launch command. From the project root,
72
+ `python main.py` also launches the viewer.
73
+
74
+ ## GUI quick start
75
+
76
+ ![DichromaticMap viewer with its plot and controls](docs/images/gui-overview.png)
77
+
78
+ The example above shows FCC ⟨110⟩ at the Σ9 preset. The plot is on the left;
79
+ settings and results are in the scrollable **Controls** panel on the right.
80
+ Click section headers to expand them, and switch between the **ORIENTATION**
81
+ and **LAYERS** tabs at the top. Blue markers represent G1, orange outlines
82
+ represent G2, marker shapes distinguish axial layers, and gold outlines mark
83
+ same-layer exact coincidences.
84
+
85
+ 1. **Choose the grains.** In **ORIENTATION**, select **Structure** and
86
+ **Tilt / viewing axis**, then choose a **CSL preset** or enter a
87
+ **Misorientation**. For a custom axis, choose **Custom [h k l]**, enter an
88
+ integer triple such as `1 -1 3`, and click **Apply axis** or press Enter.
89
+ **Display rotation** turns the drawing without changing the grain geometry.
90
+ 2. **Choose visible layers.** Open **LAYERS** and toggle individual **G1 A**,
91
+ **G2 A**, etc. For a first selection, click **No layers**, then enable
92
+ **G1 A** and **G2 A**. Coincidence and local-pair markers require the layer to
93
+ be visible in both grains. Enable **Automatic common cell** to display an
94
+ available exact or strain-search cell; **Fit cell** frames it in the view.
95
+ 3. **Navigate.** Drag to pan and use the wheel to zoom. Under **VIEW /
96
+ PERFORMANCE → VIEW**, **Field size** selects a wider or narrower region;
97
+ **Center view** (`C`) returns to the origin at the current zoom. The
98
+ **PERFORMANCE** tab contains **CPU workers**.
99
+ 4. **Measure a vector.** In **GB / VECTOR**, click **Measure vector** (`V`),
100
+ then click two distinct visible atom positions, P1 and P2. Read the vector
101
+ annotation at the lower left of the plot. Same-grain picks show that grain's
102
+ coordinates; cross-grain picks show both G1 and G2 representations.
103
+ **P2 axial periodic image** selects an axial repeat for the second endpoint
104
+ without adding plotted atoms.
105
+ 5. **Define a boundary.** Click **Pick GB** (`R`) and select B1, then B2.
106
+ The side switches appear after the second pick; left/right are relative to
107
+ B1 → B2. Use `1` or `2` for the two complementary grain-side arrangements,
108
+ and `F` to show all sides again. Layer visibility settings still apply.
109
+ 6. **Select and count a cell.** Expand **MANUAL COMMON CELL**, click
110
+ **Pick 4 CSL vertices** (`M`), and select four gold sites of one layer in
111
+ clockwise or counterclockwise order around a convex cell. Use **Undo
112
+ vertex**, **Clear** or **Fit** as needed. The readout gives G1/G2 counts for
113
+ the complete selected cell, including portions outside the current view.
114
+ **Apply GB side visibility to counts** optionally restricts those counts
115
+ to the displayed grain sides.
116
+ 7. **Export the figure.** Scroll to **Export plot as PNG…**, choose a file
117
+ name and save. The PNG contains the plot with its current layers, rotation
118
+ and annotations; the controls are excluded.
119
+
120
+ Press `Esc` to stop picking while retaining existing selections. Pressing `R`
121
+ or `V` starts a fresh boundary or vector selection. Click near a visible atom
122
+ or eligible cell marker; background clicks do not create arbitrary vertices.
123
+
124
+ For inexact orientations, expand **NEAR-CSL**, select a **Method**, and click
125
+ **Enable Near-CSL**:
126
+
127
+ | Method | How to use it | Effect |
128
+ | --- | --- | --- |
129
+ | **Local matching · no bulk strain** | Adjust **Local pair distance**; inspect purple midpoint markers and use them for manual cell picks | Finds nearby same-layer pairs while preserving the atom positions |
130
+ | **Homogeneous strain + periodic cell** | Set **Max principal strain** and **Search index bound**, then choose a returned candidate | Automatically applies the first result, or the candidate you select, to both grains |
131
+
132
+ A manually selected local cell containing at least one near pair can also be
133
+ fitted with **Apply bulk strain to selected cell** in **MANUAL COMMON CELL**.
134
+ Set its strain and rotation limits before applying; **Restore original local
135
+ structure** returns to the original geometry. This operation has a separate
136
+ apply step from the automatic search.
137
+
138
+ For control-by-control instructions, selection rules, result interpretation
139
+ and troubleshooting, see the [English GUI guide](docs/en/README.md#gui-overview)
140
+ or [中文 GUI 使用指南](docs/zh/README.md#gui-overview). Detailed workflows cover
141
+ [vector measurements](docs/en/README.md#gui-vector),
142
+ [Near-CSL methods](docs/en/README.md#gui-near-csl), and
143
+ [manual cells and counts](docs/en/README.md#gui-manual-cell).
144
+
145
+ ## Python usage
146
+
147
+ ```python
148
+ from dichromatic_map import get_geometry, projected_columns, local_near_pairs
149
+
150
+ geometry = get_geometry("FCC", "110")
151
+ grain1 = projected_columns(12, 9, rotation_deg=11, lattice="FCC", axis="110")
152
+ grain2 = projected_columns(12, 9, rotation_deg=-11, lattice="FCC", axis="110")
153
+ pairs = local_near_pairs(grain1, grain2, distance=0.05)
154
+
155
+ print("Axial layers:", geometry.layer_count)
156
+ print("Near pairs:", len(pairs.layers))
157
+ print("Pair separations / a0:", pairs.distances)
158
+ ```
159
+
160
+ The grains above have a reference misorientation of 22°. Matching uses the
161
+ supplied projected columns and preserves their layer labels.
162
+
163
+ | Function exported by `dichromatic_map` | Purpose |
164
+ | --- | --- |
165
+ | `get_geometry` | Obtain planar geometry, axial layers and repeat distance |
166
+ | `projected_columns` | Generate a grain's projected columns in a rectangular region |
167
+ | `same_layer_coincidence_sites` | Locate same-layer coincidences within a specified tolerance |
168
+ | `local_near_pairs` | Find same-layer mutual nearest pairs within a distance threshold |
169
+ | `exact_csl_cell` | Obtain a layer-preserving common translation cell for a recognized commensurate angle |
170
+ | `count_cell_atoms` | Count atoms in complete shared or per-grain polygons |
171
+
172
+ ## Documentation
173
+
174
+ | Topic | English | 中文 |
175
+ | --- | --- | --- |
176
+ | Installation, viewer workflows and Python API | [User guide](docs/en/README.md) | [使用手册](docs/zh/README.md) |
177
+ | Algorithms, numerical conventions and implementation | [Implementation details](docs/en/development.md) | [开发细节](docs/zh/development.md) |
178
+
179
+ ## Contributing and support
180
+
181
+ Report problems through [GitHub Issues](https://github.com/Yazhuo-Liu/DichromaticMap/issues)
182
+ or [yliu3500@gatech.edu](mailto:yliu3500@gatech.edu). Contributions can be
183
+ submitted as a pull request or by email; see the [contribution guide](CONTRIBUTING.md).
184
+ This project is developed by volunteers and does not currently accept external
185
+ donations.
186
+
187
+ ## License
188
+
189
+ DichromaticMap is distributed under the [MIT License](LICENSE).
@@ -0,0 +1,169 @@
1
+ # DichromaticMap
2
+
3
+ [English user guide](docs/en/README.md) · [中文使用手册](docs/zh/README.md)
4
+
5
+ DichromaticMap provides a Python library and an interactive viewer for
6
+ layer-resolved FCC/BCC tilt grain-boundary dichromatic patterns. Use it to
7
+ inspect two overlaid grains, identify coincidence sites, measure crystal
8
+ vectors, count atoms in selected cells and explore common cells under uniform
9
+ strain.
10
+
11
+ ## Features
12
+
13
+ - FCC/BCC lattices with ⟨100⟩, ⟨110⟩, ⟨111⟩, ⟨112⟩ and custom integer tilt axes.
14
+ - Independent grain/layer visibility, grain-boundary side filtering and
15
+ display rotation.
16
+ - Same-layer exact coincidence-site lattice (CSL) detection and local near-pair
17
+ matching.
18
+ - Vector measurements in both grain coordinate frames, including axial
19
+ periodic images.
20
+ - Manual common cells with separate G1/G2 atom counts and optional uniform
21
+ strain fitting.
22
+ - Automatic homogeneous-strain common-cell search and PNG export.
23
+ - NumPy-based numerical functions usable independently of the viewer.
24
+
25
+ Coordinates and distances use the reference lattice constant a₀ as their unit.
26
+ Local matching preserves the atom positions. Strain operations impose a
27
+ geometric deformation; they do not perform atomic relaxation or minimize
28
+ elastic energy. A manually selected polygon alone does not establish crystal
29
+ periodicity.
30
+
31
+ ## Install and launch
32
+
33
+ Requires Python 3.10 or later. Download the project, open its root directory,
34
+ and install the library with its viewer:
35
+
36
+ ```bash
37
+ python -m pip install ".[gui]"
38
+ python -m dichromatic_map
39
+ ```
40
+
41
+ The viewer uses PySide6 and PyQtGraph. For numerical calculations only, install
42
+ with `python -m pip install .`; the numerical library requires only NumPy.
43
+
44
+ ```bash
45
+ python -m dichromatic_map --lattice BCC --axis 100
46
+ python -m dichromatic_map --axis "1 -1 3" --workers 4
47
+ python -m dichromatic_map --angle 22 --save pattern.png
48
+ python -m dichromatic_map --help
49
+ ```
50
+
51
+ `dichromatic-map` is an equivalent launch command. From the project root,
52
+ `python main.py` also launches the viewer.
53
+
54
+ ## GUI quick start
55
+
56
+ ![DichromaticMap viewer with its plot and controls](docs/images/gui-overview.png)
57
+
58
+ The example above shows FCC ⟨110⟩ at the Σ9 preset. The plot is on the left;
59
+ settings and results are in the scrollable **Controls** panel on the right.
60
+ Click section headers to expand them, and switch between the **ORIENTATION**
61
+ and **LAYERS** tabs at the top. Blue markers represent G1, orange outlines
62
+ represent G2, marker shapes distinguish axial layers, and gold outlines mark
63
+ same-layer exact coincidences.
64
+
65
+ 1. **Choose the grains.** In **ORIENTATION**, select **Structure** and
66
+ **Tilt / viewing axis**, then choose a **CSL preset** or enter a
67
+ **Misorientation**. For a custom axis, choose **Custom [h k l]**, enter an
68
+ integer triple such as `1 -1 3`, and click **Apply axis** or press Enter.
69
+ **Display rotation** turns the drawing without changing the grain geometry.
70
+ 2. **Choose visible layers.** Open **LAYERS** and toggle individual **G1 A**,
71
+ **G2 A**, etc. For a first selection, click **No layers**, then enable
72
+ **G1 A** and **G2 A**. Coincidence and local-pair markers require the layer to
73
+ be visible in both grains. Enable **Automatic common cell** to display an
74
+ available exact or strain-search cell; **Fit cell** frames it in the view.
75
+ 3. **Navigate.** Drag to pan and use the wheel to zoom. Under **VIEW /
76
+ PERFORMANCE → VIEW**, **Field size** selects a wider or narrower region;
77
+ **Center view** (`C`) returns to the origin at the current zoom. The
78
+ **PERFORMANCE** tab contains **CPU workers**.
79
+ 4. **Measure a vector.** In **GB / VECTOR**, click **Measure vector** (`V`),
80
+ then click two distinct visible atom positions, P1 and P2. Read the vector
81
+ annotation at the lower left of the plot. Same-grain picks show that grain's
82
+ coordinates; cross-grain picks show both G1 and G2 representations.
83
+ **P2 axial periodic image** selects an axial repeat for the second endpoint
84
+ without adding plotted atoms.
85
+ 5. **Define a boundary.** Click **Pick GB** (`R`) and select B1, then B2.
86
+ The side switches appear after the second pick; left/right are relative to
87
+ B1 → B2. Use `1` or `2` for the two complementary grain-side arrangements,
88
+ and `F` to show all sides again. Layer visibility settings still apply.
89
+ 6. **Select and count a cell.** Expand **MANUAL COMMON CELL**, click
90
+ **Pick 4 CSL vertices** (`M`), and select four gold sites of one layer in
91
+ clockwise or counterclockwise order around a convex cell. Use **Undo
92
+ vertex**, **Clear** or **Fit** as needed. The readout gives G1/G2 counts for
93
+ the complete selected cell, including portions outside the current view.
94
+ **Apply GB side visibility to counts** optionally restricts those counts
95
+ to the displayed grain sides.
96
+ 7. **Export the figure.** Scroll to **Export plot as PNG…**, choose a file
97
+ name and save. The PNG contains the plot with its current layers, rotation
98
+ and annotations; the controls are excluded.
99
+
100
+ Press `Esc` to stop picking while retaining existing selections. Pressing `R`
101
+ or `V` starts a fresh boundary or vector selection. Click near a visible atom
102
+ or eligible cell marker; background clicks do not create arbitrary vertices.
103
+
104
+ For inexact orientations, expand **NEAR-CSL**, select a **Method**, and click
105
+ **Enable Near-CSL**:
106
+
107
+ | Method | How to use it | Effect |
108
+ | --- | --- | --- |
109
+ | **Local matching · no bulk strain** | Adjust **Local pair distance**; inspect purple midpoint markers and use them for manual cell picks | Finds nearby same-layer pairs while preserving the atom positions |
110
+ | **Homogeneous strain + periodic cell** | Set **Max principal strain** and **Search index bound**, then choose a returned candidate | Automatically applies the first result, or the candidate you select, to both grains |
111
+
112
+ A manually selected local cell containing at least one near pair can also be
113
+ fitted with **Apply bulk strain to selected cell** in **MANUAL COMMON CELL**.
114
+ Set its strain and rotation limits before applying; **Restore original local
115
+ structure** returns to the original geometry. This operation has a separate
116
+ apply step from the automatic search.
117
+
118
+ For control-by-control instructions, selection rules, result interpretation
119
+ and troubleshooting, see the [English GUI guide](docs/en/README.md#gui-overview)
120
+ or [中文 GUI 使用指南](docs/zh/README.md#gui-overview). Detailed workflows cover
121
+ [vector measurements](docs/en/README.md#gui-vector),
122
+ [Near-CSL methods](docs/en/README.md#gui-near-csl), and
123
+ [manual cells and counts](docs/en/README.md#gui-manual-cell).
124
+
125
+ ## Python usage
126
+
127
+ ```python
128
+ from dichromatic_map import get_geometry, projected_columns, local_near_pairs
129
+
130
+ geometry = get_geometry("FCC", "110")
131
+ grain1 = projected_columns(12, 9, rotation_deg=11, lattice="FCC", axis="110")
132
+ grain2 = projected_columns(12, 9, rotation_deg=-11, lattice="FCC", axis="110")
133
+ pairs = local_near_pairs(grain1, grain2, distance=0.05)
134
+
135
+ print("Axial layers:", geometry.layer_count)
136
+ print("Near pairs:", len(pairs.layers))
137
+ print("Pair separations / a0:", pairs.distances)
138
+ ```
139
+
140
+ The grains above have a reference misorientation of 22°. Matching uses the
141
+ supplied projected columns and preserves their layer labels.
142
+
143
+ | Function exported by `dichromatic_map` | Purpose |
144
+ | --- | --- |
145
+ | `get_geometry` | Obtain planar geometry, axial layers and repeat distance |
146
+ | `projected_columns` | Generate a grain's projected columns in a rectangular region |
147
+ | `same_layer_coincidence_sites` | Locate same-layer coincidences within a specified tolerance |
148
+ | `local_near_pairs` | Find same-layer mutual nearest pairs within a distance threshold |
149
+ | `exact_csl_cell` | Obtain a layer-preserving common translation cell for a recognized commensurate angle |
150
+ | `count_cell_atoms` | Count atoms in complete shared or per-grain polygons |
151
+
152
+ ## Documentation
153
+
154
+ | Topic | English | 中文 |
155
+ | --- | --- | --- |
156
+ | Installation, viewer workflows and Python API | [User guide](docs/en/README.md) | [使用手册](docs/zh/README.md) |
157
+ | Algorithms, numerical conventions and implementation | [Implementation details](docs/en/development.md) | [开发细节](docs/zh/development.md) |
158
+
159
+ ## Contributing and support
160
+
161
+ Report problems through [GitHub Issues](https://github.com/Yazhuo-Liu/DichromaticMap/issues)
162
+ or [yliu3500@gatech.edu](mailto:yliu3500@gatech.edu). Contributions can be
163
+ submitted as a pull request or by email; see the [contribution guide](CONTRIBUTING.md).
164
+ This project is developed by volunteers and does not currently accept external
165
+ donations.
166
+
167
+ ## License
168
+
169
+ DichromaticMap is distributed under the [MIT License](LICENSE).