@dra2020/district-analytics 5.6.2 → 5.6.5

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.
package/dist/cli.js CHANGED
@@ -89745,10 +89745,10 @@ function scorePartisan(Vf, VfArray, options) {
89745
89745
  // Calculate alternate responsiveness metrics for reference
89746
89746
  const bigR = bAlternateMetrics ? calcBigR(Vf, estSf) : undefined;
89747
89747
  const littleR = bAlternateMetrics ? estResponsiveness(Vf, inferredSVpoints) : undefined;
89748
- const MIR = bAlternateMetrics ? calcMinimalInverseResponsiveness(Vf, littleR) : undefined;
89748
+ const MIR = (bAlternateMetrics && littleR) ? calcMinimalInverseResponsiveness(Vf, littleR) : undefined;
89749
89749
  const rD = (!bConstrained || bAlternateMetrics) ? estResponsiveDistricts(VfArray) : undefined;
89750
89750
  const rDf = bAlternateMetrics ? estResponsiveDistrictsShare(rD, N) : undefined;
89751
- const gamma = bAlternateMetrics ? calcGammaNEW(Vf, estSf, littleR) : undefined;
89751
+ const gamma = (bAlternateMetrics && littleR) ? calcGamma(Vf, estSf, littleR) : undefined;
89752
89752
  const Cn = countCompetitiveDistricts(VfArray);
89753
89753
  const cD = estCompetitiveDistricts(VfArray); // NOTE - Cd by definition uses a more narrow probability distribution vs. Rd
89754
89754
  // const cD = bConstrained ? estCompetitiveDistricts(VfArray) : rD as number;
@@ -90058,15 +90058,17 @@ exports.estUnearnedSeats = estUnearnedSeats;
90058
90058
  // ESTIMATE RESPONSIVENESS ("COMPETITIVE")
90059
90059
  // R# - Estimate responsiveness at the statewide vote share
90060
90060
  function estResponsiveness(Vf, inferredSVpoints) {
90061
- let R = undefined;
90061
+ let r = undefined;
90062
90062
  // NOTE - Seat values are already fractions [0.0–1.0] here.
90063
90063
  const lowerPt = findBracketingLowerVf(Vf, inferredSVpoints);
90064
90064
  const upperPt = findBracketingUpperVf(Vf, inferredSVpoints);
90065
- if (!(U.areRoughlyEqual((upperPt.v - lowerPt.v), 0, S.EPSILON))) {
90066
- R = ((upperPt.s - lowerPt.s) / (upperPt.v - lowerPt.v));
90067
- R = U.trim(R);
90065
+ if (lowerPt && upperPt) {
90066
+ if (!(U.areRoughlyEqual((upperPt.v - lowerPt.v), 0, S.EPSILON))) {
90067
+ r = ((upperPt.s - lowerPt.s) / (upperPt.v - lowerPt.v));
90068
+ r = U.trim(r);
90069
+ }
90068
90070
  }
90069
- return R;
90071
+ return r;
90070
90072
  }
90071
90073
  exports.estResponsiveness = estResponsiveness;
90072
90074
  // Find the S(V) point that brackets a Vf value on the lower end
@@ -90261,30 +90263,36 @@ function estSeatBias(inferredSVpoints, nDistricts) {
90261
90263
  exports.estSeatBias = estSeatBias;
90262
90264
  // VOTES BIAS -- John Nagle's simple vote bias @ 50% (alpha2), a percentage.
90263
90265
  function estVotesBias(inferredSVpoints, nDistricts) {
90264
- let extraVf = 0.0;
90266
+ let extraVf = undefined;
90265
90267
  // Interpolate the extra Vf required @ Sf = 0.5
90266
90268
  const lowerPt = findBracketingLowerSf(0.5, inferredSVpoints);
90267
90269
  const upperPt = findBracketingUpperSf(0.5, inferredSVpoints);
90268
- if ((upperPt.s - lowerPt.s) != 0) {
90269
- const ratio = (upperPt.v - lowerPt.v) / (upperPt.s - lowerPt.s);
90270
- const deltaS = 0.5 - lowerPt.s;
90271
- extraVf = lowerPt.v + (ratio * deltaS) - 0.5;
90270
+ if (lowerPt && upperPt) {
90271
+ extraVf = 0.0;
90272
+ if ((upperPt.s - lowerPt.s) != 0) {
90273
+ const ratio = (upperPt.v - lowerPt.v) / (upperPt.s - lowerPt.s);
90274
+ const deltaS = 0.5 - lowerPt.s;
90275
+ extraVf = lowerPt.v + (ratio * deltaS) - 0.5;
90276
+ }
90277
+ extraVf = U.trim(extraVf);
90272
90278
  }
90273
- extraVf = U.trim(extraVf);
90274
90279
  return extraVf;
90275
90280
  }
90276
90281
  exports.estVotesBias = estVotesBias;
90277
90282
  // GEOMETRIC SEATS BIAS (@ V = statewide vote share)
90278
90283
  function estGeometricSeatsBias(Vf, inferredSVpoints) {
90284
+ let BsGf = undefined;
90279
90285
  const bgsSVpoints = inferGeometricSeatsBiasPoints(inferredSVpoints);
90280
90286
  // Interpolate the seat fraction @ Vf
90281
90287
  const lowerPt = findBracketingLowerVf(Vf, bgsSVpoints);
90282
90288
  const upperPt = findBracketingUpperVf(Vf, bgsSVpoints);
90283
- const ratio = (upperPt.s - lowerPt.s) / (upperPt.v - lowerPt.v);
90284
- const deltaV = Vf - lowerPt.v;
90285
- const deltaS = ratio * deltaV;
90286
- const BsGf = lowerPt.s + deltaS;
90287
- return U.trim(BsGf);
90289
+ if (lowerPt && upperPt) {
90290
+ const ratio = (upperPt.s - lowerPt.s) / (upperPt.v - lowerPt.v);
90291
+ const deltaV = Vf - lowerPt.v;
90292
+ const deltaS = ratio * deltaV;
90293
+ BsGf = U.trim(lowerPt.s + deltaS);
90294
+ }
90295
+ return BsGf;
90288
90296
  }
90289
90297
  exports.estGeometricSeatsBias = estGeometricSeatsBias;
90290
90298
  function inferGeometricSeatsBiasPoints(inferredSVpoints) {
@@ -90510,11 +90518,11 @@ function isBalanced(Vf) {
90510
90518
  // return (0.5 + plan.responsiveness * (plan.statewide_vote_share - 0.5) \
90511
90519
  // - (plan.predicted_D_seats / plan.districts)) \
90512
90520
  // * 100
90513
- function calcGammaNEW(Vf, Sf, r) {
90521
+ function calcGamma(Vf, Sf, r) {
90514
90522
  const g = 0.5 + (r * (Vf - 0.5)) - Sf;
90515
90523
  return U.trim(g);
90516
90524
  }
90517
- exports.calcGammaNEW = calcGammaNEW;
90525
+ exports.calcGamma = calcGamma;
90518
90526
  // HELPERS
90519
90527
  function printPartisanScorecardHeader() {
90520
90528
  console.log('XX, Name, N, V%, ^S#, S#, B%, B$, UE#, I$, C#, Cd, Md, C$, <P$');
@@ -102847,7 +102855,14 @@ class AnalyticsSession {
102847
102855
  // Using the the data in the analytics session, calculate all the
102848
102856
  // analytics & validations, saving/updating the individual test results.
102849
102857
  analyzePlan(bLog = false, overridesJSON) {
102858
+ // Return values:
102859
+ // * true = everything good
102860
+ // * false = should not have been called with empty plan
102861
+ // * exception = exception caught and logged on the console
102850
102862
  try {
102863
+ // Guard against being handed a map w/o any precincts assigned
102864
+ if (U.isObjectEmpty(this.plan._planByGeoID))
102865
+ return false;
102851
102866
  preprocess_1.doPreprocessData(this, bLog);
102852
102867
  analyze_1.doAnalyzeDistricts(this, bLog);
102853
102868
  analyze_1.doAnalyzePlan(this, bLog);
@@ -102855,9 +102870,10 @@ class AnalyticsSession {
102855
102870
  this._scorecard = score_1.scorePlan(this, this._profile, bLog, overridesJSON);
102856
102871
  results_1.doAnalyzePostProcessing(this, bLog);
102857
102872
  }
102858
- catch (_a) {
102859
- console.log("Exception caught by analyzePlan()");
102860
- return false;
102873
+ catch (e) {
102874
+ console.log("Exception caught by analyzePlan().");
102875
+ console.log(e.message);
102876
+ throw e;
102861
102877
  }
102862
102878
  return true;
102863
102879
  }