src/stats/CellNeighborList.js
import Stat from "./Stat.js"
import BorderPixelsByCell from "./PixelsByCell.js"
import CPM from "../models/CPM.js"
/** This stat computes a list of all cell ids of the cells that border to "cell" and
belong to a different cellid, also giving the interface length for each contact.
@experimental
@example
* let CPM = require("path/to/build")
*
* // Set up a CPM and manipulator
* let C = new CPM.CPM( [300,300], {
* T:20,
* torus:[false,false],
* J:[[0,20],[20,10]],
* V:[0,200],
* LAMBDA_V:[0,2]
* })
* let gm = new CPM.GridManipulator( C )
*
* // Seed a cells, run a little, then divide it
* gm.seedCell(1)
* for( let t = 0; t < 50; t++ ){
* C.timeStep()
* }
* gm.divideCell(1)
*
* // Get neighborlist
* console.log( C.getStat( CPM.CellNeighborList ) )
*/
class CellNeighborList extends Stat {
/** The set model function of CellNeighborList requires an object of type CPM.
@param {CPM} M The CPM to compute bordering cells for.*/
set model( M ){
if( M instanceof CPM ){
/** The CPM to compute borderpixels for.
@type {CPM} */
this.M = M
} else {
throw( "The stat CellNeighborList is only implemented for CPMs, where cellborderpixels are stored!" )
}
}
/** The getNeighborsOfCell method of CellNeighborList computes a list of all pixels
that border to "cell" and belong to a different cellid.
@param {CellId} cellid the unique cell id of the cell to get neighbors from.
@param {CellArrayObject} cellborderpixels object produced by {@link BorderPixelsByCell}, with keys for each cellid
and as corresponding value the border pixel indices of their pixels.
@returns {CellObject} a dictionairy with keys = neighbor cell ids, and
values = number of neighbor cellpixels at the border.
*/
getNeighborsOfCell( cellid, cellborderpixels ){
let neigh_cell_amountborder = { }
let cbp = cellborderpixels[cellid]
//loop over border pixels of cell
for ( let cellpix = 0; cellpix < cbp.length; cellpix++ ) {
//get neighbouring pixels of borderpixel of cell
let neighbours_of_borderpixel_cell = this.M.neigh( cbp[cellpix] )
//don't add a pixel in cell more than twice
//loop over neighbouring pixels and store the parent cell if it is different from
//cell, add or increment the key corresponding to the neighbor in the dictionairy
for ( let neighborpix of neighbours_of_borderpixel_cell ) {
let neighbor_id = this.M.pixt( neighborpix )
if (neighbor_id != cellid) {
neigh_cell_amountborder[neighbor_id] = neigh_cell_amountborder[neighbor_id]+1 || 1
}
}
}
return neigh_cell_amountborder
}
/** The compute method of CellNeighborList computes for each cell on the grid
a list of all pixels at its border that belong to a different cellid.
@returns {CellObject} a dictionairy with keys = cell ids, and
values = an object produced by {@link getNeighborsOfCell} (which has keys for each
neighboring cellid and values the number of contacting pixels for that cell).
*/
compute(){
let cellborderpixels = this.M.getStat( BorderPixelsByCell )
let neighborlist = {}
// the this.M.cellIDs() iterator returns non-background cellids on the grid.
for( let i of this.M.cellIDs() ){
neighborlist[i] = this.getNeighborsOfCell( i, cellborderpixels )
}
return neighborlist
}
}
export default CellNeighborList