Skip to content

Commit

Permalink
type name to better reflect that logic encapsulated in each instance …
Browse files Browse the repository at this point in the history
…of the type
  • Loading branch information
vreuter committed Dec 2, 2024
1 parent 02a4250 commit 194a852
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 43 deletions.
12 changes: 6 additions & 6 deletions src/main/scala/AssignTraceIds.scala
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ import at.ac.oeaw.imba.gerlich.gerlib.syntax.all.*

import at.ac.oeaw.imba.gerlich.looptrace.ImagingRoundsConfiguration.{
RoiPartnersRequirementType,
TraceIdDefinitionAndFiltrationRule,
TraceIdDefinitionRule,
}
import at.ac.oeaw.imba.gerlich.looptrace.cli.ScoptCliReaders
import at.ac.oeaw.imba.gerlich.looptrace.csv.ColumnNames.{
Expand Down Expand Up @@ -113,7 +113,7 @@ object AssignTraceIds extends ScoptCliReaders, StrictLogging:
}

private def definePairwiseDistanceThresholds(
rules: NonEmptyList[TraceIdDefinitionAndFiltrationRule],
rules: NonEmptyList[TraceIdDefinitionRule],
): Map[(ImagingTimepoint, ImagingTimepoint), DistanceThreshold] =
import AtLeast2.syntax.toList
rules.map(_.mergeGroup)
Expand All @@ -139,7 +139,7 @@ object AssignTraceIds extends ScoptCliReaders, StrictLogging:
}

private def computeNeighborsGraph(
rules: NonEmptyList[TraceIdDefinitionAndFiltrationRule],
rules: NonEmptyList[TraceIdDefinitionRule],
pixels: Pixels3D,
)(records: NonEmptyList[InputRecord]): SimplestGraph[RoiIndex] =
val lookupProximity: Map[(ImagingTimepoint, ImagingTimepoint), ProximityComparable[InputRecord]] =
Expand Down Expand Up @@ -197,13 +197,13 @@ object AssignTraceIds extends ScoptCliReaders, StrictLogging:
TraceId.unsafe(NonnegativeInt(1) + maxRoiId.get)

private[looptrace] def labelRecordsWithTraceId(
rules: NonEmptyList[TraceIdDefinitionAndFiltrationRule],
rules: NonEmptyList[TraceIdDefinitionRule],
discardIfNotInGroupOfInterest: Boolean,
pixels: Pixels3D,
)(records: NonEmptyList[InputRecord]): NonEmptyList[OutputRecord] =
/* Necessary imports and type aliases */
import AtLeast2.syntax.{ remove, toNes, toSet }
type TimepointExpectationLookup = NonEmptyMap[ImagingTimepoint, TraceIdDefinitionAndFiltrationRule]
type TimepointExpectationLookup = NonEmptyMap[ImagingTimepoint, TraceIdDefinitionRule]

