Skip to content

Commit a37dbe7

Browse files
committed
adds tqdm and new row inversion method
1 parent 34d42f7 commit a37dbe7

File tree

6 files changed

+62
-17
lines changed

6 files changed

+62
-17
lines changed

CHANGELOG.md

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,22 @@
11
# Changelog
22

3+
Follows [Keep A Changelog format](https://keepachangelog.com/en/1.1.0/)
4+
5+
## 0.0.3
6+
7+
### Added
8+
9+
- Uses tqdm for progress bar tracking
10+
- Adds better row mode instead of starting chunked and instantly switching to row
11+
12+
### Changed
13+
14+
- Prints elapsed seconds as integer instead of float
15+
- Expands documentation for missing parameters
16+
317
## 0.0.2
418

5-
### New features
19+
### Added
620

721
- Writes scores to a text file
822

example_config.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,14 @@ overwrite = true
1212

1313
[inversion]
1414
solution_fov_width = 2
15-
detector_row_range = [300, 400] #[0, 792]
15+
detector_row_range = [0, 50]
1616
field_angle_range = [-1227, 1227]
1717
response_dependency_name = "logt"
1818
response_dependency_list = [5.7, 5.8, 5.9, 6.0 , 6.1, 6.2, 6.3, 6.4, 6.5, 6.6, 6.7, 6.8]
1919
smooth_over = 'dependence'
2020

2121
[model]
22-
alphas = [3E-5] #[0.2, 0.1, 0.01, 0.005]
22+
alphas = [3E-5, 4E-5, 0.1] #[0.2, 0.1, 0.01, 0.005]
2323
rhos = [0.1]
2424
warm_start = false
2525
tol = 1E-2

overlappogram/cli.py

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,10 @@
2121
@click.command()
2222
@click.argument("config")
2323
def unfold(config):
24-
"""Unfold an overlappogram given a configuration toml file.""" # TODO improve message
24+
"""Unfold an overlappogram given a configuration toml file.
25+
26+
See https://eccco-mission.github.io/overlappogram/configuration.html for the configuration file format.
27+
"""
2528

2629
with open(config) as f:
2730
config = toml.load(f)
@@ -42,6 +45,8 @@ def unfold(config):
4245

4346
for alpha in config["model"]["alphas"]:
4447
for rho in config["model"]["rhos"]:
48+
print(80*"-")
49+
print(f"Beginning inversion for alpha={alpha}, rho={rho}.")
4550
start = time.time()
4651
em_cube, prediction, scores, unconverged_rows = inversion.invert(
4752
overlappogram,
@@ -54,9 +59,9 @@ def unfold(config):
5459
)
5560
end = time.time()
5661
print(
57-
f"Inversion Time for alpha={alpha}, rho={rho}:",
58-
end - start,
59-
f"; {len(unconverged_rows)} unconverged rows",
62+
f"Inversion for alpha={alpha}, rho={rho} took",
63+
int(end - start),
64+
f"seconds; {len(unconverged_rows)} unconverged rows",
6065
)
6166

6267
postfix = (

overlappogram/inversion.py

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
from ndcube import NDCube
1010
from sklearn.exceptions import ConvergenceWarning
1111
from sklearn.linear_model import ElasticNet
12+
from tqdm import tqdm
1213

1314
from overlappogram.response import prepare_response_function
1415

@@ -60,6 +61,8 @@ def __init__(
6061
response_dependency_list=response_dependency_list,
6162
)
6263

64+
self._progress_bar = None # initialized in invert call
65+
6366
@property
6467
def is_inverted(self) -> bool:
6568
return not any(
@@ -107,7 +110,8 @@ def _progress_indicator(self, future):
107110
with self._thread_count_lock:
108111
if not future.cancelled():
109112
self._completed_row_count += 1
110-
print(f"{self._completed_row_count / self.total_row_count * 100:3.0f}% complete", end="\r")
113+
#print(f"{self._completed_row_count / self.total_row_count * 100:3.0f}% complete", end="\r")
114+
self._progress_bar.update(1)
111115

112116
def _switch_to_row_inversion(self, model_config, alpha, rho, num_row_threads=50):
113117
self._mode = InversionMode.ROW
@@ -161,6 +165,29 @@ def _collect_results(self, mode_switch_thread_count, model_config, alpha, rho):
161165
self._switch_to_row_inversion(model_config, alpha, rho)
162166
break
163167

168+
def _start_row_inversion(self, model_config, alpha, rho, num_threads):
169+
self.executors = [concurrent.futures.ThreadPoolExecutor(max_workers=num_threads)]
170+
171+
self.futures = {}
172+
self._models = []
173+
for i, row_index in enumerate(range(self._detector_row_range[0], self._detector_row_range[1])):
174+
enet_model = ElasticNet(
175+
alpha=alpha,
176+
l1_ratio=rho,
177+
tol=model_config["tol"],
178+
max_iter=model_config["max_iter"],
179+
precompute=False, # setting this to true slows down performance dramatically
180+
positive=True,
181+
copy_X=False,
182+
fit_intercept=False,
183+
selection=model_config["selection"],
184+
warm_start=False, # warm start doesn't make sense in the row version
185+
)
186+
self._models.append(enet_model)
187+
future = self.executors[-1].submit(self._invert_image_row, row_index, i)
188+
future.add_done_callback(self._progress_indicator)
189+
self.futures[future] = (row_index, i)
190+
164191
def _start_chunk_inversion(self, model_config, alpha, rho, num_threads):
165192
starts = np.arange(
166193
self._detector_row_range[0],
@@ -255,6 +282,8 @@ def invert(
255282

256283
self._mode = mode
257284

285+
self._progress_bar = tqdm(total=self.total_row_count, unit='row', delay=1, leave=False)
286+
258287
self._models = []
259288
self._completed_row_count = 0
260289

@@ -269,16 +298,16 @@ def invert(
269298
# mode never switches since count=0
270299
self._collect_results(0, model_config, alpha, rho)
271300
elif self._mode == InversionMode.ROW:
272-
self._start_chunk_inversion(model_config, alpha, rho, num_threads)
273-
# TODO: it would be better to have a mode to start in row but right now we fake it with a fast mode switch
274-
self._collect_results(np.inf, model_config, alpha, rho) # immediately switch mode
301+
self._start_row_inversion(model_config, alpha, rho, num_threads)
275302
self._collect_results(np.inf, model_config, alpha, rho)
276303
else:
277304
raise ValueError("Invalid InversionMode.")
278305

279306
for executor in self.executors:
280307
executor.shutdown()
281308

309+
self._progress_bar.close()
310+
282311
return (
283312
np.transpose(self._em_data, (2, 0, 1)),
284313
self._inversion_prediction,

overlappogram/spectral.py

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,12 +47,8 @@ def create_spectrally_pure_images(image_list: list, gnt_path: str, rsp_dep_list:
4747
for index in range(len(image_list)):
4848
# Create spectrally pure data cube.
4949
for em_data in image_list:
50-
# with fits.open(image_list[index]) as em_hdul:
51-
# em_data_cube = em_hdul[0].data.astype(np.float64)
5250
em_data_cube = em_data.astype(np.float64)
5351
em_data_cube = np.transpose(em_data_cube, axes=(1, 2, 0))
54-
# em_dep_list = em_hdul[1].data['logt']
55-
# print(em_dep_list)
5652
if index == 0:
5753
image_height, num_slits, num_logts = np.shape(em_data_cube)
5854
gnt_data_cube = np.zeros((image_height, num_slits, num_gnts), dtype=np.float64)

pyproject.toml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ requires = ["setuptools",
55

66
[project]
77
name = "overlappogram"
8-
version = "0.0.2"
8+
version = "0.0.3"
99
dependencies = ["numpy",
1010
"astropy",
1111
"scikit-learn",
@@ -16,7 +16,8 @@ dependencies = ["numpy",
1616
"scipy",
1717
"ndcube",
1818
"toml",
19-
"click"
19+
"click",
20+
"tqdm"
2021
]
2122
requires-python = ">=3.9"
2223
authors = [

0 commit comments

Comments
 (0)