linny-r 1.5.5 → 1.5.7

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.
@@ -750,8 +750,8 @@ class LinnyRModel {
750
750
  }
751
751
 
752
752
  isConstrained(node) {
753
- // Return the constraint that node is involved in if such constraint exists,
754
- // and otherwise NULL
753
+ // Return the constraint that node is involved in if such constraint
754
+ // exists, and otherwise NULL.
755
755
  let c = null;
756
756
  for(c in this.constraints) if(this.constraints.hasOwnProperty(c)) {
757
757
  c = this.constraints[c];
@@ -761,25 +761,25 @@ class LinnyRModel {
761
761
  }
762
762
 
763
763
  get runLength() {
764
- // Return the number of time steps to by computed for a simulation
765
- // NOTE: this includes a final lookahead period
764
+ // Return the number of time steps to by computed for a simulation.
765
+ // NOTE: This includes a final lookahead period.
766
766
  return this.end_period - this.start_period + 1 + this.look_ahead;
767
767
  }
768
-
768
+
769
769
  inferDimensions() {
770
- // Generates the list of dimensions for experimental design
771
- // NOTE: a dimension is a list of one or more relevant selectors
770
+ // Generate the list of dimensions for experimental design.
771
+ // NOTE: A dimension is a list of one or more relevant selectors.
772
772
  let newdim;
773
773
  this.dimensions.length = 0;
774
- // NOTE: ignore the equations dataset
774
+ // NOTE: Ignore the equations dataset.
775
775
  for(let d in this.datasets) if(this.datasets.hasOwnProperty(d) &&
776
776
  this.datasets[d] !== this.equations_dataset) {
777
777
  // Get selector list
778
778
  const
779
779
  ds = this.datasets[d],
780
- // NOTE: ignore wildcard selectors!
780
+ // NOTE: Ignore wildcard selectors!
781
781
  sl = ds.plainSelectors;
782
- // Ignore datasets with fewer than 2 "plain" selectors
782
+ // Ignore datasets with fewer than 2 "plain" selectors.
783
783
  if(sl.length > 1) {
784
784
  newdim = true;
785
785
  // Merge into dimension if there are shared selectors
@@ -3108,12 +3108,12 @@ class LinnyRModel {
3108
3108
  // Set an array to [0, ..., run length] of numbers initialized as
3109
3109
  // "not computed" to ensure that they will be evaluated "lazily"
3110
3110
  // NOTES:
3111
- // (1) the first element (0) corresponds to t = 0, i.e., the model time
3112
- // step just prior to the time step defined by start_period
3113
- // (2) all vectors must be initialized with an appropriate value for
3114
- // element 0
3115
- // (3) `other` specifies value for t = 1 and beyond if vector is static
3116
- // and has to to be initialized to a constant (typically 0)
3111
+ // (1) the first element (0) corresponds to t = 0, i.e., the model
3112
+ // time step just prior to the time step defined by start_period.
3113
+ // (2) All vectors must be initialized with an appropriate value for
3114
+ // element 0.
3115
+ // (3) `other` specifies value for t = 1 and beyond if vector is
3116
+ // static and has to to be initialized to a constant (typically 0).
3117
3117
  v.length = this.runLength + 1;
3118
3118
  v.fill(other);
3119
3119
  v[0] = initial;
@@ -9800,6 +9800,11 @@ class Chart {
9800
9800
  dy = 0,
9801
9801
  x = 0,
9802
9802
  y = rt + rh + font_height;
9803
+ // Store XY-area coordinates for use by Chart Manager.
9804
+ this.plot_ox = rl;
9805
+ this.plot_oy = rt + rh;
9806
+ this.plot_width = rw;
9807
+ this.plot_height = rh;
9803
9808
  if(this.histogram) {
9804
9809
  // Draw bin boundaries along the horizontal axis
9805
9810
  dx = rw / this.bins;
@@ -9820,15 +9825,15 @@ class Chart {
9820
9825
  // If multiple bars (`vv` is number of visible variables), draw
9821
9826
  // ticks to mark horizontal area per run number.
9822
9827
  if(vv > 1) {
9823
- this.addSVG(['<line x1="', rl, '" y1="', rt + rh - 3,
9824
- '" x2="', rl, '" y2="', rt + rh + 3,
9828
+ this.addSVG(['<line x1="', rl, '" y1="', rt + rh,
9829
+ '" x2="', rl, '" y2="', rt + rh + 6,
9825
9830
  '" stroke="black" stroke-width="1.5"/>']);
9826
9831
  }
9827
9832
  x = rl + dx;
9828
9833
  for(let i = 0; i < runs.length; i++) {
9829
9834
  if(vv > 1) {
9830
- this.addSVG(['<line x1="', x, '" y1="', rt + rh - 3,
9831
- '" x2="', x, '" y2="', rt + rh + 3,
9835
+ this.addSVG(['<line x1="', x, '" y1="', rt + rh,
9836
+ '" x2="', x, '" y2="', rt + rh + 6,
9832
9837
  '" stroke="black" stroke-width="1.5"/>']);
9833
9838
  }
9834
9839
  if(selx.plot_dimensions.length > 0) {
@@ -9920,22 +9925,31 @@ class Chart {
9920
9925
  maxv *= (maxv > 0 ? 1.1 : 0.9);
9921
9926
  if(minv < 0) minv *= 1.1;
9922
9927
  }
9928
+ // For bar chart, maxv must be non-negative.
9929
+ if(stat_bars) maxv = Math.max(maxv, 0);
9923
9930
  const range = maxv - minv;
9931
+ this.plot_min_y = minv;
9932
+ this.plot_max_y = maxv;
9924
9933
  if(range > 0) {
9925
9934
  const step = this.labelStep(range, 5, VM.NEAR_ZERO);
9926
9935
  let x0 = rl,
9927
9936
  y0 = rt + rh,
9928
9937
  maxy = Math.ceil(maxv / step) * step,
9929
9938
  miny = (minv >= 0 ? 0 : -Math.ceil(-minv / step) * step);
9939
+ this.plot_min_y = miny;
9940
+ this.plot_max_y = maxy;
9930
9941
  y = miny;
9931
9942
  const labels = [];
9932
9943
  while(y <= maxy) {
9933
- // NOTE: force number to become a string so that its length
9934
- // attribute can be used when drawing it
9935
- labels.push('' + VM.sig4Dig(y));
9944
+ // NOTE: Large values having exponents will be "neat" numbers,
9945
+ // so then display fewer decimals, as these will be zeroes.
9946
+ const v = (Math.abs(y) > 1e5 ? VM.sig2Dig(y) : VM.sig4Dig(y));
9947
+ // NOTE: Force number to become a string so that its length
9948
+ // attribute can be used when drawing it.
9949
+ labels.push('' + v);
9936
9950
  y += step;
9937
9951
  }
9938
- // First calculate dy as the vertical distance between labels
9952
+ // First calculate dy as the vertical distance between labels.
9939
9953
  dy = rh / (labels.length - 1);
9940
9954
  // Draw labels, starting at lowest Y
9941
9955
  y = rt + rh;
@@ -9946,11 +9960,11 @@ class Chart {
9946
9960
  y -= dy;
9947
9961
  }
9948
9962
  // Then calculate dx and dy as the respective horizontal and
9949
- // vertical pixel equivalents of one unit
9963
+ // vertical pixel equivalents of one unit.
9950
9964
  dx = rw / time_steps;
9951
9965
  dy = rh / (maxy - miny);
9952
9966
  y0 = rt + rh + dy * miny;
9953
- // Draw axes Y = 0 and X = 0 in black and slightly thicker
9967
+ // Draw axes Y = 0 and X = 0 in black and slightly thicker.
9954
9968
  this.addSVG(['<line x1="', x0, '" y1="', y0, '" x2="', x0 + rw,
9955
9969
  '" y2="', y0, '" stroke="black" stroke-width="2"/>']);
9956
9970
  this.addSVG(['<line x1="', x0, '" y1="', rt, '" x2="', x0,
@@ -10024,8 +10038,8 @@ class Chart {
10024
10038
  const
10025
10039
  rnr = runs[ri],
10026
10040
  bv = bar_values[vi][rnr],
10027
- bart = rt + (maxy - bv) * dy,
10028
- barh = (bv - miny) * dy;
10041
+ barh = Math.abs(bv) * dy,
10042
+ bart = y0 - Math.max(0, bv) * dy;
10029
10043
  x = rl + ri * dx + barsp + vcnt * varsp;
10030
10044
  this.addSVG(['<rect x="', x, '" y="', bart,
10031
10045
  '" width="', barw, '" height="', barh,
@@ -10328,8 +10342,8 @@ class ActorSelector {
10328
10342
  // CLASS ExperimentRunResult
10329
10343
  class ExperimentRunResult {
10330
10344
  constructor(r, v, a='') {
10331
- // NOTE: constructor can be called with `v` a chart variable, a dataset,
10332
- // or an XML node; if `v` is the equations dataset, then `a` is the
10345
+ // NOTE: Constructor can be called with `v` a chart variable, a dataset,
10346
+ // or an XML node. When `v` is the equations dataset, then `a` is the
10333
10347
  // identifier of the dataset modifier to be used.
10334
10348
  this.run = r;
10335
10349
  if(v instanceof ChartVariable) {
@@ -10350,12 +10364,11 @@ class ExperimentRunResult {
10350
10364
  this.exceptions = VM.UNDEFINED;
10351
10365
  this.last = VM.UNDEFINED;
10352
10366
  } else {
10353
- // Copy relevant properties of chart variable `v`
10354
- // NOTE: vector must be computed (may not have happened when the chart
10355
- // manager is not showing; no computation is done when vector has length
10356
- // greater than 0)
10357
- // NOTE: computation will be for the running experiment, so NO need to
10358
- // set the run_index for the chart of this variable
10367
+ // Copy relevant properties of chart variable `v`.
10368
+ // NOTE: Vector must be computed, unless the vector already has
10369
+ // length greater than 0. Computation will be for the running
10370
+ // experiment, so NO need to set the run_index for the chart of
10371
+ // this variable.
10359
10372
  v.computeVector();
10360
10373
  this.N = v.N;
10361
10374
  this.sum = v.sum;
@@ -10366,13 +10379,14 @@ class ExperimentRunResult {
10366
10379
  this.non_zero_tally = v.non_zero_tally;
10367
10380
  this.exceptions = v.exceptions;
10368
10381
  // NOTES:
10369
- // (1) run results are vectors: "initial value" v[0] is also stored
10370
- // (2) use slice() to make a copy of the vector, as the variable's
10371
- // vector may change again (for the next experiment, or when drawing
10372
- // a chart after a run)
10373
- // (3) slice(0, N) takes elements 0 to N-1, so add 1 to run length
10382
+ // (1) Run results are vectors: "initial value" v[0] is also stored.
10383
+ // (2) Use slice() to make a copy of the vector, as the variable's
10384
+ // vector may change again (for the next experiment, or when
10385
+ // drawing a chart after a run).
10386
+ // (3) slice(0, N) takes elements 0 to N-1, so add 1 to run length.
10374
10387
  this.vector = v.vector.slice(0, this.run.time_steps + 1);
10375
- // NOTE: use the last step of the experiment time period
10388
+ // Use the last step of the experiment time period for the LAST
10389
+ // statistic.
10376
10390
  this.last = (this.vector.length > 0 ?
10377
10391
  this.vector[this.vector.length - 1] : VM.UNDEFINED);
10378
10392
  }
@@ -10380,18 +10394,18 @@ class ExperimentRunResult {
10380
10394
  // This dataset will be an "outcome" dataset => store statistics only
10381
10395
  // @@TO DO: deal with wildcard equations: these will have *multiple*
10382
10396
  // vectors associated with numbered entities (via #) and therefore
10383
- // *all* these results should be stored (with # replaced by its value)
10397
+ // *all* these results should be stored (with # replaced by its value).
10384
10398
  this.x_variable = false;
10385
10399
  this.object_id = v.identifier;
10386
10400
  if(v === MODEL.equations_dataset && a) {
10387
10401
  this.attribute = a;
10388
10402
  } else {
10389
10403
  this.attribute = '';
10390
- // NOTE: the running experiment determines the modifier
10404
+ // NOTE: The running experiment determines the modifier.
10391
10405
  const xx = MODEL.running_experiment;
10392
10406
  if(xx) {
10393
10407
  const mm = v.matchingModifiers(xx.activeCombination);
10394
- // Use the first matching selector, as this is the most specific one
10408
+ // Use the first matching selector, as this is the most specific one.
10395
10409
  if(mm.length > 0) this.attribute = mm[0].selector;
10396
10410
  }
10397
10411
  }
@@ -10401,18 +10415,18 @@ class ExperimentRunResult {
10401
10415
  this.non_zero_tally = 0;
10402
10416
  this.exceptions = 0;
10403
10417
  const
10404
- // NOTE: run result dataset selector will be plain (no wildcards)
10418
+ // NOTE: Run result dataset selector will be plain (no wildcards).
10405
10419
  x = v.modifiers[this.attribute].expression,
10406
10420
  t_end = MODEL.end_period - MODEL.start_period + 1;
10407
- // N = # time steps
10421
+ // N = # time steps.
10408
10422
  this.N = t_end;
10409
10423
  let r,
10410
10424
  // Use the time-scaled (!) vector of the dataset...
10411
10425
  rv = v.vector;
10412
10426
  if(x) {
10413
- // ... or use the result of the modifier expression if defined
10427
+ // ... or use the result of the modifier expression if defined.
10414
10428
  if(x.isStatic) {
10415
- // For static expressions, statistics can be inferred directly
10429
+ // For static expressions, statistics can be inferred directly.
10416
10430
  r = x.result(0);
10417
10431
  this.mean = r;
10418
10432
  this.sum = r * t_end;
@@ -10423,7 +10437,7 @@ class ExperimentRunResult {
10423
10437
  } else if(Math.abs(r) > VM.NEAR_ZERO) {
10424
10438
  this.non_zero_tally = t_end;
10425
10439
  }
10426
- // Preclude further computation of statistics
10440
+ // Preclude further computation of statistics.
10427
10441
  rv = null;
10428
10442
  } else {
10429
10443
  // Ensure that expression vector is computed in full
@@ -10432,7 +10446,7 @@ class ExperimentRunResult {
10432
10446
  }
10433
10447
  }
10434
10448
  if(rv) {
10435
- // Do not include t = 0 in statistics
10449
+ // Do not include t = 0 in statistics.
10436
10450
  for(let t = 1; t <= t_end; t++) {
10437
10451
  r = rv[t];
10438
10452
  // Map undefined values and all errors to 0
@@ -10446,68 +10460,71 @@ class ExperimentRunResult {
10446
10460
  this.minimum = Math.min(this.minimum, r);
10447
10461
  this.maximum = Math.max(this.maximum, r);
10448
10462
  }
10449
- // Compute the mean
10463
+ // Compute the mean.
10450
10464
  this.mean = this.sum / t_end;
10451
- // Compute the variance
10465
+ // Compute the variance.
10452
10466
  let sumsq = 0;
10453
10467
  for(let t = 1; t <= t_end; t++) {
10454
10468
  r = rv[t];
10455
- // Map undefined values and all errors to 0
10469
+ // Map undefined values and all errors to 0.
10456
10470
  if(r < VM.MINUS_INFINITY || r > VM.PLUS_INFINITY) r = 0;
10457
10471
  sumsq += Math.pow(r - this.mean, 2);
10458
10472
  }
10459
10473
  this.variance = sumsq / t_end;
10460
10474
  this.last = rv[t_end];
10461
10475
  }
10462
- // Do not store the RR vector -- outcomes are meant to conserve space
10476
+ // Do not store the RR vector, since outcomes are meant to reduce
10477
+ // the amount of memory (and model file size).
10463
10478
  this.vector = [];
10464
10479
  } else {
10465
- // Parsing run results while loading a file: `v` is an XML tree
10480
+ // Parsing run results while loading a file: `v` is an XML tree.
10466
10481
  this.initFromXML(v);
10467
10482
  }
10468
- // The vector MAY need to be scaled to model time by different methods, but
10469
- // since this is likely to be rare, such scaling is performed "lazily", so
10470
- // the method-specific vectors are initially set to NULL
10483
+ // The vector MAY need to be scaled to model time by different methods,
10484
+ // but since this is likely to be rare, such scaling is performed
10485
+ // "lazily", so the method-specific vectors are initially set to NULL.
10471
10486
  this.resetScaledVectors();
10472
10487
  }
10473
10488
 
10474
10489
  resetScaledVectors() {
10475
- // Set the special vectors to null, so they will be recalculated
10490
+ // Set the special vectors to null, so they will be recalculated.
10476
10491
  this.scaled_vectors = {'NEAREST': [], 'MEAN': [], 'SUM': [], 'MAX': []};
10477
10492
  }
10478
10493
 
10479
10494
  get displayName() {
10480
- // Returns the name of the result variable
10495
+ // Return the name of the result variable.
10481
10496
  const
10482
10497
  obj = MODEL.objectByID(this.object_id),
10483
10498
  dn = obj.displayName;
10484
- // NOTE: for equations dataset, only display the modifier selector
10499
+ // NOTE: For equations dataset, only display the modifier selector.
10485
10500
  if(obj === MODEL.equations_dataset) {
10486
10501
  const m = obj.modifiers[this.attribute.toLowerCase()];
10487
10502
  if(m) return m.selector;
10488
- console.log('WARNING: Run result of non-existent equation', this.attribute);
10503
+ console.log('WARNING: Run result of non-existent equation',
10504
+ this.attribute);
10489
10505
  return this.attribute;
10490
10506
  }
10491
10507
  return (this.attribute ? dn + '|' + this.attribute : dn);
10492
10508
  }
10493
10509
 
10494
10510
  get vectorString() {
10495
- // Vector is stored as semicolon-separated floating point numbers reduced
10496
- // to N-digit precision to keep model files more compact; default: N = 6
10511
+ // Vector is stored as semicolon-separated floating point numbers
10512
+ // reduced to N-digit precision to keep model files more compact.
10513
+ // By default, N = 6; this can be altered in linny-r-config.js.
10497
10514
  if(this.was_ignored) return '';
10498
10515
  let v = [],
10499
10516
  prev = '',
10500
10517
  cnt = 1;
10501
10518
  for(let i = 0; i < this.vector.length; i++) {
10502
- // Format number with desired precision
10519
+ // Format number with desired precision.
10503
10520
  const f = this.vector[i].toPrecision(CONFIGURATION.results_precision);
10504
- // While value is same as previous, do not store, but count
10521
+ // While value is same as previous, do not store, but count.
10505
10522
  if(f === prev) {
10506
10523
  cnt++;
10507
10524
  } else {
10508
10525
  if(cnt > 1) {
10509
- // More than one => "compress"
10510
- // NOTE: parse so JavaScript will represent it most compactly
10526
+ // More than one => "compress".
10527
+ // NOTE: Parse so JavaScript will represent it most compactly.
10511
10528
  v.push(cnt + 'x' + parseFloat(prev));
10512
10529
  cnt = 1;
10513
10530
  } else if(prev) {
@@ -10516,10 +10533,10 @@ class ExperimentRunResult {
10516
10533
  prev = f;
10517
10534
  }
10518
10535
  }
10519
- // Add the last "batch" of numbers
10536
+ // Add the last "batch" of numbers.
10520
10537
  if(cnt > 1) {
10521
- // More than one => "compress"
10522
- // NOTE: parse so JavaScript will represent it most compactly
10538
+ // More than one => "compress".
10539
+ // NOTE: Parse so JavaScript will represent it most compactly.
10523
10540
  v.push(cnt + 'x' + parseFloat(prev));
10524
10541
  cnt = 1;
10525
10542
  } else if(prev) {
@@ -10529,7 +10546,7 @@ class ExperimentRunResult {
10529
10546
  }
10530
10547
 
10531
10548
  unpackVectorString(str) {
10532
- // Converts semicolon-separated data to a numeric array
10549
+ // Convert semicolon-separated data to a numeric array.
10533
10550
  this.vector = [];
10534
10551
  if(str && !this.was_ignored) {
10535
10552
  const numbers = str.split(';');
@@ -10571,8 +10588,8 @@ class ExperimentRunResult {
10571
10588
  this.x_variable = nodeParameterValue(node, 'x-variable') === '1';
10572
10589
  this.was_ignored = nodeParameterValue(node, 'ignored') === '1';
10573
10590
  this.object_id = xmlDecoded(nodeContentByTag(node, 'object-id'));
10574
- // NOTE: special check to guarantee upward compatibility to version
10575
- // 1.3.0 and higher
10591
+ // NOTE: Special check to guarantee upward compatibility to version
10592
+ // 1.3.0 and higher.
10576
10593
  let attr = nodeContentByTag(node, 'attribute');
10577
10594
  if(this.object_id === UI.EQUATIONS_DATASET_ID &&
10578
10595
  !earlierVersion(MODEL.version, '1.3.0')) attr = xmlDecoded(attr);
@@ -10590,40 +10607,40 @@ class ExperimentRunResult {
10590
10607
  }
10591
10608
 
10592
10609
  valueAtModelTime(t, mtsd, method, periodic) {
10593
- // Returns the experiment result value for model time t
10594
- // NOTE: result for t = 0 should always be v[0], irrespective of scaling
10610
+ // Return the experiment result value for model time `t`.
10611
+ // NOTE: Result for t = 0 should always be v[0], irrespective of scaling.
10595
10612
  if(t === 0 || this.was_ignored) return VM.UNDEFINED;
10596
- // Now t will be > 0
10613
+ // Now t will be > 0.
10597
10614
  const
10598
10615
  rtsd = this.run.time_step_duration,
10599
- // NOTE: absolute scaling means "use time step t as index"
10616
+ // NOTE: Absolute scaling means "use time step t as index".
10600
10617
  t_multiplier = (method === 'ABS' ||
10601
10618
  Math.abs(rtsd - mtsd) < VM.NEAR_ZERO ? 1 : mtsd / rtsd);
10602
10619
  let v = null,
10603
10620
  ti = t;
10604
10621
  if(t_multiplier !== 1 && !method) method = 'NEAREST';
10605
10622
  if(t_multiplier === 1) {
10606
- // If same time scale, use the result vector without any scaling
10607
- // NOTE: vector[0] corresponds with t = 1
10623
+ // If same time scale, use the result vector without any scaling.
10624
+ // NOTE: vector[0] corresponds with t = 1.
10608
10625
  v = this.vector;
10609
10626
  } else if(this.scaled_vectors.hasOwnProperty(method)) {
10610
- // Other methods: compute entire vector, anticipating on more "gets"
10627
+ // Other methods: compute entire vector, anticipating on more "gets".
10611
10628
  v = this.scaled_vectors[method];
10612
10629
  if(v.length <= 0) {
10613
- // Infer the "official" method name
10630
+ // Infer the "official" method name.
10614
10631
  let mcode = method.toLowerCase();
10615
10632
  if(mcode === 'mean' || mcode === 'sum') mcode = 'w-' + mcode;
10616
- // NOTE: scaleData expects "pure data", so slice off v[0]
10633
+ // NOTE: scaleData expects "pure data", so slice off v[0].
10617
10634
  VM.scaleDataToVector(this.vector.slice(1), v, rtsd, mtsd, MODEL.runLength,
10618
10635
  1, VM.UNDEFINED, periodic, mcode);
10619
- // NOTE: the scaled vector WILL have an "initial value" v[0], which
10620
- // will depend on periodicity
10636
+ // NOTE: The scaled vector WILL have an "initial value" v[0], which
10637
+ // will depend on periodicity.
10621
10638
  }
10622
10639
  } else {
10623
- // Unrecognized method
10640
+ // Unrecognized method.
10624
10641
  return VM.UNDEFINED;
10625
10642
  }
10626
- // Apply periodicity while ignoring v[0] (which is only used when t=0)
10643
+ // Apply periodicity while ignoring v[0] (which is only used when t=0).
10627
10644
  if(periodic) ti = (ti - 1) % (v.length - 1) + 1;
10628
10645
  if(ti < v.length) return v[ti];
10629
10646
  return VM.UNDEFINED;
@@ -10740,17 +10757,17 @@ class ExperimentRun {
10740
10757
  }
10741
10758
 
10742
10759
  addResults() {
10743
- // Adds the experiment chart variables and outcomes as run results
10744
- // NOTE: experiments may have different time step durations
10760
+ // Add the experiment chart variables and outcomes as run results.
10761
+ // NOTE: Experiments may have different time step durations.
10745
10762
  this.time_step_duration = MODEL.timeStepDuration;
10746
10763
  // Reset each output chart to achieve that all chart variables will
10747
- // be recomputed for the current model settings
10764
+ // be recomputed for the current model settings.
10748
10765
  for(let i = 0; i < this.experiment.charts.length; i++) {
10749
10766
  this.experiment.charts[i].resetVectors();
10750
10767
  }
10751
- // Calculate number of vectors/outcomes/equations to store
10768
+ // Calculate number of vectors/outcomes/equations to store.
10752
10769
  this.oc_list = MODEL.outcomes;
10753
- // NOTE: all equations are also considered to be outcomes
10770
+ // NOTE: All equations are also considered to be outcomes.
10754
10771
  this.eq_list = Object.keys(MODEL.equations_dataset.modifiers);
10755
10772
  const
10756
10773
  cv = this.experiment.variables.length,
@@ -10760,19 +10777,19 @@ class ExperimentRun {
10760
10777
  if(cv) xr.push(pluralS(cv, 'variable'));
10761
10778
  if(oc) xr.push(pluralS(oc, 'outcome'));
10762
10779
  if(eq) xr.push(pluralS(eq, 'equation'));
10763
- // NOTE: for long simulation periods, computing run results can take
10764
- // a substantial amount of time, hence it is performed using function
10765
- // timeouts so that the browser can update the progress needle
10780
+ // NOTE: For long simulation periods, computing run results can take
10781
+ // a substantial amount of time. Hence it is performed using function
10782
+ // timeouts so that the browser can update the progress needle.
10766
10783
  UI.setMessage('Processing experiment run results: ' + xr.join(', '));
10767
10784
  UI.setProgressNeedle(0);
10768
10785
  this.steps = cv + oc + eq;
10769
- // Keep track of progress
10786
+ // Keep track of progress.
10770
10787
  this.step = 0;
10771
10788
  this.addChartResults(0);
10772
10789
  }
10773
10790
 
10774
10791
  addChartResults(vi) {
10775
- // Add a run result object for chart variable with index `vi`
10792
+ // Add a run result object for chart variable with index `vi`.
10776
10793
  if(vi < this.experiment.variables.length) {
10777
10794
  this.results.push(
10778
10795
  new ExperimentRunResult(this, this.experiment.variables[vi]));
@@ -10785,9 +10802,9 @@ class ExperimentRun {
10785
10802
  }
10786
10803
 
10787
10804
  addOutcomeResults(oi) {
10788
- // Add a run result object for outcome dataset with index `vi`
10805
+ // Add a run result object for outcome dataset with index `vi`.
10789
10806
  if(oi < this.oc_list.length) {
10790
- // NOTE: this stores results only for "active" selectors (current run)
10807
+ // NOTE: This stores results only for "active" selectors (current run).
10791
10808
  this.results.push(new ExperimentRunResult(this, MODEL.outcomes[oi]));
10792
10809
  this.step++;
10793
10810
  UI.setProgressNeedle(this.step / this.steps);
@@ -10798,22 +10815,22 @@ class ExperimentRun {
10798
10815
  }
10799
10816
 
10800
10817
  addEquationResults(ei) {
10801
- // Add a run result object for equation with index `ei`
10818
+ // Add a run result object for equation with index `ei`.
10802
10819
  if(ei < this.eq_list.length) {
10803
10820
  const k = this.eq_list[ei];
10804
- // NOTE: passing key `k` as 3rd parameter signals "use this attribute"
10821
+ // NOTE: Passing key `k` as 3rd parameter signals "use this attribute".
10805
10822
  this.results.push(
10806
10823
  new ExperimentRunResult(this, MODEL.equations_dataset, k));
10807
10824
  this.step++;
10808
10825
  UI.setProgressNeedle(this.step / this.steps);
10809
10826
  setTimeout((x) => x.addEquationResults(ei + 1), 0, this);
10810
10827
  } else {
10811
- // Register when this result was stored
10828
+ // Register when this result was stored.
10812
10829
  this.time_recorded = new Date().getTime();
10813
- // Clear the progress needle
10830
+ // Clear the progress needle.
10814
10831
  UI.setProgressNeedle(0);
10815
10832
  UI.setMessage('');
10816
- // Log the time it took to compute all results
10833
+ // Log the time it took to compute all results.
10817
10834
  VM.logMessage(VM.block_count - 1,
10818
10835
  `Processing run results took ${VM.elapsedTime} seconds.`);
10819
10836
  // Report results if applicable.
@@ -10829,8 +10846,8 @@ class ExperimentRun {
10829
10846
  }
10830
10847
 
10831
10848
  addMessages() {
10832
- // Stores the message texts of the virtual machine (one per block) so that
10833
- // they can be viewed when an experiment run is selected in the viewer
10849
+ // Store the message texts of the virtual machine (one per block) so that
10850
+ // they can be viewed when an experiment run is selected in the viewer.
10834
10851
  this.warning_count = 0;
10835
10852
  this.solver_seconds = 0;
10836
10853
  for(let i = 0; i < VM.messages.length; i++) {
@@ -10846,7 +10863,7 @@ class ExperimentRun {
10846
10863
  }
10847
10864
 
10848
10865
  resetScaledVectors() {
10849
- // Sets the vectors with scaled run results to NULL so they will recompute
10866
+ // Set the vectors with scaled run results to NULL so they will recompute.
10850
10867
  for(let i = 0; i < this.results.length; i++) {
10851
10868
  this.results[i].resetScaledVectors();
10852
10869
  }