mergeron 2024.738940.0__py3-none-any.whl → 2024.738949.0__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 (24) hide show
  1. mergeron/core/excel_helper.py +38 -25
  2. mergeron/core/ftc_merger_investigations_data.py +33 -30
  3. mergeron/core/{guidelines_standards.py → guidelines_boundaries.py} +35 -29
  4. mergeron/core/proportions_tests.py +12 -10
  5. mergeron/examples/concentration_as_diversion.py +30 -26
  6. mergeron/examples/{safeharbor_boundaries_for_mergers_with_asymmetric_shares.py → enforcement_boundaries_for_mergers_with_asymmetric_shares.py} +84 -90
  7. mergeron/examples/{safeharbor_boundaries_for_symmetric_firm_mergers.py → enforcement_boundaries_for_symmetric_firm_mergers.py} +3 -3
  8. mergeron/examples/guidelines_enforcement_patterns.py +18 -16
  9. mergeron/examples/investigations_stats_obs_tables.py +15 -14
  10. mergeron/examples/investigations_stats_sim_tables.py +49 -54
  11. mergeron/examples/plotSafeHarbs_symbolically.py +1 -1
  12. mergeron/examples/sound_guppi_safeharbor.py +59 -54
  13. mergeron/examples/summarize_ftc_investigations_data.py +4 -4
  14. mergeron/examples/visualize_empirical_margin_distribution.py +2 -2
  15. mergeron/examples/visualize_guidelines_tests.py +67 -65
  16. mergeron/gen/__init__.py +104 -42
  17. mergeron/gen/_data_generation_functions_nonpublic.py +6 -6
  18. mergeron/gen/data_generation.py +1 -4
  19. mergeron/gen/investigations_stats.py +21 -27
  20. mergeron/gen/{guidelines_tests.py → upp_tests.py} +98 -102
  21. {mergeron-2024.738940.0.dist-info → mergeron-2024.738949.0.dist-info}/METADATA +2 -5
  22. mergeron-2024.738949.0.dist-info/RECORD +42 -0
  23. {mergeron-2024.738940.0.dist-info → mergeron-2024.738949.0.dist-info}/WHEEL +1 -1
  24. mergeron-2024.738940.0.dist-info/RECORD +0 -42
@@ -14,6 +14,7 @@ from numpy import einsum, row_stack, unique
14
14
  import mergeron.core.ftc_merger_investigations_data as fid
15
15
  import mergeron.gen.investigations_stats as isl
16
16
  from mergeron import DATA_DIR
17
+ from mergeron.gen import INVResolution
17
18
 
18
19
  if not sys.warnoptions:
19
20
  warnings.simplefilter("ignore")
