Closed dih-cdisc closed 1 year ago
Initial outline of issue discussed at the SME Meeting 2022 10 19 SampleSoAs_Timepoints.docx
Comment from various sources:
The features required are:
Timepoints needed are:
Also need support for cohort studies
Specific SoA points to consider (not extensive) from Berber. Timepoints
Cycles
Arms
Unscheduled visits:
Sketch design available here on the wiki
In particular note the slide deck and the diagram 2023 01 25 DDF Model Incl Timepoints"
Updated sketch design and supporting slide deck
@cupkes @ggasg start having a look
Ok. Here's what I have so far...
Let's talk about the timline composition starting at the Timeline class. /**
public class Timeline {
**private final String timelineId;**
// A textual description of the timeline. There will likely be numerous timelines in a study and this
// field provides the context for the particular timeline.
**private String timelineDescription;**
// It makes sense to have object references to SoA structure objects (timepoint, entry, exit)
// This should be the highest level in the JSON payload to attach the object details. Below this level
// (such as pointers between timepoints) references will be ID references to avoid duplication.
// The timeline entry and exi don't seem to be as important in the composition of a timeline, if
// we reference "timelines" from higher in the class hierarchy.
// If every timeline has a discrete entry and exit point, then why do we really need seperate, referenceable
// Entry and Exit classes. This could simply be just some useful attribution in a timeline.
// Example, if I'm grabbing timeline named "base timeline for this study", and I grab the timeline, why do
// I need to deferefeence the entry? It seems as if I would just ask for the first timepoint, ordinally.
// Maybe entry is an attribute of a timepoint? Just my thoughts.
**private Entry timelineEntry;**
// Ditto from above for exit.
**private Exit timelineExit;**
// At this point, this is an unordered list of timepoints. We might consider more encapsulation by
// creating a timepointSequence wrapper.
**private List<Timepoint> timelineTimepoints;**
// Are cycles really discrete timelines that provide some type of iteration mechanism?
// Do we force the design to break cyclic seqences
// off from strictly linear sequences? Or, do we add complexity to the definition of a timeline
// Maybe a cycle is just attached to an existing timeline defines a time loop? Remember,
// these aren't your typical "timeines"...they are more of a seqencical structuring of activities, conditions
// and encounters. So, it's quite logical to want to repeat a portion of a longer sequence to
// meet a particular condition. I must noodle on this...
// Ok, my initial thoughts lead to a sentinel that observes a timeline and has a cycle start and end maybe...
// and there must be an iteration condition (iterate? Yes, No).
// A timepoint of type Cycle with a relationship that points to a cycle start (another timepoint) and
// with a condition attached that determines progression? This could muddy the timepoint and it's
// truly polymorphic while currently the Branch vs Node types don't really have anly overloaded behaviors (yet).
// However, I'm still for it because how is a cycle that much different than a branch except it points
// to something upstream as opposed to downstream?
// It seems plausible to encapsulate starts, ends and loops in the actual timeline class itself.
Now, let's review the timepoint class:
/**
public class Timepoint {
private final String timepointId;
// The textual representation of the timepoint.
private String timepointDescription;
// Denotes the type timepoint object added to the timeline. The value can be either a node or a branch.
// a branch being used to link alternate or sub-timelines to an existing timeline.
private Code timepointType;
// The condition that may be associated with the timepoint, if the timepoint is of type branch
// (according to the presentation material).
// Even though a condition could or should be re-used across multiple timepoints and/or entries
// this reference should be an object reference as there would be no other object reference
// available to ensure inclusion in the JSON payload (to my understanding)
private Condition timepointCondition;
// Unsure of the nescessity of this id reference to an actual Exit class.
// It seems to make sense to associate an exit condition and maybe an exit flag to a timepoint.
// What attributes are required to be associated with an Exit that should be solely
// contained in an Exit class? Maybe just saying a timepoint is a final timepoint is just as intuitive?
private String timepointExitId;
// Must assume this is an object reference as no other references exist in the model except for Encounter and
// that would not necessarily be the same timepoint being referenced, so no duplication will likely exist.
// This could be considered an attribute of the timepoint because I'm not sure that the timing
// has any value outside of its inclusion in the timepoint data (except for maybe...reuse?)
private Timing timepointScheduledAt;
// when referencing objects from the timeline, it's important to use id references
// because the API JSON payload would result in duplicate expressions of objects pointing
// to the timeline. This assumption should be asserted.
// All of these fields below should be defined as relationships in the CT.
// In particular for pointers between timepoints, it seems to me that there
// should be some clear understanding that only a Branch type timepoint
// is capable of pointing to more than one previous or next timepoint. Am I misunderstanding the
// the use of the type attribute?
private List<String> previousTimepointIds;
private List<String> nextTimepointIds;
// I'm somewhat confused as to why an encounter has multiple touchpoints in the timeline, but I haven't
// heard of a broad set of use cases for traversal of the timeline.
// You can get to a timepoint from an encounter via a timing. You then have a circular reference from the timing
// via the timepoint. There is potential for these to be out of sync as well, correct?
private String timepointEncounterId;
// This is the only way to associate activities with timepoints, as we've decided that the cardinality
// from timepoint to activities is one to many, correct?
private List<String> timepointActivityIds;
// I'm still waffling on this entry concept. We know the first timepoint in any sequence simply because
// it has no pointer to a predecessor. If a timepoint can be a node or a branch, why can't it also be
// an entry timepoint or an exit timepoint. Polymorphism has been problematic, however, much like BC data,
// it is more elegant that trying to provide solid semantics to differentiate things that are ideally
// seen as similar yet unique among themselves. Like managing anything as a category without actually
// referencing the category (i.e. StudyData).
private String timepointEntryId;
Timing up next:
/**
public class Timing {
private final String timingId;
// Code values that describe the type of timing. Valid values include Before, After and Absolute.
private Code timingType;
// According to the presentation, the value will be provide further context based on the type of the timing.
// For example, if the timing type is absolute then maybe something like "first dose, day 0"
// and if the type is Before it could be "1 day before x".
private String timingValue;
// Code values that describe the timing relative to the associated timepoint, I believe. Somewhat unsure here.
// Values are typical of gant task relationship dependencies. They are: StartToStart, StartToEnd,
// EndToEnd and EndToStart.
private Code timingRelativeToFrom;
// Defines window of time associated with the timing. This seems like slack in a project timeline.
// Example value could be 2 hour window. In a standard task sequence that sounds like "2 hours of slack"
// in the schedule to accomplish associated activities, etc... Is this correct?
private String timingWindow;
Let's wrap up for today with Condition:
/**
public class Condition {
private final String conditionId;
// The textual representation of the transition rule. 'Nuff said.
private String conditionDescription;
// Not much to this class. Doesn't seem like enough information to reside in its own class definition.
// Are we defining this class strictly for reuse in timelines, like codes?
// Still is hard to argue that it's way better as a class reference than a string field, since
// the conditionId is the only thing we're associating with the class except for description.
// The answer must be that we are not done defining the class.
Add of timepoints into the model