Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 10 additions & 20 deletions .github/workflows/code-quality.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
name: Code quality
name: Code Quality

on: [push, pull_request]
on:
push:
branches: [master, main, development]
pull_request:
branches: [master, main, development]

jobs:
build:
Expand All @@ -18,27 +22,13 @@ jobs:
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install black pylint pytest coverage coveralls
pip install -r requirements/requirements.txt

- name: Run black
continue-on-error: true
run: black --check .
pip install black pylint

- name: Run lint with pylint
continue-on-error: true
run: |
find qDNA tools -type f -name "*.py" ! -name "__init__.py" | xargs pylint

- name: Run tests with pytest
run: python -m pytest
pylint --rcfile=.pylintrc $(git ls-files 'qDNA/*.py')

- name: Run tests with coverage
run: |
coverage run -m pytest

- name: Upload coverage to Coveralls
- name: Run black
continue-on-error: true
env:
COVERALLS_REPO_TOKEN: ${{ secrets.COVERALLS_REPO_TOKEN }}
run: coveralls
run: black --check .
3 changes: 0 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,6 @@ docs/_templates/
__pycache__
.pytest_cache/

# created for pylint
.pylintrc

# created by coverage
.coverage
htmlcov/
Expand Down
57 changes: 57 additions & 0 deletions .pylintrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
[MASTER]
ignore=tests
jobs=1
load-plugins=
extension-pkg-whitelist=

[MESSAGES CONTROL]
disable=
C0114, # missing-module-docstring
C0116, # missing-function-docstring
C0301, # line-too-long
R0903, # too-few-public-methods
R0801, # duplicate-code
W0511, # fixme
R0902, # too-many-instance-attributes
R0912, # too-many-branches
R0913, # too-many-arguments
R0914, # too-many-locals
R0915, # too-many-statements
R0917, # too-many-positional-arguments
R0401, # cyclic-import
E0401, # import-error

[REPORTS]
output-format=colorized
reports=no
score=yes

[BASIC]
good-names=
bad-names=
variable-rgx=.*
attr-rgx=.*
argument-rgx=.*
method-rgx=.*
module-rgx=.*
class-rgx=.*
function-rgx=.*


[TYPECHECK]
ignored-modules=
ignored-classes=optparse.Values,thread._local,_thread._local
generated-members=numpy.*,torch.*

[FORMAT]
max-line-length=120
indent-string=' '

[DESIGN]
max-args=7
max-attributes=10
max-locals=20
max-returns=6
max-branches=12
max-statements=50
max-line-length=100
4 changes: 1 addition & 3 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,7 @@
# Do not add full module names
add_module_names = False

numpydoc_show_inherited_class_members = (
False # Show inherited class members in the documentation
)
numpydoc_show_inherited_class_members = False # Show inherited class members in the documentation
numpydoc_show_property_with_doc = (
False # Show properties with documentation in the class documentation
)
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,6 @@ requires = ["setuptools>=61.0", "wheel"]
build-backend = "setuptools.build_meta"

[tool.black]
line-length = 120
line-length = 100
target-version = ['py311']
skip-string-normalization = true
2 changes: 0 additions & 2 deletions qDNA/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,3 @@
from .evaluation import *
from .visualization import *
from .legacy import *

# some nice comment...
8 changes: 2 additions & 6 deletions qDNA/environment/observables.py
Original file line number Diff line number Diff line change
Expand Up @@ -124,15 +124,11 @@ def get_eh_observable(tb_basis, particle, start_state, end_state):

# Create the electron observable
if particle == "electron":
eh_observable = np.kron(
get_observable(tb_basis, start_state, end_state), np.eye(num_sites)
)
eh_observable = np.kron(get_observable(tb_basis, start_state, end_state), np.eye(num_sites))

# Create the hole observable
elif particle == "hole":
eh_observable = np.kron(
np.eye(num_sites), get_observable(tb_basis, start_state, end_state)
)
eh_observable = np.kron(np.eye(num_sites), get_observable(tb_basis, start_state, end_state))

# Create the exciton observable
elif particle == "exciton":
Expand Down
6 changes: 1 addition & 5 deletions qDNA/environment/therm_ops.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,11 +106,7 @@ def get_loc_therm_op(eigv, eigs, unique, site_m, relaxation, matrix_dim):
omega_i, omega_j = eigv[i], eigv[j]
state_i, state_j = eigs[:, i], eigs[:, j]
if omega_i - omega_j == unique:
op += (
state_j[site_m].conjugate()
* state_i[site_m]
* np.outer(state_j, state_i)
)
op += state_j[site_m].conjugate() * state_i[site_m] * np.outer(state_j, state_i)
if relaxation:
op = add_groundstate(op)

