Skip to content

Commit

Permalink
Implement logging
Browse files Browse the repository at this point in the history
  • Loading branch information
bobleesj committed Jun 18, 2024
1 parent 64f53b8 commit 66ec6ce
Show file tree
Hide file tree
Showing 20 changed files with 129 additions and 185 deletions.
177 changes: 34 additions & 143 deletions example.ipynb

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

setup(
name="cifkit",
version="0.20",
version="0.21",
package_dir={"": "src"},
packages=find_packages(where="src"),
install_requires=[], # List your dependencies here
Expand Down
44 changes: 25 additions & 19 deletions src/cifkit/figures/polyhedron.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,15 @@ def generate_color_mapping(labels):
return color_map


def plot(points, vertex_labels, file_path, formula, is_displayed, output_dir=None):
def plot(
points,
vertex_labels,
file_path,
formula,
show_labels,
is_displayed,
output_dir=None,
):
"""
Generate and save a 3D plot of a molecular structure.
"""
Expand All @@ -46,7 +54,7 @@ def plot(points, vertex_labels, file_path, formula, is_displayed, output_dir=Non
central_atom_coord = points[-1]
central_atom_label = vertex_labels[-1]
# Coordination numbers
coordination_number = len(points) - 1
coordination_number = len(points) - 1

# Title
title = f"Formula: {formula}, Central atom: {central_atom_label}, CN: {coordination_number},\n{file_path}"
Expand All @@ -60,26 +68,26 @@ def plot(points, vertex_labels, file_path, formula, is_displayed, output_dir=Non
sphere = pv.Sphere(radius=radius, center=point)
plotter.add_mesh(sphere, color=label_colors[label])

# Add labels with index
indexed_label = (
f"{idx + 1}. {label}" # Creating a label with numbering
)
# Creating a label with numbering
indexed_label = f"{idx + 1}. {label}"
adjusted_point = point + [
0.3,
0.3,
0.3,
] # Offset to avoid overlapping with the sphere
if idx != len(points) - 1:
plotter.add_point_labels(
adjusted_point,
[indexed_label], # Use the indexed label
font_size=50,
text_color=label_colors[label],
always_visible=True,
shape=None,
margin=0,
reset_camera=False,
)

if show_labels:
if idx != len(points) - 1:
plotter.add_point_labels(
adjusted_point,
[indexed_label], # Use the indexed label
font_size=50,
text_color=label_colors[label],
always_visible=True,
shape=None,
margin=0,
reset_camera=False,
)

delaunay = Delaunay(points)
hull = ConvexHull(points)
Expand Down Expand Up @@ -144,5 +152,3 @@ def plot(points, vertex_labels, file_path, formula, is_displayed, output_dir=Non
"""
# Save the screenshot
plotter.screenshot(save_path)


31 changes: 25 additions & 6 deletions src/cifkit/models/cif.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@

# Polyhedron
import os
import logging
from cifkit.figures import polyhedron
from cifkit.utils.unit import round_dict_values
from cifkit.utils.log_messages import CifLog

# Parser .cif file
from cifkit.utils.cif_parser import (
Expand Down Expand Up @@ -96,12 +98,18 @@ def wrapper(self, *args, **kwargs):
return wrapper


class Cif:
def __init__(self, file_path: str, display=True) -> None:
# Global logging
logging.basicConfig(
level=logging.INFO,
format="%(asctime)s - %(levelname)s - %(message)s",
)


class Cif:
def __init__(self, file_path: str, logging_enabled=False) -> None:
self.file_path = file_path
if display:
print(f"Processing {self.file_path}")
self.logging_enabled = logging_enabled

"""Initialize the Cif object with the file path."""
self.file_name = os.path.basename(file_path)
self.file_name_without_ext = os.path.splitext(self.file_name)[0]
Expand All @@ -110,15 +118,22 @@ def __init__(self, file_path: str, display=True) -> None:
self._preprocess()
self._load_data()

def _log_info(self, message):
"""Log a formatted message if logging is enabled."""
if self.logging_enabled:
formatted_message = message.format(file_path=self.file_path)
logging.info(formatted_message)

def _preprocess(self):
"""Preprocess each .cif file and check any error."""
self._log_info(CifLog.PREPROCESSING.value)
check_unique_atom_site_labels(self.file_path)
remove_author_loop(self.file_path)
preprocess_label_element_loop_values(self.file_path)

def _load_data(self):
"""Load data from the .cif file and process it."""

self._log_info(CifLog.LOADING_DATA.value)
self._block = get_cif_block(self.file_path)
self._parse_cif_data()
self._generate_supercell()
Expand Down Expand Up @@ -162,6 +177,7 @@ def _generate_supercell(self):
"""

def compute_connections(self, cutoff_radius=10.0):
self._log_info(CifLog.COMPUTE_CONNECTIONS.value)
"""Compute nearest neighbor connections per site label."""
self.connections = get_site_connections(
[
Expand Down Expand Up @@ -403,7 +419,9 @@ def get_polyhedron_labels_by_CN_best_methods(
)

@ensure_connections
def plot_polyhedron(self, site_label, is_displayed=False, output_dir=None):
def plot_polyhedron(
self, site_label, show_labels=True, is_displayed=False, output_dir=None
):
coords, vertex_labels = get_polyhedron_coordinates_labels(
self.CN_connections_by_best_methods, site_label
)
Expand All @@ -412,6 +430,7 @@ def plot_polyhedron(self, site_label, is_displayed=False, output_dir=None):
vertex_labels,
self.file_path,
self.formula,
show_labels,
is_displayed,
output_dir,
)
7 changes: 7 additions & 0 deletions src/cifkit/utils/log_messages.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
from enum import Enum


class CifLog(Enum):
PREPROCESSING = "Preprocessing {file_path}"
LOADING_DATA = "Parsing .cif file and generating a supercell"
COMPUTE_CONNECTIONS = "Computing pair distances and coordination numbers"
3 changes: 1 addition & 2 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,8 @@
from cifkit.utils import cif_parser, folder
from cifkit import Cif
from cifkit import CifEnsemble
from cifkit.preprocessors import environment
from cifkit.coordination import composition
from cifkit.coordination import method, filter
from cifkit.coordination import filter

"""
CifEnsemble - histogram test
Expand Down
50 changes: 36 additions & 14 deletions tests/core/models/test_cif.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import os
import shutil
import pytest
import logging
from cifkit import Cif
from cifkit.utils.error_messages import CifParserError
from cifkit.utils.log_messages import CifLog
from cifkit.utils import folder


Expand Down Expand Up @@ -90,6 +92,38 @@ def test_lazy_loading(cif_URhIn):
assert cif_URhIn.connections is not None


"""
Test log
"""


@pytest.mark.fast
def test_init_log(caplog):
file_path = "tests/data/cif/URhIn.cif"
cif = Cif(file_path, logging_enabled=True)

with caplog.at_level(logging.INFO):
assert (
CifLog.PREPROCESSING.value.format(file_path=file_path)
in caplog.text
)

assert CifLog.LOADING_DATA.value in caplog.text

cif.compute_connections()
with caplog.at_level(logging.INFO):
assert CifLog.COMPUTE_CONNECTIONS.value in caplog.text


@pytest.mark.fast
def test_init_no_log(caplog):
file_path = "tests/data/cif/URhIn.cif"
Cif(file_path)

with caplog.at_level(logging.INFO):
assert caplog.text == ""


@pytest.mark.fast
def test_shortest_distance(cif_URhIn):
assert cif_URhIn.shortest_distance == 2.697
Expand Down Expand Up @@ -342,10 +376,6 @@ def test_plot_polyhedron_default_output_folder(cif_URhIn):
expected_output_dir = "tests/data/cif/polyhedrons"
output_file_path = os.path.join(expected_output_dir, "URhIn_In1.png")

# Ensure the directory exists
if not os.path.exists(expected_output_dir):
os.makedirs(expected_output_dir)

# Define the output file path
cif_URhIn.plot_polyhedron("In1")

Expand All @@ -359,13 +389,9 @@ def test_plot_polyhedron_with_output_folder_given(cif_URhIn):
expected_output_dir = "tests/data/cif/polyhedrons_user"
output_file_path = os.path.join(expected_output_dir, "URhIn_In1.png")

# Ensure the directory exists
if not os.path.exists(expected_output_dir):
os.makedirs(expected_output_dir)

# Define the output file path
cif_URhIn.plot_polyhedron(
"In1", is_displayed=True, output_dir="tests/data/cif/polyhedrons_user"
"In1", is_displayed=False, output_dir="tests/data/cif/polyhedrons_user"
)

assert os.path.exists(output_file_path)
Expand All @@ -378,16 +404,12 @@ def test_plot_polyhedrons(cif_ensemble_test):
# Define the directory to store the output
expected_output_dir = "tests/data/cif/ensemble_test/polyhedrons"
# Ensure the directory exists
if not os.path.exists(expected_output_dir):
os.makedirs(expected_output_dir)

cifs = cif_ensemble_test.cifs
for cif in cifs:
labels = cif.site_labels
print("Label from the cif object")
print(labels)
for label in labels:
cif.plot_polyhedron(label)
cif.plot_polyhedron(label, show_labels=True)

# Check the number of files
image_file_count = folder.get_file_count(expected_output_dir, ".png")
Expand Down
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 66ec6ce

Please sign in to comment.