Skip to content
Open
Show file tree
Hide file tree
Changes from 6 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
224 changes: 224 additions & 0 deletions src/arcade/patch/agent/cell/PatchCellCARTCombinedCombinatorial.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,224 @@
package arcade.patch.agent.cell;

import java.util.Deque;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.logging.Logger;
import sim.engine.SimState;
import sim.util.Bag;
import sim.util.distribution.Poisson;
import ec.util.MersenneTwisterFast;
import arcade.core.env.location.Location;
import arcade.core.sim.Simulation;
import arcade.core.util.GrabBag;
import arcade.core.util.Parameters;
import arcade.patch.env.grid.PatchGrid;

/**
* Abstract class of {@link PatchCellCART} for combined CD4/CD8 combinatorial CART-cells with
* selected module versions.
*/
public abstract class PatchCellCARTCombinedCombinatorial extends PatchCellCARTCombined {

/** Logger for this class. */
private static final Logger LOGGER =
Logger.getLogger(PatchCellCARTCombinedCombinatorial.class.getName());

/** Number of bound synnotchs required to trigger activation/inactivation. */
protected final double synNotchThreshold;

/** synnotch receptor-antigen binding rate. */
protected final double bindingConstant;

/** synnotch receptor-antigen unbinding rate. */
protected final double unbindingConstant;

/** car receptor degradation rate. */
protected final double carDegradationConstant;

/** Number of synnotch receptors on this cell. */
public int synnotchs;

Check failure on line 40 in src/arcade/patch/agent/cell/PatchCellCARTCombinedCombinatorial.java

View workflow job for this annotation

GitHub Actions / checkstyle

[checkstyle] src/arcade/patch/agent/cell/PatchCellCARTCombinedCombinatorial.java#L40 <com.puppycrawl.tools.checkstyle.checks.design.VisibilityModifierCheck>

Variable 'synnotchs' must be private and have accessor methods.
Raw output
/github/workspace/./src/arcade/patch/agent/cell/PatchCellCARTCombinedCombinatorial.java:40:16: error: Variable 'synnotchs' must be private and have accessor methods. (com.puppycrawl.tools.checkstyle.checks.design.VisibilityModifierCheck)

/** Number of bound synnotch receptors on this cell. */
public int boundSynNotch;

Check failure on line 43 in src/arcade/patch/agent/cell/PatchCellCARTCombinedCombinatorial.java

View workflow job for this annotation

GitHub Actions / checkstyle

[checkstyle] src/arcade/patch/agent/cell/PatchCellCARTCombinedCombinatorial.java#L43 <com.puppycrawl.tools.checkstyle.checks.design.VisibilityModifierCheck>

Variable 'boundSynNotch' must be private and have accessor methods.
Raw output
/github/workspace/./src/arcade/patch/agent/cell/PatchCellCARTCombinedCombinatorial.java:43:16: error: Variable 'boundSynNotch' must be private and have accessor methods. (com.puppycrawl.tools.checkstyle.checks.design.VisibilityModifierCheck)

/** maximum CAR receptors possible. */
protected final int maxCars;

/** poisson distribution. */
PatchCellCARTCombinedInducible.PoissonFactory poissonFactory;

/** Target cell that is bound. */
protected PatchCellTissue boundCell;

/** basal CAR receptor expression rate. */
protected final double basalCARGenerationRate;

/** Half-life of synnotch activation TF. */
protected final double synNotchActivationDelay;

/** List of recent synnotch binding events. */
protected Deque<BindingEvent> bindingHistory = new LinkedList<>();

/**
* Creates a T cell {@code PatchCellCARTCombinedCombinatorial} agent. *
*
* @param container the cell container
* @param location the {@link Location} of the cell
* @param parameters the dictionary of parameters
*/
public PatchCellCARTCombinedCombinatorial(
PatchCellContainer container, Location location, Parameters parameters) {
this(container, location, parameters, null);
}

/**
* Creates a T cell {@code PatchCellCARTCombinedCombinatorial} agent. *
*
* @param container the cell container
* @param location the {@link Location} of the cell
* @param parameters the dictionary of parameters
* @param links the map of population links
*/
public PatchCellCARTCombinedCombinatorial(
PatchCellContainer container, Location location, Parameters parameters, GrabBag links) {
super(container, location, parameters, links);
bindingConstant = parameters.getDouble("K_SYNNOTCH_ON");
unbindingConstant = parameters.getDouble("K_SYNNOTCH_OFF");
carDegradationConstant = parameters.getDouble("K_CAR_DEGRADE");
synnotchs = parameters.getInt("SYNNOTCHS");
synNotchThreshold = parameters.getDouble("SYNNOTCH_THRESHOLD") * synnotchs;
basalCARGenerationRate = parameters.getDouble("K_CAR_GENERATION");
synNotchActivationDelay = parameters.getDouble("SYNNOTCH_ACTIVATION_DELAY");
boundSynNotch = 0;
maxCars = cars;
poissonFactory = Poisson::new;
}

/**
* Binds to target cell in neighborhood. *
*
* @param simstate the simulation state
*/
protected void checkForBinding(SimState simstate) {
Simulation sim = (Simulation) simstate;
PatchGrid grid = (PatchGrid) sim.getGrid();

Bag allAgents = new Bag();
getTissueAgents(allAgents, grid.getObjectsAtLocation(location));
for (Location neighborLocation : location.getNeighbors()) {
Bag bag = new Bag(grid.getObjectsAtLocation(neighborLocation));
getTissueAgents(allAgents, bag);
}

if (allAgents.size() > 0) {
PatchCellTissue randomCell =
(PatchCellTissue) allAgents.get(simstate.random.nextInt(allAgents.size()));
if (randomCell.getSynNotchAntigens() > 0) {
boundCell = randomCell;
}
}
}

/**
* Calculates the number of binding and unbinding events for the synnotch receptor . *
*
* @param random the random object
* @param sim the simulation instance
*/
protected void calculateCARS(MersenneTwisterFast random, Simulation sim) {
int TAU = 60;

Check failure on line 130 in src/arcade/patch/agent/cell/PatchCellCARTCombinedCombinatorial.java

View workflow job for this annotation

GitHub Actions / checkstyle

[checkstyle] src/arcade/patch/agent/cell/PatchCellCARTCombinedCombinatorial.java#L130 <com.puppycrawl.tools.checkstyle.checks.naming.LocalVariableNameCheck>

Name 'TAU' must match pattern '^[a-z][a-zA-Z0-9]*$'.
Raw output
/github/workspace/./src/arcade/patch/agent/cell/PatchCellCARTCombinedCombinatorial.java:130:13: error: Name 'TAU' must match pattern '^[a-z][a-zA-Z0-9]*$'. (com.puppycrawl.tools.checkstyle.checks.naming.LocalVariableNameCheck)
double currentTime = sim.getSchedule().getTime();
int unboundSynNotch = synnotchs - boundSynNotch;

double expectedBindingEvents =
bindingConstant
/ (volume * 6.0221415e23 * 1e-15)
* unboundSynNotch
* boundCell.getSynNotchAntigens()
* contactFraction
* TAU;

int bindingEvents = poissonFactory.createPoisson(expectedBindingEvents, random).nextInt();

if (bindingEvents > 0) {
bindingHistory.addLast(new BindingEvent(currentTime, bindingEvents));
}
double expectedUnbindingEvents = unbindingConstant * boundSynNotch * TAU;
int unbindingEvents =
poissonFactory.createPoisson(expectedUnbindingEvents, random).nextInt();

boundSynNotch += bindingEvents;
boundSynNotch -= unbindingEvents;
boundCell.updateSynNotchAntigens(unbindingEvents, bindingEvents);

// model synnotch activation TF degradation
int ineffectiveBoundSynNotchs = 0;
// find all binding events that are older than the synNotchActivationDelay
Iterator<BindingEvent> it = bindingHistory.iterator();
while (it.hasNext()) {
BindingEvent e = it.next();
if (currentTime - e.timeStep >= synNotchActivationDelay) {
ineffectiveBoundSynNotchs += e.count;
// remove binding event from history if older than delay
it.remove();
}
}

boundSynNotch -= ineffectiveBoundSynNotchs;
synnotchs = Math.max(0, synnotchs - ineffectiveBoundSynNotchs);
}

/** A {@code PoissonFactory} object instantiates Poisson distributions. */
interface PoissonFactory {
/**
* Creates instance of Poisson.
*
* @param lambda the Poisson distribution lambda
* @param random the random number generator
* @return a Poisson distribution instance
*/
Poisson createPoisson(double lambda, MersenneTwisterFast random);
}

/**
* returns the poisson distribution.
*
* @param lambda the Poisson distribution lambda
* @param random the random number generator
* @return a Poisson distribution instance
*/
public double callPoisson(double lambda, MersenneTwisterFast random) {
return poissonFactory.createPoisson(lambda, random).nextInt();
}

/** resets bound target cell and unbinds from it. */
public void resetBoundCell() {
if (boundCell != null) {
boundCell.updateSynNotchAntigens(boundSynNotch, 0);
boundCell = null;
}
boundSynNotch = 0;
}

/** private class for tracking synnotch binding events. */
private static class BindingEvent {

/** timestamp for binding events. */
double timeStep;

/** number of binding events at this time step. */
int count;

/**
* Instantiates the binding event.
*
* @param timeStep simulation timestamp of binding event
* @param count number of binding events
*/
BindingEvent(double timeStep, int count) {
this.timeStep = timeStep;
this.count = count;
}
}
}
112 changes: 23 additions & 89 deletions src/arcade/patch/agent/cell/PatchCellCARTCombinedInducible.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,129 +2,63 @@

