Skip to content

Commit aec97d8

Browse files
authored
Use raise instead of log_and_raise function (#247)
* revert: use `raise <error>` instead of `log_and_raise` function Signed-off-by: Josh Loecker <joshloecker@icloud.com> * chore: remove non-existant import --------- Signed-off-by: Josh Loecker <joshloecker@icloud.com>
1 parent d9601c7 commit aec97d8

11 files changed

Lines changed: 155 additions & 487 deletions

main/como/cluster_rnaseq.py

Lines changed: 23 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
import numpy as np
99

1010
from como.data_types import LogLevel
11-
from como.utils import log_and_raise_error, stringlist_to_list
11+
from como.utils import stringlist_to_list
1212

1313

1414
@dataclass
@@ -35,77 +35,43 @@ def __post_init__(self): # noqa: C901, ignore too complex
3535
self.seed = np.random.randint(0, 100_000)
3636

3737
if (isdigit(self.min_active_count) and int(self.min_active_count) < 0) or self.min_active_count != "default":
38-
log_and_raise_error(
39-
"min_active_count must be either 'default' or an integer > 0",
40-
error=ValueError,
41-
level=LogLevel.ERROR,
42-
)
38+
raise ValueError("min_active_count must be either 'default' or an integer > 0")
4339

4440
if (isdigit(self.quantile) and 0 > int(self.quantile) > 100) or self.quantile != "default":
45-
log_and_raise_error(
46-
"quantile must be either 'default' or an integer between 0 and 100",
47-
error=ValueError,
48-
level=LogLevel.ERROR,
49-
)
41+
raise ValueError("quantile must be either 'default' or an integer between 0 and 100")
5042

5143
if (isdigit(self.replicate_ratio) and 0 > self.replicate_ratio > 1.0) or self.replicate_ratio != "default":
52-
log_and_raise_error(
53-
"--rep-ratio must be either 'default' or a float between 0 and 1",
54-
error=ValueError,
55-
level=LogLevel.ERROR,
56-
)
44+
raise ValueError("--rep-ratio must be either 'default' or a float between 0 and 1")
5745

5846
if (isdigit(self.batch_ratio) and 0 > self.batch_ratio > 1.0) or self.batch_ratio != "default":
59-
log_and_raise_error(
60-
"--batch-ratio must be either 'default' or a float between 0 and 1",
61-
error=ValueError,
62-
level=LogLevel.ERROR,
63-
)
47+
raise ValueError("--batch-ratio must be either 'default' or a float between 0 and 1")
6448

6549
if self.filtering_technique.lower() not in {"quantile", "tpm", "cpm", "zfpkm"}:
66-
log_and_raise_error(
67-
"--technique must be either 'quantile', 'tpm', 'cpm', 'zfpkm'",
68-
error=ValueError,
69-
level=LogLevel.ERROR,
70-
)
50+
raise ValueError("--technique must be either 'quantile', 'tpm', 'cpm', 'zfpkm'")
7151

7252
if self.filtering_technique.lower() == "tpm":
7353
self.filtering_technique = "quantile"
7454

7555
if self.cluster_algorithm.lower() not in {"mca", "umap"}:
76-
log_and_raise_error(
77-
"--clust_algo must be either 'mca', 'umap'",
78-
error=ValueError,
79-
level=LogLevel.ERROR,
80-
)
56+
raise ValueError("--clust_algo must be either 'mca', 'umap'")
8157

8258
if 0 > self.min_distance > 1.0:
83-
log_and_raise_error(
84-
"--min_dist must be a float between 0 and 1",
85-
error=ValueError,
86-
level=LogLevel.ERROR,
87-
)
88-
89-
if (isdigit(self.num_replicate_neighbors) and self.num_replicate_neighbors < 1) or self.num_replicate_neighbors != "default":
90-
log_and_raise_error(
91-
"--n-neighbors-rep must be either 'default' or an integer > 1",
92-
error=ValueError,
93-
level=LogLevel.ERROR,
94-
)
95-
96-
if (isdigit(self.num_batch_neighbors) and self.num_batch_neighbors < 1) or self.num_batch_neighbors != "default":
97-
log_and_raise_error(
98-
"--n-neighbors-batch must be either 'default' or an integer > 1",
99-
error=ValueError,
100-
level=LogLevel.ERROR,
101-
)
102-
103-
if (isdigit(self.num_context_neighbors) and self.num_context_neighbors < 1) or self.num_context_neighbors != "default":
104-
log_and_raise_error(
105-
"--n-neighbors-context must be either 'default' or an integer > 1",
106-
error=ValueError,
107-
level=LogLevel.ERROR,
108-
)
59+
raise ValueError("--min_dist must be a float between 0 and 1")
60+
61+
if (
62+
isdigit(self.num_replicate_neighbors) and self.num_replicate_neighbors < 1
63+
) or self.num_replicate_neighbors != "default":
64+
raise ValueError("--n-neighbors-rep must be either 'default' or an integer > 1")
65+
66+
if (
67+
isdigit(self.num_batch_neighbors) and self.num_batch_neighbors < 1
68+
) or self.num_batch_neighbors != "default":
69+
raise ValueError("--n-neighbors-batch must be either 'default' or an integer > 1")
70+
71+
if (
72+
isdigit(self.num_context_neighbors) and self.num_context_neighbors < 1
73+
) or self.num_context_neighbors != "default":
74+
raise ValueError("--n-neighbors-context must be either 'default' or an integer > 1")
10975

11076

11177
def _parse_args() -> _Arguments:

main/como/combine_distributions.py

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
)
2121
from como.pipelines.identifier import convert
2222
from como.utils import LogLevel, get_missing_gene_data, log_and_raise_error, num_columns
23+
from como.utils import num_columns
2324