Expand Down
16 changes: 4 additions & 12 deletions qDNA/environment/therm_rates.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,7 @@ def ohmic_spectral_density(omega, cutoff_freq, reorg_energy, exponent):
"""
if omega <= 0:
return 0
return (np.pi * reorg_energy * omega**exponent / cutoff_freq) * np.exp(
-omega / cutoff_freq
)
return (np.pi * reorg_energy * omega**exponent / cutoff_freq) * np.exp(-omega / cutoff_freq)


# ----------------------------------------------------------------------
Expand All @@ -76,9 +74,7 @@ def bose_einstein_distrib(omega, temperature):
float
Bose-Einstein distribution.
"""
assert (
temperature != 0 and omega != 0
), "Temperature and frequency must be non-zero."
assert temperature != 0 and omega != 0, "Temperature and frequency must be non-zero."
return 1.0 / (np.exp(c.hbar * omega * 1e12 / (c.k * temperature)) - 1)


Expand Down Expand Up @@ -142,12 +138,8 @@ def rate_constant_redfield(
spec_omega_ji = debye_spectral_density(-omega, cutoff_freq, reorg_energy)

elif spectral_density == "ohmic":
spec_omega_ij = ohmic_spectral_density(
omega, cutoff_freq, reorg_energy, exponent
)
spec_omega_ji = ohmic_spectral_density(
-omega, cutoff_freq, reorg_energy, exponent
)
spec_omega_ij = ohmic_spectral_density(omega, cutoff_freq, reorg_energy, exponent)
spec_omega_ji = ohmic_spectral_density(-omega, cutoff_freq, reorg_energy, exponent)

n_omega_ij = bose_einstein_distrib(omega, temperature)
n_omega_ji = bose_einstein_distrib(-omega, temperature)
Expand Down
21 changes: 5 additions & 16 deletions qDNA/evaluation/evaluation.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,9 +78,7 @@ def calc_lifetime(self):
start_time = time.time()
gs_pop = self.get_groundstate_pop()["groundstate"]
try:
_, index = next(
(val, i) for i, val in enumerate(gs_pop) if val >= 1 - 1 / np.e
)
_, index = next((val, i) for i, val in enumerate(gs_pop) if val >= 1 - 1 / np.e)
self.lifetime = self.times[index]
if self.t_unit == "ps":
self.lifetime *= 1000
Expand Down Expand Up @@ -136,9 +134,7 @@ def calc_charge_separation(self, average=True):

# Calculate the electron-hole distance
distance_list = 3.4 * get_eh_distance(self.eh_basis)
self.charge_separation = [
distance_list @ dm.diag()[1:] for dm in self.get_result()
]
self.charge_separation = [distance_list @ dm.diag()[1:] for dm in self.get_result()]
if average:
self.charge_separation = np.mean(self.charge_separation).real
return self.charge_separation
Expand Down Expand Up @@ -203,9 +199,7 @@ def calc_backbone_transfer(self, average=True):
If the backbone attribute is not set, indicating the model is not a Fishbone model.
"""

assert (
self.backbone
), "Backbone population can only be calculated for Fishbone models"
assert self.backbone, "Backbone population can only be calculated for Fishbone models"
self._back_to_unitary()

upper_backbone_sites, lower_backbone_sites = [], []
Expand Down Expand Up @@ -250,9 +244,7 @@ def calc_exciton_transfer(self, average=True):
assert (
self.double_stranded
), "Exciton transfer can only be calculated for double-stranded models"
assert (
not self.backbone
), "Exciton transfer can only be calculated for non-backbone models"
assert not self.backbone, "Exciton transfer can only be calculated for non-backbone models"
self._back_to_unitary()

upper_sites, lower_sites = [], []
Expand Down Expand Up @@ -334,10 +326,7 @@ def __init__(self, evaluation_list, **kwargs):
"observables", ["lifetime", "charge_separation", "dipole_moment"]
)

self.args = [
(i, self.observables, self.evaluation_list)
for i in range(self.num_sequences)
]
self.args = [(i, self.observables, self.evaluation_list) for i in range(self.num_sequences)]

def calc_results(self, filepath=None, save=True):
"""
Expand Down
8 changes: 2 additions & 6 deletions qDNA/gui/advanced_frame.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,15 +54,11 @@ def __init__(self, master):
super().__init__(master)

# help label
self.help_label = ctk.CTkLabel(
self, text="Help", font=ctk.CTkFont(size=15, weight="bold")
)
self.help_label = ctk.CTkLabel(self, text="Help", font=ctk.CTkFont(size=15, weight="bold"))
self.help_label.grid(row=0, column=0, pady=10, padx=10)

# github link
self.open_github_button = ctk.CTkButton(
self, text="GitHub", command=master.open_github
)
self.open_github_button = ctk.CTkButton(self, text="GitHub", command=master.open_github)
self.open_github_button.grid(row=1, column=0, pady=10, padx=10)

# documentation link
Expand Down
21 changes: 5 additions & 16 deletions qDNA/gui/fasta_window.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,9 +98,7 @@ def __init__(self, master):
text="Calculate Exciton Population",
variable=self.exciton_transfer_var,
)
self.exciton_transfer_checkbox.grid(
row=3, column=1, padx=10, pady=10, sticky="w"
)
self.exciton_transfer_checkbox.grid(row=3, column=1, padx=10, pady=10, sticky="w")

