open-fdd 0.1.1__py3-none-any.whl → 0.1.4__py3-none-any.whl
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.
- open_fdd/air_handling_unit/faults/__init__.py +2253 -0
- open_fdd/air_handling_unit/faults/fault_condition.py +38 -18
- open_fdd/air_handling_unit/faults/fault_condition_eight.py +91 -31
- open_fdd/air_handling_unit/faults/fault_condition_eleven.py +93 -35
- open_fdd/air_handling_unit/faults/fault_condition_fifteen.py +111 -49
- open_fdd/air_handling_unit/faults/fault_condition_five.py +89 -34
- open_fdd/air_handling_unit/faults/fault_condition_four.py +136 -61
- open_fdd/air_handling_unit/faults/fault_condition_fourteen.py +103 -40
- open_fdd/air_handling_unit/faults/fault_condition_nine.py +95 -35
- open_fdd/air_handling_unit/faults/fault_condition_one.py +83 -31
- open_fdd/air_handling_unit/faults/fault_condition_seven.py +85 -26
- open_fdd/air_handling_unit/faults/fault_condition_six.py +134 -73
- open_fdd/air_handling_unit/faults/fault_condition_ten.py +91 -30
- open_fdd/air_handling_unit/faults/fault_condition_thirteen.py +95 -34
- open_fdd/air_handling_unit/faults/fault_condition_three.py +84 -29
- open_fdd/air_handling_unit/faults/fault_condition_twelve.py +98 -37
- open_fdd/air_handling_unit/faults/fault_condition_two.py +84 -32
- open_fdd/air_handling_unit/faults/helper_utils.py +295 -93
- open_fdd/air_handling_unit/images/ahu1_fc1_2024-06_1.jpg +0 -0
- open_fdd/air_handling_unit/images/ahu1_fc1_2024-06_2.jpg +0 -0
- open_fdd/air_handling_unit/images/example1.jpg +0 -0
- open_fdd/air_handling_unit/images/example2.jpg +0 -0
- open_fdd/air_handling_unit/images/fc10_definition.png +0 -0
- open_fdd/air_handling_unit/images/fc11_definition.png +0 -0
- open_fdd/air_handling_unit/images/fc12_definition.png +0 -0
- open_fdd/air_handling_unit/images/fc13_definition.png +0 -0
- open_fdd/air_handling_unit/images/fc1_definition.png +0 -0
- open_fdd/air_handling_unit/images/fc1_report_screenshot_all.png +0 -0
- open_fdd/air_handling_unit/images/fc2_definition.png +0 -0
- open_fdd/air_handling_unit/images/fc3_definition.png +0 -0
- open_fdd/air_handling_unit/images/fc4_definition.png +0 -0
- open_fdd/air_handling_unit/images/fc5_definition.png +0 -0
- open_fdd/air_handling_unit/images/fc6_definition.png +0 -0
- open_fdd/air_handling_unit/images/fc7_definition.png +0 -0
- open_fdd/air_handling_unit/images/fc8_definition.png +0 -0
- open_fdd/air_handling_unit/images/fc9_definition.png +0 -0
- open_fdd/air_handling_unit/images/latex_generator.py +175 -0
- open_fdd/air_handling_unit/images/params.docx +0 -0
- open_fdd/air_handling_unit/images/params.pdf +0 -0
- open_fdd/air_handling_unit/images/plot_for_repo.png +0 -0
- open_fdd/air_handling_unit/reports/base_report.py +47 -0
- open_fdd/air_handling_unit/reports/report_fc7.py +3 -1
- open_fdd/tests/ahu/test_ahu_fc1.py +18 -1
- open_fdd/tests/ahu/test_ahu_fc10.py +1 -1
- open_fdd/tests/ahu/test_ahu_fc11.py +1 -1
- open_fdd/tests/ahu/test_ahu_fc12.py +1 -1
- open_fdd/tests/ahu/test_ahu_fc13.py +1 -1
- open_fdd/tests/ahu/test_ahu_fc14.py +1 -1
- open_fdd/tests/ahu/test_ahu_fc15.py +1 -1
- open_fdd/tests/ahu/test_ahu_fc2.py +1 -1
- open_fdd/tests/ahu/test_ahu_fc3.py +1 -1
- open_fdd/tests/ahu/test_ahu_fc4.py +2 -2
- open_fdd/tests/ahu/test_ahu_fc5.py +1 -1
- open_fdd/tests/ahu/test_ahu_fc6.py +2 -2
- open_fdd/tests/ahu/test_ahu_fc7.py +1 -1
- open_fdd/tests/ahu/test_ahu_fc8.py +1 -1
- open_fdd/tests/ahu/test_ahu_fc9.py +1 -1
- {open_fdd-0.1.1.dist-info → open_fdd-0.1.4.dist-info}/METADATA +34 -5
- open_fdd-0.1.4.dist-info/RECORD +82 -0
- open_fdd-0.1.1.dist-info/RECORD +0 -59
- {open_fdd-0.1.1.dist-info → open_fdd-0.1.4.dist-info}/LICENSE +0 -0
- {open_fdd-0.1.1.dist-info → open_fdd-0.1.4.dist-info}/WHEEL +0 -0
- {open_fdd-0.1.1.dist-info → open_fdd-0.1.4.dist-info}/top_level.txt +0 -0
@@ -1,6 +1,9 @@
|
|
1
1
|
import pandas as pd
|
2
2
|
import numpy as np
|
3
|
-
from open_fdd.air_handling_unit.faults.fault_condition import
|
3
|
+
from open_fdd.air_handling_unit.faults.fault_condition import (
|
4
|
+
FaultCondition,
|
5
|
+
MissingColumnError,
|
6
|
+
)
|
4
7
|
import sys
|
5
8
|
|
6
9
|
|
@@ -10,6 +13,7 @@ class FaultConditionThree(FaultCondition):
|
|
10
13
|
"""
|
11
14
|
|
12
15
|
def __init__(self, dict_):
|
16
|
+
super().__init__()
|
13
17
|
self.mix_degf_err_thres = float
|
14
18
|
self.return_degf_err_thres = float
|
15
19
|
self.outdoor_degf_err_thres = float
|
@@ -20,39 +24,90 @@ class FaultConditionThree(FaultCondition):
|
|
20
24
|
self.troubleshoot_mode = bool # default to False
|
21
25
|
self.rolling_window_size = int
|
22
26
|
|
27
|
+
self.equation_string = (
|
28
|
+
"fc3_flag = 1 if (MAT - εMAT > max(RAT + εRAT, OAT + εOAT)) and (VFDSPD > 0) "
|
29
|
+
"for N consecutive values else 0 \n"
|
30
|
+
)
|
31
|
+
self.description_string = "Fault Condition 3: Mix temperature too high; should be between outside and return air \n"
|
32
|
+
self.required_column_description = "Required inputs are the mix air temperature, return air temperature, outside air temperature, and supply fan VFD speed \n"
|
33
|
+
self.error_string = f"One or more required columns are missing or None \n"
|
34
|
+
|
23
35
|
self.set_attributes(dict_)
|
24
36
|
|
25
|
-
|
26
|
-
|
27
|
-
self.
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
# Fault condition-specific checks / flags
|
34
|
-
df["mat_check"] = df[self.mat_col] - self.mix_degf_err_thres
|
35
|
-
df["temp_min_check"] = np.maximum(
|
36
|
-
df[self.rat_col] + self.return_degf_err_thres,
|
37
|
-
df[self.oat_col] + self.outdoor_degf_err_thres,
|
38
|
-
)
|
37
|
+
# Set required columns specific to this fault condition
|
38
|
+
self.required_columns = [
|
39
|
+
self.mat_col,
|
40
|
+
self.rat_col,
|
41
|
+
self.oat_col,
|
42
|
+
self.supply_vfd_speed_col,
|
43
|
+
]
|
39
44
|
|
40
|
-
|
41
|
-
|
45
|
+
# Check if any of the required columns are None
|
46
|
+
if any(col is None for col in self.required_columns):
|
47
|
+
raise MissingColumnError(
|
48
|
+
f"{self.error_string}"
|
49
|
+
f"{self.equation_string}"
|
50
|
+
f"{self.description_string}"
|
51
|
+
f"{self.required_column_description}"
|
52
|
+
f"{self.required_columns}"
|
53
|
+
)
|
54
|
+
|
55
|
+
# Ensure all required columns are strings
|
56
|
+
self.required_columns = [str(col) for col in self.required_columns]
|
57
|
+
|
58
|
+
self.mapped_columns = (
|
59
|
+
f"Your config dictionary is mapped as: {', '.join(self.required_columns)}"
|
42
60
|
)
|
43
61
|
|
44
|
-
|
45
|
-
|
46
|
-
|
62
|
+
def get_required_columns(self) -> str:
|
63
|
+
"""Returns a string representation of the required columns."""
|
64
|
+
return (
|
65
|
+
f"{self.equation_string}"
|
66
|
+
f"{self.description_string}"
|
67
|
+
f"{self.required_column_description}"
|
68
|
+
f"{self.mapped_columns}"
|
47
69
|
)
|
48
|
-
# Set flag to 1 if rolling sum equals the window size
|
49
|
-
df["fc3_flag"] = (rolling_sum >= self.rolling_window_size).astype(int)
|
50
70
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
del df["temp_min_check"]
|
56
|
-
del df["combined_check"]
|
71
|
+
def apply(self, df: pd.DataFrame) -> pd.DataFrame:
|
72
|
+
try:
|
73
|
+
# Ensure all required columns are present
|
74
|
+
self.check_required_columns(df)
|
57
75
|
|
58
|
-
|
76
|
+
if self.troubleshoot_mode:
|
77
|
+
self.troubleshoot_cols(df)
|
78
|
+
|
79
|
+
# Check analog outputs [data with units of %] are floats only
|
80
|
+
columns_to_check = [self.supply_vfd_speed_col]
|
81
|
+
self.check_analog_pct(df, columns_to_check)
|
82
|
+
|
83
|
+
# Fault condition-specific checks / flags
|
84
|
+
df["mat_check"] = df[self.mat_col] - self.mix_degf_err_thres
|
85
|
+
df["temp_min_check"] = np.maximum(
|
86
|
+
df[self.rat_col] + self.return_degf_err_thres,
|
87
|
+
df[self.oat_col] + self.outdoor_degf_err_thres,
|
88
|
+
)
|
89
|
+
|
90
|
+
df["combined_check"] = (df["mat_check"] > df["temp_min_check"]) & (
|
91
|
+
df[self.supply_vfd_speed_col] > 0.01
|
92
|
+
)
|
93
|
+
|
94
|
+
# Rolling sum to count consecutive trues
|
95
|
+
rolling_sum = (
|
96
|
+
df["combined_check"].rolling(window=self.rolling_window_size).sum()
|
97
|
+
)
|
98
|
+
# Set flag to 1 if rolling sum equals the window size
|
99
|
+
df["fc3_flag"] = (rolling_sum >= self.rolling_window_size).astype(int)
|
100
|
+
|
101
|
+
if self.troubleshoot_mode:
|
102
|
+
print("Troubleshoot mode enabled - not removing helper columns")
|
103
|
+
sys.stdout.flush()
|
104
|
+
del df["mat_check"]
|
105
|
+
del df["temp_min_check"]
|
106
|
+
del df["combined_check"]
|
107
|
+
|
108
|
+
return df
|
109
|
+
|
110
|
+
except MissingColumnError as e:
|
111
|
+
print(f"Error: {e.message}")
|
112
|
+
sys.stdout.flush()
|
113
|
+
raise e
|
@@ -1,8 +1,10 @@
|
|
1
1
|
import pandas as pd
|
2
2
|
import numpy as np
|
3
3
|
import operator
|
4
|
-
from open_fdd.air_handling_unit.faults.fault_condition import
|
5
|
-
|
4
|
+
from open_fdd.air_handling_unit.faults.fault_condition import (
|
5
|
+
FaultCondition,
|
6
|
+
MissingColumnError,
|
7
|
+
)
|
6
8
|
import sys
|
7
9
|
|
8
10
|
|
@@ -13,6 +15,7 @@ class FaultConditionTwelve(FaultCondition):
|
|
13
15
|
"""
|
14
16
|
|
15
17
|
def __init__(self, dict_):
|
18
|
+
super().__init__()
|
16
19
|
self.delta_t_supply_fan = float
|
17
20
|
self.mix_degf_err_thres = float
|
18
21
|
self.supply_degf_err_thres = float
|
@@ -24,48 +27,106 @@ class FaultConditionTwelve(FaultCondition):
|
|
24
27
|
self.troubleshoot_mode = bool # default False
|
25
28
|
self.rolling_window_size = int
|
26
29
|
|
27
|
-
self.
|
30
|
+
self.equation_string = (
|
31
|
+
"fc12_flag = 1 if SAT >= MAT + εMAT in "
|
32
|
+
"economizer + mech cooling mode for N consecutive values else 0 \n"
|
33
|
+
)
|
34
|
+
self.description_string = (
|
35
|
+
"Fault Condition 12: Supply air temperature too high; should be less than "
|
36
|
+
"mixed air temperature in economizer plus mechanical cooling mode \n"
|
37
|
+
)
|
38
|
+
self.required_column_description = (
|
39
|
+
"Required inputs are the supply air temperature, mixed air temperature, "
|
40
|
+
"cooling signal, and economizer signal \n"
|
41
|
+
)
|
42
|
+
self.error_string = f"One or more required columns are missing or None \n"
|
28
43
|
|
29
|
-
|
30
|
-
if self.troubleshoot_mode:
|
31
|
-
self.troubleshoot_cols(df)
|
44
|
+
self.set_attributes(dict_)
|
32
45
|
|
33
|
-
#
|
34
|
-
|
35
|
-
self.
|
46
|
+
# Set required columns specific to this fault condition
|
47
|
+
self.required_columns = [
|
48
|
+
self.sat_col,
|
49
|
+
self.mat_col,
|
36
50
|
self.cooling_sig_col,
|
51
|
+
self.economizer_sig_col,
|
37
52
|
]
|
38
|
-
self.check_analog_pct(df, columns_to_check)
|
39
53
|
|
40
|
-
#
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
54
|
+
# Check if any of the required columns are None
|
55
|
+
if any(col is None for col in self.required_columns):
|
56
|
+
raise MissingColumnError(
|
57
|
+
f"{self.error_string}"
|
58
|
+
f"{self.equation_string}"
|
59
|
+
f"{self.description_string}"
|
60
|
+
f"{self.required_column_description}"
|
61
|
+
f"{self.required_columns}"
|
62
|
+
)
|
63
|
+
|
64
|
+
# Ensure all required columns are strings
|
65
|
+
self.required_columns = [str(col) for col in self.required_columns]
|
66
|
+
|
67
|
+
self.mapped_columns = (
|
68
|
+
f"Your config dictionary is mapped as: {', '.join(self.required_columns)}"
|
55
69
|
)
|
56
70
|
|
57
|
-
|
58
|
-
|
59
|
-
|
71
|
+
def get_required_columns(self) -> str:
|
72
|
+
"""Returns a string representation of the required columns."""
|
73
|
+
return (
|
74
|
+
f"{self.equation_string}"
|
75
|
+
f"{self.description_string}"
|
76
|
+
f"{self.required_column_description}"
|
77
|
+
f"{self.mapped_columns}"
|
60
78
|
)
|
61
|
-
# Set flag to 1 if rolling sum equals the window size
|
62
|
-
df["fc12_flag"] = (rolling_sum >= self.rolling_window_size).astype(int)
|
63
79
|
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
80
|
+
def apply(self, df: pd.DataFrame) -> pd.DataFrame:
|
81
|
+
try:
|
82
|
+
# Ensure all required columns are present
|
83
|
+
self.check_required_columns(df)
|
84
|
+
|
85
|
+
if self.troubleshoot_mode:
|
86
|
+
self.troubleshoot_cols(df)
|
87
|
+
|
88
|
+
# Check analog outputs [data with units of %] are floats only
|
89
|
+
columns_to_check = [
|
90
|
+
self.economizer_sig_col,
|
91
|
+
self.cooling_sig_col,
|
92
|
+
]
|
93
|
+
self.check_analog_pct(df, columns_to_check)
|
94
|
+
|
95
|
+
# Create helper columns
|
96
|
+
df["sat_minus_saterr_delta_supply_fan"] = (
|
97
|
+
df[self.sat_col] - self.supply_degf_err_thres - self.delta_t_supply_fan
|
98
|
+
)
|
99
|
+
df["mat_plus_materr"] = df[self.mat_col] + self.mix_degf_err_thres
|
70
100
|
|
71
|
-
|
101
|
+
df["combined_check"] = operator.or_(
|
102
|
+
# OS4 AHU state clg @ min OA
|
103
|
+
(df["sat_minus_saterr_delta_supply_fan"] > df["mat_plus_materr"])
|
104
|
+
# verify AHU in OS4 mode
|
105
|
+
& (df[self.cooling_sig_col] > 0.01)
|
106
|
+
& (df[self.economizer_sig_col] == self.ahu_min_oa_dpr), # OR
|
107
|
+
(df["sat_minus_saterr_delta_supply_fan"] > df["mat_plus_materr"])
|
108
|
+
# verify AHU is running in OS 3 clg mode in 100 OA
|
109
|
+
& (df[self.cooling_sig_col] > 0.01)
|
110
|
+
& (df[self.economizer_sig_col] > 0.9),
|
111
|
+
)
|
112
|
+
|
113
|
+
# Rolling sum to count consecutive trues
|
114
|
+
rolling_sum = (
|
115
|
+
df["combined_check"].rolling(window=self.rolling_window_size).sum()
|
116
|
+
)
|
117
|
+
# Set flag to 1 if rolling sum equals the window size
|
118
|
+
df["fc12_flag"] = (rolling_sum >= self.rolling_window_size).astype(int)
|
119
|
+
|
120
|
+
if self.troubleshoot_mode:
|
121
|
+
print("Troubleshoot mode enabled - not removing helper columns")
|
122
|
+
sys.stdout.flush()
|
123
|
+
del df["sat_minus_saterr_delta_supply_fan"]
|
124
|
+
del df["mat_plus_materr"]
|
125
|
+
del df["combined_check"]
|
126
|
+
|
127
|
+
return df
|
128
|
+
|
129
|
+
except MissingColumnError as e:
|
130
|
+
print(f"Error: {e.message}")
|
131
|
+
sys.stdout.flush()
|
132
|
+
raise e
|
@@ -1,6 +1,9 @@
|
|
1
1
|
import pandas as pd
|
2
2
|
import numpy as np
|
3
|
-
from open_fdd.air_handling_unit.faults.fault_condition import
|
3
|
+
from open_fdd.air_handling_unit.faults.fault_condition import (
|
4
|
+
FaultCondition,
|
5
|
+
MissingColumnError,
|
6
|
+
)
|
4
7
|
import sys
|
5
8
|
|
6
9
|
|
@@ -10,9 +13,7 @@ class FaultConditionTwo(FaultCondition):
|
|
10
13
|
"""
|
11
14
|
|
12
15
|
def __init__(self, dict_):
|
13
|
-
|
14
|
-
:param dict_:
|
15
|
-
"""
|
16
|
+
super().__init__()
|
16
17
|
self.mix_degf_err_thres = float
|
17
18
|
self.return_degf_err_thres = float
|
18
19
|
self.outdoor_degf_err_thres = float
|
@@ -23,39 +24,90 @@ class FaultConditionTwo(FaultCondition):
|
|
23
24
|
self.troubleshoot_mode = bool # default to False
|
24
25
|
self.rolling_window_size = int
|
25
26
|
|
27
|
+
self.equation_string = (
|
28
|
+
"fc2_flag = 1 if (MAT + εMAT < min(RAT - εRAT, OAT - εOAT)) and (VFDSPD > 0) "
|
29
|
+
"for N consecutive values else 0 \n"
|
30
|
+
)
|
31
|
+
self.description_string = "Fault Condition 2: Mix temperature too low; should be between outside and return air \n"
|
32
|
+
self.required_column_description = "Required inputs are the mix air temperature, return air temperature, outside air temperature, and supply fan VFD speed \n"
|
33
|
+
self.error_string = f"One or more required columns are missing or None \n"
|
34
|
+
|
26
35
|
self.set_attributes(dict_)
|
27
36
|
|
28
|
-
|
29
|
-
|
30
|
-
self.
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
# Fault condition-specific checks / flags
|
37
|
-
df["mat_check"] = df[self.mat_col] + self.mix_degf_err_thres
|
38
|
-
df["temp_min_check"] = np.minimum(
|
39
|
-
df[self.rat_col] - self.return_degf_err_thres,
|
40
|
-
df[self.oat_col] - self.outdoor_degf_err_thres,
|
41
|
-
)
|
37
|
+
# Set required columns specific to this fault condition
|
38
|
+
self.required_columns = [
|
39
|
+
self.mat_col,
|
40
|
+
self.rat_col,
|
41
|
+
self.oat_col,
|
42
|
+
self.supply_vfd_speed_col,
|
43
|
+
]
|
42
44
|
|
43
|
-
|
44
|
-
|
45
|
+
# Check if any of the required columns are None
|
46
|
+
if any(col is None for col in self.required_columns):
|
47
|
+
raise MissingColumnError(
|
48
|
+
f"{self.error_string}"
|
49
|
+
f"{self.equation_string}"
|
50
|
+
f"{self.description_string}"
|
51
|
+
f"{self.required_column_description}"
|
52
|
+
f"{self.required_columns}"
|
53
|
+
)
|
54
|
+
|
55
|
+
# Ensure all required columns are strings
|
56
|
+
self.required_columns = [str(col) for col in self.required_columns]
|
57
|
+
|
58
|
+
self.mapped_columns = (
|
59
|
+
f"Your config dictionary is mapped as: {', '.join(self.required_columns)}"
|
45
60
|
)
|
46
61
|
|
47
|
-
|
48
|
-
|
49
|
-
|
62
|
+
def get_required_columns(self) -> str:
|
63
|
+
"""Returns a string representation of the required columns."""
|
64
|
+
return (
|
65
|
+
f"{self.equation_string}"
|
66
|
+
f"{self.description_string}"
|
67
|
+
f"{self.required_column_description}"
|
68
|
+
f"{self.mapped_columns}"
|
50
69
|
)
|
51
|
-
# Set flag to 1 if rolling sum equals the window size
|
52
|
-
df["fc2_flag"] = (rolling_sum >= self.rolling_window_size).astype(int)
|
53
70
|
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
del df["temp_min_check"]
|
59
|
-
del df["combined_check"]
|
71
|
+
def apply(self, df: pd.DataFrame) -> pd.DataFrame:
|
72
|
+
try:
|
73
|
+
# Ensure all required columns are present
|
74
|
+
self.check_required_columns(df)
|
60
75
|
|
61
|
-
|
76
|
+
if self.troubleshoot_mode:
|
77
|
+
self.troubleshoot_cols(df)
|
78
|
+
|
79
|
+
# Check analog outputs [data with units of %] are floats only
|
80
|
+
columns_to_check = [self.supply_vfd_speed_col]
|
81
|
+
self.check_analog_pct(df, columns_to_check)
|
82
|
+
|
83
|
+
# Fault condition-specific checks / flags
|
84
|
+
df["mat_check"] = df[self.mat_col] + self.mix_degf_err_thres
|
85
|
+
df["temp_min_check"] = np.minimum(
|
86
|
+
df[self.rat_col] - self.return_degf_err_thres,
|
87
|
+
df[self.oat_col] - self.outdoor_degf_err_thres,
|
88
|
+
)
|
89
|
+
|
90
|
+
df["combined_check"] = (df["mat_check"] < df["temp_min_check"]) & (
|
91
|
+
df[self.supply_vfd_speed_col] > 0.01
|
92
|
+
)
|
93
|
+
|
94
|
+
# Rolling sum to count consecutive trues
|
95
|
+
rolling_sum = (
|
96
|
+
df["combined_check"].rolling(window=self.rolling_window_size).sum()
|
97
|
+
)
|
98
|
+
# Set flag to 1 if rolling sum equals the window size
|
99
|
+
df["fc2_flag"] = (rolling_sum >= self.rolling_window_size).astype(int)
|
100
|
+
|
101
|
+
if self.troubleshoot_mode:
|
102
|
+
print("Troubleshoot mode enabled - not removing helper columns")
|
103
|
+
sys.stdout.flush()
|
104
|
+
del df["mat_check"]
|
105
|
+
del df["temp_min_check"]
|
106
|
+
del df["combined_check"]
|
107
|
+
|
108
|
+
return df
|
109
|
+
|
110
|
+
except MissingColumnError as e:
|
111
|
+
print(f"Error: {e.message}")
|
112
|
+
sys.stdout.flush()
|
113
|
+
raise e
|