Skip to content

Commit

Permalink
add "external biomass grid process" using gRPC and tables using TableSaw
Browse files Browse the repository at this point in the history
A bit of a sloppy commit since I tackled those two things in parallel.
They could have been better separated...
  • Loading branch information
nicolaspayette committed Nov 29, 2024
1 parent 6dfe878 commit 1994c6b
Show file tree
Hide file tree
Showing 20 changed files with 361 additions and 244 deletions.
1 change: 1 addition & 0 deletions agents/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,5 @@ plugins {
dependencies {
api(project(":biology"))
api(project(":geography"))
api(project(":io"))
}
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,8 @@ private Evaluation(final Vessel vessel) {
vessel.getEventManager(),
FishingAction.class,
0.0,
(caughtSoFar, fishingAction) -> caughtSoFar + fishingAction.getTotalBiomassCaught(),
(caughtSoFar, fishingAction) -> caughtSoFar +
fishingAction.getFishCaught().getTotalBiomass().getValue(),
Action.class,
0.0,
(hoursSoFar, action) ->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,11 +65,6 @@ private Fishing(
super(start, duration, vessel, vessel.getCurrentCell());
}

@Override
public double getTotalBiomassCaught() {
return fishCaught.getTotalBiomass().getValue();
}

@Override
protected Action complete(
final LocalDateTime dateTime
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import sim.util.Int2D;
import uk.ac.ox.poseidon.agents.behaviours.GridAction;
import uk.ac.ox.poseidon.agents.vessels.Vessel;
import uk.ac.ox.poseidon.biology.Bucket;

import java.time.Duration;
import java.time.LocalDateTime;
Expand All @@ -37,5 +38,6 @@ public FishingAction(
super(start, duration, vessel, cell);
}

public abstract double getTotalBiomassCaught();
public abstract Bucket<?> getFishCaught();

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/*
* POSEIDON: an agent-based model of fisheries
* Copyright (c) 2024 CoHESyS Lab [email protected]
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/

package uk.ac.ox.poseidon.agents.tables;

import tech.tablesaw.api.DateTimeColumn;
import tech.tablesaw.api.StringColumn;
import tech.tablesaw.api.Table;
import uk.ac.ox.poseidon.agents.behaviours.Action;
import uk.ac.ox.poseidon.io.tables.ListenerTable;

public abstract class ActionListenerTable<A extends Action> implements ListenerTable<A> {
private final StringColumn vesselId = StringColumn.create("vessel_id");
private final DateTimeColumn actionStart = DateTimeColumn.create("action_start");
private final DateTimeColumn actionEnd = DateTimeColumn.create("action_end");

private final Table table =
Table.create(
vesselId,
actionStart,
actionEnd
);

@Override
public void receive(final A action) {
actionStart.append(action.getStart());
actionEnd.append(action.getEnd());
vesselId.append(action.getVessel().getId());
}

@Override
public Table get() {
return table;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/*
* POSEIDON: an agent-based model of fisheries
* Copyright (c) 2024 CoHESyS Lab [email protected]
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/

package uk.ac.ox.poseidon.agents.tables;

import tech.tablesaw.api.DoubleColumn;
import tech.tablesaw.api.StringColumn;
import uk.ac.ox.poseidon.agents.behaviours.fishing.FishingAction;
import uk.ac.ox.poseidon.geography.grids.GridExtent;

public class FishingActionListenerTable extends GridActionListenerTable<FishingAction> {

private final StringColumn speciesCode = StringColumn.create("species_code");
private final DoubleColumn biomassCaught = DoubleColumn.create("biomass_caught");

public FishingActionListenerTable(final GridExtent gridExtent) {
super(gridExtent);
get().addColumns(speciesCode, biomassCaught);
}

@Override
public void receive(final FishingAction fishingAction) {
super.receive(fishingAction);
fishingAction.getFishCaught().getMap().forEach((species, content) -> {
speciesCode.append(species.getCode());
biomassCaught.append(content.asBiomass().getValue());
});
}

@Override
public Class<FishingAction> getEventClass() {
return FishingAction.class;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*
* POSEIDON: an agent-based model of fisheries
* Copyright (c) 2024 CoHESyS Lab [email protected]
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/

package uk.ac.ox.poseidon.agents.tables;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import uk.ac.ox.poseidon.agents.behaviours.fishing.FishingAction;
import uk.ac.ox.poseidon.core.Factory;
import uk.ac.ox.poseidon.core.Simulation;
import uk.ac.ox.poseidon.geography.grids.GridExtent;
import uk.ac.ox.poseidon.io.tables.ListenerTableFactory;

@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public class FishingActionListenerTableFactory
extends ListenerTableFactory<FishingAction, FishingActionListenerTable> {

private Factory<? extends GridExtent> gridExtent;

@Override
protected FishingActionListenerTable newTable(final Simulation simulation) {
return new FishingActionListenerTable(gridExtent.get(simulation));
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/*
* POSEIDON: an agent-based model of fisheries
* Copyright (c) 2024 CoHESyS Lab [email protected]
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/

package uk.ac.ox.poseidon.agents.tables;

import com.vividsolutions.jts.geom.Coordinate;
import tech.tablesaw.api.DoubleColumn;
import uk.ac.ox.poseidon.agents.behaviours.GridAction;
import uk.ac.ox.poseidon.geography.grids.GridExtent;

public abstract class GridActionListenerTable<A extends GridAction> extends ActionListenerTable<A> {
private final GridExtent gridExtent;
private final DoubleColumn lon = DoubleColumn.create("lon");
private final DoubleColumn lat = DoubleColumn.create("lat");

public GridActionListenerTable(final GridExtent gridExtent) {
super();
get().addColumns(lon, lat);
this.gridExtent = gridExtent;
}

@Override
public void receive(final A action) {
super.receive(action);
final Coordinate coordinate = gridExtent.toCoordinate(action.getCell());
lon.append(coordinate.x);
lat.append(coordinate.y);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,19 +20,18 @@
package uk.ac.ox.poseidon.core.time;

import lombok.RequiredArgsConstructor;
import sim.util.distribution.AbstractDistribution;

import java.time.Duration;
import java.util.function.Supplier;

@RequiredArgsConstructor
public class DistributedDurationSupplier implements Supplier<Duration> {
public class DurationSupplier implements Supplier<Duration> {

private final AbstractDistribution distribution;
private final Supplier<Long> secondsSupplier;

@Override
public Duration get() {
return Duration.ofSeconds(distribution.nextInt());
return Duration.ofSeconds(secondsSupplier.get());
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,13 @@ public class ExponentiallyDistributedDurationSupplierFactory

@Override
protected Supplier<Duration> newInstance(final Simulation simulation) {
return new DistributedDurationSupplier(
final Exponential exponential =
new Exponential(
1.0 / meanDuration.get(simulation).getSeconds(),
simulation.random
)
);
return new DurationSupplier(
() -> (long) (1 + exponential.nextInt())
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import lombok.Setter;
import sim.engine.Steppable;
import sim.util.Int2D;
import tech.tablesaw.api.Table;
import uk.ac.ox.poseidon.agents.behaviours.BackToInitialBehaviourFactory;
import uk.ac.ox.poseidon.agents.behaviours.WaitBehaviourFactory;
import uk.ac.ox.poseidon.agents.behaviours.choices.BestOptionsFromFriendsSupplierFactory;
Expand All @@ -39,6 +40,7 @@
import uk.ac.ox.poseidon.agents.registers.Register;
import uk.ac.ox.poseidon.agents.registers.RegisterFactory;
import uk.ac.ox.poseidon.agents.registers.RegisteringFactory;
import uk.ac.ox.poseidon.agents.tables.FishingActionListenerTableFactory;
import uk.ac.ox.poseidon.agents.vessels.RandomHomePortFactory;
import uk.ac.ox.poseidon.agents.vessels.VesselFactory;
import uk.ac.ox.poseidon.agents.vessels.VesselScopeFactory;
Expand All @@ -50,7 +52,6 @@
import uk.ac.ox.poseidon.core.Factory;
import uk.ac.ox.poseidon.core.GlobalScopeFactory;
import uk.ac.ox.poseidon.core.Scenario;
import uk.ac.ox.poseidon.core.Simulation;
import uk.ac.ox.poseidon.core.schedule.ScheduledRepeatingFactory;
import uk.ac.ox.poseidon.core.schedule.SteppableSequenceFactory;
import uk.ac.ox.poseidon.core.suppliers.PoissonIntSupplierFactory;
Expand All @@ -72,7 +73,9 @@

import java.nio.file.Path;
import java.time.LocalDate;
import java.time.Period;
import java.util.List;
import java.util.function.Supplier;

@SuppressWarnings("MagicNumber")
@Getter
Expand All @@ -84,9 +87,9 @@ public class BasicScenario extends Scenario {
private Factory<? extends Species> speciesA = new SpeciesFactory("A");
private Factory<? extends Species> speciesB = new SpeciesFactory("B");
private Factory<? extends BiomassDiffusionRule> biomassDiffusionRule =
new SmoothBiomassDiffusionRuleFactory(0.001, 0.01);
new SmoothBiomassDiffusionRuleFactory(0.01, 0.01);
private Factory<? extends BiomassGrowthRule> biomassGrowthRule =
new LogisticGrowthRuleFactory(0.7);
new LogisticGrowthRuleFactory(0.1);

private GlobalScopeFactory<? extends GridExtent> gridExtent =
new GridExtentFactory(
Expand All @@ -97,6 +100,8 @@ public class BasicScenario extends Scenario {
-5,
5
);
private Factory<? extends Supplier<Table>> catchTable =
new FishingActionListenerTableFactory(gridExtent);
private Factory<? extends VesselField> vesselField = new VesselFieldFactory(gridExtent);
private Factory<? extends Distance> distance = new EquirectangularDistanceFactory(gridExtent);
private Factory<? extends BathymetricGrid> bathymetricGrid =
Expand All @@ -117,7 +122,6 @@ public class BasicScenario extends Scenario {
3,
2
);

private Factory<? extends GridPathFinder> pathFinder =
new DefaultPathFinderFactory(
bathymetricGrid,
Expand Down Expand Up @@ -200,20 +204,20 @@ public class BasicScenario extends Scenario {
),
new ChooseDestinationBehaviourFactory(
new EpsilonGreedyDestinationSupplierFactory(
0.2,
0.25,
optionValues,
new NeighbourhoodGridExplorerFactory(
optionValues,
pathFinder,
new ShiftedIntSupplierFactory(
new PoissonIntSupplierFactory(5),
new PoissonIntSupplierFactory(1),
1
)
),
new ImitatingPickerFactory<>(
optionValues,
new BestOptionsFromFriendsSupplierFactory<>(
2,
5,
optionValuesRegister
)
),
Expand All @@ -222,7 +226,7 @@ public class BasicScenario extends Scenario {
new TravelAlongPathBehaviourFactory(
new DefaultFishingBehaviourFactory<>(
new FixedBiomassProportionGearFactory(
0.05,
0.1,
new DurationFactory(0, 1, 0, 0)
),
new VoidHoldFactory<>(),
Expand Down Expand Up @@ -263,16 +267,7 @@ public static void main(final String[] args) {
scenario,
Path.of("/home/nicolas/Desktop/scenario.yaml")
);
final Simulation simulation = scenario.newSimulation();
simulation.start();
while (
simulation
.getTemporalSchedule()
.getDateTime()
.isBefore(LocalDate.of(LocalDate.now().getYear() + 10, 1, 1).atStartOfDay())
) {
simulation.schedule.step(simulation);
}
simulation.finish();
new QuickRunner(scenario).runFor(Period.ofYears(1));

}
}
Loading

0 comments on commit 1994c6b

Please sign in to comment.