val lookupRecord: NonEmptyMap[RoiIndex, InputRecord] = records.map(r => r.index -> r).toNem
val lookupRule: TimepointExpectationLookup =
Expand Down Expand Up @@ -252,7 +252,7 @@ object AssignTraceIds extends ScoptCliReaders, StrictLogging:
.flatMap{ r => lookupRule.apply(r.timepoint) }
.toNel
.fold(!discardIfNotInGroupOfInterest){ rules =>
given Eq[TraceIdDefinitionAndFiltrationRule] = Eq.fromUniversalEquals
given Eq[TraceIdDefinitionRule] = Eq.fromUniversalEquals
val nUniqueRules = rules.toList.toSet.size
if nUniqueRules =!= 1
then throw new Exception(
Expand Down
24 changes: 12 additions & 12 deletions src/main/scala/ImagingRoundsConfiguration.scala
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ final case class ImagingRoundsConfiguration private(
sequence: ImagingSequence,
locusGrouping: Set[ImagingRoundsConfiguration.LocusGroup], // should be empty iff there are no locus rounds in the sequence
proximityFilterStrategy: ImagingRoundsConfiguration.ProximityFilterStrategy,
private val maybeMergeRulesForTracing: Option[(NonEmptyList[ImagingRoundsConfiguration.TraceIdDefinitionAndFiltrationRule], Boolean)],
private val maybeMergeRulesForTracing: Option[(NonEmptyList[ImagingRoundsConfiguration.TraceIdDefinitionRule], Boolean)],
// TODO: We could, by default, skip regional and blank imaging rounds (but do use repeats).
tracingExclusions: Set[ImagingTimepoint], // Timepoints of imaging rounds to not use for tracing
):
Expand All @@ -40,7 +40,7 @@ final case class ImagingRoundsConfiguration private(
/** Simply take the rounds from the contained imagingRounds sequence. */
final def allRounds: NonEmptyList[ImagingRound] = sequence.allRounds

final def mergeRules: Option[NonEmptyList[ImagingRoundsConfiguration.TraceIdDefinitionAndFiltrationRule]] =
final def mergeRules: Option[NonEmptyList[ImagingRoundsConfiguration.TraceIdDefinitionRule]] =
maybeMergeRulesForTracing.map(_._1)

final def discardRoisNotInGroupsOfInterest: Boolean = maybeMergeRulesForTracing.fold(false)(_._2)
Expand Down Expand Up @@ -128,7 +128,7 @@ object ImagingRoundsConfiguration extends LazyLogging:
locusGrouping: Set[LocusGroup],
proximityFilterStrategy: ProximityFilterStrategy,
tracingExclusions: Set[ImagingTimepoint],
maybeMergeRules: Option[(NonEmptyList[TraceIdDefinitionAndFiltrationRule], Boolean)],
maybeMergeRules: Option[(NonEmptyList[TraceIdDefinitionRule], Boolean)],
checkLocusTimepointCovering: Boolean,
): ErrMsgsOr[ImagingRoundsConfiguration] = {
val knownTimes = sequence.allTimepoints
Expand Down Expand Up @@ -213,7 +213,7 @@ object ImagingRoundsConfiguration extends LazyLogging:
// Then, find repeated locus timepoints WITHIN each merge group.
type GroupId = Int
val repeatsByGroup: Map[GroupId, NonEmptyMap[ImagingTimepoint, AtLeast2[Set, ImagingTimepoint]]] =
def processOneRule = (r: TraceIdDefinitionAndFiltrationRule) =>
def processOneRule = (r: TraceIdDefinitionRule) =>
r.mergeGroup.members.toList.foldRight(Map.empty[ImagingTimepoint, NonEmptySet[ImagingTimepoint]]){
(rt, acc) => locusTimesByRegional
.get(rt)
Expand Down Expand Up @@ -377,14 +377,14 @@ object ImagingRoundsConfiguration extends LazyLogging:
.map(_.toSet)
.toValidatedNel
}
val maybeMergeRulesNel: ValidatedNel[String, Option[(NonEmptyList[TraceIdDefinitionAndFiltrationRule], Boolean)]] =
val maybeMergeRulesNel: ValidatedNel[String, Option[(NonEmptyList[TraceIdDefinitionRule], Boolean)]] =
val sectionKey = "mergeRulesForTracing"
data.get(sectionKey) match {
case None | Some(ujson.Null) =>
logger.debug(s"No section '$sectionKey', ignoring")
Validated.Valid(None)
case Some(jsonData) =>
TraceIdDefinitionAndFiltrationRulesSet.fromJson(jsonData).toValidated.map(_.some)
TraceIdDefinitionRulesSet.fromJson(jsonData).toValidated.map(_.some)
}
val checkLocusTimepointCoveringNel: ValidatedNel[String, Boolean] =
data.get("checkLocusTimepointCovering") match {
Expand All @@ -409,7 +409,7 @@ object ImagingRoundsConfiguration extends LazyLogging:
locusGrouping: Set[LocusGroup],
proximityFilterStrategy: ProximityFilterStrategy,
tracingExclusions: Set[ImagingTimepoint],
maybeMergeRules: Option[(NonEmptyList[TraceIdDefinitionAndFiltrationRule], Boolean)],
maybeMergeRules: Option[(NonEmptyList[TraceIdDefinitionRule], Boolean)],
checkLocusTimepointCoveringNel: Boolean,
): ImagingRoundsConfiguration =
build(
Expand Down Expand Up @@ -519,18 +519,18 @@ object ImagingRoundsConfiguration extends LazyLogging:
end ProximityGroup

/** How to redefine trace IDs and filter ROIs on the basis of proximity to one another */
final case class TraceIdDefinitionAndFiltrationRule(
final case class TraceIdDefinitionRule(
mergeGroup: ProximityGroup[EuclideanDistance.Threshold, ImagingTimepoint],
requirement: RoiPartnersRequirementType,
)

/** Helpers for working with the data type for trace ID definition and filtration */
object TraceIdDefinitionAndFiltrationRulesSet:
object TraceIdDefinitionRulesSet:
/** The key which maps to the collection of groups */
private val groupsKey = "groups"
private val strictnessKey = "discardRoisNotInGroupsOfInterest"

def fromJson(json: ujson.Readable): EitherNel[String, (NonEmptyList[TraceIdDefinitionAndFiltrationRule], Boolean)] =
def fromJson(json: ujson.Readable): EitherNel[String, (NonEmptyList[TraceIdDefinitionRule], Boolean)] =
Try{ read[Map[String, ujson.Value]](json) }
.toEither
.leftMap(e => NonEmptyList.one(s"Cannot read JSON as key-value pairs: ${e.getMessage}"))
Expand Down Expand Up @@ -576,7 +576,7 @@ object ImagingRoundsConfiguration extends LazyLogging:
case (Some(threshold), None) => NonEmptyList.one("Missing requirement type for ROI merge").asLeft
case (None, Some(reqType)) => NonEmptyList.one("Missing threshold for ROI merge").asLeft
case (Some(threshold), Some(reqType)) =>
groups.map{ g => TraceIdDefinitionAndFiltrationRule(
groups.map{ g => TraceIdDefinitionRule(
ProximityGroup(threshold, g),
reqType,
)
Expand Down Expand Up @@ -618,7 +618,7 @@ object ImagingRoundsConfiguration extends LazyLogging:
AtLeast2.unsafe(uniques)
)
}
end TraceIdDefinitionAndFiltrationRulesSet
end TraceIdDefinitionRulesSet

/** Check list of items for nonemptiness. */
private def liftToNel[A](as: List[A], context: Option[String] = None): Either[String, NonEmptyList[A]] =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import at.ac.oeaw.imba.gerlich.looptrace.ImagingRoundsConfiguration.{
RoiPartnersRequirementType,
SelectiveProximityPermission,
SelectiveProximityProhibition,
TraceIdDefinitionAndFiltrationRule,
TraceIdDefinitionRule,
UniversalProximityPermission,
UniversalProximityProhibition,
}
Expand Down Expand Up @@ -218,7 +218,7 @@ class TestImagingRoundsConfigurationExamplesParsability extends AnyFunSuite with
NonEmptyList.of(Set(6, 7), Set(8, 9))
.map(_.map(ImagingTimepoint.unsafe).pipe(AtLeast2.unsafe))
.map{ g =>
TraceIdDefinitionAndFiltrationRule(
TraceIdDefinitionRule(
ProximityGroup(expDistance, g),
RoiPartnersRequirementType.Conjunctive,
)
Expand Down Expand Up @@ -262,7 +262,7 @@ class TestImagingRoundsConfigurationExamplesParsability extends AnyFunSuite with
check = (msg: String, exp: String) => msg.startsWith(exp) // Here we just to prefix check.
)

private def checkParseSuccess(configFile: os.Path, expectedMergeParseResult: (Boolean, NonEmptyList[TraceIdDefinitionAndFiltrationRule])) =
private def checkParseSuccess(configFile: os.Path, expectedMergeParseResult: (Boolean, NonEmptyList[TraceIdDefinitionRule])) =
val (expFilter, expRules) = expectedMergeParseResult
ImagingRoundsConfiguration.fromJsonFile(configFile) match {
case Left(messages) =>
Expand All @@ -276,7 +276,7 @@ class TestImagingRoundsConfigurationExamplesParsability extends AnyFunSuite with
val mergeRulesNel = conf.mergeRules match {
case None => "No merge rules section".invalidNel
case Some(obsRules) =>
given Eq[TraceIdDefinitionAndFiltrationRule] = Eq.fromUniversalEquals
given Eq[TraceIdDefinitionRule] = Eq.fromUniversalEquals
if obsRules === expRules
then ().validNel
else f"Observed rules ($obsRules) don't match expected ($expRules)".invalidNel
Expand Down
Loading

0 comments on commit 194a852

Please sign in to comment.