mergeron 2024.738930.0__py3-none-any.whl → 2024.738936.2__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.

Potentially problematic release.


This version of mergeron might be problematic. Click here for more details.

Files changed (30) hide show
  1. mergeron/core/__init__.py +1 -1
  2. mergeron/core/guidelines_standards.py +247 -57
  3. mergeron/core/proportions_tests.py +19 -19
  4. mergeron/core/pseudorandom_numbers.py +30 -29
  5. mergeron/examples/__init__.py +1 -1
  6. mergeron/examples/concentration_as_diversion.py +75 -88
  7. mergeron/examples/investigations_stats_obs_tables.py +119 -111
  8. mergeron/examples/investigations_stats_sim_tables.py +108 -87
  9. mergeron/examples/plotSafeHarbs_symbolically.py +2 -2
  10. mergeron/examples/safeharbor_boundaries_for_mergers_with_asymmetric_shares.py +35 -28
  11. mergeron/examples/safeharbor_boundaries_for_symmetric_firm_mergers.py +6 -13
  12. mergeron/examples/sound_guppi_safeharbor.py +23 -18
  13. mergeron/examples/testIntrinsicClearanceRates.py +5 -5
  14. mergeron/examples/visualize_empirical_margin_distribution.py +1 -1
  15. mergeron/examples/{visualize_guidelines_tests_scatterplots.py → visualize_guidelines_tests.py} +42 -48
  16. mergeron/ext/__init__.py +1 -1
  17. mergeron/gen/__init__.py +1 -1
  18. mergeron/gen/data_generation.py +25 -24
  19. mergeron/gen/guidelines_tests.py +47 -47
  20. mergeron/gen/investigations_stats.py +98 -46
  21. mergeron/jinja_LaTex_templates/clrrate_cis_summary_table_template.tex.jinja2 +2 -3
  22. mergeron/jinja_LaTex_templates/ftcinvdata_byhhianddelta_table_template.tex.jinja2 +2 -3
  23. mergeron/jinja_LaTex_templates/ftcinvdata_summary_table_template.tex.jinja2 +1 -2
  24. mergeron/jinja_LaTex_templates/ftcinvdata_summarypaired_table_template.tex.jinja2 +13 -14
  25. mergeron/jinja_LaTex_templates/mergeron.cls +161 -0
  26. mergeron/jinja_LaTex_templates/mergeron_table_collection_template.tex.jinja2 +90 -0
  27. {mergeron-2024.738930.0.dist-info → mergeron-2024.738936.2.dist-info}/METADATA +15 -18
  28. mergeron-2024.738936.2.dist-info/RECORD +41 -0
  29. mergeron-2024.738930.0.dist-info/RECORD +0 -39
  30. {mergeron-2024.738930.0.dist-info → mergeron-2024.738936.2.dist-info}/WHEEL +0 -0
@@ -13,7 +13,6 @@ __version__ = version(_PKG_NAME)
13
13
 
14
14
  import enum
15
15
  from collections.abc import Mapping, Sequence
16
- from pathlib import Path
17
16
  from typing import Any, Literal, NamedTuple, TypeAlias
18
17
 
19
18
  import numpy as np
@@ -27,9 +26,6 @@ from ..core import guidelines_standards as gsf # noqa: TID252
27
26
  from . import data_generation as dgl
28
27
  from . import investigations_stats as isl
29
28
 
30
- mod_path = Path(__file__)
31
- data_path = Path.home() / mod_path.parent.stem
32
-
33
29
  ptb.parameters.MAX_NUMEXPR_THREADS = 8
34
30
  ptb.parameters.MAX_BLOSC_THREADS = 4
35
31
 
@@ -53,7 +49,7 @@ class GUPPIWghtngSelector(enum.StrEnum):
53
49
  OSD = "own-share-weighted distance"
54
50
 
55
51
 
