001    /**
002     * Created by IntelliJ IDEA.
003     * User: Wei Wang
004     * Date: Apr 16, 2003
005     * Time: 9:56:12 PM
006     */
007    
008    package EVolve.util.phasedetectors;
009    
010    import java.awt.Component;
011    import java.util.ArrayList;
012    
013    import javax.swing.JLabel;
014    import javax.swing.JTextField;
015    
016    import EVolve.Scene;
017    import EVolve.util.HelperFuncs;
018    import EVolve.util.equators.Set;
019    import EVolve.util.equators.UnorderedUnlimitedSet;
020    import EVolve.util.settings.PhaseDetectorSetting;
021    import EVolve.visualization.XYViz.XYVisualization;
022    
023    
024    
025    
026    public class HotspotPhaseDetector extends PhaseDetector{
027        private final byte graduateChange = 0x0000, notChange = 0x0001, empty = 0x0002;
028        private byte status[];
029        private int noiseTolerance, sampleSize;
030        private float threshold;
031        private final String configName = "hotspot_detector";
032    
033        private UnorderedUnlimitedSet workingSet;
034    
035        private JTextField[] contents;
036        private String[] tags;
037    
038        public HotspotPhaseDetector(XYVisualization visual) {
039            super(visual);
040            workingSet = new UnorderedUnlimitedSet();
041            data.add(workingSet);
042    
043            threshold = (float)0.8;
044            noiseTolerance = 2;
045            sampleSize = 1;
046    
047    
048            tags = new String[3];
049            tags[0] = "[Noise tolerance (intervals)]";
050            tags[1] = "[Threshold]";
051            tags[2] = "[Sample]";
052    
053            JTextField textUpperThreshold, textNoiseTolerance;
054            JTextField textSampleSize;
055            contents = new JTextField[3];
056            contents[0] = textNoiseTolerance = new JTextField();
057            contents[0].setColumns(2);
058    
059            contents[1] = textUpperThreshold = new JTextField();
060            contents[1].setColumns(3);
061    
062            contents[2] = textSampleSize = new JTextField();
063            contents[2].setColumns(2);
064    
065            textUpperThreshold.setText(String.valueOf(threshold));
066            textUpperThreshold.setToolTipText("Match threshold, from 0-1");
067            textSampleSize.setText(String.valueOf(sampleSize));
068            textSampleSize.setToolTipText("Take how many previous intervals as a sample set");
069            textNoiseTolerance.setText(String.valueOf(noiseTolerance));
070            textNoiseTolerance.setToolTipText("Noise tolerance");
071            refreshDetectorParameters();
072        }
073    
074        public void reset() {
075            super.reset();
076            workingSet = new UnorderedUnlimitedSet();
077            data.add(workingSet);
078        }
079    
080        public String getName() {
081            return "Hotspot Detector";
082        }
083    
084        protected void refreshDetectorParameters() {
085            //PhaseDetectorSetting setting = PhaseDetectorSetting.v();
086            //setting.readDataFromFile(tags, contents, configName);
087            try {
088                noiseTolerance = Integer.parseInt(contents[0].getText());
089                threshold = Float.parseFloat(contents[1].getText());
090                sampleSize = Integer.parseInt(contents[2].getText());
091            } catch (NumberFormatException e) {
092                Scene.showErrorMessage("Format of detector configuration file is incorrect.");
093                return;
094            }
095        }
096    
097        protected ArrayList autoDetectPhase() {
098            ArrayList returnVal = new ArrayList();
099    
100            refreshDetectorParameters();
101    
102            HelperFuncs.stop = -1;
103    
104            if (sampleSize<=0) return returnVal;
105    
106            status = new byte[data.size()];
107            float[] rates = new float[data.size()];
108    
109            for (int iteration = 0; iteration < sampleSize; iteration++) {
110                for (int i=iteration; i<data.size(); i=i+sampleSize) {
111                    if (i<sampleSize) continue;
112    
113                    float rate = parse(i);
114                    rates[i] = rate;
115                    if (rate >= 0) {
116                        byte currentStatus = (rate >= threshold) ? notChange : graduateChange;
117                        status[i] = currentStatus;
118                    } else {
119                        status[i] = empty;
120                    }
121                }
122    
123            }
124    
125            int previous = status[0], noise = 1;
126            for (int i=1; i<status.length; i++) {
127                if (status[i] != previous) {
128                    noise ++;
129                    if (noise > noiseTolerance) {
130                        if (previous == graduateChange)
131                            returnVal.add(new Integer(i-noise));
132                        else
133                            returnVal.add(new Integer(i-noise+1));
134                        noise = 0;
135                        previous = status[i];
136                    }
137                } else {
138                    noise = 0;
139                }
140            }
141    
142            //****************************** logging begins *********************
143            System.out.println("Logging ....");
144            System.out.println("===============================================");
145            for (int i=0; i<status.length/10; i++) {
146                System.out.print(""+i*10+"-"+(i*10+9)+":");
147                for (int j=0; j<10; j++) {
148                    System.out.print(status[i*10+j]+",");
149                }
150                System.out.println("");
151                System.out.print(""+i*10+"-"+(i*10+9)+":");
152                for (int j=0; j<10; j++) {
153                    System.out.print(rates[i*10+j]+",");
154                }
155                System.out.println("");
156            }
157            System.out.print(""+(status.length/10)*10+"-"+(status.length)+":");
158            for (int i=(status.length/10)*10; i<status.length; i++) {
159                System.out.print(status[i]+",");
160            }
161            System.out.println("");
162            for (int i=(status.length/10)*10; i<status.length; i++) {
163                System.out.print(rates[i]+",");
164            }
165            System.out.println("");
166            //****************************** logging ends *********************
167    
168            return returnVal;
169        }
170    
171        public Component[] createDetectorParamsControls() {
172            Component returnVal[] = new Component[tags.length+contents.length];
173    
174            for (int i=0; i<tags.length; i++) {
175                String prompt = tags[i].substring(1,tags[i].length()-1) + ": ";
176                returnVal[i*2] = new JLabel(prompt);
177                returnVal[i*2+1] = contents[i];
178            }
179    
180            return returnVal;
181        }
182    
183        public void collectData(long xMappedId, long yMappedId) {
184            int x = (int)(xMappedId/interval);
185    
186            if (x >= data.size()) {
187                workingSet = new UnorderedUnlimitedSet();
188                while (data.size() < x) {
189                    data.add(workingSet);
190                    workingSet = new UnorderedUnlimitedSet();
191                }
192                data.add(workingSet);
193            } /*else {
194                workingSet = (UnorderedUnlimitedSet)data.get(x);
195            }*/
196    
197            workingSet.addElement(yMappedId);
198        }
199    
200        public void saveSetting() {
201            PhaseDetectorSetting.v().save(tags,contents,configName);
202        }
203    
204        public void triggerPhases(int noiseTolerance, float threshold, boolean append) {
205            PhaseEntityTrigger trigger = new PhaseEntityTrigger();
206            ArrayList triggered = trigger.gatherTiggeredPhase(data, noiseTolerance, threshold);
207    
208            if (triggered.size() == 0) {
209                Scene.showErrorMessage("No phase triggered.");
210            } else {
211                undoRedo.registerAction(triggered,PhaseUndoRedo.triggeredPhases,append);
212            }
213            undoRedo.update();
214        }
215    
216        public void entitySetPhases(int noiseTolerance, float threshold, boolean append) {
217            PhaseEntitySet entitySet = new PhaseEntitySet();
218            ArrayList sets = entitySet.gatherTiggeredPhase(data, noiseTolerance, threshold);
219    
220            if (sets.size() == 0) {
221                Scene.showErrorMessage("No phase triggered.");
222            } else {
223                undoRedo.registerAction(sets,PhaseUndoRedo.entitySetPhases,append);
224            }
225            undoRedo.update();
226        }
227    
228        private float parse(int checkPoint) {
229    
230            float match = 0;
231    
232            if (checkPoint == 0) return 0;
233            //************** debugging
234            if ((HelperFuncs.inDebug)) {
235                HelperFuncs.getDebugNo();
236            }
237            if (checkPoint == HelperFuncs.stop) {
238                int qq = 0;
239                qq++;
240            }
241            //************** debugging
242            UnorderedUnlimitedSet previous, current;
243    
244            current = (UnorderedUnlimitedSet)data.get(checkPoint);
245            for (int j=checkPoint+1; j<checkPoint+sampleSize; j++) {
246                if (j>=data.size()) break;
247                current = (UnorderedUnlimitedSet)current.union((Set)data.get(j));
248            }
249            previous = (UnorderedUnlimitedSet)data.get(checkPoint - 1);
250            for (int j=checkPoint-2; j>=checkPoint-sampleSize; j--) {
251                previous = (UnorderedUnlimitedSet)previous.union((Set)data.get(j));
252            }
253            float unionSize = (float)previous.union(current).size();
254            if (unionSize != 0)
255                match = ((float)previous.intersection(current).size())/unionSize;
256            else
257                match = -1;
258    
259            return match;
260        }
261    
262    }