Skip to content

Commit 1620c99

Browse files
Add weekly report period to PeriodicReport (#333)
* Add weekly report period to PeriodicReport Added a new weekly value to ReportPeriod and updated PeriodicReport to accommodate it. Updated AT_PeriodicReport to test for weekly reports and updated other failing tests to now account for the weekly ReportPeriod value. * Update weekly logic in PeriodicReport Updated the weekly logic in PeriodicReport to now have weekly reports be flushed on an interval of day 7, day 14, day 21 etc regardless of what the sim start time was. With the old logic, we were just adding 7 days to whatever the sim start time was, which if the sim start time was 3.5 then the flush interval would be day 10, day 17, day 24, etc.
1 parent b193235 commit 1620c99

6 files changed

Lines changed: 165 additions & 5 deletions

File tree

simulation/src/main/java/gov/hhs/aspr/ms/gcm/simulation/plugins/reports/support/PeriodicReport.java

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,10 +50,15 @@ public PeriodicReport(ReportLabel reportLabel, ReportPeriod reportPeriod) {
5050
*/
5151
private Integer reportingHour = 0;
5252

53+
/*
54+
* The week value to be used in report lines
55+
*/
56+
private Integer reportingWeek = 0;
57+
5358
/**
5459
* Adds the time field column(s) to the given {@link ReportHeader.Builder} as
5560
* appropriate to the {@link ReportPeriod} specified during construction. DAILY
56-
* : Day HOURLY : Day, Hour END_OF_SIMULATION has no header additions
61+
* : day; HOURLY : day, hour; WEEKLY : day, week; END_OF_SIMULATION has no header additions
5762
*/
5863
protected final ReportHeader.Builder addTimeFieldHeaders(ReportHeader.Builder reportHeaderBuilder) {
5964
switch (reportPeriod) {
@@ -67,6 +72,10 @@ protected final ReportHeader.Builder addTimeFieldHeaders(ReportHeader.Builder re
6772
reportHeaderBuilder.add("day");
6873
reportHeaderBuilder.add("hour");
6974
break;
75+
case WEEKLY:
76+
reportHeaderBuilder.add("day");
77+
reportHeaderBuilder.add("week");
78+
break;
7079
default:
7180
throw new RuntimeException("unknown report period " + reportPeriod);
7281
}
@@ -82,8 +91,9 @@ protected final ReportPeriod getReportPeriod() {
8291
}
8392

8493
/**
85-
* Places the current reporting day and report hour on the report as appropriate
86-
* to the {@link ReportPeriod} specified during construction.
94+
* Places the current reporting day, reporting hour, and reporting week on the
95+
* report as appropriate to the {@link ReportPeriod} specified during
96+
* construction.
8797
*/
8898
protected final void fillTimeFields(final ReportItem.Builder reportItemBuilder) {
8999

@@ -98,6 +108,10 @@ protected final void fillTimeFields(final ReportItem.Builder reportItemBuilder)
98108
reportItemBuilder.addValue(reportingDay);
99109
reportItemBuilder.addValue(reportingHour);
100110
break;
111+
case WEEKLY:
112+
reportItemBuilder.addValue(reportingDay);
113+
reportItemBuilder.addValue(reportingWeek);
114+
break;
101115
default:
102116
throw new RuntimeException("unknown report period " + reportPeriod);
103117
}
@@ -124,6 +138,7 @@ public final void init(ReportContext reportContext) {
124138
if (reportingHour > 23) {
125139
reportingHour = 23;
126140
}
141+
reportingWeek = (int) (reportContext.getTime() / 7);
127142

128143
prepare(reportContext);
129144

@@ -161,6 +176,8 @@ private double getNextPlanTime() {
161176
case HOURLY:
162177
return reportingDay + (double) (reportingHour) / 24;
163178

179+
case WEEKLY:
180+
return reportingWeek * 7;
164181
default:
165182
throw new RuntimeException("unhandled report period " + reportPeriod);
166183
}
@@ -178,6 +195,11 @@ private void incrementReportingTimeFields() {
178195
reportingDay++;
179196
}
180197
break;
198+
case WEEKLY:
199+
int extraDays = reportingDay % 7;
200+
reportingDay += (7 - extraDays);
201+
reportingWeek++;
202+
break;
181203
case END_OF_SIMULATION:
182204
// do nothing
183205
break;

simulation/src/main/java/gov/hhs/aspr/ms/gcm/simulation/plugins/reports/support/ReportPeriod.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
* periodicity of the report.
66
*/
77
public enum ReportPeriod {
8-
HOURLY, DAILY, END_OF_SIMULATION;
8+
HOURLY, DAILY, WEEKLY, END_OF_SIMULATION;
99

1010
public ReportPeriod next() {
1111
int index = (ordinal()+1) % ReportPeriod.values().length;

simulation/src/test/java/gov/hhs/aspr/ms/gcm/simulation/plugins/groups/reports/AT_GroupPropertyReport.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -410,6 +410,12 @@ public void testInit_ReportPeriod() {
410410
assertDoesNotThrow(() -> Integer.parseInt(reportItem.getValue(1)));
411411
assertDoesNotThrow(() -> TestGroupTypeId.valueOf(reportItem.getValue(2)));
412412
break;
413+
case WEEKLY:
414+
assertEquals(REPORT_WEEKLY_HEADER, reportHeader);
415+
assertDoesNotThrow(() -> Integer.parseInt(reportItem.getValue(0)));
416+
assertDoesNotThrow(() -> Integer.parseInt(reportItem.getValue(1)));
417+
assertDoesNotThrow(() -> TestGroupTypeId.valueOf(reportItem.getValue(2)));
418+
break;
413419
default:
414420
throw new RuntimeException("unhandled case " + reportPeriod);
415421
}
@@ -842,6 +848,9 @@ public void testInit_ReportHeader() {
842848
case HOURLY:
843849
assertEquals(REPORT_HOURLY_HEADER, reportHeader);
844850
break;
851+
case WEEKLY:
852+
assertEquals(REPORT_WEEKLY_HEADER, reportHeader);
853+
break;
845854
default:
846855
throw new RuntimeException("unhandled case " + reportPeriod);
847856
}
@@ -943,6 +952,7 @@ public void testInit_State() {
943952

944953
private static final ReportHeader REPORT_DAILY_HEADER = ReportHeader.builder().setReportLabel(REPORT_LABEL).add("day").add("group_type").add("property").add("value").add("group_count").build();
945954
private static final ReportHeader REPORT_HOURLY_HEADER = ReportHeader.builder().setReportLabel(REPORT_LABEL).add("day").add("hour").add("group_type").add("property").add("value").add("group_count").build();
955+
private static final ReportHeader REPORT_WEEKLY_HEADER = ReportHeader.builder().setReportLabel(REPORT_LABEL).add("day").add("week").add("group_type").add("property").add("value").add("group_count").build();
946956
private static final ReportHeader REPORT_END_OF_SIMULATION_HEADER = ReportHeader.builder().setReportLabel(REPORT_LABEL).add("group_type").add("property").add("value").add("group_count").build();
947957

948958
}

simulation/src/test/java/gov/hhs/aspr/ms/gcm/simulation/plugins/personproperties/reports/AT_PersonPropertyInteractionReportPluginData.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -358,7 +358,7 @@ public void testToString() {
358358

359359
String expectedValue = "PersonPropertyInteractionReportPluginData [data=Data ["
360360
+ "reportLabel=SimpleReportLabel [value=report label95], "
361-
+ "reportPeriod=HOURLY, "
361+
+ "reportPeriod=WEEKLY, "
362362
+ "personPropertyIds=["
363363
+ "PERSON_PROPERTY_1_BOOLEAN_MUTABLE_NO_TRACK, "
364364
+ "PERSON_PROPERTY_2_INTEGER_MUTABLE_NO_TRACK, "

simulation/src/test/java/gov/hhs/aspr/ms/gcm/simulation/plugins/personproperties/reports/AT_PersonPropertyReport.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -427,6 +427,9 @@ private void testInit_ReportHeader(ReportPeriod reportPeriod) {
427427
case HOURLY:
428428
expectedReportHeader = REPORT_HOURLY_HEADER;
429429
break;
430+
case WEEKLY:
431+
expectedReportHeader = REPORT_WEEKLY_HEADER;
432+
break;
430433
default:
431434
throw new RuntimeException("unhandled case " + reportPeriod);
432435

@@ -1160,6 +1163,8 @@ public String toString() {
11601163

11611164
private static final ReportHeader REPORT_HOURLY_HEADER = ReportHeader.builder().setReportLabel(REPORT_LABEL).add("day").add("hour").add("region")
11621165
.add("property").add("value").add("person_count").build();
1166+
private static final ReportHeader REPORT_WEEKLY_HEADER = ReportHeader.builder().setReportLabel(REPORT_LABEL).add("day").add("week").add("region")
1167+
.add("property").add("value").add("person_count").build();
11631168
private static final ReportHeader REPORT_DAILY_HEADER = ReportHeader.builder().setReportLabel(REPORT_LABEL).add("day").add("region")
11641169
.add("property").add("value").add("person_count").build();
11651170
private static final ReportHeader REPORT_END_OF_SIMULATION_HEADER = ReportHeader.builder().setReportLabel(REPORT_LABEL).add("region")

simulation/src/test/java/gov/hhs/aspr/ms/gcm/simulation/plugins/reports/support/AT_PeriodicReport.java

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,55 @@ protected void prepare(ReportContext reportContext) {
140140
}
141141
}
142142

143+
/*
144+
* Used to test the fillTimeFields() method when the period is
145+
* ReportPeriod.WEEKLY
146+
*/
147+
private static class WeeklyTestReport extends PeriodicReport {
148+
149+
private MutableInteger testCounter = new MutableInteger();
150+
151+
public WeeklyTestReport(ReportLabel reportLabel, ReportPeriod reportPeriod) {
152+
super(reportLabel, reportPeriod);
153+
if (reportPeriod != ReportPeriod.WEEKLY) {
154+
throw new RuntimeException("must be a weekly report");
155+
}
156+
}
157+
158+
@Override
159+
protected void flush(ReportContext reportContext) {
160+
testCounter.increment();
161+
ReportItem.Builder reportItemBuilder = ReportItem.builder();
162+
163+
fillTimeFields(reportItemBuilder);
164+
165+
ReportItem reportItem = reportItemBuilder.setReportLabel(getReportLabel()).build();
166+
int dayValue = (int) FastMath.ceil(reportContext.getTime());
167+
int extraDays = dayValue % 7;
168+
if (extraDays != 0) {
169+
dayValue += (7 - extraDays);
170+
}
171+
172+
String expectedDayTimeString = Integer.toString(dayValue);
173+
String expectedWeekTimeString = Integer.toString(dayValue / 7);
174+
String actualDayTimeString = reportItem.getValue(0);
175+
String actualWeekTimeString = reportItem.getValue(1);
176+
assertEquals(expectedDayTimeString, actualDayTimeString);
177+
assertEquals(expectedWeekTimeString, actualWeekTimeString);
178+
179+
reportContext.releaseOutput(reportItem);
180+
}
181+
182+
@Override
183+
protected void prepare(ReportContext reportContext) {
184+
ReportHeader.Builder reportHeaderBuilder = ReportHeader.builder();
185+
this.addTimeFieldHeaders(reportHeaderBuilder);
186+
ReportHeader reportHeader = reportHeaderBuilder.setReportLabel(getReportLabel()).build();
187+
188+
reportContext.releaseOutput(reportHeader);
189+
}
190+
}
191+
143192
/*
144193
* Used to test the fillTimeFields() method when the period is
145194
* ReportPeriod.END_OF_SIMULATION
@@ -226,6 +275,15 @@ public void testAddTimeFieldHeaders() {
226275
assertEquals("day", headerStrings.get(0));
227276
assertEquals("hour", headerStrings.get(1));
228277

278+
reportHeaderBuilder = ReportHeader.builder();
279+
testReport = new TestReport(reportLabel, ReportPeriod.WEEKLY);
280+
testReport.addTimeFieldHeaders(reportHeaderBuilder);
281+
reportHeader = reportHeaderBuilder.setReportLabel(reportLabel).build();
282+
headerStrings = reportHeader.getHeaderStrings();
283+
assertEquals(2, headerStrings.size());
284+
assertEquals("day", headerStrings.get(0));
285+
assertEquals("week", headerStrings.get(1));
286+
229287
reportHeaderBuilder = ReportHeader.builder();
230288
testReport = new TestReport(reportLabel, ReportPeriod.DAILY);
231289
testReport.addTimeFieldHeaders(reportHeaderBuilder);
@@ -350,6 +408,63 @@ public void testFillTimeFields_Hourly() {
350408

351409
}
352410

411+
@Test
412+
@UnitTestMethod(target = PeriodicReport.class, name = "init", args = { ReportContext.class })
413+
public void testFillTimeFields_Weekly() {
414+
double simulationEndTime = 21.5;
415+
416+
List<Plugin> plugins = new ArrayList<>();
417+
418+
ReportLabel reportLabel = new SimpleReportLabel("report");
419+
WeeklyTestReport weeklyTestReport = new WeeklyTestReport(reportLabel, ReportPeriod.WEEKLY);
420+
421+
plugins.add(Plugin.builder()//
422+
.setPluginId(new SimplePluginId("anonymous plugin"))//
423+
.setInitializer((pc) -> {
424+
pc.addReport(weeklyTestReport::init);
425+
})//
426+
.build());
427+
428+
TestPluginData.Builder pluginBuilder = TestPluginData.builder();
429+
430+
// create an agent that will make the engine run for a few days
431+
pluginBuilder.addTestActorPlan("actor", new TestActorPlan(simulationEndTime, (c) -> {
432+
}));
433+
434+
TestPluginData testPluginData = pluginBuilder.build();
435+
Plugin testPlugin = TestPlugin.getTestPlugin(testPluginData);
436+
plugins.add(testPlugin);
437+
438+
// build and execute the engine
439+
TestOutputConsumer testOutputConsumer = TestSimulation.builder()//
440+
.addPlugins(plugins)//
441+
.build()//
442+
.execute();
443+
444+
// weeks 0 through 4 weeks inclusive
445+
Set<Integer> expectedWeeks = new LinkedHashSet<>();
446+
Set<Integer> expectedDays = new LinkedHashSet<>();
447+
for (int i = 1; i <= 4; i++) {
448+
expectedWeeks.add(i);
449+
expectedDays.add(i * 7);
450+
}
451+
452+
Set<Integer> actualDays = new LinkedHashSet<>();
453+
Set<Integer> actualWeeks = new LinkedHashSet<>();
454+
Map<ReportItem, Integer> outputItems = testOutputConsumer.getOutputItemMap(ReportItem.class);
455+
for (ReportItem reportItem : outputItems.keySet()) {
456+
Integer count = outputItems.get(reportItem);
457+
assertEquals(1, count);
458+
int day = Integer.parseInt(reportItem.getValue(0));
459+
actualDays.add(day);
460+
int week = Integer.parseInt(reportItem.getValue(1));
461+
actualWeeks.add(week);
462+
}
463+
464+
assertEquals(expectedDays, actualDays);
465+
assertEquals(expectedWeeks, actualWeeks);
466+
}
467+
353468
@Test
354469
@UnitTestMethod(target = PeriodicReport.class, name = "init", args = { ReportContext.class })
355470
public void testFillTimeFields_EndOfSimulation() {
@@ -459,6 +574,14 @@ public void testInit() {
459574
}
460575
expectedTimes.add(simulationEndTime);
461576

577+
break;
578+
case WEEKLY:
579+
int lastWeek = (int) (simulationEndTime / 7);
580+
for (int i = 1; i <= lastWeek; i++) {
581+
double time = i * 7;
582+
expectedTimes.add(time);
583+
}
584+
expectedTimes.add(simulationEndTime);
462585
break;
463586
default:
464587
throw new RuntimeException("unhandled report period " + reportPeriod);

0 commit comments

Comments
 (0)