import java.util.logging.Logger;
import sim.engine.SimState;
import sim.util.Bag;
import sim.util.distribution.Poisson;
import ec.util.MersenneTwisterFast;
import arcade.core.env.location.Location;
import arcade.core.sim.Simulation;
import arcade.core.util.GrabBag;
import arcade.core.util.Parameters;
import arcade.patch.env.grid.PatchGrid;

public class PatchCellCARTCombinedInducible extends PatchCellCARTCombined {
/** Extension of {@link PatchCellCARTCombinedCombinatorial} for synnotch circuit. */
public class PatchCellCARTCombinedInducible extends PatchCellCARTCombinedCombinatorial {

/** Logger for this class. */
private static final Logger LOGGER =
Logger.getLogger(PatchCellCARTCombinedInducible.class.getName());
protected final double synNotchThreshold;
protected final double bindingConstant;
protected final double unbindingConstant;
protected final double carDegradationConstant;
public final int synnotchs;
public int boundSynNotch;
protected final int maxCars;
PoissonFactory poissonFactory;
private PatchCellTissue boundCell;

/**
* Creates a tissue {@code PatchCellSynNotch} agent. *
* Creates a tissue {@code PatchCellCARTCombinedInducible} agent. *
*
* @param location the {@link Location} of the cell
* @param container the cell container
* @param parameters the dictionary of parameters
*/
public PatchCellCARTCombinedInducible(
PatchCellContainer container, Location location, Parameters parameters) {
this(container, location, parameters, null);
}

/**
* Creates a T cell {@code PatchCellCARTCombinedInducible} agent. *
*
* @param container the cell container
* @param location the {@link Location} of the cell
* @param parameters the dictionary of parameters
* @param links the map of population links
*/
public PatchCellCARTCombinedInducible(
PatchCellContainer container, Location location, Parameters parameters, GrabBag links) {
super(container, location, parameters, links);
bindingConstant = parameters.getDouble("K_SYNNOTCH_ON");
unbindingConstant = parameters.getDouble("K_SYNNOTCH_OFF");
carDegradationConstant = parameters.getDouble("K_CAR_DEGRADE");
synnotchs = parameters.getInt("SYNNOTCHS");
synNotchThreshold = parameters.getDouble("SYNNOTCH_THRESHOLD") * synnotchs;
boundSynNotch = 0;
maxCars = cars;
cars = 0;
poissonFactory = Poisson::new;
}

public double callPoisson(double lambda, MersenneTwisterFast random) {
return poissonFactory.createPoisson(lambda, random).nextInt();
}

@Override
public void step(SimState simstate) {
if (boundCell == null) {
checkForBinding(simstate);
Simulation sim = (Simulation) simstate;
if (super.boundCell == null) {
super.checkForBinding(simstate);
} else {
calculateCARS(simstate.random);
calculateCARS(simstate.random, sim);
}
super.step(simstate);
}

private void calculateCARS(MersenneTwisterFast random) {
@Override
protected void calculateCARS(MersenneTwisterFast random, Simulation sim) {
int TAU = 60;

Check failure on line 57 in src/arcade/patch/agent/cell/PatchCellCARTCombinedInducible.java

View workflow job for this annotation

GitHub Actions / checkstyle

[checkstyle] src/arcade/patch/agent/cell/PatchCellCARTCombinedInducible.java#L57 <com.puppycrawl.tools.checkstyle.checks.naming.LocalVariableNameCheck>

Name 'TAU' must match pattern '^[a-z][a-zA-Z0-9]*$'.
Raw output
/github/workspace/./src/arcade/patch/agent/cell/PatchCellCARTCombinedInducible.java:57:13: error: Name 'TAU' must match pattern '^[a-z][a-zA-Z0-9]*$'. (com.puppycrawl.tools.checkstyle.checks.naming.LocalVariableNameCheck)
int unboundSynNotch = synnotchs - boundSynNotch;
double expectedBindingEvents =
bindingConstant
/ (volume * 6.0221415e23 * 1e-15)
* unboundSynNotch
* boundCell.getSynNotchAntigens()
* contactFraction
* TAU;
int bindingEvents = poissonFactory.createPoisson(expectedBindingEvents, random).nextInt();
double expectedUnbindingEvents = unbindingConstant * boundSynNotch * TAU;
int unbindingEvents =
poissonFactory.createPoisson(expectedUnbindingEvents, random).nextInt();

boundSynNotch += bindingEvents;
boundSynNotch -= unbindingEvents;
boundCell.updateSynNotchAntigens(unbindingEvents, bindingEvents);
super.calculateCARS(random, sim);
double n = 4.4;
int new_cars =
int newCars =
(int) (maxCars / (1 + Math.pow(synNotchThreshold, n) / Math.pow(boundSynNotch, n)));

cars = Math.max((int) (cars - (carDegradationConstant * cars * TAU)), new_cars);
}

/** A {@code PoissonFactory} object instantiates Poisson distributions. */
interface PoissonFactory {
/**
* Creates instance of Poisson.
*
* @param lambda the Poisson distribution lambda
* @param random the random number generator
* @return a Poisson distribution instance
*/
Poisson createPoisson(double lambda, MersenneTwisterFast random);
}

private void checkForBinding(SimState simstate) {
Simulation sim = (Simulation) simstate;
PatchGrid grid = (PatchGrid) sim.getGrid();

Bag allAgents = new Bag();
getTissueAgents(allAgents, grid.getObjectsAtLocation(location));
for (Location neighborLocation : location.getNeighbors()) {
Bag bag = new Bag(grid.getObjectsAtLocation(neighborLocation));
getTissueAgents(allAgents, bag);
}

if (allAgents.size() > 0) {
PatchCellTissue randomCell =
(PatchCellTissue) allAgents.get(simstate.random.nextInt(allAgents.size()));
if (randomCell.getSynNotchAntigens() > 0) {
boundCell = randomCell;
}
}
}

public void resetBoundCell() {
if (boundCell != null) {
boundCell.updateSynNotchAntigens(boundSynNotch, 0);
boundCell = null;
}
boundSynNotch = 0;
cars = Math.max((int) (cars - (carDegradationConstant * cars * TAU)), newCars);
}
}
Loading
Loading