@dra2020/district-analytics 14.1.3 → 15.0.1

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.
@@ -44,8 +44,6 @@ var __importStar = (this && this.__importStar) || function (mod) {
44
44
  Object.defineProperty(exports, "__esModule", ({ value: true }));
45
45
  exports.AnalyticsSession = void 0;
46
46
  const baseclient_1 = __webpack_require__(/*! @dra2020/baseclient */ "@dra2020/baseclient");
47
- // import * as DT from '@dra2020/dra-types';
48
- const Score = __importStar(__webpack_require__(/*! @dra2020/dra-score */ "@dra2020/dra-score"));
49
47
  const dra_analytics_1 = __webpack_require__(/*! @dra2020/dra-analytics */ "@dra2020/dra-analytics");
50
48
  const preprocess_1 = __webpack_require__(/*! ./preprocess */ "./src/preprocess.ts");
51
49
  const analyze_1 = __webpack_require__(/*! ./analyze */ "./src/analyze.ts");
@@ -56,7 +54,6 @@ const minority_1 = __webpack_require__(/*! ./minority */ "./src/minority.ts");
56
54
  const D = __importStar(__webpack_require__(/*! ./_data */ "./src/_data.ts"));
57
55
  const M = __importStar(__webpack_require__(/*! ./minority */ "./src/minority.ts"));
58
56
  const U = __importStar(__webpack_require__(/*! ./utils */ "./src/utils.ts"));
59
- // import * as S from './settings';
60
57
  class AnalyticsSession {
61
58
  constructor(SessionRequest) {
62
59
  this.legislativeDistricts = false; // 2020
@@ -110,58 +107,41 @@ class AnalyticsSession {
110
107
  (0, analyze_1.doAnalyzeDistricts)(this, bLog);
111
108
  // This does a little stuff that didn't get factored out into dra-score and then dra-analytics
112
109
  (0, analyze_1.doAnalyzePlan)(this, bLog);
113
- // THE MAIN ANALYTICS ARE NEXT
110
+ // THE MAIN ANALYTICS
114
111
  // Even though we don't save the profile (as I thought we would),
115
112
  // we allow it to be exported, so keep generating it, and use it
116
113
  // to gather the inputs to new analytics (as well as the legacy).
117
114
  this._profile = (0, score_1.profilePlan)(this, bLog);
118
- let legacyScorecard = {};
119
115
  let legacyScorecardAlt = {};
120
116
  let newScorecard = {};
121
- // LEGACY - Run legacy analytics
122
- if (this.config.legacyanalytics) {
123
- if (bLog)
124
- console.log("Running legacy analytics ...");
125
- legacyScorecard = (0, score_1.scorePlan)(this, this._profile, bLog, overridesJSON);
126
- }
127
117
  // Construct a new/alternate scorecard
128
- if (this.config.newanalytics) {
129
- if (bLog)
130
- console.log("Running new analytics ...");
131
- newScorecard = (0, score_1.computeMetrics)(this._profile, this.getGoodShapes(), bLog); // w/o ratings
132
- newScorecard = (0, score_1.rateKeyDimensions)(newScorecard, this._profile, bLog); // w/ ratings
133
- legacyScorecardAlt = (0, score_1.thunkScorecard)(newScorecard, bLog);
134
- // Add minority notes
135
- legacyScorecardAlt.minority.details['majorityMinority'] = M.getMajorityMinority(this);
136
- legacyScorecardAlt.minority.details['vraPreclearance'] = M.getVRASection5(this);
137
- // Compare the new & legacy scorecards
138
- (0, score_1.compareScorecards)(legacyScorecardAlt, legacyScorecard, bLog);
139
- }
140
- // Use the new scorecard, after creating it
141
- this._scorecard = (this.config.newanalytics) ? legacyScorecardAlt : legacyScorecard;
142
- // Post-scorecard housekeeping - copied from scorePlan()
143
- if (this.config.newanalytics) {
144
- // Before returning, create a dummy population deviation test, for
145
- // doHasEqualPopulations() to use later.This is preserving the old calling sequence.
146
- let test = this.getTest(4 /* PopulationDeviation */);
147
- // Get the raw population deviation
148
- const popDev = this._scorecard.populationDeviation.raw;
149
- // Populate the test entry
150
- test['score'] = popDev;
151
- test['details'] = { 'maxDeviation': this._scorecard.populationDeviation.notes['maxDeviation'] };
152
- // Populate the N+1 summary "district" in district.statistics
153
- let totalPop = this.districts.table.totalPop;
154
- let popDevPct = this.districts.table.popDevPct;
155
- let totalVAP = this.districts.table.totalVAP;
156
- const summaryRow = this.districts.numberOfRows() - 1;
157
- totalPop[summaryRow] = this._profile.population.targetSize;
158
- popDevPct[summaryRow] = popDev;
159
- totalVAP[summaryRow] = Math.round(totalVAP[summaryRow] / this._profile.nDistricts);
160
- // Added w/ new scorecard
161
- // Use 'roughly' equal population from dra-analytics
162
- let test2 = this.getTest(3 /* EqualPopulation */);
163
- test2['score'] = newScorecard.populationDeviation.roughlyEqual;
164
- }
118
+ newScorecard = (0, score_1.computeMetrics)(this._profile, this.getGoodShapes(), bLog); // w/o ratings
119
+ newScorecard = (0, score_1.rateKeyDimensions)(newScorecard, this._profile, bLog); // w/ ratings
120
+ legacyScorecardAlt = (0, score_1.thunkScorecard)(newScorecard, bLog);
121
+ // Add minority notes
122
+ legacyScorecardAlt.minority.details['majorityMinority'] = M.getMajorityMinority(this);
123
+ legacyScorecardAlt.minority.details['vraPreclearance'] = M.getVRASection5(this);
124
+ this._scorecard = legacyScorecardAlt;
125
+ // Before returning, create a dummy population deviation test, for
126
+ // doHasEqualPopulations() to use later.This is preserving the old calling sequence.
127
+ let test = this.getTest(4 /* PopulationDeviation */);
128
+ // Get the raw population deviation
129
+ const popDev = this._scorecard.populationDeviation.raw;
130
+ // Populate the test entry
131
+ test['score'] = popDev;
132
+ test['details'] = { 'maxDeviation': this._scorecard.populationDeviation.notes['maxDeviation'] };
133
+ // Populate the N+1 summary "district" in district.statistics
134
+ let totalPop = this.districts.table.totalPop;
135
+ let popDevPct = this.districts.table.popDevPct;
136
+ let totalVAP = this.districts.table.totalVAP;
137
+ const summaryRow = this.districts.numberOfRows() - 1;
138
+ totalPop[summaryRow] = this._profile.population.targetSize;
139
+ popDevPct[summaryRow] = popDev;
140
+ totalVAP[summaryRow] = Math.round(totalVAP[summaryRow] / this._profile.nDistricts);
141
+ // Added w/ new scorecard
142
+ // Use 'roughly' equal population from dra-analytics
143
+ let test2 = this.getTest(3 /* EqualPopulation */);
144
+ test2['score'] = newScorecard.populationDeviation.roughlyEqual;
165
145
  // END main analytics
166
146
  (0, results_1.doAnalyzePostProcessing)(this, bLog);
167
147
  }
@@ -267,18 +247,9 @@ class AnalyticsSession {
267
247
  // Return a pointer to the the test entry for this test
268
248
  return this.tests[testID];
269
249
  }
270
- // LEGACY - Threshold defined in dra-analytics for new analytics
271
250
  // NOTE - Not sure why this has to be up here ...
272
251
  populationDeviationThreshold() {
273
- let threshold;
274
- if (this.config.legacyanalytics && !this.config.newanalytics) {
275
- // NOTE - This assumes the plan has been profiled
276
- const scorer = new Score.Scorer();
277
- threshold = scorer.populationDeviationThreshold(this.legislativeDistricts); // TODO - 2020
278
- }
279
- else {
280
- threshold = dra_analytics_1.Rate.popdevThreshold(this.legislativeDistricts);
281
- }
252
+ const threshold = dra_analytics_1.Rate.popdevThreshold(this.legislativeDistricts);
282
253
  return threshold;
283
254
  }
284
255
  }
@@ -330,7 +301,6 @@ const U = __importStar(__webpack_require__(/*! ./utils */ "./src/utils.ts"));
330
301
  const S = __importStar(__webpack_require__(/*! ./settings */ "./src/settings.ts"));
331
302
  const compact_1 = __webpack_require__(/*! ./compact */ "./src/compact.ts");
332
303
  const dra_analytics_2 = __webpack_require__(/*! @dra2020/dra-analytics */ "@dra2020/dra-analytics");
333
- // import { fptpWin } from './political'
334
304
  // DEBUG COUNTERS
335
305
  let nMissingDataset = 0;
336
306
  let nMissingProperty = 0;
@@ -1265,7 +1235,7 @@ exports.doDeriveSecondaryTests = doDeriveSecondaryTests;
1265
1235
 
1266
1236
 
1267
1237
  //
1268
- // SPLITTING of counties & districts
1238
+ // SPLITTING
1269
1239
  //
1270
1240
  var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
1271
1241
  if (k2 === undefined) k2 = k;
@@ -1289,7 +1259,7 @@ var __importStar = (this && this.__importStar) || function (mod) {
1289
1259
  Object.defineProperty(exports, "__esModule", ({ value: true }));
1290
1260
  exports.doFindSplitVTDs = exports.doFindCountiesSplitUnexpectedly = void 0;
1291
1261
  const U = __importStar(__webpack_require__(/*! ./utils */ "./src/utils.ts"));
1292
- // NOTE - The active code is below the long multi-line section to be deleted.
1262
+ // The main county-district splitting code is in the dra-analytics package.
1293
1263
  // ANALYZE SIMPLE COUNTY & VTD SPLITTING
1294
1264
  /*
1295
1265
 
@@ -1502,10 +1472,10 @@ var __importStar = (this && this.__importStar) || function (mod) {
1502
1472
  return result;
1503
1473
  };
1504
1474
  Object.defineProperty(exports, "__esModule", ({ value: true }));
1505
- exports.scoreKIWYSICompactness = exports.extractDistrictProperties = void 0;
1475
+ exports.extractDistrictProperties = void 0;
1506
1476
  const baseclient_1 = __webpack_require__(/*! @dra2020/baseclient */ "@dra2020/baseclient");
1507
- const dra_analytics_1 = __webpack_require__(/*! @dra2020/dra-analytics */ "@dra2020/dra-analytics");
1508
1477
  const U = __importStar(__webpack_require__(/*! ./utils */ "./src/utils.ts"));
1478
+ // The main compactness code is in the dra-analytics package.
1509
1479
  // HELPER TO EXTRACT PROPERTIES OF DISTRICT SHAPES
1510
1480
  function extractDistrictProperties(s, bLog = false) {
1511
1481
  // NOTE - I am assuming that district IDs are integers 1–N
@@ -1533,35 +1503,6 @@ function isAShape(poly) {
1533
1503
  return false;
1534
1504
  return poly.geometry && poly.geometry.coordinates && !U.isArrayEmpty(poly.geometry.coordinates);
1535
1505
  }
1536
- // SCORE KIWYSI COMPACTNESS
1537
- // LEGACY
1538
- function scoreKIWYSICompactness(s, bLog = false) {
1539
- const rawShapes = s.districts.getDistrictShapes();
1540
- // Filter the real shapes & throw everything else away
1541
- let goodShapes = {};
1542
- goodShapes['type'] = "FeatureCollection";
1543
- goodShapes['features'] = [];
1544
- for (let i = 0; i < rawShapes.features.length; i++) {
1545
- const shape = rawShapes.features[i];
1546
- if (isAShape(shape)) {
1547
- const d = baseclient_1.Poly.polyDescribe(shape);
1548
- let f = {
1549
- type: 'Feature',
1550
- properties: { districtID: `${i + 1}` },
1551
- geometry: {
1552
- type: (d.npoly > 1) ? 'MultiPolygon' : 'Polygon',
1553
- coordinates: shape.geometry.coordinates
1554
- }
1555
- };
1556
- goodShapes.features.push(f);
1557
- }
1558
- }
1559
- const scores = dra_analytics_1.Compactness.kiwysiScoreShapes(goodShapes, 0 /* Revised */);
1560
- // Round & invert the scores here at the source vs. later on, higher up.
1561
- // Raw KIWYSI scores will be 1–100 with smaller better, so map to 1–100 bigger better.
1562
- return scores.map(n => 100 - Math.round(n) + 1);
1563
- }
1564
- exports.scoreKIWYSICompactness = scoreKIWYSICompactness;
1565
1506
  // SAVE THESE NOTES, IN CASE WE NEED TO REWORK HOW WE PERFORM THESE CALCS.
1566
1507
  // THEY REFLECT HOW I DID THEM IN PYTHON.
1567
1508
  //
@@ -1614,20 +1555,6 @@ function doHasEqualPopulations(s, bLog = false) {
1614
1555
  let popDevTest = s.getTest(4 /* PopulationDeviation */);
1615
1556
  const popDevPct = popDevTest['score'];
1616
1557
  const popDevNormalized = popDevTest['normalizedScore'];
1617
- // LEGACY - Has 'roughly' equal populations is calculated in dra-analytics
1618
- if (s.config.legacyanalytics && !s.config.newanalytics) {
1619
- // 09-19-2020 - Added to catch edge case of only one non-empty district
1620
- const p = s._profile;
1621
- const totPopByDistrict = p.population.byDistrict.filter(x => x > 0);
1622
- const bTwoOrMoreDistricts = (totPopByDistrict.length > 1) ? true : false;
1623
- // Populate the test entry
1624
- if (bTwoOrMoreDistricts && (popDevNormalized > 0)) {
1625
- test['score'] = true;
1626
- }
1627
- else {
1628
- test['score'] = false;
1629
- }
1630
- } // end
1631
1558
  test['details']['deviation'] = popDevPct;
1632
1559
  test['details']['thresholds'] = popDevTest['details']['scale'];
1633
1560
  // Populate the N+1 summary "district" in district.statistics
@@ -1736,7 +1663,7 @@ function doAnalyzeRacialPolarization(s, districtID, groups, bLog = false) {
1736
1663
  return dra_analytics_1.Minority.analyzeRacialVoting(points, districtID, groups);
1737
1664
  }
1738
1665
  exports.doAnalyzeRacialPolarization = doAnalyzeRacialPolarization;
1739
- // 11-18-2020 - Moved RPV to racial-voting package.
1666
+ // RPV is in the dra-analytics package.
1740
1667
 
1741
1668
 
1742
1669
  /***/ }),
@@ -2158,11 +2085,8 @@ var __importStar = (this && this.__importStar) || function (mod) {
2158
2085
  return result;
2159
2086
  };
2160
2087
  Object.defineProperty(exports, "__esModule", ({ value: true }));
2161
- exports.compareScorecards = exports.thunkScorecard = exports.rateKeyDimensions = exports.computeMetrics = exports.scorePlan = exports.getStatewideDemographics = exports.profilePlan = void 0;
2162
- const Score = __importStar(__webpack_require__(/*! @dra2020/dra-score */ "@dra2020/dra-score"));
2088
+ exports.thunkScorecard = exports.rateKeyDimensions = exports.computeMetrics = exports.getStatewideDemographics = exports.profilePlan = void 0;
2163
2089
  const U = __importStar(__webpack_require__(/*! ./utils */ "./src/utils.ts"));
2164
- const M = __importStar(__webpack_require__(/*! ./minority */ "./src/minority.ts"));
2165
- const C = __importStar(__webpack_require__(/*! ./compact */ "./src/compact.ts"));
2166
2090
  const dra_analytics_1 = __webpack_require__(/*! @dra2020/dra-analytics */ "@dra2020/dra-analytics");
2167
2091
  // PROFILE A PLAN
2168
2092
  const KEEP_DECIMALS = 6;
@@ -2275,55 +2199,7 @@ function getStatewideDemographics(s, bLog = false) {
2275
2199
  return demographics;
2276
2200
  }
2277
2201
  exports.getStatewideDemographics = getStatewideDemographics;
2278
- // SCORE A PLAN - Legacy using dra-score
2279
- // LEGACY
2280
- function scorePlan(s, p, bLog = false, overridesJSON) {
2281
- let scorer = new Score.Scorer();
2282
- const scorecard = scorer.score(p, overridesJSON);
2283
- // LEGACY POST-SCORECARD HOUSEKEEPING
2284
- if (s.config.legacyanalytics && !s.config.newanalytics) {
2285
- // Before returning, create a dummy population deviation test, for
2286
- // doHasEqualPopulations() to use later.This is preserving the old calling sequence.
2287
- let test = s.getTest(4 /* PopulationDeviation */);
2288
- // Get the raw population deviation
2289
- const popDev = scorecard.populationDeviation.raw;
2290
- // Populate the test entry
2291
- test['score'] = popDev;
2292
- test['details'] = { 'maxDeviation': scorecard.populationDeviation.notes['maxDeviation'] };
2293
- // Populate the N+1 summary "district" in district.statistics
2294
- let totalPop = s.districts.table.totalPop;
2295
- let popDevPct = s.districts.table.popDevPct;
2296
- let totalVAP = s.districts.table.totalVAP;
2297
- const summaryRow = s.districts.numberOfRows() - 1;
2298
- totalPop[summaryRow] = p.population.targetSize;
2299
- popDevPct[summaryRow] = popDev;
2300
- totalVAP[summaryRow] = Math.round(totalVAP[summaryRow] / p.nDistricts);
2301
- } // end
2302
- // Add minority notes
2303
- scorecard.minority.details['majorityMinority'] = M.getMajorityMinority(s);
2304
- scorecard.minority.details['vraPreclearance'] = M.getVRASection5(s);
2305
- try {
2306
- // Add KIWYSI compactness score
2307
- const kiwysiScores = C.scoreKIWYSICompactness(s, bLog);
2308
- // 10-21-2020 - Computing the average score here
2309
- const avgKIWYSIScore = Math.round(U.avgArray(kiwysiScores));
2310
- scorecard.compactness.details['kiwysi'] = avgKIWYSIScore;
2311
- // 10-21-2020 - Added KIWYSI scores to the by-district details
2312
- let byDistrict = scorecard.compactness.details['byDistrict'];
2313
- const nDistricts = byDistrict.length;
2314
- for (let districtID = 1; districtID <= nDistricts; districtID++) {
2315
- byDistrict[districtID - 1].kiwysiScore = kiwysiScores[districtID - 1];
2316
- }
2317
- }
2318
- catch (e) {
2319
- console.log("Exception caught scoring KIWYSI compactness.");
2320
- console.log(e.message);
2321
- // throw e;
2322
- }
2323
- return scorecard;
2324
- }
2325
- exports.scorePlan = scorePlan;
2326
- // SCORE A PLAN - New using dra-analytics
2202
+ // SCORE A PLAN using dra-analytics
2327
2203
  function computeMetrics(p, districtShapes, bLog = false) {
2328
2204
  if (bLog)
2329
2205
  console.log("Computing metrics ...");
@@ -2468,287 +2344,6 @@ function thunkScorecard(newScorecard, bLog = false) {
2468
2344
  return scorecard;
2469
2345
  }
2470
2346
  exports.thunkScorecard = thunkScorecard;
2471
- function compareScorecards(altLegacyScorecard, legacyScorecard, bLog = false) {
2472
- if (bLog)
2473
- console.log("Comparing new & legacy scorecards ...");
2474
- // A pretty loose tolerance, because we're not trimming values in the new analytics
2475
- const DECIMAL_PLACES = 2;
2476
- const DEFAULT_TOLERANCE = toleranceFn(DECIMAL_PLACES);
2477
- // COMPARE PARTISAN SCORECARD
2478
- // Compare BIAS section
2479
- matchFloats("bestS", altLegacyScorecard.partisan.bias.bestS, legacyScorecard.partisan.bias.bestS, DEFAULT_TOLERANCE);
2480
- matchFloats("bestSf", altLegacyScorecard.partisan.bias.bestSf, legacyScorecard.partisan.bias.bestSf, DEFAULT_TOLERANCE);
2481
- matchFloats("estS", altLegacyScorecard.partisan.bias.estS, legacyScorecard.partisan.bias.estS, DEFAULT_TOLERANCE);
2482
- matchFloats("estSf", altLegacyScorecard.partisan.bias.estSf, legacyScorecard.partisan.bias.estSf, DEFAULT_TOLERANCE);
2483
- matchFloats("deviation", altLegacyScorecard.partisan.bias.deviation, legacyScorecard.partisan.bias.deviation, DEFAULT_TOLERANCE);
2484
- matchInts("proportionality/score", altLegacyScorecard.partisan.bias.score, legacyScorecard.partisan.bias.score);
2485
- matchFloats("tOf", altLegacyScorecard.partisan.bias.tOf, legacyScorecard.partisan.bias.tOf, DEFAULT_TOLERANCE);
2486
- matchFloats("fptpS", altLegacyScorecard.partisan.bias.fptpS, legacyScorecard.partisan.bias.fptpS, DEFAULT_TOLERANCE);
2487
- matchFloats("bS50", altLegacyScorecard.partisan.bias.bS50, legacyScorecard.partisan.bias.bS50, DEFAULT_TOLERANCE);
2488
- matchFloats("deviation", altLegacyScorecard.partisan.bias.deviation, legacyScorecard.partisan.bias.deviation, DEFAULT_TOLERANCE);
2489
- matchUndefinableFloats("decl", altLegacyScorecard.partisan.bias.decl, legacyScorecard.partisan.bias.decl, toleranceFn(1));
2490
- let rvPointsAlt = altLegacyScorecard.partisan.bias.rvPoints;
2491
- let rvPoints = legacyScorecard.partisan.bias.rvPoints;
2492
- if (matchUndefinedness("rvPoints", rvPointsAlt, rvPoints)) {
2493
- rvPointsAlt = rvPointsAlt;
2494
- rvPoints = rvPoints;
2495
- matchFloats("rvPoints/Sb", rvPointsAlt.Sb, rvPoints.Sb, DEFAULT_TOLERANCE);
2496
- matchFloats("rvPoints/Ra", rvPointsAlt.Ra, rvPoints.Ra, DEFAULT_TOLERANCE);
2497
- matchFloats("rvPoints/Rb", rvPointsAlt.Rb, rvPoints.Rb, DEFAULT_TOLERANCE);
2498
- matchFloats("rvPoints/Va", rvPointsAlt.Va, rvPoints.Va, DEFAULT_TOLERANCE);
2499
- matchFloats("rvPoints/Vb", rvPointsAlt.Vb, rvPoints.Vb, DEFAULT_TOLERANCE);
2500
- }
2501
- matchFloats("gSym", altLegacyScorecard.partisan.bias.gSym, legacyScorecard.partisan.bias.gSym, DEFAULT_TOLERANCE);
2502
- matchUndefinableFloats("gamma", altLegacyScorecard.partisan.bias.gamma, legacyScorecard.partisan.bias.gamma, DEFAULT_TOLERANCE);
2503
- matchFloats("eG", altLegacyScorecard.partisan.bias.eG, legacyScorecard.partisan.bias.eG, DEFAULT_TOLERANCE);
2504
- matchUndefinableFloats("bSV", altLegacyScorecard.partisan.bias.bSV, legacyScorecard.partisan.bias.bSV, DEFAULT_TOLERANCE);
2505
- matchFloats("prop", altLegacyScorecard.partisan.bias.prop, legacyScorecard.partisan.bias.prop, DEFAULT_TOLERANCE);
2506
- matchFloats("mMs", altLegacyScorecard.partisan.bias.mMs, legacyScorecard.partisan.bias.mMs, DEFAULT_TOLERANCE);
2507
- matchFloats("mMd", altLegacyScorecard.partisan.bias.mMd, legacyScorecard.partisan.bias.mMd, DEFAULT_TOLERANCE);
2508
- matchUndefinableFloats("lO", altLegacyScorecard.partisan.bias.lO, legacyScorecard.partisan.bias.lO, DEFAULT_TOLERANCE);
2509
- // Compare Impact section
2510
- matchFloats("unearnedS", altLegacyScorecard.partisan.impact.unearnedS, legacyScorecard.partisan.impact.unearnedS, DEFAULT_TOLERANCE);
2511
- // Note - We don't use the impact score, so we don't compute it in the new scorecard.
2512
- // matchInts("impact/score", altLegacyScorecard.partisan.impact.score as number, legacyScorecard.partisan.impact.score);
2513
- // Compare Responsiveness section
2514
- matchUndefinableFloats("bigR", altLegacyScorecard.partisan.responsiveness.bigR, legacyScorecard.partisan.responsiveness.bigR, DEFAULT_TOLERANCE);
2515
- matchUndefinableFloats("littleR", altLegacyScorecard.partisan.responsiveness.littleR, legacyScorecard.partisan.responsiveness.littleR, DEFAULT_TOLERANCE);
2516
- matchUndefinableFloats("mIR", altLegacyScorecard.partisan.responsiveness.mIR, legacyScorecard.partisan.responsiveness.mIR, DEFAULT_TOLERANCE);
2517
- matchFloats("rD", altLegacyScorecard.partisan.responsiveness.rD, legacyScorecard.partisan.responsiveness.rD, DEFAULT_TOLERANCE);
2518
- matchFloats("rDf", altLegacyScorecard.partisan.responsiveness.rDf, legacyScorecard.partisan.responsiveness.rDf, DEFAULT_TOLERANCE);
2519
- matchFloats("cSimple", altLegacyScorecard.partisan.responsiveness.cSimple, legacyScorecard.partisan.responsiveness.cSimple, DEFAULT_TOLERANCE);
2520
- matchFloats("cD", altLegacyScorecard.partisan.responsiveness.cD, legacyScorecard.partisan.responsiveness.cD, DEFAULT_TOLERANCE);
2521
- matchFloats("cDf", altLegacyScorecard.partisan.responsiveness.cDf, legacyScorecard.partisan.responsiveness.cDf, DEFAULT_TOLERANCE);
2522
- matchInts("competitiveness/score", altLegacyScorecard.partisan.responsiveness.score, legacyScorecard.partisan.responsiveness.score);
2523
- matchPointArrays("dSVpoints", altLegacyScorecard.partisan.dSVpoints, legacyScorecard.partisan.dSVpoints, DEFAULT_TOLERANCE);
2524
- matchPointArrays("rSVpoints", altLegacyScorecard.partisan.rSVpoints, legacyScorecard.partisan.rSVpoints, DEFAULT_TOLERANCE);
2525
- matchUndefinableFloats("averageDVf", altLegacyScorecard.partisan.averageDVf, legacyScorecard.partisan.averageDVf, DEFAULT_TOLERANCE);
2526
- matchUndefinableFloats("averageRVf", altLegacyScorecard.partisan.averageRVf, legacyScorecard.partisan.averageRVf, DEFAULT_TOLERANCE);
2527
- matchDicts("partisan/details", altLegacyScorecard.partisan.details, legacyScorecard.partisan.details);
2528
- // COMPARE MINORITY SCORECARD
2529
- matchObjectsAndArrays("pivotByDemographic", altLegacyScorecard.minority.pivotByDemographic, legacyScorecard.minority.pivotByDemographic);
2530
- matchFloats("opportunityDistricts", altLegacyScorecard.minority.opportunityDistricts, legacyScorecard.minority.opportunityDistricts, DEFAULT_TOLERANCE);
2531
- matchFloats("coalitionDistricts", altLegacyScorecard.minority.coalitionDistricts, legacyScorecard.minority.coalitionDistricts, DEFAULT_TOLERANCE);
2532
- matchInts("minority/score", altLegacyScorecard.minority.score, legacyScorecard.minority.score);
2533
- matchDicts("minority/details", altLegacyScorecard.minority.details, legacyScorecard.minority.details);
2534
- // COMPARE COMPACTNESS SCORECARD
2535
- matchFloats("reock", altLegacyScorecard.compactness.reock.raw, legacyScorecard.compactness.reock.raw, DEFAULT_TOLERANCE);
2536
- matchInts("reock/normalized", altLegacyScorecard.compactness.reock.normalized, legacyScorecard.compactness.reock.normalized);
2537
- matchFloats("polsby", altLegacyScorecard.compactness.polsby.raw, legacyScorecard.compactness.polsby.raw, DEFAULT_TOLERANCE);
2538
- matchInts("polsby/normalized", altLegacyScorecard.compactness.polsby.normalized, legacyScorecard.compactness.polsby.normalized);
2539
- matchInts("compactness/score", altLegacyScorecard.compactness.score, legacyScorecard.compactness.score);
2540
- // Compare 'byDistrict' results separately
2541
- const _altCompactnessByDistrict = dra_analytics_1.Utils.deepCopy(altLegacyScorecard.compactness.details['byDistrict']);
2542
- const _CompactnessByDistrict = dra_analytics_1.Utils.deepCopy(legacyScorecard.compactness.details['byDistrict']);
2543
- const _altCompactnessDetails = dra_analytics_1.Utils.deepCopy(altLegacyScorecard.compactness.details);
2544
- const _CompactnessDetails = dra_analytics_1.Utils.deepCopy(legacyScorecard.compactness.details);
2545
- delete _altCompactnessDetails['byDistrict'];
2546
- delete _CompactnessDetails['byDistrict'];
2547
- matchDicts("compactness/details", _altCompactnessDetails, _CompactnessDetails);
2548
- matchCompactnessByDistrict("compactness/byDistrict", _altCompactnessByDistrict, _CompactnessByDistrict, DEFAULT_TOLERANCE);
2549
- // COMPARE SPLITTING SCORECARD
2550
- matchFloats("county", altLegacyScorecard.splitting.county.raw, legacyScorecard.splitting.county.raw, DEFAULT_TOLERANCE);
2551
- matchInts("county/normalized", altLegacyScorecard.splitting.county.normalized, legacyScorecard.splitting.county.normalized);
2552
- matchFloats("district", altLegacyScorecard.splitting.district.raw, legacyScorecard.splitting.district.raw, DEFAULT_TOLERANCE);
2553
- matchInts("district/normalized", altLegacyScorecard.splitting.district.normalized, legacyScorecard.splitting.district.normalized);
2554
- matchInts("splitting/score", altLegacyScorecard.splitting.score, legacyScorecard.splitting.score);
2555
- matchDicts("splitting/details", altLegacyScorecard.splitting.details, legacyScorecard.splitting.details);
2556
- // COMPARE POPULATION SCORECARD
2557
- matchFloats("popdev", altLegacyScorecard.populationDeviation.raw, legacyScorecard.populationDeviation.raw, DEFAULT_TOLERANCE);
2558
- matchInts("popdev/score", altLegacyScorecard.populationDeviation.normalized, legacyScorecard.populationDeviation.normalized);
2559
- matchDicts("popdev/notes", altLegacyScorecard.populationDeviation.notes, legacyScorecard.populationDeviation.notes);
2560
- matchDicts("details", altLegacyScorecard.details, legacyScorecard.details);
2561
- }
2562
- exports.compareScorecards = compareScorecards;
2563
- // Matching helpers
2564
- function matchFloats(property, received, good, tolerance) {
2565
- if (dra_analytics_1.Utils.areRoughlyEqual(received, good, tolerance)) {
2566
- return true;
2567
- }
2568
- else {
2569
- console.log(`${property} does not match: ${good} expected. Received ${received}.`);
2570
- return false;
2571
- }
2572
- }
2573
- function toleranceFn(places) {
2574
- return 0.5 / Math.pow(10, places);
2575
- }
2576
- function matchInts(property, received, good) {
2577
- if (received == good) {
2578
- return true;
2579
- }
2580
- else {
2581
- console.log(`${property} does not match: ${good} expected. Received ${received}.`);
2582
- return false;
2583
- }
2584
- }
2585
- function matchUndefinableFloats(property, received, good, tolerance) {
2586
- if ((received === undefined) && (good === undefined))
2587
- return true;
2588
- if ((received === undefined) || (good === undefined)) {
2589
- console.log(`${property} does not match: ${good} expected. Received ${received}.`);
2590
- return false;
2591
- }
2592
- return matchFloats(property, received, good, tolerance);
2593
- }
2594
- // https://stackoverflow.com/questions/13142968/deep-comparison-of-objects-arrays
2595
- function matchObjectsAndArrays(property, received, good) {
2596
- if ((received === undefined) && (good === undefined))
2597
- return true; // Both undefined
2598
- if ((received === undefined) || (good === undefined)) { // One undefined but not the other
2599
- console.log(`${property} does not match: ${good} expected. Received ${received}.`);
2600
- return false;
2601
- }
2602
- if ((Object.keys(received).length === 0) && (Object.keys(good).length === 0))
2603
- return true; // Both empty
2604
- if (JSON.stringify(received) === JSON.stringify(good))
2605
- return true; // Contents match
2606
- console.log(`${property} objects or arrays do not match.`); // Contents don't match
2607
- return false;
2608
- }
2609
- function matchDicts(property, received, good) {
2610
- if ((Object.keys(received).length === 0) && (Object.keys(good).length === 0))
2611
- return true; // Both empty
2612
- const receivedStr = JSON.stringify(received);
2613
- const goodStr = JSON.stringify(good);
2614
- if (receivedStr === goodStr)
2615
- return true; // Contents match
2616
- console.log(`${property} does not match: ${goodStr} expected. Received ${receivedStr}.`); // Contents don't match
2617
- return false;
2618
- }
2619
- function matchUndefinedness(property, received, good) {
2620
- if ((received === undefined) && (good === undefined))
2621
- return true;
2622
- if ((received === undefined) || (good === undefined))
2623
- return false;
2624
- return true;
2625
- }
2626
- function matchPointArrays(property, received, good, tolerance) {
2627
- if (received.length != good.length) {
2628
- console.log(`${property} does not match: Different number of points.`);
2629
- return false;
2630
- }
2631
- for (var i = 0; i < received.length; i++) {
2632
- const vLabel = property + '/' + i.toString() + '/' + 'v';
2633
- const sLabel = property + '/' + i.toString() + '/' + 's';
2634
- if (!matchFloats(vLabel, received[i].v, good[i].v, tolerance))
2635
- return false;
2636
- if (!matchFloats(sLabel, received[i].s, good[i].s, tolerance))
2637
- return false;
2638
- }
2639
- return true;
2640
- }
2641
- function matchCompactnessByDistrict(property, received, good, tolerance) {
2642
- if (received.length != good.length) {
2643
- console.log(`${property} does not match: Different number of districts.`);
2644
- return false;
2645
- }
2646
- let bMismatched = false;
2647
- for (var i = 0; i < received.length; i++) {
2648
- const rawReock = property + '/' + i.toString() + '/' + 'rawReock';
2649
- if (!matchFloats(rawReock, received[i].rawReock, good[i].rawReock, tolerance))
2650
- bMismatched = true;
2651
- const normalizedReock = property + '/' + i.toString() + '/' + 'normalizedReock';
2652
- if (!matchInts(normalizedReock, received[i].normalizedReock, good[i].normalizedReock))
2653
- bMismatched = true;
2654
- const rawPolsby = property + '/' + i.toString() + '/' + 'rawPolsby';
2655
- if (!matchFloats(rawPolsby, received[i].rawPolsby, good[i].rawPolsby, tolerance))
2656
- bMismatched = true;
2657
- // 09-17-21 - By-district Polsby–Popper ratings from dra-score in production are wrong!
2658
- // const normalizedPolsby: string = property + '/' + i.toString() + '/' + 'normalizedPolsby';
2659
- // if (!matchInts(normalizedPolsby, received[i].normalizedPolsby, good[i].normalizedPolsby)) bMismatched = true;
2660
- const kiwysiScore = property + '/' + i.toString() + '/' + 'kiwysiScore';
2661
- if (!matchInts(kiwysiScore, received[i].kiwysiScore, good[i].kiwysiScore))
2662
- bMismatched = true;
2663
- }
2664
- if (bMismatched = true)
2665
- return false;
2666
- return true;
2667
- }
2668
- // Not used, after all
2669
- /* Modeled after David Sielaff's Jest extension 'toBeArrayWithValuesCloseTo'
2670
-
2671
- function matchFloatArrays(property: string, received: Array<any>, expected: Array<any>, tolerance: number): boolean
2672
- {
2673
- // Note - Not sure what this check was for ...
2674
- // if (expected.length == 0) {
2675
- // return {
2676
- // message: () => `expected arrays of same size`,
2677
- // pass: received.length == 0
2678
- // }
2679
- // }
2680
-
2681
- if (typeof expected[0] === "number")
2682
- {
2683
- if (typeof received[0] === "number") return matchArrays1d(property, received, expected, tolerance);
2684
-
2685
- console.log(`${property} does not match: array doesn't contain numbers.`);
2686
- return false;
2687
- }
2688
-
2689
- // Note - Ditto
2690
- // if (expected[0].length == 0) {
2691
- // return {
2692
- // message: () => `expected arrays of same size`,
2693
- // pass: received[0].length == 0
2694
- // }
2695
- // }
2696
-
2697
- if (expected[0] instanceof Array && typeof expected[0][0] === "number")
2698
- {
2699
- if (received[0] instanceof Array && typeof received[0][0] === "number") return matchArrays2d(property, received, expected, tolerance);
2700
-
2701
- console.log(`${property} does not match: arrays don't have the same dimensionality and content.`);
2702
- return false;
2703
- }
2704
-
2705
- console.log(`${property}: Expected 1d or 2d arrays.`);
2706
- return false;
2707
- }
2708
-
2709
- function matchArrays1d(property: string, received: number[], expected: number[], tolerance: number): boolean
2710
- {
2711
- if (received.length != expected.length)
2712
- {
2713
- console.log(`${property} does not match: arrays have different lengths.`);
2714
- return false;
2715
- }
2716
-
2717
- for (var index = 0; index < received.length; index++)
2718
- {
2719
- const cell: string = property + '/' + index.toString();
2720
- if (!matchFloats(cell, received[index], expected[index], tolerance)) return false;
2721
- }
2722
-
2723
- return true;
2724
- }
2725
-
2726
- function matchArrays2d(property: string, received: number[][], expected: number[][], tolerance: number): boolean
2727
- {
2728
- if (received.length != expected.length)
2729
- {
2730
- console.log(`${property} does not match: arrays have different lengths.`);
2731
- return false;
2732
- }
2733
-
2734
- for (var index = 0; index < received.length; index++)
2735
- {
2736
- if (received[index].length != expected[index].length)
2737
- {
2738
- console.log(`${property} does not match: arrays have different lengths.`);
2739
- return false;
2740
- }
2741
-
2742
- for (var inner = 0; inner < received[index].length; inner++)
2743
- {
2744
- const cell: string = property + '/' + index.toString() + '/' + inner.toString();
2745
- if (!matchFloats(cell, received[index][inner], expected[index][inner], tolerance)) return false;
2746
- }
2747
- }
2748
-
2749
- return true;
2750
- }
2751
- */
2752
2347
 
2753
2348
 
2754
2349
  /***/ }),
@@ -2768,25 +2363,12 @@ exports.OUT_OF_STATE = exports.NUMBER_OF_ITEMS_TO_REPORT = exports.NOT_ASSIGNED
2768
2363
  // Keep four decimal places for fractions [0–1], i.e.,
2769
2364
  // keep two decimal places for %'s [0–100].
2770
2365
  exports.PRECISION = 4;
2771
- // LEGACY - Not used
2772
- // Normalized scores [0-100]
2773
- // export const NORMALIZED_RANGE: number = 100;
2774
2366
  // The dummy district ID for features not assigned districts yet
2775
2367
  exports.NOT_ASSIGNED = 0;
2776
2368
  // # of items to report as problematic (e.g., features, districts, etc.)
2777
2369
  exports.NUMBER_OF_ITEMS_TO_REPORT = 10;
2778
2370
  // The virtual geoID for "neighbors" in other states
2779
2371
  exports.OUT_OF_STATE = "OUT_OF_STATE";
2780
- // LEGACY - Not used
2781
- // "Roughly equal" = average census block size / 2
2782
- // const AVERAGE_BLOCK_SIZE = 30;
2783
- // export const EQUAL_TOLERANCE: number = AVERAGE_BLOCK_SIZE / 2;
2784
- // LEGACY - Not used
2785
- // County & district splitting weights
2786
- // export const COUNTY_SPLITTING_WEIGHT = 0.8;
2787
- // export const DISTRICT_SPLITTING_WEIGHT = 1.0 - COUNTY_SPLITTING_WEIGHT;
2788
- // 2020
2789
- // export const SHAPES = "2010 VTD shapes";
2790
2372
 
2791
2373
 
2792
2374
  /***/ }),
