Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -11,39 +11,47 @@
* or submit itself to any jurisdiction.
*/
import { h, iconBan } from '/js/src/index.js';
import { formatDetectorQuality } from '../format/formatDetectorQuality.js';
import { getQcSummaryDisplay } from './getQcSummaryDisplay.js';
import { qcFlagOverviewPanelLink } from '../../../components/qcFlags/qcFlagOverviewPanelLink.js';
import { DetectorType } from '../../../domain/enums/DetectorTypes.js';

/**
* Factory for detectors related active columns for synchronous QC flags configuration
* Factory for detectors related active columns configuration displaying, in a single column per detector, both the detector's
* online quality and its synchronous QC flags summary, one under the other
*
* @param {Detector[]} detectors detectors list
* @param {object} [options] additional options
* @param {object|string|string[]} [options.profiles] profiles to which the column is restricted to
* @param {QcSummary} [options.qcSummary] QC summary of synchronous QC flags for given LHC period
* @return {object} active columns configuration
*/
export const runDetectorsSyncQcActiveColumns = (
export const runDetectorsQualitiesAndSyncQcActiveColumns = (
detectors,
{ profiles, qcSummary } = {},
) => Object.fromEntries(detectors?.map(({ name: detectorName, id: detectorId, type: detectorType }) => [
detectorName, {
name: detectorName.toUpperCase(),
visible: true,
format: (_, { runNumber, detectorsQualities }) => {
const detectorWasActiveDuringRun = Boolean(detectorsQualities.find(({ name }) => name === detectorName));
if (detectorType === DetectorType.PHYSICAL && !detectorWasActiveDuringRun) {
return null;
const detectorWasActiveDuringRun = detectorsQualities.find(({ name }) => name === detectorName);

const qualityDisplay = detectorWasActiveDuringRun
? formatDetectorQuality(detectorWasActiveDuringRun.quality)
: null;

let syncQcDisplay = null;
if (!(detectorType === DetectorType.PHYSICAL && !detectorWasActiveDuringRun)) {
const runDetectorSummary = qcSummary?.[runNumber]?.[detectorId];
syncQcDisplay = runDetectorSummary
? qcFlagOverviewPanelLink(
getQcSummaryDisplay({ ...runDetectorSummary, missingVerificationsCount: 0 }), // Ignore verifications
{ runNumber, dplDetectorId: detectorId },
)
: h('m2.badge.gray', iconBan());
}

const runDetectorSummary = qcSummary?.[runNumber]?.[detectorId];
return runDetectorSummary
? qcFlagOverviewPanelLink(
getQcSummaryDisplay({ ...runDetectorSummary, missingVerificationsCount: 0 }), // Ignore verifications
{ runNumber, dplDetectorId: detectorId },
)
: h('m2.badge.gray', iconBan());
return qualityDisplay || syncQcDisplay ? h('.flex-column.g1', [qualityDisplay, syncQcDisplay]) : null;
},
profiles,
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,12 @@
* or submit itself to any jurisdiction.
*/
import { buildUrl, RemoteData } from '/js/src/index.js';
import { TabbedPanelModel } from '../../../components/TabbedPanel/TabbedPanelModel.js';
import { rctDetectorsProvider } from '../../../services/detectors/detectorsProvider.js';
import { jsonFetch } from '../../../utilities/fetch/jsonFetch.js';
import { DetectorType } from '../../../domain/enums/DetectorTypes.js';
import { ObservableData } from '../../../utilities/ObservableData.js';
import { FixedPdpBeamTypeRunsOverviewModel } from '../Overview/FixedPdpBeamTypeRunsOverviewModel.js';

export const RUNS_PER_LHC_PERIOD_PANELS_KEYS = {
DETECTOR_QUALITIES: 'detectorQualities',
SYNCHRONOUS_FLAGS: 'synchronousFlags',
};

/**
* Runs Per LHC Period overview model
*/
Expand All @@ -39,8 +33,6 @@ export class RunsPerLhcPeriodOverviewModel extends FixedPdpBeamTypeRunsOverviewM
this._lhcPeriodId = null;
this._lhcPeriodStatistics$ = new ObservableData(RemoteData.notAsked());

this._onlineDetectors$ = rctDetectorsProvider.physical$;

this._syncDetectors$ = ObservableData
.builder()
.source(rctDetectorsProvider.qc$)
Expand All @@ -51,11 +43,7 @@ export class RunsPerLhcPeriodOverviewModel extends FixedPdpBeamTypeRunsOverviewM
.build();

this._syncDetectors$.bubbleTo(this);
this._onlineDetectors$.bubbleTo(this);
this._lhcPeriodStatistics$.bubbleTo(this);

this._tabbedPanelModel = new RunsPerLhcPeriodTabbedPanelModel(this._qcSummary$);
this._tabbedPanelModel.bubbleTo(this);
}

/**
Expand Down Expand Up @@ -107,15 +95,6 @@ export class RunsPerLhcPeriodOverviewModel extends FixedPdpBeamTypeRunsOverviewM
return this._lhcPeriodStatistics$.getCurrent();
}

/**
* Get all detectors
*
* @return {RemoteData<Detector[]>} detectors
*/
get onlineDetectors() {
return this._onlineDetectors$.getCurrent();
}

/**
* Get all detectors for synchronous QC flags
*
Expand All @@ -132,15 +111,6 @@ export class RunsPerLhcPeriodOverviewModel extends FixedPdpBeamTypeRunsOverviewM
return this._syncDetectors$.getCurrent();
}

/**
* Returns the model for the tabbed component
*
* @return {RunsPerLhcPeriodTabbedPanelModel} the tabbed component model
*/
get tabbedPanelModel() {
return this._tabbedPanelModel;
}

/**
* Set id of current LHC period which runs are fetched
*
Expand All @@ -160,15 +130,3 @@ export class RunsPerLhcPeriodOverviewModel extends FixedPdpBeamTypeRunsOverviewM
return { lhcPeriodId: this._lhcPeriodId };
}
}

/**
* RunsPerLhcPeriodTabbedPanelModel
*/
class RunsPerLhcPeriodTabbedPanelModel extends TabbedPanelModel {
/**
* Constructor
*/
constructor() {
super(Object.values(RUNS_PER_LHC_PERIOD_PANELS_KEYS));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,8 @@ import { table } from '../../../components/common/table/table.js';
import { paginationComponent } from '../../../components/Pagination/paginationComponent.js';
import { estimateDisplayableRowsCount } from '../../../utilities/estimateDisplayableRowsCount.js';
import { runsActiveColumns } from '../ActiveColumns/runsActiveColumns.js';
import { runDetectorsQualitiesActiveColumns } from '../ActiveColumns/runDetectorsQualitiesActiveColumns.js';
import { isRunNotSubjectToQc } from '../../../components/qcFlags/isRunNotSubjectToQc.js';
import { runDetectorsSyncQcActiveColumns } from '../ActiveColumns/runDetectorsSyncQcActiveColumns.js';
import { tabbedPanelComponent } from '../../../components/TabbedPanel/tabbedPanelComponent.js';
import { RUNS_PER_LHC_PERIOD_PANELS_KEYS } from './RunsPerLhcPeriodOverviewModel.js';
import { runDetectorsQualitiesAndSyncQcActiveColumns } from '../ActiveColumns/runDetectorsQualitiesAndSyncQcActiveColumns.js';
import { mergeRemoteData } from '../../../utilities/mergeRemoteData.js';
import errorAlert from '../../../components/common/errorAlert.js';
import spinner from '../../../components/common/spinner.js';
Expand Down Expand Up @@ -54,11 +51,9 @@ export const RunsPerLhcPeriodOverviewPage = ({ runs: { perLhcPeriodOverviewModel
const {
items: remoteRuns,
lhcPeriodStatistics: remoteLhcPeriodStatistics,
onlineDetectors: remoteOnlineDetectors,
syncDetectors: remoteSyncDetectors,
displayOptions,
sortModel,
tabbedPanelModel,
mcReproducibleAsNotBad,
qcSummary: remoteQcSummary,
pdpBeamTypes,
Expand All @@ -70,11 +65,11 @@ export const RunsPerLhcPeriodOverviewPage = ({ runs: { perLhcPeriodOverviewModel
/**
* Render runs table with given detectors' active columns configuration
*
* @param {object} activeColumns common acctivte column
* @param {object} detectorsActiveColumns detectors specific columns
* @param {object} activeColumns common active columns
* @param {object} detectorsColumns detectors specific columns, displaying quality and synchronous QC flags summary
* @return {Component} table with pagination
*/
const getTableWithGivenDetectorsColumns = (activeColumns, detectorsActiveColumns) =>
const getTableWithGivenDetectorsColumns = (activeColumns, detectorsColumns) =>
table(

/*
Expand All @@ -83,7 +78,7 @@ export const RunsPerLhcPeriodOverviewPage = ({ runs: { perLhcPeriodOverviewModel
remoteRuns,
{
...activeColumns,
...detectorsActiveColumns,
...detectorsColumns,
},
{ classes: getRowClasses },
{
Expand Down Expand Up @@ -114,45 +109,24 @@ export const RunsPerLhcPeriodOverviewPage = ({ runs: { perLhcPeriodOverviewModel
exportTriggerAndModal(perLhcPeriodOverviewModel.exportModel, modalModel),
]),
h(
'.intermediate-flex-column',
'.flex-column.w-100',
remoteRuns.match({
NotAsked: () => null,
Failure: (errors) => errorAlert(errors),
Loading: () => spinner(),
Success: () => [
...tabbedPanelComponent(
tabbedPanelModel,
{
[RUNS_PER_LHC_PERIOD_PANELS_KEYS.DETECTOR_QUALITIES]: 'Qualities of detectors',
[RUNS_PER_LHC_PERIOD_PANELS_KEYS.SYNCHRONOUS_FLAGS]: 'Synchronous QC flags',
},
{
[RUNS_PER_LHC_PERIOD_PANELS_KEYS.DETECTOR_QUALITIES]: () => remoteOnlineDetectors.match({
Success: (onlineDetectors) => getTableWithGivenDetectorsColumns(
activeColumns,
runDetectorsQualitiesActiveColumns(onlineDetectors, { profiles: 'runsPerLhcPeriod' }),
),
NotAsked: () => null,
Failure: (errors) => errorAlert(errors),
Loading: () => spinner(),
mergeRemoteData([remoteSyncDetectors, remoteQcSummary]).match({
Success: ([syncDetectors, synchronousQcSummary]) => getTableWithGivenDetectorsColumns(
activeColumns,
runDetectorsQualitiesAndSyncQcActiveColumns(syncDetectors, {
profiles: 'runsPerLhcPeriod',
qcSummary: synchronousQcSummary,
}),

[RUNS_PER_LHC_PERIOD_PANELS_KEYS.SYNCHRONOUS_FLAGS]: () =>
mergeRemoteData([remoteQcSummary, remoteSyncDetectors]).match({
Success: ([synchronousQcSummary, syncDetectors]) => getTableWithGivenDetectorsColumns(
activeColumns,
runDetectorsSyncQcActiveColumns(syncDetectors, {
profiles: 'runsPerLhcPeriod',
qcSummary: synchronousQcSummary,
}),
),
NotAsked: () => null,
Failure: (errors) => errorAlert(errors),
Loading: () => spinner(),
}),
},
{ panelClass: ['scroll-auto'] },
),
),
NotAsked: () => null,
Failure: (errors) => errorAlert(errors),
Loading: () => spinner(),
}),
paginationComponent(pagination),
] }),
),
Expand Down
4 changes: 1 addition & 3 deletions lib/public/views/Runs/RunsModel.js
Original file line number Diff line number Diff line change
Expand Up @@ -87,11 +87,9 @@ export class RunsModel extends Observable {
* Load runs overview data
* @param {object} params the parameters for the model
* @param {string} params.lhcPeriodId id of the LHC period to display
* @param {string} params.panel key of the panel to display
* @return {void}
*/
loadPerLhcPeriodOverview({ lhcPeriodId, panel }) {
this._perLhcPeriodOverviewModel.tabbedPanelModel.currentPanelKey = panel;
loadPerLhcPeriodOverview({ lhcPeriodId }) {
if (!this._perLhcPeriodOverviewModel.pagination.isInfiniteScrollEnabled) {
this._perLhcPeriodOverviewModel.lhcPeriodId = lhcPeriodId;
this._perLhcPeriodOverviewModel.setFilterFromURL(false);
Expand Down
5 changes: 2 additions & 3 deletions test/public/runs/navigationUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,10 @@ exports.navigateToRunsOverview = async (page) => {
* @param {number} expectedRowsCount expected number of rows on runs per data pass page
* @return {Promise<void>} promise
*/
exports.navigateToRunsPerLhcPeriod = async (page, lhcPeriodId, expectedRowsCount, tabPanel='detectorQualities') => {
exports.navigateToRunsPerLhcPeriod = async (page, lhcPeriodId, expectedRowsCount) => {
await waitForNavigation(page, () => pressElement(page, 'a#lhc-period-overview', true));
await waitForNavigation(page, () => pressElement(page, `#row${lhcPeriodId}-associatedRuns a`, true));
await pressElement(page, `#${tabPanel}-tab`, true);
expectUrlParams(page, { page: 'runs-per-lhc-period', lhcPeriodId, panel: tabPanel }, ['pdpBeamType']);
expectUrlParams(page, { page: 'runs-per-lhc-period', lhcPeriodId }, ['pdpBeamType']);
await waitForTableLength(page, expectedRowsCount);
};

Expand Down
29 changes: 10 additions & 19 deletions test/public/runs/runsPerLhcPeriod.overview.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -106,34 +106,25 @@ module.exports = () => {
inelasticInteractionRateAtEnd: (value) => value === '-' || !isNaN(Number(value.replace(/,/g, ''))),
};

// By default current tab is 'detectorsQualities'
const tableDataValidatorsWithDetectorQualities = {
...tableDataValidators,
...Object.fromEntries(DETECTORS.map((detectorName) => [detectorName, (quality) => expect(quality).oneOf([...RUN_QUALITIES, ''])])),
// Detector columns now combine, in a single cell, both the detector's quality and its synchronous QC flags summary
const combinedDetectorCellValidator = (cellText) => {
const lines = cellText.split('\n').map((line) => line.trim()).filter(Boolean);
return lines.length <= 2 && lines.every((line) => RUN_QUALITIES.includes(line) || !isNaN(Number(line)));
};

await waitForTableLength(page, 4);
await validateTableData(page, new Map(Object.entries(tableDataValidatorsWithDetectorQualities)));

await waitForNavigation(page, () => pressElement(page, '#synchronousFlags-tab'));

await page.waitForSelector('tbody tr:not(.loading-row)');

const tableDataValidatorsWithQualityFromSynchronousFlags = {
const tableDataValidatorsWithDetectorColumns = {
...tableDataValidators,
...Object.fromEntries(DETECTORS.map((detectorName) => [
detectorName,
(notBadDataFraction) => !notBadDataFraction || !isNaN(Number(notBadDataFraction)),
])),
...Object.fromEntries(DETECTORS.map((detectorName) => [detectorName, combinedDetectorCellValidator])),
};

await waitForTableLength(page, 4);
await validateTableData(page, new Map(Object.entries(tableDataValidatorsWithQualityFromSynchronousFlags)));
await expectInnerText(page, '#row56-FT0', '83');
await validateTableData(page, new Map(Object.entries(tableDataValidatorsWithDetectorColumns)));

const ft0CellText = await getInnerText(await page.waitForSelector('#row56-FT0'));
expect(ft0CellText).to.include('83');
});

it('should display detector columns in RCT order (AOT/MUON after physical) for synchronous flags', async () => {
// Note test starts already on synchronous flags tab
const headers = await page.$$eval(
'table thead th',
(ths) => ths.map((th) => th.id).filter(Boolean),
Expand Down
Loading