Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ export:
- type: CSVExporter
parameters:
fileNameRoot: "test_base"
interval: 1.0
decimalPlacesCount: 3
data:
- time

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,14 @@ import org.slf4j.LoggerFactory
* @property exportPath the directory to write exported files (temporary folder is used when omitted)
* @property appendTime if true a timestamp is appended to the file name to avoid overwriting
* @property fileExtension the extension for the exported files (default: 'csv')
* @property decimalPlacesCount the count of places after decimal
*/
class CSVExporter<T, P : Position<P>>
@JvmOverloads
constructor(
private val fileNameRoot: String = "",
val interval: Double = DEFAULT_INTERVAL,
val decimalPlacesCount: Int = 2,
val exportPath: String =
createTempDirectory("alchemist-export")
.absolutePathString()
Expand Down Expand Up @@ -100,17 +102,21 @@ constructor(
val data = extractor.extractDataAsText(environment, reaction, time, step)
val names = extractor.columnNames
when {
data.size <= 1 -> data.values.joinToString(" ")
data.size <= 1 ->
roundValues(data.values, decimalPlacesCount).joinToString(" ")
// Labels and keys match
data.size == names.size && data.keys.containsAll(names) ->
Comment on lines 104 to 108

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Nathekip, add a test with multiple columns, please, and if that it goes red, apply a fix!
Thank you, let me know

names.joinToString(" ") {
requireNotNull(data[it]) {
BugReporting.reportBug(
"Bug in ${this::class.simpleName}",
mapOf("key" to it, "data" to data),
)
}
}
roundValues(
names.map { name ->
requireNotNull(data[name]) {
BugReporting.reportBug(
"Bug in ${this::class.simpleName}",
mapOf("key" to name, "data" to data),
)
}
},
decimalPlacesCount,
).joinToString(" ")
// If the labels do not match keys, require predictable iteration order
else -> {
require(data.hasPredictableIteration) {
Expand All @@ -122,7 +128,7 @@ constructor(
""".trimIndent(),
)
}
data.values.joinToString(" ")
roundValues(data.values, decimalPlacesCount).joinToString(" ")
}
}
}
Expand All @@ -140,6 +146,15 @@ constructor(
}
}

private fun roundValues(values: Collection<String>, decimalsNumber: Int): Collection<String> = values.map { raw ->
val number = raw.toDoubleOrNull()
if (number == null || !number.isFinite() || number % 1.0 == 0.0) {
raw
} else {
String.format(Locale.US, "%.${decimalsNumber}f", number)
}
}

private companion object {
/**
* Character used to separate comments from data on export files.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ class TestCSVExporter<T, P : Position<P>> :
}
"should have limited-length decimals" {
val limitedDecimalsFile = simulation.csvExporters()[1].dataFile("fixed-decimals_")
val precision2 = """(0\.0*\d\d|\d\.0*\d|\d\.\d|\d\d)(e(-|\+)\d+)?"""
val precision2 = """(\d\d\.\d\d|0\.0*\d\d|\d\.0*\d|\d\.\d|\d\d)(e(-|\+)\d+)?"""
val lineRegex = Regex("""^$precision2(\s($precision2))+$""")
limitedDecimalsFile.useLines { lines ->
lines
Expand Down
Loading