2425

2526
def _combine_z_distribution_for_batch(
@@ -191,10 +192,9 @@ def _combine_z_distribution_for_context(
191192
for res in zscore_results:
192193
matrix = res.z_score_matrix.copy()
193194
if len(matrix.columns) > 1:
194-
log_and_raise_error(
195-
f"Expected a single column for combined z-score dataframe for data '{res.type.value.lower()}'. Got '{len(matrix.columns)}' columns",
196-
error=ValueError,
197-
level=LogLevel.ERROR,
195+
raise ValueError(
196+
f"Expected a single column for combined z-score dataframe for data '{res.type.value.lower()}'. "
197+
f"Got '{len(matrix.columns)}' columns"
198198
)
199199

200200
matrix.columns = [res.type.value.lower()]
@@ -327,10 +327,9 @@ async def _begin_combining_distributions(
327327
else ""
328328
)
329329
if not index_name:
330-
log_and_raise_error(
331-
f"Unable to find common gene identifier across batches for source '{source.value}' in context '{context_name}'",
332-
error=ValueError,
333-
level=LogLevel.ERROR,
330+
raise ValueError(
331+
f"Unable to find common gene identifier across batches for source "
332+
f"'{source.value}' in context '{context_name}'"
334333
)
335334
merged_batch_results = pd.concat(batch_results, axis="columns")
336335
merged_batch_results.index.name = index_name

main/como/create_context_specific_model.py

Lines changed: 36 additions & 104 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
Solver,
3535
_BoundaryReactions,
3636
)
37-
from como.utils import log_and_raise_error, set_up_logging, split_gene_expression_data
37+
from como.utils import set_up_logging, split_gene_expression_data
3838

3939

4040
def _reaction_indices_to_ids(
@@ -235,10 +235,8 @@ def _build_with_fastcore(
235235
)
236236
s_matrix = cast(npt.NDArray[np.floating], cobra.util.create_stoichiometric_matrix(model=model))
237237
if lower_bounds.shape[0] != upper_bounds.shape[0] != s_matrix.shape[1]:
238-
log_and_raise_error(
239-
message="Lower bounds, upper bounds, and stoichiometric matrix must have the same number of reactions.",
240-
error=ValueError,
241-
level=LogLevel.ERROR,
238+
raise ValueError(
239+
"Lower bounds, upper bounds, and stoichiometric matrix must have the same number of reactions."
242240
)
243241
logger.debug("Creating feasible model")
244242
_, cobra_model = _feasibility_test(cobra_model, "other")
@@ -301,7 +299,7 @@ def _build_with_tinit(
301299
solver,
302300
idx_force,
303301
) -> Model:
304-
log_and_raise_error("tINIT is not yet implemented.", error=NotImplementedError, level=LogLevel.CRITICAL)
302+
raise NotImplementedError("tINIT is not yet implemented.")
305303
model = reference_model
306304
properties = tINITProperties(
307305
reactions_scores=expr_vector,
@@ -331,7 +329,7 @@ def _build_with_corda(
331329
:param neg_expression_threshold: Reactions expressed below this value will be placed in "negative" expression bin
332330
:param high_expression_threshold: Reactions expressed above this value will be placed in the "high" expression bin
333331
"""
334-
log_and_raise_error("CORDA is not yet implemented", error=NotImplementedError, level=LogLevel.CRITICAL)
332+
raise NotImplementedError("CORDA is not yet implemented")
335333
model = reference_model
336334
properties = CORDAProperties(
337335
high_conf_rx=[],
@@ -450,12 +448,7 @@ def _read_reference_model(filepath: Path) -> cobra.Model:
450448
case ".json":
451449
reference_model = cobra.io.load_json_model(filepath)
452450
case _:
453-
log_and_raise_error(
454-
f"Reference model format must be .xml, .mat, or .json; found '{filepath.suffix}'",
455-
error=ValueError,
456-
level=LogLevel.ERROR,
457-
)
458-
return reference_model
451+
raise ValueError(f"Reference model format must be .xml, .mat, or .json; found '{filepath.suffix}'")
459452

460453

461454
async def _build_model(
@@ -523,28 +516,16 @@ async def _build_model(
523516
ref_ub[i] = float(rxn.upper_bound)
524517
reaction_ids.append(rxn.id)
525518
if ref_lb.shape[0] != ref_ub.shape[0] != len(reaction_ids):
526-
log_and_raise_error(
527-
message=(
528-
"Lower bounds, upper bounds, and reaction IDs must have the same length.\n"
529-
f"Number of reactions: {len(reaction_ids)}\n"
530-
f"Number of upper bounds: {ref_ub.shape[0]}\n"
531-
f"Number of lower bounds: {ref_lb.shape[0]}"
532-
),
533-
error=ValueError,
534-
level=LogLevel.ERROR,
519+
raise ValueError(
520+
"Lower bounds, upper bounds, and reaction IDs must have the same length.\n"
521+
f"Number of reactions: {len(reaction_ids)}\n"
522+
f"Number of upper bounds: {ref_ub.shape[0]}\n"
523+
f"Number of lower bounds: {ref_lb.shape[0]}"
535524
)
536525
if np.isnan(ref_lb).any():
537-
log_and_raise_error(
538-
message="Lower bounds contains unfilled values!",
539-
error=ValueError,
540-
level=LogLevel.ERROR,
541-
)
526+
raise ValueError("Lower bounds contains unfilled values!")
542527
if np.isnan(ref_ub).any():
543-
log_and_raise_error(
544-
message="Upper bounds contains unfilled values!",
545-
error=ValueError,
546-
level=LogLevel.ERROR,
547-
)
528+
raise ValueError("Upper bounds contains unfilled values!")
548529

549530
# get expressed reactions
550531
reaction_expression: collections.OrderedDict[str, int] = await _map_expression_to_reaction(
@@ -635,14 +616,10 @@ async def _build_model(
635616
idx_force=force_reaction_indices,
636617
)
637618
else:
638-
log_and_raise_error(
639-
(
640-
f"Reconstruction algorithm must be {Algorithm.GIMME.value}, "
641-
f"{Algorithm.FASTCORE.value}, {Algorithm.IMAT.value}, or {Algorithm.TINIT.value}. "
642-
f"Got: {recon_algorithm.value}"
643-
),
644-
error=ValueError,
645-
level=LogLevel.ERROR,
619+
raise ValueError(
620+
f"Reconstruction algorithm must be {Algorithm.GIMME.value}, "
621+
f"{Algorithm.FASTCORE.value}, {Algorithm.IMAT.value}, or {Algorithm.TINIT.value}. "
622+
f"Got: {recon_algorithm.value}"
646623
)
647624

648625
inconsistent_and_infeasible_reactions: pd.DataFrame = pd.concat(
@@ -690,13 +667,9 @@ async def _collect_boundary_reactions(path: Path) -> _BoundaryReactions:
690667
"minimum reaction rate",
691668
"maximum reaction rate",
692669
]:
693-
log_and_raise_error(
694-
(
695-
f"Boundary reactions file must have columns named 'Reaction', 'Abbreviation', 'Compartment', "
696-
f"'Minimum Reaction Rate', and 'Maximum Reaction Rate'. Found: {column}"
697-
),
698-
error=ValueError,
699-
level=LogLevel.ERROR,
670+
raise ValueError(
671+
f"Boundary reactions file must have columns named 'Reaction', 'Abbreviation', 'Compartment', "
672+
f"'Minimum Reaction Rate', and 'Maximum Reaction Rate'. Found: {column}"
700673
)
701674

702675
reactions: list[str] = [""] * len(df)
@@ -707,11 +680,7 @@ async def _collect_boundary_reactions(path: Path) -> _BoundaryReactions:
707680
for i in range(len(boundary_type)):
708681
boundary: str = boundary_type[i].lower()
709682
if boundary not in boundary_map:
710-
log_and_raise_error(
711-
f"Boundary reaction type must be 'Exchange', 'Demand', or 'Sink'. Found: {boundary}",
712-
error=ValueError,
713-
level=LogLevel.ERROR,
714-
)
683+
raise ValueError(f"Boundary reaction type must be 'Exchange', 'Demand', or 'Sink'. Found: {boundary}")
715684

716685
shorthand_compartment = CobraCompartments.get_shorthand(reaction_compartment[i])
717686
reactions[i] = f"{boundary_map.get(boundary)}_{reaction_abbreviation[i]}[{shorthand_compartment}]"
@@ -741,10 +710,8 @@ async def _write_model_to_disk(
741710
elif path.suffix in xml_suffix:
742711
tasks.add(asyncio.to_thread(cobra.io.write_sbml_model, model=model, filename=path))
743712
else:
744-
log_and_raise_error(
745-
f"Invalid output model filetype. Should be one of .xml, .sbml, .mat, or .json. Got '{path.suffix}'",
746-
error=ValueError,
747-
level=LogLevel.ERROR,
713+
raise ValueError(
714+
f"Invalid output model filetype. Should be one of .xml, .sbml, .mat, or .json. Got '{path.suffix}'"
748715
)
749716
logger.success(f"Will save metabolic model for context '{context_name}' to: '{path}'")
750717
await asyncio.gather(*tasks)
@@ -809,43 +776,19 @@ async def create_context_specific_model( # noqa: C901
809776
output_model_filepaths = [output_model_filepaths] if isinstance(output_model_filepaths, Path) else output_model_filepaths
810777

811778
if not reference_model.exists():
812-
log_and_raise_error(
813-
f"Reference model not found at {reference_model}",
814-
error=FileNotFoundError,
815-
level=LogLevel.ERROR,
816-
)
779+
raise FileNotFoundError(f"Reference model not found at {reference_model}")
817780
if not active_genes_filepath.exists():
818-
log_and_raise_error(
819-
f"Active genes file not found at {active_genes_filepath}",
820-
error=FileNotFoundError,
821-
level=LogLevel.ERROR,
822-
)
781+
raise FileNotFoundError(f"Active genes file not found at {active_genes_filepath}")
823782
if algorithm == Algorithm.FASTCORE and not output_fastcore_expression_index_filepath:
824-
log_and_raise_error(
825-
"The fastcore expression index output filepath must be provided",
826-
error=ValueError,
827-
level=LogLevel.ERROR,
828-
)
783+
raise ValueError("The fastcore expression index output filepath must be provided")
829784
if boundary_rxns_filepath and not boundary_rxns_filepath.exists():
830-
log_and_raise_error(
831-
f"Boundary reactions file not found at {boundary_rxns_filepath}",
832-
error=FileNotFoundError,
833-
level=LogLevel.ERROR,
834-
)
785+
raise FileNotFoundError(f"Boundary reactions file not found at {boundary_rxns_filepath}")
835786

836787
if algorithm not in Algorithm:
837-
log_and_raise_error(
838-
f"Algorithm {algorithm} not supported. Use one of {', '.join(a.value for a in Algorithm)}",
839-
error=ValueError,
840-
level=LogLevel.ERROR,
841-
)
788+
raise ValueError(f"Algorithm {algorithm} not supported. Use one of {', '.join(a.value for a in Algorithm)}")
842789

843790
if solver not in Solver:
844-
log_and_raise_error(
845-
f"Solver '{solver}' not supported. Use one of {', '.join(s.value for s in Solver)}",
846-
error=ValueError,
847-
level=LogLevel.ERROR,
848-
)
791+
raise ValueError(f"Solver '{solver}' not supported. Use one of {', '.join(s.value for s in Solver)}")
849792

850793
mat_suffix, json_suffix, xml_suffix = {".mat"}, {".json"}, {".sbml", ".xml"}
851794
if any(path.suffix not in {*mat_suffix, *json_suffix, *xml_suffix} for path in output_model_filepaths):
@@ -858,6 +801,7 @@ async def create_context_specific_model( # noqa: C901
858801
f"Invalid output filetype. Should be 'xml', 'sbml', 'mat', or 'json'. Got:\n{invalid_suffix}'",
859802
error=ValueError,
860803
level=LogLevel.ERROR,
804+
raise ValueError(f"Invalid output filetype. Should be 'xml', 'sbml', 'mat', or 'json'. Got:\n{invalid_suffix}'")
861805
)
862806

863807
boundary_reactions = None
@@ -869,23 +813,15 @@ async def create_context_specific_model( # noqa: C901
869813
exclude_rxns_filepath: Path = Path(exclude_rxns_filepath)
870814
df = await _create_df(exclude_rxns_filepath)
871815
if "abbreviation" not in df.columns:
872-
log_and_raise_error(
873-
"The exclude reactions file should have a single column with a header named Abbreviation",
874-
error=ValueError,
875-
level=LogLevel.ERROR,
876-
)
816+
raise ValueError("The exclude reactions file should have a single column with a header named Abbreviation")
877817
exclude_rxns = df["abbreviation"].tolist()
878818

879819
force_rxns: list[str] = []
880820
if force_rxns_filepath:
881821
force_rxns_filepath: Path = Path(force_rxns_filepath)
882822
df = await _create_df(force_rxns_filepath, lowercase_col_names=True)
883823
if "abbreviation" not in df.columns:
884-
log_and_raise_error(
885-
"The force reactions file should have a single column with a header named Abbreviation",
886-
error=ValueError,
887-
level=LogLevel.ERROR,
888-
)
824+
raise ValueError("The force reactions file should have a single column with a header named Abbreviation")
889825
force_rxns = df["abbreviation"].tolist()
890826

891827
# Test that gurobi is using a valid license file
@@ -894,14 +830,10 @@ async def create_context_specific_model( # noqa: C901
894830

895831
gurobi_present = find_spec("gurobipy")
896832
if not gurobi_present:
897-
log_and_raise_error(
898-
message=(
899-
"The gurobi solver requires the gurobipy package to be installed. "
900-
"Please install gurobipy and try again. "
901-
"This can be done by installing the 'gurobi' optional dependency."
902-
),
903-
error=ImportError,
904-
level=LogLevel.ERROR,
833+
raise ImportError(
834+
"The gurobi solver requires the gurobipy package to be installed. "
835+
"Please install gurobipy and try again. "
836+
"This can be done by installing the 'gurobi' optional dependency."
905837
)
906838

907839
if not Path(f"{os.environ['HOME']}/gurobi.lic").exists():

0 commit comments

Comments
 (0)