package stoppers; import java.lang.*; import java.io.*; import main.BetterTokenizer; import main.Cell; import main.GeneralInput; import main.Model; /** PulseStop.java Detects a square-wave-like pulse for a node. @author WJS */ public class PulseStop extends SimpleStop { private float interval=0.1f; private String node; private int pos=0; // matches array index private boolean above=true; private float threshold=0.25f; private float avgValue=0.0f; private float maxscore=1.0f; private float currentScore=0.0f; private boolean timeAvging=false; private float integral=0.0f; private boolean useFadingMemory=false; private float fadingMemory=0.0f; private int fadingMemoryPeriod=27; /** No arg constructor for instantiating by name */ public PulseStop() { stopTime = 1; } /** */ public PulseStop(float stop_time) { stopTime = stop_time; } /** */ public boolean stop(float time) { if(time < (lastTime + interval)) return false; float currentStep = time - lastTime; avgValue = 0; for(int i = 0; i < model.arrayHeight; i++) { avgValue += model.cells[(i*model.arrayWidth) + pos].nodePeek(node); } avgValue /= model.arrayHeight; if(above) { currentScore = maxscore * (1 - ((float)Math.pow(avgValue/threshold, 3) / (1 + (float)Math.pow(avgValue/threshold, 3)))); } else { currentScore = maxscore * ((float)Math.pow(avgValue/threshold, 3) / (1 + (float)Math.pow(avgValue/threshold, 3))); } if(useFadingMemory) { // not a real moving average, but shoud achieve the desired effect fadingMemory -= ((currentStep / fadingMemoryPeriod) * fadingMemory); fadingMemory += ((currentStep / fadingMemoryPeriod) * currentScore); score = fadingMemory; } else if(timeAvging) { integral += currentStep * currentScore; score = integral / time; } else score = currentScore; lastTime = time; if(time < stopTime) { return false; } else return true; } /** */ public void reset() { super.reset(); avgValue = 0f; fadingMemory = 0f; integral = 0f; currentScore = 0f; } /** */ protected void loadParameter(String info, BetterTokenizer tokenizer) throws Exception { if(info.equals("Node")) { GeneralInput.nextToken(tokenizer); node = tokenizer.sval; } else if(info.equals("Position")) { GeneralInput.nextToken(tokenizer); pos = ((int)tokenizer.nval-1); } // subtract 1 to make pos an array index else if(info.equals("OnOffThreshold")) { GeneralInput.nextToken(tokenizer); threshold = (float)tokenizer.nval; } else if(info.equals("MaxScore")) { GeneralInput.nextToken(tokenizer); maxscore = (float)tokenizer.nval; } else if(info.equals("Interval")) { GeneralInput.nextToken(tokenizer); interval = (float)tokenizer.nval; } else if(info.equals("Mode")) { GeneralInput.nextToken(tokenizer); if(tokenizer.sval.equals("Above")) above = true; else above = false; } else if(info.equals("Averaging")) { GeneralInput.nextToken(tokenizer); if(tokenizer.sval.equals("Entire")) timeAvging = true; else if(tokenizer.sval.equals("FadingMemory")) useFadingMemory = true; else if(tokenizer.sval.equals("None")) timeAvging = useFadingMemory = false; } else if(info.equals("ScorePeriod")) { GeneralInput.nextToken(tokenizer); fadingMemoryPeriod = (int)tokenizer.nval; timeAvging = false; useFadingMemory = true; } else super.loadParameter(info,tokenizer); } }