Skip to content

Commit a51954d

Browse files
[O2B-1126] Show data passes counts (#1346)
* add migration * add references * add model associations * add jsonRequest method * add abstract synchronizer * cleanup * cleanup * cleanup * cleanup * cleanup * simplify * cleanup * cleanup * add monalisa service * docs annotation * refactor * change main method to return void instead of boolean * db action * handle field mappings * remove abstract class * single concrete class * add variables * use env vars * linter * refactor * docs refactor * typo * refactor * refactor * fixes * refactored * not then chain * refactor{ * types * rename * use seuqlize to fetch last runs * add type, use URL class * remove file read * docs * add synchronizer factory * add docs * cleanup * no await * refactor * typdef * refactor context * rename * docs * docs * rename * working * rename * rename * add test for getting data passes * add test for getting data passes * sync test * add test for data pass sync * amend data * add details fetching * add env * fetching data passes and details * rename * add tests * rename * reduce test data size * docs * refactor * typo * typo * docs * rename * docs * cleanup * remove dead code * add service * cleanup * add filtering by periods * add data passes seeders * rename * add data passes service tests * test * revoke unfound changes * add controllers * rename * refactor * refactor * refactor * no dependency * refactor * refactor * refactor: * reaname' * rename * cleanup * docs * reaname * refactor * add router * restore * amend test * expose api * add test * add tests * amend * docs * amend test * amend * add Data Passes page * expose page * styling * add reset method * rename * use sorting * add unit * docs * amend test * rename * rename * use filtering by name * add test * use generic model * aboid undefined destruciton error * use proper method * add to to api * display on front * add color * docs * amend test * amend tests * amend test * amend test * styling * no await * use new styling * amend test * amend sequelize association * refactor * put differnt styles * move file * refactor * amend test * amend * revoke * Update lib/public/views/lhcPeriods/ActiveColumns/lhcPeriodsActiveColumns.js Co-authored-by: Martin Boulais <31805063+martinboulais@users.noreply.github.com> * Update lib/public/views/lhcPeriods/ActiveColumns/lhcPeriodsActiveColumns.js Co-authored-by: Martin Boulais <31805063+martinboulais@users.noreply.github.com> * linter * fix test * resize --------- Co-authored-by: Martin Boulais <31805063+martinboulais@users.noreply.github.com>
1 parent 0a9e241 commit a51954d

10 files changed

Lines changed: 71 additions & 29 deletions

File tree

lib/database/adapters/LhcPeriodStatisticsAdapter.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,12 +33,14 @@ class LhcPeriodStatisticsAdapter {
3333
const { id, avgCenterOfMassEnergy, lhcPeriod } = databaseObject;
3434
const distinctEnergies = databaseObject.get('distinctEnergies');
3535
const beamType = databaseObject.get('beamType');
36+
const dataPassesCount = databaseObject.get('dataPassesCount');
3637
const runsCount = databaseObject.get('runsCount');
3738
const entity = {
3839
id,
3940
avgCenterOfMassEnergy,
4041
distinctEnergies: distinctEnergies?.split(',').map((energy) => Number(energy)) ?? [],
4142
beamType,
43+
dataPassesCount,
4244
runsCount,
4345
};
4446
entity.lhcPeriod = lhcPeriod ? this.lhcPeriodAdapter.toEntity(lhcPeriod) : null;

lib/database/models/lhcPeriod.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ module.exports = (sequelize) => {
3333

3434
LhcPeriod.associate = (models) => {
3535
LhcPeriod.hasMany(models.Run, { foreignKey: 'lhcPeriodId', as: 'runs' });
36-
LhcPeriod.hasOne(models.DataPass);
36+
LhcPeriod.hasMany(models.DataPass, { foreignKey: 'lhcPeriodId', as: 'dataPass' });
3737
};
3838

3939
return LhcPeriod;

lib/database/models/typedefs/SequelizeLhcPeriodStatistics.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,5 +18,6 @@
1818
* @property {number|null} avgCenterOfMassEnergy
1919
* @property {number[]|null} distinctEnergies
2020
* @property {SequelizeLhcPeriod} lhcPeriod
21+
* @property {number} dataPassesCount
2122
* @property {number} runsCount
2223
*/

lib/domain/entities/LhcPeriodStatistics.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,5 +18,6 @@
1818
* @property {number|null} avgCenterOfMassEnergy
1919
* @property {number[]} distinctEnergies
2020
* @property {LhcPeriod} lhcPeriod
21+
* @property {number} dataPassesCount
2122
* @property {number} runsCount
2223
*/

lib/public/views/lhcPeriods/ActiveColumns/lhcPeriodsActiveColumns.js

Lines changed: 34 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@
1414
import { h } from '/js/src/index.js';
1515
import { formatDistinctLhcBeamEnergies } from '../format/formatDistinctLhcBeamEnergies.js';
1616
import { formatLhcPeriodYear } from '../format/formatYear.js';
17-
import { frontLink } from '../../../components/common/navigation/frontLink.js';
1817
import { textFilter } from '../../../components/Filters/common/filters/textFilter.js';
18+
import { frontLink } from '../../../components/common/navigation/frontLink.js';
1919

2020
/**
2121
* List of active columns for a generic periods table
@@ -24,29 +24,48 @@ export const lhcPeriodsActiveColumns = {
2424
name: {
2525
name: 'Name',
2626
visible: true,
27-
format: (name, { id, runsCount }) => h('.flex-row.flex-wrap', [
28-
h('.ph1.mh1.w-10', name),
29-
h('.mh4'),
30-
frontLink(
31-
['Runs', h('.badge', `(${runsCount})`)],
32-
'runs-per-lhc-period',
33-
{ lhcPeriodName: name },
34-
{ class: `mh1 ${runsCount === 0 ? 'gray-darker' : ''}` },
35-
),
36-
frontLink('Data Passes', 'data-passes-per-lhc-period-overview', { lhcPeriodId: id }, { class: 'mh1' }),
37-
]),
3827
sortable: true,
3928
filter: ({ namesFilterModel }) => textFilter(
4029
namesFilterModel,
4130
{ class: 'w-75 mt1', placeholder: 'e.g. LHC22a, lhc23b, ...' },
4231
),
32+
classes: 'w-15',
33+
},
34+
35+
associatedRuns: {
36+
name: 'Runs',
37+
visible: true,
38+
format: (_, { name, runsCount }) =>
39+
runsCount === 0
40+
? 'No runs'
41+
: frontLink(
42+
h('.flex-row.g3', [h('.f6.badge.bg-gray-light.black', runsCount), 'Runs']),
43+
'runs-per-lhc-period',
44+
{ lhcPeriodName: name },
45+
),
46+
classes: 'w-15',
47+
},
48+
49+
associatedDataPasses: {
50+
name: 'Data Passes',
51+
visible: true,
52+
format: (_, { id, dataPassesCount }) =>
53+
dataPassesCount === 0
54+
? 'No data pass'
55+
: frontLink(
56+
h('.flex-row.g3', [h('.f6.badge.bg-gray-light.black', dataPassesCount), 'Data Passes']),
57+
'data-passes-per-lhc-period-overview',
58+
{ lhcPeriodId: id },
59+
),
60+
classes: 'w-20',
4361
},
4462

4563
avgCenterOfMassEnergy: {
46-
name: ['Avg ', h('img', { src: '/assets/center-of-mass-energy.svg' }), ' [GeV]'],
64+
name: h('.flex-wrap', ['Avg ', h('img', { src: '/assets/center-of-mass-energy.svg' }), '[GeV]']),
4765
visible: true,
4866
sortable: true,
4967
format: (avgCenterOfMassEnergy) => avgCenterOfMassEnergy ? `${Number(avgCenterOfMassEnergy).toFixed(2)}` : '-',
68+
classes: 'w-10',
5069
},
5170

5271
year: {
@@ -58,6 +77,7 @@ export const lhcPeriodsActiveColumns = {
5877
yearsFilterModel,
5978
{ class: 'w-75 mt1', placeholder: 'e.g. 2022, 2023, ...' },
6079
),
80+
classes: 'w-7',
6181
},
6282

6383
beamType: {
@@ -69,6 +89,7 @@ export const lhcPeriodsActiveColumns = {
6989
beamTypesFilterModel,
7090
{ class: 'w-75 mt1', placeholder: 'e.g. pp, PbPb' },
7191
),
92+
classes: 'w-7',
7293
},
7394

7495
distinctEnergies: {

lib/server/services/lhcPeriod/LhcPeriodStatisticsService.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,15 @@ const RUNS_COUNT_SUBQUERY = `
6565
)
6666
`;
6767

68+
/*
69+
* Subquery to calculate number of data passes associated with given LHC Period
70+
*/
71+
const DATA_PASSES_COUNT_SUBQUERY = `
72+
(SELECT COUNT(dp.id)
73+
FROM data_passes as dp
74+
WHERE dp.lhc_period_id = lhcPeriod.id
75+
)`;
76+
6877
/**
6978
* @typedef LhcPeriodIdentifier object to uniquely identify a lhc period
7079
* @property {string} [name] the lhc period name
@@ -105,6 +114,10 @@ class LhcPeriodStatisticsService {
105114
query: RUNS_COUNT_SUBQUERY,
106115
alias: 'runsCount',
107116
});
117+
queryBuilder.includeAttribute({
118+
query: DATA_PASSES_COUNT_SUBQUERY,
119+
alias: 'dataPassesCount',
120+
});
108121

109122
const data = await LhcPeriodStatisticsRepository.findOne(queryBuilder);
110123
return data ? lhcPeriodStatisticsAdapter.toEntity(data) : null;
@@ -206,6 +219,10 @@ class LhcPeriodStatisticsService {
206219
query: PDP_BEAM_TYPES_IN_STATISTICS_SUBQUERY,
207220
alias: 'beamType',
208221
});
222+
queryBuilder.includeAttribute({
223+
query: DATA_PASSES_COUNT_SUBQUERY,
224+
alias: 'dataPassesCount',
225+
});
209226

210227
queryBuilder.includeAttribute({
211228
query: RUNS_COUNT_SUBQUERY,

test/api/lhcPeriodsStatistics.test.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ const lhcPeriod_LHC22b = {
2626
name: 'LHC22b',
2727
},
2828
runsCount: 1,
29+
dataPassesCount: 2,
2930
};
3031

3132
const lhcPeriod_LHC22a = {
@@ -41,6 +42,8 @@ const lhcPeriod_LHC22a = {
4142
name: 'LHC22a',
4243
},
4344
runsCount: 3,
45+
dataPassesCount: 1,
46+
4447
};
4548

4649
const lhcPeriod_LHC23f = {
@@ -52,6 +55,7 @@ const lhcPeriod_LHC23f = {
5255
id: 3,
5356
name: 'LHC23f',
5457
},
58+
dataPassesCount: 0,
5559
runsCount: 0,
5660
};
5761

test/lib/server/monalisa-synchronization/MonALISASynchronizer.test.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,13 @@ const { repositories: { DataPassRepository, LhcPeriodRepository } } = require('.
1818
const { dataSource } = require('../../../../lib/database/DataSource.js');
1919

2020
const { extractLhcPeriod } = require('../../../../lib/server/utilities/extractLhcPeriod');
21+
const { resetDatabaseContent } = require('../../../utilities/resetDatabaseContent.js');
2122

2223
const YEAR_LOWER_LIMIT = 2023;
2324

2425
module.exports = () => {
26+
after(async () => resetDatabaseContent());
27+
2528
it('Should get data with respect to given year limit and in correct format', async () => {
2629
const monALISAClient = getMockMonALISAClient(YEAR_LOWER_LIMIT);
2730
const mockDataPasses = await monALISAClient.getDataPasses();

test/lib/server/services/lhcPeriod/LhcPeriodStatisticsService.test.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ const lhcPeriod_LHC22b = {
2727
name: 'LHC22b',
2828
},
2929
runsCount: 1,
30+
dataPassesCount: 2,
3031
};
3132

3233
const lhcPeriod_LHC22a = {
@@ -42,6 +43,8 @@ const lhcPeriod_LHC22a = {
4243
name: 'LHC22a',
4344
},
4445
runsCount: 3,
46+
dataPassesCount: 1,
47+
4548
};
4649

4750
const lhcPeriod_LHC23f = {
@@ -53,6 +56,7 @@ const lhcPeriod_LHC23f = {
5356
id: 3,
5457
name: 'LHC23f',
5558
},
59+
dataPassesCount: 0,
5660
runsCount: 0,
5761
};
5862

test/public/lhcPeriods/overview.test.js

Lines changed: 4 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@ module.exports = () => {
5252
// Expectations of header texts being of a certain datatype
5353
const headerDatatypes = {
5454
name: (name) => periodNameRegex.test(name),
55+
associatedRuns: (display) => /(No runs)|(\d+\nRuns)/.test(display),
56+
associatedDataPasses: (display) => /(No data passes)|(\d+\nData Passes)/.test(display),
5557
year: (year) => !isNaN(year),
5658
beamType: (beamType) => allowedBeamTypesDisplayes.has(beamType),
5759
avgCenterOfMassEnergy: (avgCenterOfMassEnergy) => !isNaN(avgCenterOfMassEnergy),
@@ -192,29 +194,16 @@ module.exports = () => {
192194

193195
await page.waitForTimeout(100);
194196

195-
const countsPerLhcPeriod = {
196-
LHC22b: 1,
197-
LHC22a: 3,
198-
LHC23f: 0,
199-
};
200-
201-
/**
202-
* As @see getAllDataFields returns innerText from cells, in case of lhcPeriod.name column, text from inner buttons is also taken.
203-
* @param {string[]} periodNames list of names
204-
* @return {string[]} cells content
205-
*/
206-
const appendButtonsText = (periodNames) => periodNames.map((name) => `${name}\nRuns(${countsPerLhcPeriod[name]})\nData Passes`);
207-
208197
let allLhcPeriodNameCellsContent = await getAllDataFields(page, 'name');
209-
expect(allLhcPeriodNameCellsContent).to.has.all.deep.members(appendButtonsText(['LHC22a']));
198+
expect(allLhcPeriodNameCellsContent).to.has.all.deep.members(['LHC22a']);
210199

211200
const resetFiltersButton = await page.$('#reset-filters');
212201
expect(resetFiltersButton).to.not.be.null;
213202
await resetFiltersButton.evaluate((button) => button.click());
214203
await page.waitForTimeout(100);
215204

216205
allLhcPeriodNameCellsContent = await getAllDataFields(page, 'name');
217-
expect(allLhcPeriodNameCellsContent).to.has.all.deep.members(appendButtonsText(['LHC22a', 'LHC22b', 'LHC23f']));
206+
expect(allLhcPeriodNameCellsContent).to.has.all.deep.members(['LHC22a', 'LHC22b', 'LHC23f']);
218207
});
219208

220209
it('should successfuly apply lhc period year filter', async () => {

0 commit comments

Comments
 (0)