Skip to content

Commit

Permalink
add lackadaisical case for trace ID assignment and grouping of proxim…
Browse files Browse the repository at this point in the history
…al ROIs, #279
  • Loading branch information
vreuter committed Nov 17, 2024
1 parent 93beaf5 commit 650e15b
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 8 deletions.
23 changes: 15 additions & 8 deletions src/main/scala/AssignTraceIds.scala
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ object AssignTraceIds extends ScoptCliReaders, StrictLogging:
lookupProximity
// First, these records' timepoints may not have been in the rules set and
// may therefore need to be tested for proximity.
.get(r1.context.timepoint -> r2.context.timepoint)
.get(r1.timepoint -> r2.timepoint)
// Emit a pair of edge endpoints iff these records are proximal.
.flatMap(_.proximal(r1, r2).option(r1.index -> r2.index))
case notPair =>
Expand All @@ -159,7 +159,7 @@ object AssignTraceIds extends ScoptCliReaders, StrictLogging:

maybeRecords.toNel.map{ records =>
val lookupRecord: NonEmptyMap[RoiIndex, InputRecord] = records.map(r => r.index -> r).toNem
val lookupStringency: TimepointExpectationLookup =
val lookupRule: TimepointExpectationLookup =
// Provide a way to get the expected group members and requirement stringency for a given timepoint.
given orderForKeyValuePairs[V]: Order[(ImagingTimepoint, V)] = Order.by(_._1)
given semigroup: Semigroup[TimepointExpectationLookup] =
Expand Down Expand Up @@ -196,14 +196,18 @@ object AssignTraceIds extends ScoptCliReaders, StrictLogging:
val newRecs: List[(InputRecord, TraceId, Option[NonEmptySet[RoiIndex]])] =
AtLeast2.either(recGroup.map(_.index).toList.toSet).fold(
Function.const{ // singleton
if discardIfNotInGroupOfInterest then List()
else List((recGroup.head, currId, None))
given Eq[RoiPartnersRequirementType] = Eq.fromUniversalEquals
val useRecord = lookupRule
.apply(recGroup.head.timepoint)
.fold(!discardIfNotInGroupOfInterest)(_.requirement === RoiPartnersRequirementType.Lackadaisical)
if useRecord then List((recGroup.head, currId, None))
else List()
},
multiIds =>
val useGroup: Boolean =
recGroup // at least two ROIs in group/component
.toList
.flatMap{ r => lookupStringency.apply(r.context.timepoint) }
.flatMap{ r => lookupRule.apply(r.timepoint) }
.toNel
.fold(!discardIfNotInGroupOfInterest){ rules =>
given Eq[TraceIdDefinitionAndFiltrationRule] = Eq.fromUniversalEquals
Expand All @@ -215,12 +219,14 @@ object AssignTraceIds extends ScoptCliReaders, StrictLogging:
else
val rule = rules.head
val expectedTimes = rule.mergeGroup.members.toSet
val observedTimes = recGroup.map(_.context.timepoint).toList.toSet
val observedTimes = recGroup.map(_.timepoint).toList.toSet
rule.requirement match {
case RoiPartnersRequirementType.Conjunctive =>
observedTimes === expectedTimes
case RoiPartnersRequirementType.Disjunctive => ???
case RoiPartnersRequirementType.Disjunctive =>
observedTimes subsetOf expectedTimes
case RoiPartnersRequirementType.Lackadaisical =>
true
}
}
if useGroup
Expand Down Expand Up @@ -257,7 +263,8 @@ object AssignTraceIds extends ScoptCliReaders, StrictLogging:
box: BoundingBox,
maybeMergeInputs: Set[RoiIndex], // may be empty, as the input collection is possibly a mix of singletons and merge results
maybeNucleusNumber: Option[NucleusNumber], // allow the program to operate on non-nuclei-filtered ROIs.
)
):
final def timepoint: ImagingTimepoint = context.timepoint

/** Helpers for working with this program's input records */
object InputRecord:
Expand Down
2 changes: 2 additions & 0 deletions src/main/scala/ImagingRoundsConfiguration.scala
Original file line number Diff line number Diff line change
Expand Up @@ -449,6 +449,8 @@ object ImagingRoundsConfiguration extends LazyLogging:
case Disjunctive
/** Require proximity of 'all' group members (i.e., logical AND). */
case Conjunctive
/** Group ROIs for tracing if they're proximal, but do 'not' discard singletons from the groups. */
case Lackadaisical

/** A grouping of elements {@code E} to consider for proximity relative to some distance threshold */
final case class ProximityGroup[T <: DistanceThreshold, E](
Expand Down

0 comments on commit 650e15b

Please sign in to comment.