56
- UPPTestSpec: TypeAlias = tuple[
52
+ UPPTestRegime: TypeAlias = tuple[
57
53
  isl.PolicySelector, GUPPIWghtngSelector, GUPPIWghtngSelector | None
58
54
  ]
59
55
 
@@ -65,17 +61,17 @@ class UPPTests(NamedTuple):
65
61
  ipr_test: NDArray[np.bool_]
66
62
 
67
63
 
68
- def sim_inv_cnts_ll(
69
- _inv_parm_vec: gsf.GuidelinesSTD,
64
+ def sim_invres_cnts_ll(
65
+ _invres_parm_vec: gsf.GuidelinesSTD,
70
66
  _mkt_sample_spec: dgl.MarketSampleSpec,
71
- _sim_inv_cnts_kwargs: Mapping[str, Any],
67
+ _sim_invres_cnts_kwargs: Mapping[str, Any],
72
68
  /,
73
69
  ) -> tuple[NDArray[np.int64], NDArray[np.int64], NDArray[np.int64]]:
74
70
  """
75
71
  A function to parallelize simulations
76
72
 
77
- The parameters _sim_inv_cnts_kwargs is passed unaltered to
78
- the parent function, sim_inv_cnts(), except that, if provided,
73
+ The parameters _sim_invres_cnts_kwargs is passed unaltered to
74
+ the parent function, sim_invres_cnts(), except that, if provided,
79
75
  "seed_seq_list" is used to spawn a seed sequence for each thread,
80
76
  to assure independent samples in each thread. The number of draws
81
77
  in each thread may be tuned, by trial and error, to the amount of
@@ -92,23 +88,25 @@ def sim_inv_cnts_ll(
92
88
  _mkt_sample_spec_here = evolve(_mkt_sample_spec, sample_size=_subsample_sz)
93
89
 
94
90
  _rng_seed_seq_list = [None] * _iter_count
95
- if _sim_inv_cnts_kwargs:
96
- if _sseql := _sim_inv_cnts_kwargs.get("seed_seq_list", None):
91
+ if _sim_invres_cnts_kwargs:
92
+ if _sseql := _sim_invres_cnts_kwargs.get("seed_seq_list", None):
97
93
  _rng_seed_seq_list = list(
98
94
  zip(*[g.spawn(_iter_count) for g in _sseql], strict=True) # type: ignore
99
95
  )
100
96
 
101
- _sim_inv_cnts_ll_kwargs = {
102
- _k: _v for _k, _v in _sim_inv_cnts_kwargs.items() if _k != "seed_seq_list"
97
+ _sim_invres_cnts_ll_kwargs = {
98
+ _k: _v
99
+ for _k, _v in _sim_invres_cnts_kwargs.items()
100
+ if _k != "seed_seq_list"
103
101
  }
104
102
  else:
105
- _sim_inv_cnts_ll_kwargs = {}
103
+ _sim_invres_cnts_ll_kwargs = {}
106
104
 
107
105
  _res_list = Parallel(n_jobs=_thread_count, prefer="threads")(
108
- delayed(sim_inv_cnts)(
109
- _inv_parm_vec,
106
+ delayed(sim_invres_cnts)(
107
+ _invres_parm_vec,
110
108
  _mkt_sample_spec_here,
111
- **_sim_inv_cnts_ll_kwargs,
109
+ **_sim_invres_cnts_ll_kwargs,
112
110
  saved_array_name_suffix=f"{_thread_id:0{int(np.ceil(np.log10(_thread_count)))}d}",
113
111
  seed_seq_list=_rng_seed_seq_list_ch,
114
112
  )
@@ -117,9 +115,9 @@ def sim_inv_cnts_ll(
117
115
 
118
116
  _res_list_stacks = [np.stack([_j[_k] for _j in _res_list]) for _k in range(3)]
119
117
  (
120
- _inv_cnts_sim_byfirmcount_array,
121
- _inv_cnts_sim_bydelta_array,
122
- _inv_cnts_sim_byconczone_array,
118
+ _invres_cnts_sim_byfirmcount_array,
119
+ _invres_cnts_sim_bydelta_array,
120
+ _invres_cnts_sim_byconczone_array,
123
121
  ) = (
124
122
  np.column_stack((
125
123
  _g[0, :, :_h],
@@ -130,18 +128,18 @@ def sim_inv_cnts_ll(
130
128
  del _res_list, _res_list_stacks
131
129
 
132
130
  return (
133
- _inv_cnts_sim_byfirmcount_array,
134
- _inv_cnts_sim_bydelta_array,
135
- _inv_cnts_sim_byconczone_array,
131
+ _invres_cnts_sim_byfirmcount_array,
132
+ _invres_cnts_sim_bydelta_array,
133
+ _invres_cnts_sim_byconczone_array,
136
134
  )
137
135
 
138
136
 
139
- def sim_inv_cnts(
137
+ def sim_invres_cnts(
140
138
  _guppi_test_parms: gsf.GuidelinesSTD,
141
139
  _mkt_sample_spec: dgl.MarketSampleSpec,
142
140
  /,
143
141
  *,
144
- sim_inv_sel: tuple[
142
+ sim_test_regime: tuple[
145
143
  isl.PolicySelector, GUPPIWghtngSelector, GUPPIWghtngSelector | None
146
144
  ],
147
145
  saved_array_name_suffix: str = "",
@@ -177,10 +175,10 @@ def sim_inv_cnts(
177
175
  save_data_to_file=save_data_to_file,
178
176
  )
179
177
 
180
- _upp_tests_data = gen_guppi_arrays(
178
+ _upp_tests_data = gen_upp_arrays(
181
179
  _guppi_test_parms,
182
180
  _market_data,
183
- sim_inv_sel,
181
+ sim_test_regime,
184
182
  saved_array_name_suffix=saved_array_name_suffix,
185
183
  save_data_to_file=save_data_to_file,
186
184
  )
@@ -200,12 +198,12 @@ def sim_inv_cnts(
200
198
  )
201
199
  _max_firm_count = len(_firm_counts_prob_weights)
202
200
 
203
- _inv_cnts_sim_byfirmcount_array = -1 * np.ones(_stats_rowlen, np.int64)
201
+ _invres_cnts_sim_byfirmcount_array = -1 * np.ones(_stats_rowlen, np.int64)
204
202
  for _firm_cnt in 2 + np.arange(_max_firm_count):
205
203
  _firm_count_test = _fcounts == _firm_cnt
206
204
 
207
- _inv_cnts_sim_byfirmcount_array = np.row_stack((
208
- _inv_cnts_sim_byfirmcount_array,
205
+ _invres_cnts_sim_byfirmcount_array = np.row_stack((
206
+ _invres_cnts_sim_byfirmcount_array,
209
207
  np.array([
210
208
  _firm_cnt,
211
209
  np.einsum("ij->", 1 * _firm_count_test),
@@ -215,15 +213,15 @@ def sim_inv_cnts(
215
213
  ],
216
214
  ]),
217
215
  ))
218
- _inv_cnts_sim_byfirmcount_array = _inv_cnts_sim_byfirmcount_array[1:]
216
+ _invres_cnts_sim_byfirmcount_array = _invres_cnts_sim_byfirmcount_array[1:]
219
217
 
220
218
  _hhi_delta_ranged = isl.hhi_delta_ranger(_hhi_delta)
221
- _inv_cnts_sim_bydelta_array = -1 * np.ones(_stats_rowlen, np.int64)
219
+ _invres_cnts_sim_bydelta_array = -1 * np.ones(_stats_rowlen, np.int64)
222
220
  for _hhi_delta_lim in isl.HHI_DELTA_KNOTS[:-1]:
223
221
  _hhi_delta_test = _hhi_delta_ranged == _hhi_delta_lim
224
222
 
225
- _inv_cnts_sim_bydelta_array = np.row_stack((
226
- _inv_cnts_sim_bydelta_array,
223
+ _invres_cnts_sim_bydelta_array = np.row_stack((
224
+ _invres_cnts_sim_bydelta_array,
227
225
  np.array([
228
226
  _hhi_delta_lim,
229
227
  np.einsum("ij->", 1 * _hhi_delta_test),
@@ -234,7 +232,7 @@ def sim_inv_cnts(
234
232
  ]),
235
233
  ))
236
234
 
237
- _inv_cnts_sim_bydelta_array = _inv_cnts_sim_bydelta_array[1:]
235
+ _invres_cnts_sim_bydelta_array = _invres_cnts_sim_bydelta_array[1:]
238
236
 
239
237
  # Clearance/enfrocement counts --- by zone, coded
240
238
  try:
@@ -269,21 +267,23 @@ def sim_inv_cnts(
269
267
  ]),
270
268
  ))
271
269
 
272
- _inv_cnts_sim_byconczone_array = isl.inv_cnts_byconczone(_stats_byconczone_sim[1:])
270
+ _invres_cnts_sim_byconczone_array = isl.invres_cnts_byconczone(
271
+ _stats_byconczone_sim[1:]
272
+ )
273
273
  del _stats_byconczone_sim
274
274
  del _hhi_delta, _hhi_post, _fcounts
275
275
 
276
276
  return (
277
- _inv_cnts_sim_byfirmcount_array,
278
- _inv_cnts_sim_bydelta_array,
279
- _inv_cnts_sim_byconczone_array,
277
+ _invres_cnts_sim_byfirmcount_array,
278
+ _invres_cnts_sim_bydelta_array,
279
+ _invres_cnts_sim_byconczone_array,
280
280
  )
281
281
 
282
282
 
283
- def gen_guppi_arrays(
284
- _guppi_test_parms: Sequence[float],
283
+ def gen_upp_arrays(
284
+ _guppi_test_parms: gsf.GuidelinesSTD,
285
285
  _market_data: dgl.MarketsSample,
286
- _sim_inv_sel: tuple[
286
+ _sim_test_regime: tuple[
287
287
  isl.PolicySelector, GUPPIWghtngSelector, GUPPIWghtngSelector | None
288
288
  ],
289
289
  /,
@@ -291,11 +291,11 @@ def gen_guppi_arrays(
291
291
  saved_array_name_suffix: str = "",
292
292
  save_data_to_file: SaveData = False,
293
293
  ) -> UPPTests:
294
- _r_bar, _g_bar, _divr_bar, _cmcr_bar, _ipr_bar = (
295
- getattr(_guppi_test_parms, _f) for _f in ("rec", "guppi", "divr", "cmcr", "ipr")
294
+ _g_bar, _divr_bar, _cmcr_bar, _ipr_bar = (
295
+ getattr(_guppi_test_parms, _f) for _f in ("guppi", "divr", "cmcr", "ipr")
296
296
  )
297
297
 
298
- _inv_sel, _guppi_wgtng_policy, _divr_wgtng_policy = _sim_inv_sel
298
+ _invres_select, _guppi_wgtng_policy, _divr_wgtng_policy = _sim_test_regime
299
299
 
300
300
  _guppi_array = np.empty_like(_market_data.divr_array)
301
301
  np.einsum(
@@ -387,7 +387,7 @@ def gen_guppi_arrays(
387
387
  if _divr_wgtng_policy == GUPPIWghtngSelector.MAX:
388
388
  _divr_test_vector = _market_data.divr_array.max(axis=1, keepdims=True)
389
389
 
390
- if _inv_sel == isl.PolicySelector.ENFT:
390
+ if _invres_select == isl.PolicySelector.ENFT:
391
391
  _upp_tests_data = UPPTests(
392
392
  _guppi_test_vector >= _g_bar,
393
393
  (_guppi_test_vector >= _g_bar) | (_divr_test_vector >= _divr_bar),
@@ -3,6 +3,7 @@ Routines to format and print summary data on merger enforcement patterns.
3
3
 
4
4
  """
5
5
 
6
+ import subprocess
6
7
  from importlib.metadata import version
7
8
 
8
9
  from .. import _PKG_NAME, DATA_DIR # noqa: TID252
@@ -11,7 +12,7 @@ __version__ = version(_PKG_NAME)
11
12
 
12
13
 
13
14
  import enum
14
- from collections.abc import Mapping
15
+ from collections.abc import Mapping, Sequence
15
16
  from pathlib import Path
16
17
  from types import SimpleNamespace
17
18
  from typing import TypeVar
@@ -26,6 +27,8 @@ from ..core import ftc_merger_investigations_data as fid # noqa: TID252
26
27
  from ..core.proportions_tests import propn_ci # noqa: TID252
27
28
 
28
29
  T = TypeVar("T", bound=NBitBase)
30
+ TF = TypeVar("TF", bound=NBitBase)
31
+ TI = TypeVar("TI", bound=NBitBase)
29
32
 
30
33
 
31
34
  @enum.unique
@@ -124,22 +127,33 @@ latex_jinja_env = Environment(
124
127
  variable_end_string="}",
125
128
  comment_start_string=R"((#", # r'#{',
126
129
  comment_end_string=R"#))", # '}',
127
- line_statement_prefix="%%",
130
+ line_statement_prefix="##",
128
131
  line_comment_prefix="%#",
129
132
  trim_blocks=True,
130
133
  lstrip_blocks=True,
131
134
  autoescape=select_autoescape(disabled_extensions=("tex.jinja2",)),
132
135
  loader=FileSystemLoader(Path(__file__).parents[1] / "jinja_LaTex_templates"),
133
136
  )
134
- TABLE_HELPER_DOTTEX = DATA_DIR / R"TikZTableSettings.tex"
135
- table_helper_design = latex_jinja_env.get_template("setup_tikz_tables.tex.jinja2")
136
- if not TABLE_HELPER_DOTTEX.is_file():
137
+
138
+ # Place files related to rendering latex in outpu data directory
139
+ if not (_out_path := DATA_DIR.joinpath(f"{_PKG_NAME}.cls")).is_file():
140
+ _out_path.write_text(
141
+ Path(__file__)
142
+ .parents[1]
143
+ .joinpath("jinja_LaTex_templates", "mergeron.cls")
144
+ .read_text()
145
+ )
146
+
147
+
148
+ if not (_DOTTEX := DATA_DIR / Rf"{_PKG_NAME}_TikZTableSettings.tex").is_file():
137
149
  # Write to dottex
138
- with TABLE_HELPER_DOTTEX.open("w", encoding="UTF-8") as table_helper_dottex:
139
- table_helper_dottex.write(
140
- table_helper_design.render(tmpl_data=StatsContainer())
150
+ with _DOTTEX.open("w", encoding="UTF-8") as _table_helper_dottex:
151
+ _table_helper_dottex.write(
152
+ latex_jinja_env.get_template("setup_tikz_tables.tex.jinja2").render(
153
+ tmpl_data=StatsContainer()
154
+ )
141
155
  )
142
- print("\n", file=table_helper_dottex)
156
+ print("\n", file=_table_helper_dottex)
143
157
 
144
158
 
145
159
  # Parameters and functions to interpolate selected HHI and ΔHHI values
@@ -203,13 +217,13 @@ ZONE_DETAIL_STRINGS_DELTA = {
203
217
  }
204
218
 
205
219
 
206
- def inv_stats_output(
220
+ def invres_stats_output(
207
221
  _data_array_dict: fid.INVData,
208
222
  _data_period: str = "1996-2003",
209
223
  _table_ind_group: INDGRPConstants = INDGRPConstants.ALL,
210
224
  _table_evid_cond: EVIDENConstants = EVIDENConstants.UR,
211
225
  _stats_group: StatsGrpSelector = StatsGrpSelector.FC,
212
- _inv_sel: PolicySelector = PolicySelector.CLRN,
226
+ _test_regime: PolicySelector = PolicySelector.CLRN,
213
227
  /,
214
228
  *,
215
229
  return_type_sel: StatsReturnSelector = StatsReturnSelector.RPT,
@@ -224,49 +238,49 @@ def inv_stats_output(
224
238
 
225
239
  match _stats_group:
226
240
  case StatsGrpSelector.ZN:
227
- _latex_tbl_inv_stats_func = latex_tbl_inv_stats_byzone
241
+ _latex_tbl_invres_stats_func = latex_tbl_invres_stats_byzone
228
242
  case StatsGrpSelector.FC:
229
- _latex_tbl_inv_stats_func = latex_tbl_inv_stats_1dim
243
+ _latex_tbl_invres_stats_func = latex_tbl_invres_stats_1dim
230
244
  case StatsGrpSelector.DL:
231
- _latex_tbl_inv_stats_func = latex_tbl_inv_stats_1dim
245
+ _latex_tbl_invres_stats_func = latex_tbl_invres_stats_1dim
232
246
  case _:
233
247
  raise ValueError(
234
248
  'Statistics formatted, "{_stats_group}" not available here.'
235
249
  )
236
250
 
237
- _inv_stats_cnts = inv_stats_cnts_by_group(
251
+ _invres_stats_cnts = invres_stats_cnts_by_group(
238
252
  _data_array_dict,
239
253
  _data_period,
240
254
  _table_ind_group,
241
255
  _table_evid_cond,
242
256
  _stats_group,
243
- _inv_sel,
257
+ _test_regime,
244
258
  )
245
259
 
246
- _inv_stats_hdr_list, _inv_stats_dat_list = _latex_tbl_inv_stats_func(
247
- _inv_stats_cnts, None, return_type_sel=return_type_sel, sort_order=sort_order
260
+ _invres_stats_hdr_list, _invres_stats_dat_list = _latex_tbl_invres_stats_func(
261
+ _invres_stats_cnts, None, return_type_sel=return_type_sel, sort_order=sort_order
248
262
  )
249
263
 
250
264
  if print_to_screen:
251
265
  print(
252
- f"{_inv_sel.capitalize()} stats ({return_type_sel})",
266
+ f"{_test_regime.capitalize()} stats ({return_type_sel})",
253
267
  f"for Period: {_data_period}",
254
268
  "\u2014",
255
269
  f"{_table_ind_group};",
256
270
  _table_evid_cond,
257
271
  )
258
- stats_print_rows(_inv_stats_hdr_list, _inv_stats_dat_list)
272
+ stats_print_rows(_invres_stats_hdr_list, _invres_stats_dat_list)
259
273
 
260
- return _inv_stats_hdr_list, _inv_stats_dat_list
274
+ return _invres_stats_hdr_list, _invres_stats_dat_list
261
275
 
262
276
 
263
- def inv_stats_cnts_by_group(
277
+ def invres_stats_cnts_by_group(
264
278
  _invdata_array_dict: Mapping[str, Mapping[str, Mapping[str, fid.TableData]]],
265
279
  _study_period: str,
266
280
  _table_ind_grp: INDGRPConstants,
267
281
  _table_evid_cond: EVIDENConstants,
268
282
  _stats_group: StatsGrpSelector,
269
- _inv_sel: PolicySelector,
283
+ _test_regime: PolicySelector,
270
284
  /,
271
285
  ) -> NDArray[np.int64]:
272
286
  if _stats_group == StatsGrpSelector.HD:
@@ -276,14 +290,14 @@ def inv_stats_cnts_by_group(
276
290
 
277
291
  match _stats_group:
278
292
  case StatsGrpSelector.FC:
279
- _cnts_func = inv_cnts_byfirmcount
280
- _cnts_listing_func = inv_cnts_listing_byfirmcount
293
+ _cnts_func = invres_cnts_byfirmcount
294
+ _cnts_listing_func = invres_cnts_listing_byfirmcount
281
295
  case StatsGrpSelector.DL:
282
- _cnts_func = inv_cnts_bydelta
283
- _cnts_listing_func = inv_cnts_listing_byhhianddelta
296
+ _cnts_func = invres_cnts_bydelta
297
+ _cnts_listing_func = invres_cnts_listing_byhhianddelta
284
298
  case StatsGrpSelector.ZN:
285
- _cnts_func = inv_cnts_byconczone
286
- _cnts_listing_func = inv_cnts_listing_byhhianddelta
299
+ _cnts_func = invres_cnts_byconczone
300
+ _cnts_listing_func = invres_cnts_listing_byhhianddelta
287
301
 
288
302
  return _cnts_func(
289
303
  _cnts_listing_func(
@@ -291,17 +305,17 @@ def inv_stats_cnts_by_group(
291
305
  _study_period,
292
306
  _table_ind_grp,
293
307
  _table_evid_cond,
294
- _inv_sel,
308
+ _test_regime,
295
309
  )
296
310
  )
297
311
 
298
312
 
299
- def inv_cnts_listing_byfirmcount(
313
+ def invres_cnts_listing_byfirmcount(
300
314
  _data_array_dict: Mapping[str, Mapping[str, Mapping[str, fid.TableData]]],
301
315
  _data_period: str = "1996-2003",
302
316
  _table_ind_group: INDGRPConstants = INDGRPConstants.ALL,
303
317
  _table_evid_cond: EVIDENConstants = EVIDENConstants.UR,
304
- _inv_sel: PolicySelector = PolicySelector.CLRN,
318
+ _test_regime: PolicySelector = PolicySelector.CLRN,
305
319
  /,
306
320
  ) -> NDArray[np.int64]:
307
321
  if _data_period not in _data_array_dict:
@@ -318,7 +332,7 @@ def inv_cnts_listing_byfirmcount(
318
332
 
319
333
  _ndim_in = 1
320
334
  _stats_kept_indxs = []
321
- match _inv_sel:
335
+ match _test_regime:
322
336
  case PolicySelector.CLRN:
323
337
  _stats_kept_indxs = [-1, -2]
324
338
  case PolicySelector.ENFT:
@@ -332,12 +346,12 @@ def inv_cnts_listing_byfirmcount(
332
346
  ])
333
347
 
334
348
 
335
- def inv_cnts_listing_byhhianddelta(
349
+ def invres_cnts_listing_byhhianddelta(
336
350
  _data_array_dict: Mapping[str, Mapping[str, Mapping[str, fid.TableData]]],
337
351
  _data_period: str = "1996-2003",
338
352
  _table_ind_group: INDGRPConstants = INDGRPConstants.ALL,
339
353
  _table_evid_cond: EVIDENConstants = EVIDENConstants.UR,
340
- _inv_sel: PolicySelector = PolicySelector.CLRN,
354
+ _test_regime: PolicySelector = PolicySelector.CLRN,
341
355
  /,
342
356
  ) -> NDArray[np.int64]:
343
357
  if _data_period not in _data_array_dict:
@@ -354,7 +368,7 @@ def inv_cnts_listing_byhhianddelta(
354
368
 
355
369
  _ndim_in = 2
356
370
  _stats_kept_indxs = []
357
- match _inv_sel:
371
+ match _test_regime:
358
372
  case PolicySelector.CLRN:
359
373
  _stats_kept_indxs = [-1, -2]
360
374
  case PolicySelector.ENFT:
@@ -394,7 +408,9 @@ def table_no_lku(
394
408
  return _tno
395
409
 
396
410
 
397
- def inv_cnts_byfirmcount(_cnts_array: NDArray[np.integer[T]], /) -> NDArray[np.int64]:
411
+ def invres_cnts_byfirmcount(
412
+ _cnts_array: NDArray[np.integer[T]], /
413
+ ) -> NDArray[np.int64]:
398
414
  _ndim_in = 1
399
415
  return np.row_stack([
400
416
  np.concatenate([
@@ -405,7 +421,7 @@ def inv_cnts_byfirmcount(_cnts_array: NDArray[np.integer[T]], /) -> NDArray[np.i
405
421
  ])
406
422
 
407
423
 
408
- def inv_cnts_bydelta(_cnts_array: NDArray[np.integer[T]], /) -> NDArray[np.int64]:
424
+ def invres_cnts_bydelta(_cnts_array: NDArray[np.integer[T]], /) -> NDArray[np.int64]:
409
425
  _ndim_in = 2
410
426
  return np.row_stack([
411
427
  np.concatenate([
@@ -416,7 +432,7 @@ def inv_cnts_bydelta(_cnts_array: NDArray[np.integer[T]], /) -> NDArray[np.int64
416
432
  ])
417
433
 
418
434
 
419
- def inv_cnts_byconczone(_cnts_array: NDArray[np.integer[T]], /) -> NDArray[np.int64]:
435
+ def invres_cnts_byconczone(_cnts_array: NDArray[np.integer[T]], /) -> NDArray[np.int64]:
420
436
  # Prepare to tag clearance stats by presumption zone
421
437
  _hhi_zone_post_ranged = hhi_zone_post_ranger(_cnts_array[:, 0] / 1e4)
422
438
  _hhi_delta_ranged = hhi_delta_ranger(_cnts_array[:, 1] / 1e4)
@@ -487,8 +503,8 @@ def inv_cnts_byconczone(_cnts_array: NDArray[np.integer[T]], /) -> NDArray[np.in
487
503
  return _cnts_byconczone[1:]
488
504
 
489
505
 
490
- def latex_tbl_inv_stats_1dim(
491
- _inparr: NDArray[np.integer[T]] | NDArray[np.floating[T]],
506
+ def latex_tbl_invres_stats_1dim(
507
+ _inparr: NDArray[np.floating[TF] | np.integer[TI]],
492
508
  _totals_row: int | None = None,
493
509
  /,
494
510
  *,
@@ -539,8 +555,8 @@ def latex_tbl_inv_stats_1dim(
539
555
  return _stats_hdr_list, _stats_dat_list
540
556
 
541
557
 
542
- def latex_tbl_inv_stats_byzone(
543
- _inparr: NDArray[np.integer[T]] | NDArray[np.floating[T]],
558
+ def latex_tbl_invres_stats_byzone(
559
+ _inparr: NDArray[np.floating[TF] | np.integer[TI]],
544
560
  _totals_row: int | None = None,
545
561
  /,
546
562
  *,
@@ -648,9 +664,9 @@ def _stats_formatted_row(
648
664
 
649
665
 
650
666
  def stats_print_rows(
651
- _inv_stats_hdr_list: list[str], _inv_stats_dat_list: list[list[str]]
667
+ _invres_stats_hdr_list: list[str], _invres_stats_dat_list: list[list[str]]
652
668
  ) -> None:
653
- for _idx, _hdr in enumerate(_inv_stats_hdr_list):
669
+ for _idx, _hdr in enumerate(_invres_stats_hdr_list):
654
670
  # _hv = (
655
671
  # re.match(r"^\\node.*?(\{.*\});?", _hdr)[1]
656
672
  # if _hdr.startswith(R"\node")
@@ -662,8 +678,44 @@ def stats_print_rows(
662
678
  print(
663
679
  _hdr_str,
664
680
  "&",
665
- " & ".join(_inv_stats_dat_list[_idx]),
681
+ " & ".join(_invres_stats_dat_list[_idx]),
666
682
  LTX_ARRAY_LINEEND,
667
683
  end="",
668
684
  )
669
685
  print()
686
+
687
+
688
+ def render_table_pdf(
689
+ _table_dottex_pathlist: Sequence[str], _table_coll_path: str, /
690
+ ) -> None:
691
+ _table_collection_design = latex_jinja_env.get_template(
692
+ "mergeron_table_collection_template.tex.jinja2"
693
+ )
694
+ _table_collection_content = StatsContainer()
695
+
696
+ _table_collection_content.path_list = _table_dottex_pathlist
697
+
698
+ with Path(DATA_DIR / _table_coll_path).open(
699
+ "w", encoding="utf8"
700
+ ) as _table_coll_file:
701
+ _table_coll_file.write(
702
+ _table_collection_design.render(tmpl_data=_table_collection_content)
703
+ )
704
+ print("\n", file=_table_coll_file)
705
+
706
+ _run_rc = subprocess.run(
707
+ f"latexmk -f -quiet -synctex=0 -interaction=nonstopmode -file-line-error -pdflua {_table_coll_path}".split(), # noqa: S603
708
+ check=True,
709
+ cwd=DATA_DIR,
710
+ )
711
+ if _run_rc:
712
+ subprocess.run(
713
+ "latexmk -quiet -c".split(), # noqa: S603
714
+ check=True,
715
+ cwd=DATA_DIR,
716
+ )
717
+ del _run_rc
718
+
719
+ print(
720
+ f"Tables rendered to path, {f"{Path(DATA_DIR / _table_coll_path).with_suffix(".pdf")}"}"
721
+ )
@@ -7,14 +7,14 @@
7
7
  ((* set table_ref, obs_merger_class_desc = "3.1", tmpl_data.obs_merger_class *))
8
8
  ((* endif *))
9
9
 
10
- ((* if tmpl_data.clrenf_sel == 'Enforcement' *))
10
+ ((* if tmpl_data.test_regime == 'Enforcement' *))
11
11
  ((* set prop_title = "Proportion Enforced" *))
12
12
  ((* else *))
13
13
  ((* set prop_title = "Proportion Cleared" *))
14
14
  ((* endif *))
15
15
 
16
16
 
17
- \begin{center}
17
+ \centering
18
18
  \caption{
19
19
  \JINVAR{ prop_title } and Simulated \JINVAR{ tmpl_data.PolicySelector} Rates
20
20
  for FTC Investigated Mergers
@@ -118,5 +118,4 @@
118
118
  Generated Data \\
119
119
  };
120
120
  \end{tikzpicture}
121
- \end{center}
122
121
  \end{table}
@@ -14,11 +14,11 @@
14
14
  ((* set data_pub_year = "" *))
15
15
  ((* endif *))
16
16
 
17
- \begin{center}
17
+ \centering
18
18
  \caption{FTC Merger Investigations Data, Fiscal Years \JINVAR{ tmpl_data.obs_period|join('--') }}\label{tbl:FTCInvData_ByConc_\JINVAR{ tmpl_data.obs_merger_class|replace(" ", "") -}_\JINVAR{ obs_period_last -}}
19
19
 
20
20
  {\footnotesize
21
- Odds ratio --- Enforced to Closed, by Post-Merger HHI and Change in Concentration \\
21
+ Odds ratio --- Enforced to Closed, by Post-Merger HHI and Change in Concentration \\
22
22
  \JINVAR{ obs_merger_class_desc } \\[0.5\baselineskip]
23
23
  }
24
24
  \begin{tikzpicture}[font = \sffamily]
@@ -79,5 +79,4 @@
79
79
  % Fill top left corner, with more or fewer header/descriptor rows, only the top-left coordinates change
80
80
  \draw[hdrtext, draw = OBSHDRFill] (hdrcoldescNW |- hdrrowdescNW) rectangle (datamtrx.north west); % (x1, y2); -| gives (x2, y1)
81
81
  \end{tikzpicture}
82
- \end{center}
83
82
  \end{table}
@@ -7,7 +7,7 @@
7
7
  ((* set table_ref, obs_merger_class_desc = "3.1", tmpl_data.obs_merger_class *))
8
8
  ((* endif *))
9
9
 
10
- \begin{center}
10
+ \centering
11
11
  \caption{FTC Merger Investigations Data}\label{tbl:FTCInvData_\JINVAR{ tmpl_data.obs_summary_type|replace(" ", "") -}_\JINVAR{ tmpl_data.obs_merger_class|replace(" ", "") -}}
12
12
  {\footnotesize \JINVAR{ tmpl_data.obs_summary_type_title } \\
13
13
  \JINVAR{ obs_merger_class_desc } \\[0.5\baselineskip]}
@@ -53,6 +53,5 @@
53
53
  % \(\cdot\) Fed. Trade Comm'n (2013), \textit{supra} note~\ref{fn:FTCInvData1996to2011}, Table~4.1 and Table~10.2 \\
54
54
  };
55
55
  \end{tikzpicture}
56
- \end{center}
57
56
  \end{table}
58
57