Beispiel #1
0
  /**
   * \brief Examines all the agents within a voxel of the agent-grid, to determine if a swimming
   * agent is in contact with an agent in the biofilm
   *
   * <p>To determine if a swimming cell is near contact with the biofilm surface, the agent checks
   * the status of the agent grid voxel it resides within. If this is 1, this is noted as having
   * agents within it that are within the biofilm structure. The agent now examines how close it is
   * to each of these agents. If within a certain distance (radius + stickiness constant), then the
   * agent is deemed to have adhered to the structure. Any overlap will be addressed during shoving
   * analysis. If not, the agent will perform another move.
   *
   * @author Kieran Alden
   * @param gridIndex The index of the agent grid to be checked
   * @param distanceSeekingAgent The distance within which two cells are deemed to be in contact
   * @return Boolean noting whether the agent is in contact with an agent in the biofilm
   */
  public Boolean isAgentInContactWithAgentInBiofilm(int gridIndex, double distanceSeekingAgent) {
    LocatedGroup agentsInGrid = currentSimulator.agentGrid.returnGroupInVoxel(gridIndex);

    Double dist = 0.0;
    // Now iterate through each one. If we're close enough, move done.
    // Shoving can then sort out distance between the two cells.
    for (LocatedAgent aLoc : agentsInGrid.group)
      dist = aLoc.getLocation().distance(swimmingAgentPosition);
    if (dist <= distanceSeekingAgent) return true;
    // If not, we'll do another move.
    return false;
  }
Beispiel #2
0
  /**
   * \brief On agent division, divides the mass between the old and new agent, at a specified
   * fraction
   *
   * <p>On agent division, divides the mass between the old and new agent, at a specified fraction
   *
   * @param baby The new agent, which is inheriting mass
   * @param babyMassFrac The fraction of this agents mass that should be transferred to the new
   *     agent
   */
  public void divideCompounds(LocatedAgent baby, double babyMassFrac) {
    // Choose the division plan and apply position modifications
    for (int i = 0; i < particleMass.length; i++) {
      baby.particleMass[i] *= babyMassFrac;
      this.particleMass[i] *= 1 - babyMassFrac;
    }

    // Update radius, mass, volumes and growth rates
    updateSize();
    baby.updateSize();

    updateGrowthRates();
    baby.updateGrowthRates();
  }
Beispiel #3
0
  /**
   * \brief Create a new agent in a specified position
   *
   * <p>Create a new agent in a specified position
   *
   * @param position Vector stating where this agent should be located
   */
  public void createNewAgent(ContinuousVector position) {
    try {
      // Get a clone of the progenitor
      LocatedAgent baby = (LocatedAgent) sendNewAgent();
      baby.giveName();

      // randomize its mass
      baby.mutatePop();

      baby.updateSize();

      this._myDivRadius = getDivRadius();
      baby._myDivRadius = getDivRadius();
      baby._myDeathRadius = getDeathRadius();

      // Just to avoid to be in the carrier
      position.x += this._totalRadius;

      baby.setLocation(position);

      baby.registerBirth();

    } catch (CloneNotSupportedException e) {
      utils.LogFile.writeLog("Error met in LocAgent:createNewAgent()");
    }
  }
Beispiel #4
0
  /**
   * \brief Pulling : The movement of agents by a shrinking biofilm. Move calculated and added to
   * the agents movement vector.
   *
   * <p>The movement of agents by a shrinking biofilm. Move calculated and added to the agents
   * movement vector.
   *
   * @param aNeighbor Reference to the potentially shoving neighbour
   * @param isMutual Whether movement is shared between two agents or applied only to this one
   * @param gain Double noting change in position
   * @return Boolean stating whether pulling is detected (true) or not (false)
   */
  public boolean addSpringMovement(LocatedAgent aNeighbor, boolean isMutual, double gain) {
    double d, distance, delta;

    if (aNeighbor == this) return false;

    // Build the escape vector and find the distance between you and your
    // neighbourhood
    d = computeDifferenceVector(_location, aNeighbor._location);

    _diff.normalizeVector();

    distance = getShoveRadius() + aNeighbor.getShoveRadius();
    distance += getSpeciesParam().shoveLimit;

    delta = d - distance;
    double lMax = _totalRadius;

    if (delta > 0) gain *= Math.exp(-delta * 5 / (lMax));
    if (delta > lMax) gain = 0;

    /* Apply shoving _________________________________________________ */

    if (isMutual) {
      _diff.times(-0.5 * delta * gain);
      this._movement.add(_diff);
      aNeighbor._movement.subtract(_diff);
    } else {
      _diff.times(-delta * gain);
      this._movement.add(_diff);
    }

    return (_movement.norm() > _radius * gain);
  }
