diff --git a/lib/database/adapters/DataPassAdapter.js b/lib/database/adapters/DataPassAdapter.js index d4ca53fd80..066d89c81b 100644 --- a/lib/database/adapters/DataPassAdapter.js +++ b/lib/database/adapters/DataPassAdapter.js @@ -40,14 +40,14 @@ class DataPassAdapter { const runsCount = databaseObject.get('runsCount'); const simulationPassesCount = databaseObject.get('simulationPassesCount'); - const pdpBeamType = databaseObject.get('pdpBeamType'); + const pdpBeamTypes = databaseObject.get('pdpBeamTypes')?.split(',') || []; return { id, name, skimmingStage, versions: (versions ?? []).map(this.dataPassVersionAdapter.toEntity), - pdpBeamType, + pdpBeamTypes, runsCount, simulationPassesCount, isFrozen, diff --git a/lib/database/adapters/LhcPeriodStatisticsAdapter.js b/lib/database/adapters/LhcPeriodStatisticsAdapter.js index 06982fd247..858b82175d 100644 --- a/lib/database/adapters/LhcPeriodStatisticsAdapter.js +++ b/lib/database/adapters/LhcPeriodStatisticsAdapter.js @@ -34,7 +34,7 @@ class LhcPeriodStatisticsAdapter { const runsCount = databaseObject.get('runsCount'); const distinctEnergies = databaseObject.get('distinctEnergies')?.split(',').map((energy) => parseFloat(energy)) || []; - const beamTypes = databaseObject.get('beamTypes')?.split(',') || []; + const pdpBeamTypes = databaseObject.get('pdpBeamTypes')?.split(',') || []; const dataPassesCount = databaseObject.get('dataPassesCount'); const simulationPassesCount = databaseObject.get('simulationPassesCount'); @@ -43,7 +43,7 @@ class LhcPeriodStatisticsAdapter { avgCenterOfMassEnergy, runsCount, distinctEnergies, - beamTypes, + pdpBeamTypes, dataPassesCount, simulationPassesCount, lhcPeriod: lhcPeriod ? this.lhcPeriodAdapter.toEntity(lhcPeriod) : null, diff --git a/lib/database/adapters/SimulationPassAdapter.js b/lib/database/adapters/SimulationPassAdapter.js index 214f850f55..f09fc185b4 100644 --- a/lib/database/adapters/SimulationPassAdapter.js +++ b/lib/database/adapters/SimulationPassAdapter.js @@ -42,6 +42,7 @@ class SimulationPassAdapter { const dataPassesCount = databaseObject.get('dataPassesCount'); const runsCount = databaseObject.get('runsCount'); + const pdpBeamTypes = databaseObject.get('pdpBeamTypes')?.split(',') || []; return { id, @@ -54,6 +55,7 @@ class SimulationPassAdapter { outputSize, runsCount, dataPassesCount, + pdpBeamTypes, }; } } diff --git a/lib/database/models/typedefs/SequelizeLhcPeriodStatistics.js b/lib/database/models/typedefs/SequelizeLhcPeriodStatistics.js index 1d172b0383..072e2811b0 100644 --- a/lib/database/models/typedefs/SequelizeLhcPeriodStatistics.js +++ b/lib/database/models/typedefs/SequelizeLhcPeriodStatistics.js @@ -17,7 +17,7 @@ * @property {number} id * @property {number|null} avgCenterOfMassEnergy * @property {number[]} distinctEnergies - * @property {string[]} beamTypes + * @property {string[]} pdpBeamTypes * @property {number} runsCount * @property {number} dataPassesCount * @property {number} simulationPassesCount diff --git a/lib/domain/entities/LhcPeriodStatistics.js b/lib/domain/entities/LhcPeriodStatistics.js index b45f13d843..40716c3365 100644 --- a/lib/domain/entities/LhcPeriodStatistics.js +++ b/lib/domain/entities/LhcPeriodStatistics.js @@ -17,7 +17,7 @@ * @property {number} id * @property {LhcPeriod} lhcPeriod * @property {number[]|null} distinctEnergies - * @property {string[]} beamTypes + * @property {string[]} pdpBeamTypes * @property {number} runsCount * @property {number} dataPassesCount * @property {number} simulationPassesCount diff --git a/lib/public/views/DataPasses/ActiveColumns/dataPassesActiveColumns.js b/lib/public/views/DataPasses/ActiveColumns/dataPassesActiveColumns.js index 9223123473..45d55bf6c6 100644 --- a/lib/public/views/DataPasses/ActiveColumns/dataPassesActiveColumns.js +++ b/lib/public/views/DataPasses/ActiveColumns/dataPassesActiveColumns.js @@ -46,13 +46,13 @@ export const dataPassesActiveColumns = { associatedRuns: { name: 'Runs', visible: true, - format: (_, { id, runsCount, pdpBeamType }) => + format: (_, { id, runsCount }) => runsCount === 0 ? 'No runs' : frontLink( badge(runsCount), 'runs-per-data-pass', - { dataPassId: id, pdpBeamType }, + { dataPassId: id }, ), classes: 'w-10', }, diff --git a/lib/public/views/QcFlags/QcFlagsModel.js b/lib/public/views/QcFlags/QcFlagsModel.js index 0d59bc4ec6..9cb026aa8a 100644 --- a/lib/public/views/QcFlags/QcFlagsModel.js +++ b/lib/public/views/QcFlags/QcFlagsModel.js @@ -95,9 +95,9 @@ export class QcFlagsModel extends Observable { /** * Load the creation for data pass page model * - * @param {Object} params - Parameters for the method - * @param {number} params.dataPassId - The data pass ID - * @param {string} [params.runNumberDetectorsMap] - String representation of run number to detector map + * @param {Object} parameters - Parameters for the method + * @param {number} parameters.dataPassId - The data pass ID + * @param {string} parameters.runNumberDetectorsMap - String representation of run number to detector map * @returns {void} */ loadCreationForDataPass({ dataPassId, runNumberDetectorsMap }) { @@ -190,7 +190,7 @@ export class QcFlagsModel extends Observable { * Load the creation for simulation pass page model * @param {object} parameters parameters for the model * @param {number} parameters.simulationPassId - The simulation pass ID - * @param {string} [parameters.runNumberDetectorsMap] - String representation of run number to detector map + * @param {string} parameters.runNumberDetectorsMap - String representation of run number to detector map * @returns {void} */ loadCreationForSimulationPass({ simulationPassId, runNumberDetectorsMap }) { diff --git a/lib/public/views/Runs/ActiveColumns/getInelasticInteractionRateActiveColumns.js b/lib/public/views/Runs/ActiveColumns/getInelasticInteractionRateActiveColumns.js new file mode 100644 index 0000000000..0f55ac0fb6 --- /dev/null +++ b/lib/public/views/Runs/ActiveColumns/getInelasticInteractionRateActiveColumns.js @@ -0,0 +1,27 @@ +/** + * @license + * Copyright CERN and copyright holders of ALICE O2. This software is + * distributed under the terms of the GNU General Public License v3 (GPL + * Version 3), copied verbatim in the file "COPYING". + * + * See http://alice-o2.web.cern.ch/license for full licensing information. + * + * In applying this license CERN does not waive the privileges and immunities + * granted to it by virtue of its status as an Intergovernmental Organization + * or submit itself to any jurisdiction. + */ + +import { PdpBeamType } from '../../../domain/enums/PdpBeamType.js'; +import { inelasticInteractionRateActiveColumnsForPbPb as inelForPbPb } from './inelasticInteractionRateActiveColumnsForPbPb.js'; +import { inelasticInteractionRateActiveColumnsForProtonProton as inelForPP } from './inelasticInteractionRateActiveColumnsForProtonProton.js'; + +/** + * Get appropriate runs' activate columns dependent on their pdp beam types + * + * @param {string[]} pdpBeamTypes lit of pdp beam types + * @return {ActiveColumn} active column + */ +export const getInelasticInteractionRateColumns = (pdpBeamTypes) => ({ + ...pdpBeamTypes?.includes(PdpBeamType.LEAD_LEAD) ? inelForPbPb : {}, + ...pdpBeamTypes?.includes(PdpBeamType.PROTON_PROTON) ? inelForPP : {}, +}); diff --git a/lib/public/views/Runs/Overview/FixedPdpBeamTypeRunsOverviewModel.js b/lib/public/views/Runs/Overview/FixedPdpBeamTypeRunsOverviewModel.js index 590f456d00..82eaf9e819 100644 --- a/lib/public/views/Runs/Overview/FixedPdpBeamTypeRunsOverviewModel.js +++ b/lib/public/views/Runs/Overview/FixedPdpBeamTypeRunsOverviewModel.js @@ -26,25 +26,26 @@ export class FixedPdpBeamTypeRunsOverviewModel extends RunsWithQcModel { */ constructor(model) { super(model); - - this._pdpBeamType = null; + this._pdpBeamTypes = []; } /** * Get pdp_beam_type of fetched runs * - * @return {string} beam type + * @return {string[]} beam type */ get pdpBeamTypes() { - return this._pdpBeamType; + return this._pdpBeamTypes; } /** * Set pdp_beam_type of fetched runs * - * @param {string} pdpBeamType beam type + * @param {string|string[]|null} pdpBeamTypes beam type, nullish values are ignored */ - set pdpBeamTypes(pdpBeamType) { - this._pdpBeamType = pdpBeamType; + setPdpBeamTypes(pdpBeamTypes) { + if (pdpBeamTypes) { + this._pdpBeamTypes = typeof pdpBeamTypes === 'string' ? pdpBeamTypes.split(',') : pdpBeamTypes; + } } } diff --git a/lib/public/views/Runs/RunPerDataPass/RunsPerDataPassOverviewModel.js b/lib/public/views/Runs/RunPerDataPass/RunsPerDataPassOverviewModel.js index fcf6ed2e01..5a9ff0bdd1 100644 --- a/lib/public/views/Runs/RunPerDataPass/RunsPerDataPassOverviewModel.js +++ b/lib/public/views/Runs/RunPerDataPass/RunsPerDataPassOverviewModel.js @@ -122,11 +122,16 @@ export class RunsPerDataPassOverviewModel extends FixedPdpBeamTypeRunsOverviewMo this._fetchQcSummary(); this._fetchGaqSummary(); - await this._fetchDataPass(); - this._dataPass$.getCurrent().match({ - Success: ({ skimmingStage }) => skimmingStage === SkimmingStage.SKIMMABLE && this._fetchSkimmableRuns(), - Other: () => null, - }); + await this._fetchDataPass().then(() => + this._dataPass$.getCurrent().match({ + Success: ({ skimmingStage, pdpBeamTypes }) => { + if (skimmingStage === SkimmingStage.SKIMMABLE) { + this._fetchSkimmableRuns(); + } + this.setPdpBeamTypes(pdpBeamTypes); + }, + Other: () => null, + })); super.load(); } diff --git a/lib/public/views/Runs/RunPerDataPass/RunsPerDataPassOverviewPage.js b/lib/public/views/Runs/RunPerDataPass/RunsPerDataPassOverviewPage.js index 99916d46ed..02c6a08070 100644 --- a/lib/public/views/Runs/RunPerDataPass/RunsPerDataPassOverviewPage.js +++ b/lib/public/views/Runs/RunPerDataPass/RunsPerDataPassOverviewPage.js @@ -11,7 +11,7 @@ * or submit itself to any jurisdiction. */ -import { DropdownComponent, h, iconWarning, sessionService, switchCase } from '/js/src/index.js'; +import { DropdownComponent, h, iconWarning, sessionService } from '/js/src/index.js'; import { table } from '../../../components/common/table/table.js'; import { paginationComponent } from '../../../components/Pagination/paginationComponent.js'; import { estimateDisplayableRowsCount } from '../../../utilities/estimateDisplayableRowsCount.js'; @@ -20,8 +20,6 @@ import spinner from '../../../components/common/spinner.js'; import { tooltip } from '../../../components/common/popover/tooltip.js'; import { breadcrumbs } from '../../../components/common/navigation/breadcrumbs.js'; import { createRunDetectorsAsyncQcActiveColumns } from '../ActiveColumns/runDetectorsAsyncQcActiveColumns.js'; -import { inelasticInteractionRateActiveColumnsForPbPb } from '../ActiveColumns/inelasticInteractionRateActiveColumnsForPbPb.js'; -import { inelasticInteractionRateActiveColumnsForProtonProton } from '../ActiveColumns/inelasticInteractionRateActiveColumnsForProtonProton.js'; import { filtersPanelPopover } from '../../../components/Filters/common/filtersPanelPopover.js'; import { runNumbersFilter } from '../../../components/Filters/RunsFilter/runNumbersFilter.js'; import { qcSummaryLegendTooltip } from '../../../components/qcFlags/qcSummaryLegendTooltip.js'; @@ -38,6 +36,7 @@ import { mergeRemoteData } from '../../../utilities/mergeRemoteData.js'; import { numericalComparisonFilter } from '../../../components/Filters/common/filters/numericalComparisonFilter.js'; import { iconCaretBottom } from '/js/src/icons.js'; import { BkpRoles } from '../../../domain/enums/BkpRoles.js'; +import { getInelasticInteractionRateColumns } from '../ActiveColumns/getInelasticInteractionRateActiveColumns.js'; import { exportTriggerAndModal } from '../../../components/common/dataExport/exportTriggerAndModal.js'; import { mcReproducibleAsNotBadToggle } from '../mcReproducibleAsNotBadToggle.js'; @@ -63,14 +62,14 @@ const getRowClasses = (run) => isRunNotSubjectToQc(run) ? '.danger' : null; * @return {Component|null} badge or button */ const skimmableControl = (dataPass, onclick, requestResult) => { - const { name, pdpBeamType, skimmingStage } = dataPass; + const { name, pdpBeamTypes, skimmingStage } = dataPass; const skimmableIndicator = badge('Skimmable', { color: Color.SUCCESS }); if (skimmingStage === SkimmingStage.SKIMMABLE) { return skimmableIndicator; } const validSkimmableProductionNameRegex = /_apass\d+(?!.*(skimming|skimmed|debug|test))/; - if (validSkimmableProductionNameRegex.test(name) && pdpBeamType === PdpBeamType.PROTON_PROTON) { + if (validSkimmableProductionNameRegex.test(name) && pdpBeamTypes.includes(PdpBeamType.PROTON_PROTON)) { const buttonContent = 'Mark as skimmable'; return requestResult.match({ Success: () => skimmableIndicator, @@ -109,7 +108,7 @@ export const RunsPerDataPassOverviewPage = ({ dataPassId, sortModel, mcReproducibleAsNotBad, - pdpBeamType, + pdpBeamTypes, markAsSkimmableRequestResult, skimmableRuns: remoteSkimmableRuns, freezeOrUnfreezeActionState, @@ -128,17 +127,7 @@ export const RunsPerDataPassOverviewPage = ({ Success: ([dataPass, runs, detectors, qcSummary, gaqSummary]) => { const activeColumns = { ...runsActiveColumns, - ...switchCase( - pdpBeamType, - { - [PdpBeamType.PROTON_PROTON]: inelasticInteractionRateActiveColumnsForProtonProton, - [PdpBeamType.LEAD_LEAD]: inelasticInteractionRateActiveColumnsForPbPb, - }, - { - ...inelasticInteractionRateActiveColumnsForProtonProton, - ...inelasticInteractionRateActiveColumnsForPbPb, - }, - ), + ...getInelasticInteractionRateColumns(pdpBeamTypes), ...dataPass.skimmingStage === SkimmingStage.SKIMMABLE ? { readyForSkimming: { diff --git a/lib/public/views/Runs/RunPerPeriod/RunsPerLhcPeriodOverviewModel.js b/lib/public/views/Runs/RunPerPeriod/RunsPerLhcPeriodOverviewModel.js index dbd1bc8c3b..dccecc821a 100644 --- a/lib/public/views/Runs/RunPerPeriod/RunsPerLhcPeriodOverviewModel.js +++ b/lib/public/views/Runs/RunPerPeriod/RunsPerLhcPeriodOverviewModel.js @@ -13,10 +13,10 @@ import { buildUrl, RemoteData } from '/js/src/index.js'; import { TabbedPanelModel } from '../../../components/TabbedPanel/TabbedPanelModel.js'; import { detectorsProvider } from '../../../services/detectors/detectorsProvider.js'; -import { RunsWithQcModel } from '../Overview/RunsWithQcModel.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', @@ -26,7 +26,7 @@ export const RUNS_PER_LHC_PERIOD_PANELS_KEYS = { /** * Runs Per LHC Period overview model */ -export class RunsPerLhcPeriodOverviewModel extends RunsWithQcModel { +export class RunsPerLhcPeriodOverviewModel extends FixedPdpBeamTypeRunsOverviewModel { /** * Constructor * @@ -78,7 +78,12 @@ export class RunsPerLhcPeriodOverviewModel extends RunsWithQcModel { return; } - await this._fetchLhcPeriod(); + await this._fetchLhcPeriod().then(() => { + this._lhcPeriodStatistics$.getCurrent().match({ + Success: ({ pdpBeamTypes }) => this.setPdpBeamTypes(pdpBeamTypes), + Other: () => null, + }); + }); super.load(); } diff --git a/lib/public/views/Runs/RunPerPeriod/RunsPerLhcPeriodOverviewPage.js b/lib/public/views/Runs/RunPerPeriod/RunsPerLhcPeriodOverviewPage.js index 0ecc55ef65..70d97485be 100644 --- a/lib/public/views/Runs/RunPerPeriod/RunsPerLhcPeriodOverviewPage.js +++ b/lib/public/views/Runs/RunPerPeriod/RunsPerLhcPeriodOverviewPage.js @@ -17,18 +17,16 @@ import { paginationComponent } from '../../../components/Pagination/paginationCo import { estimateDisplayableRowsCount } from '../../../utilities/estimateDisplayableRowsCount.js'; import { runsActiveColumns } from '../ActiveColumns/runsActiveColumns.js'; import { runDetectorsQualitiesActiveColumns } from '../ActiveColumns/runDetectorsQualitiesActiveColumns.js'; -import { inelasticInteractionRateActiveColumnsForProtonProton } from '../ActiveColumns/inelasticInteractionRateActiveColumnsForProtonProton.js'; -import { inelasticInteractionRateActiveColumnsForPbPb } from '../ActiveColumns/inelasticInteractionRateActiveColumnsForPbPb.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 { PdpBeamType } from '../../../domain/enums/PdpBeamType.js'; -import { filtersPanelPopover } from '../../../components/Filters/common/filtersPanelPopover.js'; -import { runNumbersFilter } from '../../../components/Filters/RunsFilter/runNumbersFilter.js'; import { mergeRemoteData } from '../../../utilities/mergeRemoteData.js'; import errorAlert from '../../../components/common/errorAlert.js'; import spinner from '../../../components/common/spinner.js'; +import { getInelasticInteractionRateColumns } from '../ActiveColumns/getInelasticInteractionRateActiveColumns.js'; +import { filtersPanelPopover } from '../../../components/Filters/common/filtersPanelPopover.js'; +import { runNumbersFilter } from '../../../components/Filters/RunsFilter/runNumbersFilter.js'; import { mcReproducibleAsNotBadToggle } from '../mcReproducibleAsNotBadToggle.js'; import { exportTriggerAndModal } from '../../../components/common/dataExport/exportTriggerAndModal.js'; @@ -66,6 +64,7 @@ export const RunsPerLhcPeriodOverviewPage = ({ runs: { perLhcPeriodOverviewModel sortModel, tabbedPanelModel, mcReproducibleAsNotBad, + pdpBeamTypes, } = perLhcPeriodOverviewModel; /** @@ -102,12 +101,11 @@ export const RunsPerLhcPeriodOverviewPage = ({ runs: { perLhcPeriodOverviewModel NotAsked: () => null, Failure: (errors) => errorAlert(errors), Loading: () => spinner(), - Success: ([lhcPeriodStatistics, runs]) => { + Success: ([lhcPeriodStatistics]) => { const activeColumns = { ...runsActiveColumns, - ...runs.some((run) => run.pdpBeamType === PdpBeamType.LEAD_LEAD) ? inelasticInteractionRateActiveColumnsForPbPb : {}, - ...runs.some((run) => run.pdpBeamType === PdpBeamType.PROTON_PROTON) - ? inelasticInteractionRateActiveColumnsForProtonProton : {}, + ...getInelasticInteractionRateColumns(pdpBeamTypes), + }; return [ diff --git a/lib/public/views/Runs/RunsModel.js b/lib/public/views/Runs/RunsModel.js index 8298ee2857..ba30c3519a 100644 --- a/lib/public/views/Runs/RunsModel.js +++ b/lib/public/views/Runs/RunsModel.js @@ -85,8 +85,8 @@ export class RunsModel extends Observable { /** * Load runs overview data * @param {object} params the parameters for the model - * @param {string} [params.lhcPeriodId] the id of the LHC period to display - * @param {string} [params.panel] the key of the panel to display + * @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 }) { @@ -108,14 +108,12 @@ export class RunsModel extends Observable { /** * Load runs overview data * @param {object} params the parameters for the model - * @param {string} [params.dataPassId] the id of the data pass to display - * @param {string} [params.pdpBeamType] the beam type of the data pass to display + * @param {string} params.dataPassId the id of the data pass to display * @return {void} */ - loadPerDataPassOverview({ dataPassId, pdpBeamType }) { + loadPerDataPassOverview({ dataPassId }) { if (!this._perDataPassOverviewModel.pagination.isInfiniteScrollEnabled) { this._perDataPassOverviewModel.dataPassId = parseInt(dataPassId, 10); - this._perDataPassOverviewModel.pdpBeamType = pdpBeamType; this._perDataPassOverviewModel.load(); } } @@ -130,8 +128,8 @@ export class RunsModel extends Observable { /** * Load runs overview per simulation pass data - * @param {object} root0 - The parameters for the model. - * @param {string} root0.simulationPassId - The ID of the simulation pass to load. + * @param {object} params - The parameters for the model. + * @param {string} params.simulationPassId - The ID of the simulation pass to load. * @return {void} */ loadPerSimulationPassOverview({ simulationPassId }) { diff --git a/lib/public/views/Runs/RunsPerSimulationPass/RunsPerSimulationPassOverviewModel.js b/lib/public/views/Runs/RunsPerSimulationPass/RunsPerSimulationPassOverviewModel.js index 1ac4463884..a82281e476 100644 --- a/lib/public/views/Runs/RunsPerSimulationPass/RunsPerSimulationPassOverviewModel.js +++ b/lib/public/views/Runs/RunsPerSimulationPass/RunsPerSimulationPassOverviewModel.js @@ -11,15 +11,15 @@ * or submit itself to any jurisdiction. */ import { buildUrl, RemoteData } from '/js/src/index.js'; -import { RunsWithQcModel } from '../Overview/RunsWithQcModel.js'; import { ObservableData } from '../../../utilities/ObservableData.js'; import { getRemoteData } from '../../../utilities/fetch/getRemoteData.js'; import { detectorsProvider } from '../../../services/detectors/detectorsProvider.js'; +import { FixedPdpBeamTypeRunsOverviewModel } from '../Overview/FixedPdpBeamTypeRunsOverviewModel.js'; /** * Runs Per Simulation Pass overview model */ -export class RunsPerSimulationPassOverviewModel extends RunsWithQcModel { +export class RunsPerSimulationPassOverviewModel extends FixedPdpBeamTypeRunsOverviewModel { /** * Constructor * @param {Model} model global model @@ -74,7 +74,12 @@ export class RunsPerSimulationPassOverviewModel extends RunsWithQcModel { */ async load() { this._fetchQcSummary(); - this._fetchSimulationPass(); + this._fetchSimulationPass().then(() => { + this._simulationPass$.getCurrent().match({ + Success: ({ pdpBeamTypes }) => this.setPdpBeamTypes(pdpBeamTypes), + Other: () => null, + }); + }); super.load(); } diff --git a/lib/public/views/Runs/RunsPerSimulationPass/RunsPerSimulationPassOverviewPage.js b/lib/public/views/Runs/RunsPerSimulationPass/RunsPerSimulationPassOverviewPage.js index b782137187..630874cf54 100644 --- a/lib/public/views/Runs/RunsPerSimulationPass/RunsPerSimulationPassOverviewPage.js +++ b/lib/public/views/Runs/RunsPerSimulationPass/RunsPerSimulationPassOverviewPage.js @@ -19,14 +19,12 @@ import { runsActiveColumns } from '../ActiveColumns/runsActiveColumns.js'; import { breadcrumbs } from '../../../components/common/navigation/breadcrumbs.js'; import spinner from '../../../components/common/spinner.js'; import { createRunDetectorsAsyncQcActiveColumns } from '../ActiveColumns/runDetectorsAsyncQcActiveColumns.js'; -import { inelasticInteractionRateActiveColumnsForPbPb } from '../ActiveColumns/inelasticInteractionRateActiveColumnsForPbPb.js'; -import { inelasticInteractionRateActiveColumnsForProtonProton } from '../ActiveColumns/inelasticInteractionRateActiveColumnsForProtonProton.js'; import { qcSummaryLegendTooltip } from '../../../components/qcFlags/qcSummaryLegendTooltip.js'; import { isRunNotSubjectToQc } from '../../../components/qcFlags/isRunNotSubjectToQc.js'; -import { PdpBeamType } from '../../../domain/enums/PdpBeamType.js'; import { frontLink } from '../../../components/common/navigation/frontLink.js'; import { mergeRemoteData } from '../../../utilities/mergeRemoteData.js'; import errorAlert from '../../../components/common/errorAlert.js'; +import { getInelasticInteractionRateColumns } from '../ActiveColumns/getInelasticInteractionRateActiveColumns.js'; import { exportTriggerAndModal } from '../../../components/common/dataExport/exportTriggerAndModal.js'; import { filtersPanelPopover } from '../../../components/Filters/common/filtersPanelPopover.js'; import { runNumbersFilter } from '../../../components/Filters/RunsFilter/runNumbersFilter.js'; @@ -67,6 +65,7 @@ export const RunsPerSimulationPassOverviewPage = ({ qcSummary: remoteQcSummary, displayOptions, sortModel, + pdpBeamTypes, mcReproducibleAsNotBad, } = perSimulationPassOverviewModel; @@ -81,9 +80,7 @@ export const RunsPerSimulationPassOverviewPage = ({ Success: ([simulationPass, runs, detectors, qcSummary]) => { const activeColumns = { ...runsActiveColumns, - ...runs.some((run) => run.pdpBeamType === PdpBeamType.LEAD_LEAD) ? inelasticInteractionRateActiveColumnsForPbPb : {}, - ...runs.some((run) => run.pdpBeamType === PdpBeamType.PROTON_PROTON) - ? inelasticInteractionRateActiveColumnsForProtonProton : {}, + ...getInelasticInteractionRateColumns(pdpBeamTypes), ...createRunDetectorsAsyncQcActiveColumns( perSimulationPassOverviewModel.runDetectorsSelectionModel, detectors, diff --git a/lib/public/views/lhcPeriods/ActiveColumns/lhcPeriodsActiveColumns.js b/lib/public/views/lhcPeriods/ActiveColumns/lhcPeriodsActiveColumns.js index 8d1eeeb19a..e88c97053a 100644 --- a/lib/public/views/lhcPeriods/ActiveColumns/lhcPeriodsActiveColumns.js +++ b/lib/public/views/lhcPeriods/ActiveColumns/lhcPeriodsActiveColumns.js @@ -99,13 +99,13 @@ export const lhcPeriodsActiveColumns = { classes: 'w-7', }, - beamTypes: { + pdpBeamTypes: { name: 'Beam Type', visible: true, sortable: true, - format: (beamTypes) => beamTypes.length > 0 ? beamTypes.join(',') : '-', - filter: ({ beamTypesFilterModel }) => textFilter( - beamTypesFilterModel, + format: (pdpBeamTypes) => pdpBeamTypes.length > 0 ? pdpBeamTypes.join(',') : '-', + filter: ({ pdpBeamTypesFilterModel }) => textFilter( + pdpBeamTypesFilterModel, { class: 'w-75 mt1', placeholder: 'e.g. pp, PbPb' }, ), classes: 'w-7', diff --git a/lib/public/views/lhcPeriods/Overview/LhcPeriodsOverviewModel.js b/lib/public/views/lhcPeriods/Overview/LhcPeriodsOverviewModel.js index f26d52bac2..eb2d5e48cd 100644 --- a/lib/public/views/lhcPeriods/Overview/LhcPeriodsOverviewModel.js +++ b/lib/public/views/lhcPeriods/Overview/LhcPeriodsOverviewModel.js @@ -31,8 +31,8 @@ export class LhcPeriodsOverviewModel extends OverviewPageModel { this._registerFilter(this._namesFilterModel); this._yearsFilterModel = new TextTokensFilterModel(); this._registerFilter(this._yearsFilterModel); - this._beamTypesFilterModel = new TextTokensFilterModel(); - this._registerFilter(this._beamTypesFilterModel); + this._pdpBeamTypesFilterModel = new TextTokensFilterModel(); + this._registerFilter(this._pdpBeamTypesFilterModel); } /** @@ -43,7 +43,7 @@ export class LhcPeriodsOverviewModel extends OverviewPageModel { filter: { names: this._namesFilterModel.normalized, years: this._yearsFilterModel.normalized, - beamTypes: this._beamTypesFilterModel.normalized, + pdpBeamTypes: this._pdpBeamTypesFilterModel.normalized, }, }; @@ -86,8 +86,8 @@ export class LhcPeriodsOverviewModel extends OverviewPageModel { * Returns lhc periods beam type filter model * @return {TextTokensFilterModel} lhc periods beam type filter model */ - get beamTypesFilterModel() { - return this._beamTypesFilterModel; + get pdpBeamTypesFilterModel() { + return this._pdpBeamTypesFilterModel; } /** @@ -99,7 +99,7 @@ export class LhcPeriodsOverviewModel extends OverviewPageModel { super.reset(); this._namesFilterModel.reset(); this._yearsFilterModel.reset(); - this._beamTypesFilterModel.reset(); + this._pdpBeamTypesFilterModel.reset(); } /** @@ -121,6 +121,6 @@ export class LhcPeriodsOverviewModel extends OverviewPageModel { * @return {boolean} true if any filter is active */ isAnyFilterActive() { - return !this._namesFilterModel.isEmpty || !this._yearsFilterModel.isEmpty || !this._beamTypesFilterModel.isEmpty; + return !this._namesFilterModel.isEmpty || !this._yearsFilterModel.isEmpty || !this._pdpBeamTypesFilterModel.isEmpty; } } diff --git a/lib/server/controllers/lhcPeriodStatistics.controller.js b/lib/server/controllers/lhcPeriodStatistics.controller.js index 229ecebf44..c70b04b67c 100644 --- a/lib/server/controllers/lhcPeriodStatistics.controller.js +++ b/lib/server/controllers/lhcPeriodStatistics.controller.js @@ -32,10 +32,10 @@ const listLhcPeriodStatisticsHandler = async (req, res) => { ids: Joi.array().items(Joi.number()), names: Joi.array().items(Joi.string()), years: Joi.array().items(Joi.number()), - beamTypes: Joi.array().items(Joi.string()), + pdpBeamTypes: Joi.array().items(Joi.string()), }, page: PaginationDto, - sort: DtoFactory.order(['id', 'name', 'avgCenterOfMassEnergy', 'year', 'beamTypes']), + sort: DtoFactory.order(['id', 'name', 'avgCenterOfMassEnergy', 'year', 'pdpBeamTypes']), }), req, res, diff --git a/lib/server/services/dataPasses/DataPassService.js b/lib/server/services/dataPasses/DataPassService.js index 6d37b459cf..617aa9c7e4 100644 --- a/lib/server/services/dataPasses/DataPassService.js +++ b/lib/server/services/dataPasses/DataPassService.js @@ -190,7 +190,7 @@ class DataPassService { return dataSource.transaction(async () => { const dataPass = await this.getOneOrFail(identifier); - if (dataPass.pdpBeamType !== PdpBeamType.PROTON_PROTON) { + if (!dataPass.pdpBeamTypes.includes(PdpBeamType.PROTON_PROTON)) { throw new BadParameterError(`Cannot mark ${dataPass.name} as skimmable.` + ' Only production for PROTON_PROTON runs can be marked as skimmable'); } @@ -273,7 +273,7 @@ class DataPassService { }) .includeAttribute({ query: (sequelize) => sequelize.fn('GROUP_CONCAT', sequelize.fn('DISTINCT', sequelize.col('runs.pdp_beam_type'))), - alias: 'pdpBeamType', + alias: 'pdpBeamTypes', }) .include({ association: 'runs', diff --git a/lib/server/services/lhcPeriod/LhcPeriodStatisticsService.js b/lib/server/services/lhcPeriod/LhcPeriodStatisticsService.js index 0803fd1b89..4e92ae675e 100644 --- a/lib/server/services/lhcPeriod/LhcPeriodStatisticsService.js +++ b/lib/server/services/lhcPeriod/LhcPeriodStatisticsService.js @@ -96,8 +96,8 @@ class LhcPeriodStatisticsService { case 'year': expression = (sequelize) => sequelize.literal('SUBSTRING(lhcPeriod.name, 4, 2)'); break; - case 'beamTypes': - expression = (sequelize) => sequelize.literal('beamTypes'); + case 'pdpBeamTypes': + expression = (sequelize) => sequelize.literal('pdpBeamTypes'); break; } @@ -113,7 +113,7 @@ class LhcPeriodStatisticsService { } if (filter) { - const { ids, names, years, beamTypes } = filter; + const { ids, names, years, pdpBeamTypes } = filter; if (ids) { queryBuilder.where('id').oneOf(...ids); } @@ -126,7 +126,7 @@ class LhcPeriodStatisticsService { { years }, ); } - if (beamTypes) { + if (pdpBeamTypes) { const targetIds = (await LhcPeriodStatisticsRepository.findAll({ raw: true, include: { @@ -136,7 +136,7 @@ class LhcPeriodStatisticsService { association: 'runs', required: true, where: { - pdpBeamType: { [Op.in]: beamTypes }, + pdpBeamType: { [Op.in]: pdpBeamTypes }, definition: RunDefinition.PHYSICS, runQuality: RunQualities.GOOD, }, @@ -183,7 +183,7 @@ class LhcPeriodStatisticsService { }) .includeAttribute({ query: (sequelize) => sequelize.fn('GROUP_CONCAT', sequelize.fn('DISTINCT', sequelize.col('lhcPeriod->runs.pdp_beam_type'))), - alias: 'beamTypes', + alias: 'pdpBeamTypes', }) .include({ association: 'lhcPeriod', diff --git a/lib/server/services/simulationPasses/SimulationPassService.js b/lib/server/services/simulationPasses/SimulationPassService.js index ef4d410ee7..957a7ff3a5 100644 --- a/lib/server/services/simulationPasses/SimulationPassService.js +++ b/lib/server/services/simulationPasses/SimulationPassService.js @@ -140,6 +140,10 @@ class SimulationPassService { query: (sequelize) => sequelize.fn('count', sequelize.fn('distinct', sequelize.col('dataPasses.id'))), alias: 'dataPassesCount', }) + .includeAttribute({ + query: (sequelize) => sequelize.fn('GROUP_CONCAT', sequelize.fn('DISTINCT', sequelize.col('runs.pdp_beam_type'))), + alias: 'pdpBeamTypes', + }) .include({ association: 'runs', through: { attributes: [] }, diff --git a/test/api/dataPasses.test.js b/test/api/dataPasses.test.js index 9153bbcb5e..3ce5947435 100644 --- a/test/api/dataPasses.test.js +++ b/test/api/dataPasses.test.js @@ -25,7 +25,7 @@ const { BkpRoles } = require('../../lib/domain/enums/BkpRoles.js'); const LHC22b_apass1 = { id: 1, name: 'LHC22b_apass1', - pdpBeamType: 'pp', + pdpBeamTypes: ['pp'], skimmingStage: SkimmingStage.SKIMMABLE, isFrozen: false, versions: [ diff --git a/test/api/index.js b/test/api/index.js index c318e90e2a..e368ca5e61 100644 --- a/test/api/index.js +++ b/test/api/index.js @@ -56,7 +56,7 @@ module.exports = () => { describe('Tags API', TagsSuite); describe('LhcPeriodsStatistics API', LhcPeriodsStatisticsSuite); describe('DataPasses API', DataPassesSuite); - describe('SimulationPassesSuite API', SimulationPassesSuite); + describe('SimulationPasses API', SimulationPassesSuite); describe('DplDetectors API', DplDetectorsSuite); describe('QcFlagTypes API', QcFlagTypesSuite); describe('QcFlags API', QcFlagsSuite); diff --git a/test/api/lhcPeriodsStatistics.test.js b/test/api/lhcPeriodsStatistics.test.js index 54ffbdcb51..8b3a78c2d4 100644 --- a/test/api/lhcPeriodsStatistics.test.js +++ b/test/api/lhcPeriodsStatistics.test.js @@ -23,7 +23,7 @@ const lhcPeriod_LHC22a = { id: 1, name: 'LHC22a', }, - beamTypes: ['PbPb'], + pdpBeamTypes: ['PbPb'], distinctEnergies: [ 23.21, 56.1, @@ -40,7 +40,7 @@ const lhcPeriod_LHC22b = { id: 2, name: 'LHC22b', }, - beamTypes: ['pp'], + pdpBeamTypes: ['pp'], distinctEnergies: [55.2], runsCount: 4, dataPassesCount: 3, @@ -54,7 +54,7 @@ const lhcPeriod_LHC23f = { id: 3, name: 'LHC23f', }, - beamTypes: ['OO'], + pdpBeamTypes: ['OO'], distinctEnergies: [], dataPassesCount: 1, runsCount: 1, @@ -186,9 +186,9 @@ module.exports = () => { done(); }); }); - it('should successfully filter on beamTypes', (done) => { + it('should successfully filter on pdpBeamTypes', (done) => { request(server) - .get('/api/lhcPeriodsStatistics?filter[beamTypes][]=pp') + .get('/api/lhcPeriodsStatistics?filter[pdpBeamTypes][]=pp') .expect(200) .end((err, res) => { if (err) { @@ -244,9 +244,9 @@ module.exports = () => { done(); }); }); - it('should successfully sort on beamTypes', (done) => { + it('should successfully sort on pdpBeamTypes', (done) => { request(server) - .get('/api/lhcPeriodsStatistics?sort[beamTypes]=DESC') + .get('/api/lhcPeriodsStatistics?sort[pdpBeamTypes]=DESC') .expect(200) .end((err, res) => { if (err) { diff --git a/test/api/simulationPasses.test.js b/test/api/simulationPasses.test.js index 56dab799a2..c4c154b212 100644 --- a/test/api/simulationPasses.test.js +++ b/test/api/simulationPasses.test.js @@ -20,6 +20,7 @@ const LHC23k6c = { id: 1, name: 'LHC23k6c', jiraId: 'SIMTICKET-1', + pdpBeamTypes: ['PbPb', 'pp'], description: 'Some Random general purpose for LHC23k6c', pwg: 'PWGX2', requestedEventsCount: 1345555, @@ -33,6 +34,7 @@ const LHC23k6b = { id: 2, name: 'LHC23k6b', jiraId: 'SIMTICKET-2', + pdpBeamTypes: ['PbPb'], description: 'Some Random general purpose for LHC23k6b', pwg: 'PWGX1', requestedEventsCount: 2345555, @@ -46,6 +48,7 @@ const LHC23k6a = { id: 3, name: 'LHC23k6a', jiraId: 'SIMTICKET-3', + pdpBeamTypes: ['PbPb'], description: 'Some Random general purpose for LHC23k6a', pwg: 'PWGX3', requestedEventsCount: 2245555, diff --git a/test/lib/server/services/dataPasses/DataPassService.test.js b/test/lib/server/services/dataPasses/DataPassService.test.js index 40fecc4d70..733469aa2b 100644 --- a/test/lib/server/services/dataPasses/DataPassService.test.js +++ b/test/lib/server/services/dataPasses/DataPassService.test.js @@ -26,7 +26,7 @@ const { Op } = require('sequelize'); const LHC22b_apass1 = { id: 1, name: 'LHC22b_apass1', - pdpBeamType: 'pp', + pdpBeamTypes: ['pp'], skimmingStage: SkimmingStage.SKIMMABLE, isFrozen: false, versions: [ diff --git a/test/lib/server/services/lhcPeriod/LhcPeriodStatisticsService.test.js b/test/lib/server/services/lhcPeriod/LhcPeriodStatisticsService.test.js index c1f8473f35..4e96f810aa 100644 --- a/test/lib/server/services/lhcPeriod/LhcPeriodStatisticsService.test.js +++ b/test/lib/server/services/lhcPeriod/LhcPeriodStatisticsService.test.js @@ -24,7 +24,7 @@ const lhcPeriod_LHC22a = { id: 1, name: 'LHC22a', }, - beamTypes: ['PbPb'], + pdpBeamTypes: ['PbPb'], distinctEnergies: [ 23.21, 56.1, @@ -41,7 +41,7 @@ const lhcPeriod_LHC22b = { id: 2, name: 'LHC22b', }, - beamTypes: ['pp'], + pdpBeamTypes: ['pp'], distinctEnergies: [55.2], runsCount: 4, dataPassesCount: 3, @@ -55,7 +55,7 @@ const lhcPeriod_LHC23f = { id: 3, name: 'LHC23f', }, - beamTypes: ['OO'], + pdpBeamTypes: ['OO'], distinctEnergies: [], dataPassesCount: 1, runsCount: 1, @@ -155,11 +155,11 @@ module.exports = () => { expect(lhcPeriods[2]).to.be.eql(lhcPeriod_LHC23f); }); - it('should successfully filter period statistics on beamTypes', async () => { + it('should successfully filter period statistics on pdpBeamTypes', async () => { const dto = { query: { filter: { - beamTypes: ['pp'], + pdpBeamTypes: ['pp'], }, }, }; @@ -168,11 +168,11 @@ module.exports = () => { expect(lhcPeriods).to.have.deep.members([lhcPeriod_LHC22b]); }); - it('should successfully sort period statistics on beamTypes', async () => { + it('should successfully sort period statistics on pdpBeamTypes', async () => { const dto = { query: { sort: { - beamTypes: 'ASC', + pdpBeamTypes: 'ASC', }, }, }; diff --git a/test/lib/server/services/simulationPasses/SimulationPassesService.test.js b/test/lib/server/services/simulationPasses/SimulationPassesService.test.js index 0675bf8922..01a1ed321b 100644 --- a/test/lib/server/services/simulationPasses/SimulationPassesService.test.js +++ b/test/lib/server/services/simulationPasses/SimulationPassesService.test.js @@ -21,6 +21,7 @@ const LHC23k6c = { id: 1, name: 'LHC23k6c', jiraId: 'SIMTICKET-1', + pdpBeamTypes: ['PbPb', 'pp'], description: 'Some Random general purpose for LHC23k6c', pwg: 'PWGX2', requestedEventsCount: 1345555, @@ -34,6 +35,7 @@ const LHC23k6b = { id: 2, name: 'LHC23k6b', jiraId: 'SIMTICKET-2', + pdpBeamTypes: ['PbPb'], description: 'Some Random general purpose for LHC23k6b', pwg: 'PWGX1', requestedEventsCount: 2345555, @@ -47,6 +49,7 @@ const LHC23k6a = { id: 3, name: 'LHC23k6a', jiraId: 'SIMTICKET-3', + pdpBeamTypes: ['PbPb'], description: 'Some Random general purpose for LHC23k6a', pwg: 'PWGX3', requestedEventsCount: 2245555, diff --git a/test/public/dataPasses/overviewPerLhcPeriod.test.js b/test/public/dataPasses/overviewPerLhcPeriod.test.js index 410c48dc2f..4ab08e8de0 100644 --- a/test/public/dataPasses/overviewPerLhcPeriod.test.js +++ b/test/public/dataPasses/overviewPerLhcPeriod.test.js @@ -108,7 +108,7 @@ module.exports = () => { expectUrlParams(page, { page: 'runs-per-data-pass', dataPassId: '2', - pdpBeamType: 'pp', + pdpBeamTypes: 'pp', }); }); diff --git a/test/public/lhcPeriods/overview.test.js b/test/public/lhcPeriods/overview.test.js index 163302ed2e..13beb52714 100644 --- a/test/public/lhcPeriods/overview.test.js +++ b/test/public/lhcPeriods/overview.test.js @@ -63,7 +63,7 @@ module.exports = () => { associatedDataPasses: (display) => /(No data passes)|(\d+)/.test(display), associatedSimulationPasses: (display) => /(No MC)|(\d+)/.test(display), year: (year) => !isNaN(year), - beamTypes: (beamTypes) => beamTypes.split(',').every((type) => allowedBeamTypesDisplays.has(type)), + pdpBeamTypes: (pdpBeamTypes) => pdpBeamTypes.split(',').every((type) => allowedBeamTypesDisplays.has(type)), avgCenterOfMassEnergy: (avgCenterOfMassEnergy) => avgCenterOfMassEnergy === '-' || !isNaN(avgCenterOfMassEnergy), distinctEnergies: (distinctEnergies) => distinctEnergies === '-' || distinctEnergies @@ -150,6 +150,6 @@ module.exports = () => { await page.waitForSelector('#reset-filters:disabled'); await fillInput(page, 'div.flex-row.items-baseline:nth-of-type(3) input[type=text]', 'PbPb'); await page.waitForSelector('#reset-filters:disabled', { hidden: true, timeout: 250 }); - await expectColumnValues(page, 'beamTypes', ['PbPb']); + await expectColumnValues(page, 'pdpBeamTypes', ['PbPb']); }); }; diff --git a/test/public/qcFlags/detailsForDataPass.test.js b/test/public/qcFlags/detailsForDataPass.test.js index d1536b9fbc..f62bfe2834 100644 --- a/test/public/qcFlags/detailsForDataPass.test.js +++ b/test/public/qcFlags/detailsForDataPass.test.js @@ -66,7 +66,7 @@ module.exports = () => { it('can navigate to runs per data pass page', async () => { await waitForNavigation(page, () => pressElement(page, '#qc-flag-details-dataPass a', true)); - expectUrlParams(page, { page: 'runs-per-data-pass', dataPassId: '1', pdpBeamType: 'pp' }); + expectUrlParams(page, { page: 'runs-per-data-pass', dataPassId: '1', pdpBeamTypes: 'pp' }); await waitForNavigation(page, () => page.goBack()); }); diff --git a/test/public/runs/dataPassesUtilities.js b/test/public/runs/dataPassesUtilities.js new file mode 100644 index 0000000000..420940c95a --- /dev/null +++ b/test/public/runs/dataPassesUtilities.js @@ -0,0 +1,21 @@ +const { waitForNavigation, pressElement, getInnerText, expectUrlParams, waitForTableLength } = require('../defaults.js'); + +/** + * Navigate to Runs per Data Pass page + * + * @param {Puppeteer.Page} page page + * @param {number} lhcPeriodId id of lhc period on LHC Period overview page + * @param {number} dataPassId id of data pass on Data Passes per LHC Period page + * @param {number} expectedRowsCount expected number of rows on runs per data pass page + * @return {Promise} promise + */ +exports.navigateToRunsPerDataPass = async (page, lhcPeriodId, dataPassId, expectedRowsCount) => { + await waitForNavigation(page, () => pressElement(page, 'a#lhc-period-overview', true)); + const pdpBeamTypes = await getInnerText(await page.waitForSelector(`#row${lhcPeriodId}-pdpBeamTypes`)); + await waitForNavigation(page, () => pressElement(page, `#row${lhcPeriodId}-associatedDataPasses a`, true)); + expectUrlParams(page, { page: 'data-passes-per-lhc-period-overview', lhcPeriodId }); + await page.waitForSelector('th#description'); + await waitForNavigation(page, () => pressElement(page, `#row${dataPassId}-associatedRuns a`, true)); + expectUrlParams(page, { page: 'runs-per-data-pass', dataPassId, pdpBeamTypes }); + await waitForTableLength(page, expectedRowsCount); +};