2020import org .labkey .api .query .UserSchema ;
2121import org .labkey .api .security .User ;
2222import org .labkey .api .studies .StudiesService ;
23+ import org .labkey .api .studies .query .ResultsOORDisplayColumn ;
2324import org .labkey .api .study .Dataset ;
2425import org .labkey .api .study .DatasetTable ;
2526import org .labkey .api .util .logging .LogHelper ;
@@ -60,8 +61,9 @@ public void performDatasetCustomization(DatasetTable ds)
6061
6162 if (!ds .getDataset ().isDemographicData ())
6263 {
63- appendAgeAtTimeCol (ds .getUserSchema (), ati , DATE_COL );
64+ appendAgeAtTimeCol (ds .getUserSchema (), ati , ID_COL , DATE_COL );
6465 appendPvlColumns (ds , ID_COL , DATE_COL );
66+ appendSivChallengeColumns (ati , ID_COL , DATE_COL );
6567 }
6668
6769 appendDemographicsColumns (ati );
@@ -104,7 +106,7 @@ else if (pks.contains("subjectId"))
104106 return null ;
105107 }
106108
107- private void appendAgeAtTimeCol (UserSchema demographicsSchema , AbstractTableInfo ds , final String dateColName )
109+ private void appendAgeAtTimeCol (UserSchema demographicsSchema , AbstractTableInfo ds , final String subjectColName , final String dateColName )
108110 {
109111 String name = "ageAtTime" ;
110112 if (ds .getColumn (name , false ) != null )
@@ -114,7 +116,7 @@ private void appendAgeAtTimeCol(UserSchema demographicsSchema, AbstractTableInfo
114116 if (pkCol == null )
115117 return ;
116118
117- final ColumnInfo idCol = ds .getColumn (ID_COL );
119+ final ColumnInfo idCol = ds .getColumn (subjectColName );
118120 if (idCol == null )
119121 return ;
120122
@@ -272,10 +274,100 @@ private void appendPvlColumns(DatasetTable ds, String subjectColName, String dat
272274 ExprColumn newCol = new ExprColumn (ti , name , sql , JdbcType .DOUBLE , subjectCol , dateCol );
273275 newCol .setDescription ("Displays the viral load from this timepoint, if present" );
274276 newCol .setLabel ("SIV PVL (copies/mL)" );
277+ newCol .setDisplayColumnFactory (ResultsOORDisplayColumn ::new );
275278 ti .addColumn (newCol );
279+
280+ String nameOOR = name + "OORIndicator" ;
281+ SQLFragment sqlOOR = new SQLFragment ("(SELECT CASE WHEN count(t.result) = 1 THEN max(t.resultOORIndicator) ELSE null END as expr FROM studydataset." + tableName + " t WHERE t.participantid = " + ExprColumn .STR_TABLE_ALIAS + ".participantid AND CAST(t.date AS DATE) = CAST(" + ExprColumn .STR_TABLE_ALIAS + ".date AS DATE) AND t.sampletype = 'Plasma' AND t.target = 'SIV')" );
282+ ExprColumn newColOOR = new ExprColumn (ti , nameOOR , sqlOOR , JdbcType .VARCHAR , subjectCol , dateCol );
283+ newColOOR .setDescription ("For the corresponding PVL, this indicates if the value is out-of-range" );
284+ newColOOR .setLabel ("SIV PVL OOR Indicator" );
285+ newColOOR .setHidden (true );
286+
287+ ti .addColumn (newColOOR );
276288 }
277289 }
278290
291+ private void appendSivChallengeColumns (AbstractTableInfo targetTable , String subjectColName , String dateColName )
292+ {
293+ String name = "timePostSivChallenge" ;
294+ if (targetTable .getColumn (name , false ) != null )
295+ return ;
296+
297+ final ColumnInfo pkCol = getPkCol (targetTable );
298+ if (pkCol == null )
299+ return ;
300+
301+ final ColumnInfo idCol = targetTable .getColumn (subjectColName );
302+ if (idCol == null )
303+ return ;
304+
305+ final ColumnInfo dateCol = targetTable .getColumn (dateColName );
306+ if (dateCol == null )
307+ return ;
308+
309+ final String targetSchemaName = targetTable .getUserSchema ().getName ();
310+ final Container targetSchemaContainer = targetTable .getUserSchema ().getContainer ();
311+ final User u = targetTable .getUserSchema ().getUser ();
312+ final String schemaName = targetTable .getPublicSchemaName ();
313+ final String queryName = targetTable .getName ();
314+
315+ WrappedColumn col = new WrappedColumn (pkCol , name );
316+ col .setLabel ("SIV Challenge" );
317+ col .setReadOnly (true );
318+ col .setIsUnselectable (true );
319+ col .setUserEditable (false );
320+ col .setFk (new LookupForeignKey (){
321+ @ Override
322+ public TableInfo getLookupTableInfo ()
323+ {
324+ String name = queryName + "_sivChallenge" ;
325+ UserSchema targetSchema = targetTable .getUserSchema ().getDefaultSchema ().getUserSchema (targetSchemaName );
326+ QueryDefinition qd = QueryService .get ().createQueryDef (u , targetSchemaContainer , targetSchema , name );
327+ qd .setSql ("SELECT\n " +
328+ "max(ad.date) as infectionDate,\n " +
329+ // NOTE: CAST() is used to ensure whole numbers
330+ "CONVERT(TIMESTAMPDIFF('SQL_TSI_DAY', CAST(max(ad.date) AS DATE), CAST(c." + dateColName + " AS DATE)), INTEGER) as daysPostInfection,\n " +
331+ "CONVERT(age_in_months(CAST(max(ad.date) AS DATE), CAST(c." + dateColName + " AS DATE)), FLOAT) as monthsPostInfection,\n " +
332+ pkCol .getFieldKey ().toString () + "\n " +
333+ "FROM \" " + schemaName + "\" .\" " + queryName + "\" c " +
334+ "JOIN studies.subjectAnchorDates ad ON (ad.subjectId = c." + idCol .getFieldKey ().toSQLString () + " AND ad.date = c." + dateCol .getFieldKey ().toString () + ")\n " +
335+ "WHERE ad.eventLabel = 'SIV Infection'\n " +
336+ "GROUP BY c.date, c." + pkCol .getFieldKey ().toString () + "\n " +
337+ "HAVING count(*) = 1"
338+ );
339+ qd .setIsTemporary (true );
340+
341+ List <QueryException > errors = new ArrayList <>();
342+ TableInfo ti = qd .getTable (errors , true );
343+ if (!errors .isEmpty ())
344+ {
345+ _log .warn ("Error creating sivChallenge lookup table for: " + schemaName + "." + queryName + " in container: " + targetSchema .getContainer ().getPath ());
346+ for (QueryException e : errors )
347+ {
348+ _log .warn (e .getMessage (), e );
349+ }
350+ }
351+
352+ if (ti != null )
353+ {
354+ ((BaseColumnInfo )ti .getColumn (pkCol .getName ())).setHidden (true );
355+ ((BaseColumnInfo )ti .getColumn (pkCol .getName ())).setKeyField (true );
356+
357+ ((BaseColumnInfo )ti .getColumn ("infectionDate" )).setLabel ("Infection Date" );
358+ ((BaseColumnInfo )ti .getColumn ("daysPostInfection" )).setLabel ("Days Post-Infection" );
359+ ((BaseColumnInfo )ti .getColumn ("monthsPostInfection" )).setLabel ("Months Post-Infection" );
360+ }
361+
362+ return ti ;
363+ }
364+ });
365+
366+ targetTable .addColumn (col );
367+ }
368+
369+ // TODO: was on ART or not??
370+
279371 private BaseColumnInfo getWrappedIdCol (UserSchema targetQueryUserSchema , String targetQueryName , AbstractTableInfo demographicsTable , String colName )
280372 {
281373 WrappedColumn col = new WrappedColumn (demographicsTable .getColumn (ID_COL ), colName );
0 commit comments