package stoppers; import java.lang.*; import java.io.*; import main.BetterTokenizer; import main.Cell; import main.GeneralInput; import main.Model; /** A stopper that looks for a single cell with a high value of a Node, surrounded by cells with low values of that Node. The code in here borrows liberally from the Oscillating Stripe Stop. It should give the best score to a stable, non-oscillating single cell with a high value whose neighbors all have a low value for that Node. @author Eli @version 3/19/99 */ public class CellSurround2Stop extends SimpleStop { int nodeNum; float interval; int xPos, yPos; /** The threshold below which the concentration of a node is considered 0. This is used to say whether a cell has switched low. */ float lowThreshold; /** The threshold above which the concentration of a node is considered 1. This is used to say whether a cell has switched high. */ float highThreshold; /** Used to set the fade time of the fading average (which determines score from stopper) */ float averagingTime = 10; /** Set to true if center cell is > highThreshold and surrounding cells are < lowThreshold */ boolean patternGood = false; float lastCenterVal = 0, fadeAvg = 0; // No arg constructor for instantiating by name public CellSurround2Stop() { stopTime = 1; } public CellSurround2Stop(float stop_time) { stopTime = stop_time; } public boolean stop(float time) { // trivial reasons to return if(time < lastTime + interval) return false; if(time > stopTime) return true; fadeAvg -= fadeAvg / averagingTime; float center_val = model.cells[yPos * model.arrayWidth + xPos].getValue(nodeNum); if(center_val < highThreshold) fadeAvg += 1; fadeAvg += Math.abs(lastCenterVal - center_val) / averagingTime; lastCenterVal = center_val; float max_surround = checkBullseye(model.cells, time); if(max_surround > lowThreshold) fadeAvg += 1; score = fadeAvg; lastTime = time; return false; } /** Returns the maximum value of the target node in the surrounding cells. Also sets patternGood to true if center cell is above threshold, surrounding cells are below low threshold. */ public float checkBullseye(Cell [] cells, float time) { Cell cell = cells[yPos * model.arrayWidth + xPos]; float [] surround = new float[cell.neighbors.length]; float center_value = 0f; float surround_max = 0f; patternGood = true; for(int neighbor = 0; neighbor < cell.neighbors.length; neighbor++) { surround[neighbor] = cell.neighbors[neighbor].getValue(nodeNum); if(surround_max < surround[neighbor]) surround_max = surround[neighbor]; if(surround[neighbor] > lowThreshold) patternGood = false; } center_value = cell.getValue(nodeNum); if(center_value < highThreshold) patternGood = false; return surround_max; } public boolean didPass(float s) { return didPass(); } public boolean didPass() { if(score < Cutoff) return true; return patternGood; } public void reset() { super.reset(); patternGood = false; lastCenterVal = 0; fadeAvg = 0; } protected void loadParameter(String info, BetterTokenizer tokenizer) throws Exception { if(info.equals("Node")) { GeneralInput.nextToken(tokenizer); nodeNum = model.cells[0].getNodeNum(tokenizer.sval); } else if(info.equals("LowThreshold")) { GeneralInput.nextToken(tokenizer); lowThreshold = ((float)tokenizer.nval); } else if(info.equals("HighThreshold")) { GeneralInput.nextToken(tokenizer); highThreshold = ((float)tokenizer.nval); } else if(info.equals("AveragingTime")) { GeneralInput.nextToken(tokenizer); averagingTime = ((float)tokenizer.nval); } else if(info.equals("XPos")) { GeneralInput.nextToken(tokenizer); xPos = ((int)tokenizer.nval); } else if(info.equals("YPos")) { GeneralInput.nextToken(tokenizer); yPos = ((int)tokenizer.nval); } else if(info.equals("Interval")) { GeneralInput.nextToken(tokenizer); interval = (float)tokenizer.nval; } else super.loadParameter(info,tokenizer); } }