package stoppers; import java.lang.*; import java.io.*; import main.BetterTokenizer; import main.Cell; import main.GeneralInput; import main.Model; /** Specially made stopping class for exploring switching behavior in the neurogenic network. The idea behind this stopper is that the AC/SC switch ought to through two neighboring cells in opposite directions, assuming they start at different concentrations. So the second and third cell in the second row are assumed to be a lower and higher init concentration cell respectively. Then the stopper looks to see if the higher cell ends up above the high threshold and the lower cell ends below the low threshold. Also, since this should occur because of the switching and not just because they started on either side of some threshold, the fifth cell in the row is assumed to start at the low init concentration and the whole thing is only a success if cell 2 = low, cell 3 = high, cell 5 = high. */ public class NeuroNoiseStop extends SimpleStop { int nodeNum; /** 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; float interval; int firstGoodRow, lastGoodRow, numSkippedRows, thresholdRow; float lastScoreTime = 0; // No arg constructor for instantiating by name public NeuroNoiseStop() { this(1); } public NeuroNoiseStop(float stop_time) { stopTime = stop_time; } public void init(Model model) { super.init(model); score = 0; } public boolean stop(float time) { // trivial reasons to return if(time < lastTime + interval) return false; if(time > stopTime) return true; // The following code assumes that each row of cells contains a low cell second // from the left and a high cell third from left. // It also assumes that the 5th cell in each row is a control cell firstGoodRow = lastGoodRow = -1; numSkippedRows = 0; thresholdRow = -1; float timestep_score = 0; // Assuming every other row has active cells for(int row = 1; row < model.arrayHeight; row += 2) { int cell_num = row * model.arrayWidth; float low_val = model.cells[cell_num + 1].getValue(nodeNum); float high_val = model.cells[cell_num + 2].getValue(nodeNum); float control_val = model.cells[cell_num + 4].getValue(nodeNum); timestep_score += (1 - (high_val - low_val)) / (model.arrayHeight / 2); if(low_val < lowThreshold && high_val > highThreshold) { if(firstGoodRow < 0) { firstGoodRow = (row - 1) / 2; lastGoodRow = (row - 1) / 2; } else { numSkippedRows += (row - 1) / 2 - lastGoodRow - 1; lastGoodRow = (row - 1)/2; } } if(thresholdRow < 0 && control_val > highThreshold) thresholdRow = (row - 1)/2; } score *= lastScoreTime; score += (time - lastScoreTime) * timestep_score; score /= time; if(score < 0) { score = score; } lastScoreTime = time; return false; // Only stop when run out of time } public boolean didPass(float s) { return didPass(); } public boolean didPass() { if(score < Cutoff) return true; for(int row = 1; row < model.arrayHeight; row += 2) { int cell_num = row * model.arrayWidth; float low_val = model.cells[cell_num + 1].getValue(nodeNum); float high_val = model.cells[cell_num + 2].getValue(nodeNum); float control_val = model.cells[cell_num + 4].getValue(nodeNum); if(low_val > lowThreshold || high_val < highThreshold || control_val < highThreshold) return false; } return true; } public void reset() { score = 0; lastScoreTime = 0; super.reset(); } public void saveOutputTags(PrintWriter ps, String inset) { super.saveOutputTags(ps, inset); ps.println(inset + "&FirstGoodRow\tnumber"); ps.println(inset + "&LastGoodRow\tnumber"); ps.println(inset + "&NumSkippedRows\tnumber"); ps.println(inset + "&ThresholdRow\tnumber"); } public void saveOutput(PrintWriter ps, String inset) { super.saveOutput(ps, inset); ps.println(inset + "&FirstGoodRow\t" + firstGoodRow); ps.println(inset + "&LastGoodRow\t" + lastGoodRow); ps.println(inset + "&NumSkippedRows\t" + numSkippedRows); ps.println(inset + "&ThresholdRow\t" + thresholdRow); } 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("Interval")) { GeneralInput.nextToken(tokenizer); interval = ((float)tokenizer.nval); } else super.loadParameter(info,tokenizer); } }