Beispiel #5
0
  /**
   * \brief Mutual shoving : The movement by shoving of an agent is calculated based on the cell
   * overlap and added to the agents movement vector.
   *
   * <p>Mutual shoving : The movement by shoving of an agent is calculated based on the cell overlap
   * and added to the agents movement vector. Both agents are moved of half the overlapping distance
   * in opposite directions.
   *
   * @param aNeighbour Reference to the potentially shoving neighbour
   * @param isMutual Whether movement is shared between two agents or applied only to this one
   * @param gain Double noting change in position
   * @return Boolean stating whether shoving is detected (true) or not (false)
   */
  public boolean addPushMovement(LocatedAgent aNeighbour, boolean isMutual, double gain) {
    double d, distance;

    if (aNeighbour == this) return false;

    // Build the escape vector and find the distance between you and your
    // neighbourhood
    d = computeDifferenceVector(_location, aNeighbour._location);

    _diff.normalizeVector();

    // Compute effective cell-cell distance
    distance = getShoveRadius() + aNeighbour.getShoveRadius();
    distance += getSpeciesParam().shoveLimit;
    distance = d - distance;

    /* Apply shoving _________________________________________________ */

    // Compute shoving distance for the current agent
    if (distance <= 0) {
      if (isMutual) {
        _diff.times(gain * 0.5 * Math.abs(distance));
        this._movement.add(_diff);
        aNeighbour._movement.subtract(_diff);
      } else {
        _diff.times(Math.abs(gain * distance));
        this._movement.add(_diff);
      }
      return true;
    } else {
      return false;
    }
  }
Beispiel #6
0
  /**
   * \brief Used in 'one-time' attachment scenarios, where clones of the progenitor are created in
   * the birth area of the substratum.
   *
   * @param spRoot The XML mark-up group for a particular species being created.
   */
  public void createPop(XMLParser spRoot) {
    int howMany = spRoot.getAttributeInt("number");
    if (howMany <= 0) return;

    // Define the birth area - this is taken from the coordinates tags in the protocol file
    // (Nov13) OR if an initial area is not declared, this is the whole Y and Z of the domain with a
    // height of 1.
    ContinuousVector[] _initArea = defineSquareArea(spRoot);
    // Create all the required agents
    ContinuousVector cc = new ContinuousVector();

    for (int i = 0; i < howMany; i++)
      if (_progenitor instanceof LocatedAgent) {
        // Set coordinates within the birth area - randomly
        if (!Simulator.isChemostat) shuffleCoordinates(cc, _initArea);

        // Create the agent at these coordinates
        ((LocatedAgent) _progenitor).createNewAgent(cc);
      } else _progenitor.createNewAgent();

    LogFile.writeLog(
        howMany
            + " agents of species "
            + speciesName
            + " for one-time attachment successfully created");
  }
Beispiel #7
0
  /**
   * \brief Find a sibling of this agent
   *
   * <p>Find a sibling of this agent
   *
   * @param indexSpecies The index used to reference this species in the simulation dictionary
   */
  public void findCloseSiblings(int indexSpecies) {
    int nNb;
    boolean test;
    double shoveDist;
    LocatedAgent aNb;

    getPotentialShovers(getInteractDistance());
    nNb = _myNeighbors.size();

    for (int iNb = 0; iNb < nNb; iNb++) {
      aNb = _myNeighbors.removeFirst();
      // test EPS-species
      test = (indexSpecies == aNb.speciesIndex);

      // Test distance
      shoveDist = 2 * (getShoveRadius() + aNb.getShoveRadius());
      test = test && computeDifferenceVector(_location, aNb.getLocation()) <= shoveDist;

      if (test & aNb != this) _myNeighbors.addLast(aNb);
    }
  }