@@ -2802,7 +2384,6 @@ exports.OUT_OF_STATE = "OUT_OF_STATE";
2802
2384
  // TYPE DEFINITIONS
2803
2385
  //
2804
2386
  Object.defineProperty(exports, "__esModule", ({ value: true }));
2805
- // END
2806
2387
 
2807
2388
 
2808
2389
  /***/ }),
@@ -2842,18 +2423,6 @@ const DT = __importStar(__webpack_require__(/*! @dra2020/dra-types */ "@dra2020/
2842
2423
  const _data_1 = __webpack_require__(/*! ./_data */ "./src/_data.ts");
2843
2424
  const S = __importStar(__webpack_require__(/*! ./settings */ "./src/settings.ts"));
2844
2425
  // PLAN HELPERS
2845
- // LEGACY - Not used
2846
- // Is a "neighbor" in state?
2847
- // export function isInState(geoID: string): boolean
2848
- // {
2849
- // return geoID != S.OUT_OF_STATE;
2850
- // }
2851
- // LEGACY - Not used
2852
- // Is a "neighbor" out of state?
2853
- // export function isOutOfState(geoID: string): boolean
2854
- // {
2855
- // return geoID == S.OUT_OF_STATE;
2856
- // }
2857
2426
  // Get the districtID to which a geoID is assigned
2858
2427
  function getDistrict(plan, geoID) {
2859
2428
  // All geoIDs in a state *should be* assigned to a district (including the
@@ -3082,12 +2651,6 @@ function depthof(a) {
3082
2651
  }
3083
2652
  }
3084
2653
  exports.depthof = depthof;
3085
- /* TriState
3086
- export function mapBooleanToTriState(bool: boolean): T.TriState
3087
- {
3088
- return (bool) ? T.TriState.Green : T.TriState.Red;
3089
- }
3090
- */
3091
2654
 
3092
2655
 
3093
2656
  /***/ }),
@@ -3304,16 +2867,6 @@ module.exports = require("@dra2020/dra-analytics");
3304
2867
 
3305
2868
  /***/ }),
3306
2869
 
3307
- /***/ "@dra2020/dra-score":
3308
- /*!*************************************!*\
3309
- !*** external "@dra2020/dra-score" ***!
3310
- \*************************************/
3311
- /***/ ((module) => {
3312
-
3313
- module.exports = require("@dra2020/dra-score");
3314
-
3315
- /***/ }),
3316
-
3317
2870
  /***/ "@dra2020/dra-types":
3318
2871
  /*!*************************************!*\
3319
2872
  !*** external "@dra2020/dra-types" ***!