# --------------------------------------------------------------

Expand All @@ -113,12 +111,8 @@ def __init__(self, master):
)

# submit button
self.submit_button = ctk.CTkButton(
self, text="Submit", command=self.process_files
)
self.submit_button.grid(
row=5, column=0, columnspan=2, padx=10, pady=10, sticky="ew"
)
self.submit_button = ctk.CTkButton(self, text="Submit", command=self.process_files)
self.submit_button.grid(row=5, column=0, columnspan=2, padx=10, pady=10, sticky="ew")

# console frame
self.scrollable_console_frame = ScrollableConsoleFrame(self)
Expand Down Expand Up @@ -183,10 +177,7 @@ def estimate_comp_time(self):
for upper_strand in self.upper_strands:
comp_time += comp_time_dict[self.tb_model_name][len(upper_strand) - 2]
comp_time /= min(self.num_cpu, len(self.upper_strands))
print(
f"Estimated Computation Time {comp_time}"
+ f"\nUsing {self.num_cpu} kernels"
)
print(f"Estimated Computation Time {comp_time}" + f"\nUsing {self.num_cpu} kernels")

# ------------------------------------------------------------------

Expand All @@ -213,9 +204,7 @@ def process_files(self):
tb_sites = get_tb_sites(upper_strand, tb_model_name=self.tb_model_name)
tb_sites_list.append(tb_sites)

evaluation_list = [
Evaluation(tb_sites, **self.kwargs) for tb_sites in tb_sites_list
]
evaluation_list = [Evaluation(tb_sites, **self.kwargs) for tb_sites in tb_sites_list]
parallel = EvaluationParallel(evaluation_list, observables=observables)
results = parallel.calc_results(
filepath=os.path.join(DATA_DIR, "gui", "result.json"), save=True
Expand Down
8 changes: 2 additions & 6 deletions qDNA/gui/gui_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,9 @@

def change_state_all_widgets(frame, state):
for widget in frame.winfo_children():
if isinstance(
widget, ctk.CTkBaseClass
): # Check if the widget is a customtkinter widget
if isinstance(widget, ctk.CTkBaseClass): # Check if the widget is a customtkinter widget
widget.configure(state=state)
elif isinstance(
widget, ctk.CTkFrame
): # Recursively disable widgets in nested frames
elif isinstance(widget, ctk.CTkFrame): # Recursively disable widgets in nested frames
change_state_all_widgets(widget, state)


Expand Down
8 changes: 2 additions & 6 deletions qDNA/gui/initial_frame.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,7 @@ def __init__(self, master):
# --------------------------------------------------------------

# upper strand label
self.upper_strand_label = ctk.CTkLabel(
self, text="Upper DNA Strand \n(5'-3' direction):"
)
self.upper_strand_label = ctk.CTkLabel(self, text="Upper DNA Strand \n(5'-3' direction):")
self.upper_strand_label.grid(row=2, column=0, pady=0, padx=10)

# upper strand entry
Expand All @@ -50,9 +48,7 @@ def __init__(self, master):
# --------------------------------------------------------------

# lower strand label
self.lower_strand_label = ctk.CTkLabel(
self, text="Lower DNA Strand \n(3'-5' direction):"
)
self.lower_strand_label = ctk.CTkLabel(self, text="Lower DNA Strand \n(3'-5' direction):")
self.lower_strand_label.grid(row=4, column=0, pady=0, padx=10)

# lower strand entry
Expand Down
8 changes: 2 additions & 6 deletions qDNA/gui/lind_diss_frame.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,16 +74,12 @@ def __init__(self, master):

# local thermalization checkbox
self.loc_therm_var = ctk.BooleanVar(value=self.defaults["loc_therm"])
self.loc_therm_check = ctk.CTkCheckBox(
self, text="Local", variable=self.loc_therm_var
)
self.loc_therm_check = ctk.CTkCheckBox(self, text="Local", variable=self.loc_therm_var)
self.loc_therm_check.grid(row=6, column=0, padx=10, pady=10)

# global thermalization checkbox
self.glob_therm_var = ctk.BooleanVar(value=self.defaults["glob_therm"])
self.glob_therm_check = ctk.CTkCheckBox(
self, text="Global", variable=self.glob_therm_var
)
self.glob_therm_check = ctk.CTkCheckBox(self, text="Global", variable=self.glob_therm_var)
self.glob_therm_check.grid(row=6, column=1, padx=10, pady=10)

# --------------------------------------------------------------
Expand Down
Loading