Beispiel #8
0
  /**
   * \brief With it determined that cell division will occur, create a new agent from the existing
   * one
   *
   * <p>With it determined that cell division will occur, create a new agent from the existing one
   *
   * @throws CloneNotSupportedException Thrown if the agent cannot be cloned
   */
  public void makeKid() throws CloneNotSupportedException {

    // Create the new instance
    LocatedAgent baby = (LocatedAgent) sendNewAgent();
    // Note that mutateAgent() does nothing yet
    baby.mutateAgent();

    this._myDivRadius = getDivRadius();
    baby._myDivRadius = getDivRadius();
    baby._myDeathRadius = getDeathRadius();

    // Update the lineage
    recordGenealogy(baby);

    // Share mass of all compounds between two daughter cells and compute
    // new size
    divideCompounds(baby, getBabyMassFrac());
    // sonia:chemostat
    if (Simulator.isChemostat) {
      // upon division the daughter cells remain with the coordinates of their progenitor

    } else {
      // Compute movement to apply to both cells
      setDivisionDirection(getInteractDistance(baby) / 2);

      // move both daughter cells
      baby._movement.subtract(_divisionDirection);
      _movement.add(_divisionDirection);
    }
    // Now register the agent inside the guilds and the agent grid
    baby.registerBirth();
    baby._netVolumeRate = 0;
  }
Beispiel #9
0
  /**
   * \brief On agent division, transfers EPS between the old and new agent, at a specified ratio
   *
   * <p>On agent division, transfers EPS between the old and new agent, at a specified ratio
   *
   * @param baby The new agent, which is inheriting mass
   * @param splitRatio The ratio of the EPS that should be transferred to the new agent
   */
  public void transferCompounds(LocatedAgent baby, double splitRatio) {
    // Choose the division plan and apply position modifications
    double m;
    for (int i = 0; i < particleMass.length; i++) {
      m = this.particleMass[i] * splitRatio;
      baby.particleMass[i] += m;
      this.particleMass[i] = this.particleMass[i] - m;
    }

    // Update radius, mass and volumes
    updateSize();
    baby.updateSize();
  }
Beispiel #10
0
  @SuppressWarnings("unchecked")
  /**
   * \brief Creates a daughter Located Agent by cloning this agent and parameter objects
   *
   * <p>Creates a daughter Located Agent by cloning this agent and parameter objects
   *
   * @throws CloneNotSupportedException Thrown if the agent cannot be cloned
   */
  public Object clone() throws CloneNotSupportedException {
    LocatedAgent o = (LocatedAgent) super.clone();

    o._location = (ContinuousVector) this._location.clone();
    o._movement = (ContinuousVector) this._movement.clone();
    o._divisionDirection = (ContinuousVector) this._divisionDirection.clone();
    o._myNeighbors = (LinkedList<LocatedAgent>) this._myNeighbors.clone();

    o._agentGridIndex = this._agentGridIndex;

    return (Object) o;
  }
Beispiel #11
0
 /**
  * \brief Return the shoving interaction distance to be used in shoving against a specified agent
  *
  * <p>Return the shoving interaction distance to be used in shoving against a specified agent
  *
  * @return Double specifying the shoving interaction distance that will be applied
  */
 public double getInteractDistance(LocatedAgent baby) {
   return getShoveRadius() + baby.getShoveRadius() + ((LocatedParam) _speciesParam).shoveLimit;
 }
