Skip to content

Commit ecd42bb

Browse files
committed
Cross-folder instrument utilization report
1 parent e933795 commit ecd42bb

11 files changed

Lines changed: 498 additions & 1 deletion
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<query xmlns="http://labkey.org/data/xml/query">
2+
<metadata>
3+
<tables xmlns="http://labkey.org/data/xml">
4+
<table tableName="InstrumentUtilizationByDay" tableDbType="TABLE">
5+
<tableTitle>Runs by Day</tableTitle>
6+
<columns>
7+
<column columnName="AcquisitionDate">
8+
<columnTitle>Date</columnTitle>
9+
<formatString>Date</formatString>
10+
</column>
11+
<column columnName="RunCount">
12+
<columnTitle>Runs</columnTitle>
13+
</column>
14+
<column columnName="FileCount">
15+
<columnTitle>Files</columnTitle>
16+
</column>
17+
<column columnName="InstrumentNickname">
18+
<columnTitle>Instrument</columnTitle>
19+
</column>
20+
</columns>
21+
</table>
22+
</tables>
23+
</metadata>
24+
</query>
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/*
2+
* Copyright (c) 2026 LabKey Corporation
3+
*
4+
* Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0
5+
*/
6+
7+
-- Number of sample files and runs acquired per day, by instrument, across all folders the user can read.
8+
-- Consumed by the instrument utilization calendar and the "Runs by Day" grid on the Show Instrument page.
9+
SELECT
10+
CAST(AcquisitionDay AS TIMESTAMP) AS AcquisitionDate,
11+
COUNT(*) AS FileCount,
12+
COUNT(DISTINCT RunId) AS RunCount,
13+
InstrumentNickname
14+
FROM
15+
(SELECT
16+
CAST(YEAR(AcquiredTime) AS VARCHAR) || '-' ||
17+
(CASE WHEN MONTH(AcquiredTime) < 10 THEN '0' ELSE '' END) || CAST(MONTH(AcquiredTime) AS VARCHAR) || '-' ||
18+
(CASE WHEN DAYOFMONTH(AcquiredTime) < 10 THEN '0' ELSE '' END) || CAST(DAYOFMONTH(AcquiredTime) AS VARCHAR) AS AcquisitionDay,
19+
ReplicateId.RunId AS RunId,
20+
InstrumentNickname
21+
FROM targetedms.SampleFile
22+
WHERE AcquiredTime IS NOT NULL) X
23+
GROUP BY AcquisitionDay, InstrumentNickname
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<query xmlns="http://labkey.org/data/xml/query">
2+
<metadata>
3+
<tables xmlns="http://labkey.org/data/xml">
4+
<table tableName="InstrumentUtilizationByMonth" tableDbType="TABLE">
5+
<tableTitle>Runs by Month</tableTitle>
6+
<columns>
7+
<column columnName="MonthStart">
8+
<columnTitle>Month</columnTitle>
9+
<formatString>yyyy-MM</formatString>
10+
</column>
11+
<column columnName="RunCount">
12+
<columnTitle>Runs</columnTitle>
13+
</column>
14+
<column columnName="FileCount">
15+
<columnTitle>Files</columnTitle>
16+
</column>
17+
<column columnName="InstrumentNickname">
18+
<columnTitle>Instrument</columnTitle>
19+
</column>
20+
</columns>
21+
</table>
22+
</tables>
23+
</metadata>
24+
</query>
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
/*
2+
* Copyright (c) 2026 LabKey Corporation
3+
*
4+
* Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0
5+
*/
6+
7+
-- Number of sample files and runs acquired per month, by instrument, across all folders the user can read.
8+
-- Consumed by the "Runs by Month" grid on the Show Instrument page.
9+
SELECT
10+
CAST(MonthStart || '-01' AS TIMESTAMP) AS MonthStart,
11+
COUNT(*) AS FileCount,
12+
COUNT(DISTINCT RunId) AS RunCount,
13+
InstrumentNickname
14+
FROM
15+
(SELECT
16+
CAST(YEAR(AcquiredTime) AS VARCHAR) || '-' ||
17+
(CASE WHEN MONTH(AcquiredTime) < 10 THEN '0' ELSE '' END) || CAST(MONTH(AcquiredTime) AS VARCHAR) AS MonthStart,
18+
ReplicateId.RunId AS RunId,
19+
InstrumentNickname
20+
FROM targetedms.SampleFile
21+
WHERE AcquiredTime IS NOT NULL) X
22+
GROUP BY MonthStart, InstrumentNickname
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
<div id="app"></div>
2+
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
2+
<view xmlns="http://labkey.org/data/xml/view" frame="none" title="Instrument Scheduler">
3+
4+
5+
<permissionClasses>
6+
7+
<permissionClass name="org.labkey.api.security.permissions.ReadPermission"/>
8+
9+
</permissionClasses>
10+
11+
12+
13+
<dependencies>
14+
<dependency path="clientapi"/>
15+
16+
17+
18+
<dependency path="gen/instrumentScheduler.0d0ec74aeaa5bb72a486.js"/>
19+
20+
21+
</dependencies>
22+
</view>
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
<div id="app"></div>
2+
3+
<script src="http://localhost:3001/instrumentScheduler.js" nonce="<%=scriptNonce%>"></script>
4+
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
2+
<view xmlns="http://labkey.org/data/xml/view" frame="none" title="Instrument Scheduler">
3+
4+
5+
<permissionClasses>
6+
7+
<permissionClass name="org.labkey.api.security.permissions.ReadPermission"/>
8+
9+
</permissionClasses>
10+
11+
12+
13+
<dependencies>
14+
<dependency path="clientapi"/>
15+
16+
17+
</dependencies>
18+
</view>