@@ -144,7 +145,7 @@ def invres_stats_odds_ratio_byhhianddelta(
144
145
  _invres_rate_table_content.invdata_byhhianddelta = _odds_ratio_data_str
145
146
 
146
147
  _output_dottex_path = DATA_DIR / INVDATA_DOTTEX_FORMAT_STR.format(
147
- f"{_stats_group}_{_data_period_1}_{_merger_class.replace(' ', '')}"
148
+ f"{_stats_group}_{_data_period_1}_{_merger_class.replace(" ", "")}"
148
149
  )
149
150
  with _output_dottex_path.open(
150
151
  "w", encoding="utf8"
@@ -168,13 +169,13 @@ def invres_stats_obs_setup(
168
169
  _data_array_dict: Mapping,
169
170
  _data_periods: tuple[str, str],
170
171
  _merger_classes: Sequence[isl.INDGRPConstants | isl.EVIDENConstants],
171
- _test_regime: isl.PolicySelector = isl.PolicySelector.CLRN,
172
+ _invres_spec: INVResolution = INVResolution.CLRN,
172
173
  /,
173
174
  ) -> tuple[str, ...]:
174
175
  _notes_str_base = " ".join((
175
176
  "NOTES:",
176
177
  isl.LTX_ARRAY_LINEEND,
177
- Rf"\(\cdot\) Data for period, {_data_periods[1].replace('-', '--')}",
178
+ Rf"\(\cdot\) Data for period, {_data_periods[1].replace("-", "--")}",
178
179
  "calculated by subtracting reported figures for 1996--{}".format(
179
180
  int(_data_periods[1].split("-")[0]) - 1
180
181
  ),
@@ -182,7 +183,7 @@ def invres_stats_obs_setup(
182
183
  ))
183
184
  _stats_group_dict = {
184
185
  isl.StatsGrpSelector.FC: {
185
- "desc": f"{_test_regime.capitalize()} rates by Firm Count",
186
+ "desc": f"{_invres_spec.capitalize()} rates by Firm Count",
186
187
  "title_str": "By Number of Significant Competitors",
187
188
  "hval": "Firm Count",
188
189
  "hcol_width": 54,
@@ -195,7 +196,7 @@ def invres_stats_obs_setup(
195
196
  )),
196
197
  },
197
198
  isl.StatsGrpSelector.DL: {
198
- "desc": Rf"{_test_regime.capitalize()} rates by range of \(\Delta HHI\)",
199
+ "desc": Rf"{_invres_spec.capitalize()} rates by range of \(\Delta HHI\)",
199
200
  "title_str": R"By Change in Concentration (\Deltah{})",
200
201
  "hval": R"$\Delta HHI$",
201
202
  "hval_plus": R"{ $[\Delta_L, \Delta_H)$ pts.}",
@@ -217,7 +218,7 @@ def invres_stats_obs_setup(
217
218
  )),
218
219
  },
219
220
  isl.StatsGrpSelector.ZN: {
220
- "desc": f"{_test_regime.capitalize()} rates by Approximate Presumption Zone",
221
+ "desc": f"{_invres_spec.capitalize()} rates by Approximate Presumption Zone",
221
222
  "title_str": R"By Approximate \textit{2010 Guidelines} Concentration-Based Standards",
222
223
  "hval": "Approximate Standard",
223
224
  "hcol_width": 190,
@@ -238,7 +239,7 @@ def invres_stats_obs_setup(
238
239
  _merger_classes,
239
240
  _stats_group_key,
240
241
  _stats_group_dict[_stats_group_key],
241
- _test_regime,
242
+ _invres_spec,
242
243
  )
243
244
  _output_dottex_pathlist += (_output_dottex_path,)
244
245
 
@@ -251,7 +252,7 @@ def _invres_stats_obs_render(
251
252
  _merger_classes: Sequence[isl.INDGRPConstants | isl.EVIDENConstants],
252
253
  _stats_group: isl.StatsGrpSelector,
253
254
  _stats_group_dict: Mapping,
254
- _test_regime: isl.PolicySelector = isl.PolicySelector.CLRN,
255
+ _invres_spec: isl.INVResolution = isl.INVResolution.CLRN,
255
256
  /,
256
257
  ) -> str:
257
258
  _invres_rate_table_content = isl.StatsContainer()
@@ -262,7 +263,7 @@ def _invres_stats_obs_render(
262
263
  print(
263
264
  f'{_stats_group_dict["desc"]}:', ", ".join([f'"{g}"' for g in _merger_classes])
264
265
  )
265
- _invres_rate_table_content.test_regime = _test_regime.capitalize()
266
+ _invres_rate_table_content.test_regime = _invres_spec.capitalize()
266
267
  _invres_rate_table_content.obs_summary_type = f"{_stats_group}"
267
268
  _invres_rate_table_content.obs_summary_type_title = _stats_group_dict.get(
268
269
  "title_str"
@@ -290,7 +291,7 @@ def _invres_stats_obs_render(
290
291
  _invres_rate_table_content.obs_merger_class_0 = f"{_merger_classes[0]}"
291
292
  _invres_rate_table_content.obs_merger_class_1 = f"{_merger_classes[1]}"
292
293
  _invres_rate_table_content.obs_periods_str = (
293
- Rf"{' & '.join(_data_periods)} \\".replace("-", "--")
294
+ Rf"{" & ".join(_data_periods)} \\".replace("-", "--")
294
295
  )
295
296
 
296
297
  _invres_rate_table_content.invdata_notewidth = _stats_group_dict["notewidth"]
@@ -349,7 +350,7 @@ def _invres_stats_obs_render(
349
350
  _table_ind_group,
350
351
  _table_evid_cond,
351
352
  _stats_group,
352
- _test_regime,
353
+ _invres_spec,
353
354
  return_type_sel=isl.StatsReturnSelector.CNT,
354
355
  print_to_screen=False,
355
356
  )[1][-1][0]
@@ -361,7 +362,7 @@ def _invres_stats_obs_render(
361
362
  _table_ind_group,
362
363
  _table_evid_cond,
363
364
  _stats_group,
364
- _test_regime,
365
+ _invres_spec,
365
366
  return_type_sel=isl.StatsReturnSelector.RPT,
366
367
  sort_order=_sort_order,
367
368
  print_to_screen=False,
@@ -384,7 +385,7 @@ def _invres_stats_obs_render(
384
385
  ])
385
386
 
386
387
  _invdata_datstr = "".join([
387
- f"{' & '.join(_invdata_dat_list[g])} {isl.LTX_ARRAY_LINEEND}"
388
+ f"{" & ".join(_invdata_dat_list[g])} {isl.LTX_ARRAY_LINEEND}"
388
389
  for g in range(len(_invdata_dat_list))
389
390
  ])
390
391
 
@@ -459,7 +460,7 @@ if __name__ == "__main__":
459
460
  isl.EVIDENConstants.ED,
460
461
  ) # clstl.INDGRPConstants.IID)
461
462
  data_periods = ("1996-2003", "2004-2011")
462
- test_regime = isl.PolicySelector.ENFT
463
+ test_regime = isl.INVResolution.ENFT
463
464
 
464
465
  # Now generate the various tables summarizing merger investigations data
465
466
  invres_stats_byhhianddelta_pathlist = invres_stats_odds_ratio_byhhianddelta(
@@ -8,25 +8,32 @@ Format output as LaTeX tables (using TikZ).
8
8
  import sys
9
9
  import warnings
10
10
  from collections.abc import Mapping, Sequence
11
+ from dataclasses import fields
11
12
  from datetime import datetime, timedelta
12
13
  from io import TextIOWrapper
13
- from pathlib import Path
14
14
  from typing import Any
15
15
 
16
16
  import numpy as np
17
- import re2 as re # type: ignore
18
- import tables as ptb # type: ignore
19
17
  from attrs import evolve
20
18
 
21
19
  import mergeron.core.ftc_merger_investigations_data as fid
22
- import mergeron.core.guidelines_standards as gsl
20
+ import mergeron.core.guidelines_boundaries as gbl
23
21
  import mergeron.gen.data_generation as dgl
24
- import mergeron.gen.guidelines_tests as gtl
25
22
  import mergeron.gen.investigations_stats as isl
23
+ import mergeron.gen.upp_tests as utl
26
24
  from mergeron import DATA_DIR
27
- from mergeron.core.guidelines_standards import GuidelinesStandards
28
25
  from mergeron.core.proportions_tests import propn_ci
29
- from mergeron.gen import PCMConstants, PCMSpec, RECConstants, ShareSpec, SHRConstants
26
+ from mergeron.gen import (
27
+ INVResolution,
28
+ MarketSampleSpec,
29
+ PCMConstants,
30
+ PCMSpec,
31
+ RECConstants,
32
+ ShareSpec,
33
+ SHRConstants,
34
+ UPPAggrSelector,
35
+ UPPTestRegime,
36
+ )
30
37
 
31
38
  if not sys.warnoptions:
32
39
  warnings.simplefilter("ignore") # , category="RuntimeWarning")
@@ -42,9 +49,9 @@ def invres_stats_sim_setup(
42
49
  _invdata: fid.INVData,
43
50
  _data_period: str,
44
51
  _merger_class: isl.INDGRPConstants | isl.EVIDENConstants,
45
- _invres_parm_vec: gsl.GuidelinesSTD,
46
- _sample_spec: dgl.MarketSampleSpec,
47
- _invres_stats_kwargs: Mapping[str, Any] | None = None,
52
+ _invres_parm_vec: gbl.HMGThresholds,
53
+ _sample_spec: MarketSampleSpec,
54
+ _invres_stats_kwargs: utl.IVNRESCntsArgs | None = None,
48
55
  /,
49
56
  ) -> str:
50
57
  _table_ind_group = (
@@ -59,10 +66,14 @@ def invres_stats_sim_setup(
59
66
  )
60
67
 
61
68
  _invres_stats_kwargs = _invres_stats_kwargs or {
62
- "sim_test_regime": isl.PolicySelector.ENFT
69
+ "sim_test_regime": UPPTestRegime(INVResolution.ENFT, UPPAggrSelector.MAX, None)
63
70
  }
64
- _sim_test_regime = _invres_stats_kwargs["sim_test_regime"]
65
- _test_regime, _guppi_wgtng_policy, _divr_wgtng_policy = _sim_test_regime
71
+ _sim_test_regime = _invres_stats_kwargs.get("sim_test_regime")
72
+
73
+ _invres_spec, _guppi_wgtng_policy, _divr_wgtng_policy = (
74
+ getattr(_sim_test_regime, _f.name)
75
+ for _f in fields(_sim_test_regime) # type: ignore
76
+ )
66
77
 
67
78
  # Get observed rates
68
79
  (
@@ -76,7 +87,7 @@ def invres_stats_sim_setup(
76
87
  _table_ind_group,
77
88
  _table_evid_cond,
78
89
  _grp,
79
- _test_regime,
90
+ _invres_spec,
80
91
  )
81
92
  for _grp in (
82
93
  isl.StatsGrpSelector.FC,
@@ -97,7 +108,7 @@ def invres_stats_sim_setup(
97
108
 
98
109
  # Generate simulated rates
99
110
  _start_time = datetime.now()
100
- _upp_tests_counts = gtl.sim_invres_cnts_ll(
111
+ _upp_tests_counts = utl.sim_invres_cnts_ll(
101
112
  _invres_parm_vec, _sample_spec_here, _invres_stats_kwargs
102
113
  )
103
114
  _total_duration = datetime.now() - _start_time
@@ -109,7 +120,7 @@ def invres_stats_sim_setup(
109
120
  # Prepare and write/print output tables
110
121
  _stats_group_dict = {
111
122
  isl.StatsGrpSelector.FC: {
112
- "desc": f"{_test_regime.capitalize()} rates by firm count",
123
+ "desc": f"{_invres_spec.capitalize()} rates by firm count",
113
124
  "title_str": "By Number of Significant Competitors",
114
125
  "hval": "Firm Count",
115
126
  "hcol_width": 54,
@@ -118,7 +129,7 @@ def invres_stats_sim_setup(
118
129
  "sim_array": _upp_tests_counts.by_firm_count,
119
130
  },
120
131
  isl.StatsGrpSelector.DL: {
121
- "desc": Rf"{_test_regime.capitalize()} rates by range of $\Delta HHI$",
132
+ "desc": Rf"{_invres_spec.capitalize()} rates by range of $\Delta HHI$",
122
133
  "title_str": R"By Change in Concentration (\Deltah{})",
123
134
  "hval": R"$\Delta HHI$",
124
135
  "hval_plus": R"{ $[\Delta_L, \Delta_H)$ }",
@@ -137,7 +148,7 @@ def invres_stats_sim_setup(
137
148
  "sim_array": _upp_tests_counts.by_delta,
138
149
  },
139
150
  isl.StatsGrpSelector.ZN: {
140
- "desc": f"{_test_regime.capitalize()} rates by Approximate Presumption Zone",
151
+ "desc": f"{_invres_spec.capitalize()} rates by Approximate Presumption Zone",
141
152
  "title_str": "{} {}".format(
142
153
  R"By Approximate \textit{2010 Guidelines}",
143
154
  "Concentration-Based Standards",
@@ -151,7 +162,7 @@ def invres_stats_sim_setup(
151
162
  }
152
163
 
153
164
  _stats_table_name = dottex_format_str.format(
154
- _test_regime.capitalize(),
165
+ _invres_spec.capitalize(),
155
166
  _merger_class.replace(" ", ""),
156
167
  _data_period.split("-")[1],
157
168
  )
@@ -177,8 +188,8 @@ def invres_stats_sim_render(
177
188
  _merger_class: isl.INDGRPConstants | isl.EVIDENConstants,
178
189
  _stats_group: isl.StatsGrpSelector,
179
190
  _stats_group_dict_sub: Mapping[str, Any],
180
- _invres_parm_vec: gsl.GuidelinesSTD,
181
- _sim_test_regime: gtl.UPPTestRegime,
191
+ _invres_parm_vec: gbl.HMGThresholds,
192
+ _sim_test_regime: UPPTestRegime,
182
193
  _stats_table_file: TextIOWrapper,
183
194
  /,
184
195
  ) -> None:
@@ -203,7 +214,13 @@ def invres_stats_sim_render(
203
214
  _stats_table_content.dbar,
204
215
  _stats_table_content.cmcr_bound,
205
216
  _stats_table_content.ipr_bound,
206
- ) = (rf"{_s * 100:.1f}\%" for _s in _invres_parm_vec[1:])
217
+ ) = (
218
+ rf"{_s * 100:.1f}\%"
219
+ for _s in (
220
+ getattr(_invres_parm_vec, _f)
221
+ for _f in ("rec", "guppi", "divr", "cmcr", "ipr")
222
+ )
223
+ )
207
224
 
208
225
  # Prepare and write/print output tables
209
226
  _stats_cis_wilson_notestr = " ".join((
@@ -216,9 +233,9 @@ def invres_stats_sim_render(
216
233
  isl.LTX_ARRAY_LINEEND,
217
234
  ))
218
235
 
219
- _eg_count = (_relfreq_eg := 0.01) * _sim_sample_sz
236
+ _eg_count = int(_relfreq_eg := 0.01) * _sim_sample_sz
220
237
  _stats_sim_ci_eg = 100 * np.array(
221
- propn_ci(0.50 * _eg_count, _eg_count, method="Exact")
238
+ propn_ci(int(0.50 * _eg_count), _eg_count, method="Exact")
222
239
  )
223
240
  _stats_sim_notestr = " ".join((
224
241
  Rf"\(\cdot\) Simulated {_stats_table_content.test_res} rates are estimated by",
@@ -250,7 +267,7 @@ def invres_stats_sim_render(
250
267
  _stats_table_content.stats_cis_notewidth = _stats_group_dict_sub["notewidth"]
251
268
  _stats_cis_numobs_notestr = " ".join((
252
269
  R"\(\cdot\) Estimates for Proportion {} are based on".format(
253
- "Enforced" if _invres_select == isl.PolicySelector.ENFT else "Cleared"
270
+ "Enforced" if _invres_select == INVResolution.ENFT else "Cleared"
254
271
  ),
255
272
  f"{_obs_sample_sz:,d} total observations (investigated mergers).",
256
273
  ))
@@ -361,22 +378,9 @@ if __name__ == "__main__":
361
378
  sample_sz_base = 10**7
362
379
  pcm_dist_type, pcm_dist_parms = PCMConstants.EMPR, None
363
380
 
364
- save_data_to_file_flag = False
365
- save_data_to_file: gtl.SaveData = False
366
- if save_data_to_file_flag:
367
- h5path = DATA_DIR / Path(__file__).with_suffix(".h5").name
368
- blosc_filters = ptb.Filters(complevel=3, complib="blosc:lz4", fletcher32=True)
369
- h5datafile = ptb.open_file(
370
- str(h5path),
371
- mode="w",
372
- title="Datasets, Sound GUPPI Safeharbor",
373
- filters=blosc_filters,
374
- )
375
- save_data_to_file = (True, h5datafile, "/")
376
-
377
381
  sim_test_regime = (
378
- (isl.PolicySelector.CLRN, gtl.UPPAggrSelector.MAX, None),
379
- (isl.PolicySelector.ENFT, gtl.UPPAggrSelector.OSD, None),
382
+ UPPTestRegime(INVResolution.CLRN, utl.UPPAggrSelector.MAX, None),
383
+ UPPTestRegime(INVResolution.ENFT, utl.UPPAggrSelector.OSD, None),
380
384
  )[1]
381
385
  invres_stats_kwargs = {"sim_test_regime": sim_test_regime}
382
386
 
@@ -387,16 +391,16 @@ if __name__ == "__main__":
387
391
  continue
388
392
 
389
393
  print(
390
- f"{sim_test_regime[0].capitalize()} rates and c.i.s",
394
+ f"{sim_test_regime.resolution.capitalize()} rates and c.i.s",
391
395
  f"for the class of mergers, '{merger_class}',",
392
396
  f"for study period, {study_period}:",
393
397
  )
394
398
  stats_table_content.obs_period = study_period.split("-")
395
399
 
396
400
  invres_parm_vec = (
397
- GuidelinesStandards(2010).presumption
401
+ gbl.GuidelinesThresholds(2010).presumption
398
402
  if study_period.split("-")[1] == data_periods[1].split("-")[1]
399
- else GuidelinesStandards(1992).presumption
403
+ else gbl.GuidelinesThresholds(1992).presumption
400
404
  )
401
405
 
402
406
  mkt_sample_spec = dgl.MarketSampleSpec(
@@ -406,26 +410,17 @@ if __name__ == "__main__":
406
410
  hsr_filing_test_type=dgl.SSZConstants.HSR_NTH,
407
411
  )
408
412
 
409
- # A file to write tables to, and a hierarchy under which to store the data
410
- if save_data_to_file:
411
- h5hier_pat = re.compile(r"\W")
412
- h5hier = f"/{h5hier_pat.sub("_", f"{merger_class} {study_period}")}"
413
- save_data_to_file = (True, save_data_to_file[1], h5hier)
414
-
415
413
  table_dottex_name = invres_stats_sim_setup(
416
414
  invdata_array_dict,
417
415
  study_period,
418
416
  merger_class,
419
417
  invres_parm_vec,
420
418
  mkt_sample_spec,
421
- invres_stats_kwargs,
419
+ invres_stats_kwargs, # type: ignore
422
420
  )
423
421
  table_dottex_namelist += (table_dottex_name,)
424
422
 
425
423
  isl.render_table_pdf(
426
424
  table_dottex_namelist,
427
- dottex_format_str.format(f"{sim_test_regime[0]}".capitalize(), "All", "All"),
425
+ dottex_format_str.format(sim_test_regime.resolution.capitalize(), "All", "All"),
428
426
  )
429
-
430
- if save_data_to_file:
431
- save_data_to_file[1].close()
@@ -1,7 +1,7 @@
1
1
  """
2
2
 
3
3
  Solve for, and plot, weighted-average GUPPI boundaries using sympy,
4
- as a check against the numerical solutions in mergeron.core.guidelines_standards
4
+ as a check against the numerical solutions in mergeron.core.guidelines_boundaries
5
5
 
6
6
  """
7
7
 
@@ -1,43 +1,39 @@
1
- import re
2
1
  from datetime import datetime, timedelta
3
2
  from itertools import product as iterprod
4
3
  from pathlib import Path
5
4
  from typing import Literal
6
5
 
7
6
  import numpy as np
8
- import tables as ptb # type: ignore
9
7
 
10
- import mergeron.core.guidelines_standards as gsl
8
+ import mergeron.core.guidelines_boundaries as gbl
11
9
  import mergeron.gen.data_generation as dgl
12
- import mergeron.gen.guidelines_tests as gtl
13
10
  import mergeron.gen.investigations_stats as isl
11
+ import mergeron.gen.upp_tests as utl
14
12
  from mergeron import DATA_DIR
13
+ from mergeron.core.pseudorandom_numbers import DIST_PARMS_DEFAULT
15
14
  from mergeron.gen import (
16
- EMPTY_ARRAY_DEFAULT,
17
- FCOUNT_WTS_DEFAULT,
15
+ INVResolution,
18
16
  MarketSampleSpec,
19
17
  PCMConstants,
20
18
  PCMSpec,
21
19
  ShareSpec,
22
20
  SHRConstants,
23
- )
24
-
25
- tests_of_interest: tuple[gtl.UPPTestRegime, ...] = (
26
- gtl.UPPTestRegime(
27
- isl.PolicySelector.CLRN, gtl.UPPAggrSelector.MAX, gtl.UPPAggrSelector.MAX
28
- ),
29
- gtl.UPPTestRegime(
30
- isl.PolicySelector.ENFT, gtl.UPPAggrSelector.MIN, gtl.UPPAggrSelector.MIN
31
- ),
21
+ UPPAggrSelector,
22
+ UPPTestRegime,
32
23
  )
33
24
 
34
25
  PROG_PATH = Path(__file__)
35
26
 
27
+ tests_of_interest: tuple[UPPTestRegime, ...] = (
28
+ UPPTestRegime(INVResolution.CLRN, UPPAggrSelector.MAX, UPPAggrSelector.MAX),
29
+ UPPTestRegime(INVResolution.ENFT, UPPAggrSelector.MIN, UPPAggrSelector.MIN),
30
+ )
31
+
36
32
 
37
33
  def analyze_invres_data(
38
34
  _sample_size: int = 10**6,
39
- _hmg_std_pub_year: Literal[1992, 2010, 2023] = 1992,
40
- _test_sel: gtl.UPPTestRegime = tests_of_interest[1],
35
+ _hmg_pub_year: Literal[1992, 2010, 2023] = 1992,
36
+ _test_regime: UPPTestRegime = tests_of_interest[1],
41
37
  /,
42
38
  *,
43
39
  save_data_to_file_flag: bool = False,
@@ -51,39 +47,35 @@ def analyze_invres_data(
51
47
  _sample_size
52
48
  Number of draws (mergers) to analyze
53
49
 
54
- _hmg_std_pub_year
50
+ _hmg_pub_year
55
51
  Guidelines version for ∆HHI standard
56
52
 
57
- _test_sel
53
+ _test_regime
58
54
  Specifies analysis of enforcement rates or, alternatively, clearance rates
59
55
 
60
56
  save_data_to_file_flag
61
57
  If True, simulated data are save to file (hdf5 format)
62
58
 
63
59
  """
64
- _invres_parm_vec = gsl.GuidelinesStandards(_hmg_std_pub_year).presumption
60
+ _invres_parm_vec = gbl.GuidelinesThresholds(_hmg_pub_year).presumption
65
61
 
66
- _save_data_to_file: gtl.SaveData = False
62
+ _save_data_to_file: utl.SaveData = False
67
63
  if save_data_to_file_flag:
68
- _h5_hier_pat = re.compile(r"\W")
69
- _blosc_filters = ptb.Filters(
70
- complevel=3, complib="blosc:lz4hc", fletcher32=True
71
- )
72
- _h5_datafile = ptb.open_file(
73
- DATA_DIR / PROG_PATH.with_suffix(".h5").name,
74
- mode="w",
75
- title=f"GUPPI Safeharbor {_test_sel.resolution.capitalize()} Rate Module",
76
- filters=_blosc_filters,
77
- )
78
- _h5_hier = f"/{_h5_hier_pat.sub("_", f"Standards from {_hmg_std_pub_year} Guidelines")}"
64
+ _h5_path = DATA_DIR / PROG_PATH.with_suffix(".h5").name
65
+ (_, _h5_file, _h5_group), _h5_subgroup_name = utl.initialize_hd5(
66
+ _h5_path, _hmg_pub_year, _test_regime
67
+ ) # type: ignore
79
68
 
80
- _save_data_to_file = (True, _h5_datafile, _h5_hier)
69
+ _h5_group = _h5_file.create_group(
70
+ _h5_group, _h5_subgroup_name, f"{_invres_parm_vec}"
71
+ )
72
+ _save_data_to_file = (True, _h5_file, _h5_group)
81
73
 
82
74
  # ##
83
75
  # Print summaries of intrinsic clearance/enforcement rates by ∆HHI,
84
76
  # with asymmetric margins
85
77
  # ##
86
- for _recapture_spec_test, _pcm_dist_test_tup, _pcm_dist_firm2_test in iterprod(
78
+ for _recapture_spec_test, _pcm_dist_test, _pcm_dist_firm2_test in iterprod(
87
79
  (dgl.RECConstants.INOUT, dgl.RECConstants.FIXED),
88
80
  [
89
81
  tuple(
@@ -92,7 +84,7 @@ def analyze_invres_data(
92
84
  (
93
85
  np.array((0, 1), dtype=np.float64),
94
86
  np.array((10, 10), dtype=np.float64),
95
- np.empty(2),
87
+ None,
96
88
  ),
97
89
  strict=True,
98
90
  )
@@ -102,52 +94,64 @@ def analyze_invres_data(
102
94
  (dgl.FM2Constants.IID, dgl.FM2Constants.MNL),
103
95
  ):
104
96
  if _recapture_spec_test == "proportional" and (
105
- _pcm_dist_test_tup[0] != "Uniform" or _pcm_dist_firm2_test == "MNL-dep"
97
+ _pcm_dist_test[0] != "Uniform" or _pcm_dist_firm2_test == "MNL-dep"
106
98
  ):
99
+ continue
107
100
  # When margins are specified as symmetric, then
108
101
  # recapture_spec must be proportional and
109
102
  # margins distributions must be iid;
110
- continue
111
103
 
112
- _pcm_dist_type_test, _pcm_dist_parms_test = _pcm_dist_test_tup
104
+ _pcm_dist_type_test, _pcm_dist_parms_test = _pcm_dist_test
113
105
 
114
106
  print()
115
107
  print(
116
- f"Simulated {_test_sel.resolution.capitalize()} rates by range of ∆HHI",
108
+ f"Simulated {_test_regime.resolution.capitalize()} rates by range of ∆HHI",
117
109
  f'recapture-rate calibrated, "{_recapture_spec_test}"',
118
110
  f'Firm 2 margins, "{_pcm_dist_firm2_test}"',
119
- f"and margins distributed {_pcm_dist_type_test}{_pcm_dist_parms_test}:",
111
+ f"and margins distributed as, {_pcm_dist_type_test}{
112
+ _pcm_dist_parms_test if _pcm_dist_type_test.name == "BETA" else ""
113
+ }:",
120
114
  sep="; ",
121
115
  )
122
116
 
123
- _ind_sample_spec = MarketSampleSpec(
117
+ _mkt_sample_spec = MarketSampleSpec(
124
118
  _sample_size,
125
119
  _invres_parm_vec.rec,
126
120
  share_spec=ShareSpec(
127
- _recapture_spec_test,
128
- SHRConstants.UNI,
129
- EMPTY_ARRAY_DEFAULT,
130
- FCOUNT_WTS_DEFAULT,
121
+ _recapture_spec_test, SHRConstants.UNI, DIST_PARMS_DEFAULT, None
131
122
  ),
132
123
  pcm_spec=PCMSpec(
133
124
  _pcm_dist_type_test, _pcm_dist_firm2_test, _pcm_dist_parms_test
134
125
  ),
135
126
  )
136
127
 
137
- _invres_cnts_kwargs = {
138
- "sim_test_regime": _test_sel,
139
- "save_data_to_file": _save_data_to_file,
140
- }
128
+ if _save_data_to_file:
129
+ _h5_file.flush()
130
+
131
+ _h5_subgrp_name = "invres_rec{}_pcm{}_fm2res{}".format(
132
+ _recapture_spec_test.name,
133
+ _pcm_dist_type_test.name,
134
+ _pcm_dist_firm2_test.name,
135
+ )
136
+
137
+ _h5_subgroup = _h5_file.create_group(
138
+ _h5_group, _h5_subgrp_name, title=f"{_mkt_sample_spec}"
139
+ )
140
+ _save_data_to_file = (True, _h5_file, _h5_subgroup)
141
+
142
+ _invres_cnts_kwargs = utl.IVNRESCntsArgs(
143
+ sim_test_regime=_test_regime, save_data_to_file=_save_data_to_file
144
+ )
141
145
 
142
146
  _start_time = datetime.now()
143
147
 
144
- upp_test_counts = gtl.sim_invres_cnts_ll(
145
- _invres_parm_vec, _ind_sample_spec, _invres_cnts_kwargs
148
+ upp_test_counts = utl.sim_invres_cnts_ll(
149
+ _invres_parm_vec, _mkt_sample_spec, _invres_cnts_kwargs
146
150
  )
147
151
  _run_duration = datetime.now() - _start_time
148
152
  print(
149
153
  f"Simulation completed in {_run_duration / timedelta(seconds=1):.6f} secs.",
150
- f"on {_ind_sample_spec.sample_size:,d} draws",
154
+ f"on {_mkt_sample_spec.sample_size:,d} draws",
151
155
  sep=", ",
152
156
  )
153
157
 
@@ -166,10 +170,11 @@ def analyze_invres_data(
166
170
  ])
167
171
  print(_stats_teststr_val)
168
172
  del _stats_hdr_list, _stats_dat_list, _stats_teststr_val
169
- del _pcm_dist_test_tup, _pcm_dist_firm2_test, _recapture_spec_test
173
+ del _pcm_dist_test, _pcm_dist_firm2_test, _recapture_spec_test
170
174
  del _pcm_dist_type_test, _pcm_dist_parms_test
171
175
 
172
- if save_data_to_file_flag:
176
+ if _save_data_to_file:
177
+ _h5_file.flush()
173
178
  _save_data_to_file[1].close() # type: ignore
174
179
 
175
180
 
@@ -16,13 +16,13 @@ for data_period in invdata:
16
16
  print(leader_str, table_type, "-->")
17
17
  leader_str += "\t"
18
18
  for table_no in (isd11 := isd1[table_type]):
19
- (invdata_indugrp, invdata_evid_cond, table_data_array) = isd11[table_no]
19
+ (invdata_ind_group, invdata_evid_cond, table_data_array) = isd11[table_no]
20
20
  print(
21
21
  leader_str,
22
22
  table_no,
23
23
  " \N{EM DASH} ",
24
- invdata_indugrp,
25
- f", {invdata_evid_cond or 'N/A'}",
24
+ invdata_ind_group,
25
+ f", {invdata_evid_cond or "N/A"}",
26
26
  ", ",
27
27
  sep="",
28
28
  end="",
@@ -39,6 +39,6 @@ data_period, data_type, table_no = ("2004-2011", "HHI and Delta", "Table 3.3")
39
39
  print(f"Investigations data, {data_period}, by {data_type}, {table_no}")
40
40
  print(
41
41
  "{}, {}\n{}".format(
42
- *invdata[data_period][f"By{data_type.replace(' ', '')}"][table_no]
42
+ *invdata[data_period][f"By{data_type.replace(" ", "")}"][table_no]
43
43
  )
44
44
  )
@@ -14,7 +14,7 @@ from scipy import stats # type: ignore
14
14
 
15
15
  import mergeron.core.damodaran_margin_data as dmgn
16
16
  from mergeron import DATA_DIR
17
- from mergeron.core.guidelines_standards import boundary_plot
17
+ from mergeron.core.guidelines_boundaries import boundary_plot
18
18
 
19
19
  PROG_PATH = Path(__file__)
20
20
 
@@ -97,4 +97,4 @@ if __name__ == "__main__":
97
97
  mgn_ax.set_ylabel("Relative Frequency", fontsize=10)
98
98
 
99
99
  mgn_fig.tight_layout()
100
- plt.savefig(PROG_PATH.with_suffix(".pdf"))
100
+ plt.savefig(DATA_DIR / PROG_PATH.with_suffix(".pdf").name)