Beispiel #12
0
  /**
   * \brief For self-attachment scenarios, initialises agents on the boundary layer rather than
   * substrarum, and models their swim to the surface or biofilm
   *
   * <p>For self-attachment scenarios, the agents are initialised at the top of the boundary layer
   * rather than on the substratum. These agents then perform a 'run and tumble' motion until they
   * either attach to the substratum or forming biofilm. This method captures this behaviour for
   * cells that are created for a time step. Once this swimming action has been performed, the agent
   * is created at its final position. Note that input of agents onto the boundary layer is decided
   * by a parameter set in the protocol file, cellAttachmentFrequency, measured in hours. The number
   * of cells is adjusted to suit the global time step that is being used. Also note that this
   * injection of cells can be for a set period (specified in the protocol file as parameter
   * cellInjectionPeriod), or can be stopped and started (modelling a 'settling' period) using
   * parameters cellInjectionOffPeriod and cellInjectionStopHour. This is explained in detail in the
   * tutorial for version 1.2 of iDynoMiCS.
   *
   * @param spRoot The Species markup from the protocol file for one particular species being
   *     initialised
   * @param numberAttachedInjectedAgents The number of agents of this type that need to be created
   *     in this global timestep
   */
  public void createBoundaryLayerPop(XMLParser spRoot, int numberAttachedInjectedAgents) {
    LogFile.writeLog(
        "\t\tAttempting to create "
            + numberAttachedInjectedAgents
            + " agents of "
            + speciesName
            + " in the boundary layer");
    // Create all the required agents

    // Note that this continues UNTIL THE DESIRED NUMBER OF CELLS HAVE ATTACHED SOMEWHERE
    // Just out of interest, I've decided to keep a count of how many cells are required for this to
    // happen
    int totalNumberOfInjectedAgents = 0;
    int agentsReturnedToBulk = 0;
    int requiredNumAttachedAgents = numberAttachedInjectedAgents;

    // Temporary DiscreteVector to make finding the boundary layer tidier.
    DiscreteVector dV = new DiscreteVector();

    while (numberAttachedInjectedAgents > 0) {
      totalNumberOfInjectedAgents++;

      if (_progenitor instanceof LocatedAgent) {
        swimmingAgentPosition.reset();

        // Now to choose coordinates for this particular agent
        while (true) {
          // This cell needs to take a random location in the Z and Y
          // directions. The X will come from the position of the
          // boundary layer on those axes. Generate these randomly.
          swimmingAgentPosition.y = ExtraMath.getUniRandDbl() * domain.length_Y;
          if (domain.is3D) {
            swimmingAgentPosition.z = ExtraMath.getUniRandDbl() * domain.length_Z;
          }
          // Now to work out the X coordinate. This is based on where
          // the top of the boundary layer is when this agent is
          // created. The top of the boundary layer is calculated in
          // Domain at each step. Now the resolution differs (this is
          // in nI x nJ x nK rather than microns - so this will need
          // to be converted accordingly. Method to calculate this:
          // - get the value from the top of the boundary layer
          // - reduce by 1 (such that the micron value will be the
          // 						 top of the layer)
          // - multiply by resolution of this domain.
          dV.set(swimmingAgentPosition, domain._resolution);
          if (!domain.is3D) dV.k = 1;
          swimmingAgentPosition.x = domain._topOfBoundaryLayer[dV.j][dV.k] - 1.0;

          swimmingAgentPosition.x *= domain._resolution;
          // Check this is ok.
          // System.out.println("Trying starting position "+dV.toString()+" =>
          // "+this.swimmingAgentPosition.toString());
          if (domain.testCrossedBoundary(swimmingAgentPosition) == null) break;
        }

        // Now we can do the run and tumble motion of these cells

        int cellRunResult = performRunAndTumble(spRoot);

        // If increment the relevant counters, as these may be useful
        switch (cellRunResult) {
          case 1: // Successfully Attached
            numberAttachedInjectedAgents--;
            // Create the agent at these coordinates
            ((LocatedAgent) _progenitor).createNewAgent(this.swimmingAgentPosition);
            // System.out.println("Cell "+swimmingAgentPosition.toString()+" attached");
            break;
          case 2:
            // System.out.println("Cell at "+swimmingAgentPosition.toString()+" returned to bulk");
            agentsReturnedToBulk++;
            break;
        }
      } else {
        // If this isn't a located species, just create a new agent.
        _progenitor.createNewAgent();
      }
    }
    // Write the stats to the log file incase of interest
    LogFile.writeLog(
        requiredNumAttachedAgents
            + " agents of species "
            + speciesName
            + " for self-attachment successfully created");
    LogFile.writeLog(
        totalNumberOfInjectedAgents + " agents of species " + speciesName + " attempted to attach");
    LogFile.writeLog(
        agentsReturnedToBulk + " agents of species " + speciesName + " returned to the bulk");
  }