src/org/labkey/targetedms/TargetedMSController.java

Lines changed: 58 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4815,6 +4815,8 @@ public ShowInstrumentAction()
48154815
}
48164816

48174817
private static final String FOLDER_SUMMARY = "FolderSummary";
4818+
private static final String UTILIZATION_BY_DAY = "UtilizationByDay";
4819+
private static final String UTILIZATION_BY_MONTH = "UtilizationByMonth";
48184820

48194821
private InstrumentForm _form;
48204822

@@ -4846,11 +4848,29 @@ protected QueryView createQueryView(InstrumentForm form, BindException errors, b
48464848
TargetedMSSchema schema = new TargetedMSSchema(getUser(), getContainer());
48474849
return schema.createView(getViewContext(), settings, errors);
48484850
}
4851+
if (UTILIZATION_BY_DAY.equalsIgnoreCase(dataRegion))
4852+
{
4853+
QuerySettings settings = new QuerySettings(getViewContext(), UTILIZATION_BY_DAY, "InstrumentUtilizationByDay");
4854+
settings.setBaseSort(new Sort("-AcquisitionDate"));
4855+
settings.setBaseFilter(new SimpleFilter(FieldKey.fromParts("InstrumentNickname"), form.getName()));
4856+
settings.setContainerFilterName(ContainerFilter.Type.AllFolders.name());
4857+
TargetedMSSchema schema = new TargetedMSSchema(getUser(), getContainer());
4858+
return schema.createView(getViewContext(), settings, errors);
4859+
}
4860+
if (UTILIZATION_BY_MONTH.equalsIgnoreCase(dataRegion))
4861+
{
4862+
QuerySettings settings = new QuerySettings(getViewContext(), UTILIZATION_BY_MONTH, "InstrumentUtilizationByMonth");
4863+
settings.setBaseSort(new Sort("-MonthStart"));
4864+
settings.setBaseFilter(new SimpleFilter(FieldKey.fromParts("InstrumentNickname"), form.getName()));
4865+
settings.setContainerFilterName(ContainerFilter.Type.AllFolders.name());
4866+
TargetedMSSchema schema = new TargetedMSSchema(getUser(), getContainer());
4867+
return schema.createView(getViewContext(), settings, errors);
4868+
}
48494869
throw new NotFoundException("Unknown dataRegion: " + dataRegion);
48504870
}
48514871

48524872
@Override
4853-
public ModelAndView getView(InstrumentForm form, BindException errors)
4873+
public ModelAndView getView(InstrumentForm form, BindException errors) throws Exception
48544874
{
48554875
if (form.getName() == null)
48564876
{
@@ -4876,6 +4896,21 @@ public ModelAndView getView(InstrumentForm form, BindException errors)
48764896
result.addView(nameView);
48774897
}
48784898

4899+
var calendarView = new JspView<>("/org/labkey/targetedms/view/instrumentUtilizationCalendar.jsp", form.getName());
4900+
calendarView.setTitle("Utilization Calendar");
4901+
calendarView.setFrame(WebPartView.FrameType.PORTAL);
4902+
result.addView(calendarView);
4903+
4904+
QueryView byDayView = createInitializedQueryView(form, errors, false, UTILIZATION_BY_DAY);
4905+
byDayView.setFrame(WebPartView.FrameType.NONE);
4906+
QueryView byMonthView = createInitializedQueryView(form, errors, false, UTILIZATION_BY_MONTH);
4907+
byMonthView.setFrame(WebPartView.FrameType.NONE);
4908+
4909+
var utilizationView = new JspView<>("/org/labkey/targetedms/view/instrumentUtilizationGrids.jsp", new InstrumentUtilizationBean(byDayView, byMonthView));
4910+
utilizationView.setTitle("Runs Acquired");
4911+
utilizationView.setFrame(WebPartView.FrameType.PORTAL);
4912+
result.addView(utilizationView);
4913+
48794914
QueryView folderSummaryView = createQueryView(form, errors, false, FOLDER_SUMMARY);
48804915
folderSummaryView.setTitle("Summary by Folder");
48814916
folderSummaryView.setFrame(WebPartView.FrameType.PORTAL);
@@ -4891,6 +4926,28 @@ public ModelAndView getView(InstrumentForm form, BindException errors)
48914926
}
48924927
}
48934928

4929+
public static class InstrumentUtilizationBean
4930+
{
4931+
private final QueryView _byDayView;
4932+
private final QueryView _byMonthView;
4933+
4934+
public InstrumentUtilizationBean(QueryView byDayView, QueryView byMonthView)
4935+
{
4936+
_byDayView = byDayView;
4937+
_byMonthView = byMonthView;
4938+
}
4939+
4940+
public QueryView getByDayView()
4941+
{
4942+
return _byDayView;
4943+
}
4944+
4945+
public QueryView getByMonthView()
4946+
{
4947+
return _byMonthView;
4948+
}
4949+
}
4950+
48944951
@RequiresPermission(ReadPermission.class)
48954952
public class ShowReplicatesAction extends ShowRunSingleDetailsAction<RunDetailsForm>
48964953
{

0 commit comments

Comments
 (0)