From acf76c7b4fac3d343aa2d87b8185e754f86de517 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 27 Sep 2024 07:58:46 +0000 Subject: [PATCH 1/7] Bump com.sksamuel.scapegoat:scalac-scapegoat-plugin_2.13.14 (#972) --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index c95d8e7366..83cbc7f2b7 100644 --- a/build.gradle +++ b/build.gradle @@ -30,7 +30,7 @@ ext { jtsVersion = '1.20.0' confluentKafkaVersion = '7.4.0' tscfgVersion = '1.1.3' - scapegoatVersion = '3.0.0' + scapegoatVersion = '3.0.2' testContainerVersion = '0.41.4' From 2f7842fc296cdb465a37d89bbfe4b7de4a932ea7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 27 Sep 2024 07:59:25 +0000 Subject: [PATCH 2/7] Bump org.scala-lang:scala-library from 2.13.14 to 2.13.15 Bumps [org.scala-lang:scala-library](https://github.com/scala/scala) from 2.13.14 to 2.13.15. - [Release notes](https://github.com/scala/scala/releases) - [Commits](https://github.com/scala/scala/compare/v2.13.14...v2.13.15) --- updated-dependencies: - dependency-name: org.scala-lang:scala-library dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 83cbc7f2b7..1c9bbe44d0 100644 --- a/build.gradle +++ b/build.gradle @@ -25,7 +25,7 @@ ext { javaVersion = JavaVersion.VERSION_17 scalaVersion = '2.13' - scalaBinaryVersion = '2.13.14' + scalaBinaryVersion = '2.13.15' pekkoVersion = '1.1.1' jtsVersion = '1.20.0' confluentKafkaVersion = '7.4.0' From 257cda8701aa3853122ff2925f91b9ccf68180cb Mon Sep 17 00:00:00 2001 From: Sebastian Peter Date: Fri, 27 Sep 2024 10:05:55 +0200 Subject: [PATCH 3/7] Updating scoverage to 2.2.1 Signed-off-by: Sebastian Peter --- gradle/scripts/scoverage.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/scripts/scoverage.gradle b/gradle/scripts/scoverage.gradle index 4e95c17262..a998819c42 100644 --- a/gradle/scripts/scoverage.gradle +++ b/gradle/scripts/scoverage.gradle @@ -3,7 +3,7 @@ // https://github.com/scoverage/gradle-scoverage/issues/109 for details scoverage { - scoverageVersion = "2.1.1" + scoverageVersion = "2.2.1" scoverageScalaVersion = scalaBinaryVersion coverageOutputHTML = false coverageOutputXML = true From d31dd527108dbf6630fd3ab5362404243f6ab3e3 Mon Sep 17 00:00:00 2001 From: Sebastian Peter Date: Fri, 27 Sep 2024 12:01:02 +0200 Subject: [PATCH 4/7] Simplifying integration in QuantityUtil, fixing test Signed-off-by: Sebastian Peter --- CHANGELOG.md | 1 + .../util/scala/quantities/QuantityUtil.scala | 106 +++++------------- .../util/quantities/QuantityUtilSpec.scala | 54 +-------- 3 files changed, 29 insertions(+), 132 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7854a5e918..a03112920d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -85,6 +85,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Simplifying ThermalHouse [#940](https://github.com/ie3-institute/simona/issues/940) - Prepare ThermalStorageTestData for Storage without storageVolumeLvlMin [#894](https://github.com/ie3-institute/simona/issues/894) - Renamed `ActivityStartTrigger`, `ScheduleTriggerMessage`, `CompletionMessage` in UML Diagrams[#675](https://github.com/ie3-institute/simona/issues/675) +- Simplifying quantity integration in QuantityUtil [#973](https://github.com/ie3-institute/simona/issues/973) ### Fixed - Removed a repeated line in the documentation of vn_simona config [#658](https://github.com/ie3-institute/simona/issues/658) diff --git a/src/main/scala/edu/ie3/util/scala/quantities/QuantityUtil.scala b/src/main/scala/edu/ie3/util/scala/quantities/QuantityUtil.scala index 4ca6d188fb..b55678ef83 100644 --- a/src/main/scala/edu/ie3/util/scala/quantities/QuantityUtil.scala +++ b/src/main/scala/edu/ie3/util/scala/quantities/QuantityUtil.scala @@ -7,14 +7,13 @@ package edu.ie3.util.scala.quantities import edu.ie3.simona.exceptions.QuantityException -import edu.ie3.util.quantities.{QuantityUtil => PSQuantityUtil} import squants.time.{Hours, TimeDerivative, TimeIntegral} import squants.{Quantity, Seconds, UnitOfMeasure} import tech.units.indriya.ComparableQuantity import tech.units.indriya.function.Calculus import tech.units.indriya.quantity.Quantities -import scala.collection.mutable +import scala.collection.immutable.SortedMap import scala.util.{Failure, Try} object QuantityUtil { @@ -120,27 +119,39 @@ object QuantityUtil { lastValue: Q, ) - /* Determine the starting and ending value for the integral */ - val startValue = startingValue(values, windowStart) - val (lastTick, lastValue) = endingValue(values, windowEnd) - val valuesWithinWindow = mutable.LinkedHashMap.newBuilder - .addAll( - (values filter { case (tick, _) => - tick >= windowStart && tick <= windowEnd - }).toSeq - .sortBy(_._1) + val sortedValues = SortedMap.from(values) + + /* Determine the unit from the first best value */ + val unit = sortedValues.values.headOption + .map(_.unit) + .getOrElse( + throw new QuantityException( + "Unable to determine unit for dummy starting value." + ) ) - .result() + val zeroValue = unit(0d) + + /* the first relevant value for integration is placed before or at windowStart */ + val startValue = sortedValues + .rangeUntil(windowStart + 1) + .lastOption + .map { case (_, value) => + value + } + .getOrElse(zeroValue) - /* We need a value at the window end, so if the last value is not exactly there, replicate it at that point */ - if (windowEnd > lastTick) - valuesWithinWindow.addOne(windowEnd -> lastValue) + /* Filtering out values outside the specified time window. + Excluding the value at first tick because the fold below starts with it. + At the end, we add a dummy value (we only care about the ending tick). + */ + val valuesWithinWindow = sortedValues.range(windowStart + 1, windowEnd) + + (windowEnd -> zeroValue) /* Actually determining the integral, but sweeping over values and summing up everything */ valuesWithinWindow .foldLeft( IntegrationState( - startValue * Hours(0), + zeroValue * Hours(0), windowStart, startValue, ) @@ -158,67 +169,4 @@ object QuantityUtil { .currentIntegral } - /** Determine the starting value for the integration - * - * @param values - * Mapping of ticks to values - * @param windowStart - * Tick, where the integration window starts - * @tparam Q - * Type of quantity to account for - * @return - * Either the first value before the window starts or 0, if not - * apparent - */ - private def startingValue[Q <: squants.Quantity[Q]]( - values: Map[Long, Q], - windowStart: Long, - ): Q = { - values - .filter { case (tick, _) => - tick <= windowStart - } - .maxOption[(Long, Q)](Ordering.by(_._1)) match { - case Some((_, value)) => value - case None => - val unit = values.headOption - .map(_._2.unit) - .getOrElse( - throw new QuantityException( - "Unable to determine unit for dummy starting value." - ) - ) - unit(0d) - } - } - - /** Determine the last value for the integration - * - * @param values - * Mapping of ticks to values - * @param windowEnd - * Tick, where the integration window ends - * @tparam Q - * Type of quantity to account for - * @return - * Last entry before the integration window ends and it's corresponding - * tick - */ - private def endingValue[Q <: Quantity[Q]]( - values: Map[Long, Q], - windowEnd: Long, - ): (Long, Q) = { - values - .filter { case (tick, _) => - tick <= windowEnd - } - .maxOption[(Long, Q)](Ordering.by(_._1)) match { - case Some(tickToValue) => tickToValue - case None => - throw new QuantityException( - "Cannot integrate over an empty set of values." - ) - } - } - } diff --git a/src/test/scala/edu/ie3/util/quantities/QuantityUtilSpec.scala b/src/test/scala/edu/ie3/util/quantities/QuantityUtilSpec.scala index 1c1edb1f44..5f43a6a58b 100644 --- a/src/test/scala/edu/ie3/util/quantities/QuantityUtilSpec.scala +++ b/src/test/scala/edu/ie3/util/quantities/QuantityUtilSpec.scala @@ -6,7 +6,6 @@ package edu.ie3.util.quantities -import edu.ie3.simona.exceptions.QuantityException import edu.ie3.simona.test.common.UnitSpec import edu.ie3.util.scala.quantities.QuantityUtil import org.scalatest.prop.TableDrivenPropertyChecks @@ -28,57 +27,6 @@ class QuantityUtilSpec extends UnitSpec with TableDrivenPropertyChecks { ) "Integrating over quantities" when { - "determining the start value" should { - val startingValue = - PrivateMethod[Power](Symbol("startingValue")) - - "throw an exception, if values are empty and unit of \"empty\" quantity cannot be determined" in { - intercept[QuantityException] { - QuantityUtil invokePrivate startingValue( - Map.empty[Long, Power], - 1L, - ) - }.getMessage shouldBe "Unable to determine unit for dummy starting value." - } - - "bring default value, if there is nothing before window starts" in { - QuantityUtil invokePrivate startingValue( - values, - 1L, - ) should be - unit(0d) - - } - - "bring correct value, if there is something before window starts" in { - QuantityUtil invokePrivate startingValue( - values, - 2L, - ) should be - unit(5d) - - } - } - - "determining the end value" should { - val endingValue = - PrivateMethod[(Long, Power)](Symbol("endingValue")) - - "throw and exception, if there is no value before the window ends" in { - intercept[QuantityException] { - QuantityUtil invokePrivate endingValue(values, 1L) - }.getMessage shouldBe "Cannot integrate over an empty set of values." - } - - "bring correct value, if there is something before window ends" in { - QuantityUtil invokePrivate endingValue(values, 2L) match { - case (tick, value) => - tick shouldBe 2L - value should approximate(unit(5d)) - } - } - } - "actually integrating" should { "lead to correct values" in { val cases = Table( @@ -94,7 +42,7 @@ class QuantityUtilSpec extends UnitSpec with TableDrivenPropertyChecks { values, windowStart, windowEnd, - ) =~ expectedResult + ) should approximate(expectedResult) } } } From 19b33c48f3074cd6606883cc7fd876edf45a3dbd Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 30 Sep 2024 07:00:04 +0000 Subject: [PATCH 5/7] Bump org.mockito:mockito-core from 5.13.0 to 5.14.0 (#976) --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 1c9bbe44d0..383a9ffb70 100644 --- a/build.gradle +++ b/build.gradle @@ -103,7 +103,7 @@ dependencies { /* testing */ testImplementation 'org.spockframework:spock-core:2.3-groovy-4.0' testImplementation 'org.scalatestplus:mockito-3-4_2.13:3.2.10.0' - testImplementation 'org.mockito:mockito-core:5.13.0' // mocking framework + testImplementation 'org.mockito:mockito-core:5.14.0' // mocking framework testImplementation "org.scalatest:scalatest_${scalaVersion}:3.2.19" testRuntimeOnly 'com.vladsch.flexmark:flexmark-all:0.64.8' //scalatest html output testImplementation group: 'org.pegdown', name: 'pegdown', version: '1.6.0' From 948738ea6430a813990e65c26aded8e77a9375d6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 30 Sep 2024 07:09:10 +0000 Subject: [PATCH 6/7] Bump com.sksamuel.scapegoat:scalac-scapegoat-plugin_2.13.15 (#975) --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 383a9ffb70..bb5f356f29 100644 --- a/build.gradle +++ b/build.gradle @@ -30,7 +30,7 @@ ext { jtsVersion = '1.20.0' confluentKafkaVersion = '7.4.0' tscfgVersion = '1.1.3' - scapegoatVersion = '3.0.2' + scapegoatVersion = '3.0.3' testContainerVersion = '0.41.4' From 6c75d5ce219426799961db41ec2f3bbff109ed33 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 1 Oct 2024 08:17:07 +0000 Subject: [PATCH 7/7] Bump org.mockito:mockito-core from 5.14.0 to 5.14.1 (#977) --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index bb5f356f29..5d3c289349 100644 --- a/build.gradle +++ b/build.gradle @@ -103,7 +103,7 @@ dependencies { /* testing */ testImplementation 'org.spockframework:spock-core:2.3-groovy-4.0' testImplementation 'org.scalatestplus:mockito-3-4_2.13:3.2.10.0' - testImplementation 'org.mockito:mockito-core:5.14.0' // mocking framework + testImplementation 'org.mockito:mockito-core:5.14.1' // mocking framework testImplementation "org.scalatest:scalatest_${scalaVersion}:3.2.19" testRuntimeOnly 'com.vladsch.flexmark:flexmark-all:0.64.8' //scalatest html output testImplementation group: 'org.pegdown', name: 'pegdown', version: '1.6.0'