diff --git a/src/main/java/plugins/fab/MiceProfiler/MiceProfilerLabelAnalyser.java b/src/main/java/plugins/fab/MiceProfiler/MiceProfilerLabelAnalyser.java index cfea292485d842b927c2cc0e0ac0335b81a6537f..5bf07bc2f8661780c79009f4f8818960ec0b2731 100644 --- a/src/main/java/plugins/fab/MiceProfiler/MiceProfilerLabelAnalyser.java +++ b/src/main/java/plugins/fab/MiceProfiler/MiceProfilerLabelAnalyser.java @@ -18,1631 +18,25 @@ */ package plugins.fab.MiceProfiler; -import java.awt.BasicStroke; -import java.awt.BorderLayout; -import java.awt.Color; -import java.awt.Component; -import java.awt.Dimension; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.io.File; -import java.io.IOException; -import java.util.ArrayList; -import java.util.HashMap; - -import javax.swing.BoxLayout; -import javax.swing.ButtonGroup; -import javax.swing.JCheckBox; -import javax.swing.JCheckBoxMenuItem; -import javax.swing.JLabel; -import javax.swing.JMenu; -import javax.swing.JMenuBar; -import javax.swing.JMenuItem; -import javax.swing.JPanel; -import javax.swing.JRadioButton; -import javax.swing.JScrollPane; -import javax.swing.JTextField; - -import org.jfree.chart.ChartFactory; -import org.jfree.chart.ChartPanel; -import org.jfree.chart.JFreeChart; -import org.jfree.chart.plot.PlotOrientation; -import org.jfree.chart.plot.XYPlot; -import org.jfree.chart.renderer.xy.DeviationRenderer; -import org.jfree.data.xy.XYSeries; -import org.jfree.data.xy.XYSeriesCollection; -import org.jfree.data.xy.YIntervalSeries; -import org.jfree.data.xy.YIntervalSeriesCollection; - -import icy.file.xls.XlsManager; -import icy.gui.dialog.ActionDialog; -import icy.gui.dialog.SaveDialog; -import icy.gui.frame.IcyFrame; -import icy.gui.util.GuiUtil; -import icy.main.Icy; -import icy.plugin.abstract_.Plugin; -import icy.plugin.interface_.PluginBundled; -import icy.plugin.interface_.PluginImageAnalysis; -import icy.swimmingPool.SwimmingObject; -import icy.swimmingPool.SwimmingPoolEvent; -import icy.swimmingPool.SwimmingPoolListener; -import jmapps.ui.MessageDialog; -import jxl.format.Colour; +import icy.plugin.abstract_.PluginActionable; /** - * @author Fab - * Goal : extract graphs from animal pool. - * Take its source from the swimming pool. - * Can be multi instanced. + * Just for backward compatibility (plugin is now bundled in Mice Profiler Tracker) */ -public class MiceProfilerLabelAnalyser extends Plugin - implements PluginImageAnalysis, PluginBundled, SwimmingPoolListener, ActionListener +public class MiceProfilerLabelAnalyser extends PluginActionable { - - JPanel mainPanel = GuiUtil.generatePanel(); - IcyFrame icyFrame = GuiUtil.generateTitleFrame("Label Analyser", mainPanel, new Dimension(0, 0), true, true, true, - true); - - ArrayList<EventSelector> eventSelectorList = null; - JFreeChart chart; - XYSeriesCollection xyDataset = new XYSeriesCollection(); - YIntervalSeriesCollection yintervalseriescollection = new YIntervalSeriesCollection(); - - JTextField binSizeTextField = new JTextField("150"); - JTextField fpsTextField = new JTextField("15"); - JTextField totalTimeTextField = new JTextField("7200"); - ArrayList<AnimalPoolSelector> animalList = new ArrayList<AnimalPoolSelector>(); - IcyFrame graphFrame = new IcyFrame("graph", true, true, true, true); - // JCheckBox displayLegendCheckBox = new JCheckBox("display Legend", false); - JCheckBoxMenuItem displayLegendCheckBoxMenuItem = new JCheckBoxMenuItem("display Legend", true); - - // JButton extractDataToProbabilityGridButton = new JButton("Compute decision graph script"); - JMenuItem extractDataToProbabilityGridMenuItem = new JMenuItem("Compute decision graph script to console"); - JTextField extractDataToProbabilityTimeValue = new JTextField("150"); - // JButton extractCurrentDataGraphToExcelButton = new JButton("Export current graph to xls"); - - JMenuItem extractCurrentDataGraphToExcelMenuItem = new JMenuItem("Export current graph to xls"); - JMenuItem extractCurrentDataGraphWithAllLabelDensityToExcelMenuItem = new JMenuItem( - "Export graphs to xls (one per label-density)"); - // JButton extractAllDataToGraphAndExcel = new JButton("Export all datas (in pools) to xls"); - JMenuItem extractAllDataToGraphAndExcelMenuItem = new JMenuItem("Export all datas (in pools) to xls"); + final MiceProfilerLabelAnalyserInternal implementer; public MiceProfilerLabelAnalyser() { + super(); - // CHECK IF ANIMAL ARE LOADED IN SWIMMING POOL. IF NOT RETURN. - - animalList.clear(); - ArrayList<SwimmingObject> liste = Icy.getMainInterface().getSwimmingPool().getObjects(); - for (SwimmingObject so : liste) - { - if (so.getObject() instanceof Animal) - { - animalList.add(new AnimalPoolSelector((Animal) so.getObject())); - } - } - - if (animalList.size() == 0) - { - MessageDialog.createInfoDialog(null, "No animal loaded, please run VideoLabelMaker first."); - return; - } - - // END OF ANIMAL LOADED CHECK - - Icy.getMainInterface().getSwimmingPool().addListener(this); - - chart = ChartFactory.createXYLineChart("", "t", "y", yintervalseriescollection, PlotOrientation.VERTICAL, true, // true , - false, false); - - XYPlot xyplot = (XYPlot) chart.getPlot(); - xyplot.setInsets(new org.jfree.chart.ui.RectangleInsets(5D, 5D, 5D, 20D)); - xyplot.setBackgroundPaint(Color.lightGray); - xyplot.setAxisOffset(new org.jfree.chart.ui.RectangleInsets(5D, 5D, 5D, 5D)); - xyplot.setDomainGridlinePaint(Color.white); - xyplot.setRangeGridlinePaint(Color.white); - DeviationRenderer deviationrenderer = new DeviationRenderer(true, false); - for (int i = 0; i < 100; i++) - { - deviationrenderer.setSeriesStroke(i, new BasicStroke(3F, 1, 1)); - deviationrenderer.setSeriesStroke(i + 1, new BasicStroke(3F, 1, 1)); - deviationrenderer.setSeriesFillPaint(0, new Color(255, 200, 200)); - deviationrenderer.setSeriesFillPaint(1, new Color(200, 200, 255)); - deviationrenderer.setSeriesFillPaint(3, new Color(200, 255, 200)); - deviationrenderer.setSeriesFillPaint(2, new Color(255, 255, 200)); - } - xyplot.setRenderer(deviationrenderer); - - refreshData(); - - icyFrame.addToDesktopPane(); - icyFrame.pack(); - icyFrame.setSize(800, 600); - icyFrame.center(); - icyFrame.toFront(); - icyFrame.setVisible(true); - - graphFrame.addToDesktopPane(); - // graphFrame.center(); - graphFrame.setVisible(true); - icyFrame.toFront(); - - extractCurrentDataGraphToExcelMenuItem.addActionListener(this); - extractAllDataToGraphAndExcelMenuItem.addActionListener(this); - // displayLegendCheckBoxMenuItem.addActionListener( this ); - extractDataToProbabilityGridMenuItem.addActionListener(this); - extractCurrentDataGraphWithAllLabelDensityToExcelMenuItem.addActionListener(this); - - JMenuBar menuBar = new JMenuBar(); - JMenu menuExport = new JMenu("Export"); - menuExport.add(extractCurrentDataGraphToExcelMenuItem); - menuExport.add(extractAllDataToGraphAndExcelMenuItem); - menuExport.add(extractDataToProbabilityGridMenuItem); - menuExport.add(extractCurrentDataGraphWithAllLabelDensityToExcelMenuItem); - menuBar.add(menuExport); - - // JMenu menuGraph = new JMenu("Graph"); - // menuGraph.add( displayLegendCheckBoxMenuItem ); - // menuBar.add( menuGraph ); - - icyFrame.setJMenuBar(menuBar); - - } - - /** - * refresh graphs - * - * @param file - */ - void refreshGraph(boolean xlsExport, String file) - { - - XlsManager xls = null; - int cursorX = 0; - int cursorY = 1; - - if (xlsExport) - { - String saveFileName = file; - if (file == null) - { - saveFileName = SaveDialog.chooseFile("Export current graph to xls file", - System.getProperty("user.home"), "outputGraph.xls", ".xls"); - if (saveFileName == null) - return; - } - - try - { - xls = new XlsManager(new File(saveFileName)); - xls.createNewPage("Mice profiler graph export"); - - } - catch (IOException e) - { - - e.printStackTrace(); - } - } - - int binSize = Integer.parseInt(binSizeTextField.getText()); - int endFrame = Integer.parseInt(totalTimeTextField.getText()); - float fps = Float.parseFloat(fpsTextField.getText()); - - xyDataset.removeAllSeries(); - yintervalseriescollection.removeAllSeries(); - - // creation des series: - - // no pool - - for (EventSelector eventSelector : eventSelectorList) - { - - for (AnimalPoolSelector animalSelector : animalList) - { - - if (animalSelector.noPool.isSelected()) - { - - if (animalSelector.enable.isSelected()) - { - - if (eventSelector.nbEventCheckBox.isSelected()) - { - EventTimeLine eventTimeLine = animalSelector.animal.eventTimeLineList - .get(eventSelector.eventNumber); - String titreSerie = animalSelector.animal.animalName + " np Event Nb" - + eventTimeLine.criteriaName; - XYSeries seriesXY = new XYSeries(titreSerie); - - if (xlsExport) - { - cursorX++; - xls.setLabel(cursorX, 0, titreSerie); - cursorY = 1; - } - - YIntervalSeries yintervalseries = new YIntervalSeries( - animalSelector.animal.animalName + " np Event Nb" + eventTimeLine.criteriaName); - - for (int t = 0; t < endFrame; t += binSize) - { - double value = eventTimeLine.getNbEvent(t, t + binSize - 1); - yintervalseries.add(t / fps, value, value, value); - - if (xlsExport) - { - xls.setNumber(0, cursorY, t / fps); // legende - xls.setNumber(cursorX, cursorY, value); // valeur - cursorY++; - } - - } - yintervalseriescollection.addSeries(yintervalseries); - - } - - if (eventSelector.lengthCheckBox.isSelected()) - { - EventTimeLine eventTimeLine = animalSelector.animal.eventTimeLineList - .get(eventSelector.eventNumber); - XYSeries seriesXY = new XYSeries( - animalSelector.animal.animalName + " np Event l" + eventTimeLine.criteriaName); - - String titreSerie = animalSelector.animal.animalName + " np Event l" - + eventTimeLine.criteriaName; - YIntervalSeries yintervalseries = new YIntervalSeries(titreSerie); - - if (xlsExport) - { - cursorX++; - xls.setLabel(cursorX, 0, titreSerie); - cursorY = 1; - } - - for (int t = 0; t < endFrame; t += binSize) - { - double value = eventTimeLine.getLengthEvent(t, t + binSize - 1); - yintervalseries.add(t / fps, value, value, value); - - if (xlsExport) - { - xls.setNumber(0, cursorY, t / fps); // legende - xls.setNumber(cursorX, cursorY, value); // valeur - cursorY++; - } - - } - yintervalseriescollection.addSeries(yintervalseries); - - } - - // critere discret - if (eventSelector.displayDiscreteValueCheckBox.isSelected()) - { - EventTimeLine eventTimeLine = animalSelector.animal.eventTimeLineList - .get(eventSelector.eventNumber); - XYSeries seriesXY = new XYSeries( - animalSelector.animal.animalName + " dv Event " + eventTimeLine.criteriaName); - - String titreSerie = animalSelector.animal.animalName + " dv Event " - + eventTimeLine.criteriaName; - - YIntervalSeries yintervalseries = new YIntervalSeries(titreSerie); - - if (xlsExport) - { - cursorX++; - xls.setLabel(cursorX, 0, titreSerie); - cursorY = 1; - } - - for (int t = 0; t < endFrame; t += binSize) - { - - double value = eventTimeLine.getMeanValue(t, t + binSize - 1); - yintervalseries.add(t / fps, value, value, value); - - if (xlsExport) - { - xls.setNumber(0, cursorY, t / fps); // legende - xls.setNumber(cursorX, cursorY, value); // valeur - cursorY++; - } - - } - yintervalseriescollection.addSeries(yintervalseries); - - } - - // critere density - if (eventSelector.densityCheckBox.isSelected()) - { - - EventTimeLine eventTimeLine = animalSelector.animal.eventTimeLineList - .get(eventSelector.eventNumber); - XYSeries seriesXY = new XYSeries( - animalSelector.animal.animalName + " dv Density " + eventTimeLine.criteriaName); - - String titreSerie = animalSelector.animal.animalName + " dv Density " - + eventTimeLine.criteriaName; - - YIntervalSeries yintervalseries = new YIntervalSeries(titreSerie); - - if (xlsExport) - { - cursorX++; - xls.setLabel(cursorX, 0, titreSerie); - cursorY = 1; - } - - for (int t = 0; t < endFrame; t += binSize) - { - - double value = eventTimeLine.getDensity(t, t + binSize - 1); - - yintervalseries.add(t / fps, value, value, value); - - if (xlsExport) - { - xls.setNumber(0, cursorY, t / fps); // legende - xls.setNumber(cursorX, cursorY, value); // valeur - cursorY++; - } - - } - yintervalseriescollection.addSeries(yintervalseries); - - } - - } - } - } - - } - - updateGraphSeriesForPool(Criteria.NB_EVENT, 1, endFrame, binSize, xls, xlsExport); - updateGraphSeriesForPool(Criteria.LENGTH_EVENT, 1, endFrame, binSize, xls, xlsExport); - updateGraphSeriesForPool(Criteria.DISCRETE_VALUE, 1, endFrame, binSize, xls, xlsExport); - updateGraphSeriesForPool(Criteria.DENSITY_VALUE, 1, endFrame, binSize, xls, xlsExport); - updateGraphSeriesForPool(Criteria.NB_EVENT, 2, endFrame, binSize, xls, xlsExport); - updateGraphSeriesForPool(Criteria.LENGTH_EVENT, 2, endFrame, binSize, xls, xlsExport); - updateGraphSeriesForPool(Criteria.DISCRETE_VALUE, 2, endFrame, binSize, xls, xlsExport); - updateGraphSeriesForPool(Criteria.DENSITY_VALUE, 2, endFrame, binSize, xls, xlsExport); - - if (xlsExport) - { - // System.out.println( "xls debug: " + xls.getExcelPage() ); - xls.SaveAndClose(); - } - - } - - enum Criteria - { - NB_EVENT, LENGTH_EVENT, DISCRETE_VALUE, DENSITY_VALUE - } - - void updateGraphSeriesForPool(Criteria criteria, int pool, int endFrame, int binSize, XlsManager xls, - boolean xlsExport) - { - int cursorX = 1; - int cursorY = 0; - - float fps = Float.parseFloat(fpsTextField.getText()); - - boolean process = false; - for (AnimalPoolSelector animalSelector : animalList) - { - if ((pool == 1 && animalSelector.pool1.isSelected()) || (pool == 2 && animalSelector.pool2.isSelected())) - { - process = true; - } - } - - if (!process) - return; - - for (EventSelector eventSelector : eventSelectorList) - { - if ((criteria == Criteria.NB_EVENT && eventSelector.nbEventCheckBox.isSelected()) - || (criteria == Criteria.LENGTH_EVENT && eventSelector.lengthCheckBox.isSelected()) - || (criteria == Criteria.DISCRETE_VALUE && eventSelector.displayDiscreteValueCheckBox.isSelected()) - || (criteria == Criteria.DENSITY_VALUE && eventSelector.densityCheckBox.isSelected())) - { - - String chaine = "p" + pool + " " + criteria.toString(); - chaine += animalList.get(0).animal.eventTimeLineList.get(eventSelector.eventNumber).criteriaName; - XYSeries seriesXY = new XYSeries(chaine); - YIntervalSeries yintervalseries = new YIntervalSeries(chaine); - - if (xlsExport) - { - xls.createNewPage(chaine); - cursorX = 1; - } - - for (int t = 0; t < endFrame; t += binSize) - { - if (xlsExport) - { - xls.setLabel(cursorX, cursorY, "" + t + "-" + (t + binSize)); - cursorY++; - cursorY++; - - } - - // ROI3DArea r = new ROI3DArea( new Point3D.Double( 0,0,0 ) ); - - ArrayList<Double> listResultat = new ArrayList<Double>(); - - for (AnimalPoolSelector animalSelector : animalList) - { - - if ((pool == 1 && animalSelector.pool1.isSelected()) - || (pool == 2 && animalSelector.pool2.isSelected())) - { - - if (animalSelector.enable.isSelected()) - { - EventTimeLine eventTimeLine = animalSelector.animal.eventTimeLineList - .get(eventSelector.eventNumber); - - if (criteria == Criteria.NB_EVENT) - { - listResultat.add(eventTimeLine.getNbEvent(t, t + binSize - 1)); - - if (xlsExport) - { - xls.setNumber(cursorX, cursorY, eventTimeLine.getNbEvent(t, t + binSize - 1)); - cursorY++; - } - - } - if (criteria == Criteria.LENGTH_EVENT) - { - listResultat.add(eventTimeLine.getLengthEvent(t, t + binSize - 1)); - - if (xlsExport) - { - xls.setNumber(cursorX, cursorY, - eventTimeLine.getLengthEvent(t, t + binSize - 1)); - cursorY++; - } - - } - - if (criteria == Criteria.DISCRETE_VALUE) - { - listResultat.add(eventTimeLine.getMeanValue(t, t + binSize - 1)); - - if (xlsExport) - { - xls.setNumber(cursorX, cursorY, eventTimeLine.getMeanValue(t, t + binSize - 1)); - cursorY++; - } - - } - if (criteria == Criteria.DENSITY_VALUE) - { - listResultat.add(eventTimeLine.getDensity(t, t + binSize - 1)); - - if (xlsExport) - { - xls.setNumber(cursorX, cursorY, eventTimeLine.getDensity(t, t + binSize - 1)); - cursorY++; - } - - } - - } - } - } - - if (listResultat.size() != 0) - { - double[] resultatTab2 = new double[listResultat.size()]; - for (int i = 0; i < listResultat.size(); i++) - { - resultatTab2[i] = listResultat.get(i); - } - - double error = flanagan.analysis.Stat.standardDeviation(resultatTab2); - error = error / Math.sqrt(listResultat.size() - 1); - double mean = flanagan.analysis.Stat.mean(resultatTab2); - - yintervalseries.add(t / fps, mean, mean - (error), mean + (error)); - - if (xlsExport) - { - cursorY++; - xls.setNumber(cursorX, cursorY, mean); - } - - } - else - { - yintervalseries.add(t / fps, 0, 0, 0); - } - - cursorX++; - cursorY = 0; - } - - xyDataset.addSeries(seriesXY); - - yintervalseriescollection.addSeries(yintervalseries); - - } - } - } - - /** - * Refresh Datas - */ - private void refreshData() - { - - mainPanel.removeAll(); - - JPanel animalPoolListPanel = GuiUtil.generatePanel("Animal pool List"); - JPanel criteriaListPanel = GuiUtil.generatePanel("criteria List"); - - ArrayList<SwimmingObject> liste = Icy.getMainInterface().getSwimmingPool().getObjects(); - animalList.clear(); - - Animal animalToGetCriteria = null; - for (SwimmingObject so : liste) - { - if (so.getObject() instanceof Animal) - { - animalList.add(new AnimalPoolSelector((Animal) so.getObject())); - animalToGetCriteria = (Animal) so.getObject(); - } - } - - if (animalToGetCriteria == null) // there is no more animal in pool - { - return; - } - - for (AnimalPoolSelector animalSelector : animalList) - { - animalPoolListPanel.add(animalSelector.panel); - } - - mainPanel.add(GuiUtil.besidesPanel(new JLabel("Bin Size ( nb frames )"), binSizeTextField, - new JLabel("Total time to compute ( nb frames )"), totalTimeTextField)); - // mainPanel.add( GuiUtil.besidesPanel ( displayLegendCheckBox , extractAllDataToGraphAndExcelMenuItem , extractDataToProbabilityGridButton ) ); - // mainPanel.add( GuiUtil.besidesPanel ( displayLegendCheckBox , extractDataToProbabilityGridMenuItem ) ); - // mainPanel.add( GuiUtil.besidesPanel ( displayLegendCheckBoxMenuItem ) ); - - // mainPanel.add( GuiUtil.besidesPanel( new JLabel("time window forward:") , extractDataToProbabilityTimeValue , extractCurrentDataGraphToExcelMenuItem - // ) ); - mainPanel.add(GuiUtil.besidesPanel(new JLabel("time window forward:"), extractDataToProbabilityTimeValue)); - mainPanel.add(GuiUtil.besidesPanel(new JLabel("FPS:"), fpsTextField)); - - eventSelectorList = new ArrayList<EventSelector>(); - - for (EventTimeLine et : animalToGetCriteria.eventTimeLineList) - { - EventSelector eventSelector = new EventSelector(animalToGetCriteria.eventTimeLineList.indexOf(et), et); - eventSelectorList.add(eventSelector); - - criteriaListPanel.add(eventSelector.panel); - } - - JPanel parameterPanel = new JPanel(new BorderLayout()); - - JScrollPane animalPoolListScrollPane = new JScrollPane(animalPoolListPanel, - JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS); - JScrollPane criteriaListScrollPane = new JScrollPane(criteriaListPanel, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, - JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS); - - parameterPanel.add(animalPoolListScrollPane, BorderLayout.WEST); - parameterPanel.add(criteriaListScrollPane, BorderLayout.CENTER); - - mainPanel.add(parameterPanel); - - graphFrame.getContentPane() - .add(new ChartPanel(chart, 700, 200, 700, 200, 700, 700, false, false, true, true, true, true)); - graphFrame.pack(); - - refreshGraph(false, ""); - - mainPanel.updateUI(); - - } - - @Override - public void swimmingPoolChangeEvent(SwimmingPoolEvent swimmingPoolEvent) - { - - refreshData(); - - } - - @Override - public void compute() - { - - } - - class EventSelector implements ActionListener - { - JPanel panel = GuiUtil.generatePanelWithoutBorder(); - int eventNumber; - JCheckBox nbEventCheckBox = new JCheckBox("nb Event"); - JCheckBox lengthCheckBox = new JCheckBox("length"); - JCheckBox densityCheckBox = new JCheckBox("density"); - JLabel criteriaLabel; - JCheckBox displayDiscreteValueCheckBox = new JCheckBox("discrete Value"); - - public EventSelector(int eventNumber, EventTimeLine e) - { - this.eventNumber = eventNumber; - - int maxSizeString = e.criteriaName.length(); - if (maxSizeString > 40) - maxSizeString = 40; - - criteriaLabel = new JLabel(e.criteriaName.substring(0, maxSizeString)); - criteriaLabel.setToolTipText(e.criteriaName); - - if (e.timeLineCategory == TimeLineCategory.USE_BOOLEAN_EVENT) - { - panel.add(GuiUtil.besidesPanel(criteriaLabel, densityCheckBox, nbEventCheckBox, lengthCheckBox)); - } - - if (e.timeLineCategory == TimeLineCategory.USE_DISCRETE_EVENT) - { - panel.add(GuiUtil.besidesPanel(criteriaLabel, displayDiscreteValueCheckBox)); - } - - densityCheckBox.addActionListener(this); - nbEventCheckBox.addActionListener(this); - lengthCheckBox.addActionListener(this); - displayDiscreteValueCheckBox.addActionListener(this); - - } - - @Override - public void actionPerformed(ActionEvent e) - { - refreshGraph(false, ""); - } - - } - - class AnimalPoolSelector implements ActionListener - { - JPanel panel = GuiUtil.generatePanelWithoutBorder(); - Animal animal; - - JCheckBox enable = new JCheckBox("Enable", true); - JRadioButton pool1 = new JRadioButton("Pool 1"); - JRadioButton pool2 = new JRadioButton("Pool 2"); - JRadioButton noPool = new JRadioButton("no pool", true); - - ButtonGroup poolGroup = new ButtonGroup(); - ButtonGroup carecterizationGroup = new ButtonGroup(); - - public AnimalPoolSelector(Animal animal) - { - - this.animal = animal; - - enable.addActionListener(this); - pool1.addActionListener(this); - pool2.addActionListener(this); - noPool.addActionListener(this); - - poolGroup.add(pool1); - poolGroup.add(pool2); - poolGroup.add(noPool); - - int maxSizeString = animal.animalName.length(); - if (maxSizeString > 5) - maxSizeString = 5; - - enable.setText(animal.animalName.substring(0, maxSizeString)); - enable.setToolTipText(animal.animalName); - - panel.add(GuiUtil.besidesPanel(new Component[] { - - enable, pool1, pool2, noPool} - - )); - - } - - @Override - public void actionPerformed(ActionEvent e) - { - refreshGraph(false, ""); - } - } - - @Override - public void actionPerformed(ActionEvent e) - { - - refreshGraph(false, ""); - - if (e.getSource() == extractCurrentDataGraphToExcelMenuItem) - { - extractCurrentDataGraphToExcel(); - } - - if (e.getSource() == extractAllDataToGraphAndExcelMenuItem) - { - exportAllData(); - } - - if (e.getSource() == extractDataToProbabilityGridMenuItem) - { - extractDataToProbabilityGrid2(); - } - - if (e.getSource() == extractCurrentDataGraphWithAllLabelDensityToExcelMenuItem) - { - extractDataGraphWithAllLabelDensityToExcel(); - } - - } - - /** - * Extract all the data by selecting all the different criteria, one by one. - */ - private void extractDataGraphWithAllLabelDensityToExcel() - { - String saveFileName = SaveDialog.chooseFile("Save xls file", "", "Mice Profiler - "); - - if (saveFileName == null) - return; - - for (EventSelector eventSelector : eventSelectorList) - { - for (EventSelector eventSelector2 : eventSelectorList) // clear all check boxes - { - eventSelector2.densityCheckBox.setSelected(false); - } - - eventSelector.densityCheckBox.setSelected(true); - - String eventLabel = eventSelector.criteriaLabel.getText().replaceAll("[^a-zA-Z0-9\\._]+", "_"); - String fileName = saveFileName + " - " + eventLabel + ".xls"; - - refreshGraph(true, fileName); - } - - } - - private void extractCurrentDataGraphToExcel() - { - - refreshGraph(true, null); - - } - - /** - * Extraction des grilles de proba de passage d'un etat a un autre sous feuille excel. - * Nouvelle version 2 (nov 2010) - */ - private void extractDataToProbabilityGrid2() - { - - System.out.println("export version nov 2010"); - - int timeWindow = Integer.parseInt(extractDataToProbabilityTimeValue.getText()); - int offsetY = 3; - int offsetX = 1; - - // XlsManager xls =null; - // try { - // xls = new XlsManager( System.getProperty("user.home") + "\\output "+(timeWindow-15)+"-"+timeWindow+"f.xls"); - // } catch (IOException e) { - // - // e.printStackTrace(); - // } - - // JTextField startTextField = new JTextField("0"); - - ActionDialog actionDialog = new ActionDialog("Select parameters for tansition graph."); - JPanel mainPanel = new JPanel(); - actionDialog.setPreferredSize(new Dimension(400, 400)); - actionDialog.getMainPanel().add(new JScrollPane(mainPanel)); - // actionDialog.getMainPanel().setLayout( new BoxLayout( actionDialog.getMainPanel() , BoxLayout.PAGE_AXIS )); - mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.PAGE_AXIS)); - animalList.get(0).animal.eventTimeLineList.size(); - - JTextField minProbability = new JTextField("0.3"); - mainPanel.add(GuiUtil.createLineBoxPanel(new JLabel("Min probability: "), minProbability)); - JTextField fpsTextField = new JTextField("15"); - mainPanel.add(GuiUtil.createLineBoxPanel(new JLabel("FPS: "), fpsTextField)); - JTextField maxNumberOfCandidateTextField = new JTextField("4"); - mainPanel - .add(GuiUtil.createLineBoxPanel(new JLabel("Max number of ancestor: "), maxNumberOfCandidateTextField)); - JCheckBox forceLocation = new JCheckBox("Force the location of the event in the graph (circular rendering)", - false); - mainPanel.add(GuiUtil.createLineBoxPanel(forceLocation)); - - HashMap<Integer, JCheckBox> selectedEventHashMap = new HashMap<Integer, JCheckBox>(); - - for (EventTimeLine event : animalList.get(0).animal.eventTimeLineList) - { - JCheckBox booleanField = new JCheckBox(event.criteriaName, true); - // actionDialog.getMainPanel().add( GuiUtil.createLineBoxPanel( booleanField ) ); - mainPanel.add(GuiUtil.createLineBoxPanel(booleanField)); - int index = animalList.get(0).animal.eventTimeLineList.indexOf(event); - selectedEventHashMap.put(index, booleanField); - if (index == 1) - booleanField.setSelected(false); - if (index >= 7 && index <= 10) - booleanField.setSelected(false); - if (index >= 13 && index <= 20) - booleanField.setSelected(false); - if (index >= 27) - booleanField.setSelected(false); - - } - actionDialog.pack(); - actionDialog.setLocationRelativeTo(null); - actionDialog.setVisible(true); - - if (actionDialog.isCanceled()) - return; - - float fps = Float.parseFloat(fpsTextField.getText()); - int MAX_NUMBER_OF_CANDIDATE = Integer.parseInt(maxNumberOfCandidateTextField.getText()); - - System.out.println("WARNING:"); - System.out.println( - "This output consider all the loaded animal in the Label Analyser as coming from the same pool."); - System.out.println("i.e. only 1 pool is considered."); - System.out.println("version Jan 2013. p>0.1 instead of p>0.3"); - - int nbTotalDeCritere = animalList.get(0).animal.eventTimeLineList.size(); - - float poolProba0_4[][][] = new float[animalList.size()][nbTotalDeCritere][nbTotalDeCritere]; - float poolProba4_8[][][] = new float[animalList.size()][nbTotalDeCritere][nbTotalDeCritere]; - - for (int animalNumber = 0; animalNumber < animalList.size(); animalNumber++) - { - Animal animal = animalList.get(animalNumber).animal; - // xls.createNewPage( animal.animalName ); - - // xls.setLabel( 0 , 0 , "se lit: event de la colonne x a une proba p d etre precede par ligne y"); - // xls.setLabel( 0 , 1 , "timeforward(frames):" + (timeWindow-15) + " to " + timeWindow ); - // xls.setLabel( 0 , 2 , "animal:" + animal.animalName ); - - // int FENETRE_RECHERCHE_FRAME = 15*3; - int FENETRE_RECHERCHE_FRAME = (int) (fps * 3); - - for (int eventNumberSource = 0; eventNumberSource < animal.eventTimeLineList.size(); eventNumberSource++) // parcours la liste des events. - { - - // xls.setNumber( 2*eventNumberSource+1 + offsetX, 0 + offsetY , eventNumberSource + 1 ); - - for (int eventNumberTarget = 0; eventNumberTarget < animal.eventTimeLineList - .size(); eventNumberTarget++) // parcours la liste des events. - { - - // xls.setNumber( 0 + offsetX , eventNumberTarget+1 + offsetY , eventNumberTarget + 1 ); - // xls.setLabel( 0 , eventNumberTarget+1 + offsetY , animalList.get( 0 ).animal.eventTimeLineList.get( eventNumberTarget ).criteriaName ); - - EventTimeLine eventTimeLineSource = animal.eventTimeLineList.get(eventNumberSource); - EventTimeLine eventTimeLineTarget = animal.eventTimeLineList.get(eventNumberTarget); - - float nbEventSource04 = 0; - float nbEventTarget04 = 0; - float nbPassageSourceTargetOk04 = 0; - float nbPassageTargetSourceOk04 = 0; - - for (EventCriteria eventCriteriaSource : eventTimeLineSource.eventList) - { - if (eventCriteriaSource.startFrame > 3600) - continue; - nbEventSource04++; - - for (EventCriteria eventCriteriaTarget : eventTimeLineTarget.eventList) - { - if (eventCriteriaTarget.startFrame > 3600) - continue; - - if (eventCriteriaTarget.startFrame >= eventCriteriaSource.endFrame - && eventCriteriaTarget.startFrame <= eventCriteriaSource.endFrame - + FENETRE_RECHERCHE_FRAME) - { - nbPassageSourceTargetOk04++; - break; - } - } - } - - for (EventCriteria eventCriteriaTarget : eventTimeLineTarget.eventList) - { - if (eventCriteriaTarget.startFrame > 3600) - continue; - nbEventTarget04++; - - for (EventCriteria eventCriteriaSource : eventTimeLineSource.eventList) - { - if (eventCriteriaSource.startFrame > 3600) - continue; - if (eventCriteriaTarget.startFrame >= eventCriteriaSource.endFrame - && eventCriteriaTarget.startFrame <= eventCriteriaSource.endFrame - + FENETRE_RECHERCHE_FRAME) - { - nbPassageTargetSourceOk04++; - break; - } - } - } - - float probaStoT04 = nbPassageSourceTargetOk04 / nbEventSource04; - float probaTtoS04 = nbPassageTargetSourceOk04 / nbEventTarget04; - float proba2Way04 = probaStoT04 * probaTtoS04; - - float nbEventSource48 = 0; - float nbEventTarget48 = 0; - float nbPassageSourceTargetOk48 = 0; - float nbPassageTargetSourceOk48 = 0; - - for (EventCriteria eventCriteriaSource : eventTimeLineSource.eventList) - { - if (eventCriteriaSource.startFrame < 3600) - continue; - nbEventSource48++; - - for (EventCriteria eventCriteriaTarget : eventTimeLineTarget.eventList) - { - if (eventCriteriaTarget.startFrame < 3600) - continue; - - if (eventCriteriaTarget.startFrame >= eventCriteriaSource.endFrame - && eventCriteriaTarget.startFrame <= eventCriteriaSource.endFrame - + FENETRE_RECHERCHE_FRAME) - { - nbPassageSourceTargetOk48++; - break; - } - } - } - - for (EventCriteria eventCriteriaTarget : eventTimeLineTarget.eventList) - { - if (eventCriteriaTarget.startFrame < 3600) - continue; - nbEventTarget48++; - - for (EventCriteria eventCriteriaSource : eventTimeLineSource.eventList) - { - if (eventCriteriaSource.startFrame < 3600) - continue; - if (eventCriteriaTarget.startFrame >= eventCriteriaSource.endFrame - && eventCriteriaTarget.startFrame <= eventCriteriaSource.endFrame - + FENETRE_RECHERCHE_FRAME) - { - nbPassageTargetSourceOk48++; - break; - } - } - } - - float probaStoT48 = nbPassageSourceTargetOk48 / nbEventSource48; - float probaTtoS48 = nbPassageTargetSourceOk48 / nbEventTarget48; - float proba2Way48 = probaStoT48 * probaTtoS48; - - if (eventNumberSource != 9 && eventNumberSource != 10 && eventNumberTarget != 9 - && eventNumberTarget != 10) // enleve le speed - { - poolProba0_4[animalNumber][eventNumberSource][eventNumberTarget] = proba2Way04; - poolProba4_8[animalNumber][eventNumberSource][eventNumberTarget] = proba2Way48; - } - - } - } - - } - - float meanAnimalProba0_4[][] = new float[nbTotalDeCritere][nbTotalDeCritere]; - float stddevAnimalProba0_4[][] = new float[nbTotalDeCritere][nbTotalDeCritere]; - float meanAnimalProba4_8[][] = new float[nbTotalDeCritere][nbTotalDeCritere]; - float stddevAnimalProba4_8[][] = new float[nbTotalDeCritere][nbTotalDeCritere]; - - for (int eventNumberSource = 0; eventNumberSource < nbTotalDeCritere; eventNumberSource++) // parcours la liste des events. - { - for (int eventNumberTarget = 0; eventNumberTarget < nbTotalDeCritere; eventNumberTarget++) // parcours la liste des events. - { - float[] tabProba = new float[animalList.size()]; - for (int animalNumber = 0; animalNumber < animalList.size(); animalNumber++) - { - tabProba[animalNumber] = poolProba0_4[animalNumber][eventNumberSource][eventNumberTarget]; - meanAnimalProba0_4[eventNumberSource][eventNumberTarget] += poolProba0_4[animalNumber][eventNumberSource][eventNumberTarget]; - - } - meanAnimalProba0_4[eventNumberSource][eventNumberTarget] /= animalList.size(); - stddevAnimalProba0_4[eventNumberSource][eventNumberTarget] = flanagan.analysis.Stat - .standardDeviation(tabProba); - ; - } - } - - for (int eventNumberSource = 0; eventNumberSource < nbTotalDeCritere; eventNumberSource++) // parcours la liste des events. - { - for (int eventNumberTarget = 0; eventNumberTarget < nbTotalDeCritere; eventNumberTarget++) // parcours la liste des events. - { - float[] tabProba = new float[animalList.size()]; - for (int animalNumber = 0; animalNumber < animalList.size(); animalNumber++) - { - tabProba[animalNumber] = poolProba4_8[animalNumber][eventNumberSource][eventNumberTarget]; - meanAnimalProba4_8[eventNumberSource][eventNumberTarget] += poolProba4_8[animalNumber][eventNumberSource][eventNumberTarget]; - - } - meanAnimalProba4_8[eventNumberSource][eventNumberTarget] /= animalList.size(); - stddevAnimalProba4_8[eventNumberSource][eventNumberTarget] = flanagan.analysis.Stat - .standardDeviation(tabProba); - ; - } - } - - ArrayList<ArrayList<EventResult>> resultatParSource0_4 = new ArrayList<ArrayList<EventResult>>(); - ArrayList<ArrayList<EventResult>> resultatParSource4_8 = new ArrayList<ArrayList<EventResult>>(); - - // int MAX_NUMBER_OF_CANDIDATE = 4; // was 4 - - { - for (int nbEventTarget = 0; nbEventTarget < nbTotalDeCritere; nbEventTarget++) - { - ArrayList<EventResult> eventResultList = new ArrayList<EventResult>(); - for (int nbEventSource = 0; nbEventSource < nbTotalDeCritere; nbEventSource++) - { - JCheckBox eTarget = selectedEventHashMap.get(nbEventTarget); - JCheckBox eSource = selectedEventHashMap.get(nbEventSource); - if (!eTarget.isSelected() || !eSource.isSelected()) - continue; - - /* - * if ( nbEventTarget == 1 || nbEventSource == 1 ) continue; - * if ( nbEventTarget == 7 || nbEventSource == 7 ) continue; - * if ( nbEventTarget == 8 || nbEventSource == 8 ) continue; - * if ( nbEventTarget == 9 || nbEventSource == 9 ) continue; - * if ( nbEventTarget == 10 || nbEventSource == 10 ) continue; - * if ( nbEventTarget == 13 || nbEventSource == 13 ) continue; - * if ( nbEventTarget == 14 || nbEventSource == 14 ) continue; - * if ( nbEventTarget == 15 || nbEventSource == 15 ) continue; - * if ( nbEventTarget == 16 || nbEventSource == 16 ) continue; - * if ( nbEventTarget == 17 || nbEventSource == 17 ) continue; - * if ( nbEventTarget == 18 || nbEventSource == 18 ) continue; - * if ( nbEventTarget == 19 || nbEventSource == 19 ) continue; - * if ( nbEventTarget == 20 || nbEventSource == 20 ) continue; - * if ( nbEventTarget >= 27 || nbEventSource >= 27 ) continue; - */ - - float probaProposee = meanAnimalProba0_4[nbEventSource][nbEventTarget]; - float stddevPropose = stddevAnimalProba0_4[nbEventSource][nbEventTarget]; - - ArrayList<EventResult> eventResultListClone = (ArrayList<EventResult>) eventResultList.clone(); - - for (EventResult resultClient : eventResultListClone) - { - if (resultClient.proba < probaProposee) - { - eventResultList.remove(resultClient); - break; - } - } - - if (eventResultList.size() < MAX_NUMBER_OF_CANDIDATE) - { - EventResult result = new EventResult(nbEventSource, nbEventTarget, probaProposee, stddevPropose, - "red"); - eventResultList.add(result); - } - - } - resultatParSource0_4.add(eventResultList); - - } - } - - { - - for (int nbEventTarget = 0; nbEventTarget < nbTotalDeCritere; nbEventTarget++) - { - ArrayList<EventResult> eventResultList = new ArrayList<EventResult>(); - for (int nbEventSource = 0; nbEventSource < nbTotalDeCritere; nbEventSource++) - { - JCheckBox eTarget = selectedEventHashMap.get(nbEventTarget); - JCheckBox eSource = selectedEventHashMap.get(nbEventSource); - if (!eTarget.isSelected() || !eSource.isSelected()) - continue; - // - // if ( nbEventTarget == 1 || nbEventSource == 1 ) continue; - // if ( nbEventTarget == 7 || nbEventSource == 7 ) continue; - // if ( nbEventTarget == 8 || nbEventSource == 8 ) continue; - // if ( nbEventTarget == 9 || nbEventSource == 9 ) continue; - // if ( nbEventTarget == 10 || nbEventSource == 10 ) continue; - // if ( nbEventTarget == 13 || nbEventSource == 13 ) continue; - // if ( nbEventTarget == 14 || nbEventSource == 14 ) continue; - // if ( nbEventTarget == 15 || nbEventSource == 15 ) continue; - // if ( nbEventTarget == 16 || nbEventSource == 16 ) continue; - // if ( nbEventTarget == 17 || nbEventSource == 17 ) continue; - // if ( nbEventTarget == 18 || nbEventSource == 18 ) continue; - // if ( nbEventTarget == 19 || nbEventSource == 19 ) continue; - // if ( nbEventTarget == 20 || nbEventSource == 20 ) continue; - // if ( nbEventTarget >= 27 || nbEventSource >= 27 ) continue; - - float probaProposee = meanAnimalProba4_8[nbEventSource][nbEventTarget]; - float stddevPropose = stddevAnimalProba4_8[nbEventSource][nbEventTarget]; - - ArrayList<EventResult> eventResultListClone = (ArrayList<EventResult>) eventResultList.clone(); - - for (EventResult resultClient : eventResultListClone) - { - if (resultClient.proba < probaProposee) - { - eventResultList.remove(resultClient); - break; - } - } - - if (eventResultList.size() < MAX_NUMBER_OF_CANDIDATE) - { - EventResult result = new EventResult(nbEventSource, nbEventTarget, probaProposee, stddevPropose, - "green"); - eventResultList.add(result); - } - - } - resultatParSource4_8.add(eventResultList); - - } - } - - // GRAPH: - - boolean FORCE_LOCATION = forceLocation.isSelected(); - - System.out.println("Put the following script in GraphViz:"); - if (FORCE_LOCATION) - { - System.out.println("/* @command = neato **/"); - } - System.out.println("digraph {"); - System.out.println("splines=true;"); - - // set the location of each available event - - if (FORCE_LOCATION) - { - double x = 0; - double y = 0; - double angle = 0; - - for (int eventIndex = 0; eventIndex < nbTotalDeCritere; eventIndex++) - { - JCheckBox eventBox = selectedEventHashMap.get(eventIndex); - if (!eventBox.isSelected()) - continue; - // - // if( eventIndex == 1 ) continue; - // if( eventIndex == 7 ) continue; - // if( eventIndex == 8 ) continue; - // if( eventIndex == 9 ) continue; - // if( eventIndex == 10 ) continue; - // if( eventIndex == 13 ) continue; - // if( eventIndex == 14 ) continue; - // if( eventIndex == 15 ) continue; - // if( eventIndex == 16 ) continue; - // if( eventIndex == 17 ) continue; - // if( eventIndex == 18 ) continue; - // if( eventIndex == 19 ) continue; - // if( eventIndex == 20 ) continue; - // if( eventIndex >= 27 ) continue; - - x = 300 + Math.cos(angle) * 300; - y = 300 + Math.sin(angle) * 300; - - String criteriaName = animalList.get(0).animal.eventTimeLineList.get(eventIndex).criteriaName; - criteriaName = keepFirstChars(criteriaName); - - String result = "\"" + criteriaName + "\""; - result += "["; - result += " pos=\"" + x + "," + y + "!" + "\" "; - result += " shape=\"box\" "; - result += " width=\"2\" "; - result += "]"; - - System.out.println(result); - - angle += (Math.PI * 2d) / 14d; - - // x+=200; - // if ( x > 100 ) - // { - // y+=100; - // x=0; - // } - - } - - } - - // animalList.get( 0 ).animal.eventTimeLineList.get( eventSource ).criteriaName - - // create graph - - for (int sourceList = 0; sourceList < nbTotalDeCritere; sourceList++) - { - ArrayList<EventResult> eventResultList0_4 = resultatParSource0_4.get(sourceList); - ArrayList<EventResult> eventResultList4_8 = resultatParSource4_8.get(sourceList); - - ArrayList<EventResult> finalResult = createCommonList(eventResultList0_4, eventResultList4_8); - - for (EventResult eventResult : finalResult) - { - if (eventResult.enable) - { - if (eventResult.proba >= 0.1f) // was 0.3f - { - System.out.println(eventResult); - } - else - { - - } - } - } - - } - - System.out.println("}"); - - // xls.SaveAndClose(); - - } - - ArrayList<EventResult> createCommonList(ArrayList<EventResult> eventResultList0_4, - ArrayList<EventResult> eventResultList4_8) - { - ArrayList<EventResult> finalResult = new ArrayList<EventResult>(); - for (EventResult eventResult0_4 : eventResultList0_4) - { - finalResult.add(eventResult0_4); - } - for (EventResult eventResult4_8 : eventResultList4_8) - { - finalResult.add(eventResult4_8); - } - - for (EventResult eventResultA : finalResult) - { - for (EventResult eventResultB : finalResult) - { - if (eventResultA != eventResultB && eventResultA.enable && eventResultB.enable - && eventResultA.eventSource == eventResultB.eventSource - && eventResultA.eventTarget == eventResultB.eventTarget - && checkIfProbaOverlap(eventResultA, eventResultB)) - { - eventResultA.proba = (eventResultA.proba + eventResultB.proba) / 2f; - eventResultB.enable = false; - eventResultA.color = "black"; - } - - } - } - - return finalResult; - } - - private boolean checkIfProbaOverlap(EventResult eventResultA, EventResult eventResultB) - { - float sigma = 1f; - - float borneMinA = eventResultA.proba - eventResultA.stddev * sigma; - float borneMaxA = eventResultA.proba + eventResultA.stddev * sigma; - - float borneMinB = eventResultB.proba - eventResultB.stddev * sigma; - float borneMaxB = eventResultB.proba + eventResultB.stddev * sigma; - - if (borneMinA > borneMinB && borneMinA < borneMaxB) - return true; - if (borneMaxA > borneMinB && borneMaxA < borneMaxB) - return true; - - return false; - } - - class ProbaResult - { - public ProbaResult(float proba, float stddev, int startFrame) - { - this.stddev = stddev; - this.proba = proba; - this.startFrame = startFrame; - } - - float stddev; - float proba; - int startFrame; - } - - class EventResult - { - boolean enable = true; - - public EventResult(int eventSource, int eventTarget, float proba, float stddev, String color) - { - this.eventSource = eventSource; - this.eventTarget = eventTarget; - this.stddev = stddev; - this.proba = proba; - this.color = color; - } - - float stddev; - int eventSource; - int eventTarget; - float proba; - String color; - - @Override - public String toString() - { - - String result = ""; - result += "\"" + keepFirstChars(animalList.get(0).animal.eventTimeLineList.get(eventSource).criteriaName) - + "\""; - result += "->"; - result += "\"" + keepFirstChars(animalList.get(0).animal.eventTimeLineList.get(eventTarget).criteriaName) - + "\""; - result += " "; - result += "[ "; - result += "color=\"" + color + "\""; - result += " style=\"setlinewidth(" + proba * 5 + ")\"]"; - result += ";"; - - return result; - } - - /** - * Just provide the name of events. Without link. - * - * @return - */ - public String getEvents() - { - String result = ""; - result += "\"" + keepFirstChars(animalList.get(0).animal.eventTimeLineList.get(eventSource).criteriaName) - + "\""; - result += ";"; - result += "\"" + keepFirstChars(animalList.get(0).animal.eventTimeLineList.get(eventTarget).criteriaName) - + "\""; - result += ";"; - return result; - } - - } - - public static String keepFirstChars(String s) - { - int MAXSIZE = 20; - if (s.length() > MAXSIZE) - s = (String) s.substring(0, MAXSIZE); - return s; - } - - void exportAllData() - { - System.out.println("export all data in pool to excel."); - - // export pool 1 - - // String saveFileName = SaveDialog.chooseFile("Export all data to xls file", System.getProperty("user.home") ,"output.xls", ".xls"); - - JTextField startTextField = new JTextField("0"); - JTextField endTextField = new JTextField("8"); - - ActionDialog actionDialog = new ActionDialog("Select range (in minutes)"); - actionDialog.getMainPanel().setLayout(new BoxLayout(actionDialog.getMainPanel(), BoxLayout.PAGE_AXIS)); - actionDialog.getMainPanel().add(GuiUtil.createLineBoxPanel(new JLabel("start (minutes)"), startTextField)); - actionDialog.getMainPanel().add(GuiUtil.createLineBoxPanel(new JLabel("end (minutes)"), endTextField)); - actionDialog.pack(); - actionDialog.setLocationRelativeTo(null); - actionDialog.setVisible(true); - - if (actionDialog.isCanceled()) - return; - - float startMinute = Float.parseFloat(startTextField.getText()); - float endMinute = Float.parseFloat(endTextField.getText()); - - String saveFileName = SaveDialog.chooseFile("Save xls file", "", "Mice Profiler - all data", ".xls"); - - if (saveFileName == null) - return; - XlsManager xls = null; - - try - { - - xls = new XlsManager(saveFileName); - xls.createNewPage("Data in pool"); - - } - catch (IOException e) - { - - e.printStackTrace(); - } - - xls.createNewPage("Results"); - - int cursorY = 0; - - for (EventSelector eventSelector : eventSelectorList) - { - String eventTitle = animalList.get(0).animal.eventTimeLineList.get(eventSelector.eventNumber).criteriaName; - - xls.setLabel(0, cursorY, "Event #" + eventSelector.eventNumber, Colour.YELLOW); - cursorY++; - xls.setLabel(0, cursorY, eventTitle); - cursorY += 2; - - cursorY = exportXLSPool(1, eventSelector, cursorY, xls, startMinute, endMinute); - cursorY += 3; - cursorY = exportXLSPool(2, eventSelector, cursorY, xls, startMinute, endMinute); - cursorY += 4; - } - - xls.SaveAndClose(); - - } - - int exportXLSPool(int pool, EventSelector eventSelector, int cursorY, XlsManager xls, float startMinute, - float endMinute) - { - float halfMinute = (endMinute + startMinute) / 2f; - - xls.setLabel(0, cursorY, "p" + pool); - // xls.setLabel( 1, cursorY, "nb e 0-4" ); - xls.setLabel(1, cursorY, "nb event from " + startMinute + " to " + halfMinute + " minutes"); - // xls.setLabel( 2, cursorY, "nb e 4-8" ); - xls.setLabel(2, cursorY, "nb event from " + halfMinute + " to " + endMinute + " minutes"); - // xls.setLabel( 3, cursorY, "nb e 0-8" ); - xls.setLabel(3, cursorY, "nb event from " + startMinute + " to " + endMinute + " minutes"); - - // xls.setLabel( 4, cursorY, "l e 0-4" ); - xls.setLabel(4, cursorY, "length of event from " + startMinute + " to " + halfMinute + " minutes"); - // xls.setLabel( 5, cursorY, "l e 4-8" ); - xls.setLabel(5, cursorY, "length of event from " + halfMinute + " to " + endMinute + " minutes"); - // xls.setLabel( 6, cursorY, "l e 0-8" ); - xls.setLabel(6, cursorY, "length of event from " + startMinute + " to " + endMinute + " minutes"); - - float fps = Float.parseFloat(fpsTextField.getText()); - - cursorY++; - - for (AnimalPoolSelector animalSelector : animalList) - { - if (pool == 1 && animalSelector.pool1.isSelected() || pool == 2 && animalSelector.pool2.isSelected()) - { - if (animalSelector.enable.isSelected()) - { - xls.setLabel(0, cursorY, animalSelector.animal.animalName); - - Animal animal = animalSelector.animal; - EventTimeLine eventTimeLine = animal.eventTimeLineList.get(eventSelector.eventNumber); - - // boolean debug = false; - - // nb event e 0-4 le - // if ( debug ) System.out.println("0-4"); - { - int nb = 0; - int length = 0; - - // int maxTime = (int) (4*60*fps); - int maxTime = (int) (halfMinute * 60 * fps); - int minTime = (int) (startMinute * 60 * fps); - - for (EventCriteria event : eventTimeLine.eventList) - { - if (event.startFrame < maxTime && event.startFrame >= minTime) - { - nb++; - length += event.getLength(); - // if ( debug ) - // { - // System.out.println( eventTimeLine.eventList.indexOf( event ) + ">" + event.getLength() ); - // } - } - } - xls.setNumber(1, cursorY, nb); - xls.setNumber(4, cursorY, length); - // if ( debug ) - // { - // System.out.println( "nb event"+nb ); - // System.out.println( "length event"+length ); - // } - - } - - // nb event e 4-8 le - // if ( debug ) System.out.println("4-8"); - { - int nb = 0; - int length = 0; - - // int minTime = (int)(4d*60d*fps); - int minTime = (int) (halfMinute * 60d * fps); - int maxTime = (int) (endMinute * 60 * fps); - for (EventCriteria event : eventTimeLine.eventList) - { - if (event.startFrame < maxTime && event.startFrame > minTime) - { - nb++; - length += event.getLength(); - // if ( debug ) - // { - // System.out.println( eventTimeLine.eventList.indexOf( event ) + ">" + event.getLength() ); - // } - } - } - xls.setNumber(2, cursorY, nb); - xls.setNumber(5, cursorY, length); - // if ( debug ) - // { - // System.out.println( "nb event"+nb ); - // System.out.println( "length event"+length ); - // } - - } - - // nb event e 0-8 le - // if ( debug ) System.out.println("0-8"); - { - int nb = 0; - int length = 0; - int minTime = (int) (startMinute * 60d * fps); - // int maxTime = (int) (8*60*fps); - int maxTime = (int) (endMinute * 60 * fps); - for (EventCriteria event : eventTimeLine.eventList) - { - if (event.startFrame < maxTime && event.startFrame > minTime) - { - nb++; - length += event.getLength(); - // if ( debug ) - // { - // System.out.println( eventTimeLine.eventList.indexOf( event ) + ">" + event.getLength() ); - // } - } - } - xls.setNumber(3, cursorY, nb); - xls.setNumber(6, cursorY, length); - // if ( debug ) - // { - // System.out.println( "nb event"+nb ); - // System.out.println( "length event"+length ); - // } - - } - - cursorY++; - - } - } - } - return cursorY; + implementer = new MiceProfilerLabelAnalyserInternal(); } @Override - public String getMainPluginClassName() + public void run() { - return MiceProfilerTracker.class.getName(); + // nothing to do her } } \ No newline at end of file diff --git a/src/main/java/plugins/fab/MiceProfiler/MiceProfilerLabelAnalyserInternal.java b/src/main/java/plugins/fab/MiceProfiler/MiceProfilerLabelAnalyserInternal.java new file mode 100644 index 0000000000000000000000000000000000000000..bdb27f7b9838273cb1b4ee558f57f7724b57dd2e --- /dev/null +++ b/src/main/java/plugins/fab/MiceProfiler/MiceProfilerLabelAnalyserInternal.java @@ -0,0 +1,1638 @@ +/* + * Copyright 2011, 2012 Institut Pasteur. + * + * This file is part of MiceProfiler. + * + * MiceProfiler is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * MiceProfiler is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with MiceProfiler. If not, see <http://www.gnu.org/licenses/>. + */ +package plugins.fab.MiceProfiler; + +import java.awt.BasicStroke; +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Component; +import java.awt.Dimension; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; + +import javax.swing.BoxLayout; +import javax.swing.ButtonGroup; +import javax.swing.JCheckBox; +import javax.swing.JCheckBoxMenuItem; +import javax.swing.JLabel; +import javax.swing.JMenu; +import javax.swing.JMenuBar; +import javax.swing.JMenuItem; +import javax.swing.JPanel; +import javax.swing.JRadioButton; +import javax.swing.JScrollPane; +import javax.swing.JTextField; + +import org.jfree.chart.ChartFactory; +import org.jfree.chart.ChartPanel; +import org.jfree.chart.JFreeChart; +import org.jfree.chart.plot.PlotOrientation; +import org.jfree.chart.plot.XYPlot; +import org.jfree.chart.renderer.xy.DeviationRenderer; +import org.jfree.data.xy.XYSeries; +import org.jfree.data.xy.XYSeriesCollection; +import org.jfree.data.xy.YIntervalSeries; +import org.jfree.data.xy.YIntervalSeriesCollection; + +import icy.file.xls.XlsManager; +import icy.gui.dialog.ActionDialog; +import icy.gui.dialog.MessageDialog; +import icy.gui.dialog.SaveDialog; +import icy.gui.frame.IcyFrame; +import icy.gui.util.GuiUtil; +import icy.main.Icy; +import icy.swimmingPool.SwimmingObject; +import icy.swimmingPool.SwimmingPoolEvent; +import icy.swimmingPool.SwimmingPoolListener; +import jxl.format.Colour; + +/** + * @author Fab + * Goal : extract graphs from animal pool. + * Take its source from the swimming pool. + * Can be multi instanced. + */ +public class MiceProfilerLabelAnalyserInternal implements SwimmingPoolListener, ActionListener +{ + + JPanel mainPanel = GuiUtil.generatePanel(); + IcyFrame icyFrame = GuiUtil.generateTitleFrame("Label Analyser", mainPanel, new Dimension(0, 0), true, true, true, + true); + + ArrayList<EventSelector> eventSelectorList = null; + JFreeChart chart; + XYSeriesCollection xyDataset = new XYSeriesCollection(); + YIntervalSeriesCollection yintervalseriescollection = new YIntervalSeriesCollection(); + + JTextField binSizeTextField = new JTextField("150"); + JTextField fpsTextField = new JTextField("15"); + JTextField totalTimeTextField = new JTextField("7200"); + ArrayList<AnimalPoolSelector> animalList = new ArrayList<AnimalPoolSelector>(); + IcyFrame graphFrame = new IcyFrame("graph", true, true, true, true); + // JCheckBox displayLegendCheckBox = new JCheckBox("display Legend", false); + JCheckBoxMenuItem displayLegendCheckBoxMenuItem = new JCheckBoxMenuItem("display Legend", true); + + // JButton extractDataToProbabilityGridButton = new JButton("Compute decision graph script"); + JMenuItem extractDataToProbabilityGridMenuItem = new JMenuItem("Compute decision graph script to console"); + JTextField extractDataToProbabilityTimeValue = new JTextField("150"); + // JButton extractCurrentDataGraphToExcelButton = new JButton("Export current graph to xls"); + + JMenuItem extractCurrentDataGraphToExcelMenuItem = new JMenuItem("Export current graph to xls"); + JMenuItem extractCurrentDataGraphWithAllLabelDensityToExcelMenuItem = new JMenuItem( + "Export graphs to xls (one per label-density)"); + // JButton extractAllDataToGraphAndExcel = new JButton("Export all datas (in pools) to xls"); + JMenuItem extractAllDataToGraphAndExcelMenuItem = new JMenuItem("Export all datas (in pools) to xls"); + + public MiceProfilerLabelAnalyserInternal() + { + // CHECK IF ANIMAL ARE LOADED IN SWIMMING POOL. IF NOT RETURN. + + animalList.clear(); + ArrayList<SwimmingObject> liste = Icy.getMainInterface().getSwimmingPool().getObjects(); + for (SwimmingObject so : liste) + { + if (so.getObject() instanceof Animal) + { + animalList.add(new AnimalPoolSelector((Animal) so.getObject())); + } + } + + if (animalList.size() == 0) + { + MessageDialog.showDialog("No animal loaded, please run VideoLabelMaker first.", + MessageDialog.INFORMATION_MESSAGE); + return; + } + + // END OF ANIMAL LOADED CHECK + + Icy.getMainInterface().getSwimmingPool().addListener(this); + + chart = ChartFactory.createXYLineChart("", "t", "y", yintervalseriescollection, PlotOrientation.VERTICAL, true, // true , + false, false); + + XYPlot xyplot = (XYPlot) chart.getPlot(); + xyplot.setInsets(new org.jfree.chart.ui.RectangleInsets(5D, 5D, 5D, 20D)); + xyplot.setBackgroundPaint(Color.lightGray); + xyplot.setAxisOffset(new org.jfree.chart.ui.RectangleInsets(5D, 5D, 5D, 5D)); + xyplot.setDomainGridlinePaint(Color.white); + xyplot.setRangeGridlinePaint(Color.white); + DeviationRenderer deviationrenderer = new DeviationRenderer(true, false); + for (int i = 0; i < 100; i++) + { + deviationrenderer.setSeriesStroke(i, new BasicStroke(3F, 1, 1)); + deviationrenderer.setSeriesStroke(i + 1, new BasicStroke(3F, 1, 1)); + deviationrenderer.setSeriesFillPaint(0, new Color(255, 200, 200)); + deviationrenderer.setSeriesFillPaint(1, new Color(200, 200, 255)); + deviationrenderer.setSeriesFillPaint(3, new Color(200, 255, 200)); + deviationrenderer.setSeriesFillPaint(2, new Color(255, 255, 200)); + } + xyplot.setRenderer(deviationrenderer); + + refreshData(); + + icyFrame.addToDesktopPane(); + icyFrame.pack(); + icyFrame.setSize(800, 600); + icyFrame.center(); + icyFrame.toFront(); + icyFrame.setVisible(true); + + graphFrame.addToDesktopPane(); + // graphFrame.center(); + graphFrame.setVisible(true); + icyFrame.toFront(); + + extractCurrentDataGraphToExcelMenuItem.addActionListener(this); + extractAllDataToGraphAndExcelMenuItem.addActionListener(this); + // displayLegendCheckBoxMenuItem.addActionListener( this ); + extractDataToProbabilityGridMenuItem.addActionListener(this); + extractCurrentDataGraphWithAllLabelDensityToExcelMenuItem.addActionListener(this); + + JMenuBar menuBar = new JMenuBar(); + JMenu menuExport = new JMenu("Export"); + menuExport.add(extractCurrentDataGraphToExcelMenuItem); + menuExport.add(extractAllDataToGraphAndExcelMenuItem); + menuExport.add(extractDataToProbabilityGridMenuItem); + menuExport.add(extractCurrentDataGraphWithAllLabelDensityToExcelMenuItem); + menuBar.add(menuExport); + + // JMenu menuGraph = new JMenu("Graph"); + // menuGraph.add( displayLegendCheckBoxMenuItem ); + // menuBar.add( menuGraph ); + + icyFrame.setJMenuBar(menuBar); + + } + + public void run() + { + // nothing here + } + + /** + * refresh graphs + * + * @param file + */ + void refreshGraph(boolean xlsExport, String file) + { + + XlsManager xls = null; + int cursorX = 0; + int cursorY = 1; + + if (xlsExport) + { + String saveFileName = file; + if (file == null) + { + saveFileName = SaveDialog.chooseFile("Export current graph to xls file", + System.getProperty("user.home"), "outputGraph.xls", ".xls"); + if (saveFileName == null) + return; + } + + try + { + xls = new XlsManager(new File(saveFileName)); + xls.createNewPage("Mice profiler graph export"); + + } + catch (IOException e) + { + + e.printStackTrace(); + } + } + + int binSize = Integer.parseInt(binSizeTextField.getText()); + int endFrame = Integer.parseInt(totalTimeTextField.getText()); + float fps = Float.parseFloat(fpsTextField.getText()); + + xyDataset.removeAllSeries(); + yintervalseriescollection.removeAllSeries(); + + // creation des series: + + // no pool + + for (EventSelector eventSelector : eventSelectorList) + { + + for (AnimalPoolSelector animalSelector : animalList) + { + + if (animalSelector.noPool.isSelected()) + { + + if (animalSelector.enable.isSelected()) + { + + if (eventSelector.nbEventCheckBox.isSelected()) + { + EventTimeLine eventTimeLine = animalSelector.animal.eventTimeLineList + .get(eventSelector.eventNumber); + String titreSerie = animalSelector.animal.animalName + " np Event Nb" + + eventTimeLine.criteriaName; + XYSeries seriesXY = new XYSeries(titreSerie); + + if (xlsExport) + { + cursorX++; + xls.setLabel(cursorX, 0, titreSerie); + cursorY = 1; + } + + YIntervalSeries yintervalseries = new YIntervalSeries( + animalSelector.animal.animalName + " np Event Nb" + eventTimeLine.criteriaName); + + for (int t = 0; t < endFrame; t += binSize) + { + double value = eventTimeLine.getNbEvent(t, t + binSize - 1); + yintervalseries.add(t / fps, value, value, value); + + if (xlsExport) + { + xls.setNumber(0, cursorY, t / fps); // legende + xls.setNumber(cursorX, cursorY, value); // valeur + cursorY++; + } + + } + yintervalseriescollection.addSeries(yintervalseries); + + } + + if (eventSelector.lengthCheckBox.isSelected()) + { + EventTimeLine eventTimeLine = animalSelector.animal.eventTimeLineList + .get(eventSelector.eventNumber); + XYSeries seriesXY = new XYSeries( + animalSelector.animal.animalName + " np Event l" + eventTimeLine.criteriaName); + + String titreSerie = animalSelector.animal.animalName + " np Event l" + + eventTimeLine.criteriaName; + YIntervalSeries yintervalseries = new YIntervalSeries(titreSerie); + + if (xlsExport) + { + cursorX++; + xls.setLabel(cursorX, 0, titreSerie); + cursorY = 1; + } + + for (int t = 0; t < endFrame; t += binSize) + { + double value = eventTimeLine.getLengthEvent(t, t + binSize - 1); + yintervalseries.add(t / fps, value, value, value); + + if (xlsExport) + { + xls.setNumber(0, cursorY, t / fps); // legende + xls.setNumber(cursorX, cursorY, value); // valeur + cursorY++; + } + + } + yintervalseriescollection.addSeries(yintervalseries); + + } + + // critere discret + if (eventSelector.displayDiscreteValueCheckBox.isSelected()) + { + EventTimeLine eventTimeLine = animalSelector.animal.eventTimeLineList + .get(eventSelector.eventNumber); + XYSeries seriesXY = new XYSeries( + animalSelector.animal.animalName + " dv Event " + eventTimeLine.criteriaName); + + String titreSerie = animalSelector.animal.animalName + " dv Event " + + eventTimeLine.criteriaName; + + YIntervalSeries yintervalseries = new YIntervalSeries(titreSerie); + + if (xlsExport) + { + cursorX++; + xls.setLabel(cursorX, 0, titreSerie); + cursorY = 1; + } + + for (int t = 0; t < endFrame; t += binSize) + { + + double value = eventTimeLine.getMeanValue(t, t + binSize - 1); + yintervalseries.add(t / fps, value, value, value); + + if (xlsExport) + { + xls.setNumber(0, cursorY, t / fps); // legende + xls.setNumber(cursorX, cursorY, value); // valeur + cursorY++; + } + + } + yintervalseriescollection.addSeries(yintervalseries); + + } + + // critere density + if (eventSelector.densityCheckBox.isSelected()) + { + + EventTimeLine eventTimeLine = animalSelector.animal.eventTimeLineList + .get(eventSelector.eventNumber); + XYSeries seriesXY = new XYSeries( + animalSelector.animal.animalName + " dv Density " + eventTimeLine.criteriaName); + + String titreSerie = animalSelector.animal.animalName + " dv Density " + + eventTimeLine.criteriaName; + + YIntervalSeries yintervalseries = new YIntervalSeries(titreSerie); + + if (xlsExport) + { + cursorX++; + xls.setLabel(cursorX, 0, titreSerie); + cursorY = 1; + } + + for (int t = 0; t < endFrame; t += binSize) + { + + double value = eventTimeLine.getDensity(t, t + binSize - 1); + + yintervalseries.add(t / fps, value, value, value); + + if (xlsExport) + { + xls.setNumber(0, cursorY, t / fps); // legende + xls.setNumber(cursorX, cursorY, value); // valeur + cursorY++; + } + + } + yintervalseriescollection.addSeries(yintervalseries); + + } + + } + } + } + + } + + updateGraphSeriesForPool(Criteria.NB_EVENT, 1, endFrame, binSize, xls, xlsExport); + updateGraphSeriesForPool(Criteria.LENGTH_EVENT, 1, endFrame, binSize, xls, xlsExport); + updateGraphSeriesForPool(Criteria.DISCRETE_VALUE, 1, endFrame, binSize, xls, xlsExport); + updateGraphSeriesForPool(Criteria.DENSITY_VALUE, 1, endFrame, binSize, xls, xlsExport); + updateGraphSeriesForPool(Criteria.NB_EVENT, 2, endFrame, binSize, xls, xlsExport); + updateGraphSeriesForPool(Criteria.LENGTH_EVENT, 2, endFrame, binSize, xls, xlsExport); + updateGraphSeriesForPool(Criteria.DISCRETE_VALUE, 2, endFrame, binSize, xls, xlsExport); + updateGraphSeriesForPool(Criteria.DENSITY_VALUE, 2, endFrame, binSize, xls, xlsExport); + + if (xlsExport) + { + // System.out.println( "xls debug: " + xls.getExcelPage() ); + xls.SaveAndClose(); + } + + } + + enum Criteria + { + NB_EVENT, LENGTH_EVENT, DISCRETE_VALUE, DENSITY_VALUE + } + + void updateGraphSeriesForPool(Criteria criteria, int pool, int endFrame, int binSize, XlsManager xls, + boolean xlsExport) + { + int cursorX = 1; + int cursorY = 0; + + float fps = Float.parseFloat(fpsTextField.getText()); + + boolean process = false; + for (AnimalPoolSelector animalSelector : animalList) + { + if ((pool == 1 && animalSelector.pool1.isSelected()) || (pool == 2 && animalSelector.pool2.isSelected())) + { + process = true; + } + } + + if (!process) + return; + + for (EventSelector eventSelector : eventSelectorList) + { + if ((criteria == Criteria.NB_EVENT && eventSelector.nbEventCheckBox.isSelected()) + || (criteria == Criteria.LENGTH_EVENT && eventSelector.lengthCheckBox.isSelected()) + || (criteria == Criteria.DISCRETE_VALUE && eventSelector.displayDiscreteValueCheckBox.isSelected()) + || (criteria == Criteria.DENSITY_VALUE && eventSelector.densityCheckBox.isSelected())) + { + + String chaine = "p" + pool + " " + criteria.toString(); + chaine += animalList.get(0).animal.eventTimeLineList.get(eventSelector.eventNumber).criteriaName; + XYSeries seriesXY = new XYSeries(chaine); + YIntervalSeries yintervalseries = new YIntervalSeries(chaine); + + if (xlsExport) + { + xls.createNewPage(chaine); + cursorX = 1; + } + + for (int t = 0; t < endFrame; t += binSize) + { + if (xlsExport) + { + xls.setLabel(cursorX, cursorY, "" + t + "-" + (t + binSize)); + cursorY++; + cursorY++; + + } + + // ROI3DArea r = new ROI3DArea( new Point3D.Double( 0,0,0 ) ); + + ArrayList<Double> listResultat = new ArrayList<Double>(); + + for (AnimalPoolSelector animalSelector : animalList) + { + + if ((pool == 1 && animalSelector.pool1.isSelected()) + || (pool == 2 && animalSelector.pool2.isSelected())) + { + + if (animalSelector.enable.isSelected()) + { + EventTimeLine eventTimeLine = animalSelector.animal.eventTimeLineList + .get(eventSelector.eventNumber); + + if (criteria == Criteria.NB_EVENT) + { + listResultat.add(eventTimeLine.getNbEvent(t, t + binSize - 1)); + + if (xlsExport) + { + xls.setNumber(cursorX, cursorY, eventTimeLine.getNbEvent(t, t + binSize - 1)); + cursorY++; + } + + } + if (criteria == Criteria.LENGTH_EVENT) + { + listResultat.add(eventTimeLine.getLengthEvent(t, t + binSize - 1)); + + if (xlsExport) + { + xls.setNumber(cursorX, cursorY, + eventTimeLine.getLengthEvent(t, t + binSize - 1)); + cursorY++; + } + + } + + if (criteria == Criteria.DISCRETE_VALUE) + { + listResultat.add(eventTimeLine.getMeanValue(t, t + binSize - 1)); + + if (xlsExport) + { + xls.setNumber(cursorX, cursorY, eventTimeLine.getMeanValue(t, t + binSize - 1)); + cursorY++; + } + + } + if (criteria == Criteria.DENSITY_VALUE) + { + listResultat.add(eventTimeLine.getDensity(t, t + binSize - 1)); + + if (xlsExport) + { + xls.setNumber(cursorX, cursorY, eventTimeLine.getDensity(t, t + binSize - 1)); + cursorY++; + } + + } + + } + } + } + + if (listResultat.size() != 0) + { + double[] resultatTab2 = new double[listResultat.size()]; + for (int i = 0; i < listResultat.size(); i++) + { + resultatTab2[i] = listResultat.get(i); + } + + double error = flanagan.analysis.Stat.standardDeviation(resultatTab2); + error = error / Math.sqrt(listResultat.size() - 1); + double mean = flanagan.analysis.Stat.mean(resultatTab2); + + yintervalseries.add(t / fps, mean, mean - (error), mean + (error)); + + if (xlsExport) + { + cursorY++; + xls.setNumber(cursorX, cursorY, mean); + } + + } + else + { + yintervalseries.add(t / fps, 0, 0, 0); + } + + cursorX++; + cursorY = 0; + } + + xyDataset.addSeries(seriesXY); + + yintervalseriescollection.addSeries(yintervalseries); + + } + } + } + + /** + * Refresh Datas + */ + private void refreshData() + { + + mainPanel.removeAll(); + + JPanel animalPoolListPanel = GuiUtil.generatePanel("Animal pool List"); + JPanel criteriaListPanel = GuiUtil.generatePanel("criteria List"); + + ArrayList<SwimmingObject> liste = Icy.getMainInterface().getSwimmingPool().getObjects(); + animalList.clear(); + + Animal animalToGetCriteria = null; + for (SwimmingObject so : liste) + { + if (so.getObject() instanceof Animal) + { + animalList.add(new AnimalPoolSelector((Animal) so.getObject())); + animalToGetCriteria = (Animal) so.getObject(); + } + } + + if (animalToGetCriteria == null) // there is no more animal in pool + { + return; + } + + for (AnimalPoolSelector animalSelector : animalList) + { + animalPoolListPanel.add(animalSelector.panel); + } + + mainPanel.add(GuiUtil.besidesPanel(new JLabel("Bin Size ( nb frames )"), binSizeTextField, + new JLabel("Total time to compute ( nb frames )"), totalTimeTextField)); + // mainPanel.add( GuiUtil.besidesPanel ( displayLegendCheckBox , extractAllDataToGraphAndExcelMenuItem , extractDataToProbabilityGridButton ) ); + // mainPanel.add( GuiUtil.besidesPanel ( displayLegendCheckBox , extractDataToProbabilityGridMenuItem ) ); + // mainPanel.add( GuiUtil.besidesPanel ( displayLegendCheckBoxMenuItem ) ); + + // mainPanel.add( GuiUtil.besidesPanel( new JLabel("time window forward:") , extractDataToProbabilityTimeValue , extractCurrentDataGraphToExcelMenuItem + // ) ); + mainPanel.add(GuiUtil.besidesPanel(new JLabel("time window forward:"), extractDataToProbabilityTimeValue)); + mainPanel.add(GuiUtil.besidesPanel(new JLabel("FPS:"), fpsTextField)); + + eventSelectorList = new ArrayList<EventSelector>(); + + for (EventTimeLine et : animalToGetCriteria.eventTimeLineList) + { + EventSelector eventSelector = new EventSelector(animalToGetCriteria.eventTimeLineList.indexOf(et), et); + eventSelectorList.add(eventSelector); + + criteriaListPanel.add(eventSelector.panel); + } + + JPanel parameterPanel = new JPanel(new BorderLayout()); + + JScrollPane animalPoolListScrollPane = new JScrollPane(animalPoolListPanel, + JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS); + JScrollPane criteriaListScrollPane = new JScrollPane(criteriaListPanel, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, + JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS); + + parameterPanel.add(animalPoolListScrollPane, BorderLayout.WEST); + parameterPanel.add(criteriaListScrollPane, BorderLayout.CENTER); + + mainPanel.add(parameterPanel); + + graphFrame.getContentPane() + .add(new ChartPanel(chart, 700, 200, 700, 200, 700, 700, false, false, true, true, true, true)); + graphFrame.pack(); + + refreshGraph(false, ""); + + mainPanel.updateUI(); + + } + + @Override + public void swimmingPoolChangeEvent(SwimmingPoolEvent swimmingPoolEvent) + { + + refreshData(); + + } + + class EventSelector implements ActionListener + { + JPanel panel = GuiUtil.generatePanelWithoutBorder(); + int eventNumber; + JCheckBox nbEventCheckBox = new JCheckBox("nb Event"); + JCheckBox lengthCheckBox = new JCheckBox("length"); + JCheckBox densityCheckBox = new JCheckBox("density"); + JLabel criteriaLabel; + JCheckBox displayDiscreteValueCheckBox = new JCheckBox("discrete Value"); + + public EventSelector(int eventNumber, EventTimeLine e) + { + this.eventNumber = eventNumber; + + int maxSizeString = e.criteriaName.length(); + if (maxSizeString > 40) + maxSizeString = 40; + + criteriaLabel = new JLabel(e.criteriaName.substring(0, maxSizeString)); + criteriaLabel.setToolTipText(e.criteriaName); + + if (e.timeLineCategory == TimeLineCategory.USE_BOOLEAN_EVENT) + { + panel.add(GuiUtil.besidesPanel(criteriaLabel, densityCheckBox, nbEventCheckBox, lengthCheckBox)); + } + + if (e.timeLineCategory == TimeLineCategory.USE_DISCRETE_EVENT) + { + panel.add(GuiUtil.besidesPanel(criteriaLabel, displayDiscreteValueCheckBox)); + } + + densityCheckBox.addActionListener(this); + nbEventCheckBox.addActionListener(this); + lengthCheckBox.addActionListener(this); + displayDiscreteValueCheckBox.addActionListener(this); + + } + + @Override + public void actionPerformed(ActionEvent e) + { + refreshGraph(false, ""); + } + + } + + class AnimalPoolSelector implements ActionListener + { + JPanel panel = GuiUtil.generatePanelWithoutBorder(); + Animal animal; + + JCheckBox enable = new JCheckBox("Enable", true); + JRadioButton pool1 = new JRadioButton("Pool 1"); + JRadioButton pool2 = new JRadioButton("Pool 2"); + JRadioButton noPool = new JRadioButton("no pool", true); + + ButtonGroup poolGroup = new ButtonGroup(); + ButtonGroup carecterizationGroup = new ButtonGroup(); + + public AnimalPoolSelector(Animal animal) + { + + this.animal = animal; + + enable.addActionListener(this); + pool1.addActionListener(this); + pool2.addActionListener(this); + noPool.addActionListener(this); + + poolGroup.add(pool1); + poolGroup.add(pool2); + poolGroup.add(noPool); + + int maxSizeString = animal.animalName.length(); + if (maxSizeString > 5) + maxSizeString = 5; + + enable.setText(animal.animalName.substring(0, maxSizeString)); + enable.setToolTipText(animal.animalName); + + panel.add(GuiUtil.besidesPanel(new Component[] { + + enable, pool1, pool2, noPool} + + )); + + } + + @Override + public void actionPerformed(ActionEvent e) + { + refreshGraph(false, ""); + } + } + + @Override + public void actionPerformed(ActionEvent e) + { + + refreshGraph(false, ""); + + if (e.getSource() == extractCurrentDataGraphToExcelMenuItem) + { + extractCurrentDataGraphToExcel(); + } + + if (e.getSource() == extractAllDataToGraphAndExcelMenuItem) + { + exportAllData(); + } + + if (e.getSource() == extractDataToProbabilityGridMenuItem) + { + extractDataToProbabilityGrid2(); + } + + if (e.getSource() == extractCurrentDataGraphWithAllLabelDensityToExcelMenuItem) + { + extractDataGraphWithAllLabelDensityToExcel(); + } + + } + + /** + * Extract all the data by selecting all the different criteria, one by one. + */ + private void extractDataGraphWithAllLabelDensityToExcel() + { + String saveFileName = SaveDialog.chooseFile("Save xls file", "", "Mice Profiler - "); + + if (saveFileName == null) + return; + + for (EventSelector eventSelector : eventSelectorList) + { + for (EventSelector eventSelector2 : eventSelectorList) // clear all check boxes + { + eventSelector2.densityCheckBox.setSelected(false); + } + + eventSelector.densityCheckBox.setSelected(true); + + String eventLabel = eventSelector.criteriaLabel.getText().replaceAll("[^a-zA-Z0-9\\._]+", "_"); + String fileName = saveFileName + " - " + eventLabel + ".xls"; + + refreshGraph(true, fileName); + } + + } + + private void extractCurrentDataGraphToExcel() + { + + refreshGraph(true, null); + + } + + /** + * Extraction des grilles de proba de passage d'un etat a un autre sous feuille excel. + * Nouvelle version 2 (nov 2010) + */ + private void extractDataToProbabilityGrid2() + { + + System.out.println("export version nov 2010"); + + int timeWindow = Integer.parseInt(extractDataToProbabilityTimeValue.getText()); + int offsetY = 3; + int offsetX = 1; + + // XlsManager xls =null; + // try { + // xls = new XlsManager( System.getProperty("user.home") + "\\output "+(timeWindow-15)+"-"+timeWindow+"f.xls"); + // } catch (IOException e) { + // + // e.printStackTrace(); + // } + + // JTextField startTextField = new JTextField("0"); + + ActionDialog actionDialog = new ActionDialog("Select parameters for tansition graph."); + JPanel mainPanel = new JPanel(); + actionDialog.setPreferredSize(new Dimension(400, 400)); + actionDialog.getMainPanel().add(new JScrollPane(mainPanel)); + // actionDialog.getMainPanel().setLayout( new BoxLayout( actionDialog.getMainPanel() , BoxLayout.PAGE_AXIS )); + mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.PAGE_AXIS)); + animalList.get(0).animal.eventTimeLineList.size(); + + JTextField minProbability = new JTextField("0.3"); + mainPanel.add(GuiUtil.createLineBoxPanel(new JLabel("Min probability: "), minProbability)); + JTextField fpsTextField = new JTextField("15"); + mainPanel.add(GuiUtil.createLineBoxPanel(new JLabel("FPS: "), fpsTextField)); + JTextField maxNumberOfCandidateTextField = new JTextField("4"); + mainPanel + .add(GuiUtil.createLineBoxPanel(new JLabel("Max number of ancestor: "), maxNumberOfCandidateTextField)); + JCheckBox forceLocation = new JCheckBox("Force the location of the event in the graph (circular rendering)", + false); + mainPanel.add(GuiUtil.createLineBoxPanel(forceLocation)); + + HashMap<Integer, JCheckBox> selectedEventHashMap = new HashMap<Integer, JCheckBox>(); + + for (EventTimeLine event : animalList.get(0).animal.eventTimeLineList) + { + JCheckBox booleanField = new JCheckBox(event.criteriaName, true); + // actionDialog.getMainPanel().add( GuiUtil.createLineBoxPanel( booleanField ) ); + mainPanel.add(GuiUtil.createLineBoxPanel(booleanField)); + int index = animalList.get(0).animal.eventTimeLineList.indexOf(event); + selectedEventHashMap.put(index, booleanField); + if (index == 1) + booleanField.setSelected(false); + if (index >= 7 && index <= 10) + booleanField.setSelected(false); + if (index >= 13 && index <= 20) + booleanField.setSelected(false); + if (index >= 27) + booleanField.setSelected(false); + + } + actionDialog.pack(); + actionDialog.setLocationRelativeTo(null); + actionDialog.setVisible(true); + + if (actionDialog.isCanceled()) + return; + + float fps = Float.parseFloat(fpsTextField.getText()); + int MAX_NUMBER_OF_CANDIDATE = Integer.parseInt(maxNumberOfCandidateTextField.getText()); + + System.out.println("WARNING:"); + System.out.println( + "This output consider all the loaded animal in the Label Analyser as coming from the same pool."); + System.out.println("i.e. only 1 pool is considered."); + System.out.println("version Jan 2013. p>0.1 instead of p>0.3"); + + int nbTotalDeCritere = animalList.get(0).animal.eventTimeLineList.size(); + + float poolProba0_4[][][] = new float[animalList.size()][nbTotalDeCritere][nbTotalDeCritere]; + float poolProba4_8[][][] = new float[animalList.size()][nbTotalDeCritere][nbTotalDeCritere]; + + for (int animalNumber = 0; animalNumber < animalList.size(); animalNumber++) + { + Animal animal = animalList.get(animalNumber).animal; + // xls.createNewPage( animal.animalName ); + + // xls.setLabel( 0 , 0 , "se lit: event de la colonne x a une proba p d etre precede par ligne y"); + // xls.setLabel( 0 , 1 , "timeforward(frames):" + (timeWindow-15) + " to " + timeWindow ); + // xls.setLabel( 0 , 2 , "animal:" + animal.animalName ); + + // int FENETRE_RECHERCHE_FRAME = 15*3; + int FENETRE_RECHERCHE_FRAME = (int) (fps * 3); + + for (int eventNumberSource = 0; eventNumberSource < animal.eventTimeLineList.size(); eventNumberSource++) // parcours la liste des events. + { + + // xls.setNumber( 2*eventNumberSource+1 + offsetX, 0 + offsetY , eventNumberSource + 1 ); + + for (int eventNumberTarget = 0; eventNumberTarget < animal.eventTimeLineList + .size(); eventNumberTarget++) // parcours la liste des events. + { + + // xls.setNumber( 0 + offsetX , eventNumberTarget+1 + offsetY , eventNumberTarget + 1 ); + // xls.setLabel( 0 , eventNumberTarget+1 + offsetY , animalList.get( 0 ).animal.eventTimeLineList.get( eventNumberTarget ).criteriaName ); + + EventTimeLine eventTimeLineSource = animal.eventTimeLineList.get(eventNumberSource); + EventTimeLine eventTimeLineTarget = animal.eventTimeLineList.get(eventNumberTarget); + + float nbEventSource04 = 0; + float nbEventTarget04 = 0; + float nbPassageSourceTargetOk04 = 0; + float nbPassageTargetSourceOk04 = 0; + + for (EventCriteria eventCriteriaSource : eventTimeLineSource.eventList) + { + if (eventCriteriaSource.startFrame > 3600) + continue; + nbEventSource04++; + + for (EventCriteria eventCriteriaTarget : eventTimeLineTarget.eventList) + { + if (eventCriteriaTarget.startFrame > 3600) + continue; + + if (eventCriteriaTarget.startFrame >= eventCriteriaSource.endFrame + && eventCriteriaTarget.startFrame <= eventCriteriaSource.endFrame + + FENETRE_RECHERCHE_FRAME) + { + nbPassageSourceTargetOk04++; + break; + } + } + } + + for (EventCriteria eventCriteriaTarget : eventTimeLineTarget.eventList) + { + if (eventCriteriaTarget.startFrame > 3600) + continue; + nbEventTarget04++; + + for (EventCriteria eventCriteriaSource : eventTimeLineSource.eventList) + { + if (eventCriteriaSource.startFrame > 3600) + continue; + if (eventCriteriaTarget.startFrame >= eventCriteriaSource.endFrame + && eventCriteriaTarget.startFrame <= eventCriteriaSource.endFrame + + FENETRE_RECHERCHE_FRAME) + { + nbPassageTargetSourceOk04++; + break; + } + } + } + + float probaStoT04 = nbPassageSourceTargetOk04 / nbEventSource04; + float probaTtoS04 = nbPassageTargetSourceOk04 / nbEventTarget04; + float proba2Way04 = probaStoT04 * probaTtoS04; + + float nbEventSource48 = 0; + float nbEventTarget48 = 0; + float nbPassageSourceTargetOk48 = 0; + float nbPassageTargetSourceOk48 = 0; + + for (EventCriteria eventCriteriaSource : eventTimeLineSource.eventList) + { + if (eventCriteriaSource.startFrame < 3600) + continue; + nbEventSource48++; + + for (EventCriteria eventCriteriaTarget : eventTimeLineTarget.eventList) + { + if (eventCriteriaTarget.startFrame < 3600) + continue; + + if (eventCriteriaTarget.startFrame >= eventCriteriaSource.endFrame + && eventCriteriaTarget.startFrame <= eventCriteriaSource.endFrame + + FENETRE_RECHERCHE_FRAME) + { + nbPassageSourceTargetOk48++; + break; + } + } + } + + for (EventCriteria eventCriteriaTarget : eventTimeLineTarget.eventList) + { + if (eventCriteriaTarget.startFrame < 3600) + continue; + nbEventTarget48++; + + for (EventCriteria eventCriteriaSource : eventTimeLineSource.eventList) + { + if (eventCriteriaSource.startFrame < 3600) + continue; + if (eventCriteriaTarget.startFrame >= eventCriteriaSource.endFrame + && eventCriteriaTarget.startFrame <= eventCriteriaSource.endFrame + + FENETRE_RECHERCHE_FRAME) + { + nbPassageTargetSourceOk48++; + break; + } + } + } + + float probaStoT48 = nbPassageSourceTargetOk48 / nbEventSource48; + float probaTtoS48 = nbPassageTargetSourceOk48 / nbEventTarget48; + float proba2Way48 = probaStoT48 * probaTtoS48; + + if (eventNumberSource != 9 && eventNumberSource != 10 && eventNumberTarget != 9 + && eventNumberTarget != 10) // enleve le speed + { + poolProba0_4[animalNumber][eventNumberSource][eventNumberTarget] = proba2Way04; + poolProba4_8[animalNumber][eventNumberSource][eventNumberTarget] = proba2Way48; + } + + } + } + + } + + float meanAnimalProba0_4[][] = new float[nbTotalDeCritere][nbTotalDeCritere]; + float stddevAnimalProba0_4[][] = new float[nbTotalDeCritere][nbTotalDeCritere]; + float meanAnimalProba4_8[][] = new float[nbTotalDeCritere][nbTotalDeCritere]; + float stddevAnimalProba4_8[][] = new float[nbTotalDeCritere][nbTotalDeCritere]; + + for (int eventNumberSource = 0; eventNumberSource < nbTotalDeCritere; eventNumberSource++) // parcours la liste des events. + { + for (int eventNumberTarget = 0; eventNumberTarget < nbTotalDeCritere; eventNumberTarget++) // parcours la liste des events. + { + float[] tabProba = new float[animalList.size()]; + for (int animalNumber = 0; animalNumber < animalList.size(); animalNumber++) + { + tabProba[animalNumber] = poolProba0_4[animalNumber][eventNumberSource][eventNumberTarget]; + meanAnimalProba0_4[eventNumberSource][eventNumberTarget] += poolProba0_4[animalNumber][eventNumberSource][eventNumberTarget]; + + } + meanAnimalProba0_4[eventNumberSource][eventNumberTarget] /= animalList.size(); + stddevAnimalProba0_4[eventNumberSource][eventNumberTarget] = flanagan.analysis.Stat + .standardDeviation(tabProba); + ; + } + } + + for (int eventNumberSource = 0; eventNumberSource < nbTotalDeCritere; eventNumberSource++) // parcours la liste des events. + { + for (int eventNumberTarget = 0; eventNumberTarget < nbTotalDeCritere; eventNumberTarget++) // parcours la liste des events. + { + float[] tabProba = new float[animalList.size()]; + for (int animalNumber = 0; animalNumber < animalList.size(); animalNumber++) + { + tabProba[animalNumber] = poolProba4_8[animalNumber][eventNumberSource][eventNumberTarget]; + meanAnimalProba4_8[eventNumberSource][eventNumberTarget] += poolProba4_8[animalNumber][eventNumberSource][eventNumberTarget]; + + } + meanAnimalProba4_8[eventNumberSource][eventNumberTarget] /= animalList.size(); + stddevAnimalProba4_8[eventNumberSource][eventNumberTarget] = flanagan.analysis.Stat + .standardDeviation(tabProba); + ; + } + } + + ArrayList<ArrayList<EventResult>> resultatParSource0_4 = new ArrayList<ArrayList<EventResult>>(); + ArrayList<ArrayList<EventResult>> resultatParSource4_8 = new ArrayList<ArrayList<EventResult>>(); + + // int MAX_NUMBER_OF_CANDIDATE = 4; // was 4 + + { + for (int nbEventTarget = 0; nbEventTarget < nbTotalDeCritere; nbEventTarget++) + { + ArrayList<EventResult> eventResultList = new ArrayList<EventResult>(); + for (int nbEventSource = 0; nbEventSource < nbTotalDeCritere; nbEventSource++) + { + JCheckBox eTarget = selectedEventHashMap.get(nbEventTarget); + JCheckBox eSource = selectedEventHashMap.get(nbEventSource); + if (!eTarget.isSelected() || !eSource.isSelected()) + continue; + + /* + * if ( nbEventTarget == 1 || nbEventSource == 1 ) continue; + * if ( nbEventTarget == 7 || nbEventSource == 7 ) continue; + * if ( nbEventTarget == 8 || nbEventSource == 8 ) continue; + * if ( nbEventTarget == 9 || nbEventSource == 9 ) continue; + * if ( nbEventTarget == 10 || nbEventSource == 10 ) continue; + * if ( nbEventTarget == 13 || nbEventSource == 13 ) continue; + * if ( nbEventTarget == 14 || nbEventSource == 14 ) continue; + * if ( nbEventTarget == 15 || nbEventSource == 15 ) continue; + * if ( nbEventTarget == 16 || nbEventSource == 16 ) continue; + * if ( nbEventTarget == 17 || nbEventSource == 17 ) continue; + * if ( nbEventTarget == 18 || nbEventSource == 18 ) continue; + * if ( nbEventTarget == 19 || nbEventSource == 19 ) continue; + * if ( nbEventTarget == 20 || nbEventSource == 20 ) continue; + * if ( nbEventTarget >= 27 || nbEventSource >= 27 ) continue; + */ + + float probaProposee = meanAnimalProba0_4[nbEventSource][nbEventTarget]; + float stddevPropose = stddevAnimalProba0_4[nbEventSource][nbEventTarget]; + + ArrayList<EventResult> eventResultListClone = (ArrayList<EventResult>) eventResultList.clone(); + + for (EventResult resultClient : eventResultListClone) + { + if (resultClient.proba < probaProposee) + { + eventResultList.remove(resultClient); + break; + } + } + + if (eventResultList.size() < MAX_NUMBER_OF_CANDIDATE) + { + EventResult result = new EventResult(nbEventSource, nbEventTarget, probaProposee, stddevPropose, + "red"); + eventResultList.add(result); + } + + } + resultatParSource0_4.add(eventResultList); + + } + } + + { + + for (int nbEventTarget = 0; nbEventTarget < nbTotalDeCritere; nbEventTarget++) + { + ArrayList<EventResult> eventResultList = new ArrayList<EventResult>(); + for (int nbEventSource = 0; nbEventSource < nbTotalDeCritere; nbEventSource++) + { + JCheckBox eTarget = selectedEventHashMap.get(nbEventTarget); + JCheckBox eSource = selectedEventHashMap.get(nbEventSource); + if (!eTarget.isSelected() || !eSource.isSelected()) + continue; + // + // if ( nbEventTarget == 1 || nbEventSource == 1 ) continue; + // if ( nbEventTarget == 7 || nbEventSource == 7 ) continue; + // if ( nbEventTarget == 8 || nbEventSource == 8 ) continue; + // if ( nbEventTarget == 9 || nbEventSource == 9 ) continue; + // if ( nbEventTarget == 10 || nbEventSource == 10 ) continue; + // if ( nbEventTarget == 13 || nbEventSource == 13 ) continue; + // if ( nbEventTarget == 14 || nbEventSource == 14 ) continue; + // if ( nbEventTarget == 15 || nbEventSource == 15 ) continue; + // if ( nbEventTarget == 16 || nbEventSource == 16 ) continue; + // if ( nbEventTarget == 17 || nbEventSource == 17 ) continue; + // if ( nbEventTarget == 18 || nbEventSource == 18 ) continue; + // if ( nbEventTarget == 19 || nbEventSource == 19 ) continue; + // if ( nbEventTarget == 20 || nbEventSource == 20 ) continue; + // if ( nbEventTarget >= 27 || nbEventSource >= 27 ) continue; + + float probaProposee = meanAnimalProba4_8[nbEventSource][nbEventTarget]; + float stddevPropose = stddevAnimalProba4_8[nbEventSource][nbEventTarget]; + + ArrayList<EventResult> eventResultListClone = (ArrayList<EventResult>) eventResultList.clone(); + + for (EventResult resultClient : eventResultListClone) + { + if (resultClient.proba < probaProposee) + { + eventResultList.remove(resultClient); + break; + } + } + + if (eventResultList.size() < MAX_NUMBER_OF_CANDIDATE) + { + EventResult result = new EventResult(nbEventSource, nbEventTarget, probaProposee, stddevPropose, + "green"); + eventResultList.add(result); + } + + } + resultatParSource4_8.add(eventResultList); + + } + } + + // GRAPH: + + boolean FORCE_LOCATION = forceLocation.isSelected(); + + System.out.println("Put the following script in GraphViz:"); + if (FORCE_LOCATION) + { + System.out.println("/* @command = neato **/"); + } + System.out.println("digraph {"); + System.out.println("splines=true;"); + + // set the location of each available event + + if (FORCE_LOCATION) + { + double x = 0; + double y = 0; + double angle = 0; + + for (int eventIndex = 0; eventIndex < nbTotalDeCritere; eventIndex++) + { + JCheckBox eventBox = selectedEventHashMap.get(eventIndex); + if (!eventBox.isSelected()) + continue; + // + // if( eventIndex == 1 ) continue; + // if( eventIndex == 7 ) continue; + // if( eventIndex == 8 ) continue; + // if( eventIndex == 9 ) continue; + // if( eventIndex == 10 ) continue; + // if( eventIndex == 13 ) continue; + // if( eventIndex == 14 ) continue; + // if( eventIndex == 15 ) continue; + // if( eventIndex == 16 ) continue; + // if( eventIndex == 17 ) continue; + // if( eventIndex == 18 ) continue; + // if( eventIndex == 19 ) continue; + // if( eventIndex == 20 ) continue; + // if( eventIndex >= 27 ) continue; + + x = 300 + Math.cos(angle) * 300; + y = 300 + Math.sin(angle) * 300; + + String criteriaName = animalList.get(0).animal.eventTimeLineList.get(eventIndex).criteriaName; + // criteriaName = keepFirstChars(criteriaName); + + String result = "\"" + criteriaName + "\""; + result += "["; + result += " pos=\"" + x + "," + y + "!" + "\" "; + result += " shape=\"box\" "; + result += " width=\"2\" "; + result += "]"; + + System.out.println(result); + + angle += (Math.PI * 2d) / 14d; + + // x+=200; + // if ( x > 100 ) + // { + // y+=100; + // x=0; + // } + + } + + } + + // animalList.get( 0 ).animal.eventTimeLineList.get( eventSource ).criteriaName + + // create graph + + for (int sourceList = 0; sourceList < nbTotalDeCritere; sourceList++) + { + ArrayList<EventResult> eventResultList0_4 = resultatParSource0_4.get(sourceList); + ArrayList<EventResult> eventResultList4_8 = resultatParSource4_8.get(sourceList); + + ArrayList<EventResult> finalResult = createCommonList(eventResultList0_4, eventResultList4_8); + + for (EventResult eventResult : finalResult) + { + if (eventResult.enable) + { + if (eventResult.proba >= 0.1f) // was 0.3f + { + System.out.println(eventResult); + } + else + { + + } + } + } + + } + + System.out.println("}"); + + // xls.SaveAndClose(); + + } + + ArrayList<EventResult> createCommonList(ArrayList<EventResult> eventResultList0_4, + ArrayList<EventResult> eventResultList4_8) + { + ArrayList<EventResult> finalResult = new ArrayList<EventResult>(); + for (EventResult eventResult0_4 : eventResultList0_4) + { + finalResult.add(eventResult0_4); + } + for (EventResult eventResult4_8 : eventResultList4_8) + { + finalResult.add(eventResult4_8); + } + + for (EventResult eventResultA : finalResult) + { + for (EventResult eventResultB : finalResult) + { + if (eventResultA != eventResultB && eventResultA.enable && eventResultB.enable + && eventResultA.eventSource == eventResultB.eventSource + && eventResultA.eventTarget == eventResultB.eventTarget + && checkIfProbaOverlap(eventResultA, eventResultB)) + { + eventResultA.proba = (eventResultA.proba + eventResultB.proba) / 2f; + eventResultB.enable = false; + eventResultA.color = "black"; + } + + } + } + + return finalResult; + } + + private boolean checkIfProbaOverlap(EventResult eventResultA, EventResult eventResultB) + { + float sigma = 1f; + + float borneMinA = eventResultA.proba - eventResultA.stddev * sigma; + float borneMaxA = eventResultA.proba + eventResultA.stddev * sigma; + + float borneMinB = eventResultB.proba - eventResultB.stddev * sigma; + float borneMaxB = eventResultB.proba + eventResultB.stddev * sigma; + + if (borneMinA > borneMinB && borneMinA < borneMaxB) + return true; + if (borneMaxA > borneMinB && borneMaxA < borneMaxB) + return true; + + return false; + } + + class ProbaResult + { + public ProbaResult(float proba, float stddev, int startFrame) + { + this.stddev = stddev; + this.proba = proba; + this.startFrame = startFrame; + } + + float stddev; + float proba; + int startFrame; + } + + class EventResult + { + boolean enable = true; + + public EventResult(int eventSource, int eventTarget, float proba, float stddev, String color) + { + this.eventSource = eventSource; + this.eventTarget = eventTarget; + this.stddev = stddev; + this.proba = proba; + this.color = color; + } + + float stddev; + int eventSource; + int eventTarget; + float proba; + String color; + + @Override + public String toString() + { + + String result = ""; + result += "\"" + keepFirstChars(animalList.get(0).animal.eventTimeLineList.get(eventSource).criteriaName) + + "\""; + result += "->"; + result += "\"" + keepFirstChars(animalList.get(0).animal.eventTimeLineList.get(eventTarget).criteriaName) + + "\""; + result += " "; + result += "[ "; + result += "color=\"" + color + "\""; + result += " style=\"setlinewidth(" + proba * 5 + ")\"]"; + result += ";"; + + return result; + } + + /** + * Just provide the name of events. Without link. + * + * @return + */ + public String getEvents() + { + String result = ""; + result += "\"" + keepFirstChars(animalList.get(0).animal.eventTimeLineList.get(eventSource).criteriaName) + + "\""; + result += ";"; + result += "\"" + keepFirstChars(animalList.get(0).animal.eventTimeLineList.get(eventTarget).criteriaName) + + "\""; + result += ";"; + return result; + } + + } + + public static String keepFirstChars(String s) + { + int MAXSIZE = 20; + if (s.length() > MAXSIZE) + s = (String) s.substring(0, MAXSIZE); + return s; + } + + void exportAllData() + { + System.out.println("export all data in pool to excel."); + + // export pool 1 + + // String saveFileName = SaveDialog.chooseFile("Export all data to xls file", System.getProperty("user.home") ,"output.xls", ".xls"); + + JTextField startTextField = new JTextField("0"); + JTextField endTextField = new JTextField("8"); + + ActionDialog actionDialog = new ActionDialog("Select range (in minutes)"); + actionDialog.getMainPanel().setLayout(new BoxLayout(actionDialog.getMainPanel(), BoxLayout.PAGE_AXIS)); + actionDialog.getMainPanel().add(GuiUtil.createLineBoxPanel(new JLabel("start (minutes)"), startTextField)); + actionDialog.getMainPanel().add(GuiUtil.createLineBoxPanel(new JLabel("end (minutes)"), endTextField)); + actionDialog.pack(); + actionDialog.setLocationRelativeTo(null); + actionDialog.setVisible(true); + + if (actionDialog.isCanceled()) + return; + + float startMinute = Float.parseFloat(startTextField.getText()); + float endMinute = Float.parseFloat(endTextField.getText()); + + String saveFileName = SaveDialog.chooseFile("Save xls file", "", "Mice Profiler - all data", ".xls"); + + if (saveFileName == null) + return; + XlsManager xls = null; + + try + { + + xls = new XlsManager(saveFileName); + xls.createNewPage("Data in pool"); + + } + catch (IOException e) + { + + e.printStackTrace(); + } + + xls.createNewPage("Results"); + + int cursorY = 0; + + for (EventSelector eventSelector : eventSelectorList) + { + String eventTitle = animalList.get(0).animal.eventTimeLineList.get(eventSelector.eventNumber).criteriaName; + + xls.setLabel(0, cursorY, "Event #" + eventSelector.eventNumber, Colour.YELLOW); + cursorY++; + xls.setLabel(0, cursorY, eventTitle); + cursorY += 2; + + cursorY = exportXLSPool(1, eventSelector, cursorY, xls, startMinute, endMinute); + cursorY += 3; + cursorY = exportXLSPool(2, eventSelector, cursorY, xls, startMinute, endMinute); + cursorY += 4; + } + + xls.SaveAndClose(); + + } + + int exportXLSPool(int pool, EventSelector eventSelector, int cursorY, XlsManager xls, float startMinute, + float endMinute) + { + float halfMinute = (endMinute + startMinute) / 2f; + + xls.setLabel(0, cursorY, "p" + pool); + // xls.setLabel( 1, cursorY, "nb e 0-4" ); + xls.setLabel(1, cursorY, "nb event from " + startMinute + " to " + halfMinute + " minutes"); + // xls.setLabel( 2, cursorY, "nb e 4-8" ); + xls.setLabel(2, cursorY, "nb event from " + halfMinute + " to " + endMinute + " minutes"); + // xls.setLabel( 3, cursorY, "nb e 0-8" ); + xls.setLabel(3, cursorY, "nb event from " + startMinute + " to " + endMinute + " minutes"); + + // xls.setLabel( 4, cursorY, "l e 0-4" ); + xls.setLabel(4, cursorY, "length of event from " + startMinute + " to " + halfMinute + " minutes"); + // xls.setLabel( 5, cursorY, "l e 4-8" ); + xls.setLabel(5, cursorY, "length of event from " + halfMinute + " to " + endMinute + " minutes"); + // xls.setLabel( 6, cursorY, "l e 0-8" ); + xls.setLabel(6, cursorY, "length of event from " + startMinute + " to " + endMinute + " minutes"); + + float fps = Float.parseFloat(fpsTextField.getText()); + + cursorY++; + + for (AnimalPoolSelector animalSelector : animalList) + { + if (pool == 1 && animalSelector.pool1.isSelected() || pool == 2 && animalSelector.pool2.isSelected()) + { + if (animalSelector.enable.isSelected()) + { + xls.setLabel(0, cursorY, animalSelector.animal.animalName); + + Animal animal = animalSelector.animal; + EventTimeLine eventTimeLine = animal.eventTimeLineList.get(eventSelector.eventNumber); + + // boolean debug = false; + + // nb event e 0-4 le + // if ( debug ) System.out.println("0-4"); + { + int nb = 0; + int length = 0; + + // int maxTime = (int) (4*60*fps); + int maxTime = (int) (halfMinute * 60 * fps); + int minTime = (int) (startMinute * 60 * fps); + + for (EventCriteria event : eventTimeLine.eventList) + { + if (event.startFrame < maxTime && event.startFrame >= minTime) + { + nb++; + length += event.getLength(); + // if ( debug ) + // { + // System.out.println( eventTimeLine.eventList.indexOf( event ) + ">" + event.getLength() ); + // } + } + } + xls.setNumber(1, cursorY, nb); + xls.setNumber(4, cursorY, length); + // if ( debug ) + // { + // System.out.println( "nb event"+nb ); + // System.out.println( "length event"+length ); + // } + + } + + // nb event e 4-8 le + // if ( debug ) System.out.println("4-8"); + { + int nb = 0; + int length = 0; + + // int minTime = (int)(4d*60d*fps); + int minTime = (int) (halfMinute * 60d * fps); + int maxTime = (int) (endMinute * 60 * fps); + for (EventCriteria event : eventTimeLine.eventList) + { + if (event.startFrame < maxTime && event.startFrame > minTime) + { + nb++; + length += event.getLength(); + // if ( debug ) + // { + // System.out.println( eventTimeLine.eventList.indexOf( event ) + ">" + event.getLength() ); + // } + } + } + xls.setNumber(2, cursorY, nb); + xls.setNumber(5, cursorY, length); + // if ( debug ) + // { + // System.out.println( "nb event"+nb ); + // System.out.println( "length event"+length ); + // } + + } + + // nb event e 0-8 le + // if ( debug ) System.out.println("0-8"); + { + int nb = 0; + int length = 0; + int minTime = (int) (startMinute * 60d * fps); + // int maxTime = (int) (8*60*fps); + int maxTime = (int) (endMinute * 60 * fps); + for (EventCriteria event : eventTimeLine.eventList) + { + if (event.startFrame < maxTime && event.startFrame > minTime) + { + nb++; + length += event.getLength(); + // if ( debug ) + // { + // System.out.println( eventTimeLine.eventList.indexOf( event ) + ">" + event.getLength() ); + // } + } + } + xls.setNumber(3, cursorY, nb); + xls.setNumber(6, cursorY, length); + // if ( debug ) + // { + // System.out.println( "nb event"+nb ); + // System.out.println( "length event"+length ); + // } + + } + + cursorY++; + + } + } + } + return cursorY; + } + +} \ No newline at end of file diff --git a/src/main/java/plugins/fab/MiceProfiler/MiceProfilerVideoLabelMaker.java b/src/main/java/plugins/fab/MiceProfiler/MiceProfilerVideoLabelMaker.java index 1ac656dbe67880cc3a243a02cca771f44e2f72f8..e48ecbad706b9eb75f0043ee798eed8aabcb3f26 100644 --- a/src/main/java/plugins/fab/MiceProfiler/MiceProfilerVideoLabelMaker.java +++ b/src/main/java/plugins/fab/MiceProfiler/MiceProfilerVideoLabelMaker.java @@ -18,5383 +18,25 @@ */ package plugins.fab.MiceProfiler; -import java.awt.BasicStroke; -import java.awt.BorderLayout; -import java.awt.Color; -import java.awt.Dimension; -import java.awt.Font; -import java.awt.Graphics; -import java.awt.Graphics2D; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.awt.event.KeyEvent; -import java.awt.event.KeyListener; -import java.awt.event.MouseEvent; -import java.awt.event.MouseListener; -import java.awt.event.MouseMotionListener; -import java.awt.geom.Ellipse2D; -import java.awt.geom.Point2D; -import java.awt.image.BufferedImage; -import java.io.File; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.lang.reflect.Field; -import java.text.DecimalFormat; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.Iterator; -import java.util.Scanner; -import java.util.prefs.Preferences; +import icy.plugin.abstract_.PluginActionable; -import javax.imageio.ImageIO; -import javax.swing.BoxLayout; -import javax.swing.ImageIcon; -import javax.swing.JButton; -import javax.swing.JCheckBox; -import javax.swing.JFileChooser; -import javax.swing.JLabel; -import javax.swing.JMenu; -import javax.swing.JMenuBar; -import javax.swing.JMenuItem; -import javax.swing.JPanel; -import javax.swing.JScrollPane; -import javax.swing.JTextField; -import javax.swing.SwingConstants; -import javax.xml.xpath.XPath; -import javax.xml.xpath.XPathConstants; -import javax.xml.xpath.XPathExpressionException; -import javax.xml.xpath.XPathFactory; - -import org.jfree.chart.ChartFactory; -import org.jfree.chart.ChartPanel; -import org.jfree.chart.JFreeChart; -import org.jfree.chart.plot.PlotOrientation; -import org.jfree.data.xy.XYSeries; -import org.jfree.data.xy.XYSeriesCollection; -import org.jfree.data.xy.YIntervalSeriesCollection; -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.w3c.dom.NodeList; - -import icy.file.FileUtil; -import icy.file.Loader; -import icy.file.Saver; -import icy.file.xls.XlsManager; -import icy.gui.dialog.MessageDialog; -import icy.gui.frame.IcyFrame; -import icy.gui.frame.progress.AnnounceFrame; -import icy.gui.frame.progress.ToolTipFrame; -import icy.gui.util.FontUtil; -import icy.gui.util.GuiUtil; -import icy.image.IcyBufferedImage; -import icy.image.IcyBufferedImageUtil; -import icy.main.Icy; -import icy.plugin.abstract_.Plugin; -import icy.plugin.interface_.PluginBundled; -import icy.plugin.interface_.PluginImageAnalysis; -import icy.sequence.Sequence; -import icy.swimmingPool.SwimmingObject; -import icy.type.DataType; -import icy.util.XLSUtil; -import icy.util.XMLUtil; -import jxl.Sheet; -import jxl.Workbook; -import jxl.read.biff.BiffException; -import jxl.write.WritableSheet; -import jxl.write.WritableWorkbook; -import jxl.write.WriteException; - -public class MiceProfilerVideoLabelMaker extends Plugin implements PluginImageAnalysis, PluginBundled,ActionListener, KeyListener +/** + * Just for backward compatibility (plugin is now bundled in Mice Profiler Tracker) + */ +public class MiceProfilerVideoLabelMaker extends PluginActionable { + final MiceProfilerVideoLabelMakerInternal implementer; - JPanel mainPanel = new JPanel(); - IcyFrame mainFrame = new IcyFrame("Video Label Maker", true, true, true, true); - JMenuBar menuBar = new JMenuBar(); - JMenuItem openFileMenuItem = new JMenuItem("Open XML File..."); - JMenuItem compileImageFileMenuItem = new JMenuItem("Compile image files from a list of file..."); - JMenuItem mergeHeatMapMenuItem = new JMenuItem("Stitch heatmap files..."); - - JScrollPane scrollPane = new JScrollPane(mainPanel); - JPanel setupPanel = GuiUtil.generatePanel("Setup"); - JLabel legendLabel = new JLabel("Legend", JLabel.CENTER); - JTextField scaleTextField = new JTextField("0.22"); - JTextField scaleVideoTextField = new JTextField("1"); - - int START_MINUTE = 0; - int NB_MINUTE = 8; - - float SEUIL_DISTANCE_1 = 22; - float SEUIL_DISTANCE_2 = 40; - float SEUIL_DISTANCE_HEAD_HEAD = 15; - float SEUIL_DISTANCE_HEAD_GENITAL = 15; - float SEUIL_SIDE = 12; - float SPEED_THRESHOLD_1 = (float) 0.5f; - float SPEED_THRESHOLD_2 = 2; - float SPEED_THRESHOLD_3 = 4; - float FPS = 15f; - float LOAD_FRAME_START = 0f; - float LOAD_FRAME_END = 10000000f; - float SCALE = 0.22f; - - JTextField distance1TextField = new JTextField(); - JTextField distance2TextField = new JTextField(); - JTextField distanceHeadHeadTextField = new JTextField(); - JTextField distanceHeadGenitalTextField = new JTextField(); - JTextField seuilSideTextField = new JTextField(); - JTextField speed_threshold1TextField = new JTextField(); - JTextField speed_threshold2TextField = new JTextField(); - JTextField speed_threshold3TextField = new JTextField(); - JTextField fpsTextField = new JTextField(); - // JTextField loadFrameStartTextField = new JTextField(); - // JTextField loadFrameEndTextField = new JTextField(); - JTextField computeImageStartMinuteTextField = new JTextField(); - JTextField computeImageNbMinuteTextField = new JTextField(); - JButton refreshButton = new JButton("Refresh Data with new parameters"); - - BufferedImage videoImage = new BufferedImage(200, 200, BufferedImage.TYPE_INT_BGR); - ImageComponent imageVideoComponent = new ImageComponent(); - JLabel videoTimeLabel = new JLabel("", JLabel.CENTER); - int stepY = 15; - - @Override - public void compute() - { - - mainFrame.pack(); - - mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.Y_AXIS)); - - videoTimeLabel.setFont(new Font("Arial", Font.BOLD, 15)); - legendLabel.setFont(new Font("Arial", Font.BOLD, 20)); - - JMenu fileMenu = new JMenu("File"); - fileMenu.add(openFileMenuItem); - openFileMenuItem.addActionListener(this); - fileMenu.addSeparator(); - fileMenu.add(compileImageFileMenuItem); - compileImageFileMenuItem.addActionListener(this); - fileMenu.add(mergeHeatMapMenuItem); - mergeHeatMapMenuItem.addActionListener(this); - - menuBar.add(fileMenu); - - mainFrame.setJMenuBar(menuBar); - - JPanel sidePanel = new JPanel(); - sidePanel.setLayout(new BorderLayout()); - JPanel videoPanel = GuiUtil.generatePanel("video"); - imageVideoComponent.setImage(videoImage); - // ComponentUtil.setFixedWidth( imageVideoComponent , 400 ); - videoPanel.add(GuiUtil.besidesPanel(imageVideoComponent)); - videoPanel.add(GuiUtil.besidesPanel(videoTimeLabel)); - - sidePanel.add(setupPanel, BorderLayout.NORTH); - sidePanel.add(videoPanel, BorderLayout.CENTER); - - mainFrame.getContentPane().setLayout(new BorderLayout()); - mainFrame.getContentPane().add(sidePanel, BorderLayout.EAST); - mainFrame.getContentPane().add(legendLabel, BorderLayout.SOUTH); - - mainFrame.getContentPane().add(scrollPane, BorderLayout.CENTER); - scrollPane.setPreferredSize(new Dimension(800, 450)); - - distance1TextField.setText("" + SEUIL_DISTANCE_1); - distance2TextField.setText("" + SEUIL_DISTANCE_2); - distanceHeadHeadTextField.setText("" + SEUIL_DISTANCE_HEAD_HEAD); - distanceHeadGenitalTextField.setText("" + SEUIL_DISTANCE_HEAD_GENITAL); - seuilSideTextField.setText("" + SEUIL_SIDE); - speed_threshold1TextField.setText("" + SPEED_THRESHOLD_1); - speed_threshold2TextField.setText("" + SPEED_THRESHOLD_2); - speed_threshold3TextField.setText("" + SPEED_THRESHOLD_3); - fpsTextField.setText("" + FPS); - // loadFrameStartTextField.setText( ""+LOAD_FRAME_START ); - // loadFrameEndTextField.setText( ""+LOAD_FRAME_END ); - computeImageStartMinuteTextField.setText("" + START_MINUTE); - computeImageNbMinuteTextField.setText("" + NB_MINUTE); - - setupPanel.add(GuiUtil.besidesPanel(new JLabel("Distance Threshold 1(closest) in px:"), distance1TextField)); - setupPanel.add(GuiUtil.besidesPanel(new JLabel("Distance Threshold 2 in px:"), distance2TextField)); - setupPanel.add(GuiUtil.besidesPanel(new JLabel("Distance Head-Head in px:"), distanceHeadHeadTextField)); - setupPanel - .add(GuiUtil.besidesPanel(new JLabel("Distance Head-Genital 2 in px:"), distanceHeadGenitalTextField)); - setupPanel.add(GuiUtil.besidesPanel(new JLabel("Side detection Parameter in px:"), seuilSideTextField)); - setupPanel.add(GuiUtil.besidesPanel(new JLabel("Speed Threshold 1 (black) in px:"), speed_threshold1TextField)); - setupPanel.add(GuiUtil.besidesPanel(new JLabel("Speed Threshold 2 (gray) in px:"), speed_threshold2TextField)); - setupPanel.add( - GuiUtil.besidesPanel(new JLabel("Speed Threshold 3 (lightgray) in px:"), speed_threshold3TextField)); - setupPanel.add(GuiUtil.besidesPanel(new JLabel("FPS:"), fpsTextField)); - // setupPanel.add( GuiUtil.besidesPanel( new JLabel("Load frame start:" ) , loadFrameStartTextField) ); - // setupPanel.add( GuiUtil.besidesPanel( new JLabel("Load frame end:" ) , loadFrameEndTextField) ); - setupPanel.add(GuiUtil.besidesPanel(new JLabel("Computation Start Minute:"), computeImageStartMinuteTextField)); - setupPanel.add(GuiUtil.besidesPanel(new JLabel("Computation End Minute:"), computeImageNbMinuteTextField)); - setupPanel.add(GuiUtil.besidesPanel(new JLabel("Mouse Scale"), scaleTextField)); - setupPanel.add(GuiUtil.besidesPanel(new JLabel("Video Image display scale"), scaleVideoTextField)); - - setupPanel.add(GuiUtil.besidesPanel(refreshButton)); - refreshButton.addActionListener(this); - - scaleTextField.setFont(FontUtil.setStyle(scaleTextField.getFont(), Font.BOLD)); - - scaleTextField.addKeyListener(this); - - mainFrame.pack(); - mainFrame.center(); - mainFrame.addToMainDesktopPane(); - mainFrame.setVisible(true); - - } - - class MouseInfoRecord - { - boolean isGettingToOtherAndTouch = false; - boolean isEscapingFromOtherAndUnTouch = false; - boolean isEscaping = false; - boolean distanceIsInferiorToThreshold1 = false; - boolean isGoingToTheOther = false; - boolean mouseGetToOtherMouseAndEscapeInOut = false; - boolean mouseGetToOtherMouseAndOtherEscapeInOut = false; - boolean eventA = false; - boolean eventB = false; - boolean eventC = false; - boolean eventD = false; - float speed; - Point2D headPosition; - Point2D tailPosition; - Point2D bodyPosition; - public boolean distanceIsInferiorToThreshold2 = false; - public boolean isBehindTheOther = false; - public boolean isBesideTheOther = false; - public boolean thisHeadWithOtherGenitalContact = false; - } - - public void openFile() - { - // load last preferences for loader. - JFileChooser fileChooser = new JFileChooser(); - fileChooser.setMultiSelectionEnabled(true); - String node = "plugins/PhysicTracker/videolabelmaker/browser"; - - Preferences preferences = Preferences.userRoot().node(node); - String path = preferences.get("path", ""); - fileChooser.setCurrentDirectory(new File(path)); - - int x = preferences.getInt("x", 0); - int y = preferences.getInt("y", 0); - int width = preferences.getInt("width", 400); - int height = preferences.getInt("height", 400); - - fileChooser.setLocation(x, y); - fileChooser.setPreferredSize(new Dimension(width, height)); - - int returnValue = fileChooser.showDialog(null, "Load"); - if (returnValue == JFileChooser.APPROVE_OPTION) - { - preferences.put("path", fileChooser.getCurrentDirectory().getAbsolutePath()); - preferences.putInt("x", fileChooser.getX()); - preferences.putInt("y", fileChooser.getY()); - preferences.putInt("width", fileChooser.getWidth()); - preferences.putInt("height", fileChooser.getHeight()); - - for (int i = 0; i < fileChooser.getSelectedFiles().length; i++) - { - if (fileChooser.getSelectedFiles()[i].getName().contains("extra")) - { - System.out.println( - "You are trying to load an extra xml file. Please load the original file instead."); - continue; - } - - VideoLabelPanel videoLabelPanel = new VideoLabelPanel(fileChooser.getSelectedFiles()[i]); - mainPanel.add(videoLabelPanel.panel); - videoLabelPanelArrayList.add(videoLabelPanel); - mainPanel.add(new JPanel()); - } - - } - mainPanel.updateUI(); - } - - @Override - public void actionPerformed(ActionEvent e) - { - - if (e.getSource() == refreshButton) - { - try - { - SEUIL_DISTANCE_1 = Float.parseFloat(distance1TextField.getText()); - SEUIL_DISTANCE_2 = Float.parseFloat(distance2TextField.getText()); - SEUIL_DISTANCE_HEAD_HEAD = Float.parseFloat(distanceHeadHeadTextField.getText()); - - SEUIL_DISTANCE_HEAD_GENITAL = Float.parseFloat(distanceHeadGenitalTextField.getText()); - SEUIL_SIDE = Float.parseFloat(seuilSideTextField.getText()); - SPEED_THRESHOLD_1 = Float.parseFloat(speed_threshold1TextField.getText()); - SPEED_THRESHOLD_2 = Float.parseFloat(speed_threshold2TextField.getText()); - SPEED_THRESHOLD_3 = Float.parseFloat(speed_threshold3TextField.getText()); - FPS = Float.parseFloat(fpsTextField.getText()); - } - catch (NumberFormatException e1) - { - MessageDialog.showDialog( - "One of the parameters cannot be understand as a number. Please correct it and refresh again.", - MessageDialog.ERROR_MESSAGE); - return; - } - for (VideoLabelPanel vlp : videoLabelPanelArrayList) - { - if (!vlp.isFreezed()) - { - vlp.buildResultImage(); - } - } - - double scaleVideo = 1; - try - { - scaleVideo = Double.parseDouble(scaleVideoTextField.getText()); - } - catch (Exception e1) - { - // the field is incorrect. - } - - imageVideoComponent.setZoom(scaleVideo); - - } - - if (e.getSource() == openFileMenuItem) - { - openFile(); - } - - if (e.getSource() == compileImageFileMenuItem) - { - compileImageFile(); - } - - if (e.getSource() == mergeHeatMapMenuItem) - { - mergeHeatMapDirectory(); - } - - } - - private void mergeHeatMapDirectory() - { - - JFileChooser fileChooser = new JFileChooser(); - fileChooser.setMultiSelectionEnabled(true); - - String node = "plugins/PhysicTracker/videolabelmaker/browser"; - - Preferences preferences = Preferences.userRoot().node(node); - String path = preferences.get("path", ""); - fileChooser.setCurrentDirectory(new File(path)); - - int returnValue = fileChooser.showDialog(null, "Load heatmap files"); - if (returnValue == JFileChooser.APPROVE_OPTION) - { - IcyBufferedImage resultImage = new IcyBufferedImage(1, 1, 4, DataType.USHORT); - - for (int i = 0; i < fileChooser.getSelectedFiles().length; i++) - { - File file = fileChooser.getSelectedFiles()[i]; - if (file.getAbsolutePath().toLowerCase().endsWith("heatmap.tif")) - { - java.awt.Point copyPoint = new java.awt.Point(resultImage.getWidth(), 0); - System.out.println("Loading file " + file.getAbsolutePath()); - Sequence sequence = Loader.loadSequence(file.getAbsolutePath(), 0, false); - - // write sequence file name in image. - Graphics2D g = (Graphics2D) sequence.getFirstImage().getGraphics(); - g.setColor(Color.white); - g.setFont(new Font("Arial", Font.PLAIN, 12)); - g.drawString(FileUtil.getFileName(file.getAbsolutePath(), false), 0, 15); - - int newHeight = Math.max(resultImage.getHeight(), sequence.getHeight()); - resultImage = IcyBufferedImageUtil.scale(resultImage, resultImage.getWidth() + sequence.getWidth(), - newHeight, false, SwingConstants.LEFT, SwingConstants.TOP); - - resultImage.copyData(sequence.getFirstImage(), null, copyPoint); - - } - } - - // save stitched sequence - - Sequence outputSequence = new Sequence(resultImage); - File outFile = new File(FileUtil.getDirectory(fileChooser.getSelectedFile().getAbsolutePath()) - + FileUtil.separator + "heatmap stitched.tif"); - - new AnnounceFrame("Saving stitched heatmap to file " + outFile.getAbsolutePath(), 5); - Saver.save(outputSequence, outFile); - - // load files - /* - * for ( int i = 0 ; i < fileChooser.getSelectedFiles().length ; i++ ) - * { - * try { - * BufferedImage bi = ImageIO.read( fileChooser.getSelectedFiles()[i] ); - * fileImageHashMap.put( fileChooser.getSelectedFiles()[i] , bi ); - * - * } catch (IOException e1) { - * e1.printStackTrace(); - * } - * - * fileArray.add( fileChooser.getSelectedFiles()[i] ); - * } - */ - } - - } - - private void compileImageFile() - { - - JFileChooser fileChooser = new JFileChooser(); - fileChooser.setMultiSelectionEnabled(true); - int returnValue = fileChooser.showDialog(null, "Load"); - if (returnValue == JFileChooser.APPROVE_OPTION) - { - - ArrayList<File> fileArray = new ArrayList<File>(); - HashMap<File, BufferedImage> fileImageHashMap = new HashMap<File, BufferedImage>(); - - // load files - - for (int i = 0; i < fileChooser.getSelectedFiles().length; i++) - { - try - { - BufferedImage bi = ImageIO.read(fileChooser.getSelectedFiles()[i]); - fileImageHashMap.put(fileChooser.getSelectedFiles()[i], bi); - - } - catch (IOException e1) - { - e1.printStackTrace(); - } - - fileArray.add(fileChooser.getSelectedFiles()[i]); - } - - // pack files. - - int NB_TOTAL_CRITERIA = 28; - - for (int criteria = 0; criteria < NB_TOTAL_CRITERIA; criteria++) - { - // look for maxWidth. - - int maxWidth = 0; - int nbFileMatching = 0; - - String tokenToLook = ".criteria_" + criteria + ".png"; - for (File file : fileArray) - { - if (file.getAbsoluteFile().toString().contains(tokenToLook)) - { - nbFileMatching++; - int w = fileImageHashMap.get(file).getWidth(); - // System.out.println("current w : " + w ); - if (w > maxWidth) - maxWidth = w; - } - } - - System.out.println("Max Width : " + maxWidth); - - // create targetImage - if (nbFileMatching == 0) - { - new ToolTipFrame( - "<html>No file matching .criteria_XX.png found in the list of file provided.<br>Create those images by clicking the save button<br>on each XML panel</html>"); - return; - } - ; - BufferedImage image2 = new BufferedImage(maxWidth, stepY * nbFileMatching, BufferedImage.TYPE_INT_BGR); - Graphics2D targetG = (Graphics2D) image2.getGraphics(); - - int currentY = 0; - for (File file : fileArray) - { - if (file.getAbsoluteFile().toString().contains(tokenToLook)) - { - BufferedImage bi = fileImageHashMap.get(file); - targetG.drawImage(bi, null, 0, currentY); - if (criteria == 2) - { - targetG.setColor(Color.black); - targetG.drawString(file.getAbsoluteFile().toString(), 400, currentY + stepY / 2); - } - currentY += bi.getHeight(); - } - } - - try - { - - String fileName = fileChooser.getSelectedFile().getParent() + "\\__crit_" + criteria + ".png"; - System.out.println("Saving : " + fileName); - ImageIO.write(image2, "png", new File(fileName)); - - } - catch (IOException e1) - { - e1.printStackTrace(); - } - - } - } - - System.out.println("Finished."); - - } - - ArrayList<VideoLabelPanel> videoLabelPanelArrayList = new ArrayList<VideoLabelPanel>(); - - public class ImageComponent extends JPanel implements MouseMotionListener, MouseListener - { - private static final long serialVersionUID = -5907107709763419248L; - BufferedImage image; - ArrayList<String> stringList = new ArrayList<String>(); - double zoom = 1; - - public void setZoom(double zoom) - { - this.zoom = zoom; - // System.out.println("zoom:"+zoom); - updateUI(); - } - - public ImageComponent() - { - // this.showDot = showDot; - } - - public void setImage(BufferedImage image) - { - this.image = image; - this.setPreferredSize(new Dimension((int) (image.getWidth() * zoom), (int) (image.getHeight() * zoom))); - repaint(); - this.addMouseMotionListener(this); - this.addMouseListener(this); - } - - int y = 0; - int x = 0; - // boolean showDot = false; - - @Override - protected void paintComponent(Graphics g) - { - - super.paintComponent(g); - - Graphics2D g2 = (Graphics2D) g; - - if (image != null) - { - g2.scale(zoom, zoom); - g2.drawImage(image, null, 0, 0); - - if (stringList.size() != 0) - { - float dash[] = {10.0f}; - g2.setStroke( - new BasicStroke(1.0f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 10.0f, dash, 0.0f)); - g2.drawLine(x, 0, x, image.getHeight()); - } - } - } - - @Override - public void mouseDragged(MouseEvent e) - { - x = e.getX(); - repaint(); - } - - @Override - public void mouseMoved(MouseEvent e) - { - - x = e.getX(); - - int index = e.getY() / stepY; - if (stringList.size() > index) - { - String string = stringList.get(index); - if (string != null) - { - legendLabel.setText(string); - } - } - } - - @Override - public void mouseClicked(MouseEvent e) - { - x = e.getX(); - repaint(); - } - - @Override - public void mouseEntered(MouseEvent e) - { - } - - @Override - public void mouseExited(MouseEvent e) - { - } - - @Override - public void mousePressed(MouseEvent e) - { - } - - @Override - public void mouseReleased(MouseEvent e) - { - } - - } - - public class VideoLabelPanel implements ActionListener, MouseListener, MouseMotionListener - { - - JPanel panel = null; - - int firstFrame; - int lastFrame; - - HashMap<Integer, MouseInfoRecord> mouseARecord = new HashMap<Integer, MouseInfoRecord>(); - HashMap<Integer, MouseInfoRecord> mouseBRecord = new HashMap<Integer, MouseInfoRecord>(); - - int xPixelPetT = 1; - - BufferedImage imageChrono = new BufferedImage(100, 100, BufferedImage.TYPE_INT_BGR); - ImageIcon imageIcon; - ImageComponent imageComponent = new ImageComponent(); - JButton saveImageButton = new JButton("Save Chrono Image"); - JButton exportEventsAsXML = new JButton("Export Events as XML"); - JButton exportSpeedButton = new JButton("Export speed and distance"); - // freeze settings: The scale and all the info are not propagated to this animal if the freeze is on. - JCheckBox freezeSettingsCheckBox = new JCheckBox("freeze settings"); - - JButton computeVisionInFollowButton = new JButton("Export follow vision graph"); - JButton computeVisionWhenStoppedButton = new JButton("Export stop vision graph"); - - JButton computeLocationHeatMapButton = new JButton("Create location heat map"); - - JButton computeUSVStat = new JButton("Create USV stat"); - - File file; - File extraXMLFile; // contains extra labels to include to this video. - File videoFile; - FrameAccess frameAccess; - Animal animal = null; - SwimmingObject swimmingObject = null; - - public VideoLabelPanel(File fileXML) - { - - computeVisionInFollowButton.setToolTipText("Location of I in the vision of R (R following)"); - computeVisionWhenStoppedButton.setToolTipText("Location of I in the vision of R (R stopped)"); - - JPanel sidePanel2 = GuiUtil.generatePanel("Video"); - - // check if the user is trying to load an avi file, and switch extension to XML if this is the case. - if (FileUtil.getFileExtension(fileXML.getAbsolutePath(), false).toLowerCase().equals("avi")) - { - System.out.println("Avi loaded. Switching to XML."); - fileXML = new File(FileUtil.setExtension(fileXML.getAbsolutePath(), ".avi.xml")); - System.out.println("XML file name is : " + fileXML.getAbsolutePath()); - } - - this.file = fileXML; - - panel = GuiUtil.generatePanel(fileXML.getAbsolutePath()); - - panel.setLayout(new BorderLayout()); - - sidePanel2.add(GuiUtil.besidesPanel(saveImageButton)); - sidePanel2.add(GuiUtil.besidesPanel(exportEventsAsXML)); - sidePanel2.add(GuiUtil.besidesPanel(exportSpeedButton)); - sidePanel2.add(GuiUtil.besidesPanel(computeVisionInFollowButton)); - sidePanel2.add(GuiUtil.besidesPanel(computeVisionWhenStoppedButton)); - sidePanel2.add(GuiUtil.besidesPanel(computeLocationHeatMapButton)); - sidePanel2.add(GuiUtil.besidesPanel(computeUSVStat)); - - freezeSettingsCheckBox.setSelected(false); - sidePanel2.add(GuiUtil.besidesPanel(freezeSettingsCheckBox)); - - computeVisionInFollowButton.addActionListener(this); - computeVisionWhenStoppedButton.addActionListener(this); - computeLocationHeatMapButton.addActionListener(this); - computeUSVStat.addActionListener(this); - exportEventsAsXML.addActionListener(this); - - panel.add(sidePanel2, BorderLayout.CENTER); - saveImageButton.addActionListener(this); - exportSpeedButton.addActionListener(this); - - loadXML(fileXML); - - panel.add(imageComponent, BorderLayout.EAST); - - imageComponent.setImage(imageChrono); - - imageComponent.addMouseListener(this); - imageComponent.addMouseMotionListener(this); - - buildResultImage(); - - } - - public boolean isFreezed() - { - return freezeSettingsCheckBox.isSelected(); - } - - DecimalFormat decimalFormat = new DecimalFormat("00"); - - class Periode - { - int start; - int end; - - public int length() - { - return end - start; - } - - MouseEventType mouseEvent; - } - - String nbFrameToDisplayInSecond(float value) - { - value = (int) ((10f * value) / FPS) / 10f; - return "" + value + "s"; - } - - double demiVisionDeSouris = 2f * Math.PI / 3f; - - /** - * @return This function search for the first frame recorded in the XML file. - * It then shift all data to remove all zero data at the beginning of the sequence. - */ - public int trimAnalysisRecord() - { - // look at max t val. - - int tMin = Integer.MAX_VALUE; - int tMax = 0; - { - Iterator<Integer> integerIterator = mouseARecord.keySet().iterator(); - while (integerIterator.hasNext()) - { - int val = integerIterator.next(); - if (val > tMax) - tMax = val; - if (val < tMin) - tMin = val; - } - } - { - Iterator<Integer> integerIterator = mouseBRecord.keySet().iterator(); - while (integerIterator.hasNext()) - { - int val = integerIterator.next(); - if (val > tMax) - tMax = val; - if (val < tMin) - tMin = val; - } - } - - HashMap<Integer, MouseInfoRecord> mouseARecordReSorted = new HashMap<Integer, MouseInfoRecord>(); - HashMap<Integer, MouseInfoRecord> mouseBRecordReSorted = new HashMap<Integer, MouseInfoRecord>(); - - // shift the data - if (tMin != 0) - { - { - boolean warningHasBeenDisplayed = false; - // System.out.println("Shifting data"); - for (int t = tMin; t < tMax; t++) - { - MouseInfoRecord a = mouseARecord.get(t); - MouseInfoRecord b = mouseBRecord.get(t); - if ((a == null) || (b == null)) - { - // +" \n\n Re start the tracker to perform the tracking on this frame. - String problem = "A tracking frame is missing at t=" + t + " in file " + this.file + "."; - System.out.println(problem); - if (!warningHasBeenDisplayed) - { - MessageDialog.showDialog("<html><center>" + problem - + " <hr>This Message appears once per animal file. <br>See ouput to get the total list of missing frames</html>", - MessageDialog.ERROR_MESSAGE); - warningHasBeenDisplayed = true; - } - } - else - { - mouseARecordReSorted.put(t - tMin, mouseARecord.get(t)); - mouseARecord.remove(t); - - // mouseBRecord.put( t-tMin, mouseBRecord.get( t ) ); - mouseBRecordReSorted.put(t - tMin, mouseBRecord.get(t)); - mouseBRecord.remove(t); - } - - // System.out.println( "t-TMin:" +(t-tMin) + " t:"+ t); - - // mouseARecord.put( t-tMin, mouseARecord.get( t ) ); - - // mouseARecordReSorted.put( t-tMin, mouseARecord.get( t ) ); - // mouseARecord.remove( t ); - // - // //mouseBRecord.put( t-tMin, mouseBRecord.get( t ) ); - // mouseBRecordReSorted.put( t-tMin, mouseBRecord.get( t ) ); - // mouseBRecord.remove( t ); - } - } - - mouseARecord = mouseARecordReSorted; - mouseBRecord = mouseBRecordReSorted; - } - - // System.out.println( "--- check mouse record "); - // - // MouseInfoRecord test = mouseARecord.get( 4471 ); - // System.out.println( "contain object ? " + mouseARecord.containsKey( 4471 ) ); - // System.out.println( "record is " + test ); - - // // test - // for ( int t = tMin ; t< mouseARecord.size() ; t++ ) - // { - // MouseInfoRecord info = mouseARecord.get( t ); - // if ( info == null ) - // { - // System.out.println( "error at t:" + t ); - // System.out.println( "null" ); - // } - // - //// mouseARecord.put( t-tMin, mouseARecord.get( t ) ); - //// mouseARecord.remove( t ); - // - //// mouseBRecord.put( t-tMin, mouseBRecord.get( t ) ); - //// mouseBRecord.remove( t ); - // } - - return tMin; - } - - public void buildResultImage() - { - - ArrayList<Periode> eventContactList = new ArrayList<Periode>(); - - Icy.getMainInterface().getSwimmingPool().remove(swimmingObject); - animal = new Animal(file.getName()); - swimmingObject = new SwimmingObject(animal); - - // // look at max t val. - // - // int tMin = Integer.MAX_VALUE; - // int tMax = 0; - // { - // Iterator<Integer> integerIterator = mouseARecord.keySet().iterator(); - // while ( integerIterator.hasNext() ) - // { - // int val = integerIterator.next(); - // if ( val > tMax ) tMax = val; - // if ( val < tMin ) tMin = val; - // } - // } - // { - // Iterator<Integer> integerIterator = mouseBRecord.keySet().iterator(); - // while ( integerIterator.hasNext() ) - // { - // int val = integerIterator.next(); - // if ( val > tMax ) tMax = val; - // if ( val < tMin ) tMin = val; - // } - // } - - // trimAnalysisRecord(); - - int tMin = 0; - - START_MINUTE = Integer.parseInt(computeImageStartMinuteTextField.getText()); - NB_MINUTE = Integer.parseInt(computeImageNbMinuteTextField.getText()); - - // FPS = Integer.parseInt( compute ) - - firstFrame = (int) (tMin + START_MINUTE * 60 * FPS); - // lastFrame = tMax; - - // { - lastFrame = (int) (firstFrame + NB_MINUTE * 60 * FPS); - // } - - System.out.println("first frame : " + firstFrame); - System.out.println("last frame : " + lastFrame); - - int tMax = lastFrame; - - int nbExtraEvent = 15; // getNbExtraEvent( file ); - - imageChrono = new BufferedImage(lastFrame - firstFrame, 480 + nbExtraEvent * stepY, - BufferedImage.TYPE_INT_BGR); - - imageComponent.setImage(imageChrono); - - panel.updateUI(); - - int currentY = 0; - - Graphics2D g2 = (Graphics2D) imageChrono.getGraphics(); - - // empty image - - g2.fillRect(0, 0, imageChrono.getWidth(), imageChrono.getHeight()); - - // Clean up data - { - - for (int t = 0; t < tMax; t++) - { - // System.out.println(t + " / " + tMax ); - // System.out.println( t ); - if (mouseARecord.containsKey(t)) - { - MouseInfoRecord mouseA = mouseARecord.get(t); - if (mouseA == null) - { - System.out.println("no mouse A record at t=" + t); - } - mouseA.distanceIsInferiorToThreshold1 = false; - mouseA.distanceIsInferiorToThreshold2 = false; - mouseA.isEscaping = false; - mouseA.isEscapingFromOtherAndUnTouch = false; - mouseA.isGettingToOtherAndTouch = false; - mouseA.isGoingToTheOther = false; - mouseA.mouseGetToOtherMouseAndEscapeInOut = false; - mouseA.mouseGetToOtherMouseAndOtherEscapeInOut = false; - mouseA.eventA = false; - mouseA.eventB = false; - mouseA.eventC = false; - mouseA.eventD = false; - mouseA.isBehindTheOther = false; - mouseA.isBesideTheOther = false; - mouseA.thisHeadWithOtherGenitalContact = false; - } - if (mouseBRecord.containsKey(t)) - { - MouseInfoRecord mouseB = mouseBRecord.get(t); - mouseB.distanceIsInferiorToThreshold1 = false; - mouseB.distanceIsInferiorToThreshold2 = false; - mouseB.isEscaping = false; - mouseB.isEscapingFromOtherAndUnTouch = false; - mouseB.isGettingToOtherAndTouch = false; - mouseB.isGoingToTheOther = false; - mouseB.mouseGetToOtherMouseAndEscapeInOut = false; - mouseB.mouseGetToOtherMouseAndOtherEscapeInOut = false; - mouseB.eventA = false; - mouseB.eventB = false; - mouseB.eventC = false; - mouseB.eventD = false; - mouseB.isBehindTheOther = false; - mouseB.isBesideTheOther = false; - mouseB.thisHeadWithOtherGenitalContact = false; - } - } - } - - // DISPLAY TIME - { - g2.setColor(Color.black); - - { - for (int t = 0; t < tMax; t++) - { - - if (t % (FPS * 2) < 1) - { - g2.drawString( - "" + (int) (t / (FPS * 60)) + ":" + decimalFormat.format((int) (t / FPS % 60)), - t - firstFrame, currentY + 12); - g2.drawLine(t - firstFrame, currentY, t - firstFrame, currentY + stepY); - } - - } - } - currentY += stepY; - imageComponent.stringList.add("Time"); - } - - { - - // Label 2 - // Distance de souris A a B est inferieure a SEUIL_DISTANCE_1 - boolean event = false; - int nbEvent = 0; - int total = 0; - - EventTimeLine distanceLessThanThreshold1TimeLine = new EventTimeLine("Distance < thr 1", - EventType.DISTANCE_INFERIOR_THRESHOLD_1, TimeLineCategory.USE_BOOLEAN_EVENT); - animal.eventTimeLineList.add(distanceLessThanThreshold1TimeLine); - - g2.setColor(Color.red); - for (int t = 0; t < tMax; t++) - { - // System.out.println("working on t=" + t ); - if (mouseARecord.containsKey(t)) - if (mouseBRecord.containsKey(t)) - { - // System.out.println("contain keys"); - - MouseInfoRecord mouseA = mouseARecord.get(t); - MouseInfoRecord mouseB = mouseBRecord.get(t); - - float minDistance = Float.MAX_VALUE; - minDistance = getMin(minDistance, - (float) mouseA.bodyPosition.distance(mouseB.bodyPosition)); - minDistance = getMin(minDistance, - (float) mouseA.bodyPosition.distance(mouseB.headPosition)); - minDistance = getMin(minDistance, - (float) mouseA.bodyPosition.distance(mouseB.tailPosition)); - minDistance = getMin(minDistance, - (float) mouseA.headPosition.distance(mouseB.bodyPosition)); - minDistance = getMin(minDistance, - (float) mouseA.headPosition.distance(mouseB.headPosition)); - minDistance = getMin(minDistance, - (float) mouseA.headPosition.distance(mouseB.tailPosition)); - minDistance = getMin(minDistance, - (float) mouseA.tailPosition.distance(mouseB.bodyPosition)); - minDistance = getMin(minDistance, - (float) mouseA.tailPosition.distance(mouseB.headPosition)); - minDistance = getMin(minDistance, - (float) mouseA.tailPosition.distance(mouseB.tailPosition)); - - // System.out.println( "min distance = " + minDistance ); - - if (minDistance < SEUIL_DISTANCE_1) - { - distanceLessThanThreshold1TimeLine.addPunctualEvent(t - firstFrame); - mouseA.distanceIsInferiorToThreshold1 = true; - mouseB.distanceIsInferiorToThreshold1 = true; - } - else - { - mouseA.distanceIsInferiorToThreshold1 = false; - mouseB.distanceIsInferiorToThreshold1 = false; - } - - } - } - - nbEvent = 0; - total = 0; - // draw result - for (EventCriteria eventCriteria : distanceLessThanThreshold1TimeLine.eventList) - { - nbEvent++; - total += eventCriteria.getLength(); - for (int i = eventCriteria.startFrame; i <= eventCriteria.endFrame; i++) - { - g2.drawLine(i, currentY, i, currentY + stepY); - } - } - - g2.setColor(Color.black); - g2.drawLine(0, currentY, imageChrono.getWidth(), currentY); - String string = "Distance less than THRESHOLD 1 nbEvent:" + nbEvent + " totalT:" - + nbFrameToDisplayInSecond(total); - g2.drawString(string, 0, currentY + 12); - - currentY += stepY; - - imageComponent.stringList.add(string); - - } - - { - // LABEL 3 - // Distance de souris A a B est inferieure a SEUIL_DISTANCE_2 - boolean event = false; - int nbEvent = 0; - int total = 0; - - EventTimeLine distanceLessThanThreshold2TimeLine = new EventTimeLine("Distance < thr 2", - EventType.DISTANCE_INFERIOR_THRESHOLD_2, TimeLineCategory.USE_BOOLEAN_EVENT); - animal.eventTimeLineList.add(distanceLessThanThreshold2TimeLine); - - g2.setColor(Color.orange); - for (int t = 0; t < tMax; t++) - { - if (mouseARecord.containsKey(t)) - if (mouseBRecord.containsKey(t)) - { - MouseInfoRecord mouseA = mouseARecord.get(t); - MouseInfoRecord mouseB = mouseBRecord.get(t); - - float minDistance = Float.MAX_VALUE; - minDistance = getMin(minDistance, - (float) mouseA.bodyPosition.distance(mouseB.bodyPosition)); - minDistance = getMin(minDistance, - (float) mouseA.bodyPosition.distance(mouseB.headPosition)); - minDistance = getMin(minDistance, - (float) mouseA.bodyPosition.distance(mouseB.tailPosition)); - minDistance = getMin(minDistance, - (float) mouseA.headPosition.distance(mouseB.bodyPosition)); - minDistance = getMin(minDistance, - (float) mouseA.headPosition.distance(mouseB.headPosition)); - minDistance = getMin(minDistance, - (float) mouseA.headPosition.distance(mouseB.tailPosition)); - minDistance = getMin(minDistance, - (float) mouseA.tailPosition.distance(mouseB.bodyPosition)); - minDistance = getMin(minDistance, - (float) mouseA.tailPosition.distance(mouseB.headPosition)); - minDistance = getMin(minDistance, - (float) mouseA.tailPosition.distance(mouseB.tailPosition)); - - if (minDistance < SEUIL_DISTANCE_2) - { - distanceLessThanThreshold2TimeLine.addPunctualEvent(t - firstFrame); - mouseA.distanceIsInferiorToThreshold2 = true; - mouseB.distanceIsInferiorToThreshold2 = true; - } - else - { - mouseA.distanceIsInferiorToThreshold2 = false; - mouseB.distanceIsInferiorToThreshold2 = false; - } - - } - } - - nbEvent = 0; - total = 0; - // draw result - for (EventCriteria eventCriteria : distanceLessThanThreshold2TimeLine.eventList) - { - nbEvent++; - total += eventCriteria.getLength(); - for (int i = eventCriteria.startFrame; i <= eventCriteria.endFrame; i++) - { - g2.drawLine(i, currentY, i, currentY + stepY); - } - } - - g2.setColor(Color.black); - g2.drawLine(0, currentY, imageChrono.getWidth(), currentY); - String string = "Distance less than THRESHOLD 2 nbEvent:" + nbEvent + " totalT:" - + nbFrameToDisplayInSecond(total); - g2.drawString(string, 0, currentY + 12); - - currentY += stepY; - - imageComponent.stringList.add(string); - } - - { - // LABEL 4 - // Head A - Head B SEUIL_DISTANCE_HEAD_HEAD - boolean event = false; - int nbEvent = 0; - int total = 0; - - EventTimeLine OralOralTimeLine = new EventTimeLine("Oral-Oral", EventType.ORAL_ORAL, - TimeLineCategory.USE_BOOLEAN_EVENT); - animal.eventTimeLineList.add(OralOralTimeLine); - - g2.setColor(Color.black); - for (int t = 0; t < tMax; t++) - { - if (mouseARecord.containsKey(t)) - if (mouseBRecord.containsKey(t)) - { - MouseInfoRecord mouseA = mouseARecord.get(t); - MouseInfoRecord mouseB = mouseBRecord.get(t); - - float minDistance = Float.MAX_VALUE; - minDistance = getMin(minDistance, - (float) mouseA.headPosition.distance(mouseB.headPosition)); - if (minDistance < SEUIL_DISTANCE_HEAD_HEAD) - { - OralOralTimeLine.addPunctualEvent(t - firstFrame); - - } - else - { - - } - } - } - - // display - nbEvent = 0; - total = 0; - // draw result - for (EventCriteria eventCriteria : OralOralTimeLine.eventList) - { - nbEvent++; - total += eventCriteria.getLength(); - for (int i = eventCriteria.startFrame; i <= eventCriteria.endFrame; i++) - { - g2.drawLine(i, currentY, i, currentY + stepY); - } - } - - g2.setColor(Color.black); - g2.drawLine(0, currentY, imageChrono.getWidth(), currentY); - String string = "Head - Head : nbevent: " + nbEvent + " TotalT=" + nbFrameToDisplayInSecond(total); - g2.drawString(string, 0, currentY + 12); - - currentY += stepY; - imageComponent.stringList.add(string); - - } - { - // LABEL 5 - // Head A - Genital B SEUIL_DISTANCE_HEAD_GENITAL - boolean event = false; - int nbEvent = 0; - int total = 0; - - EventTimeLine eventTimeLine = new EventTimeLine("Oral A - Genital B", EventType.ORAL_A_GENITAL_B, - TimeLineCategory.USE_BOOLEAN_EVENT); - animal.eventTimeLineList.add(eventTimeLine); - - g2.setColor(Color.RED); - for (int t = 0; t < tMax; t++) - { - if (mouseARecord.containsKey(t)) - if (mouseBRecord.containsKey(t)) - { - MouseInfoRecord mouseA = mouseARecord.get(t); - MouseInfoRecord mouseB = mouseBRecord.get(t); - - float minDistance = Float.MAX_VALUE; - minDistance = getMin(minDistance, - (float) mouseA.headPosition.distance(mouseB.tailPosition)); - if (minDistance < SEUIL_DISTANCE_HEAD_GENITAL) - { - eventTimeLine.addPunctualEvent(t - firstFrame); - - mouseA.thisHeadWithOtherGenitalContact = true; - - } - else - { - - } - } - } - nbEvent = 0; - total = 0; - // draw result - for (EventCriteria eventCriteria : eventTimeLine.eventList) - { - nbEvent++; - total += eventCriteria.getLength(); - for (int i = eventCriteria.startFrame; i <= eventCriteria.endFrame; i++) - { - g2.drawLine(i, currentY, i, currentY + stepY); - } - } - - g2.setColor(Color.black); - g2.drawLine(0, currentY, imageChrono.getWidth(), currentY); - g2.drawLine(0, currentY - 1, imageChrono.getWidth(), currentY - 1); - String string = "Head A - Genital B nbEvent:" + nbEvent + " TotalT:" + nbFrameToDisplayInSecond(total); - g2.drawString(string, 0, currentY + 12); - - currentY += stepY; - imageComponent.stringList.add(string); - - } - { - // LABEL 6 - // Head B - Genital A SEUIL_DISTANCE_HEAD_GENITAL - boolean event = false; - int nbEvent = 0; - int total = 0; - - EventTimeLine eventTimeLine = new EventTimeLine("Oral B - Genital A", EventType.ORAL_B_GENITAL_A, - TimeLineCategory.USE_BOOLEAN_EVENT); - animal.eventTimeLineList.add(eventTimeLine); - - g2.setColor(Color.GREEN); - for (int t = 0; t < tMax; t++) - { - if (mouseARecord.containsKey(t)) - if (mouseBRecord.containsKey(t)) - { - MouseInfoRecord mouseA = mouseARecord.get(t); - MouseInfoRecord mouseB = mouseBRecord.get(t); - - float minDistance = Float.MAX_VALUE; - minDistance = getMin(minDistance, - (float) mouseA.tailPosition.distance(mouseB.headPosition)); - if (minDistance < SEUIL_DISTANCE_HEAD_GENITAL) - { - eventTimeLine.addPunctualEvent(t - firstFrame); - - mouseB.thisHeadWithOtherGenitalContact = true; - - } - else - { - - } - } - } - - nbEvent = 0; - total = 0; - // draw result - for (EventCriteria eventCriteria : eventTimeLine.eventList) - { - nbEvent++; - total += eventCriteria.getLength(); - for (int i = eventCriteria.startFrame; i <= eventCriteria.endFrame; i++) - { - g2.drawLine(i, currentY, i, currentY + stepY); - } - } - - g2.setColor(Color.black); - g2.drawLine(0, currentY, imageChrono.getWidth(), currentY); - String string = "Head B - Genital A : nbEvent:" + nbEvent + " totalT:" - + nbFrameToDisplayInSecond(total); - g2.drawString(string, 0, currentY + 12); - - imageComponent.stringList.add(string); - - currentY += stepY; - } - { - // Mouse A is behind Mouse B - boolean event = false; - int nbEvent = 0; - int total = 0; - - EventTimeLine eventTimeLine = new EventTimeLine("Mouse A behind B (any distance)", EventType.A_BEHIND_B, - TimeLineCategory.USE_BOOLEAN_EVENT); - animal.eventTimeLineList.add(eventTimeLine); - - for (int t = 0; t < tMax; t++) - { - if (mouseARecord.containsKey(t)) - if (mouseBRecord.containsKey(t)) - { - MouseInfoRecord mouseA = mouseARecord.get(t); - MouseInfoRecord mouseB = mouseBRecord.get(t); - - float mouseABodyToMouseBTail = (float) mouseA.bodyPosition.distance(mouseB.tailPosition); - float mouseABodyToMouseBHead = (float) mouseA.bodyPosition.distance(mouseB.headPosition); - - if (mouseABodyToMouseBTail < mouseABodyToMouseBHead) - { - eventTimeLine.addPunctualEvent(t - firstFrame); - - mouseA.isBehindTheOther = true; - - } - else - { - - } - } - } - - g2.setColor(Color.RED); - nbEvent = 0; - total = 0; - // draw result - for (EventCriteria eventCriteria : eventTimeLine.eventList) - { - nbEvent++; - total += eventCriteria.getLength(); - for (int i = eventCriteria.startFrame; i <= eventCriteria.endFrame; i++) - { - g2.drawLine(i, currentY, i, currentY + stepY); - } - } - - g2.setColor(Color.black); - g2.drawLine(0, currentY, imageChrono.getWidth(), currentY); - g2.drawLine(0, currentY - 1, imageChrono.getWidth(), currentY - 1); - - String string = "Mouse A is behind B nbevent:" + nbEvent + " totalT:" + nbFrameToDisplayInSecond(total); - g2.drawString(string, 0, currentY + 12); - imageComponent.stringList.add(string); - - currentY += stepY; - } - - { - // Mouse B is behind Mouse A - boolean event = false; - int nbEvent = 0; - int total = 0; - - EventTimeLine eventTimeLine = new EventTimeLine("Mouse B behind A (any distance)", EventType.B_BEHIND_A, - TimeLineCategory.USE_BOOLEAN_EVENT); - animal.eventTimeLineList.add(eventTimeLine); - - for (int t = 0; t < tMax; t++) - { - if (mouseARecord.containsKey(t)) - if (mouseBRecord.containsKey(t)) - { - MouseInfoRecord mouseA = mouseARecord.get(t); - MouseInfoRecord mouseB = mouseBRecord.get(t); - - float mouseBBodyToMouseATail = (float) mouseB.bodyPosition.distance(mouseA.tailPosition); - float mouseBBodyToMouseAHead = (float) mouseB.bodyPosition.distance(mouseA.headPosition); - - if (mouseBBodyToMouseATail < mouseBBodyToMouseAHead) - { - eventTimeLine.addPunctualEvent(t - firstFrame); - - mouseB.isBehindTheOther = true; - - } - else - { - event = false; - } - } - } - - g2.setColor(Color.GREEN); - nbEvent = 0; - total = 0; - // draw result - for (EventCriteria eventCriteria : eventTimeLine.eventList) - { - nbEvent++; - total += eventCriteria.getLength(); - for (int i = eventCriteria.startFrame; i <= eventCriteria.endFrame; i++) - { - g2.drawLine(i, currentY, i, currentY + stepY); - } - } - - g2.setColor(Color.black); - g2.drawLine(0, currentY, imageChrono.getWidth(), currentY); - String string = "Mouse B is behind A nbevent:" + nbEvent + " totalT:" + nbFrameToDisplayInSecond(total); - g2.drawString(string, 0, currentY + 12); - imageComponent.stringList.add(string); - currentY += stepY; - } - { - // Mice are next to the each other and body distance < DISTANCE_2 (same way) - // Calcul par produit scalaire. si positif meme sens. - boolean event = false; - int nbEvent = 0; - int total = 0; - - EventTimeLine eventTimeLine = new EventTimeLine("Mouse next to each other (same way) < distance 2", - EventType.BESIDE_SAME_WAY, TimeLineCategory.USE_BOOLEAN_EVENT); - animal.eventTimeLineList.add(eventTimeLine); - - for (int t = 0; t < tMax; t++) - { - if (mouseARecord.containsKey(t)) - if (mouseBRecord.containsKey(t)) - { - MouseInfoRecord mouseA = mouseARecord.get(t); - MouseInfoRecord mouseB = mouseBRecord.get(t); - - float mouseABodyToMouseBBody = (float) mouseA.bodyPosition.distance(mouseB.bodyPosition); - float mouseAHeadToMouseBHead = (float) mouseA.headPosition.distance(mouseB.headPosition); - - double vectSourisAX = mouseA.headPosition.getX() - mouseA.bodyPosition.getX(); - double vectSourisAY = mouseA.headPosition.getY() - mouseA.bodyPosition.getY(); - double vectSourisBX = mouseB.headPosition.getX() - mouseB.bodyPosition.getX(); - double vectSourisBY = mouseB.headPosition.getY() - mouseB.bodyPosition.getY(); - - double produitScalaire = vectSourisAX * vectSourisBX + vectSourisAY * vectSourisBY; - double distance = Double.parseDouble(distance1TextField.getText()); - - if (produitScalaire >= 0 && mouseAHeadToMouseBHead < SEUIL_DISTANCE_1 - && mouseABodyToMouseBBody < SEUIL_DISTANCE_1) - { - eventTimeLine.addPunctualEvent(t - firstFrame); - - mouseA.isBesideTheOther = true; - mouseB.isBesideTheOther = true; - - } - else - { - - } - - } - } - - g2.setColor(Color.DARK_GRAY); - nbEvent = 0; - total = 0; - // draw result - for (EventCriteria eventCriteria : eventTimeLine.eventList) - { - nbEvent++; - total += eventCriteria.getLength(); - for (int i = eventCriteria.startFrame; i <= eventCriteria.endFrame; i++) - { - g2.drawLine(i, currentY, i, currentY + stepY); - } - } - - g2.setColor(Color.black); - g2.drawLine(0, currentY, imageChrono.getWidth(), currentY); - String string = "Mice are next to the each other and body distance < DISTANCE_2 (same way) nbevent:" - + nbEvent + " totalT:" + nbFrameToDisplayInSecond(total); - g2.drawString(string, 0, currentY + 12); - imageComponent.stringList.add(string); - currentY += stepY; - } - { - // Mice are next to the each other and body distance < DISTANCE_2 (opposite way) - boolean event = false; - int nbEvent = 0; - int total = 0; - - EventTimeLine eventTimeLine = new EventTimeLine("Mouse next to each other (opposite way) < distance 2", - EventType.BESIDE_OPPOSITE_WAY, TimeLineCategory.USE_BOOLEAN_EVENT); - animal.eventTimeLineList.add(eventTimeLine); - - for (int t = 0; t < tMax; t++) - { - if (mouseARecord.containsKey(t)) - if (mouseBRecord.containsKey(t)) - { - MouseInfoRecord mouseA = mouseARecord.get(t); - MouseInfoRecord mouseB = mouseBRecord.get(t); - - double vectSourisAX = mouseA.headPosition.getX() - mouseA.bodyPosition.getX(); - double vectSourisAY = mouseA.headPosition.getY() - mouseA.bodyPosition.getY(); - double vectSourisBX = mouseB.headPosition.getX() - mouseB.bodyPosition.getX(); - double vectSourisBY = mouseB.headPosition.getY() - mouseB.bodyPosition.getY(); - - double produitScalaire = vectSourisAX * vectSourisBX + vectSourisAY * vectSourisBY; - - float mouseABodyToMouseBHead = (float) mouseA.bodyPosition.distance(mouseB.headPosition); - float mouseAHeadToMouseBBody = (float) mouseA.headPosition.distance(mouseB.bodyPosition); - - if (produitScalaire < 0 && mouseABodyToMouseBHead < SEUIL_DISTANCE_1 - && mouseAHeadToMouseBBody < SEUIL_DISTANCE_1) - { - eventTimeLine.addPunctualEvent(t - firstFrame); - - } - else - { - - } - - } - } - - g2.setColor(Color.BLACK); - nbEvent = 0; - total = 0; - // draw result - for (EventCriteria eventCriteria : eventTimeLine.eventList) - { - nbEvent++; - total += eventCriteria.getLength(); - for (int i = eventCriteria.startFrame; i <= eventCriteria.endFrame; i++) - { - g2.drawLine(i, currentY, i, currentY + stepY); - } - } - - g2.setColor(Color.black); - g2.drawLine(0, currentY, imageChrono.getWidth(), currentY); - String string = "Mice are next to the each other and body distance < DISTANCE_2 (opposite) nbevent:" - + nbEvent + " totalT:" + nbFrameToDisplayInSecond(total); - g2.drawString(string, 0, currentY + 12); - imageComponent.stringList.add(string); - - currentY += stepY; - } - - /** frameWindow est utilisé pour lisser le calcul de deplacement entre deux points de temps. t-framewindow et t+frameWindow */ - int frameWindow = 6; // 5 - - { - EventTimeLine eventTimeLine = new EventTimeLine("Mouse A speed", EventType.MOUSE_A_SPEED, - TimeLineCategory.USE_DISCRETE_EVENT); - animal.eventTimeLineList.add(eventTimeLine); - - // Mice A speed is from 0 to SPEED_THRESHOLD_1 - float nbVal = 0; - float totalDistance = 0; - for (int t = 0; t < tMax; t++) - { - if (mouseARecord.containsKey(t - frameWindow)) - if (mouseBRecord.containsKey(t - frameWindow)) - if (mouseARecord.containsKey(t + frameWindow)) - if (mouseBRecord.containsKey(t + frameWindow)) - if (mouseARecord.containsKey(t)) - if (mouseBRecord.containsKey(t)) - { - MouseInfoRecord mouseAprev = mouseARecord.get(t - frameWindow); - MouseInfoRecord mouseBprev = mouseBRecord.get(t - frameWindow); - MouseInfoRecord mouseAnext = mouseARecord.get(t + frameWindow); - MouseInfoRecord mouseBnext = mouseBRecord.get(t + frameWindow); - MouseInfoRecord mouseA = mouseARecord.get(t); - MouseInfoRecord mouseB = mouseBRecord.get(t); - - float distance = (float) mouseAprev.bodyPosition - .distance(mouseAnext.bodyPosition); - distance /= (float) (frameWindow * 2 + 1); // pour obtenir une vitesse par frame. - - nbVal++; - totalDistance += distance; - - mouseA.speed = distance; - - eventTimeLine.addValue(t - firstFrame, distance); - - if (distance <= SPEED_THRESHOLD_1) - { - g2.setColor(Color.BLACK); - g2.drawLine(t - firstFrame, currentY, t - firstFrame, currentY + stepY); - } - if ((distance > SPEED_THRESHOLD_1) && (distance < SPEED_THRESHOLD_2)) - { - g2.setColor(Color.DARK_GRAY); - g2.drawLine(t - firstFrame, currentY, t - firstFrame, currentY + stepY); - } - if ((distance >= SPEED_THRESHOLD_2)) - { - g2.setColor(Color.GRAY); - g2.drawLine(t - firstFrame, currentY, t - firstFrame, currentY + stepY); - } - - } - } - - g2.setColor(Color.red); - g2.drawLine(0, currentY, imageChrono.getWidth(), currentY); - String string = "Mouse A speed slow=black fast=gray mean speed: " + totalDistance / nbVal; - g2.drawString(string, 0, currentY + 12); - imageComponent.stringList.add(string); - - currentY += stepY; - } - - { - EventTimeLine eventTimeLine = new EventTimeLine("Mouse B speed", EventType.MOUSE_B_SPEED, - TimeLineCategory.USE_DISCRETE_EVENT); - animal.eventTimeLineList.add(eventTimeLine); - - // Mice B speed is from 0 to SPEED_THRESHOLD_1 - float nbVal = 0; - float totalDistance = 0; - - for (int t = 0; t < tMax; t++) - { - if (mouseARecord.containsKey(t - frameWindow)) - if (mouseBRecord.containsKey(t - frameWindow)) - if (mouseARecord.containsKey(t + frameWindow)) - if (mouseBRecord.containsKey(t + frameWindow)) - if (mouseARecord.containsKey(t)) - if (mouseBRecord.containsKey(t)) - { - - MouseInfoRecord mouseAprev = mouseARecord.get(t - frameWindow); - MouseInfoRecord mouseBprev = mouseBRecord.get(t - frameWindow); - MouseInfoRecord mouseAnext = mouseARecord.get(t + frameWindow); - MouseInfoRecord mouseBnext = mouseBRecord.get(t + frameWindow); - MouseInfoRecord mouseA = mouseARecord.get(t); - MouseInfoRecord mouseB = mouseBRecord.get(t); - - float distance = (float) mouseBprev.bodyPosition - .distance(mouseBnext.bodyPosition); - distance /= (float) (frameWindow * 2 + 1); // pour obtenir une vitesse par frame. - - mouseB.speed = distance; - nbVal++; - totalDistance += distance; - - eventTimeLine.addValue(t - firstFrame, distance); - - if (distance <= SPEED_THRESHOLD_1) - { - g2.setColor(Color.BLACK); - g2.drawLine(t - firstFrame, currentY, t - firstFrame, currentY + stepY); - } - if ((distance > SPEED_THRESHOLD_1) && (distance < SPEED_THRESHOLD_2)) - { - g2.setColor(Color.DARK_GRAY); - g2.drawLine(t - firstFrame, currentY, t - firstFrame, currentY + stepY); - } - if ((distance >= SPEED_THRESHOLD_2)) - { - g2.setColor(Color.GRAY); - g2.drawLine(t - firstFrame, currentY, t - firstFrame, currentY + stepY); - } - - } - } - g2.setColor(Color.red); - g2.drawLine(0, currentY, imageChrono.getWidth(), currentY); - String string = "Mouse B speed slow=black fast=gray mean speed: " + totalDistance / nbVal; - g2.drawString(string, 0, currentY + 12); - imageComponent.stringList.add(string); - currentY += stepY; - } - - { - // Mouse A Stop - boolean event = false; - float nbEvent = 0; - float total = 0; - - EventTimeLine eventTimeLine = new EventTimeLine("A Stop", EventType.A_STOP, - TimeLineCategory.USE_BOOLEAN_EVENT); - animal.eventTimeLineList.add(eventTimeLine); - - for (int t = 0; t < tMax; t++) - { - if (mouseARecord.containsKey(t - frameWindow)) - if (mouseBRecord.containsKey(t - frameWindow)) - if (mouseARecord.containsKey(t + frameWindow)) - if (mouseBRecord.containsKey(t + frameWindow)) - if (mouseARecord.containsKey(t)) - if (mouseBRecord.containsKey(t)) - { - MouseInfoRecord mouseAprev = mouseARecord.get(t - frameWindow); - MouseInfoRecord mouseBprev = mouseBRecord.get(t - frameWindow); - MouseInfoRecord mouseAnext = mouseARecord.get(t + frameWindow); - MouseInfoRecord mouseBnext = mouseBRecord.get(t + frameWindow); - MouseInfoRecord mouseA = mouseARecord.get(t); - MouseInfoRecord mouseB = mouseBRecord.get(t); - - double distanceTPrev = mouseAprev.bodyPosition - .distance(mouseBprev.bodyPosition); - double distanceTNext = mouseAnext.bodyPosition - .distance(mouseBnext.bodyPosition); - - if (mouseA.speed < SPEED_THRESHOLD_1) - { - - eventTimeLine.addPunctualEvent(t - firstFrame); - - } - else - { - event = false; - } - - } - } - - g2.setColor(Color.red); - nbEvent = 0; - total = 0; - // draw result - for (EventCriteria eventCriteria : eventTimeLine.eventList) - { - nbEvent++; - total += eventCriteria.getLength(); - for (int i = eventCriteria.startFrame; i <= eventCriteria.endFrame; i++) - { - g2.drawLine(i, currentY, i, currentY + stepY); - } - } - - g2.setColor(Color.black); - g2.drawLine(0, currentY, imageChrono.getWidth(), currentY); - String string = "A Stop : nbEvent : " + nbEvent + " total: " + nbFrameToDisplayInSecond(total); - g2.drawString(string, 0, currentY + 12); - imageComponent.stringList.add(string); - - currentY += stepY; - } - - { - // Mouse B Stop - boolean event = false; - float nbEvent = 0; - float total = 0; - - EventTimeLine eventTimeLine = new EventTimeLine("B Stop", EventType.B_STOP, - TimeLineCategory.USE_BOOLEAN_EVENT); - animal.eventTimeLineList.add(eventTimeLine); - - for (int t = 0; t < tMax; t++) - { - if (mouseARecord.containsKey(t - frameWindow)) - if (mouseBRecord.containsKey(t - frameWindow)) - if (mouseARecord.containsKey(t + frameWindow)) - if (mouseBRecord.containsKey(t + frameWindow)) - if (mouseARecord.containsKey(t)) - if (mouseBRecord.containsKey(t)) - { - MouseInfoRecord mouseAprev = mouseARecord.get(t - frameWindow); - MouseInfoRecord mouseBprev = mouseBRecord.get(t - frameWindow); - MouseInfoRecord mouseAnext = mouseARecord.get(t + frameWindow); - MouseInfoRecord mouseBnext = mouseBRecord.get(t + frameWindow); - MouseInfoRecord mouseA = mouseARecord.get(t); - MouseInfoRecord mouseB = mouseBRecord.get(t); - - double distanceTPrev = mouseAprev.bodyPosition - .distance(mouseBprev.bodyPosition); - double distanceTNext = mouseAnext.bodyPosition - .distance(mouseBnext.bodyPosition); - - if (mouseB.speed < SPEED_THRESHOLD_1) - { - - eventTimeLine.addPunctualEvent(t - firstFrame); - - } - else - { - event = false; - } - - } - } - - g2.setColor(Color.green); - nbEvent = 0; - total = 0; - // draw result - for (EventCriteria eventCriteria : eventTimeLine.eventList) - { - nbEvent++; - total += eventCriteria.getLength(); - for (int i = eventCriteria.startFrame; i <= eventCriteria.endFrame; i++) - { - g2.drawLine(i, currentY, i, currentY + stepY); - } - } - - g2.setColor(Color.black); - g2.drawLine(0, currentY, imageChrono.getWidth(), currentY); - String string = "B Stop : nbEvent : " + nbEvent + " total: " + nbFrameToDisplayInSecond(total); - g2.drawString(string, 0, currentY + 12); - imageComponent.stringList.add(string); - - currentY += stepY; - } - - { - // Mouse A Speed > Mouse B Speed & Mouse A getting to B - boolean event = false; - float nbEvent = 0; - float total = 0; - - EventTimeLine eventTimeLine = new EventTimeLine("A Speed > B Speed & A GET TO B", - EventType.A_SPEED_HIGHER_THAN_B_SPEED_AND_A_GET_TO_B, TimeLineCategory.USE_BOOLEAN_EVENT); - animal.eventTimeLineList.add(eventTimeLine); - - for (int t = 0; t < tMax; t++) - { - if (mouseARecord.containsKey(t - frameWindow)) - if (mouseBRecord.containsKey(t - frameWindow)) - if (mouseARecord.containsKey(t + frameWindow)) - if (mouseBRecord.containsKey(t + frameWindow)) - if (mouseARecord.containsKey(t)) - if (mouseBRecord.containsKey(t)) - { - MouseInfoRecord mouseAprev = mouseARecord.get(t - frameWindow); - MouseInfoRecord mouseBprev = mouseBRecord.get(t - frameWindow); - MouseInfoRecord mouseAnext = mouseARecord.get(t + frameWindow); - MouseInfoRecord mouseBnext = mouseBRecord.get(t + frameWindow); - MouseInfoRecord mouseA = mouseARecord.get(t); - MouseInfoRecord mouseB = mouseBRecord.get(t); - - double distanceTPrev = mouseAprev.bodyPosition - .distance(mouseBprev.bodyPosition); - double distanceTNext = mouseAnext.bodyPosition - .distance(mouseBnext.bodyPosition); - - if (mouseA.speed > mouseB.speed) - { - if (distanceTPrev > distanceTNext) - { - eventTimeLine.addPunctualEvent(t - firstFrame); - - mouseA.isGoingToTheOther = true; - - } - else - { - - } - } - else - { - event = false; - } - - } - } - - g2.setColor(Color.red); - nbEvent = 0; - total = 0; - // draw result - for (EventCriteria eventCriteria : eventTimeLine.eventList) - { - nbEvent++; - total += eventCriteria.getLength(); - for (int i = eventCriteria.startFrame; i <= eventCriteria.endFrame; i++) - { - g2.drawLine(i, currentY, i, currentY + stepY); - } - } - - g2.setColor(Color.black); - g2.drawLine(0, currentY, imageChrono.getWidth(), currentY); - String string = "Mouse A Speed > Mouse B Speed & Mouse A getting to B : nbEvent : " + nbEvent - + " total: " + nbFrameToDisplayInSecond(total); - g2.drawString(string, 0, currentY + 12); - imageComponent.stringList.add(string); - - currentY += stepY; - } - { - // Mouse B Speed > Mouse A Speed & Mouse B getting to A - boolean event = false; - float nbEvent = 0; - float total = 0; - - EventTimeLine eventTimeLine = new EventTimeLine("B Speed > A Speed & B GET TO A", - EventType.B_SPEED_HIGHER_THAN_A_SPEED_AND_B_GET_TO_A, TimeLineCategory.USE_BOOLEAN_EVENT); - animal.eventTimeLineList.add(eventTimeLine); - - for (int t = 0; t < tMax; t++) - { - if (mouseARecord.containsKey(t - frameWindow)) - if (mouseBRecord.containsKey(t - frameWindow)) - if (mouseARecord.containsKey(t + frameWindow)) - if (mouseBRecord.containsKey(t + frameWindow)) - if (mouseARecord.containsKey(t)) - if (mouseBRecord.containsKey(t)) - { - MouseInfoRecord mouseAprev = mouseARecord.get(t - frameWindow); - MouseInfoRecord mouseBprev = mouseBRecord.get(t - frameWindow); - MouseInfoRecord mouseAnext = mouseARecord.get(t + frameWindow); - MouseInfoRecord mouseBnext = mouseBRecord.get(t + frameWindow); - MouseInfoRecord mouseA = mouseARecord.get(t); - MouseInfoRecord mouseB = mouseBRecord.get(t); - - double distanceTPrev = mouseAprev.bodyPosition - .distance(mouseBprev.bodyPosition); - double distanceTNext = mouseAnext.bodyPosition - .distance(mouseBnext.bodyPosition); - - if (mouseB.speed > mouseA.speed) - { - if (distanceTPrev > distanceTNext) - { - eventTimeLine.addPunctualEvent(t - firstFrame); - - mouseB.isGoingToTheOther = true; - - } - else - { - - } - } - else - { - event = false; - } - - } - } - g2.setColor(Color.green); - - nbEvent = 0; - total = 0; - // draw result - for (EventCriteria eventCriteria : eventTimeLine.eventList) - { - nbEvent++; - total += eventCriteria.getLength(); - for (int i = eventCriteria.startFrame; i <= eventCriteria.endFrame; i++) - { - g2.drawLine(i, currentY, i, currentY + stepY); - } - } - - g2.setColor(Color.black); - g2.drawLine(0, currentY, imageChrono.getWidth(), currentY); - String string = "Mouse B Speed > Mouse A Speed & Mouse B getting to A : nbEvent : " + nbEvent - + " total: " + nbFrameToDisplayInSecond(total); - g2.drawString(string, 0, currentY + 12); - imageComponent.stringList.add(string); - - currentY += stepY; - } - - { - // Mouse A Speed > Mouse B Speed & Mouse A escaping from to B - - boolean event = false; - float nbEvent = 0; - float total = 0; - - EventTimeLine eventTimeLine = new EventTimeLine("A Speed > B Speed & A escape B", - EventType.A_SPEED_HIGHER_THAN_B_SPEED_AND_A_ESCAPE_B, TimeLineCategory.USE_BOOLEAN_EVENT); - animal.eventTimeLineList.add(eventTimeLine); - - for (int t = 0; t < tMax; t++) - { - if (mouseARecord.containsKey(t - frameWindow)) - if (mouseBRecord.containsKey(t - frameWindow)) - if (mouseARecord.containsKey(t + frameWindow)) - if (mouseBRecord.containsKey(t + frameWindow)) - if (mouseARecord.containsKey(t)) - if (mouseBRecord.containsKey(t)) - { - MouseInfoRecord mouseAprev = mouseARecord.get(t - frameWindow); - MouseInfoRecord mouseBprev = mouseBRecord.get(t - frameWindow); - MouseInfoRecord mouseAnext = mouseARecord.get(t + frameWindow); - MouseInfoRecord mouseBnext = mouseBRecord.get(t + frameWindow); - MouseInfoRecord mouseA = mouseARecord.get(t); - MouseInfoRecord mouseB = mouseBRecord.get(t); - - double distanceTPrev = mouseAprev.bodyPosition - .distance(mouseBprev.bodyPosition); - double distanceTNext = mouseAnext.bodyPosition - .distance(mouseBnext.bodyPosition); - - if (mouseA.speed > mouseB.speed) - { - if (distanceTPrev < distanceTNext) - { - eventTimeLine.addPunctualEvent(t - firstFrame); - - mouseA.isEscaping = true; - - } - else - { - - mouseA.isEscaping = false; - } - } - else - { - - } - - } - } - g2.setColor(Color.red); - - nbEvent = 0; - total = 0; - // draw result - for (EventCriteria eventCriteria : eventTimeLine.eventList) - { - nbEvent++; - total += eventCriteria.getLength(); - for (int i = eventCriteria.startFrame; i <= eventCriteria.endFrame; i++) - { - g2.drawLine(i, currentY, i, currentY + stepY); - } - } - - g2.setColor(Color.black); - g2.drawLine(0, currentY, imageChrono.getWidth(), currentY); - String string = "Mouse A Speed > Mouse B Speed & Mouse A escaping from B : nbEvent : " + nbEvent - + " total: " + nbFrameToDisplayInSecond(total); - g2.drawString(string, 0, currentY + 12); - imageComponent.stringList.add(string); - - currentY += stepY; - } - - { - // Mouse B Speed > Mouse A Speed & Mouse B escaping from A - - boolean event = false; - float nbEvent = 0; - float total = 0; - - EventTimeLine eventTimeLine = new EventTimeLine("B Speed > A Speed & B escape A", - EventType.B_SPEED_HIGHER_THAN_A_SPEED_AND_B_ESCAPE_A, TimeLineCategory.USE_BOOLEAN_EVENT); - animal.eventTimeLineList.add(eventTimeLine); - - for (int t = 0; t < tMax; t++) - { - if (mouseARecord.containsKey(t - frameWindow)) - if (mouseBRecord.containsKey(t - frameWindow)) - if (mouseARecord.containsKey(t + frameWindow)) - if (mouseBRecord.containsKey(t + frameWindow)) - if (mouseARecord.containsKey(t)) - if (mouseBRecord.containsKey(t)) - { - MouseInfoRecord mouseAprev = mouseARecord.get(t - frameWindow); - MouseInfoRecord mouseBprev = mouseBRecord.get(t - frameWindow); - MouseInfoRecord mouseAnext = mouseARecord.get(t + frameWindow); - MouseInfoRecord mouseBnext = mouseBRecord.get(t + frameWindow); - MouseInfoRecord mouseA = mouseARecord.get(t); - MouseInfoRecord mouseB = mouseBRecord.get(t); - - double distanceTPrev = mouseAprev.bodyPosition - .distance(mouseBprev.bodyPosition); - double distanceTNext = mouseAnext.bodyPosition - .distance(mouseBnext.bodyPosition); - - if (mouseB.speed > mouseA.speed) - { - if (distanceTPrev < distanceTNext) - { - - eventTimeLine.addPunctualEvent(t - firstFrame); - - mouseB.isEscaping = true; - - } - else - { - mouseB.isEscaping = false; - - } - } - else - { - - } - - } - } - g2.setColor(Color.green); - - nbEvent = 0; - total = 0; - // draw result - for (EventCriteria eventCriteria : eventTimeLine.eventList) - { - nbEvent++; - total += eventCriteria.getLength(); - for (int i = eventCriteria.startFrame; i <= eventCriteria.endFrame; i++) - { - g2.drawLine(i, currentY, i, currentY + stepY); - } - } - - g2.setColor(Color.black); - g2.drawLine(0, currentY, imageChrono.getWidth(), currentY); - String string = "Mouse B Speed > Mouse A Speed & Mouse B escaping from A : nbEvent : " + nbEvent - + " total: " + nbFrameToDisplayInSecond(total); - g2.drawString(string, 0, currentY + 12); - imageComponent.stringList.add(string); - - currentY += stepY; - } - - { - // Mouse A going to B and finishing with contact starting from no contact. - - EventTimeLine eventTimeLine = new EventTimeLine( - "Mouse A going to B and finishing with contact starting from no contact", - EventType.A_GOTO_B_FINISH_CONTACT_START_NO_CONTACT, TimeLineCategory.USE_BOOLEAN_EVENT); - animal.eventTimeLineList.add(eventTimeLine); - - float nbEvent = 0; - float total = 0; - for (int t = 0; t < tMax; t++) - { - if (mouseARecord.containsKey(t)) - if (mouseBRecord.containsKey(t)) - { - - MouseInfoRecord mouseA = mouseARecord.get(t); - MouseInfoRecord mouseB = mouseBRecord.get(t); - - if (mouseA.distanceIsInferiorToThreshold1) // contact - { - ArrayList<Integer> timeToFill = new ArrayList<Integer>(); - // loop back if there is an approach - for (int t2 = t; t2 > 0; t2--) - { - if (mouseARecord.containsKey(t2)) - { - MouseInfoRecord mouseAt2 = mouseARecord.get(t2); - if (mouseAt2.isGoingToTheOther) - { - timeToFill.add(t2); - - if (!mouseAt2.distanceIsInferiorToThreshold1) - { - for (int t3 = t2; t3 > 0; t3--) - { - if (mouseARecord.containsKey(t3)) - { - MouseInfoRecord mouseAt3 = mouseARecord.get(t3); - if (mouseAt3.isGoingToTheOther) - { - timeToFill.add(t3); - } - else - { - break; - } - } - } - break; - } - - } - else // sortie de la boucle de remontee - { - // check if we started from a position far from the other. - if (mouseAt2.distanceIsInferiorToThreshold1) - timeToFill.clear(); - break; - } - } - } - - // si le time to fill est >0 c'est qu'il a trouve qq chose. - // il faut maintenant avancer dans le temps jusqu a la fin de l evenement - if (timeToFill.size() > 0) - { - for (int t2 = t + 1; t2 < tMax; t2++) - { - MouseInfoRecord mouseAt2 = mouseARecord.get(t2); - if (mouseAt2.isGoingToTheOther) - { - timeToFill.add(t2); - t = t2; - } - else - { - break; - } - } - } - - for (int i = 0; i < timeToFill.size(); i++) - { - int index = timeToFill.get(i); - MouseInfoRecord mouseAt2 = mouseARecord.get(index); - mouseAt2.isGettingToOtherAndTouch = true; - - eventTimeLine.addPunctualEvent(index - firstFrame); - - } - - } - - } - } - - g2.setColor(Color.red); - nbEvent = 0; - total = 0; - // draw result - for (EventCriteria eventCriteria : eventTimeLine.eventList) - { - // System.out.println( "event. StartFrame: " + eventCriteria.startFrame + " EndFrame: " + eventCriteria.endFrame ); - nbEvent++; - total += eventCriteria.getLength(); - for (int i = eventCriteria.startFrame; i <= eventCriteria.endFrame; i++) - { - g2.drawLine(i, currentY, i, currentY + stepY); - } - } - - g2.setColor(Color.black); - g2.drawLine(0, currentY, imageChrono.getWidth(), currentY); - String string = "Mouse A going to B and finishing with contact starting from no contact.: nbEvent : " - + nbEvent + " total: " + nbFrameToDisplayInSecond(total); - g2.drawString(string, 0, currentY + 12); - imageComponent.stringList.add(string); - - currentY += stepY; - } - - { - // Mouse B going to A and finishing with contact and starting from > Threshold Distance. - - EventTimeLine eventTimeLine = new EventTimeLine( - "Mouse B going to A and finishing with contact and starting from no contact", - EventType.B_GOTO_A_FINISH_CONTACT_START_NO_CONTACT, TimeLineCategory.USE_BOOLEAN_EVENT); - animal.eventTimeLineList.add(eventTimeLine); - - float nbVal = 0; - float totalDistance = 0; - float nbEvent = 0; - float total = 0; - for (int t = 0; t < tMax; t++) - { - if (mouseARecord.containsKey(t)) - if (mouseBRecord.containsKey(t)) - { - - MouseInfoRecord mouseA = mouseARecord.get(t); - MouseInfoRecord mouseB = mouseBRecord.get(t); - - if (mouseA.distanceIsInferiorToThreshold1) // contact - { - - ArrayList<Integer> timeToFill = new ArrayList<Integer>(); - // loop back if there is an approach - for (int t2 = t; t2 > 0; t2--) - { - - if (mouseBRecord.containsKey(t2)) - { - MouseInfoRecord mouseBt2 = mouseBRecord.get(t2); - if (mouseBt2.isGoingToTheOther) - { - timeToFill.add(t2); - - if (!mouseBt2.distanceIsInferiorToThreshold1) - { - for (int t3 = t2; t3 > 0; t3--) - { - if (mouseBRecord.containsKey(t3)) - { - MouseInfoRecord mouseBt3 = mouseBRecord.get(t3); - if (mouseBt3.isGoingToTheOther) - { - timeToFill.add(t3); - } - else - { - break; - } - } - } - break; - } - - } - else // sortie de la boucle de remontee - { - // check if we started from a position far from the other. - if (mouseBt2.distanceIsInferiorToThreshold1) - timeToFill.clear(); - break; - } - } - } - - // si le time to fill est >0 c'est qu'il a trouve qq chose. - // il faut maintenant avancer dans le temps jusqu a la fin de l evenement - if (timeToFill.size() > 0) - { - for (int t2 = t + 1; t2 < tMax; t2++) - { - MouseInfoRecord mouseBt2 = mouseBRecord.get(t2); - if (mouseBt2.isGoingToTheOther) - { - timeToFill.add(t2); - t = t2; - } - else - { - break; - } - } - } - - g2.setColor(Color.green); - if (timeToFill.size() > 0) - nbEvent++; - total += timeToFill.size(); - for (int i = 0; i < timeToFill.size(); i++) - { - int index = timeToFill.get(i); - MouseInfoRecord mouseBt2 = mouseBRecord.get(index); - mouseBt2.isGettingToOtherAndTouch = true; - eventTimeLine.addPunctualEvent(index - firstFrame); - - } - - } - - } - } - - g2.setColor(Color.green); - // draw result - - nbEvent = 0; - total = 0; - for (EventCriteria eventCriteria : eventTimeLine.eventList) - { - nbEvent++; - total += eventCriteria.getLength(); - for (int i = eventCriteria.startFrame; i <= eventCriteria.endFrame; i++) - { - g2.drawLine(i, currentY, i, currentY + stepY); - } - } - - g2.setColor(Color.black); - g2.drawLine(0, currentY, imageChrono.getWidth(), currentY); - String string = "Mouse B going to A and finishing with contact starting from no contact.: nbEvent : " - + nbEvent + " total: " + nbFrameToDisplayInSecond(total); - g2.drawString(string, 0, currentY + 12); - imageComponent.stringList.add(string); - - currentY += stepY; - } - - { - // Mouse A escaping after contact. finish with out threshold. - - EventTimeLine eventTimeLine = new EventTimeLine( - "Mouse A escaping after contact. finish with out threshold.", - EventType.A_ESCAPE_AFTER_CONTACT_FINISH_WITH_NO_CONTACT, TimeLineCategory.USE_BOOLEAN_EVENT); - animal.eventTimeLineList.add(eventTimeLine); - - float nbVal = 0; - float totalDistance = 0; - float nbEvent = 0; - float total = 0; - - for (int t = 0; t < tMax; t++) - { - if (mouseARecord.containsKey(t)) - if (mouseBRecord.containsKey(t)) - { - - MouseInfoRecord mouseA = mouseARecord.get(t); - MouseInfoRecord mouseB = mouseBRecord.get(t); - - if (mouseA.distanceIsInferiorToThreshold1) // contact - { - ArrayList<Integer> timeToFill = new ArrayList<Integer>(); - // loop back if there is an approach - for (int t2 = t; t2 < Integer.MAX_VALUE; t2++) - { - if (mouseARecord.containsKey(t2)) - { - MouseInfoRecord mouseAt2 = mouseARecord.get(t2); - if (mouseAt2.isEscaping) - { - timeToFill.add(t2); - - if (!mouseAt2.distanceIsInferiorToThreshold1) - { - - for (int t3 = t2; t3 < tMax; t3++) - { - if (mouseARecord.containsKey(t3)) - { - MouseInfoRecord mouseAt3 = mouseARecord.get(t3); - if (mouseAt3.isEscaping) - { - timeToFill.add(t3); - } - else - { - break; - } - } - } - break; - } - - } - else // sortie de la boucle de remontee - { - // check if we started from a position far from the other. - if (mouseAt2.distanceIsInferiorToThreshold1) - timeToFill.clear(); - break; - } - } - else - { - break; - } - } - g2.setColor(Color.red); - if (timeToFill.size() > 0) - nbEvent++; - total += timeToFill.size(); - - for (int i = 0; i < timeToFill.size(); i++) - { - int index = timeToFill.get(i); - MouseInfoRecord mouseAt2 = mouseARecord.get(index); - mouseAt2.isEscapingFromOtherAndUnTouch = true; - eventTimeLine.addPunctualEvent(index - firstFrame); - - } - t += timeToFill.size(); - } - - } - } - g2.setColor(Color.red); - - // draw result - nbEvent = 0; - total = 0; - for (EventCriteria eventCriteria : eventTimeLine.eventList) - { - nbEvent++; - total += eventCriteria.getLength(); - for (int i = eventCriteria.startFrame; i <= eventCriteria.endFrame; i++) - { - g2.drawLine(i, currentY, i, currentY + stepY); - } - } - - g2.setColor(Color.black); - g2.drawLine(0, currentY, imageChrono.getWidth(), currentY); - String string = "Mouse A escaping after contact and finish out of distance threshold. : nbEvent : " - + nbEvent + " total: " + nbFrameToDisplayInSecond(total); - g2.drawString(string, 0, currentY + 12); - imageComponent.stringList.add(string); - - currentY += stepY; - } - - { - // Mouse B escaping after contact. finish with out threshold. - - EventTimeLine eventTimeLine = new EventTimeLine( - "Mouse B escaping after contact. finish with out threshold.", - EventType.B_ESCAPE_AFTER_CONTACT_FINISH_WITH_NO_CONTACT, TimeLineCategory.USE_BOOLEAN_EVENT); - animal.eventTimeLineList.add(eventTimeLine); - - float nbVal = 0; - float totalDistance = 0; - float nbEvent = 0; - float total = 0; - for (int t = 0; t < tMax; t++) - { - if (mouseARecord.containsKey(t)) - if (mouseBRecord.containsKey(t)) - { - - MouseInfoRecord mouseA = mouseARecord.get(t); - MouseInfoRecord mouseB = mouseBRecord.get(t); - - if (mouseA.distanceIsInferiorToThreshold1) // contact - { - ArrayList<Integer> timeToFill = new ArrayList<Integer>(); - // loop back if there is an approach - for (int t2 = t; t2 < Integer.MAX_VALUE; t2++) - { - if (mouseBRecord.containsKey(t2)) - { - MouseInfoRecord mouseBt2 = mouseBRecord.get(t2); - if (mouseBt2.isEscaping) - { - timeToFill.add(t2); - - if (!mouseBt2.distanceIsInferiorToThreshold1) - { - - for (int t3 = t2; t3 < tMax; t3++) - { - if (mouseBRecord.containsKey(t3)) - { - MouseInfoRecord mouseBt3 = mouseBRecord.get(t3); - if (mouseBt3.isEscaping) - { - timeToFill.add(t3); - } - else - { - break; - } - } - } - break; - } - - } - else - { - - if (mouseBt2.distanceIsInferiorToThreshold1) - timeToFill.clear(); - break; - } - } - else - { - break; - } - } - g2.setColor(Color.green); - if (timeToFill.size() > 0) - nbEvent++; - total += timeToFill.size(); - - for (int i = 0; i < timeToFill.size(); i++) - { - int index = timeToFill.get(i); - MouseInfoRecord mouseBt2 = mouseBRecord.get(index); - mouseBt2.isEscapingFromOtherAndUnTouch = true; - - eventTimeLine.addPunctualEvent(index - firstFrame); - - } - t += timeToFill.size(); - } - - } - } - g2.setColor(Color.green); - - nbEvent = 0; - total = 0; - for (EventCriteria eventCriteria : eventTimeLine.eventList) - { - nbEvent++; - total += eventCriteria.getLength(); - for (int i = eventCriteria.startFrame; i <= eventCriteria.endFrame; i++) - { - g2.drawLine(i, currentY, i, currentY + stepY); - } - } - - g2.setColor(Color.black); - g2.drawLine(0, currentY, imageChrono.getWidth(), currentY); - String string = "Mouse B escaping after contact and finish out of distance threshold : nbEvent : " - + nbEvent + " total: " + nbFrameToDisplayInSecond(total); - g2.drawString(string, 0, currentY + 12); - imageComponent.stringList.add(string); - - currentY += stepY; - } - - { - // Mouse A get to mouse B and B escape with threshold distance in and out. - - EventTimeLine eventTimeLine = new EventTimeLine("A get to B and B escape threshold in and out", - EventType.A_GOTO_B_AND_B_ESCAPE_THRESHOLD_IN_OUT, TimeLineCategory.USE_BOOLEAN_EVENT); - animal.eventTimeLineList.add(eventTimeLine); - - float nbVal = 0; - float totalDistance = 0; - float nbEvent = 0; - float total = 0; - for (int t = 0; t < tMax; t++) - { - if (mouseARecord.containsKey(t)) - if (mouseBRecord.containsKey(t)) - { - - MouseInfoRecord mouseA = mouseARecord.get(t); - MouseInfoRecord mouseB = mouseBRecord.get(t); - - if (mouseA.isGettingToOtherAndTouch) // contact - { - ArrayList<Integer> timeToFill = new ArrayList<Integer>(); - - boolean step1ok = false; - boolean step2ok = false; - boolean step3ok = false; - - int seeker = t; - - // STEP 1 - - for (int t2 = seeker; t2 < tMax; t2++) - { - seeker = t2; - if (mouseARecord.containsKey(t2)) - { - MouseInfoRecord mouseAt2 = mouseARecord.get(t2); - if (mouseAt2.isGettingToOtherAndTouch) - { - timeToFill.add(t2); - } - else // sortie de la boucle de remontee - { - step1ok = true; - break; - } - } - } - - // STEP 2 - - for (int t2 = seeker; t2 < tMax; t2++) - { - seeker = t2; - if (mouseARecord.containsKey(t2)) - { - MouseInfoRecord mouseAt2 = mouseARecord.get(t2); - if (mouseAt2.distanceIsInferiorToThreshold1) - { - timeToFill.add(t2); - } - else // sortie de la boucle de remontee - { - step2ok = true; - break; - } - } - } - - // STEP 3 - - for (int t2 = seeker; t2 < tMax; t2++) - { - seeker = t2; - if (mouseBRecord.containsKey(t2)) - { - MouseInfoRecord mouseBt2 = mouseBRecord.get(t2); - if (mouseBt2.isEscapingFromOtherAndUnTouch) - { - timeToFill.add(t2); - step3ok = true; - } - else // sortie de la boucle de remontee - { - break; - } - } - } - - if (!(step1ok && step2ok && step3ok)) - { - timeToFill.clear(); - } - - g2.setColor(Color.red); - if (timeToFill.size() > 0) - nbEvent++; - total += timeToFill.size(); - - for (int i = 0; i < timeToFill.size(); i++) - { - int index = timeToFill.get(i); - MouseInfoRecord mouseBt2 = mouseBRecord.get(index); - mouseBt2.isEscapingFromOtherAndUnTouch = true; - - eventTimeLine.addPunctualEvent(index - firstFrame); - - mouseARecord.get(index).mouseGetToOtherMouseAndOtherEscapeInOut = true; - } - t += timeToFill.size(); - } - - } - } - - g2.setColor(Color.red); - nbEvent = 0; - total = 0; - // draw result - for (EventCriteria eventCriteria : eventTimeLine.eventList) - { - nbEvent++; - total += eventCriteria.getLength(); - for (int i = eventCriteria.startFrame; i <= eventCriteria.endFrame; i++) - { - g2.drawLine(i, currentY, i, currentY + stepY); - } - } - - g2.setColor(Color.black); - g2.drawLine(0, currentY, imageChrono.getWidth(), currentY); - g2.drawLine(0, currentY + 1, imageChrono.getWidth(), currentY + 1); - - String string = "Mouse A get to mouse B and B escape with threshold distance in and out : nbEvent : " - + nbEvent + " total: " + nbFrameToDisplayInSecond(total); - g2.drawString(string, 0, currentY + 12); - imageComponent.stringList.add(string); - - currentY += stepY; - } - - { - // Mouse B get to mouse A and A escape with threshold distance in and out - - EventTimeLine eventTimeLine = new EventTimeLine("B get to A and A escape threshold in and out", - EventType.B_GOTO_A_AND_A_ESCAPE_THRESHOLD_IN_OUT, TimeLineCategory.USE_BOOLEAN_EVENT); - animal.eventTimeLineList.add(eventTimeLine); - - float nbVal = 0; - float totalDistance = 0; - float nbEvent = 0; - float total = 0; - - for (int t = 0; t < tMax; t++) - { - if (mouseARecord.containsKey(t)) - if (mouseBRecord.containsKey(t)) - { - - MouseInfoRecord mouseA = mouseARecord.get(t); - MouseInfoRecord mouseB = mouseBRecord.get(t); - - if (mouseB.isGettingToOtherAndTouch) // contact - { - ArrayList<Integer> timeToFill = new ArrayList<Integer>(); - // loop forward to the contact. - - boolean step1ok = false; - boolean step2ok = false; - boolean step3ok = false; - - int seeker = t; - - // STEP 1 - - for (int t2 = seeker; t2 < tMax; t2++) - { - seeker = t2; - if (mouseBRecord.containsKey(t2)) - { - MouseInfoRecord mouseBt2 = mouseBRecord.get(t2); - if (mouseBt2.isGettingToOtherAndTouch) - { - timeToFill.add(t2); - } - else // sortie de la boucle de remontee - { - step1ok = true; - break; - } - } - } - - // STEP 2 - - for (int t2 = seeker; t2 < tMax; t2++) - { - seeker = t2; - if (mouseBRecord.containsKey(t2)) - { - MouseInfoRecord mouseBt2 = mouseBRecord.get(t2); - if (mouseBt2.distanceIsInferiorToThreshold1) - { - timeToFill.add(t2); - } - else // sortie de la boucle de remontee - { - step2ok = true; - break; - } - } - } - - // STEP 3 - - for (int t2 = seeker; t2 < tMax; t2++) - { - seeker = t2; - if (mouseARecord.containsKey(t2)) - { - MouseInfoRecord mouseAt2 = mouseARecord.get(t2); - if (mouseAt2.isEscapingFromOtherAndUnTouch) - { - timeToFill.add(t2); - step3ok = true; - } - else // sortie de la boucle de remontee - { - break; - } - } - } - - if (!(step1ok && step2ok && step3ok)) - { - timeToFill.clear(); - } - - g2.setColor(Color.green); - if (timeToFill.size() > 0) - nbEvent++; - total += timeToFill.size(); - - for (int i = 0; i < timeToFill.size(); i++) - { - int index = timeToFill.get(i); - MouseInfoRecord mouseAt2 = mouseARecord.get(index); - mouseAt2.isEscapingFromOtherAndUnTouch = true; - - eventTimeLine.addPunctualEvent(index - firstFrame); - - mouseBRecord.get(index).mouseGetToOtherMouseAndOtherEscapeInOut = true; - } - t += timeToFill.size(); - } - - } - } - g2.setColor(Color.green); - nbEvent = 0; - total = 0; - // draw result - for (EventCriteria eventCriteria : eventTimeLine.eventList) - { - nbEvent++; - total += eventCriteria.getLength(); - for (int i = eventCriteria.startFrame; i <= eventCriteria.endFrame; i++) - { - g2.drawLine(i, currentY, i, currentY + stepY); - } - } - g2.setColor(Color.black); - g2.drawLine(0, currentY, imageChrono.getWidth(), currentY); - String string = "Mouse B get to mouse A and A escape with threshold distance in and out : nbEvent : " - + nbEvent + " total: " + nbFrameToDisplayInSecond(total); - g2.drawString(string, 0, currentY + 12); - imageComponent.stringList.add(string); - - currentY += stepY; - } - - { - // Mouse A get to mouse B and A escape with threshold distance in and out. - - EventTimeLine eventTimeLine = new EventTimeLine("A get to B and A escape threshold in and out", - EventType.A_GOTO_B_AND_A_ESCAPE_THRESHOLD_IN_OUT, TimeLineCategory.USE_BOOLEAN_EVENT); - animal.eventTimeLineList.add(eventTimeLine); - - float nbVal = 0; - float totalDistance = 0; - float nbEvent = 0; - float total = 0; - for (int t = 0; t < tMax; t++) - { - if (mouseARecord.containsKey(t)) - if (mouseBRecord.containsKey(t)) - { - - MouseInfoRecord mouseA = mouseARecord.get(t); - MouseInfoRecord mouseB = mouseBRecord.get(t); - - if (mouseA.isGettingToOtherAndTouch) // contact - { - ArrayList<Integer> timeToFill = new ArrayList<Integer>(); - // loop forward to the contact. - - boolean step1ok = false; - boolean step2ok = false; - boolean step3ok = false; - - int seeker = t; - - // STEP 1 - - for (int t2 = seeker; t2 < tMax; t2++) - { - seeker = t2; - if (mouseARecord.containsKey(t2)) - { - MouseInfoRecord mouseAt2 = mouseARecord.get(t2); - if (mouseAt2.isGettingToOtherAndTouch) - { - timeToFill.add(t2); - step1ok = true; // maintenant ici - } - else // sortie de la boucle de remontee - { - // step1ok = true; avant la - break; - } - } - } - - // STEP 2 - - for (int t2 = seeker; t2 < tMax; t2++) - { - seeker = t2; - if (mouseARecord.containsKey(t2)) - { - MouseInfoRecord mouseAt2 = mouseARecord.get(t2); - if (mouseAt2.distanceIsInferiorToThreshold1) - { - timeToFill.add(t2); - step2ok = true; // mainetnant ici - } - else // sortie de la boucle de remontee - { - // step2ok = true; avant la - break; - } - } - } - - // STEP 3 - - for (int t2 = seeker; t2 < tMax; t2++) - { - seeker = t2; - if (mouseARecord.containsKey(t2)) - { - MouseInfoRecord mouseAt2 = mouseARecord.get(t2); - if (mouseAt2.isEscapingFromOtherAndUnTouch) - { - timeToFill.add(t2); - step3ok = true; - } - else // sortie de la boucle de remontee - { - break; - } - } - } - - if (!(step1ok && step2ok && step3ok)) - { - timeToFill.clear(); - } - - g2.setColor(Color.red); - if (timeToFill.size() > 0) - nbEvent++; - total += timeToFill.size(); - for (int i = 0; i < timeToFill.size(); i++) - { - int index = timeToFill.get(i); - MouseInfoRecord mouseBt2 = mouseBRecord.get(index); - mouseBt2.isEscapingFromOtherAndUnTouch = true; - - eventTimeLine.addPunctualEvent(index - firstFrame); - - mouseARecord.get(index).mouseGetToOtherMouseAndEscapeInOut = true; - } - t += timeToFill.size(); - } - - } - } - g2.setColor(Color.red); - - nbEvent = 0; - total = 0; - // draw result - for (EventCriteria eventCriteria : eventTimeLine.eventList) - { - nbEvent++; - total += eventCriteria.getLength(); - for (int i = eventCriteria.startFrame; i <= eventCriteria.endFrame; i++) - { - g2.drawLine(i, currentY, i, currentY + stepY); - } - } - - g2.setColor(Color.black); - g2.drawLine(0, currentY, imageChrono.getWidth(), currentY); - g2.drawLine(0, currentY + 1, imageChrono.getWidth(), currentY + 1); - String string = "Mouse A get to mouse B and A escape with threshold distance in and out : nbEvent : " - + nbEvent + " total: " + nbFrameToDisplayInSecond(total); - g2.drawString(string, 0, currentY + 12); - imageComponent.stringList.add(string); - - currentY += stepY; - } - - { - // Mouse B get to mouse A and B escape with threshold distance in and out - - EventTimeLine eventTimeLine = new EventTimeLine("B get to A and B escape threshold in and out", - EventType.B_GOTO_A_AND_B_ESCAPE_THRESHOLD_IN_OUT, TimeLineCategory.USE_BOOLEAN_EVENT); - animal.eventTimeLineList.add(eventTimeLine); - - float nbVal = 0; - float totalDistance = 0; - float nbEvent = 0; - float total = 0; - - for (int t = 0; t < tMax; t++) - { - if (mouseARecord.containsKey(t)) - if (mouseBRecord.containsKey(t)) - { - - MouseInfoRecord mouseA = mouseARecord.get(t); - MouseInfoRecord mouseB = mouseBRecord.get(t); - - if (mouseB.isGettingToOtherAndTouch) // contact - { - ArrayList<Integer> timeToFill = new ArrayList<Integer>(); - // loop forward to the contact. - - boolean step1ok = false; - boolean step2ok = false; - boolean step3ok = false; - - int seeker = t; - - // STEP 1 - - for (int t2 = seeker; t2 < tMax; t2++) - { - seeker = t2; - if (mouseBRecord.containsKey(t2)) - { - MouseInfoRecord mouseBt2 = mouseBRecord.get(t2); - if (mouseBt2.isGettingToOtherAndTouch) - { - timeToFill.add(t2); - step1ok = true; // maintenant ici - } - else // sortie de la boucle de remontee - { - // avant ici step1ok = true; - break; - } - } - } - - // STEP 2 - - for (int t2 = seeker; t2 < tMax; t2++) - { - seeker = t2; - if (mouseBRecord.containsKey(t2)) - { - MouseInfoRecord mouseBt2 = mouseBRecord.get(t2); - if (mouseBt2.distanceIsInferiorToThreshold1) - { - timeToFill.add(t2); - step2ok = true; // mis ici - } - else // sortie de la boucle de remontee - { - // step2ok = true; avant ici - break; - } - } - } - - // STEP 3 - - for (int t2 = seeker; t2 < tMax; t2++) - { - seeker = t2; - if (mouseBRecord.containsKey(t2)) - { - MouseInfoRecord mouseBt2 = mouseBRecord.get(t2); - if (mouseBt2.isEscapingFromOtherAndUnTouch) - { - timeToFill.add(t2); - step3ok = true; - } - else // sortie de la boucle de remontee - { - break; - } - } - } - - if (!(step1ok && step2ok && step3ok)) - { - timeToFill.clear(); - } - - g2.setColor(Color.green); - if (timeToFill.size() > 0) - nbEvent++; - total += timeToFill.size(); - - for (int i = 0; i < timeToFill.size(); i++) - { - int index = timeToFill.get(i); - MouseInfoRecord mouseAt2 = mouseARecord.get(index); - mouseAt2.isEscapingFromOtherAndUnTouch = true; - eventTimeLine.addPunctualEvent(index - firstFrame); - - mouseBRecord.get(index).mouseGetToOtherMouseAndEscapeInOut = true; - } - t += timeToFill.size(); - - } - - } - } - g2.setColor(Color.green); - nbEvent = 0; - total = 0; - // draw result - for (EventCriteria eventCriteria : eventTimeLine.eventList) - { - nbEvent++; - total += eventCriteria.getLength(); - for (int i = eventCriteria.startFrame; i <= eventCriteria.endFrame; i++) - { - g2.drawLine(i, currentY, i, currentY + stepY); - } - } - - g2.setColor(Color.black); - g2.drawLine(0, currentY, imageChrono.getWidth(), currentY); - String string = "Mouse B get to mouse A and B escape with threshold distance in and out : nbEvent : " - + nbEvent + " total: " + nbFrameToDisplayInSecond(total); - g2.drawString(string, 0, currentY + 12); - imageComponent.stringList.add(string); - - currentY += stepY; - } - - g2.drawLine(0, currentY, imageChrono.getWidth(), currentY); - - { - // Event de poursuite. - // A Poursuit B - // = - // A est en mouvement - // B est en mouvement - // A est derriere B ou A est sur le cote de B - // Distance A-B inferieure a Threshold 2 ( le plus loin ) - - EventTimeLine eventTimeLine = new EventTimeLine("A follow B", EventType.A_FOLLOW_B, - TimeLineCategory.USE_BOOLEAN_EVENT); - animal.eventTimeLineList.add(eventTimeLine); - - float nbVal = 0; - float totalDistance = 0; - float nbEvent = 0; - float total = 0; - - EventCriteria currentCriteria = null; - - for (int t = 0; t < tMax; t++) - { - if (mouseARecord.containsKey(t)) - if (mouseBRecord.containsKey(t)) - { - - MouseInfoRecord mouseA = mouseARecord.get(t); - MouseInfoRecord mouseB = mouseBRecord.get(t); - - double distanceHeadABodyB = mouseA.headPosition.distanceSq(mouseB.bodyPosition); - double distanceHeadAHeadB = mouseA.headPosition.distanceSq(mouseB.headPosition); - double distanceBodyABodyB = mouseA.bodyPosition.distanceSq(mouseB.bodyPosition); - double distanceBodyAHeadB = mouseA.bodyPosition.distanceSq(mouseB.headPosition); - - if (mouseB.distanceIsInferiorToThreshold2 // moins precis mais moins de bruit - - && mouseA.speed > SPEED_THRESHOLD_2 && mouseB.speed > SPEED_THRESHOLD_2 - && (mouseA.isBehindTheOther || mouseA.isBesideTheOther) - - ) // contact threshold 2 - { - eventTimeLine.addPunctualEvent(t - firstFrame); - - } - - } - } - // filter results - - eventTimeLine.removeEventLessThanLength(3); - - g2.setColor(Color.RED); - // display result. - nbEvent = 0; - total = 0; - // draw result - for (EventCriteria eventCriteria : eventTimeLine.eventList) - { - nbEvent++; - total += eventCriteria.getLength(); - for (int i = eventCriteria.startFrame; i <= eventCriteria.endFrame; i++) - { - g2.drawLine(i, currentY, i, currentY + stepY); - } - } - - g2.setColor(Color.black); - g2.drawLine(0, currentY, imageChrono.getWidth(), currentY); - String string = "Mouse A poursuit B : nbEvent : " + nbEvent + " total time: " + total / FPS + "s"; - g2.drawString(string, 0, currentY + 12); - imageComponent.stringList.add(string); - - currentY += stepY; - } - - g2.drawLine(0, currentY, imageChrono.getWidth(), currentY); - - { - // A est derriere B et B est derriere A - // A est à l'arret et B est à l'arret - // distance superieure a Threshold 2 - // back to back - // angle formé inferieur a ANGLE dans le code ( 0.52d Rad ) - - EventTimeLine eventTimeLine = new EventTimeLine("back to back", EventType.A_BEHIND_B_AND_B_BEHIND_A, - TimeLineCategory.USE_BOOLEAN_EVENT); - animal.eventTimeLineList.add(eventTimeLine); - - float nbVal = 0; - float totalDistance = 0; - float nbEvent = 0; - float total = 0; - - EventCriteria currentCriteria = null; - - for (int t = 0; t < tMax; t++) - { - if (mouseARecord.containsKey(t)) - if (mouseBRecord.containsKey(t)) - { - - MouseInfoRecord mouseA = mouseARecord.get(t); - MouseInfoRecord mouseB = mouseBRecord.get(t); - - double distanceHeadABodyB = mouseA.headPosition.distanceSq(mouseB.bodyPosition); - double distanceHeadAHeadB = mouseA.headPosition.distanceSq(mouseB.headPosition); - double distanceBodyABodyB = mouseA.bodyPosition.distanceSq(mouseB.bodyPosition); - double distanceBodyAHeadB = mouseA.bodyPosition.distanceSq(mouseB.headPosition); - - double VAx = mouseA.headPosition.getX() - mouseA.bodyPosition.getX(); - double VAy = mouseA.headPosition.getY() - mouseA.bodyPosition.getY(); - double angleA = Math.atan2(VAy, VAx); - - double VBx = mouseB.headPosition.getX() - mouseB.bodyPosition.getX(); - double VBy = mouseB.headPosition.getY() - mouseB.bodyPosition.getY(); - double angleB = Math.atan2(VBy, VBx); - - // angle fait par le segment qui va de la souris A a la souris B. - - double VABx = mouseB.bodyPosition.getX() - mouseA.bodyPosition.getX(); - double VABy = mouseB.bodyPosition.getY() - mouseA.bodyPosition.getY(); - double angleAB = Math.atan2(VABy, VABx); - - angleB = angleB - Math.PI; - - // on recale les angles pour les rendres comparables - - // recherche de la plus petite difference entre les angles. - - double minAngle = Double.MAX_VALUE; - for (double a = -4; a < 5; a++) - { - double testVal = Math.abs(angleB + 2 * Math.PI * a - angleA); - if (testVal < minAngle) - minAngle = testVal; - } - - double minAngleABwithA = Double.MAX_VALUE; - for (double a = -4; a < 5; a++) - { - double testVal = Math.abs(angleA + Math.PI * a - angleAB); - if (testVal < minAngleABwithA) - minAngleABwithA = testVal; - } - - double minAngleABwithB = Double.MAX_VALUE; - for (double a = -4; a < 5; a++) - { - double testVal = Math.abs(angleB + Math.PI * a - angleAB); - if (testVal < minAngleABwithB) - minAngleABwithB = testVal; - } - - if (mouseA.speed < SPEED_THRESHOLD_1 && mouseB.speed < SPEED_THRESHOLD_1) - if (!mouseA.distanceIsInferiorToThreshold2) // distance > Threshold 2 - if (minAngle < 0.52d && mouseA.isBehindTheOther && mouseB.isBehindTheOther) // && !mouseA.distanceIsInferiorToThreshold1 ) - // // premier argument trouve angle opposé et - // l'autre force culcul - if (minAngleABwithA < 0.52d) - if (minAngleABwithB < 0.52d) - { - eventTimeLine.addPunctualEvent(t - firstFrame); - } - - } - } - // filter results - - eventTimeLine.removeEventLessThanLength(3); - - g2.setColor(Color.gray); - // display result. - nbEvent = 0; - total = 0; - // draw result - for (EventCriteria eventCriteria : eventTimeLine.eventList) - { - nbEvent++; - total += eventCriteria.getLength(); - for (int i = eventCriteria.startFrame; i <= eventCriteria.endFrame; i++) - { - g2.drawLine(i, currentY, i, currentY + stepY); - } - } - - g2.setColor(Color.black); - g2.drawLine(0, currentY, imageChrono.getWidth(), currentY); - String string = "Back to back: nbEvent : " + nbEvent + " total time: " + total / FPS + "s"; - g2.drawString(string, 0, currentY + 12); - imageComponent.stringList.add(string); - - currentY += stepY; - } - - g2.drawLine(0, currentY, imageChrono.getWidth(), currentY); - - // A regarde l'autre souris - // - { - EventTimeLine eventTimeLine = new EventTimeLine("A can see B", EventType.A_CAN_SEE_B, - TimeLineCategory.USE_BOOLEAN_EVENT); - animal.eventTimeLineList.add(eventTimeLine); - - float nbVal = 0; - float totalDistance = 0; - float nbEvent = 0; - float total = 0; - - EventCriteria currentCriteria = null; - - for (int t = 0; t < tMax; t++) - { - if (mouseARecord.containsKey(t)) - if (mouseBRecord.containsKey(t)) - { - - // --------------------- - - MouseInfoRecord mouseA = mouseARecord.get(t); - MouseInfoRecord mouseB = mouseBRecord.get(t); - - double distanceHeadABodyB = mouseA.headPosition.distanceSq(mouseB.bodyPosition); - double distanceHeadAHeadB = mouseA.headPosition.distanceSq(mouseB.headPosition); - double distanceBodyABodyB = mouseA.bodyPosition.distanceSq(mouseB.bodyPosition); - double distanceBodyAHeadB = mouseA.bodyPosition.distanceSq(mouseB.headPosition); - - double VAx = mouseA.headPosition.getX() - mouseA.bodyPosition.getX(); - double VAy = mouseA.headPosition.getY() - mouseA.bodyPosition.getY(); - double angleA = Math.atan2(VAy, VAx); - - // teste A dans la vue. - - double VABx = mouseA.headPosition.getX() - mouseB.headPosition.getX(); - double VABy = mouseA.headPosition.getY() - mouseB.headPosition.getY(); - double angleBA = Math.atan2(VABy, VABx) + Math.PI; - - boolean eventIsOk = true; - - // if ( angleMin( angleBA , angleB ) < Math.PI / 2f ) - if (angleMin(angleBA, angleA) < demiVisionDeSouris) - { - // eventTimeLine.addPunctualEvent(t - firstFrame ); - } - else - { - eventIsOk = false; - } - - if (mouseA.distanceIsInferiorToThreshold2) - { - eventIsOk = false; - } - // ------------------------ - // flag l'event s'il est bon. - if (eventIsOk) - { - eventTimeLine.addPunctualEvent(t - firstFrame); - } - - } - } - // filter results - - eventTimeLine.removeEventLessThanLength(3); - - g2.setColor(Color.RED); - // display result. - nbEvent = 0; - total = 0; - // draw result - for (EventCriteria eventCriteria : eventTimeLine.eventList) - { - nbEvent++; - total += eventCriteria.getLength(); - for (int i = eventCriteria.startFrame; i <= eventCriteria.endFrame; i++) - { - g2.drawLine(i, currentY, i, currentY + stepY); - } - } - - g2.setColor(Color.black); - g2.drawLine(0, currentY, imageChrono.getWidth(), currentY); - String string = "Mouse A can see B: nbEvent : " + nbEvent + " total time: " + total / FPS + "s"; - g2.drawString(string, 0, currentY + 12); - imageComponent.stringList.add(string); - - currentY += stepY; - - } - - // B regarde l'autre souris - // - { - EventTimeLine eventTimeLine = new EventTimeLine("B can see A", EventType.B_CAN_SEE_A, - TimeLineCategory.USE_BOOLEAN_EVENT); - animal.eventTimeLineList.add(eventTimeLine); - - float nbVal = 0; - float totalDistance = 0; - float nbEvent = 0; - float total = 0; - - EventCriteria currentCriteria = null; - - for (int t = 0; t < tMax; t++) - { - if (mouseARecord.containsKey(t)) - if (mouseBRecord.containsKey(t)) - { - - MouseInfoRecord mouseA = mouseARecord.get(t); - MouseInfoRecord mouseB = mouseBRecord.get(t); - - double distanceHeadABodyB = mouseA.headPosition.distanceSq(mouseB.bodyPosition); - double distanceHeadAHeadB = mouseA.headPosition.distanceSq(mouseB.headPosition); - double distanceBodyABodyB = mouseA.bodyPosition.distanceSq(mouseB.bodyPosition); - double distanceBodyAHeadB = mouseA.bodyPosition.distanceSq(mouseB.headPosition); - - double VBx = mouseB.headPosition.getX() - mouseB.bodyPosition.getX(); - double VBy = mouseB.headPosition.getY() - mouseB.bodyPosition.getY(); - double angleB = Math.atan2(VBy, VBx); - - // teste A dans la vue. - - double VBAx = mouseB.headPosition.getX() - mouseA.headPosition.getX(); - double VBAy = mouseB.headPosition.getY() - mouseA.headPosition.getY(); - double angleBA = Math.atan2(VBAy, VBAx) + Math.PI; - - boolean eventIsOk = true; - - if (angleMin(angleBA, angleB) < demiVisionDeSouris) - { - - } - else - { - eventIsOk = false; - } - - // flag l'event s'il est bon. - if (eventIsOk) - { - eventTimeLine.addPunctualEvent(t - firstFrame); - } - - } - } - // filter results - - eventTimeLine.removeEventLessThanLength(3); - - g2.setColor(Color.GREEN); - // display result. - nbEvent = 0; - total = 0; - // draw result - for (EventCriteria eventCriteria : eventTimeLine.eventList) - { - nbEvent++; - total += eventCriteria.getLength(); - for (int i = eventCriteria.startFrame; i <= eventCriteria.endFrame; i++) - { - g2.drawLine(i, currentY, i, currentY + stepY); - } - } - - g2.setColor(Color.black); - g2.drawLine(0, currentY, imageChrono.getWidth(), currentY); - String string = "Mouse B can see A: nbEvent : " + nbEvent + " total time: " + total / FPS + "s"; - g2.drawString(string, 0, currentY + 12); - imageComponent.stringList.add(string); - - currentY += stepY; - - } - - g2.drawLine(0, currentY, imageChrono.getWidth(), currentY); - - currentY = loadExtraLabelXMLFile(file, currentY, g2); - currentY = loadExtraLabelAviSoftTXTFile(file, currentY, g2); - - Icy.getMainInterface().getSwimmingPool().add(swimmingObject); - - } - - private File getExtraXMLFile(File originalFile) - { - File extraFile = new File(FileUtil.setExtension(file.getAbsolutePath(), ".extra.xml")); - return extraFile; - } - - private File getExtraAviSoftTXTFile(File originalFile) - { - File extraFile = new File(FileUtil.setExtension(file.getAbsolutePath(), ".avisoft.txt")); - return extraFile; - } - - private File getExtraAviSoftXLSFile(File originalFile) - { - File extraFile = new File(FileUtil.setExtension(file.getAbsolutePath(), ".avisoft.xls")); - return extraFile; - } - - private int getNbExtraEvent(File originalFile) - { - - int nbExtraEvent = 0; - - { - File extraFile = getExtraXMLFile(originalFile); - if (extraFile.exists()) - { - - Document xmlDocument = XMLUtil.loadDocument(extraFile); - ArrayList<Element> labelElementList = XMLUtil.getElements(XMLUtil.getRootElement(xmlDocument), - "LABEL"); - - System.out.println("Number of extra user labels (XML): " + labelElementList.size()); - - nbExtraEvent += labelElementList.size(); - - } - } - - { - File extraFile = getExtraAviSoftTXTFile(originalFile); - if (extraFile.exists()) - { - // nlabel type duration interval starttime endtime pstart_time pstart pstart_ampl pend_time pend pend_ampl pmin_time pmin pmin_ampl - // pmax_time pmax pmax_ampl - - // Pattern pattern = Pattern.compile("(\t)(.*?)(\t)"); // finds string between tabs. - int nbElement = 0; - - HashMap<String, Integer> eventFoundHashMap = new HashMap<String, Integer>(); - - try - { - - Scanner scanner = new Scanner(extraFile); - - while (scanner.hasNextLine()) - { - int line = scanner.nextInt(); - String labelName = scanner.next(); - - // if ( labelName == null ) continue; - - int nbLabelWithThisName = 0; - if (eventFoundHashMap.containsKey(labelName)) - { - nbLabelWithThisName = eventFoundHashMap.get(labelName); - } - eventFoundHashMap.put(labelName, nbLabelWithThisName + 1); - - scanner.nextLine(); - } - - for (String labelName : eventFoundHashMap.keySet()) - { - System.out.println("Label Name : " + labelName + " #" + eventFoundHashMap.get(labelName)); - } - - nbElement += eventFoundHashMap.keySet().size(); - - } - catch (FileNotFoundException e) - { - e.printStackTrace(); - } - - System.out.println("Number of extra user labels (AviSoft TXT): " + nbElement); - - nbExtraEvent += nbElement; - } - } - - { - File extraFile = getExtraAviSoftXLSFile(originalFile); - if (extraFile.exists()) - { - // nlabel type duration interval starttime - - // Pattern pattern = Pattern.compile("(\t)(.*?)(\t)"); // finds string between tabs. - int nbElement = 0; - - HashMap<String, Integer> eventFoundHashMap = new HashMap<String, Integer>(); - - try - { - - Workbook workbook = Workbook.getWorkbook(extraFile); - - Sheet sheet = workbook.getSheet(0); - int nbRow = sheet.getRows(); - System.out.println("Number of row in excel file: " + nbRow); - - int row = 1; - while (row < nbRow) - { - String labelName = sheet.getCell(1, row).getContents(); - - int nbLabelWithThisName = 0; - if (eventFoundHashMap.containsKey(labelName)) - { - nbLabelWithThisName = eventFoundHashMap.get(labelName); - } - eventFoundHashMap.put(labelName, nbLabelWithThisName + 1); - - row++; - } - - for (String labelName : eventFoundHashMap.keySet()) - { - System.out.println("Label Name : " + labelName + " #" + eventFoundHashMap.get(labelName)); - } - - nbElement += eventFoundHashMap.keySet().size(); - - } - catch (FileNotFoundException e) - { - e.printStackTrace(); - } - catch (BiffException e) - { - // TODO Auto-generated catch block - e.printStackTrace(); - } - catch (IOException e) - { - // TODO Auto-generated catch block - e.printStackTrace(); - } - - System.out.println("Number of extra user labels (AviSoft XLS): " + nbElement); - - nbExtraEvent += nbElement; - } - } - - return nbExtraEvent; - } - - private int loadExtraLabelAviSoftTXTFile(File originalFile, int currentY, Graphics2D g2) - { - - File extraFile = getExtraAviSoftTXTFile(originalFile); - if (extraFile.exists()) - { - // nlabel type duration interval starttime endtime pstart_time pstart pstart_ampl pend_time pend pend_ampl pmin_time pmin pmin_ampl pmax_time - // pmax pmax_ampl - - // Pattern pattern = Pattern.compile("(\t)(.*?)(\t)"); // finds string between tabs. - int nbElement = 0; - - HashMap<String, EventTimeLine> eventTimeLineHashMap = new HashMap<String, EventTimeLine>(); - /* - * EventTimeLine userEvent = new EventTimeLine( userLabelName , - * EventType.USER_EVENT , TimeLineCategory.USE_BOOLEAN_EVENT ); - * animal.eventTimeLineList.add( userEvent ); - */ - - try - { - - loadDefaultUserEventSet(eventTimeLineHashMap, originalFile); - - Scanner scanner = new Scanner(extraFile); - - while (scanner.hasNextLine()) - { - int lineNumber = scanner.nextInt(); // scan line number - System.out.println("next line number : " + lineNumber); - - String labelName = scanner.next(); - - /* - * int nbLabelWithThisName = 0; - * if ( eventFoundHashMap.containsKey( labelName ) ) - * { - * nbLabelWithThisName = eventFoundHashMap.get( labelName ); - * } - * eventFoundHashMap.put( labelName , nbLabelWithThisName+1 ); - */ - // System.out.print( "label name: " + labelName + ":"); - EventTimeLine userEvent = null; - // for ( String keyString : eventTimeLineHashMap.keySet() ) - // { - // if ( keyString.equals( labelName ) ) - // { - // userEvent = eventTimeLineHashMap.get( labelName ); - // //System.out.print( ":found:"); - // break; - // } - // } - if (eventTimeLineHashMap.containsKey(labelName)) // retreive EventTimeLine - { - userEvent = eventTimeLineHashMap.get(labelName); - } - else - - // if (userEvent == null ) // means it was not found in keyset. - { // creates a new eventTimeLine for this label. - userEvent = new EventTimeLine(labelName, EventType.USER_EVENT, - TimeLineCategory.USE_BOOLEAN_EVENT); - eventTimeLineHashMap.put(labelName, userEvent); - animal.eventTimeLineList.add(userEvent); - } - - float duration = scanner.nextFloat(); - float interval = scanner.nextFloat(); - float startTime = scanner.nextFloat(); - - int durationInFrame = (int) (FPS * duration); - int startTimeInFrame = (int) (FPS * startTime); - - // System.out.println( "line: " + line + " l:" + labelName + " s:" + startTime + " d:" + duration ); - - for (int t = startTimeInFrame; t <= startTimeInFrame + durationInFrame; t++) - { - userEvent.addPunctualEvent(t - firstFrame); - // System.out.print("a"); - } - // System.out.println( ""); - if (scanner.hasNextLine()) // flush what remains in this line. - { - scanner.nextLine(); - } - } - - scanner.close(); - - // display label found - ArrayList keys = new ArrayList(eventTimeLineHashMap.keySet()); - Collections.sort(keys); - // for ( EventTimeLine eventTimeLine : eventTimeLineHashMap.values() ) - // for ( Object key : keys ) - for (int iTimeLine = 29; iTimeLine < animal.eventTimeLineList.size(); iTimeLine++) - { - // EventTimeLine eventTimeLine = eventTimeLineHashMap.get( key ); - EventTimeLine eventTimeLine = animal.eventTimeLineList.get(iTimeLine); - // EventTimeLine eventTimeLine = eventTimeLineHashMap.get( eventTimeLineString ); - System.out.println("Processing eventTimeLine... " + eventTimeLine.criteriaName + " nb event : " - + eventTimeLine.eventList.size()); - nbElement++; - - int nbEvent = 0; - int total = 0; - // draw result - g2.setColor(Color.BLUE); - for (EventCriteria eventCriteria : eventTimeLine.eventList) - { - nbEvent++; - total += eventCriteria.getLength(); - for (int i = eventCriteria.startFrame; i <= eventCriteria.endFrame; i++) - { - g2.drawLine(i, currentY, i, currentY + stepY); - } - } - - g2.setColor(Color.BLACK); - g2.drawLine(0, currentY, imageChrono.getWidth(), currentY); - String string = eventTimeLine.criteriaName + " nb event: " + nbEvent + " totalT: " - + nbFrameToDisplayInSecond(total); - g2.drawString(string, 0, currentY + 12); - - currentY += stepY; - - imageComponent.stringList.add(string); - - g2.drawLine(0, currentY, imageChrono.getWidth(), currentY); - - } - - } - catch (FileNotFoundException e) - { - e.printStackTrace(); - } - - System.out.println("Number of extra user labels (AviSoft): " + nbElement); - - } - - return currentY; - - } - - /** - * Loads a number of default user event set to force their presence in the list, and in a specific order. - * Then those events can be compared in the label analyser as they appear at the same line index event. - * (event 29 will be always the same) - * Loads the file in the folder call defaultUserEvents.txt - * Example of what it can contain: - * s - * f - * u - * d - * mo - * c - * j1 - * j2 - * mi - * n - * o - * - * @param eventTimeLineHashMap - * @param originalFile - */ - private void loadDefaultUserEventSet(HashMap<String, EventTimeLine> eventTimeLineHashMap, File originalFile) - { - - File defaultUserEventSetFile = new File( - FileUtil.getDirectory(originalFile.getAbsolutePath()) + "//defaultUserEvents.txt"); - - System.out.println("DefaultUserEventFile is: " + defaultUserEventSetFile.getAbsolutePath()); - - if (FileUtil.exists(defaultUserEventSetFile.getAbsolutePath())) - { - System.out.println("Loading default User events..."); - - try - { - Scanner scanner = new Scanner(defaultUserEventSetFile); - - while (scanner.hasNextLine()) - { - String labelName = scanner.nextLine(); - System.out.println(labelName); - EventTimeLine userEvent = new EventTimeLine(labelName, EventType.USER_EVENT, - TimeLineCategory.USE_BOOLEAN_EVENT); - eventTimeLineHashMap.put(labelName, userEvent); - animal.eventTimeLineList.add(userEvent); - } - - scanner.close(); - - } - catch (FileNotFoundException e) - { - e.printStackTrace(); - } - - } - - /* - * String labelName = ""; - * EventTimeLine userEvent = new EventTimeLine( labelName , - * EventType.USER_EVENT , TimeLineCategory.USE_BOOLEAN_EVENT ); - * eventTimeLineHashMap.put( labelName, userEvent ); - * animal.eventTimeLineList.add( userEvent ); - */ - - } - - private int loadExtraLabelXMLFile(File originalFile, int currentY, Graphics2D g2) - { - - // load labels generated by user ( file extra.xml ) - File extraFile = getExtraXMLFile(originalFile); - - System.out.println("XML file is: " + file.getAbsolutePath()); - System.out.println("Extra XML file is: " + extraFile.getAbsolutePath()); - - if (!extraFile.exists()) - return currentY; - - System.out.println("The extra info file exists... Processing..."); - - Document xmlDocument = XMLUtil.loadDocument(extraFile); - - /** offset to shit in time the incoming labels, in order to sync them if needed. */ - int offset = 0; - - ArrayList<Element> labelElementListOffset = XMLUtil.getElements(XMLUtil.getRootElement(xmlDocument), - "OFFSET"); - for (Element labelElement : labelElementListOffset) - { - offset = XMLUtil.getAttributeIntValue(labelElement, "offset", 0); - } - - /** min duration event */ - int minDurationEvent = 0; - - ArrayList<Element> labelElementListMinDuration = XMLUtil.getElements(XMLUtil.getRootElement(xmlDocument), - "MINDURATION"); - for (Element labelElement : labelElementListMinDuration) - { - minDurationEvent = XMLUtil.getAttributeIntValue(labelElement, "minduration", 0); - } - - ArrayList<Element> labelElementList = XMLUtil.getElements(XMLUtil.getRootElement(xmlDocument), "LABEL"); - - for (Element labelElement : labelElementList) - { - - String userLabelName = XMLUtil.getAttributeValue(labelElement, "name", "no name"); - String userLabelColorString = XMLUtil.getAttributeValue(labelElement, "color", "green"); - - System.out.println("Loading label " + userLabelName); - - Color userEventColor = null; - try - { - Field field = Class.forName("java.awt.Color").getField(userLabelColorString); - userEventColor = (Color) field.get(null); - } - catch (Exception e) - { - userEventColor = Color.green; // Not defined - System.err.println("Unsupported color in label " + userLabelName + " (switching to green)"); - } - - // create node - - int nbEvent = 0; - int total = 0; - - EventTimeLine userEvent = new EventTimeLine(userLabelName, EventType.USER_EVENT, - TimeLineCategory.USE_BOOLEAN_EVENT); - animal.eventTimeLineList.add(userEvent); - - synchronizeAllAnimalEvent(userEvent); - - g2.setColor(userEventColor); - - // read events. - ArrayList<Element> labelEventList = XMLUtil.getElements(labelElement, "EVENT"); - - for (Element labelEvent : labelEventList) - { - int start = XMLUtil.getAttributeIntValue(labelEvent, "start", -1); - int end = XMLUtil.getAttributeIntValue(labelEvent, "end", -1); - - if (start == -1) - { - System.err.println("Error in label " + userLabelName); - System.err.println("Wrong start value (skipping event)"); - continue; - } - - if (end == -1) - { - System.err.println("Error in label " + userLabelName); - System.err.println("Wrong end value (skipping event)"); - continue; - } - - if (start > end) - { - System.err.println("Error in label " + userLabelName); - System.err.println("start value > end value (skipping event)"); - continue; - } - - start += offset; - end += offset; - - // check minduration event: if the event is smaller than mindurationevent, create an event of the correct length from start. - - if (end - start < minDurationEvent) - { - end = start + minDurationEvent; - } - - for (int t = start; t <= end; t++) - { - userEvent.addPunctualEvent(t - firstFrame); - } - } - - nbEvent = 0; - total = 0; - // draw result - for (EventCriteria eventCriteria : userEvent.eventList) - { - nbEvent++; - total += eventCriteria.getLength(); - for (int i = eventCriteria.startFrame; i <= eventCriteria.endFrame; i++) - { - g2.drawLine(i, currentY, i, currentY + stepY); - } - } - - g2.setColor(Color.black); - g2.drawLine(0, currentY, imageChrono.getWidth(), currentY); - String string = userLabelName + nbEvent + " totalT: " + nbFrameToDisplayInSecond(total); - g2.drawString(string, 0, currentY + 12); - - currentY += stepY; - - imageComponent.stringList.add(string); - - g2.drawLine(0, currentY, imageChrono.getWidth(), currentY); - } - - System.out.println("Custom XML user label loaded."); - - return currentY; - } - - /** - * This function ensure that all the events are loaded the same way for all animals, - * and even resort them, in order to have the exact same list (and same order) of event for all animals - * - * @param userEvent - */ - private void synchronizeAllAnimalEvent(EventTimeLine userEvent) - { - - // TODO - - ArrayList<Animal> animalList = new ArrayList<Animal>(); - for (VideoLabelPanel videoLabelPanel : videoLabelPanelArrayList) - { - animalList.add(videoLabelPanel.animal); - } - - } - - float getMin(float a, float b) - { - if (a < b) - return a; - return b; - } - - public void loadXML(File currentFile) - { - - System.out.println("Loading document"); - - // LOAD DOCUMENT - - mouseARecord.clear(); - mouseBRecord.clear(); - - File XMLFile = currentFile; - if (!XMLFile.exists()) - return; - - Document XMLDocument = XMLUtil.loadDocument(XMLFile); - - XPath xpath = XPathFactory.newInstance().newXPath(); - - // VIDEO FILE NAME LOAD - - { - String expression = "//FILENAME"; - NodeList nodes; - try - { - nodes = (NodeList) xpath.evaluate(expression, XMLDocument, XPathConstants.NODESET); - - // System.out.println( "node size : " + nodes.getLength() ); - - Element fileNode = (Element) nodes.item(0); - System.out.println("Video file is :" + fileNode.getTextContent()); - videoFile = new File(fileNode.getTextContent()); - - } - catch (XPathExpressionException e) - { - - e.printStackTrace(); - } - } - - // MOUSE A LOAD - - // float startFrame = Float.parseFloat( loadFrameStartTextField.getText() ); - // float endFrame = Float.parseFloat( loadFrameEndTextField.getText() ); - - float startFrame = 0; - float endFrame = Float.MAX_VALUE; - - { - - String expression = "//MOUSEA/DET"; - NodeList nodes; - try - { - nodes = (NodeList) xpath.evaluate(expression, XMLDocument, XPathConstants.NODESET); - - // System.out.println( "mouse A node size : " + nodes.getLength() ); - - for (int i = 0; i < nodes.getLength(); i++) - { - Element detNode = (Element) nodes.item(i); - - MouseInfoRecord mouseInfoRecord = new MouseInfoRecord(); - mouseInfoRecord.bodyPosition = new Point2D.Float( - Float.parseFloat(detNode.getAttribute("bodyx")), - Float.parseFloat(detNode.getAttribute("bodyy"))); - mouseInfoRecord.headPosition = new Point2D.Float( - Float.parseFloat(detNode.getAttribute("headx")), - Float.parseFloat(detNode.getAttribute("heady"))); - mouseInfoRecord.tailPosition = new Point2D.Float( - Float.parseFloat(detNode.getAttribute("tailx")), - Float.parseFloat(detNode.getAttribute("taily"))); - - int currentT = Integer.parseInt(detNode.getAttribute("t")); - if (currentT >= startFrame && currentT <= endFrame) - { - // System.out.println("Mouse A adding record at t " + currentT ); - mouseARecord.put(currentT, mouseInfoRecord); - } - - } - - } - catch (XPathExpressionException e) - { - - e.printStackTrace(); - } - } - - // MOUSE B LOAD - - { - String expression = "//MOUSEB/DET"; - NodeList nodes; - try - { - nodes = (NodeList) xpath.evaluate(expression, XMLDocument, XPathConstants.NODESET); - - // System.out.println( "mouse B node size : " + nodes.getLength() ); - - for (int i = 0; i < nodes.getLength(); i++) - { - Element detNode = (Element) nodes.item(i); - - MouseInfoRecord mouseInfoRecord = new MouseInfoRecord(); - mouseInfoRecord.bodyPosition = new Point2D.Float( - Float.parseFloat(detNode.getAttribute("bodyx")), - Float.parseFloat(detNode.getAttribute("bodyy"))); - mouseInfoRecord.headPosition = new Point2D.Float( - Float.parseFloat(detNode.getAttribute("headx")), - Float.parseFloat(detNode.getAttribute("heady"))); - mouseInfoRecord.tailPosition = new Point2D.Float( - Float.parseFloat(detNode.getAttribute("tailx")), - Float.parseFloat(detNode.getAttribute("taily"))); - - int currentT = Integer.parseInt(detNode.getAttribute("t")); - if (currentT >= startFrame && currentT <= endFrame) - { - - // System.out.println("Mouse B adding record at t " + currentT ); - - mouseBRecord.put(currentT, mouseInfoRecord); - } - - } - - } - catch (XPathExpressionException e) - { - - e.printStackTrace(); - } - } - - startOffset = trimAnalysisRecord(); - - } - - /** Time in frame before the first analysis. Used to offset the video sequence. **/ - int startOffset = 0; - - double only2digit(double val) - { - val *= 100; - val = Math.floor(val); - val /= 100f; - return val; - } - - void computeVisionGraph(VisionGraph visionGraph) - { - // -------------------------------- - // A regarde l'autre souris ( non event / graph de vue ) - { - - float nbVal = 0; - float totalDistance = 0; - float nbEvent = 0; - float total = 0; - - int tabAngle[] = new int[361]; - int graphNumber = 0; - - int binSize = 5; - - EventCriteria currentCriteria = null; - - int tMin = Integer.MAX_VALUE; - int tMax = 0; - { - Iterator<Integer> integerIterator = mouseARecord.keySet().iterator(); - while (integerIterator.hasNext()) - { - int val = integerIterator.next(); - if (val > tMax) - tMax = val; - if (val < tMin) - tMin = val; - } - } - - for (int t = 0; t < tMax; t++) - { - if (mouseARecord.containsKey(t)) - if (mouseBRecord.containsKey(t)) - { - MouseInfoRecord mouseA = mouseARecord.get(t); - MouseInfoRecord mouseB = mouseBRecord.get(t); - - double distanceHeadABodyB = mouseA.headPosition.distanceSq(mouseB.bodyPosition); - double distanceHeadAHeadB = mouseA.headPosition.distanceSq(mouseB.headPosition); - double distanceBodyABodyB = mouseA.bodyPosition.distanceSq(mouseB.bodyPosition); - double distanceBodyAHeadB = mouseA.bodyPosition.distanceSq(mouseB.headPosition); - - double VAx = mouseA.headPosition.getX() - mouseA.bodyPosition.getX(); - double VAy = mouseA.headPosition.getY() - mouseA.bodyPosition.getY(); - double angleA = Math.atan2(VAy, VAx); - - // teste A dans la vue. - - double VABx = -mouseA.headPosition.getX() + mouseB.headPosition.getX(); - double VABy = -mouseA.headPosition.getY() + mouseB.headPosition.getY(); - double angleBA = Math.atan2(VABy, VABx); // + Math.PI; - - boolean eventIsOk = true; - - if (angleMin(angleBA, angleA) < demiVisionDeSouris) - { - - } - else - { - eventIsOk = false; - } - - if (visionGraph == VisionGraph.AT_FOLLOW_STATE) - { - // CRITERE EN POURSUITE - if ( - - (mouseA.distanceIsInferiorToThreshold2) || (!mouseA.isGettingToOtherAndTouch)) - { - eventIsOk = false; - } - } - - if (visionGraph == VisionGraph.AT_STOP_STATE) - { - if ( - // CRITERE EN OBSERVATION A L ARRET - - (mouseA.distanceIsInferiorToThreshold1) || (mouseA.speed > SPEED_THRESHOLD_1)) - - { - eventIsOk = false; - } - } - - if (eventIsOk) - { - - double angleSouris = angleA; - double angleVision = angleBA; - - angleVision = angleVision - angleSouris; - - int angleVisionDeg = (int) (180d * angleVision / Math.PI); - - while (angleVisionDeg > 180) - angleVisionDeg -= 360; - while (angleVisionDeg < -180) - angleVisionDeg += 360; - - int angleToFill = binSize * ((int) angleVisionDeg / binSize); - - tabAngle[180 + angleToFill]++; - - } - - } - } - - // Graph de placement de I dans la vue de R. - { - - XlsManager xls = null; - File xlsFile = new File(System.getProperty("user.home") + "\\" + visionGraph.toString() + " " - + animal.animalName + ".xls"); - try - { - xls = new XlsManager(xlsFile); - } - catch (IOException e) - { - - e.printStackTrace(); - } - - xls.createNewPage("result"); - - // Generation du graph de vue de la residente. - - JFreeChart chart; - XYSeriesCollection xyDataset = new XYSeriesCollection(); - YIntervalSeriesCollection yintervalseriescollection = new YIntervalSeriesCollection(); - IcyFrame graphFrame = new IcyFrame("graph " + graphNumber + " " + animal.animalName, true, true, - true, true); - graphNumber++; - - chart = ChartFactory.createXYLineChart("", "angle", "y", xyDataset, PlotOrientation.VERTICAL, true, - false, false); - - XYSeries seriesXY = new XYSeries("Sight " + animal.animalName); - xyDataset.addSeries(seriesXY); - - int cursorX = 0; - - for (int i = 0; i < 360; i += binSize) - { - seriesXY.add(i - 180, tabAngle[i]); - xls.setNumber(cursorX, 0, tabAngle[i]); - cursorX++; - } - - new AnnounceFrame("Exported in file " + xlsFile); - xls.SaveAndClose(); - - graphFrame.getContentPane().add( - new ChartPanel(chart, 500, 200, 500, 200, 500, 500, false, false, true, true, true, true)); - graphFrame.setVisible(true); - graphFrame.pack(); - graphFrame.addToMainDesktopPane(); - graphFrame.center(); - - } - - } - } - - @Override - public void actionPerformed(ActionEvent e) - { - - if (e.getSource() == computeVisionInFollowButton) - { - computeVisionGraph(VisionGraph.AT_FOLLOW_STATE); - } - if (e.getSource() == computeVisionWhenStoppedButton) - { - computeVisionGraph(VisionGraph.AT_STOP_STATE); - } - - if (e.getSource() == exportSpeedButton) - { - // export speed computation - - File xlsFile = new File(file.getAbsolutePath() + ".speed.xls"); - - try - { - XlsManager xls = new XlsManager(xlsFile); - // xls.createNewPage("Results"); - - exportSpeed(xls, mouseARecord, "Mouse A"); - exportSpeed(xls, mouseBRecord, "Mouse B"); - - xls.SaveAndClose(); - - } - catch (IOException e1) - { - e1.printStackTrace(); - } - - new AnnounceFrame("Speed data have been exported to " + xlsFile.getAbsolutePath(), 5); - - } - - if (e.getSource() == computeLocationHeatMapButton) - { - computeLocationHeatMap(); - // computeEventLocationHeatMap(); - } - - if (e.getSource() == computeUSVStat) - { - // computeVocStats(); - computeUSVStats(); - } - - if (e.getSource() == exportEventsAsXML) - { - exportEventsAsXML(); - } - - if (e.getSource() == saveImageButton) - { - // save a full strip of the image - try - { - ImageIO.write(imageChrono, "png", new File(file.getAbsolutePath() + ".1.png")); - } - catch (IOException e1) - { - e1.printStackTrace(); - } - - // save criteria by criteria - - int numeroCriteria = 0; - for (int y = 0; y < imageChrono.getHeight(); y += stepY) - { - - BufferedImage image2 = new BufferedImage(imageChrono.getWidth(), stepY, BufferedImage.TYPE_INT_BGR); - - Graphics2D targetG = (Graphics2D) image2.getGraphics(); - - targetG.drawImage(imageChrono, null, 0, -y); - - try - { - ImageIO.write(image2, "png", - new File(file.getAbsolutePath() + ".criteria_" + numeroCriteria + ".png")); - } - catch (IOException e1) - { - e1.printStackTrace(); - } - numeroCriteria++; - - } - - // save the strip with multiple lines. - - float desiredWidth = 1600 * 2; - - BufferedImage image2 = new BufferedImage((int) desiredWidth, - (int) (imageChrono.getHeight() * imageChrono.getWidth() / desiredWidth), - BufferedImage.TYPE_INT_BGR); - - Graphics2D sourceG = (Graphics2D) imageChrono.getGraphics(); - Graphics2D targetG = (Graphics2D) image2.getGraphics(); - - int stepY = 0; - for (int offset = 0; offset < imageChrono.getWidth(); offset += desiredWidth) - { - targetG.drawImage(imageChrono, null, -offset, stepY * imageChrono.getHeight()); - stepY++; - } - - try - { - ImageIO.write(image2, "png", new File(file.getAbsolutePath() + ".2.png")); - } - catch (IOException e1) - { - e1.printStackTrace(); - } - - } - - } - - private void exportEventsAsXML() - { - - Document document = XMLUtil.createDocument(true); - - for (EventTimeLine eventTimeLine : animal.eventTimeLineList) - { - Element elementTimeLine = document.createElement("EventTimeLine"); - document.getDocumentElement().appendChild(elementTimeLine); - XMLUtil.setAttributeIntValue(elementTimeLine, "index", animal.eventTimeLineList.indexOf(eventTimeLine)); - XMLUtil.setAttributeValue(elementTimeLine, "name", eventTimeLine.criteriaName); - XMLUtil.setAttributeValue(elementTimeLine, "type", eventTimeLine.eventType.toString()); - XMLUtil.setAttributeValue(elementTimeLine, "timeLineCategory", - eventTimeLine.timeLineCategory.toString()); - - for (EventCriteria event : eventTimeLine.eventList) - { - Element elementEvent = document.createElement("event"); - elementTimeLine.appendChild(elementEvent); - XMLUtil.setAttributeIntValue(elementEvent, "startFrame", event.startFrame); - XMLUtil.setAttributeIntValue(elementEvent, "endFrame", event.endFrame); - } - } - - File xmlFile = new File(file.getAbsolutePath() + ".allEventsExported.xml"); - XMLUtil.saveDocument(document, xmlFile); - AnnounceFrame f = new AnnounceFrame("File exported: " + xmlFile.getAbsolutePath()); - } - - private void computeUSVStats() - { - - // designed for USVs - // given an event, let's say an USV event, this code provide the following ratio: - // The number of USV event that are correlated with the events of a specific timeEvent. - // 100% means all the USV event are overlapping with the candidate event. - // 50% means half the USV event are ... - - WritableWorkbook workbook; - - try - { - - workbook = XLSUtil.createWorkbook(new File(file.getAbsolutePath() + ".event.xls")); - WritableSheet page = XLSUtil.createNewPage(workbook, "result"); - - int currentColumn = 1; - for (int indexOfUSVEvent = 29; indexOfUSVEvent < animal.eventTimeLineList.size(); indexOfUSVEvent++) - { - - EventTimeLine eventTimeLineWatched = animal.eventTimeLineList.get(indexOfUSVEvent); - - XLSUtil.setCellString(page, 0, 0, file.getAbsolutePath()); - // XLSUtil.setCellString( page, 0, 1, "event watched: " + eventTimeLineWatched.criteriaName ); - // XLSUtil.setCellString( page, 0, 2, "nb event(s): " + eventTimeLineWatched.eventList.size() ); - - int row = 5; - - XLSUtil.setCellString(page, 0, row, "event"); - XLSUtil.setCellString(page, currentColumn, row - 2, "Event: " + eventTimeLineWatched.criteriaName); - XLSUtil.setCellString(page, currentColumn, row - 1, - "Nb event: " + eventTimeLineWatched.eventList.size()); - - XLSUtil.setCellString(page, currentColumn, row, "nb corr event "); - XLSUtil.setCellString(page, currentColumn + 1, row, "% corr event"); - // 1 - // 1 - // 2 - row += 2; - - for (EventTimeLine eventTimeLineCandidate : animal.eventTimeLineList) - { - XLSUtil.setCellString(page, 0, row, eventTimeLineCandidate.criteriaName); - - int nbEventCandidate = eventTimeLineCandidate.eventList.size(); - // XLSUtil.setCellNumber( page, currentColumn, row, nbEventCandidate ); - - int nbOccur = 0; - - // check how many time the eventUSV occurs at the same time as the candidateEvent - for (EventCriteria eventUSV : eventTimeLineWatched.eventList) - { - - for (EventCriteria eventCandidate : eventTimeLineCandidate.eventList) - { - if (isEventOverlapping(eventUSV, eventCandidate)) - { - nbOccur++; - break; - } - - } - - } - - float ratio = 100f * (float) nbOccur / (float) eventTimeLineWatched.eventList.size(); - XLSUtil.setCellNumber(page, currentColumn, row, nbOccur); - XLSUtil.setCellNumber(page, currentColumn + 1, row, ratio); - - row++; - } - currentColumn += 2; - } - - XLSUtil.saveAndClose(workbook); - - } - catch (IOException e) - { - e.printStackTrace(); - } - catch (WriteException e) - { - e.printStackTrace(); - } - - } - - /** - * check if a is overlapping b. - */ - private boolean isEventOverlapping(EventCriteria a, EventCriteria b) - { - - if (b.startFrame <= a.endFrame && b.endFrame >= a.startFrame) - { - return true; - } - - return false; - } - - /** - * @deprecated - * @param vocEventIndex - * @param candidateEventIndex - * @param sheet - */ - private void feedXLSWithIntersectingEvent(int vocEventIndex, int candidateEventIndex, WritableSheet sheet) - { - - /** Number of vocalization intersecting/overlapping with a contact */ - - EventTimeLine vocTimeLine = animal.eventTimeLineList.get(vocEventIndex); - EventTimeLine candidateTimeLine = animal.eventTimeLineList.get(candidateEventIndex); - - int totalNbVoc = vocTimeLine.eventList.size(); - - int nbVocWithEvent = getNumberOfEventOverlap(vocTimeLine, candidateTimeLine); - - int row = sheet.getRows(); - - XLSUtil.setCellString(sheet, 0, row, "nb Voc with event :" + candidateTimeLine.criteriaName); - XLSUtil.setCellNumber(sheet, 1, row, nbVocWithEvent); - XLSUtil.setCellString(sheet, 2, row, "percent:"); - XLSUtil.setCellNumber(sheet, 3, row++, nbVocWithEvent * 100f / totalNbVoc); - - } - - /** - * @deprected - * provides the number of event vocTimeLine overlapping with the candidate time line - */ - private int getNumberOfEventOverlap(EventTimeLine vocTimeLine, EventTimeLine candidateTimeLine) - { - - int nbEvent = 0; - - System.out.println("nb of event of type ** " + vocTimeLine.criteriaName + " ** matching ** " - + candidateTimeLine.criteriaName + " **"); - - for (EventCriteria vocEvent : vocTimeLine.eventList) - { - for (EventCriteria candidateEvent : animal.eventTimeLineList.get(1).eventList) - { - if (isEventOverlapping(vocEvent, candidateEvent)) - { - nbEvent++; - break; - } - } - - } - - return nbEvent; - } - - private void computeEventLocationHeatMap() - { - // red channel : contact events - // green channel : usv events - - // check if event is found - - // System.out.println( animal.eventTimeLineList.get( 29 ).criteriaName ); - - // create image - - // should parse the all data to find min/max or check video input size. - - SCALE = Float.parseFloat(scaleTextField.getText()); - - IcyBufferedImage image = new IcyBufferedImage(800, 600, 3, DataType.USHORT); - - // check < threshold 1 events - for (EventCriteria event : animal.eventTimeLineList.get(0).eventList) - { - for (int t = event.startFrame; t <= event.endFrame; t++) - { - MouseInfoRecord mouseA = mouseARecord.get(t); - additiveDrawMouse(mouseA, image, 0); - - MouseInfoRecord mouseB = mouseBRecord.get(t); - additiveDrawMouse(mouseB, image, 0); - } - } - - // check USV - for (EventCriteria event : animal.eventTimeLineList.get(29).eventList) - { - for (int t = event.startFrame; t <= event.endFrame; t++) - { - MouseInfoRecord mouseA = mouseARecord.get(t); - additiveDrawMouse(mouseA, image, 1); - - MouseInfoRecord mouseB = mouseBRecord.get(t); - additiveDrawMouse(mouseB, image, 1); - } - } - - image.dataChanged(); - - // display image - - Sequence outPutSequence = new Sequence(image); - // Icy.getMainInterface().addSequence( outPutSequence ); - - // save Image - - File heatMapFile = new File(FileUtil.setExtension(file.getAbsolutePath(), ".heatmap.event.tif")); - Saver.save(outPutSequence, heatMapFile); - new AnnounceFrame("HeatMapFile saved to " + heatMapFile.getAbsolutePath(), 5); - - } - - private void computeLocationHeatMap() - { - - // create image - - // should parse the all data to find min/max or check video input size. - - SCALE = Float.parseFloat(scaleTextField.getText()); - - IcyBufferedImage image = new IcyBufferedImage(800, 600, 4, DataType.USHORT); - - // render mice - - // mouse A - for (Integer t : mouseARecord.keySet()) - { - MouseInfoRecord mouseA = mouseARecord.get(t); - additiveDrawMouse(mouseA, image, 0); - } - - // mouse B - for (Integer t : mouseBRecord.keySet()) - { - MouseInfoRecord mouseB = mouseBRecord.get(t); - additiveDrawMouse(mouseB, image, 1); - } - - // voc event on blue channel. (test purposes) - for (Integer t : mouseBRecord.keySet()) - { - MouseInfoRecord mouseB = mouseBRecord.get(t); - MouseInfoRecord mouseA = mouseARecord.get(t); - - EventTimeLine eventTimeLineWatched = animal.eventTimeLineList.get(29); - if (eventTimeLineWatched.getNbEvent(t, t) == 1) - { - additiveDrawMouse(mouseA, image, 2); - additiveDrawMouse(mouseB, image, 3); - } - } - - image.dataChanged(); - - // display image - - Sequence outPutSequence = new Sequence(image); - // Icy.getMainInterface().addSequence( outPutSequence ); - - // save Image - - File heatMapFile = new File(FileUtil.setExtension(file.getAbsolutePath(), ".heatmap.tif")); - Saver.save(outPutSequence, heatMapFile); - new AnnounceFrame("HeatMapFile saved to " + heatMapFile.getAbsolutePath(), 5); - - } - - private void additiveDrawMouse(MouseInfoRecord mouse, IcyBufferedImage image, int channel) - { - - Ellipse2D head = new Ellipse2D.Float((float) mouse.headPosition.getX() - (40f * SCALE) / 2f, - (float) mouse.headPosition.getY() - (40f * SCALE) / 2f, 40 * SCALE, 40 * SCALE); // 9 - Ellipse2D body = new Ellipse2D.Float((float) mouse.bodyPosition.getX() - (77f * SCALE) / 2f, - (float) mouse.bodyPosition.getY() - (77f * SCALE) / 2f, 77 * SCALE, 77 * SCALE); // 17 - Ellipse2D tail = new Ellipse2D.Float((float) mouse.tailPosition.getX() - (13f * SCALE) / 2f, - (float) mouse.tailPosition.getY() - (13f * SCALE) / 2f, 13 * SCALE, 13 * SCALE); // 3 - - int centerX = 0; - int centerY = 0; - int ray = 30; - additiveDrawOverImage(image, (int) head.getCenterX(), (int) head.getCenterY(), (int) ((40f * SCALE) / 2f), - channel); - additiveDrawOverImage(image, (int) body.getCenterX(), (int) body.getCenterY(), (int) ((77f * SCALE) / 2f), - channel); - additiveDrawOverImage(image, (int) tail.getCenterX(), (int) tail.getCenterY(), (int) ((13f * SCALE) / 2f), - channel); - - } - - private void additiveDrawOverImage(IcyBufferedImage image, int ox, int oy, int r, int channel) - { - - short[] buffer = image.getDataXYAsShort(channel); - int width = image.getWidth(); - - for (int x = -r; x < r; x++) - { - int height = (int) Math.sqrt(r * r - x * x); - - for (int y = -height; y < height; y++) - { - // bmp.SetPixel(x + ox, y + oy, Color.Red); - buffer[(oy + y) * width + x + ox]++; - } - } - - } - - private void exportSpeed(XlsManager xls, HashMap<Integer, MouseInfoRecord> mouseRecord, String name) - { - - xls.createNewPage(name); - - int tMin = 0; - - START_MINUTE = Integer.parseInt(computeImageStartMinuteTextField.getText()); - NB_MINUTE = Integer.parseInt(computeImageNbMinuteTextField.getText()); - firstFrame = (int) (tMin + START_MINUTE * 60 * FPS); - lastFrame = (int) (firstFrame + NB_MINUTE * 60 * FPS); - - int tMax = lastFrame; - /** frameWindow est utilisé pour lisser le calcul de deplacement entre deux points de temps. t-framewindow et t+frameWindow */ - int frameWindow = 6; // 5 - - double speedFrame[] = new double[tMax - firstFrame]; // speed computed at each frame - - xls.setLabel(0, 0, "frame#"); - xls.setLabel(1, 0, "speed in px/frame time"); - xls.setLabel(2, 0, "cumulated distance in px"); - - { - float nbVal = 0; - double totalDistance = 0; - for (int t = 0; t < tMax; t++) - { - if (mouseRecord.containsKey(t - frameWindow)) - if (mouseRecord.containsKey(t + frameWindow)) - if (mouseRecord.containsKey(t)) - { - MouseInfoRecord mouseRecordPrev = mouseRecord.get(t - frameWindow); - MouseInfoRecord mouseRecordNext = mouseRecord.get(t + frameWindow); - MouseInfoRecord mouseRecordCurrentFrame = mouseRecord.get(t); - - float distance = (float) mouseRecordPrev.bodyPosition - .distance(mouseRecordNext.bodyPosition); - distance /= (float) (frameWindow * 2 + 1); // pour obtenir une vitesse par frame. - - totalDistance += distance; - - mouseRecordCurrentFrame.speed = distance; - - speedFrame[t - firstFrame] = distance; - xls.setNumber(0, (int) (nbVal + 1), nbVal); - xls.setNumber(1, (int) (nbVal + 1), distance); - xls.setNumber(2, (int) (nbVal + 1), totalDistance); - - nbVal++; - } - } - - } - - xls.setLabel(4, 0, "second#"); - xls.setLabel(5, 0, "speed in px/s"); - xls.setLabel(6, 0, "cumulated distance in px"); - - // System.out.println("tMax : " + tMax ); - { - int sec = 0; - int arrayCounter = 0; - double totalDistance = 0; - while (arrayCounter < tMax - FPS) - { - - double speedSec = 0; - - for (int i = 0; i < FPS; i++) - { - speedSec += speedFrame[arrayCounter]; - totalDistance += speedFrame[arrayCounter]; - arrayCounter++; - } - - // speedSec; - - System.out.println("sec:" + sec); - - xls.setNumber(4, sec + 1, sec); - xls.setNumber(5, sec + 1, speedSec); - xls.setNumber(6, sec + 1, totalDistance); - - sec++; - } - - } - } - - @Override - public void mouseClicked(MouseEvent e) - { - try - { - updateVideoImageAt(e.getX()); - } - catch (InterruptedException ex) - { - // ignore - } - } - - @Override - public void mouseEntered(MouseEvent e) - { - } - - @Override - public void mouseExited(MouseEvent e) - { - } - - @Override - public void mousePressed(MouseEvent e) - { - } - - @Override - public void mouseReleased(MouseEvent e) - { - } - - @Override - public void mouseDragged(MouseEvent e) - { - try - { - updateVideoImageAt(e.getX()); - } - catch (InterruptedException ex) - { - // ignore - ex.printStackTrace(); - } - } - - private void updateVideoImageAt(int x) throws InterruptedException - { - - x = x + firstFrame; - // x = x+ startOffset; - - if (frameAccess == null) - { - // check if file exists. - if (videoFile.exists()) - { - frameAccess = new FrameAccess(videoFile); - } - else - { - System.out.println("File specified in XML is not present. Checking in XML folder."); - videoFile = new File(FileUtil.getDirectory(file.getAbsolutePath()) + FileUtil.separator - + FileUtil.getFileName(videoFile.getName())); - frameAccess = new FrameAccess(videoFile); - } - - } - - videoImage = frameAccess.getImageAt(x + startOffset + 3); - - if (videoImage == null) - { - videoImage = IcyBufferedImageUtil.toBufferedImage(new IcyBufferedImage(640, 480, 1, DataType.BYTE), - null); - - } - - // draw over. - - Graphics2D g2 = (Graphics2D) videoImage.getGraphics(); - - // Mouse A - { - g2.setColor(Color.red); - MouseInfoRecord mouseA = mouseARecord.get(x); - MouseInfoRecord mouseB = mouseBRecord.get(x); - if (mouseA != null) - { - SCALE = Float.parseFloat(scaleTextField.getText()); - // Ellipse2D head = new Ellipse2D.Float( (float)mouseA.headPosition.getX()-4f , (float)mouseA.headPosition.getY() - (40f*SCALE)/2f , - // 40*SCALE , 40*SCALE ); //9 - // Ellipse2D body = new Ellipse2D.Float( (float)mouseA.bodyPosition.getX()-8f , (float)mouseA.bodyPosition.getY() - (77f*SCALE)/2f , - // 77*SCALE , 77*SCALE ); // 17 - // Ellipse2D tail = new Ellipse2D.Float( (float)mouseA.tailPosition.getX()-1f , (float)mouseA.tailPosition.getY() - (13f*SCALE)/2f , - // 13*SCALE , 13*SCALE ); // 3 - // System.out.println(SCALE); - Ellipse2D head = new Ellipse2D.Float((float) mouseA.headPosition.getX() - (40f * SCALE) / 2f, - (float) mouseA.headPosition.getY() - (40f * SCALE) / 2f, 40 * SCALE, 40 * SCALE); // 9 - Ellipse2D body = new Ellipse2D.Float((float) mouseA.bodyPosition.getX() - (77f * SCALE) / 2f, - (float) mouseA.bodyPosition.getY() - (77f * SCALE) / 2f, 77 * SCALE, 77 * SCALE); // 17 - Ellipse2D tail = new Ellipse2D.Float((float) mouseA.tailPosition.getX() - (13f * SCALE) / 2f, - (float) mouseA.tailPosition.getY() - (13f * SCALE) / 2f, 13 * SCALE, 13 * SCALE); // 3 - - g2.draw(head); - g2.draw(body); - g2.draw(tail); - - // draw eye view - - double VAx = mouseA.headPosition.getX() - mouseA.bodyPosition.getX(); - double VAy = mouseA.headPosition.getY() - mouseA.bodyPosition.getY(); - double angleA = Math.atan2(VAy, VAx); - - double departAngle1 = -8d * Math.PI / 9d; - double departAngle2 = 3d * Math.PI / 9d; - - // centre - g2.drawLine((int) mouseA.headPosition.getX(), (int) mouseA.headPosition.getY(), - (int) (mouseA.headPosition.getX() + Math.cos(angleA) * 100d), - (int) (mouseA.headPosition.getY() + Math.sin(angleA) * 100d)); - - // gauche - g2.drawLine((int) mouseA.headPosition.getX(), (int) mouseA.headPosition.getY(), - (int) (mouseA.headPosition.getX() + Math.cos(angleA - 1 * Math.PI / 3d) * 50d), - (int) (mouseA.headPosition.getY() + Math.sin(angleA - 1 * Math.PI / 3d) * 50d)); - - // gauche full - g2.drawLine((int) mouseA.headPosition.getX(), (int) mouseA.headPosition.getY(), - (int) (mouseA.headPosition.getX() + Math.cos(angleA - 1 * 2 * Math.PI / 3d) * 100d), - (int) (mouseA.headPosition.getY() + Math.sin(angleA - 1 * 2 * Math.PI / 3d) * 100d)); - - // droit - g2.drawLine((int) mouseA.headPosition.getX(), (int) mouseA.headPosition.getY(), - (int) (mouseA.headPosition.getX() + Math.cos(angleA + 1 * Math.PI / 3d) * 50d), - (int) (mouseA.headPosition.getY() + Math.sin(angleA + 1 * Math.PI / 3d) * 50d)); - - // droit full - g2.drawLine((int) mouseA.headPosition.getX(), (int) mouseA.headPosition.getY(), - (int) (mouseA.headPosition.getX() + Math.cos(angleA + 1 * 2 * Math.PI / 3d) * 100d), - (int) (mouseA.headPosition.getY() + Math.sin(angleA + 1 * 2 * Math.PI / 3d) * 100d)); - - // ------------------------ MOUSE A REGARDE B - - // teste A dans la vue. - - double VABx = -mouseA.headPosition.getX() + mouseB.headPosition.getX(); - double VABy = -mouseA.headPosition.getY() + mouseB.headPosition.getY(); - double angleBA = Math.atan2(VABy, VABx); // + Math.PI; - - boolean eventIsOk = true; - - if (angleMin(angleBA, angleA) < demiVisionDeSouris) - { - - } - else - { - eventIsOk = false; - } - - if (mouseA.distanceIsInferiorToThreshold2) - { - eventIsOk = false; - } - - g2.setColor(Color.black); - g2.drawLine((int) mouseA.headPosition.getX(), (int) mouseA.headPosition.getY(), - (int) (mouseA.headPosition.getX() + Math.cos(angleBA) * 100d), - (int) (mouseA.headPosition.getY() + Math.sin(angleBA) * 100d)); - - double angleDif = angleBA - angleA; - - int angleDifDegree = (int) (180d * angleDif / Math.PI); - - while (angleDifDegree > 180) - angleDifDegree -= 360; - while (angleDifDegree < -180) - angleDifDegree += 360; - - } - } - // MOUSE B - { - g2.setColor(Color.green); - MouseInfoRecord mouseB = mouseBRecord.get(x); - if (mouseB != null) - { - // Ellipse2D head = new Ellipse2D.Float( (float)mouseB.headPosition.getX()-4f , (float)mouseB.headPosition.getY() - 4f , 9 , 9 ); - // Ellipse2D body = new Ellipse2D.Float( (float)mouseB.bodyPosition.getX()-8f , (float)mouseB.bodyPosition.getY() - 8f , 17 , 17 ); - // Ellipse2D tail = new Ellipse2D.Float( (float)mouseB.tailPosition.getX()-1f , (float)mouseB.tailPosition.getY() - 1f , 3 , 3 ); - - Ellipse2D head = new Ellipse2D.Float((float) mouseB.headPosition.getX() - (40f * SCALE) / 2f, - (float) mouseB.headPosition.getY() - (40f * SCALE) / 2f, 40 * SCALE, 40 * SCALE); // 9 - Ellipse2D body = new Ellipse2D.Float((float) mouseB.bodyPosition.getX() - (77f * SCALE) / 2f, - (float) mouseB.bodyPosition.getY() - (77f * SCALE) / 2f, 77 * SCALE, 77 * SCALE); // 17 - Ellipse2D tail = new Ellipse2D.Float((float) mouseB.tailPosition.getX() - (13f * SCALE) / 2f, - (float) mouseB.tailPosition.getY() - (13f * SCALE) / 2f, 13 * SCALE, 13 * SCALE); // 3 - - g2.draw(head); - g2.draw(body); - g2.draw(tail); - - // draw eye view - - double VAx = mouseB.headPosition.getX() - mouseB.bodyPosition.getX(); - double VAy = mouseB.headPosition.getY() - mouseB.bodyPosition.getY(); - double angleA = Math.atan2(VAy, VAx); - - double departAngle1 = -8d * Math.PI / 9d; - double departAngle2 = 3d * Math.PI / 9d; - - // centre - g2.drawLine((int) mouseB.headPosition.getX(), (int) mouseB.headPosition.getY(), - (int) (mouseB.headPosition.getX() + Math.cos(angleA) * 100d), - (int) (mouseB.headPosition.getY() + Math.sin(angleA) * 100d)); - - // gauche - g2.drawLine((int) mouseB.headPosition.getX(), (int) mouseB.headPosition.getY(), - (int) (mouseB.headPosition.getX() + Math.cos(angleA - 1 * Math.PI / 3d) * 50d), - (int) (mouseB.headPosition.getY() + Math.sin(angleA - 1 * Math.PI / 3d) * 50d)); - - // gauche full - g2.drawLine((int) mouseB.headPosition.getX(), (int) mouseB.headPosition.getY(), - (int) (mouseB.headPosition.getX() + Math.cos(angleA - 2 * Math.PI / 3d) * 100d), - (int) (mouseB.headPosition.getY() + Math.sin(angleA - 2 * Math.PI / 3d) * 100d)); - - // droit - g2.drawLine((int) mouseB.headPosition.getX(), (int) mouseB.headPosition.getY(), - (int) (mouseB.headPosition.getX() + Math.cos(angleA + 1 * Math.PI / 3d) * 50d), - (int) (mouseB.headPosition.getY() + Math.sin(angleA + 1 * Math.PI / 3d) * 50d)); - - // droit full - g2.drawLine((int) mouseB.headPosition.getX(), (int) mouseB.headPosition.getY(), - (int) (mouseB.headPosition.getX() + Math.cos(angleA + 1 * 2 * Math.PI / 3d) * 100d), - (int) (mouseB.headPosition.getY() + Math.sin(angleA + 1 * 2 * Math.PI / 3d) * 100d)); - - } - } - - videoTimeLabel.setText("frame #" + x + - - " " + (int) (x / (FPS * 60)) + ":" + decimalFormat.format((int) (x / FPS % 60))); - - imageVideoComponent.setImage(videoImage); - - // ComponentUtil.setFixedWidth( imageVideoComponent , 400 ); - - // getImage - - imageVideoComponent.updateUI(); - - } - - public double angleMin(double a1, double a2) - { - double angleMin = Double.MAX_VALUE; - - a1 = angleToZeroTwoPi(a1); - a2 = angleToZeroTwoPi(a2); - - for (int i = -2; i < 3; i++) - { - double dif = Math.abs(a1 + (i * Math.PI * 2d) - a2); - if (dif < angleMin) - angleMin = dif; - } - - return angleMin; - } - - public double angleToZeroTwoPi(double a) - { - - while (a < 0) - { - a += 2 * Math.PI; - } - while (a > 2 * Math.PI) - { - a -= 2 * Math.PI; - } - return a; - } - - @Override - public void mouseMoved(MouseEvent arg0) - { - - } - - } - - @Override - public void keyPressed(KeyEvent arg0) - { - // TODO Auto-generated method stub - - } - - @Override - public void keyReleased(KeyEvent e) - { - - if (e.getSource() == scaleTextField) - { - try - { - float scale = Float.parseFloat(scaleTextField.getText()); - float ratio = scale / 0.22f; - - distance1TextField.setText("" + ratio * 22); - distance2TextField.setText("" + ratio * 40); - distanceHeadHeadTextField.setText("" + ratio * 15); - distanceHeadGenitalTextField.setText("" + ratio * 15); - seuilSideTextField.setText("" + ratio * 12); - speed_threshold1TextField.setText("" + ratio * 0.5); - speed_threshold2TextField.setText("" + ratio * 2); - speed_threshold3TextField.setText("" + ratio * 4); - } - catch (NumberFormatException e1) - { - - } - } - - } - - @Override - public void keyTyped(KeyEvent e) + public MiceProfilerVideoLabelMaker() { + super(); + implementer = new MiceProfilerVideoLabelMakerInternal(); } @Override - public String getMainPluginClassName() + public void run() { - return MiceProfilerTracker.class.getName(); + implementer.run(); } -} +} \ No newline at end of file diff --git a/src/main/java/plugins/fab/MiceProfiler/MiceProfilerVideoLabelMakerInternal.java b/src/main/java/plugins/fab/MiceProfiler/MiceProfilerVideoLabelMakerInternal.java new file mode 100644 index 0000000000000000000000000000000000000000..e76bb03aa2526e5e1c4e7e0a5aede6f9d5e74a4c --- /dev/null +++ b/src/main/java/plugins/fab/MiceProfiler/MiceProfilerVideoLabelMakerInternal.java @@ -0,0 +1,5388 @@ +/* + * Copyright 2011, 2012 Institut Pasteur. + * + * This file is part of MiceProfiler. + * + * MiceProfiler is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * MiceProfiler is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with MiceProfiler. If not, see <http://www.gnu.org/licenses/>. + */ +package plugins.fab.MiceProfiler; + +import java.awt.BasicStroke; +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Font; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.KeyEvent; +import java.awt.event.KeyListener; +import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; +import java.awt.event.MouseMotionListener; +import java.awt.geom.Ellipse2D; +import java.awt.geom.Point2D; +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.lang.reflect.Field; +import java.text.DecimalFormat; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Scanner; +import java.util.prefs.Preferences; + +import javax.imageio.ImageIO; +import javax.swing.BoxLayout; +import javax.swing.ImageIcon; +import javax.swing.JButton; +import javax.swing.JCheckBox; +import javax.swing.JFileChooser; +import javax.swing.JLabel; +import javax.swing.JMenu; +import javax.swing.JMenuBar; +import javax.swing.JMenuItem; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.JTextField; +import javax.swing.SwingConstants; +import javax.xml.xpath.XPath; +import javax.xml.xpath.XPathConstants; +import javax.xml.xpath.XPathExpressionException; +import javax.xml.xpath.XPathFactory; + +import org.jfree.chart.ChartFactory; +import org.jfree.chart.ChartPanel; +import org.jfree.chart.JFreeChart; +import org.jfree.chart.plot.PlotOrientation; +import org.jfree.data.xy.XYSeries; +import org.jfree.data.xy.XYSeriesCollection; +import org.jfree.data.xy.YIntervalSeriesCollection; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.NodeList; + +import icy.file.FileUtil; +import icy.file.Loader; +import icy.file.Saver; +import icy.file.xls.XlsManager; +import icy.gui.dialog.MessageDialog; +import icy.gui.frame.IcyFrame; +import icy.gui.frame.progress.AnnounceFrame; +import icy.gui.frame.progress.ToolTipFrame; +import icy.gui.util.FontUtil; +import icy.gui.util.GuiUtil; +import icy.image.IcyBufferedImage; +import icy.image.IcyBufferedImageUtil; +import icy.main.Icy; +import icy.sequence.Sequence; +import icy.swimmingPool.SwimmingObject; +import icy.type.DataType; +import icy.util.XLSUtil; +import icy.util.XMLUtil; +import jxl.Sheet; +import jxl.Workbook; +import jxl.read.biff.BiffException; +import jxl.write.WritableSheet; +import jxl.write.WritableWorkbook; +import jxl.write.WriteException; + +public class MiceProfilerVideoLabelMakerInternal implements ActionListener, KeyListener +{ + JPanel mainPanel = new JPanel(); + IcyFrame mainFrame = new IcyFrame("Video Label Maker", true, true, true, true); + JMenuBar menuBar = new JMenuBar(); + JMenuItem openFileMenuItem = new JMenuItem("Open XML File..."); + JMenuItem compileImageFileMenuItem = new JMenuItem("Compile image files from a list of file..."); + JMenuItem mergeHeatMapMenuItem = new JMenuItem("Stitch heatmap files..."); + + JScrollPane scrollPane = new JScrollPane(mainPanel); + JPanel setupPanel = GuiUtil.generatePanel("Setup"); + JLabel legendLabel = new JLabel("Legend", JLabel.CENTER); + JTextField scaleTextField = new JTextField("0.22"); + JTextField scaleVideoTextField = new JTextField("1"); + + int START_MINUTE = 0; + int NB_MINUTE = 8; + + float SEUIL_DISTANCE_1 = 22; + float SEUIL_DISTANCE_2 = 40; + float SEUIL_DISTANCE_HEAD_HEAD = 15; + float SEUIL_DISTANCE_HEAD_GENITAL = 15; + float SEUIL_SIDE = 12; + float SPEED_THRESHOLD_1 = (float) 0.5f; + float SPEED_THRESHOLD_2 = 2; + float SPEED_THRESHOLD_3 = 4; + float FPS = 15f; + float LOAD_FRAME_START = 0f; + float LOAD_FRAME_END = 10000000f; + float SCALE = 0.22f; + + JTextField distance1TextField = new JTextField(); + JTextField distance2TextField = new JTextField(); + JTextField distanceHeadHeadTextField = new JTextField(); + JTextField distanceHeadGenitalTextField = new JTextField(); + JTextField seuilSideTextField = new JTextField(); + JTextField speed_threshold1TextField = new JTextField(); + JTextField speed_threshold2TextField = new JTextField(); + JTextField speed_threshold3TextField = new JTextField(); + JTextField fpsTextField = new JTextField(); + // JTextField loadFrameStartTextField = new JTextField(); + // JTextField loadFrameEndTextField = new JTextField(); + JTextField computeImageStartMinuteTextField = new JTextField(); + JTextField computeImageNbMinuteTextField = new JTextField(); + JButton refreshButton = new JButton("Refresh Data with new parameters"); + + BufferedImage videoImage = new BufferedImage(200, 200, BufferedImage.TYPE_INT_BGR); + ImageComponent imageVideoComponent = new ImageComponent(); + JLabel videoTimeLabel = new JLabel("", JLabel.CENTER); + int stepY = 15; + + public void run() + { + mainFrame.pack(); + + mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.Y_AXIS)); + + videoTimeLabel.setFont(new Font("Arial", Font.BOLD, 15)); + legendLabel.setFont(new Font("Arial", Font.BOLD, 20)); + + JMenu fileMenu = new JMenu("File"); + fileMenu.add(openFileMenuItem); + openFileMenuItem.addActionListener(this); + fileMenu.addSeparator(); + fileMenu.add(compileImageFileMenuItem); + compileImageFileMenuItem.addActionListener(this); + fileMenu.add(mergeHeatMapMenuItem); + mergeHeatMapMenuItem.addActionListener(this); + + menuBar.add(fileMenu); + + mainFrame.setJMenuBar(menuBar); + + JPanel sidePanel = new JPanel(); + sidePanel.setLayout(new BorderLayout()); + JPanel videoPanel = GuiUtil.generatePanel("video"); + imageVideoComponent.setImage(videoImage); + // ComponentUtil.setFixedWidth( imageVideoComponent , 400 ); + videoPanel.add(GuiUtil.besidesPanel(imageVideoComponent)); + videoPanel.add(GuiUtil.besidesPanel(videoTimeLabel)); + + sidePanel.add(setupPanel, BorderLayout.NORTH); + sidePanel.add(videoPanel, BorderLayout.CENTER); + + mainFrame.getContentPane().setLayout(new BorderLayout()); + mainFrame.getContentPane().add(sidePanel, BorderLayout.EAST); + mainFrame.getContentPane().add(legendLabel, BorderLayout.SOUTH); + + mainFrame.getContentPane().add(scrollPane, BorderLayout.CENTER); + scrollPane.setPreferredSize(new Dimension(800, 450)); + + distance1TextField.setText("" + SEUIL_DISTANCE_1); + distance2TextField.setText("" + SEUIL_DISTANCE_2); + distanceHeadHeadTextField.setText("" + SEUIL_DISTANCE_HEAD_HEAD); + distanceHeadGenitalTextField.setText("" + SEUIL_DISTANCE_HEAD_GENITAL); + seuilSideTextField.setText("" + SEUIL_SIDE); + speed_threshold1TextField.setText("" + SPEED_THRESHOLD_1); + speed_threshold2TextField.setText("" + SPEED_THRESHOLD_2); + speed_threshold3TextField.setText("" + SPEED_THRESHOLD_3); + fpsTextField.setText("" + FPS); + // loadFrameStartTextField.setText( ""+LOAD_FRAME_START ); + // loadFrameEndTextField.setText( ""+LOAD_FRAME_END ); + computeImageStartMinuteTextField.setText("" + START_MINUTE); + computeImageNbMinuteTextField.setText("" + NB_MINUTE); + + setupPanel.add(GuiUtil.besidesPanel(new JLabel("Distance Threshold 1(closest) in px:"), distance1TextField)); + setupPanel.add(GuiUtil.besidesPanel(new JLabel("Distance Threshold 2 in px:"), distance2TextField)); + setupPanel.add(GuiUtil.besidesPanel(new JLabel("Distance Head-Head in px:"), distanceHeadHeadTextField)); + setupPanel + .add(GuiUtil.besidesPanel(new JLabel("Distance Head-Genital 2 in px:"), distanceHeadGenitalTextField)); + setupPanel.add(GuiUtil.besidesPanel(new JLabel("Side detection Parameter in px:"), seuilSideTextField)); + setupPanel.add(GuiUtil.besidesPanel(new JLabel("Speed Threshold 1 (black) in px:"), speed_threshold1TextField)); + setupPanel.add(GuiUtil.besidesPanel(new JLabel("Speed Threshold 2 (gray) in px:"), speed_threshold2TextField)); + setupPanel.add( + GuiUtil.besidesPanel(new JLabel("Speed Threshold 3 (lightgray) in px:"), speed_threshold3TextField)); + setupPanel.add(GuiUtil.besidesPanel(new JLabel("FPS:"), fpsTextField)); + // setupPanel.add( GuiUtil.besidesPanel( new JLabel("Load frame start:" ) , loadFrameStartTextField) ); + // setupPanel.add( GuiUtil.besidesPanel( new JLabel("Load frame end:" ) , loadFrameEndTextField) ); + setupPanel.add(GuiUtil.besidesPanel(new JLabel("Computation Start Minute:"), computeImageStartMinuteTextField)); + setupPanel.add(GuiUtil.besidesPanel(new JLabel("Computation End Minute:"), computeImageNbMinuteTextField)); + setupPanel.add(GuiUtil.besidesPanel(new JLabel("Mouse Scale"), scaleTextField)); + setupPanel.add(GuiUtil.besidesPanel(new JLabel("Video Image display scale"), scaleVideoTextField)); + + setupPanel.add(GuiUtil.besidesPanel(refreshButton)); + refreshButton.addActionListener(this); + + scaleTextField.setFont(FontUtil.setStyle(scaleTextField.getFont(), Font.BOLD)); + + scaleTextField.addKeyListener(this); + + mainFrame.pack(); + mainFrame.center(); + mainFrame.addToMainDesktopPane(); + mainFrame.setVisible(true); + + } + + class MouseInfoRecord + { + boolean isGettingToOtherAndTouch = false; + boolean isEscapingFromOtherAndUnTouch = false; + boolean isEscaping = false; + boolean distanceIsInferiorToThreshold1 = false; + boolean isGoingToTheOther = false; + boolean mouseGetToOtherMouseAndEscapeInOut = false; + boolean mouseGetToOtherMouseAndOtherEscapeInOut = false; + boolean eventA = false; + boolean eventB = false; + boolean eventC = false; + boolean eventD = false; + float speed; + Point2D headPosition; + Point2D tailPosition; + Point2D bodyPosition; + public boolean distanceIsInferiorToThreshold2 = false; + public boolean isBehindTheOther = false; + public boolean isBesideTheOther = false; + public boolean thisHeadWithOtherGenitalContact = false; + } + + public void openFile() + { + // load last preferences for loader. + JFileChooser fileChooser = new JFileChooser(); + fileChooser.setMultiSelectionEnabled(true); + String node = "plugins/PhysicTracker/videolabelmaker/browser"; + + Preferences preferences = Preferences.userRoot().node(node); + String path = preferences.get("path", ""); + fileChooser.setCurrentDirectory(new File(path)); + + int x = preferences.getInt("x", 0); + int y = preferences.getInt("y", 0); + int width = preferences.getInt("width", 400); + int height = preferences.getInt("height", 400); + + fileChooser.setLocation(x, y); + fileChooser.setPreferredSize(new Dimension(width, height)); + + int returnValue = fileChooser.showDialog(null, "Load"); + if (returnValue == JFileChooser.APPROVE_OPTION) + { + preferences.put("path", fileChooser.getCurrentDirectory().getAbsolutePath()); + preferences.putInt("x", fileChooser.getX()); + preferences.putInt("y", fileChooser.getY()); + preferences.putInt("width", fileChooser.getWidth()); + preferences.putInt("height", fileChooser.getHeight()); + + for (int i = 0; i < fileChooser.getSelectedFiles().length; i++) + { + if (fileChooser.getSelectedFiles()[i].getName().contains("extra")) + { + System.out.println( + "You are trying to load an extra xml file. Please load the original file instead."); + continue; + } + + VideoLabelPanel videoLabelPanel = new VideoLabelPanel(fileChooser.getSelectedFiles()[i]); + mainPanel.add(videoLabelPanel.panel); + videoLabelPanelArrayList.add(videoLabelPanel); + mainPanel.add(new JPanel()); + } + + } + mainPanel.updateUI(); + } + + @Override + public void actionPerformed(ActionEvent e) + { + + if (e.getSource() == refreshButton) + { + try + { + SEUIL_DISTANCE_1 = Float.parseFloat(distance1TextField.getText()); + SEUIL_DISTANCE_2 = Float.parseFloat(distance2TextField.getText()); + SEUIL_DISTANCE_HEAD_HEAD = Float.parseFloat(distanceHeadHeadTextField.getText()); + + SEUIL_DISTANCE_HEAD_GENITAL = Float.parseFloat(distanceHeadGenitalTextField.getText()); + SEUIL_SIDE = Float.parseFloat(seuilSideTextField.getText()); + SPEED_THRESHOLD_1 = Float.parseFloat(speed_threshold1TextField.getText()); + SPEED_THRESHOLD_2 = Float.parseFloat(speed_threshold2TextField.getText()); + SPEED_THRESHOLD_3 = Float.parseFloat(speed_threshold3TextField.getText()); + FPS = Float.parseFloat(fpsTextField.getText()); + } + catch (NumberFormatException e1) + { + MessageDialog.showDialog( + "One of the parameters cannot be understand as a number. Please correct it and refresh again.", + MessageDialog.ERROR_MESSAGE); + return; + } + for (VideoLabelPanel vlp : videoLabelPanelArrayList) + { + if (!vlp.isFreezed()) + { + vlp.buildResultImage(); + } + } + + double scaleVideo = 1; + try + { + scaleVideo = Double.parseDouble(scaleVideoTextField.getText()); + } + catch (Exception e1) + { + // the field is incorrect. + } + + imageVideoComponent.setZoom(scaleVideo); + + } + + if (e.getSource() == openFileMenuItem) + { + openFile(); + } + + if (e.getSource() == compileImageFileMenuItem) + { + compileImageFile(); + } + + if (e.getSource() == mergeHeatMapMenuItem) + { + mergeHeatMapDirectory(); + } + + } + + private void mergeHeatMapDirectory() + { + + JFileChooser fileChooser = new JFileChooser(); + fileChooser.setMultiSelectionEnabled(true); + + String node = "plugins/PhysicTracker/videolabelmaker/browser"; + + Preferences preferences = Preferences.userRoot().node(node); + String path = preferences.get("path", ""); + fileChooser.setCurrentDirectory(new File(path)); + + int returnValue = fileChooser.showDialog(null, "Load heatmap files"); + if (returnValue == JFileChooser.APPROVE_OPTION) + { + IcyBufferedImage resultImage = new IcyBufferedImage(1, 1, 4, DataType.USHORT); + + for (int i = 0; i < fileChooser.getSelectedFiles().length; i++) + { + File file = fileChooser.getSelectedFiles()[i]; + if (file.getAbsolutePath().toLowerCase().endsWith("heatmap.tif")) + { + java.awt.Point copyPoint = new java.awt.Point(resultImage.getWidth(), 0); + System.out.println("Loading file " + file.getAbsolutePath()); + Sequence sequence = Loader.loadSequence(file.getAbsolutePath(), 0, false); + + // write sequence file name in image. + Graphics2D g = (Graphics2D) sequence.getFirstImage().getGraphics(); + g.setColor(Color.white); + g.setFont(new Font("Arial", Font.PLAIN, 12)); + g.drawString(FileUtil.getFileName(file.getAbsolutePath(), false), 0, 15); + + int newHeight = Math.max(resultImage.getHeight(), sequence.getHeight()); + resultImage = IcyBufferedImageUtil.scale(resultImage, resultImage.getWidth() + sequence.getWidth(), + newHeight, false, SwingConstants.LEFT, SwingConstants.TOP); + + resultImage.copyData(sequence.getFirstImage(), null, copyPoint); + + } + } + + // save stitched sequence + + Sequence outputSequence = new Sequence(resultImage); + File outFile = new File(FileUtil.getDirectory(fileChooser.getSelectedFile().getAbsolutePath()) + + FileUtil.separator + "heatmap stitched.tif"); + + new AnnounceFrame("Saving stitched heatmap to file " + outFile.getAbsolutePath(), 5); + Saver.save(outputSequence, outFile); + + // load files + /* + * for ( int i = 0 ; i < fileChooser.getSelectedFiles().length ; i++ ) + * { + * try { + * BufferedImage bi = ImageIO.read( fileChooser.getSelectedFiles()[i] ); + * fileImageHashMap.put( fileChooser.getSelectedFiles()[i] , bi ); + * + * } catch (IOException e1) { + * e1.printStackTrace(); + * } + * + * fileArray.add( fileChooser.getSelectedFiles()[i] ); + * } + */ + } + + } + + private void compileImageFile() + { + + JFileChooser fileChooser = new JFileChooser(); + fileChooser.setMultiSelectionEnabled(true); + int returnValue = fileChooser.showDialog(null, "Load"); + if (returnValue == JFileChooser.APPROVE_OPTION) + { + + ArrayList<File> fileArray = new ArrayList<File>(); + HashMap<File, BufferedImage> fileImageHashMap = new HashMap<File, BufferedImage>(); + + // load files + + for (int i = 0; i < fileChooser.getSelectedFiles().length; i++) + { + try + { + BufferedImage bi = ImageIO.read(fileChooser.getSelectedFiles()[i]); + fileImageHashMap.put(fileChooser.getSelectedFiles()[i], bi); + + } + catch (IOException e1) + { + e1.printStackTrace(); + } + + fileArray.add(fileChooser.getSelectedFiles()[i]); + } + + // pack files. + + int NB_TOTAL_CRITERIA = 28; + + for (int criteria = 0; criteria < NB_TOTAL_CRITERIA; criteria++) + { + // look for maxWidth. + + int maxWidth = 0; + int nbFileMatching = 0; + + String tokenToLook = ".criteria_" + criteria + ".png"; + for (File file : fileArray) + { + if (file.getAbsoluteFile().toString().contains(tokenToLook)) + { + nbFileMatching++; + int w = fileImageHashMap.get(file).getWidth(); + // System.out.println("current w : " + w ); + if (w > maxWidth) + maxWidth = w; + } + } + + System.out.println("Max Width : " + maxWidth); + + // create targetImage + if (nbFileMatching == 0) + { + new ToolTipFrame( + "<html>No file matching .criteria_XX.png found in the list of file provided.<br>Create those images by clicking the save button<br>on each XML panel</html>"); + return; + } + ; + BufferedImage image2 = new BufferedImage(maxWidth, stepY * nbFileMatching, BufferedImage.TYPE_INT_BGR); + Graphics2D targetG = (Graphics2D) image2.getGraphics(); + + int currentY = 0; + for (File file : fileArray) + { + if (file.getAbsoluteFile().toString().contains(tokenToLook)) + { + BufferedImage bi = fileImageHashMap.get(file); + targetG.drawImage(bi, null, 0, currentY); + if (criteria == 2) + { + targetG.setColor(Color.black); + targetG.drawString(file.getAbsoluteFile().toString(), 400, currentY + stepY / 2); + } + currentY += bi.getHeight(); + } + } + + try + { + + String fileName = fileChooser.getSelectedFile().getParent() + "\\__crit_" + criteria + ".png"; + System.out.println("Saving : " + fileName); + ImageIO.write(image2, "png", new File(fileName)); + + } + catch (IOException e1) + { + e1.printStackTrace(); + } + + } + } + + System.out.println("Finished."); + + } + + ArrayList<VideoLabelPanel> videoLabelPanelArrayList = new ArrayList<VideoLabelPanel>(); + + public class ImageComponent extends JPanel implements MouseMotionListener, MouseListener + { + private static final long serialVersionUID = -5907107709763419248L; + BufferedImage image; + ArrayList<String> stringList = new ArrayList<String>(); + double zoom = 1; + + public void setZoom(double zoom) + { + this.zoom = zoom; + // System.out.println("zoom:"+zoom); + updateUI(); + } + + public ImageComponent() + { + // this.showDot = showDot; + } + + public void setImage(BufferedImage image) + { + this.image = image; + this.setPreferredSize(new Dimension((int) (image.getWidth() * zoom), (int) (image.getHeight() * zoom))); + repaint(); + this.addMouseMotionListener(this); + this.addMouseListener(this); + } + + int y = 0; + int x = 0; + // boolean showDot = false; + + @Override + protected void paintComponent(Graphics g) + { + + super.paintComponent(g); + + Graphics2D g2 = (Graphics2D) g; + + if (image != null) + { + g2.scale(zoom, zoom); + g2.drawImage(image, null, 0, 0); + + if (stringList.size() != 0) + { + float dash[] = {10.0f}; + g2.setStroke( + new BasicStroke(1.0f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 10.0f, dash, 0.0f)); + g2.drawLine(x, 0, x, image.getHeight()); + } + } + } + + @Override + public void mouseDragged(MouseEvent e) + { + x = e.getX(); + repaint(); + } + + @Override + public void mouseMoved(MouseEvent e) + { + + x = e.getX(); + + int index = e.getY() / stepY; + if (stringList.size() > index) + { + String string = stringList.get(index); + if (string != null) + { + legendLabel.setText(string); + } + } + } + + @Override + public void mouseClicked(MouseEvent e) + { + x = e.getX(); + repaint(); + } + + @Override + public void mouseEntered(MouseEvent e) + { + } + + @Override + public void mouseExited(MouseEvent e) + { + } + + @Override + public void mousePressed(MouseEvent e) + { + } + + @Override + public void mouseReleased(MouseEvent e) + { + } + + } + + public class VideoLabelPanel implements ActionListener, MouseListener, MouseMotionListener + { + + JPanel panel = null; + + int firstFrame; + int lastFrame; + + HashMap<Integer, MouseInfoRecord> mouseARecord = new HashMap<Integer, MouseInfoRecord>(); + HashMap<Integer, MouseInfoRecord> mouseBRecord = new HashMap<Integer, MouseInfoRecord>(); + + int xPixelPetT = 1; + + BufferedImage imageChrono = new BufferedImage(100, 100, BufferedImage.TYPE_INT_BGR); + ImageIcon imageIcon; + ImageComponent imageComponent = new ImageComponent(); + JButton saveImageButton = new JButton("Save Chrono Image"); + JButton exportEventsAsXML = new JButton("Export Events as XML"); + JButton exportSpeedButton = new JButton("Export speed and distance"); + // freeze settings: The scale and all the info are not propagated to this animal if the freeze is on. + JCheckBox freezeSettingsCheckBox = new JCheckBox("freeze settings"); + + JButton computeVisionInFollowButton = new JButton("Export follow vision graph"); + JButton computeVisionWhenStoppedButton = new JButton("Export stop vision graph"); + + JButton computeLocationHeatMapButton = new JButton("Create location heat map"); + + JButton computeUSVStat = new JButton("Create USV stat"); + + File file; + File extraXMLFile; // contains extra labels to include to this video. + File videoFile; + FrameAccess frameAccess; + Animal animal = null; + SwimmingObject swimmingObject = null; + + public VideoLabelPanel(File fileXML) + { + + computeVisionInFollowButton.setToolTipText("Location of I in the vision of R (R following)"); + computeVisionWhenStoppedButton.setToolTipText("Location of I in the vision of R (R stopped)"); + + JPanel sidePanel2 = GuiUtil.generatePanel("Video"); + + // check if the user is trying to load an avi file, and switch extension to XML if this is the case. + if (FileUtil.getFileExtension(fileXML.getAbsolutePath(), false).toLowerCase().equals("avi")) + { + System.out.println("Avi loaded. Switching to XML."); + fileXML = new File(FileUtil.setExtension(fileXML.getAbsolutePath(), ".avi.xml")); + System.out.println("XML file name is : " + fileXML.getAbsolutePath()); + } + + this.file = fileXML; + + panel = GuiUtil.generatePanel(fileXML.getAbsolutePath()); + + panel.setLayout(new BorderLayout()); + + sidePanel2.add(GuiUtil.besidesPanel(saveImageButton)); + sidePanel2.add(GuiUtil.besidesPanel(exportEventsAsXML)); + sidePanel2.add(GuiUtil.besidesPanel(exportSpeedButton)); + sidePanel2.add(GuiUtil.besidesPanel(computeVisionInFollowButton)); + sidePanel2.add(GuiUtil.besidesPanel(computeVisionWhenStoppedButton)); + sidePanel2.add(GuiUtil.besidesPanel(computeLocationHeatMapButton)); + sidePanel2.add(GuiUtil.besidesPanel(computeUSVStat)); + + freezeSettingsCheckBox.setSelected(false); + sidePanel2.add(GuiUtil.besidesPanel(freezeSettingsCheckBox)); + + computeVisionInFollowButton.addActionListener(this); + computeVisionWhenStoppedButton.addActionListener(this); + computeLocationHeatMapButton.addActionListener(this); + computeUSVStat.addActionListener(this); + exportEventsAsXML.addActionListener(this); + + panel.add(sidePanel2, BorderLayout.CENTER); + saveImageButton.addActionListener(this); + exportSpeedButton.addActionListener(this); + + loadXML(fileXML); + + panel.add(imageComponent, BorderLayout.EAST); + + imageComponent.setImage(imageChrono); + + imageComponent.addMouseListener(this); + imageComponent.addMouseMotionListener(this); + + buildResultImage(); + + } + + public boolean isFreezed() + { + return freezeSettingsCheckBox.isSelected(); + } + + DecimalFormat decimalFormat = new DecimalFormat("00"); + + class Periode + { + int start; + int end; + + public int length() + { + return end - start; + } + + MouseEventType mouseEvent; + } + + String nbFrameToDisplayInSecond(float value) + { + value = (int) ((10f * value) / FPS) / 10f; + return "" + value + "s"; + } + + double demiVisionDeSouris = 2f * Math.PI / 3f; + + /** + * @return This function search for the first frame recorded in the XML file. + * It then shift all data to remove all zero data at the beginning of the sequence. + */ + public int trimAnalysisRecord() + { + // look at max t val. + + int tMin = Integer.MAX_VALUE; + int tMax = 0; + { + Iterator<Integer> integerIterator = mouseARecord.keySet().iterator(); + while (integerIterator.hasNext()) + { + int val = integerIterator.next(); + if (val > tMax) + tMax = val; + if (val < tMin) + tMin = val; + } + } + { + Iterator<Integer> integerIterator = mouseBRecord.keySet().iterator(); + while (integerIterator.hasNext()) + { + int val = integerIterator.next(); + if (val > tMax) + tMax = val; + if (val < tMin) + tMin = val; + } + } + + HashMap<Integer, MouseInfoRecord> mouseARecordReSorted = new HashMap<Integer, MouseInfoRecord>(); + HashMap<Integer, MouseInfoRecord> mouseBRecordReSorted = new HashMap<Integer, MouseInfoRecord>(); + + // shift the data + if (tMin != 0) + { + { + boolean warningHasBeenDisplayed = false; + // System.out.println("Shifting data"); + for (int t = tMin; t < tMax; t++) + { + MouseInfoRecord a = mouseARecord.get(t); + MouseInfoRecord b = mouseBRecord.get(t); + if ((a == null) || (b == null)) + { + // +" \n\n Re start the tracker to perform the tracking on this frame. + String problem = "A tracking frame is missing at t=" + t + " in file " + this.file + "."; + System.out.println(problem); + if (!warningHasBeenDisplayed) + { + MessageDialog.showDialog("<html><center>" + problem + + " <hr>This Message appears once per animal file. <br>See ouput to get the total list of missing frames</html>", + MessageDialog.ERROR_MESSAGE); + warningHasBeenDisplayed = true; + } + } + else + { + mouseARecordReSorted.put(t - tMin, mouseARecord.get(t)); + mouseARecord.remove(t); + + // mouseBRecord.put( t-tMin, mouseBRecord.get( t ) ); + mouseBRecordReSorted.put(t - tMin, mouseBRecord.get(t)); + mouseBRecord.remove(t); + } + + // System.out.println( "t-TMin:" +(t-tMin) + " t:"+ t); + + // mouseARecord.put( t-tMin, mouseARecord.get( t ) ); + + // mouseARecordReSorted.put( t-tMin, mouseARecord.get( t ) ); + // mouseARecord.remove( t ); + // + // //mouseBRecord.put( t-tMin, mouseBRecord.get( t ) ); + // mouseBRecordReSorted.put( t-tMin, mouseBRecord.get( t ) ); + // mouseBRecord.remove( t ); + } + } + + mouseARecord = mouseARecordReSorted; + mouseBRecord = mouseBRecordReSorted; + } + + // System.out.println( "--- check mouse record "); + // + // MouseInfoRecord test = mouseARecord.get( 4471 ); + // System.out.println( "contain object ? " + mouseARecord.containsKey( 4471 ) ); + // System.out.println( "record is " + test ); + + // // test + // for ( int t = tMin ; t< mouseARecord.size() ; t++ ) + // { + // MouseInfoRecord info = mouseARecord.get( t ); + // if ( info == null ) + // { + // System.out.println( "error at t:" + t ); + // System.out.println( "null" ); + // } + // + //// mouseARecord.put( t-tMin, mouseARecord.get( t ) ); + //// mouseARecord.remove( t ); + // + //// mouseBRecord.put( t-tMin, mouseBRecord.get( t ) ); + //// mouseBRecord.remove( t ); + // } + + return tMin; + } + + public void buildResultImage() + { + + ArrayList<Periode> eventContactList = new ArrayList<Periode>(); + + Icy.getMainInterface().getSwimmingPool().remove(swimmingObject); + animal = new Animal(file.getName()); + swimmingObject = new SwimmingObject(animal); + + // // look at max t val. + // + // int tMin = Integer.MAX_VALUE; + // int tMax = 0; + // { + // Iterator<Integer> integerIterator = mouseARecord.keySet().iterator(); + // while ( integerIterator.hasNext() ) + // { + // int val = integerIterator.next(); + // if ( val > tMax ) tMax = val; + // if ( val < tMin ) tMin = val; + // } + // } + // { + // Iterator<Integer> integerIterator = mouseBRecord.keySet().iterator(); + // while ( integerIterator.hasNext() ) + // { + // int val = integerIterator.next(); + // if ( val > tMax ) tMax = val; + // if ( val < tMin ) tMin = val; + // } + // } + + // trimAnalysisRecord(); + + int tMin = 0; + + START_MINUTE = Integer.parseInt(computeImageStartMinuteTextField.getText()); + NB_MINUTE = Integer.parseInt(computeImageNbMinuteTextField.getText()); + + // FPS = Integer.parseInt( compute ) + + firstFrame = (int) (tMin + START_MINUTE * 60 * FPS); + // lastFrame = tMax; + + // { + lastFrame = (int) (firstFrame + NB_MINUTE * 60 * FPS); + // } + + System.out.println("first frame : " + firstFrame); + System.out.println("last frame : " + lastFrame); + + int tMax = lastFrame; + + int nbExtraEvent = 15; // getNbExtraEvent( file ); + + imageChrono = new BufferedImage(lastFrame - firstFrame, 480 + nbExtraEvent * stepY, + BufferedImage.TYPE_INT_BGR); + + imageComponent.setImage(imageChrono); + + panel.updateUI(); + + int currentY = 0; + + Graphics2D g2 = (Graphics2D) imageChrono.getGraphics(); + + // empty image + + g2.fillRect(0, 0, imageChrono.getWidth(), imageChrono.getHeight()); + + // Clean up data + { + + for (int t = 0; t < tMax; t++) + { + // System.out.println(t + " / " + tMax ); + // System.out.println( t ); + if (mouseARecord.containsKey(t)) + { + MouseInfoRecord mouseA = mouseARecord.get(t); + if (mouseA == null) + { + System.out.println("no mouse A record at t=" + t); + } + mouseA.distanceIsInferiorToThreshold1 = false; + mouseA.distanceIsInferiorToThreshold2 = false; + mouseA.isEscaping = false; + mouseA.isEscapingFromOtherAndUnTouch = false; + mouseA.isGettingToOtherAndTouch = false; + mouseA.isGoingToTheOther = false; + mouseA.mouseGetToOtherMouseAndEscapeInOut = false; + mouseA.mouseGetToOtherMouseAndOtherEscapeInOut = false; + mouseA.eventA = false; + mouseA.eventB = false; + mouseA.eventC = false; + mouseA.eventD = false; + mouseA.isBehindTheOther = false; + mouseA.isBesideTheOther = false; + mouseA.thisHeadWithOtherGenitalContact = false; + } + if (mouseBRecord.containsKey(t)) + { + MouseInfoRecord mouseB = mouseBRecord.get(t); + mouseB.distanceIsInferiorToThreshold1 = false; + mouseB.distanceIsInferiorToThreshold2 = false; + mouseB.isEscaping = false; + mouseB.isEscapingFromOtherAndUnTouch = false; + mouseB.isGettingToOtherAndTouch = false; + mouseB.isGoingToTheOther = false; + mouseB.mouseGetToOtherMouseAndEscapeInOut = false; + mouseB.mouseGetToOtherMouseAndOtherEscapeInOut = false; + mouseB.eventA = false; + mouseB.eventB = false; + mouseB.eventC = false; + mouseB.eventD = false; + mouseB.isBehindTheOther = false; + mouseB.isBesideTheOther = false; + mouseB.thisHeadWithOtherGenitalContact = false; + } + } + } + + // DISPLAY TIME + { + g2.setColor(Color.black); + + { + for (int t = 0; t < tMax; t++) + { + + if (t % (FPS * 2) < 1) + { + g2.drawString( + "" + (int) (t / (FPS * 60)) + ":" + decimalFormat.format((int) (t / FPS % 60)), + t - firstFrame, currentY + 12); + g2.drawLine(t - firstFrame, currentY, t - firstFrame, currentY + stepY); + } + + } + } + currentY += stepY; + imageComponent.stringList.add("Time"); + } + + { + + // Label 2 + // Distance de souris A a B est inferieure a SEUIL_DISTANCE_1 + boolean event = false; + int nbEvent = 0; + int total = 0; + + EventTimeLine distanceLessThanThreshold1TimeLine = new EventTimeLine("Distance < thr 1", + EventType.DISTANCE_INFERIOR_THRESHOLD_1, TimeLineCategory.USE_BOOLEAN_EVENT); + animal.eventTimeLineList.add(distanceLessThanThreshold1TimeLine); + + g2.setColor(Color.red); + for (int t = 0; t < tMax; t++) + { + // System.out.println("working on t=" + t ); + if (mouseARecord.containsKey(t)) + if (mouseBRecord.containsKey(t)) + { + // System.out.println("contain keys"); + + MouseInfoRecord mouseA = mouseARecord.get(t); + MouseInfoRecord mouseB = mouseBRecord.get(t); + + float minDistance = Float.MAX_VALUE; + minDistance = getMin(minDistance, + (float) mouseA.bodyPosition.distance(mouseB.bodyPosition)); + minDistance = getMin(minDistance, + (float) mouseA.bodyPosition.distance(mouseB.headPosition)); + minDistance = getMin(minDistance, + (float) mouseA.bodyPosition.distance(mouseB.tailPosition)); + minDistance = getMin(minDistance, + (float) mouseA.headPosition.distance(mouseB.bodyPosition)); + minDistance = getMin(minDistance, + (float) mouseA.headPosition.distance(mouseB.headPosition)); + minDistance = getMin(minDistance, + (float) mouseA.headPosition.distance(mouseB.tailPosition)); + minDistance = getMin(minDistance, + (float) mouseA.tailPosition.distance(mouseB.bodyPosition)); + minDistance = getMin(minDistance, + (float) mouseA.tailPosition.distance(mouseB.headPosition)); + minDistance = getMin(minDistance, + (float) mouseA.tailPosition.distance(mouseB.tailPosition)); + + // System.out.println( "min distance = " + minDistance ); + + if (minDistance < SEUIL_DISTANCE_1) + { + distanceLessThanThreshold1TimeLine.addPunctualEvent(t - firstFrame); + mouseA.distanceIsInferiorToThreshold1 = true; + mouseB.distanceIsInferiorToThreshold1 = true; + } + else + { + mouseA.distanceIsInferiorToThreshold1 = false; + mouseB.distanceIsInferiorToThreshold1 = false; + } + + } + } + + nbEvent = 0; + total = 0; + // draw result + for (EventCriteria eventCriteria : distanceLessThanThreshold1TimeLine.eventList) + { + nbEvent++; + total += eventCriteria.getLength(); + for (int i = eventCriteria.startFrame; i <= eventCriteria.endFrame; i++) + { + g2.drawLine(i, currentY, i, currentY + stepY); + } + } + + g2.setColor(Color.black); + g2.drawLine(0, currentY, imageChrono.getWidth(), currentY); + String string = "Distance less than THRESHOLD 1 nbEvent:" + nbEvent + " totalT:" + + nbFrameToDisplayInSecond(total); + g2.drawString(string, 0, currentY + 12); + + currentY += stepY; + + imageComponent.stringList.add(string); + + } + + { + // LABEL 3 + // Distance de souris A a B est inferieure a SEUIL_DISTANCE_2 + boolean event = false; + int nbEvent = 0; + int total = 0; + + EventTimeLine distanceLessThanThreshold2TimeLine = new EventTimeLine("Distance < thr 2", + EventType.DISTANCE_INFERIOR_THRESHOLD_2, TimeLineCategory.USE_BOOLEAN_EVENT); + animal.eventTimeLineList.add(distanceLessThanThreshold2TimeLine); + + g2.setColor(Color.orange); + for (int t = 0; t < tMax; t++) + { + if (mouseARecord.containsKey(t)) + if (mouseBRecord.containsKey(t)) + { + MouseInfoRecord mouseA = mouseARecord.get(t); + MouseInfoRecord mouseB = mouseBRecord.get(t); + + float minDistance = Float.MAX_VALUE; + minDistance = getMin(minDistance, + (float) mouseA.bodyPosition.distance(mouseB.bodyPosition)); + minDistance = getMin(minDistance, + (float) mouseA.bodyPosition.distance(mouseB.headPosition)); + minDistance = getMin(minDistance, + (float) mouseA.bodyPosition.distance(mouseB.tailPosition)); + minDistance = getMin(minDistance, + (float) mouseA.headPosition.distance(mouseB.bodyPosition)); + minDistance = getMin(minDistance, + (float) mouseA.headPosition.distance(mouseB.headPosition)); + minDistance = getMin(minDistance, + (float) mouseA.headPosition.distance(mouseB.tailPosition)); + minDistance = getMin(minDistance, + (float) mouseA.tailPosition.distance(mouseB.bodyPosition)); + minDistance = getMin(minDistance, + (float) mouseA.tailPosition.distance(mouseB.headPosition)); + minDistance = getMin(minDistance, + (float) mouseA.tailPosition.distance(mouseB.tailPosition)); + + if (minDistance < SEUIL_DISTANCE_2) + { + distanceLessThanThreshold2TimeLine.addPunctualEvent(t - firstFrame); + mouseA.distanceIsInferiorToThreshold2 = true; + mouseB.distanceIsInferiorToThreshold2 = true; + } + else + { + mouseA.distanceIsInferiorToThreshold2 = false; + mouseB.distanceIsInferiorToThreshold2 = false; + } + + } + } + + nbEvent = 0; + total = 0; + // draw result + for (EventCriteria eventCriteria : distanceLessThanThreshold2TimeLine.eventList) + { + nbEvent++; + total += eventCriteria.getLength(); + for (int i = eventCriteria.startFrame; i <= eventCriteria.endFrame; i++) + { + g2.drawLine(i, currentY, i, currentY + stepY); + } + } + + g2.setColor(Color.black); + g2.drawLine(0, currentY, imageChrono.getWidth(), currentY); + String string = "Distance less than THRESHOLD 2 nbEvent:" + nbEvent + " totalT:" + + nbFrameToDisplayInSecond(total); + g2.drawString(string, 0, currentY + 12); + + currentY += stepY; + + imageComponent.stringList.add(string); + } + + { + // LABEL 4 + // Head A - Head B SEUIL_DISTANCE_HEAD_HEAD + boolean event = false; + int nbEvent = 0; + int total = 0; + + EventTimeLine OralOralTimeLine = new EventTimeLine("Oral-Oral", EventType.ORAL_ORAL, + TimeLineCategory.USE_BOOLEAN_EVENT); + animal.eventTimeLineList.add(OralOralTimeLine); + + g2.setColor(Color.black); + for (int t = 0; t < tMax; t++) + { + if (mouseARecord.containsKey(t)) + if (mouseBRecord.containsKey(t)) + { + MouseInfoRecord mouseA = mouseARecord.get(t); + MouseInfoRecord mouseB = mouseBRecord.get(t); + + float minDistance = Float.MAX_VALUE; + minDistance = getMin(minDistance, + (float) mouseA.headPosition.distance(mouseB.headPosition)); + if (minDistance < SEUIL_DISTANCE_HEAD_HEAD) + { + OralOralTimeLine.addPunctualEvent(t - firstFrame); + + } + else + { + + } + } + } + + // display + nbEvent = 0; + total = 0; + // draw result + for (EventCriteria eventCriteria : OralOralTimeLine.eventList) + { + nbEvent++; + total += eventCriteria.getLength(); + for (int i = eventCriteria.startFrame; i <= eventCriteria.endFrame; i++) + { + g2.drawLine(i, currentY, i, currentY + stepY); + } + } + + g2.setColor(Color.black); + g2.drawLine(0, currentY, imageChrono.getWidth(), currentY); + String string = "Head - Head : nbevent: " + nbEvent + " TotalT=" + nbFrameToDisplayInSecond(total); + g2.drawString(string, 0, currentY + 12); + + currentY += stepY; + imageComponent.stringList.add(string); + + } + { + // LABEL 5 + // Head A - Genital B SEUIL_DISTANCE_HEAD_GENITAL + boolean event = false; + int nbEvent = 0; + int total = 0; + + EventTimeLine eventTimeLine = new EventTimeLine("Oral A - Genital B", EventType.ORAL_A_GENITAL_B, + TimeLineCategory.USE_BOOLEAN_EVENT); + animal.eventTimeLineList.add(eventTimeLine); + + g2.setColor(Color.RED); + for (int t = 0; t < tMax; t++) + { + if (mouseARecord.containsKey(t)) + if (mouseBRecord.containsKey(t)) + { + MouseInfoRecord mouseA = mouseARecord.get(t); + MouseInfoRecord mouseB = mouseBRecord.get(t); + + float minDistance = Float.MAX_VALUE; + minDistance = getMin(minDistance, + (float) mouseA.headPosition.distance(mouseB.tailPosition)); + if (minDistance < SEUIL_DISTANCE_HEAD_GENITAL) + { + eventTimeLine.addPunctualEvent(t - firstFrame); + + mouseA.thisHeadWithOtherGenitalContact = true; + + } + else + { + + } + } + } + nbEvent = 0; + total = 0; + // draw result + for (EventCriteria eventCriteria : eventTimeLine.eventList) + { + nbEvent++; + total += eventCriteria.getLength(); + for (int i = eventCriteria.startFrame; i <= eventCriteria.endFrame; i++) + { + g2.drawLine(i, currentY, i, currentY + stepY); + } + } + + g2.setColor(Color.black); + g2.drawLine(0, currentY, imageChrono.getWidth(), currentY); + g2.drawLine(0, currentY - 1, imageChrono.getWidth(), currentY - 1); + String string = "Head A - Genital B nbEvent:" + nbEvent + " TotalT:" + nbFrameToDisplayInSecond(total); + g2.drawString(string, 0, currentY + 12); + + currentY += stepY; + imageComponent.stringList.add(string); + + } + { + // LABEL 6 + // Head B - Genital A SEUIL_DISTANCE_HEAD_GENITAL + boolean event = false; + int nbEvent = 0; + int total = 0; + + EventTimeLine eventTimeLine = new EventTimeLine("Oral B - Genital A", EventType.ORAL_B_GENITAL_A, + TimeLineCategory.USE_BOOLEAN_EVENT); + animal.eventTimeLineList.add(eventTimeLine); + + g2.setColor(Color.GREEN); + for (int t = 0; t < tMax; t++) + { + if (mouseARecord.containsKey(t)) + if (mouseBRecord.containsKey(t)) + { + MouseInfoRecord mouseA = mouseARecord.get(t); + MouseInfoRecord mouseB = mouseBRecord.get(t); + + float minDistance = Float.MAX_VALUE; + minDistance = getMin(minDistance, + (float) mouseA.tailPosition.distance(mouseB.headPosition)); + if (minDistance < SEUIL_DISTANCE_HEAD_GENITAL) + { + eventTimeLine.addPunctualEvent(t - firstFrame); + + mouseB.thisHeadWithOtherGenitalContact = true; + + } + else + { + + } + } + } + + nbEvent = 0; + total = 0; + // draw result + for (EventCriteria eventCriteria : eventTimeLine.eventList) + { + nbEvent++; + total += eventCriteria.getLength(); + for (int i = eventCriteria.startFrame; i <= eventCriteria.endFrame; i++) + { + g2.drawLine(i, currentY, i, currentY + stepY); + } + } + + g2.setColor(Color.black); + g2.drawLine(0, currentY, imageChrono.getWidth(), currentY); + String string = "Head B - Genital A : nbEvent:" + nbEvent + " totalT:" + + nbFrameToDisplayInSecond(total); + g2.drawString(string, 0, currentY + 12); + + imageComponent.stringList.add(string); + + currentY += stepY; + } + { + // Mouse A is behind Mouse B + boolean event = false; + int nbEvent = 0; + int total = 0; + + EventTimeLine eventTimeLine = new EventTimeLine("Mouse A behind B (any distance)", EventType.A_BEHIND_B, + TimeLineCategory.USE_BOOLEAN_EVENT); + animal.eventTimeLineList.add(eventTimeLine); + + for (int t = 0; t < tMax; t++) + { + if (mouseARecord.containsKey(t)) + if (mouseBRecord.containsKey(t)) + { + MouseInfoRecord mouseA = mouseARecord.get(t); + MouseInfoRecord mouseB = mouseBRecord.get(t); + + float mouseABodyToMouseBTail = (float) mouseA.bodyPosition.distance(mouseB.tailPosition); + float mouseABodyToMouseBHead = (float) mouseA.bodyPosition.distance(mouseB.headPosition); + + if (mouseABodyToMouseBTail < mouseABodyToMouseBHead) + { + eventTimeLine.addPunctualEvent(t - firstFrame); + + mouseA.isBehindTheOther = true; + + } + else + { + + } + } + } + + g2.setColor(Color.RED); + nbEvent = 0; + total = 0; + // draw result + for (EventCriteria eventCriteria : eventTimeLine.eventList) + { + nbEvent++; + total += eventCriteria.getLength(); + for (int i = eventCriteria.startFrame; i <= eventCriteria.endFrame; i++) + { + g2.drawLine(i, currentY, i, currentY + stepY); + } + } + + g2.setColor(Color.black); + g2.drawLine(0, currentY, imageChrono.getWidth(), currentY); + g2.drawLine(0, currentY - 1, imageChrono.getWidth(), currentY - 1); + + String string = "Mouse A is behind B nbevent:" + nbEvent + " totalT:" + nbFrameToDisplayInSecond(total); + g2.drawString(string, 0, currentY + 12); + imageComponent.stringList.add(string); + + currentY += stepY; + } + + { + // Mouse B is behind Mouse A + boolean event = false; + int nbEvent = 0; + int total = 0; + + EventTimeLine eventTimeLine = new EventTimeLine("Mouse B behind A (any distance)", EventType.B_BEHIND_A, + TimeLineCategory.USE_BOOLEAN_EVENT); + animal.eventTimeLineList.add(eventTimeLine); + + for (int t = 0; t < tMax; t++) + { + if (mouseARecord.containsKey(t)) + if (mouseBRecord.containsKey(t)) + { + MouseInfoRecord mouseA = mouseARecord.get(t); + MouseInfoRecord mouseB = mouseBRecord.get(t); + + float mouseBBodyToMouseATail = (float) mouseB.bodyPosition.distance(mouseA.tailPosition); + float mouseBBodyToMouseAHead = (float) mouseB.bodyPosition.distance(mouseA.headPosition); + + if (mouseBBodyToMouseATail < mouseBBodyToMouseAHead) + { + eventTimeLine.addPunctualEvent(t - firstFrame); + + mouseB.isBehindTheOther = true; + + } + else + { + event = false; + } + } + } + + g2.setColor(Color.GREEN); + nbEvent = 0; + total = 0; + // draw result + for (EventCriteria eventCriteria : eventTimeLine.eventList) + { + nbEvent++; + total += eventCriteria.getLength(); + for (int i = eventCriteria.startFrame; i <= eventCriteria.endFrame; i++) + { + g2.drawLine(i, currentY, i, currentY + stepY); + } + } + + g2.setColor(Color.black); + g2.drawLine(0, currentY, imageChrono.getWidth(), currentY); + String string = "Mouse B is behind A nbevent:" + nbEvent + " totalT:" + nbFrameToDisplayInSecond(total); + g2.drawString(string, 0, currentY + 12); + imageComponent.stringList.add(string); + currentY += stepY; + } + { + // Mice are next to the each other and body distance < DISTANCE_2 (same way) + // Calcul par produit scalaire. si positif meme sens. + boolean event = false; + int nbEvent = 0; + int total = 0; + + EventTimeLine eventTimeLine = new EventTimeLine("Mouse next to each other (same way) < distance 2", + EventType.BESIDE_SAME_WAY, TimeLineCategory.USE_BOOLEAN_EVENT); + animal.eventTimeLineList.add(eventTimeLine); + + for (int t = 0; t < tMax; t++) + { + if (mouseARecord.containsKey(t)) + if (mouseBRecord.containsKey(t)) + { + MouseInfoRecord mouseA = mouseARecord.get(t); + MouseInfoRecord mouseB = mouseBRecord.get(t); + + float mouseABodyToMouseBBody = (float) mouseA.bodyPosition.distance(mouseB.bodyPosition); + float mouseAHeadToMouseBHead = (float) mouseA.headPosition.distance(mouseB.headPosition); + + double vectSourisAX = mouseA.headPosition.getX() - mouseA.bodyPosition.getX(); + double vectSourisAY = mouseA.headPosition.getY() - mouseA.bodyPosition.getY(); + double vectSourisBX = mouseB.headPosition.getX() - mouseB.bodyPosition.getX(); + double vectSourisBY = mouseB.headPosition.getY() - mouseB.bodyPosition.getY(); + + double produitScalaire = vectSourisAX * vectSourisBX + vectSourisAY * vectSourisBY; + double distance = Double.parseDouble(distance1TextField.getText()); + + if (produitScalaire >= 0 && mouseAHeadToMouseBHead < SEUIL_DISTANCE_1 + && mouseABodyToMouseBBody < SEUIL_DISTANCE_1) + { + eventTimeLine.addPunctualEvent(t - firstFrame); + + mouseA.isBesideTheOther = true; + mouseB.isBesideTheOther = true; + + } + else + { + + } + + } + } + + g2.setColor(Color.DARK_GRAY); + nbEvent = 0; + total = 0; + // draw result + for (EventCriteria eventCriteria : eventTimeLine.eventList) + { + nbEvent++; + total += eventCriteria.getLength(); + for (int i = eventCriteria.startFrame; i <= eventCriteria.endFrame; i++) + { + g2.drawLine(i, currentY, i, currentY + stepY); + } + } + + g2.setColor(Color.black); + g2.drawLine(0, currentY, imageChrono.getWidth(), currentY); + String string = "Mice are next to the each other and body distance < DISTANCE_2 (same way) nbevent:" + + nbEvent + " totalT:" + nbFrameToDisplayInSecond(total); + g2.drawString(string, 0, currentY + 12); + imageComponent.stringList.add(string); + currentY += stepY; + } + { + // Mice are next to the each other and body distance < DISTANCE_2 (opposite way) + boolean event = false; + int nbEvent = 0; + int total = 0; + + EventTimeLine eventTimeLine = new EventTimeLine("Mouse next to each other (opposite way) < distance 2", + EventType.BESIDE_OPPOSITE_WAY, TimeLineCategory.USE_BOOLEAN_EVENT); + animal.eventTimeLineList.add(eventTimeLine); + + for (int t = 0; t < tMax; t++) + { + if (mouseARecord.containsKey(t)) + if (mouseBRecord.containsKey(t)) + { + MouseInfoRecord mouseA = mouseARecord.get(t); + MouseInfoRecord mouseB = mouseBRecord.get(t); + + double vectSourisAX = mouseA.headPosition.getX() - mouseA.bodyPosition.getX(); + double vectSourisAY = mouseA.headPosition.getY() - mouseA.bodyPosition.getY(); + double vectSourisBX = mouseB.headPosition.getX() - mouseB.bodyPosition.getX(); + double vectSourisBY = mouseB.headPosition.getY() - mouseB.bodyPosition.getY(); + + double produitScalaire = vectSourisAX * vectSourisBX + vectSourisAY * vectSourisBY; + + float mouseABodyToMouseBHead = (float) mouseA.bodyPosition.distance(mouseB.headPosition); + float mouseAHeadToMouseBBody = (float) mouseA.headPosition.distance(mouseB.bodyPosition); + + if (produitScalaire < 0 && mouseABodyToMouseBHead < SEUIL_DISTANCE_1 + && mouseAHeadToMouseBBody < SEUIL_DISTANCE_1) + { + eventTimeLine.addPunctualEvent(t - firstFrame); + + } + else + { + + } + + } + } + + g2.setColor(Color.BLACK); + nbEvent = 0; + total = 0; + // draw result + for (EventCriteria eventCriteria : eventTimeLine.eventList) + { + nbEvent++; + total += eventCriteria.getLength(); + for (int i = eventCriteria.startFrame; i <= eventCriteria.endFrame; i++) + { + g2.drawLine(i, currentY, i, currentY + stepY); + } + } + + g2.setColor(Color.black); + g2.drawLine(0, currentY, imageChrono.getWidth(), currentY); + String string = "Mice are next to the each other and body distance < DISTANCE_2 (opposite) nbevent:" + + nbEvent + " totalT:" + nbFrameToDisplayInSecond(total); + g2.drawString(string, 0, currentY + 12); + imageComponent.stringList.add(string); + + currentY += stepY; + } + + /** frameWindow est utilisé pour lisser le calcul de deplacement entre deux points de temps. t-framewindow et t+frameWindow */ + int frameWindow = 6; // 5 + + { + EventTimeLine eventTimeLine = new EventTimeLine("Mouse A speed", EventType.MOUSE_A_SPEED, + TimeLineCategory.USE_DISCRETE_EVENT); + animal.eventTimeLineList.add(eventTimeLine); + + // Mice A speed is from 0 to SPEED_THRESHOLD_1 + float nbVal = 0; + float totalDistance = 0; + for (int t = 0; t < tMax; t++) + { + if (mouseARecord.containsKey(t - frameWindow)) + if (mouseBRecord.containsKey(t - frameWindow)) + if (mouseARecord.containsKey(t + frameWindow)) + if (mouseBRecord.containsKey(t + frameWindow)) + if (mouseARecord.containsKey(t)) + if (mouseBRecord.containsKey(t)) + { + MouseInfoRecord mouseAprev = mouseARecord.get(t - frameWindow); + MouseInfoRecord mouseBprev = mouseBRecord.get(t - frameWindow); + MouseInfoRecord mouseAnext = mouseARecord.get(t + frameWindow); + MouseInfoRecord mouseBnext = mouseBRecord.get(t + frameWindow); + MouseInfoRecord mouseA = mouseARecord.get(t); + MouseInfoRecord mouseB = mouseBRecord.get(t); + + float distance = (float) mouseAprev.bodyPosition + .distance(mouseAnext.bodyPosition); + distance /= (float) (frameWindow * 2 + 1); // pour obtenir une vitesse par frame. + + nbVal++; + totalDistance += distance; + + mouseA.speed = distance; + + eventTimeLine.addValue(t - firstFrame, distance); + + if (distance <= SPEED_THRESHOLD_1) + { + g2.setColor(Color.BLACK); + g2.drawLine(t - firstFrame, currentY, t - firstFrame, currentY + stepY); + } + if ((distance > SPEED_THRESHOLD_1) && (distance < SPEED_THRESHOLD_2)) + { + g2.setColor(Color.DARK_GRAY); + g2.drawLine(t - firstFrame, currentY, t - firstFrame, currentY + stepY); + } + if ((distance >= SPEED_THRESHOLD_2)) + { + g2.setColor(Color.GRAY); + g2.drawLine(t - firstFrame, currentY, t - firstFrame, currentY + stepY); + } + + } + } + + g2.setColor(Color.red); + g2.drawLine(0, currentY, imageChrono.getWidth(), currentY); + String string = "Mouse A speed slow=black fast=gray mean speed: " + totalDistance / nbVal; + g2.drawString(string, 0, currentY + 12); + imageComponent.stringList.add(string); + + currentY += stepY; + } + + { + EventTimeLine eventTimeLine = new EventTimeLine("Mouse B speed", EventType.MOUSE_B_SPEED, + TimeLineCategory.USE_DISCRETE_EVENT); + animal.eventTimeLineList.add(eventTimeLine); + + // Mice B speed is from 0 to SPEED_THRESHOLD_1 + float nbVal = 0; + float totalDistance = 0; + + for (int t = 0; t < tMax; t++) + { + if (mouseARecord.containsKey(t - frameWindow)) + if (mouseBRecord.containsKey(t - frameWindow)) + if (mouseARecord.containsKey(t + frameWindow)) + if (mouseBRecord.containsKey(t + frameWindow)) + if (mouseARecord.containsKey(t)) + if (mouseBRecord.containsKey(t)) + { + + MouseInfoRecord mouseAprev = mouseARecord.get(t - frameWindow); + MouseInfoRecord mouseBprev = mouseBRecord.get(t - frameWindow); + MouseInfoRecord mouseAnext = mouseARecord.get(t + frameWindow); + MouseInfoRecord mouseBnext = mouseBRecord.get(t + frameWindow); + MouseInfoRecord mouseA = mouseARecord.get(t); + MouseInfoRecord mouseB = mouseBRecord.get(t); + + float distance = (float) mouseBprev.bodyPosition + .distance(mouseBnext.bodyPosition); + distance /= (float) (frameWindow * 2 + 1); // pour obtenir une vitesse par frame. + + mouseB.speed = distance; + nbVal++; + totalDistance += distance; + + eventTimeLine.addValue(t - firstFrame, distance); + + if (distance <= SPEED_THRESHOLD_1) + { + g2.setColor(Color.BLACK); + g2.drawLine(t - firstFrame, currentY, t - firstFrame, currentY + stepY); + } + if ((distance > SPEED_THRESHOLD_1) && (distance < SPEED_THRESHOLD_2)) + { + g2.setColor(Color.DARK_GRAY); + g2.drawLine(t - firstFrame, currentY, t - firstFrame, currentY + stepY); + } + if ((distance >= SPEED_THRESHOLD_2)) + { + g2.setColor(Color.GRAY); + g2.drawLine(t - firstFrame, currentY, t - firstFrame, currentY + stepY); + } + + } + } + g2.setColor(Color.red); + g2.drawLine(0, currentY, imageChrono.getWidth(), currentY); + String string = "Mouse B speed slow=black fast=gray mean speed: " + totalDistance / nbVal; + g2.drawString(string, 0, currentY + 12); + imageComponent.stringList.add(string); + currentY += stepY; + } + + { + // Mouse A Stop + boolean event = false; + float nbEvent = 0; + float total = 0; + + EventTimeLine eventTimeLine = new EventTimeLine("A Stop", EventType.A_STOP, + TimeLineCategory.USE_BOOLEAN_EVENT); + animal.eventTimeLineList.add(eventTimeLine); + + for (int t = 0; t < tMax; t++) + { + if (mouseARecord.containsKey(t - frameWindow)) + if (mouseBRecord.containsKey(t - frameWindow)) + if (mouseARecord.containsKey(t + frameWindow)) + if (mouseBRecord.containsKey(t + frameWindow)) + if (mouseARecord.containsKey(t)) + if (mouseBRecord.containsKey(t)) + { + MouseInfoRecord mouseAprev = mouseARecord.get(t - frameWindow); + MouseInfoRecord mouseBprev = mouseBRecord.get(t - frameWindow); + MouseInfoRecord mouseAnext = mouseARecord.get(t + frameWindow); + MouseInfoRecord mouseBnext = mouseBRecord.get(t + frameWindow); + MouseInfoRecord mouseA = mouseARecord.get(t); + MouseInfoRecord mouseB = mouseBRecord.get(t); + + double distanceTPrev = mouseAprev.bodyPosition + .distance(mouseBprev.bodyPosition); + double distanceTNext = mouseAnext.bodyPosition + .distance(mouseBnext.bodyPosition); + + if (mouseA.speed < SPEED_THRESHOLD_1) + { + + eventTimeLine.addPunctualEvent(t - firstFrame); + + } + else + { + event = false; + } + + } + } + + g2.setColor(Color.red); + nbEvent = 0; + total = 0; + // draw result + for (EventCriteria eventCriteria : eventTimeLine.eventList) + { + nbEvent++; + total += eventCriteria.getLength(); + for (int i = eventCriteria.startFrame; i <= eventCriteria.endFrame; i++) + { + g2.drawLine(i, currentY, i, currentY + stepY); + } + } + + g2.setColor(Color.black); + g2.drawLine(0, currentY, imageChrono.getWidth(), currentY); + String string = "A Stop : nbEvent : " + nbEvent + " total: " + nbFrameToDisplayInSecond(total); + g2.drawString(string, 0, currentY + 12); + imageComponent.stringList.add(string); + + currentY += stepY; + } + + { + // Mouse B Stop + boolean event = false; + float nbEvent = 0; + float total = 0; + + EventTimeLine eventTimeLine = new EventTimeLine("B Stop", EventType.B_STOP, + TimeLineCategory.USE_BOOLEAN_EVENT); + animal.eventTimeLineList.add(eventTimeLine); + + for (int t = 0; t < tMax; t++) + { + if (mouseARecord.containsKey(t - frameWindow)) + if (mouseBRecord.containsKey(t - frameWindow)) + if (mouseARecord.containsKey(t + frameWindow)) + if (mouseBRecord.containsKey(t + frameWindow)) + if (mouseARecord.containsKey(t)) + if (mouseBRecord.containsKey(t)) + { + MouseInfoRecord mouseAprev = mouseARecord.get(t - frameWindow); + MouseInfoRecord mouseBprev = mouseBRecord.get(t - frameWindow); + MouseInfoRecord mouseAnext = mouseARecord.get(t + frameWindow); + MouseInfoRecord mouseBnext = mouseBRecord.get(t + frameWindow); + MouseInfoRecord mouseA = mouseARecord.get(t); + MouseInfoRecord mouseB = mouseBRecord.get(t); + + double distanceTPrev = mouseAprev.bodyPosition + .distance(mouseBprev.bodyPosition); + double distanceTNext = mouseAnext.bodyPosition + .distance(mouseBnext.bodyPosition); + + if (mouseB.speed < SPEED_THRESHOLD_1) + { + + eventTimeLine.addPunctualEvent(t - firstFrame); + + } + else + { + event = false; + } + + } + } + + g2.setColor(Color.green); + nbEvent = 0; + total = 0; + // draw result + for (EventCriteria eventCriteria : eventTimeLine.eventList) + { + nbEvent++; + total += eventCriteria.getLength(); + for (int i = eventCriteria.startFrame; i <= eventCriteria.endFrame; i++) + { + g2.drawLine(i, currentY, i, currentY + stepY); + } + } + + g2.setColor(Color.black); + g2.drawLine(0, currentY, imageChrono.getWidth(), currentY); + String string = "B Stop : nbEvent : " + nbEvent + " total: " + nbFrameToDisplayInSecond(total); + g2.drawString(string, 0, currentY + 12); + imageComponent.stringList.add(string); + + currentY += stepY; + } + + { + // Mouse A Speed > Mouse B Speed & Mouse A getting to B + boolean event = false; + float nbEvent = 0; + float total = 0; + + EventTimeLine eventTimeLine = new EventTimeLine("A Speed > B Speed & A GET TO B", + EventType.A_SPEED_HIGHER_THAN_B_SPEED_AND_A_GET_TO_B, TimeLineCategory.USE_BOOLEAN_EVENT); + animal.eventTimeLineList.add(eventTimeLine); + + for (int t = 0; t < tMax; t++) + { + if (mouseARecord.containsKey(t - frameWindow)) + if (mouseBRecord.containsKey(t - frameWindow)) + if (mouseARecord.containsKey(t + frameWindow)) + if (mouseBRecord.containsKey(t + frameWindow)) + if (mouseARecord.containsKey(t)) + if (mouseBRecord.containsKey(t)) + { + MouseInfoRecord mouseAprev = mouseARecord.get(t - frameWindow); + MouseInfoRecord mouseBprev = mouseBRecord.get(t - frameWindow); + MouseInfoRecord mouseAnext = mouseARecord.get(t + frameWindow); + MouseInfoRecord mouseBnext = mouseBRecord.get(t + frameWindow); + MouseInfoRecord mouseA = mouseARecord.get(t); + MouseInfoRecord mouseB = mouseBRecord.get(t); + + double distanceTPrev = mouseAprev.bodyPosition + .distance(mouseBprev.bodyPosition); + double distanceTNext = mouseAnext.bodyPosition + .distance(mouseBnext.bodyPosition); + + if (mouseA.speed > mouseB.speed) + { + if (distanceTPrev > distanceTNext) + { + eventTimeLine.addPunctualEvent(t - firstFrame); + + mouseA.isGoingToTheOther = true; + + } + else + { + + } + } + else + { + event = false; + } + + } + } + + g2.setColor(Color.red); + nbEvent = 0; + total = 0; + // draw result + for (EventCriteria eventCriteria : eventTimeLine.eventList) + { + nbEvent++; + total += eventCriteria.getLength(); + for (int i = eventCriteria.startFrame; i <= eventCriteria.endFrame; i++) + { + g2.drawLine(i, currentY, i, currentY + stepY); + } + } + + g2.setColor(Color.black); + g2.drawLine(0, currentY, imageChrono.getWidth(), currentY); + String string = "Mouse A Speed > Mouse B Speed & Mouse A getting to B : nbEvent : " + nbEvent + + " total: " + nbFrameToDisplayInSecond(total); + g2.drawString(string, 0, currentY + 12); + imageComponent.stringList.add(string); + + currentY += stepY; + } + { + // Mouse B Speed > Mouse A Speed & Mouse B getting to A + boolean event = false; + float nbEvent = 0; + float total = 0; + + EventTimeLine eventTimeLine = new EventTimeLine("B Speed > A Speed & B GET TO A", + EventType.B_SPEED_HIGHER_THAN_A_SPEED_AND_B_GET_TO_A, TimeLineCategory.USE_BOOLEAN_EVENT); + animal.eventTimeLineList.add(eventTimeLine); + + for (int t = 0; t < tMax; t++) + { + if (mouseARecord.containsKey(t - frameWindow)) + if (mouseBRecord.containsKey(t - frameWindow)) + if (mouseARecord.containsKey(t + frameWindow)) + if (mouseBRecord.containsKey(t + frameWindow)) + if (mouseARecord.containsKey(t)) + if (mouseBRecord.containsKey(t)) + { + MouseInfoRecord mouseAprev = mouseARecord.get(t - frameWindow); + MouseInfoRecord mouseBprev = mouseBRecord.get(t - frameWindow); + MouseInfoRecord mouseAnext = mouseARecord.get(t + frameWindow); + MouseInfoRecord mouseBnext = mouseBRecord.get(t + frameWindow); + MouseInfoRecord mouseA = mouseARecord.get(t); + MouseInfoRecord mouseB = mouseBRecord.get(t); + + double distanceTPrev = mouseAprev.bodyPosition + .distance(mouseBprev.bodyPosition); + double distanceTNext = mouseAnext.bodyPosition + .distance(mouseBnext.bodyPosition); + + if (mouseB.speed > mouseA.speed) + { + if (distanceTPrev > distanceTNext) + { + eventTimeLine.addPunctualEvent(t - firstFrame); + + mouseB.isGoingToTheOther = true; + + } + else + { + + } + } + else + { + event = false; + } + + } + } + g2.setColor(Color.green); + + nbEvent = 0; + total = 0; + // draw result + for (EventCriteria eventCriteria : eventTimeLine.eventList) + { + nbEvent++; + total += eventCriteria.getLength(); + for (int i = eventCriteria.startFrame; i <= eventCriteria.endFrame; i++) + { + g2.drawLine(i, currentY, i, currentY + stepY); + } + } + + g2.setColor(Color.black); + g2.drawLine(0, currentY, imageChrono.getWidth(), currentY); + String string = "Mouse B Speed > Mouse A Speed & Mouse B getting to A : nbEvent : " + nbEvent + + " total: " + nbFrameToDisplayInSecond(total); + g2.drawString(string, 0, currentY + 12); + imageComponent.stringList.add(string); + + currentY += stepY; + } + + { + // Mouse A Speed > Mouse B Speed & Mouse A escaping from to B + + boolean event = false; + float nbEvent = 0; + float total = 0; + + EventTimeLine eventTimeLine = new EventTimeLine("A Speed > B Speed & A escape B", + EventType.A_SPEED_HIGHER_THAN_B_SPEED_AND_A_ESCAPE_B, TimeLineCategory.USE_BOOLEAN_EVENT); + animal.eventTimeLineList.add(eventTimeLine); + + for (int t = 0; t < tMax; t++) + { + if (mouseARecord.containsKey(t - frameWindow)) + if (mouseBRecord.containsKey(t - frameWindow)) + if (mouseARecord.containsKey(t + frameWindow)) + if (mouseBRecord.containsKey(t + frameWindow)) + if (mouseARecord.containsKey(t)) + if (mouseBRecord.containsKey(t)) + { + MouseInfoRecord mouseAprev = mouseARecord.get(t - frameWindow); + MouseInfoRecord mouseBprev = mouseBRecord.get(t - frameWindow); + MouseInfoRecord mouseAnext = mouseARecord.get(t + frameWindow); + MouseInfoRecord mouseBnext = mouseBRecord.get(t + frameWindow); + MouseInfoRecord mouseA = mouseARecord.get(t); + MouseInfoRecord mouseB = mouseBRecord.get(t); + + double distanceTPrev = mouseAprev.bodyPosition + .distance(mouseBprev.bodyPosition); + double distanceTNext = mouseAnext.bodyPosition + .distance(mouseBnext.bodyPosition); + + if (mouseA.speed > mouseB.speed) + { + if (distanceTPrev < distanceTNext) + { + eventTimeLine.addPunctualEvent(t - firstFrame); + + mouseA.isEscaping = true; + + } + else + { + + mouseA.isEscaping = false; + } + } + else + { + + } + + } + } + g2.setColor(Color.red); + + nbEvent = 0; + total = 0; + // draw result + for (EventCriteria eventCriteria : eventTimeLine.eventList) + { + nbEvent++; + total += eventCriteria.getLength(); + for (int i = eventCriteria.startFrame; i <= eventCriteria.endFrame; i++) + { + g2.drawLine(i, currentY, i, currentY + stepY); + } + } + + g2.setColor(Color.black); + g2.drawLine(0, currentY, imageChrono.getWidth(), currentY); + String string = "Mouse A Speed > Mouse B Speed & Mouse A escaping from B : nbEvent : " + nbEvent + + " total: " + nbFrameToDisplayInSecond(total); + g2.drawString(string, 0, currentY + 12); + imageComponent.stringList.add(string); + + currentY += stepY; + } + + { + // Mouse B Speed > Mouse A Speed & Mouse B escaping from A + + boolean event = false; + float nbEvent = 0; + float total = 0; + + EventTimeLine eventTimeLine = new EventTimeLine("B Speed > A Speed & B escape A", + EventType.B_SPEED_HIGHER_THAN_A_SPEED_AND_B_ESCAPE_A, TimeLineCategory.USE_BOOLEAN_EVENT); + animal.eventTimeLineList.add(eventTimeLine); + + for (int t = 0; t < tMax; t++) + { + if (mouseARecord.containsKey(t - frameWindow)) + if (mouseBRecord.containsKey(t - frameWindow)) + if (mouseARecord.containsKey(t + frameWindow)) + if (mouseBRecord.containsKey(t + frameWindow)) + if (mouseARecord.containsKey(t)) + if (mouseBRecord.containsKey(t)) + { + MouseInfoRecord mouseAprev = mouseARecord.get(t - frameWindow); + MouseInfoRecord mouseBprev = mouseBRecord.get(t - frameWindow); + MouseInfoRecord mouseAnext = mouseARecord.get(t + frameWindow); + MouseInfoRecord mouseBnext = mouseBRecord.get(t + frameWindow); + MouseInfoRecord mouseA = mouseARecord.get(t); + MouseInfoRecord mouseB = mouseBRecord.get(t); + + double distanceTPrev = mouseAprev.bodyPosition + .distance(mouseBprev.bodyPosition); + double distanceTNext = mouseAnext.bodyPosition + .distance(mouseBnext.bodyPosition); + + if (mouseB.speed > mouseA.speed) + { + if (distanceTPrev < distanceTNext) + { + + eventTimeLine.addPunctualEvent(t - firstFrame); + + mouseB.isEscaping = true; + + } + else + { + mouseB.isEscaping = false; + + } + } + else + { + + } + + } + } + g2.setColor(Color.green); + + nbEvent = 0; + total = 0; + // draw result + for (EventCriteria eventCriteria : eventTimeLine.eventList) + { + nbEvent++; + total += eventCriteria.getLength(); + for (int i = eventCriteria.startFrame; i <= eventCriteria.endFrame; i++) + { + g2.drawLine(i, currentY, i, currentY + stepY); + } + } + + g2.setColor(Color.black); + g2.drawLine(0, currentY, imageChrono.getWidth(), currentY); + String string = "Mouse B Speed > Mouse A Speed & Mouse B escaping from A : nbEvent : " + nbEvent + + " total: " + nbFrameToDisplayInSecond(total); + g2.drawString(string, 0, currentY + 12); + imageComponent.stringList.add(string); + + currentY += stepY; + } + + { + // Mouse A going to B and finishing with contact starting from no contact. + + EventTimeLine eventTimeLine = new EventTimeLine( + "Mouse A going to B and finishing with contact starting from no contact", + EventType.A_GOTO_B_FINISH_CONTACT_START_NO_CONTACT, TimeLineCategory.USE_BOOLEAN_EVENT); + animal.eventTimeLineList.add(eventTimeLine); + + float nbEvent = 0; + float total = 0; + for (int t = 0; t < tMax; t++) + { + if (mouseARecord.containsKey(t)) + if (mouseBRecord.containsKey(t)) + { + + MouseInfoRecord mouseA = mouseARecord.get(t); + MouseInfoRecord mouseB = mouseBRecord.get(t); + + if (mouseA.distanceIsInferiorToThreshold1) // contact + { + ArrayList<Integer> timeToFill = new ArrayList<Integer>(); + // loop back if there is an approach + for (int t2 = t; t2 > 0; t2--) + { + if (mouseARecord.containsKey(t2)) + { + MouseInfoRecord mouseAt2 = mouseARecord.get(t2); + if (mouseAt2.isGoingToTheOther) + { + timeToFill.add(t2); + + if (!mouseAt2.distanceIsInferiorToThreshold1) + { + for (int t3 = t2; t3 > 0; t3--) + { + if (mouseARecord.containsKey(t3)) + { + MouseInfoRecord mouseAt3 = mouseARecord.get(t3); + if (mouseAt3.isGoingToTheOther) + { + timeToFill.add(t3); + } + else + { + break; + } + } + } + break; + } + + } + else // sortie de la boucle de remontee + { + // check if we started from a position far from the other. + if (mouseAt2.distanceIsInferiorToThreshold1) + timeToFill.clear(); + break; + } + } + } + + // si le time to fill est >0 c'est qu'il a trouve qq chose. + // il faut maintenant avancer dans le temps jusqu a la fin de l evenement + if (timeToFill.size() > 0) + { + for (int t2 = t + 1; t2 < tMax; t2++) + { + MouseInfoRecord mouseAt2 = mouseARecord.get(t2); + if (mouseAt2.isGoingToTheOther) + { + timeToFill.add(t2); + t = t2; + } + else + { + break; + } + } + } + + for (int i = 0; i < timeToFill.size(); i++) + { + int index = timeToFill.get(i); + MouseInfoRecord mouseAt2 = mouseARecord.get(index); + mouseAt2.isGettingToOtherAndTouch = true; + + eventTimeLine.addPunctualEvent(index - firstFrame); + + } + + } + + } + } + + g2.setColor(Color.red); + nbEvent = 0; + total = 0; + // draw result + for (EventCriteria eventCriteria : eventTimeLine.eventList) + { + // System.out.println( "event. StartFrame: " + eventCriteria.startFrame + " EndFrame: " + eventCriteria.endFrame ); + nbEvent++; + total += eventCriteria.getLength(); + for (int i = eventCriteria.startFrame; i <= eventCriteria.endFrame; i++) + { + g2.drawLine(i, currentY, i, currentY + stepY); + } + } + + g2.setColor(Color.black); + g2.drawLine(0, currentY, imageChrono.getWidth(), currentY); + String string = "Mouse A going to B and finishing with contact starting from no contact.: nbEvent : " + + nbEvent + " total: " + nbFrameToDisplayInSecond(total); + g2.drawString(string, 0, currentY + 12); + imageComponent.stringList.add(string); + + currentY += stepY; + } + + { + // Mouse B going to A and finishing with contact and starting from > Threshold Distance. + + EventTimeLine eventTimeLine = new EventTimeLine( + "Mouse B going to A and finishing with contact and starting from no contact", + EventType.B_GOTO_A_FINISH_CONTACT_START_NO_CONTACT, TimeLineCategory.USE_BOOLEAN_EVENT); + animal.eventTimeLineList.add(eventTimeLine); + + float nbVal = 0; + float totalDistance = 0; + float nbEvent = 0; + float total = 0; + for (int t = 0; t < tMax; t++) + { + if (mouseARecord.containsKey(t)) + if (mouseBRecord.containsKey(t)) + { + + MouseInfoRecord mouseA = mouseARecord.get(t); + MouseInfoRecord mouseB = mouseBRecord.get(t); + + if (mouseA.distanceIsInferiorToThreshold1) // contact + { + + ArrayList<Integer> timeToFill = new ArrayList<Integer>(); + // loop back if there is an approach + for (int t2 = t; t2 > 0; t2--) + { + + if (mouseBRecord.containsKey(t2)) + { + MouseInfoRecord mouseBt2 = mouseBRecord.get(t2); + if (mouseBt2.isGoingToTheOther) + { + timeToFill.add(t2); + + if (!mouseBt2.distanceIsInferiorToThreshold1) + { + for (int t3 = t2; t3 > 0; t3--) + { + if (mouseBRecord.containsKey(t3)) + { + MouseInfoRecord mouseBt3 = mouseBRecord.get(t3); + if (mouseBt3.isGoingToTheOther) + { + timeToFill.add(t3); + } + else + { + break; + } + } + } + break; + } + + } + else // sortie de la boucle de remontee + { + // check if we started from a position far from the other. + if (mouseBt2.distanceIsInferiorToThreshold1) + timeToFill.clear(); + break; + } + } + } + + // si le time to fill est >0 c'est qu'il a trouve qq chose. + // il faut maintenant avancer dans le temps jusqu a la fin de l evenement + if (timeToFill.size() > 0) + { + for (int t2 = t + 1; t2 < tMax; t2++) + { + MouseInfoRecord mouseBt2 = mouseBRecord.get(t2); + if (mouseBt2.isGoingToTheOther) + { + timeToFill.add(t2); + t = t2; + } + else + { + break; + } + } + } + + g2.setColor(Color.green); + if (timeToFill.size() > 0) + nbEvent++; + total += timeToFill.size(); + for (int i = 0; i < timeToFill.size(); i++) + { + int index = timeToFill.get(i); + MouseInfoRecord mouseBt2 = mouseBRecord.get(index); + mouseBt2.isGettingToOtherAndTouch = true; + eventTimeLine.addPunctualEvent(index - firstFrame); + + } + + } + + } + } + + g2.setColor(Color.green); + // draw result + + nbEvent = 0; + total = 0; + for (EventCriteria eventCriteria : eventTimeLine.eventList) + { + nbEvent++; + total += eventCriteria.getLength(); + for (int i = eventCriteria.startFrame; i <= eventCriteria.endFrame; i++) + { + g2.drawLine(i, currentY, i, currentY + stepY); + } + } + + g2.setColor(Color.black); + g2.drawLine(0, currentY, imageChrono.getWidth(), currentY); + String string = "Mouse B going to A and finishing with contact starting from no contact.: nbEvent : " + + nbEvent + " total: " + nbFrameToDisplayInSecond(total); + g2.drawString(string, 0, currentY + 12); + imageComponent.stringList.add(string); + + currentY += stepY; + } + + { + // Mouse A escaping after contact. finish with out threshold. + + EventTimeLine eventTimeLine = new EventTimeLine( + "Mouse A escaping after contact. finish with out threshold.", + EventType.A_ESCAPE_AFTER_CONTACT_FINISH_WITH_NO_CONTACT, TimeLineCategory.USE_BOOLEAN_EVENT); + animal.eventTimeLineList.add(eventTimeLine); + + float nbVal = 0; + float totalDistance = 0; + float nbEvent = 0; + float total = 0; + + for (int t = 0; t < tMax; t++) + { + if (mouseARecord.containsKey(t)) + if (mouseBRecord.containsKey(t)) + { + + MouseInfoRecord mouseA = mouseARecord.get(t); + MouseInfoRecord mouseB = mouseBRecord.get(t); + + if (mouseA.distanceIsInferiorToThreshold1) // contact + { + ArrayList<Integer> timeToFill = new ArrayList<Integer>(); + // loop back if there is an approach + for (int t2 = t; t2 < Integer.MAX_VALUE; t2++) + { + if (mouseARecord.containsKey(t2)) + { + MouseInfoRecord mouseAt2 = mouseARecord.get(t2); + if (mouseAt2.isEscaping) + { + timeToFill.add(t2); + + if (!mouseAt2.distanceIsInferiorToThreshold1) + { + + for (int t3 = t2; t3 < tMax; t3++) + { + if (mouseARecord.containsKey(t3)) + { + MouseInfoRecord mouseAt3 = mouseARecord.get(t3); + if (mouseAt3.isEscaping) + { + timeToFill.add(t3); + } + else + { + break; + } + } + } + break; + } + + } + else // sortie de la boucle de remontee + { + // check if we started from a position far from the other. + if (mouseAt2.distanceIsInferiorToThreshold1) + timeToFill.clear(); + break; + } + } + else + { + break; + } + } + g2.setColor(Color.red); + if (timeToFill.size() > 0) + nbEvent++; + total += timeToFill.size(); + + for (int i = 0; i < timeToFill.size(); i++) + { + int index = timeToFill.get(i); + MouseInfoRecord mouseAt2 = mouseARecord.get(index); + mouseAt2.isEscapingFromOtherAndUnTouch = true; + eventTimeLine.addPunctualEvent(index - firstFrame); + + } + t += timeToFill.size(); + } + + } + } + g2.setColor(Color.red); + + // draw result + nbEvent = 0; + total = 0; + for (EventCriteria eventCriteria : eventTimeLine.eventList) + { + nbEvent++; + total += eventCriteria.getLength(); + for (int i = eventCriteria.startFrame; i <= eventCriteria.endFrame; i++) + { + g2.drawLine(i, currentY, i, currentY + stepY); + } + } + + g2.setColor(Color.black); + g2.drawLine(0, currentY, imageChrono.getWidth(), currentY); + String string = "Mouse A escaping after contact and finish out of distance threshold. : nbEvent : " + + nbEvent + " total: " + nbFrameToDisplayInSecond(total); + g2.drawString(string, 0, currentY + 12); + imageComponent.stringList.add(string); + + currentY += stepY; + } + + { + // Mouse B escaping after contact. finish with out threshold. + + EventTimeLine eventTimeLine = new EventTimeLine( + "Mouse B escaping after contact. finish with out threshold.", + EventType.B_ESCAPE_AFTER_CONTACT_FINISH_WITH_NO_CONTACT, TimeLineCategory.USE_BOOLEAN_EVENT); + animal.eventTimeLineList.add(eventTimeLine); + + float nbVal = 0; + float totalDistance = 0; + float nbEvent = 0; + float total = 0; + for (int t = 0; t < tMax; t++) + { + if (mouseARecord.containsKey(t)) + if (mouseBRecord.containsKey(t)) + { + + MouseInfoRecord mouseA = mouseARecord.get(t); + MouseInfoRecord mouseB = mouseBRecord.get(t); + + if (mouseA.distanceIsInferiorToThreshold1) // contact + { + ArrayList<Integer> timeToFill = new ArrayList<Integer>(); + // loop back if there is an approach + for (int t2 = t; t2 < Integer.MAX_VALUE; t2++) + { + if (mouseBRecord.containsKey(t2)) + { + MouseInfoRecord mouseBt2 = mouseBRecord.get(t2); + if (mouseBt2.isEscaping) + { + timeToFill.add(t2); + + if (!mouseBt2.distanceIsInferiorToThreshold1) + { + + for (int t3 = t2; t3 < tMax; t3++) + { + if (mouseBRecord.containsKey(t3)) + { + MouseInfoRecord mouseBt3 = mouseBRecord.get(t3); + if (mouseBt3.isEscaping) + { + timeToFill.add(t3); + } + else + { + break; + } + } + } + break; + } + + } + else + { + + if (mouseBt2.distanceIsInferiorToThreshold1) + timeToFill.clear(); + break; + } + } + else + { + break; + } + } + g2.setColor(Color.green); + if (timeToFill.size() > 0) + nbEvent++; + total += timeToFill.size(); + + for (int i = 0; i < timeToFill.size(); i++) + { + int index = timeToFill.get(i); + MouseInfoRecord mouseBt2 = mouseBRecord.get(index); + mouseBt2.isEscapingFromOtherAndUnTouch = true; + + eventTimeLine.addPunctualEvent(index - firstFrame); + + } + t += timeToFill.size(); + } + + } + } + g2.setColor(Color.green); + + nbEvent = 0; + total = 0; + for (EventCriteria eventCriteria : eventTimeLine.eventList) + { + nbEvent++; + total += eventCriteria.getLength(); + for (int i = eventCriteria.startFrame; i <= eventCriteria.endFrame; i++) + { + g2.drawLine(i, currentY, i, currentY + stepY); + } + } + + g2.setColor(Color.black); + g2.drawLine(0, currentY, imageChrono.getWidth(), currentY); + String string = "Mouse B escaping after contact and finish out of distance threshold : nbEvent : " + + nbEvent + " total: " + nbFrameToDisplayInSecond(total); + g2.drawString(string, 0, currentY + 12); + imageComponent.stringList.add(string); + + currentY += stepY; + } + + { + // Mouse A get to mouse B and B escape with threshold distance in and out. + + EventTimeLine eventTimeLine = new EventTimeLine("A get to B and B escape threshold in and out", + EventType.A_GOTO_B_AND_B_ESCAPE_THRESHOLD_IN_OUT, TimeLineCategory.USE_BOOLEAN_EVENT); + animal.eventTimeLineList.add(eventTimeLine); + + float nbVal = 0; + float totalDistance = 0; + float nbEvent = 0; + float total = 0; + for (int t = 0; t < tMax; t++) + { + if (mouseARecord.containsKey(t)) + if (mouseBRecord.containsKey(t)) + { + + MouseInfoRecord mouseA = mouseARecord.get(t); + MouseInfoRecord mouseB = mouseBRecord.get(t); + + if (mouseA.isGettingToOtherAndTouch) // contact + { + ArrayList<Integer> timeToFill = new ArrayList<Integer>(); + + boolean step1ok = false; + boolean step2ok = false; + boolean step3ok = false; + + int seeker = t; + + // STEP 1 + + for (int t2 = seeker; t2 < tMax; t2++) + { + seeker = t2; + if (mouseARecord.containsKey(t2)) + { + MouseInfoRecord mouseAt2 = mouseARecord.get(t2); + if (mouseAt2.isGettingToOtherAndTouch) + { + timeToFill.add(t2); + } + else // sortie de la boucle de remontee + { + step1ok = true; + break; + } + } + } + + // STEP 2 + + for (int t2 = seeker; t2 < tMax; t2++) + { + seeker = t2; + if (mouseARecord.containsKey(t2)) + { + MouseInfoRecord mouseAt2 = mouseARecord.get(t2); + if (mouseAt2.distanceIsInferiorToThreshold1) + { + timeToFill.add(t2); + } + else // sortie de la boucle de remontee + { + step2ok = true; + break; + } + } + } + + // STEP 3 + + for (int t2 = seeker; t2 < tMax; t2++) + { + seeker = t2; + if (mouseBRecord.containsKey(t2)) + { + MouseInfoRecord mouseBt2 = mouseBRecord.get(t2); + if (mouseBt2.isEscapingFromOtherAndUnTouch) + { + timeToFill.add(t2); + step3ok = true; + } + else // sortie de la boucle de remontee + { + break; + } + } + } + + if (!(step1ok && step2ok && step3ok)) + { + timeToFill.clear(); + } + + g2.setColor(Color.red); + if (timeToFill.size() > 0) + nbEvent++; + total += timeToFill.size(); + + for (int i = 0; i < timeToFill.size(); i++) + { + int index = timeToFill.get(i); + MouseInfoRecord mouseBt2 = mouseBRecord.get(index); + mouseBt2.isEscapingFromOtherAndUnTouch = true; + + eventTimeLine.addPunctualEvent(index - firstFrame); + + mouseARecord.get(index).mouseGetToOtherMouseAndOtherEscapeInOut = true; + } + t += timeToFill.size(); + } + + } + } + + g2.setColor(Color.red); + nbEvent = 0; + total = 0; + // draw result + for (EventCriteria eventCriteria : eventTimeLine.eventList) + { + nbEvent++; + total += eventCriteria.getLength(); + for (int i = eventCriteria.startFrame; i <= eventCriteria.endFrame; i++) + { + g2.drawLine(i, currentY, i, currentY + stepY); + } + } + + g2.setColor(Color.black); + g2.drawLine(0, currentY, imageChrono.getWidth(), currentY); + g2.drawLine(0, currentY + 1, imageChrono.getWidth(), currentY + 1); + + String string = "Mouse A get to mouse B and B escape with threshold distance in and out : nbEvent : " + + nbEvent + " total: " + nbFrameToDisplayInSecond(total); + g2.drawString(string, 0, currentY + 12); + imageComponent.stringList.add(string); + + currentY += stepY; + } + + { + // Mouse B get to mouse A and A escape with threshold distance in and out + + EventTimeLine eventTimeLine = new EventTimeLine("B get to A and A escape threshold in and out", + EventType.B_GOTO_A_AND_A_ESCAPE_THRESHOLD_IN_OUT, TimeLineCategory.USE_BOOLEAN_EVENT); + animal.eventTimeLineList.add(eventTimeLine); + + float nbVal = 0; + float totalDistance = 0; + float nbEvent = 0; + float total = 0; + + for (int t = 0; t < tMax; t++) + { + if (mouseARecord.containsKey(t)) + if (mouseBRecord.containsKey(t)) + { + + MouseInfoRecord mouseA = mouseARecord.get(t); + MouseInfoRecord mouseB = mouseBRecord.get(t); + + if (mouseB.isGettingToOtherAndTouch) // contact + { + ArrayList<Integer> timeToFill = new ArrayList<Integer>(); + // loop forward to the contact. + + boolean step1ok = false; + boolean step2ok = false; + boolean step3ok = false; + + int seeker = t; + + // STEP 1 + + for (int t2 = seeker; t2 < tMax; t2++) + { + seeker = t2; + if (mouseBRecord.containsKey(t2)) + { + MouseInfoRecord mouseBt2 = mouseBRecord.get(t2); + if (mouseBt2.isGettingToOtherAndTouch) + { + timeToFill.add(t2); + } + else // sortie de la boucle de remontee + { + step1ok = true; + break; + } + } + } + + // STEP 2 + + for (int t2 = seeker; t2 < tMax; t2++) + { + seeker = t2; + if (mouseBRecord.containsKey(t2)) + { + MouseInfoRecord mouseBt2 = mouseBRecord.get(t2); + if (mouseBt2.distanceIsInferiorToThreshold1) + { + timeToFill.add(t2); + } + else // sortie de la boucle de remontee + { + step2ok = true; + break; + } + } + } + + // STEP 3 + + for (int t2 = seeker; t2 < tMax; t2++) + { + seeker = t2; + if (mouseARecord.containsKey(t2)) + { + MouseInfoRecord mouseAt2 = mouseARecord.get(t2); + if (mouseAt2.isEscapingFromOtherAndUnTouch) + { + timeToFill.add(t2); + step3ok = true; + } + else // sortie de la boucle de remontee + { + break; + } + } + } + + if (!(step1ok && step2ok && step3ok)) + { + timeToFill.clear(); + } + + g2.setColor(Color.green); + if (timeToFill.size() > 0) + nbEvent++; + total += timeToFill.size(); + + for (int i = 0; i < timeToFill.size(); i++) + { + int index = timeToFill.get(i); + MouseInfoRecord mouseAt2 = mouseARecord.get(index); + mouseAt2.isEscapingFromOtherAndUnTouch = true; + + eventTimeLine.addPunctualEvent(index - firstFrame); + + mouseBRecord.get(index).mouseGetToOtherMouseAndOtherEscapeInOut = true; + } + t += timeToFill.size(); + } + + } + } + g2.setColor(Color.green); + nbEvent = 0; + total = 0; + // draw result + for (EventCriteria eventCriteria : eventTimeLine.eventList) + { + nbEvent++; + total += eventCriteria.getLength(); + for (int i = eventCriteria.startFrame; i <= eventCriteria.endFrame; i++) + { + g2.drawLine(i, currentY, i, currentY + stepY); + } + } + g2.setColor(Color.black); + g2.drawLine(0, currentY, imageChrono.getWidth(), currentY); + String string = "Mouse B get to mouse A and A escape with threshold distance in and out : nbEvent : " + + nbEvent + " total: " + nbFrameToDisplayInSecond(total); + g2.drawString(string, 0, currentY + 12); + imageComponent.stringList.add(string); + + currentY += stepY; + } + + { + // Mouse A get to mouse B and A escape with threshold distance in and out. + + EventTimeLine eventTimeLine = new EventTimeLine("A get to B and A escape threshold in and out", + EventType.A_GOTO_B_AND_A_ESCAPE_THRESHOLD_IN_OUT, TimeLineCategory.USE_BOOLEAN_EVENT); + animal.eventTimeLineList.add(eventTimeLine); + + float nbVal = 0; + float totalDistance = 0; + float nbEvent = 0; + float total = 0; + for (int t = 0; t < tMax; t++) + { + if (mouseARecord.containsKey(t)) + if (mouseBRecord.containsKey(t)) + { + + MouseInfoRecord mouseA = mouseARecord.get(t); + MouseInfoRecord mouseB = mouseBRecord.get(t); + + if (mouseA.isGettingToOtherAndTouch) // contact + { + ArrayList<Integer> timeToFill = new ArrayList<Integer>(); + // loop forward to the contact. + + boolean step1ok = false; + boolean step2ok = false; + boolean step3ok = false; + + int seeker = t; + + // STEP 1 + + for (int t2 = seeker; t2 < tMax; t2++) + { + seeker = t2; + if (mouseARecord.containsKey(t2)) + { + MouseInfoRecord mouseAt2 = mouseARecord.get(t2); + if (mouseAt2.isGettingToOtherAndTouch) + { + timeToFill.add(t2); + step1ok = true; // maintenant ici + } + else // sortie de la boucle de remontee + { + // step1ok = true; avant la + break; + } + } + } + + // STEP 2 + + for (int t2 = seeker; t2 < tMax; t2++) + { + seeker = t2; + if (mouseARecord.containsKey(t2)) + { + MouseInfoRecord mouseAt2 = mouseARecord.get(t2); + if (mouseAt2.distanceIsInferiorToThreshold1) + { + timeToFill.add(t2); + step2ok = true; // mainetnant ici + } + else // sortie de la boucle de remontee + { + // step2ok = true; avant la + break; + } + } + } + + // STEP 3 + + for (int t2 = seeker; t2 < tMax; t2++) + { + seeker = t2; + if (mouseARecord.containsKey(t2)) + { + MouseInfoRecord mouseAt2 = mouseARecord.get(t2); + if (mouseAt2.isEscapingFromOtherAndUnTouch) + { + timeToFill.add(t2); + step3ok = true; + } + else // sortie de la boucle de remontee + { + break; + } + } + } + + if (!(step1ok && step2ok && step3ok)) + { + timeToFill.clear(); + } + + g2.setColor(Color.red); + if (timeToFill.size() > 0) + nbEvent++; + total += timeToFill.size(); + for (int i = 0; i < timeToFill.size(); i++) + { + int index = timeToFill.get(i); + MouseInfoRecord mouseBt2 = mouseBRecord.get(index); + mouseBt2.isEscapingFromOtherAndUnTouch = true; + + eventTimeLine.addPunctualEvent(index - firstFrame); + + mouseARecord.get(index).mouseGetToOtherMouseAndEscapeInOut = true; + } + t += timeToFill.size(); + } + + } + } + g2.setColor(Color.red); + + nbEvent = 0; + total = 0; + // draw result + for (EventCriteria eventCriteria : eventTimeLine.eventList) + { + nbEvent++; + total += eventCriteria.getLength(); + for (int i = eventCriteria.startFrame; i <= eventCriteria.endFrame; i++) + { + g2.drawLine(i, currentY, i, currentY + stepY); + } + } + + g2.setColor(Color.black); + g2.drawLine(0, currentY, imageChrono.getWidth(), currentY); + g2.drawLine(0, currentY + 1, imageChrono.getWidth(), currentY + 1); + String string = "Mouse A get to mouse B and A escape with threshold distance in and out : nbEvent : " + + nbEvent + " total: " + nbFrameToDisplayInSecond(total); + g2.drawString(string, 0, currentY + 12); + imageComponent.stringList.add(string); + + currentY += stepY; + } + + { + // Mouse B get to mouse A and B escape with threshold distance in and out + + EventTimeLine eventTimeLine = new EventTimeLine("B get to A and B escape threshold in and out", + EventType.B_GOTO_A_AND_B_ESCAPE_THRESHOLD_IN_OUT, TimeLineCategory.USE_BOOLEAN_EVENT); + animal.eventTimeLineList.add(eventTimeLine); + + float nbVal = 0; + float totalDistance = 0; + float nbEvent = 0; + float total = 0; + + for (int t = 0; t < tMax; t++) + { + if (mouseARecord.containsKey(t)) + if (mouseBRecord.containsKey(t)) + { + + MouseInfoRecord mouseA = mouseARecord.get(t); + MouseInfoRecord mouseB = mouseBRecord.get(t); + + if (mouseB.isGettingToOtherAndTouch) // contact + { + ArrayList<Integer> timeToFill = new ArrayList<Integer>(); + // loop forward to the contact. + + boolean step1ok = false; + boolean step2ok = false; + boolean step3ok = false; + + int seeker = t; + + // STEP 1 + + for (int t2 = seeker; t2 < tMax; t2++) + { + seeker = t2; + if (mouseBRecord.containsKey(t2)) + { + MouseInfoRecord mouseBt2 = mouseBRecord.get(t2); + if (mouseBt2.isGettingToOtherAndTouch) + { + timeToFill.add(t2); + step1ok = true; // maintenant ici + } + else // sortie de la boucle de remontee + { + // avant ici step1ok = true; + break; + } + } + } + + // STEP 2 + + for (int t2 = seeker; t2 < tMax; t2++) + { + seeker = t2; + if (mouseBRecord.containsKey(t2)) + { + MouseInfoRecord mouseBt2 = mouseBRecord.get(t2); + if (mouseBt2.distanceIsInferiorToThreshold1) + { + timeToFill.add(t2); + step2ok = true; // mis ici + } + else // sortie de la boucle de remontee + { + // step2ok = true; avant ici + break; + } + } + } + + // STEP 3 + + for (int t2 = seeker; t2 < tMax; t2++) + { + seeker = t2; + if (mouseBRecord.containsKey(t2)) + { + MouseInfoRecord mouseBt2 = mouseBRecord.get(t2); + if (mouseBt2.isEscapingFromOtherAndUnTouch) + { + timeToFill.add(t2); + step3ok = true; + } + else // sortie de la boucle de remontee + { + break; + } + } + } + + if (!(step1ok && step2ok && step3ok)) + { + timeToFill.clear(); + } + + g2.setColor(Color.green); + if (timeToFill.size() > 0) + nbEvent++; + total += timeToFill.size(); + + for (int i = 0; i < timeToFill.size(); i++) + { + int index = timeToFill.get(i); + MouseInfoRecord mouseAt2 = mouseARecord.get(index); + mouseAt2.isEscapingFromOtherAndUnTouch = true; + eventTimeLine.addPunctualEvent(index - firstFrame); + + mouseBRecord.get(index).mouseGetToOtherMouseAndEscapeInOut = true; + } + t += timeToFill.size(); + + } + + } + } + g2.setColor(Color.green); + nbEvent = 0; + total = 0; + // draw result + for (EventCriteria eventCriteria : eventTimeLine.eventList) + { + nbEvent++; + total += eventCriteria.getLength(); + for (int i = eventCriteria.startFrame; i <= eventCriteria.endFrame; i++) + { + g2.drawLine(i, currentY, i, currentY + stepY); + } + } + + g2.setColor(Color.black); + g2.drawLine(0, currentY, imageChrono.getWidth(), currentY); + String string = "Mouse B get to mouse A and B escape with threshold distance in and out : nbEvent : " + + nbEvent + " total: " + nbFrameToDisplayInSecond(total); + g2.drawString(string, 0, currentY + 12); + imageComponent.stringList.add(string); + + currentY += stepY; + } + + g2.drawLine(0, currentY, imageChrono.getWidth(), currentY); + + { + // Event de poursuite. + // A Poursuit B + // = + // A est en mouvement + // B est en mouvement + // A est derriere B ou A est sur le cote de B + // Distance A-B inferieure a Threshold 2 ( le plus loin ) + + EventTimeLine eventTimeLine = new EventTimeLine("A follow B", EventType.A_FOLLOW_B, + TimeLineCategory.USE_BOOLEAN_EVENT); + animal.eventTimeLineList.add(eventTimeLine); + + float nbVal = 0; + float totalDistance = 0; + float nbEvent = 0; + float total = 0; + + EventCriteria currentCriteria = null; + + for (int t = 0; t < tMax; t++) + { + if (mouseARecord.containsKey(t)) + if (mouseBRecord.containsKey(t)) + { + + MouseInfoRecord mouseA = mouseARecord.get(t); + MouseInfoRecord mouseB = mouseBRecord.get(t); + + double distanceHeadABodyB = mouseA.headPosition.distanceSq(mouseB.bodyPosition); + double distanceHeadAHeadB = mouseA.headPosition.distanceSq(mouseB.headPosition); + double distanceBodyABodyB = mouseA.bodyPosition.distanceSq(mouseB.bodyPosition); + double distanceBodyAHeadB = mouseA.bodyPosition.distanceSq(mouseB.headPosition); + + if (mouseB.distanceIsInferiorToThreshold2 // moins precis mais moins de bruit + + && mouseA.speed > SPEED_THRESHOLD_2 && mouseB.speed > SPEED_THRESHOLD_2 + && (mouseA.isBehindTheOther || mouseA.isBesideTheOther) + + ) // contact threshold 2 + { + eventTimeLine.addPunctualEvent(t - firstFrame); + + } + + } + } + // filter results + + eventTimeLine.removeEventLessThanLength(3); + + g2.setColor(Color.RED); + // display result. + nbEvent = 0; + total = 0; + // draw result + for (EventCriteria eventCriteria : eventTimeLine.eventList) + { + nbEvent++; + total += eventCriteria.getLength(); + for (int i = eventCriteria.startFrame; i <= eventCriteria.endFrame; i++) + { + g2.drawLine(i, currentY, i, currentY + stepY); + } + } + + g2.setColor(Color.black); + g2.drawLine(0, currentY, imageChrono.getWidth(), currentY); + String string = "Mouse A poursuit B : nbEvent : " + nbEvent + " total time: " + total / FPS + "s"; + g2.drawString(string, 0, currentY + 12); + imageComponent.stringList.add(string); + + currentY += stepY; + } + + g2.drawLine(0, currentY, imageChrono.getWidth(), currentY); + + { + // A est derriere B et B est derriere A + // A est à l'arret et B est à l'arret + // distance superieure a Threshold 2 + // back to back + // angle formé inferieur a ANGLE dans le code ( 0.52d Rad ) + + EventTimeLine eventTimeLine = new EventTimeLine("back to back", EventType.A_BEHIND_B_AND_B_BEHIND_A, + TimeLineCategory.USE_BOOLEAN_EVENT); + animal.eventTimeLineList.add(eventTimeLine); + + float nbVal = 0; + float totalDistance = 0; + float nbEvent = 0; + float total = 0; + + EventCriteria currentCriteria = null; + + for (int t = 0; t < tMax; t++) + { + if (mouseARecord.containsKey(t)) + if (mouseBRecord.containsKey(t)) + { + + MouseInfoRecord mouseA = mouseARecord.get(t); + MouseInfoRecord mouseB = mouseBRecord.get(t); + + double distanceHeadABodyB = mouseA.headPosition.distanceSq(mouseB.bodyPosition); + double distanceHeadAHeadB = mouseA.headPosition.distanceSq(mouseB.headPosition); + double distanceBodyABodyB = mouseA.bodyPosition.distanceSq(mouseB.bodyPosition); + double distanceBodyAHeadB = mouseA.bodyPosition.distanceSq(mouseB.headPosition); + + double VAx = mouseA.headPosition.getX() - mouseA.bodyPosition.getX(); + double VAy = mouseA.headPosition.getY() - mouseA.bodyPosition.getY(); + double angleA = Math.atan2(VAy, VAx); + + double VBx = mouseB.headPosition.getX() - mouseB.bodyPosition.getX(); + double VBy = mouseB.headPosition.getY() - mouseB.bodyPosition.getY(); + double angleB = Math.atan2(VBy, VBx); + + // angle fait par le segment qui va de la souris A a la souris B. + + double VABx = mouseB.bodyPosition.getX() - mouseA.bodyPosition.getX(); + double VABy = mouseB.bodyPosition.getY() - mouseA.bodyPosition.getY(); + double angleAB = Math.atan2(VABy, VABx); + + angleB = angleB - Math.PI; + + // on recale les angles pour les rendres comparables + + // recherche de la plus petite difference entre les angles. + + double minAngle = Double.MAX_VALUE; + for (double a = -4; a < 5; a++) + { + double testVal = Math.abs(angleB + 2 * Math.PI * a - angleA); + if (testVal < minAngle) + minAngle = testVal; + } + + double minAngleABwithA = Double.MAX_VALUE; + for (double a = -4; a < 5; a++) + { + double testVal = Math.abs(angleA + Math.PI * a - angleAB); + if (testVal < minAngleABwithA) + minAngleABwithA = testVal; + } + + double minAngleABwithB = Double.MAX_VALUE; + for (double a = -4; a < 5; a++) + { + double testVal = Math.abs(angleB + Math.PI * a - angleAB); + if (testVal < minAngleABwithB) + minAngleABwithB = testVal; + } + + if (mouseA.speed < SPEED_THRESHOLD_1 && mouseB.speed < SPEED_THRESHOLD_1) + if (!mouseA.distanceIsInferiorToThreshold2) // distance > Threshold 2 + if (minAngle < 0.52d && mouseA.isBehindTheOther && mouseB.isBehindTheOther) // && !mouseA.distanceIsInferiorToThreshold1 ) + // // premier argument trouve angle opposé et + // l'autre force culcul + if (minAngleABwithA < 0.52d) + if (minAngleABwithB < 0.52d) + { + eventTimeLine.addPunctualEvent(t - firstFrame); + } + + } + } + // filter results + + eventTimeLine.removeEventLessThanLength(3); + + g2.setColor(Color.gray); + // display result. + nbEvent = 0; + total = 0; + // draw result + for (EventCriteria eventCriteria : eventTimeLine.eventList) + { + nbEvent++; + total += eventCriteria.getLength(); + for (int i = eventCriteria.startFrame; i <= eventCriteria.endFrame; i++) + { + g2.drawLine(i, currentY, i, currentY + stepY); + } + } + + g2.setColor(Color.black); + g2.drawLine(0, currentY, imageChrono.getWidth(), currentY); + String string = "Back to back: nbEvent : " + nbEvent + " total time: " + total / FPS + "s"; + g2.drawString(string, 0, currentY + 12); + imageComponent.stringList.add(string); + + currentY += stepY; + } + + g2.drawLine(0, currentY, imageChrono.getWidth(), currentY); + + // A regarde l'autre souris + // + { + EventTimeLine eventTimeLine = new EventTimeLine("A can see B", EventType.A_CAN_SEE_B, + TimeLineCategory.USE_BOOLEAN_EVENT); + animal.eventTimeLineList.add(eventTimeLine); + + float nbVal = 0; + float totalDistance = 0; + float nbEvent = 0; + float total = 0; + + EventCriteria currentCriteria = null; + + for (int t = 0; t < tMax; t++) + { + if (mouseARecord.containsKey(t)) + if (mouseBRecord.containsKey(t)) + { + + // --------------------- + + MouseInfoRecord mouseA = mouseARecord.get(t); + MouseInfoRecord mouseB = mouseBRecord.get(t); + + double distanceHeadABodyB = mouseA.headPosition.distanceSq(mouseB.bodyPosition); + double distanceHeadAHeadB = mouseA.headPosition.distanceSq(mouseB.headPosition); + double distanceBodyABodyB = mouseA.bodyPosition.distanceSq(mouseB.bodyPosition); + double distanceBodyAHeadB = mouseA.bodyPosition.distanceSq(mouseB.headPosition); + + double VAx = mouseA.headPosition.getX() - mouseA.bodyPosition.getX(); + double VAy = mouseA.headPosition.getY() - mouseA.bodyPosition.getY(); + double angleA = Math.atan2(VAy, VAx); + + // teste A dans la vue. + + double VABx = mouseA.headPosition.getX() - mouseB.headPosition.getX(); + double VABy = mouseA.headPosition.getY() - mouseB.headPosition.getY(); + double angleBA = Math.atan2(VABy, VABx) + Math.PI; + + boolean eventIsOk = true; + + // if ( angleMin( angleBA , angleB ) < Math.PI / 2f ) + if (angleMin(angleBA, angleA) < demiVisionDeSouris) + { + // eventTimeLine.addPunctualEvent(t - firstFrame ); + } + else + { + eventIsOk = false; + } + + if (mouseA.distanceIsInferiorToThreshold2) + { + eventIsOk = false; + } + // ------------------------ + // flag l'event s'il est bon. + if (eventIsOk) + { + eventTimeLine.addPunctualEvent(t - firstFrame); + } + + } + } + // filter results + + eventTimeLine.removeEventLessThanLength(3); + + g2.setColor(Color.RED); + // display result. + nbEvent = 0; + total = 0; + // draw result + for (EventCriteria eventCriteria : eventTimeLine.eventList) + { + nbEvent++; + total += eventCriteria.getLength(); + for (int i = eventCriteria.startFrame; i <= eventCriteria.endFrame; i++) + { + g2.drawLine(i, currentY, i, currentY + stepY); + } + } + + g2.setColor(Color.black); + g2.drawLine(0, currentY, imageChrono.getWidth(), currentY); + String string = "Mouse A can see B: nbEvent : " + nbEvent + " total time: " + total / FPS + "s"; + g2.drawString(string, 0, currentY + 12); + imageComponent.stringList.add(string); + + currentY += stepY; + + } + + // B regarde l'autre souris + // + { + EventTimeLine eventTimeLine = new EventTimeLine("B can see A", EventType.B_CAN_SEE_A, + TimeLineCategory.USE_BOOLEAN_EVENT); + animal.eventTimeLineList.add(eventTimeLine); + + float nbVal = 0; + float totalDistance = 0; + float nbEvent = 0; + float total = 0; + + EventCriteria currentCriteria = null; + + for (int t = 0; t < tMax; t++) + { + if (mouseARecord.containsKey(t)) + if (mouseBRecord.containsKey(t)) + { + + MouseInfoRecord mouseA = mouseARecord.get(t); + MouseInfoRecord mouseB = mouseBRecord.get(t); + + double distanceHeadABodyB = mouseA.headPosition.distanceSq(mouseB.bodyPosition); + double distanceHeadAHeadB = mouseA.headPosition.distanceSq(mouseB.headPosition); + double distanceBodyABodyB = mouseA.bodyPosition.distanceSq(mouseB.bodyPosition); + double distanceBodyAHeadB = mouseA.bodyPosition.distanceSq(mouseB.headPosition); + + double VBx = mouseB.headPosition.getX() - mouseB.bodyPosition.getX(); + double VBy = mouseB.headPosition.getY() - mouseB.bodyPosition.getY(); + double angleB = Math.atan2(VBy, VBx); + + // teste A dans la vue. + + double VBAx = mouseB.headPosition.getX() - mouseA.headPosition.getX(); + double VBAy = mouseB.headPosition.getY() - mouseA.headPosition.getY(); + double angleBA = Math.atan2(VBAy, VBAx) + Math.PI; + + boolean eventIsOk = true; + + if (angleMin(angleBA, angleB) < demiVisionDeSouris) + { + + } + else + { + eventIsOk = false; + } + + // flag l'event s'il est bon. + if (eventIsOk) + { + eventTimeLine.addPunctualEvent(t - firstFrame); + } + + } + } + // filter results + + eventTimeLine.removeEventLessThanLength(3); + + g2.setColor(Color.GREEN); + // display result. + nbEvent = 0; + total = 0; + // draw result + for (EventCriteria eventCriteria : eventTimeLine.eventList) + { + nbEvent++; + total += eventCriteria.getLength(); + for (int i = eventCriteria.startFrame; i <= eventCriteria.endFrame; i++) + { + g2.drawLine(i, currentY, i, currentY + stepY); + } + } + + g2.setColor(Color.black); + g2.drawLine(0, currentY, imageChrono.getWidth(), currentY); + String string = "Mouse B can see A: nbEvent : " + nbEvent + " total time: " + total / FPS + "s"; + g2.drawString(string, 0, currentY + 12); + imageComponent.stringList.add(string); + + currentY += stepY; + + } + + g2.drawLine(0, currentY, imageChrono.getWidth(), currentY); + + currentY = loadExtraLabelXMLFile(file, currentY, g2); + currentY = loadExtraLabelAviSoftTXTFile(file, currentY, g2); + + Icy.getMainInterface().getSwimmingPool().add(swimmingObject); + + } + + private File getExtraXMLFile(File originalFile) + { + File extraFile = new File(FileUtil.setExtension(file.getAbsolutePath(), ".extra.xml")); + return extraFile; + } + + private File getExtraAviSoftTXTFile(File originalFile) + { + File extraFile = new File(FileUtil.setExtension(file.getAbsolutePath(), ".avisoft.txt")); + return extraFile; + } + + private File getExtraAviSoftXLSFile(File originalFile) + { + File extraFile = new File(FileUtil.setExtension(file.getAbsolutePath(), ".avisoft.xls")); + return extraFile; + } + + private int getNbExtraEvent(File originalFile) + { + + int nbExtraEvent = 0; + + { + File extraFile = getExtraXMLFile(originalFile); + if (extraFile.exists()) + { + + Document xmlDocument = XMLUtil.loadDocument(extraFile); + ArrayList<Element> labelElementList = XMLUtil.getElements(XMLUtil.getRootElement(xmlDocument), + "LABEL"); + + System.out.println("Number of extra user labels (XML): " + labelElementList.size()); + + nbExtraEvent += labelElementList.size(); + + } + } + + { + File extraFile = getExtraAviSoftTXTFile(originalFile); + if (extraFile.exists()) + { + // nlabel type duration interval starttime endtime pstart_time pstart pstart_ampl pend_time pend pend_ampl pmin_time pmin pmin_ampl + // pmax_time pmax pmax_ampl + + // Pattern pattern = Pattern.compile("(\t)(.*?)(\t)"); // finds string between tabs. + int nbElement = 0; + + HashMap<String, Integer> eventFoundHashMap = new HashMap<String, Integer>(); + + try + { + + Scanner scanner = new Scanner(extraFile); + + while (scanner.hasNextLine()) + { + int line = scanner.nextInt(); + String labelName = scanner.next(); + + // if ( labelName == null ) continue; + + int nbLabelWithThisName = 0; + if (eventFoundHashMap.containsKey(labelName)) + { + nbLabelWithThisName = eventFoundHashMap.get(labelName); + } + eventFoundHashMap.put(labelName, nbLabelWithThisName + 1); + + scanner.nextLine(); + } + + for (String labelName : eventFoundHashMap.keySet()) + { + System.out.println("Label Name : " + labelName + " #" + eventFoundHashMap.get(labelName)); + } + + nbElement += eventFoundHashMap.keySet().size(); + + } + catch (FileNotFoundException e) + { + e.printStackTrace(); + } + + System.out.println("Number of extra user labels (AviSoft TXT): " + nbElement); + + nbExtraEvent += nbElement; + } + } + + { + File extraFile = getExtraAviSoftXLSFile(originalFile); + if (extraFile.exists()) + { + // nlabel type duration interval starttime + + // Pattern pattern = Pattern.compile("(\t)(.*?)(\t)"); // finds string between tabs. + int nbElement = 0; + + HashMap<String, Integer> eventFoundHashMap = new HashMap<String, Integer>(); + + try + { + + Workbook workbook = Workbook.getWorkbook(extraFile); + + Sheet sheet = workbook.getSheet(0); + int nbRow = sheet.getRows(); + System.out.println("Number of row in excel file: " + nbRow); + + int row = 1; + while (row < nbRow) + { + String labelName = sheet.getCell(1, row).getContents(); + + int nbLabelWithThisName = 0; + if (eventFoundHashMap.containsKey(labelName)) + { + nbLabelWithThisName = eventFoundHashMap.get(labelName); + } + eventFoundHashMap.put(labelName, nbLabelWithThisName + 1); + + row++; + } + + for (String labelName : eventFoundHashMap.keySet()) + { + System.out.println("Label Name : " + labelName + " #" + eventFoundHashMap.get(labelName)); + } + + nbElement += eventFoundHashMap.keySet().size(); + + } + catch (FileNotFoundException e) + { + e.printStackTrace(); + } + catch (BiffException e) + { + // TODO Auto-generated catch block + e.printStackTrace(); + } + catch (IOException e) + { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + System.out.println("Number of extra user labels (AviSoft XLS): " + nbElement); + + nbExtraEvent += nbElement; + } + } + + return nbExtraEvent; + } + + private int loadExtraLabelAviSoftTXTFile(File originalFile, int currentY, Graphics2D g2) + { + + File extraFile = getExtraAviSoftTXTFile(originalFile); + if (extraFile.exists()) + { + // nlabel type duration interval starttime endtime pstart_time pstart pstart_ampl pend_time pend pend_ampl pmin_time pmin pmin_ampl pmax_time + // pmax pmax_ampl + + // Pattern pattern = Pattern.compile("(\t)(.*?)(\t)"); // finds string between tabs. + int nbElement = 0; + + HashMap<String, EventTimeLine> eventTimeLineHashMap = new HashMap<String, EventTimeLine>(); + /* + * EventTimeLine userEvent = new EventTimeLine( userLabelName , + * EventType.USER_EVENT , TimeLineCategory.USE_BOOLEAN_EVENT ); + * animal.eventTimeLineList.add( userEvent ); + */ + + try + { + + loadDefaultUserEventSet(eventTimeLineHashMap, originalFile); + + Scanner scanner = new Scanner(extraFile); + + while (scanner.hasNextLine()) + { + int lineNumber = scanner.nextInt(); // scan line number + System.out.println("next line number : " + lineNumber); + + String labelName = scanner.next(); + + /* + * int nbLabelWithThisName = 0; + * if ( eventFoundHashMap.containsKey( labelName ) ) + * { + * nbLabelWithThisName = eventFoundHashMap.get( labelName ); + * } + * eventFoundHashMap.put( labelName , nbLabelWithThisName+1 ); + */ + // System.out.print( "label name: " + labelName + ":"); + EventTimeLine userEvent = null; + // for ( String keyString : eventTimeLineHashMap.keySet() ) + // { + // if ( keyString.equals( labelName ) ) + // { + // userEvent = eventTimeLineHashMap.get( labelName ); + // //System.out.print( ":found:"); + // break; + // } + // } + if (eventTimeLineHashMap.containsKey(labelName)) // retreive EventTimeLine + { + userEvent = eventTimeLineHashMap.get(labelName); + } + else + + // if (userEvent == null ) // means it was not found in keyset. + { // creates a new eventTimeLine for this label. + userEvent = new EventTimeLine(labelName, EventType.USER_EVENT, + TimeLineCategory.USE_BOOLEAN_EVENT); + eventTimeLineHashMap.put(labelName, userEvent); + animal.eventTimeLineList.add(userEvent); + } + + float duration = scanner.nextFloat(); + float interval = scanner.nextFloat(); + float startTime = scanner.nextFloat(); + + int durationInFrame = (int) (FPS * duration); + int startTimeInFrame = (int) (FPS * startTime); + + // System.out.println( "line: " + line + " l:" + labelName + " s:" + startTime + " d:" + duration ); + + for (int t = startTimeInFrame; t <= startTimeInFrame + durationInFrame; t++) + { + userEvent.addPunctualEvent(t - firstFrame); + // System.out.print("a"); + } + // System.out.println( ""); + if (scanner.hasNextLine()) // flush what remains in this line. + { + scanner.nextLine(); + } + } + + scanner.close(); + + // display label found + ArrayList keys = new ArrayList(eventTimeLineHashMap.keySet()); + Collections.sort(keys); + // for ( EventTimeLine eventTimeLine : eventTimeLineHashMap.values() ) + // for ( Object key : keys ) + for (int iTimeLine = 29; iTimeLine < animal.eventTimeLineList.size(); iTimeLine++) + { + // EventTimeLine eventTimeLine = eventTimeLineHashMap.get( key ); + EventTimeLine eventTimeLine = animal.eventTimeLineList.get(iTimeLine); + // EventTimeLine eventTimeLine = eventTimeLineHashMap.get( eventTimeLineString ); + System.out.println("Processing eventTimeLine... " + eventTimeLine.criteriaName + " nb event : " + + eventTimeLine.eventList.size()); + nbElement++; + + int nbEvent = 0; + int total = 0; + // draw result + g2.setColor(Color.BLUE); + for (EventCriteria eventCriteria : eventTimeLine.eventList) + { + nbEvent++; + total += eventCriteria.getLength(); + for (int i = eventCriteria.startFrame; i <= eventCriteria.endFrame; i++) + { + g2.drawLine(i, currentY, i, currentY + stepY); + } + } + + g2.setColor(Color.BLACK); + g2.drawLine(0, currentY, imageChrono.getWidth(), currentY); + String string = eventTimeLine.criteriaName + " nb event: " + nbEvent + " totalT: " + + nbFrameToDisplayInSecond(total); + g2.drawString(string, 0, currentY + 12); + + currentY += stepY; + + imageComponent.stringList.add(string); + + g2.drawLine(0, currentY, imageChrono.getWidth(), currentY); + + } + + } + catch (FileNotFoundException e) + { + e.printStackTrace(); + } + + System.out.println("Number of extra user labels (AviSoft): " + nbElement); + + } + + return currentY; + + } + + /** + * Loads a number of default user event set to force their presence in the list, and in a specific order. + * Then those events can be compared in the label analyser as they appear at the same line index event. + * (event 29 will be always the same) + * Loads the file in the folder call defaultUserEvents.txt + * Example of what it can contain: + * s + * f + * u + * d + * mo + * c + * j1 + * j2 + * mi + * n + * o + * + * @param eventTimeLineHashMap + * @param originalFile + */ + private void loadDefaultUserEventSet(HashMap<String, EventTimeLine> eventTimeLineHashMap, File originalFile) + { + + File defaultUserEventSetFile = new File( + FileUtil.getDirectory(originalFile.getAbsolutePath()) + "//defaultUserEvents.txt"); + + System.out.println("DefaultUserEventFile is: " + defaultUserEventSetFile.getAbsolutePath()); + + if (FileUtil.exists(defaultUserEventSetFile.getAbsolutePath())) + { + System.out.println("Loading default User events..."); + + try + { + Scanner scanner = new Scanner(defaultUserEventSetFile); + + while (scanner.hasNextLine()) + { + String labelName = scanner.nextLine(); + System.out.println(labelName); + EventTimeLine userEvent = new EventTimeLine(labelName, EventType.USER_EVENT, + TimeLineCategory.USE_BOOLEAN_EVENT); + eventTimeLineHashMap.put(labelName, userEvent); + animal.eventTimeLineList.add(userEvent); + } + + scanner.close(); + + } + catch (FileNotFoundException e) + { + e.printStackTrace(); + } + + } + + /* + * String labelName = ""; + * EventTimeLine userEvent = new EventTimeLine( labelName , + * EventType.USER_EVENT , TimeLineCategory.USE_BOOLEAN_EVENT ); + * eventTimeLineHashMap.put( labelName, userEvent ); + * animal.eventTimeLineList.add( userEvent ); + */ + + } + + private int loadExtraLabelXMLFile(File originalFile, int currentY, Graphics2D g2) + { + + // load labels generated by user ( file extra.xml ) + File extraFile = getExtraXMLFile(originalFile); + + System.out.println("XML file is: " + file.getAbsolutePath()); + System.out.println("Extra XML file is: " + extraFile.getAbsolutePath()); + + if (!extraFile.exists()) + return currentY; + + System.out.println("The extra info file exists... Processing..."); + + Document xmlDocument = XMLUtil.loadDocument(extraFile); + + /** offset to shit in time the incoming labels, in order to sync them if needed. */ + int offset = 0; + + ArrayList<Element> labelElementListOffset = XMLUtil.getElements(XMLUtil.getRootElement(xmlDocument), + "OFFSET"); + for (Element labelElement : labelElementListOffset) + { + offset = XMLUtil.getAttributeIntValue(labelElement, "offset", 0); + } + + /** min duration event */ + int minDurationEvent = 0; + + ArrayList<Element> labelElementListMinDuration = XMLUtil.getElements(XMLUtil.getRootElement(xmlDocument), + "MINDURATION"); + for (Element labelElement : labelElementListMinDuration) + { + minDurationEvent = XMLUtil.getAttributeIntValue(labelElement, "minduration", 0); + } + + ArrayList<Element> labelElementList = XMLUtil.getElements(XMLUtil.getRootElement(xmlDocument), "LABEL"); + + for (Element labelElement : labelElementList) + { + + String userLabelName = XMLUtil.getAttributeValue(labelElement, "name", "no name"); + String userLabelColorString = XMLUtil.getAttributeValue(labelElement, "color", "green"); + + System.out.println("Loading label " + userLabelName); + + Color userEventColor = null; + try + { + Field field = Class.forName("java.awt.Color").getField(userLabelColorString); + userEventColor = (Color) field.get(null); + } + catch (Exception e) + { + userEventColor = Color.green; // Not defined + System.err.println("Unsupported color in label " + userLabelName + " (switching to green)"); + } + + // create node + + int nbEvent = 0; + int total = 0; + + EventTimeLine userEvent = new EventTimeLine(userLabelName, EventType.USER_EVENT, + TimeLineCategory.USE_BOOLEAN_EVENT); + animal.eventTimeLineList.add(userEvent); + + synchronizeAllAnimalEvent(userEvent); + + g2.setColor(userEventColor); + + // read events. + ArrayList<Element> labelEventList = XMLUtil.getElements(labelElement, "EVENT"); + + for (Element labelEvent : labelEventList) + { + int start = XMLUtil.getAttributeIntValue(labelEvent, "start", -1); + int end = XMLUtil.getAttributeIntValue(labelEvent, "end", -1); + + if (start == -1) + { + System.err.println("Error in label " + userLabelName); + System.err.println("Wrong start value (skipping event)"); + continue; + } + + if (end == -1) + { + System.err.println("Error in label " + userLabelName); + System.err.println("Wrong end value (skipping event)"); + continue; + } + + if (start > end) + { + System.err.println("Error in label " + userLabelName); + System.err.println("start value > end value (skipping event)"); + continue; + } + + start += offset; + end += offset; + + // check minduration event: if the event is smaller than mindurationevent, create an event of the correct length from start. + + if (end - start < minDurationEvent) + { + end = start + minDurationEvent; + } + + for (int t = start; t <= end; t++) + { + userEvent.addPunctualEvent(t - firstFrame); + } + } + + nbEvent = 0; + total = 0; + // draw result + for (EventCriteria eventCriteria : userEvent.eventList) + { + nbEvent++; + total += eventCriteria.getLength(); + for (int i = eventCriteria.startFrame; i <= eventCriteria.endFrame; i++) + { + g2.drawLine(i, currentY, i, currentY + stepY); + } + } + + g2.setColor(Color.black); + g2.drawLine(0, currentY, imageChrono.getWidth(), currentY); + String string = userLabelName + nbEvent + " totalT: " + nbFrameToDisplayInSecond(total); + g2.drawString(string, 0, currentY + 12); + + currentY += stepY; + + imageComponent.stringList.add(string); + + g2.drawLine(0, currentY, imageChrono.getWidth(), currentY); + } + + System.out.println("Custom XML user label loaded."); + + return currentY; + } + + /** + * This function ensure that all the events are loaded the same way for all animals, + * and even resort them, in order to have the exact same list (and same order) of event for all animals + * + * @param userEvent + */ + private void synchronizeAllAnimalEvent(EventTimeLine userEvent) + { + + // TODO + + ArrayList<Animal> animalList = new ArrayList<Animal>(); + for (VideoLabelPanel videoLabelPanel : videoLabelPanelArrayList) + { + animalList.add(videoLabelPanel.animal); + } + + } + + float getMin(float a, float b) + { + if (a < b) + return a; + return b; + } + + public void loadXML(File currentFile) + { + + System.out.println("Loading document"); + + // LOAD DOCUMENT + + mouseARecord.clear(); + mouseBRecord.clear(); + + File XMLFile = currentFile; + if (!XMLFile.exists()) + return; + + Document XMLDocument = XMLUtil.loadDocument(XMLFile); + + XPath xpath = XPathFactory.newInstance().newXPath(); + + // VIDEO FILE NAME LOAD + + { + String expression = "//FILENAME"; + NodeList nodes; + try + { + nodes = (NodeList) xpath.evaluate(expression, XMLDocument, XPathConstants.NODESET); + + // System.out.println( "node size : " + nodes.getLength() ); + + Element fileNode = (Element) nodes.item(0); + System.out.println("Video file is :" + fileNode.getTextContent()); + videoFile = new File(fileNode.getTextContent()); + + } + catch (XPathExpressionException e) + { + + e.printStackTrace(); + } + } + + // MOUSE A LOAD + + // float startFrame = Float.parseFloat( loadFrameStartTextField.getText() ); + // float endFrame = Float.parseFloat( loadFrameEndTextField.getText() ); + + float startFrame = 0; + float endFrame = Float.MAX_VALUE; + + { + + String expression = "//MOUSEA/DET"; + NodeList nodes; + try + { + nodes = (NodeList) xpath.evaluate(expression, XMLDocument, XPathConstants.NODESET); + + // System.out.println( "mouse A node size : " + nodes.getLength() ); + + for (int i = 0; i < nodes.getLength(); i++) + { + Element detNode = (Element) nodes.item(i); + + MouseInfoRecord mouseInfoRecord = new MouseInfoRecord(); + mouseInfoRecord.bodyPosition = new Point2D.Float( + Float.parseFloat(detNode.getAttribute("bodyx")), + Float.parseFloat(detNode.getAttribute("bodyy"))); + mouseInfoRecord.headPosition = new Point2D.Float( + Float.parseFloat(detNode.getAttribute("headx")), + Float.parseFloat(detNode.getAttribute("heady"))); + mouseInfoRecord.tailPosition = new Point2D.Float( + Float.parseFloat(detNode.getAttribute("tailx")), + Float.parseFloat(detNode.getAttribute("taily"))); + + int currentT = Integer.parseInt(detNode.getAttribute("t")); + if (currentT >= startFrame && currentT <= endFrame) + { + // System.out.println("Mouse A adding record at t " + currentT ); + mouseARecord.put(currentT, mouseInfoRecord); + } + + } + + } + catch (XPathExpressionException e) + { + + e.printStackTrace(); + } + } + + // MOUSE B LOAD + + { + String expression = "//MOUSEB/DET"; + NodeList nodes; + try + { + nodes = (NodeList) xpath.evaluate(expression, XMLDocument, XPathConstants.NODESET); + + // System.out.println( "mouse B node size : " + nodes.getLength() ); + + for (int i = 0; i < nodes.getLength(); i++) + { + Element detNode = (Element) nodes.item(i); + + MouseInfoRecord mouseInfoRecord = new MouseInfoRecord(); + mouseInfoRecord.bodyPosition = new Point2D.Float( + Float.parseFloat(detNode.getAttribute("bodyx")), + Float.parseFloat(detNode.getAttribute("bodyy"))); + mouseInfoRecord.headPosition = new Point2D.Float( + Float.parseFloat(detNode.getAttribute("headx")), + Float.parseFloat(detNode.getAttribute("heady"))); + mouseInfoRecord.tailPosition = new Point2D.Float( + Float.parseFloat(detNode.getAttribute("tailx")), + Float.parseFloat(detNode.getAttribute("taily"))); + + int currentT = Integer.parseInt(detNode.getAttribute("t")); + if (currentT >= startFrame && currentT <= endFrame) + { + + // System.out.println("Mouse B adding record at t " + currentT ); + + mouseBRecord.put(currentT, mouseInfoRecord); + } + + } + + } + catch (XPathExpressionException e) + { + + e.printStackTrace(); + } + } + + startOffset = trimAnalysisRecord(); + + } + + /** Time in frame before the first analysis. Used to offset the video sequence. **/ + int startOffset = 0; + + double only2digit(double val) + { + val *= 100; + val = Math.floor(val); + val /= 100f; + return val; + } + + void computeVisionGraph(VisionGraph visionGraph) + { + // -------------------------------- + // A regarde l'autre souris ( non event / graph de vue ) + { + + float nbVal = 0; + float totalDistance = 0; + float nbEvent = 0; + float total = 0; + + int tabAngle[] = new int[361]; + int graphNumber = 0; + + int binSize = 5; + + EventCriteria currentCriteria = null; + + int tMin = Integer.MAX_VALUE; + int tMax = 0; + { + Iterator<Integer> integerIterator = mouseARecord.keySet().iterator(); + while (integerIterator.hasNext()) + { + int val = integerIterator.next(); + if (val > tMax) + tMax = val; + if (val < tMin) + tMin = val; + } + } + + for (int t = 0; t < tMax; t++) + { + if (mouseARecord.containsKey(t)) + if (mouseBRecord.containsKey(t)) + { + MouseInfoRecord mouseA = mouseARecord.get(t); + MouseInfoRecord mouseB = mouseBRecord.get(t); + + double distanceHeadABodyB = mouseA.headPosition.distanceSq(mouseB.bodyPosition); + double distanceHeadAHeadB = mouseA.headPosition.distanceSq(mouseB.headPosition); + double distanceBodyABodyB = mouseA.bodyPosition.distanceSq(mouseB.bodyPosition); + double distanceBodyAHeadB = mouseA.bodyPosition.distanceSq(mouseB.headPosition); + + double VAx = mouseA.headPosition.getX() - mouseA.bodyPosition.getX(); + double VAy = mouseA.headPosition.getY() - mouseA.bodyPosition.getY(); + double angleA = Math.atan2(VAy, VAx); + + // teste A dans la vue. + + double VABx = -mouseA.headPosition.getX() + mouseB.headPosition.getX(); + double VABy = -mouseA.headPosition.getY() + mouseB.headPosition.getY(); + double angleBA = Math.atan2(VABy, VABx); // + Math.PI; + + boolean eventIsOk = true; + + if (angleMin(angleBA, angleA) < demiVisionDeSouris) + { + + } + else + { + eventIsOk = false; + } + + if (visionGraph == VisionGraph.AT_FOLLOW_STATE) + { + // CRITERE EN POURSUITE + if ( + + (mouseA.distanceIsInferiorToThreshold2) || (!mouseA.isGettingToOtherAndTouch)) + { + eventIsOk = false; + } + } + + if (visionGraph == VisionGraph.AT_STOP_STATE) + { + if ( + // CRITERE EN OBSERVATION A L ARRET + + (mouseA.distanceIsInferiorToThreshold1) || (mouseA.speed > SPEED_THRESHOLD_1)) + + { + eventIsOk = false; + } + } + + if (eventIsOk) + { + + double angleSouris = angleA; + double angleVision = angleBA; + + angleVision = angleVision - angleSouris; + + int angleVisionDeg = (int) (180d * angleVision / Math.PI); + + while (angleVisionDeg > 180) + angleVisionDeg -= 360; + while (angleVisionDeg < -180) + angleVisionDeg += 360; + + int angleToFill = binSize * ((int) angleVisionDeg / binSize); + + tabAngle[180 + angleToFill]++; + + } + + } + } + + // Graph de placement de I dans la vue de R. + { + + XlsManager xls = null; + File xlsFile = new File(System.getProperty("user.home") + "\\" + visionGraph.toString() + " " + + animal.animalName + ".xls"); + try + { + xls = new XlsManager(xlsFile); + } + catch (IOException e) + { + + e.printStackTrace(); + } + + xls.createNewPage("result"); + + // Generation du graph de vue de la residente. + + JFreeChart chart; + XYSeriesCollection xyDataset = new XYSeriesCollection(); + YIntervalSeriesCollection yintervalseriescollection = new YIntervalSeriesCollection(); + IcyFrame graphFrame = new IcyFrame("graph " + graphNumber + " " + animal.animalName, true, true, + true, true); + graphNumber++; + + chart = ChartFactory.createXYLineChart("", "angle", "y", xyDataset, PlotOrientation.VERTICAL, true, + false, false); + + XYSeries seriesXY = new XYSeries("Sight " + animal.animalName); + xyDataset.addSeries(seriesXY); + + int cursorX = 0; + + for (int i = 0; i < 360; i += binSize) + { + seriesXY.add(i - 180, tabAngle[i]); + xls.setNumber(cursorX, 0, tabAngle[i]); + cursorX++; + } + + new AnnounceFrame("Exported in file " + xlsFile); + xls.SaveAndClose(); + + graphFrame.getContentPane().add( + new ChartPanel(chart, 500, 200, 500, 200, 500, 500, false, false, true, true, true, true)); + graphFrame.setVisible(true); + graphFrame.pack(); + graphFrame.addToMainDesktopPane(); + graphFrame.center(); + + } + + } + } + + @Override + public void actionPerformed(ActionEvent e) + { + + if (e.getSource() == computeVisionInFollowButton) + { + computeVisionGraph(VisionGraph.AT_FOLLOW_STATE); + } + if (e.getSource() == computeVisionWhenStoppedButton) + { + computeVisionGraph(VisionGraph.AT_STOP_STATE); + } + + if (e.getSource() == exportSpeedButton) + { + // export speed computation + + File xlsFile = new File(file.getAbsolutePath() + ".speed.xls"); + + try + { + XlsManager xls = new XlsManager(xlsFile); + // xls.createNewPage("Results"); + + exportSpeed(xls, mouseARecord, "Mouse A"); + exportSpeed(xls, mouseBRecord, "Mouse B"); + + xls.SaveAndClose(); + + } + catch (IOException e1) + { + e1.printStackTrace(); + } + + new AnnounceFrame("Speed data have been exported to " + xlsFile.getAbsolutePath(), 5); + + } + + if (e.getSource() == computeLocationHeatMapButton) + { + computeLocationHeatMap(); + // computeEventLocationHeatMap(); + } + + if (e.getSource() == computeUSVStat) + { + // computeVocStats(); + computeUSVStats(); + } + + if (e.getSource() == exportEventsAsXML) + { + exportEventsAsXML(); + } + + if (e.getSource() == saveImageButton) + { + // save a full strip of the image + try + { + ImageIO.write(imageChrono, "png", new File(file.getAbsolutePath() + ".1.png")); + } + catch (IOException e1) + { + e1.printStackTrace(); + } + + // save criteria by criteria + + int numeroCriteria = 0; + for (int y = 0; y < imageChrono.getHeight(); y += stepY) + { + + BufferedImage image2 = new BufferedImage(imageChrono.getWidth(), stepY, BufferedImage.TYPE_INT_BGR); + + Graphics2D targetG = (Graphics2D) image2.getGraphics(); + + targetG.drawImage(imageChrono, null, 0, -y); + + try + { + ImageIO.write(image2, "png", + new File(file.getAbsolutePath() + ".criteria_" + numeroCriteria + ".png")); + } + catch (IOException e1) + { + e1.printStackTrace(); + } + numeroCriteria++; + + } + + // save the strip with multiple lines. + + float desiredWidth = 1600 * 2; + + BufferedImage image2 = new BufferedImage((int) desiredWidth, + (int) (imageChrono.getHeight() * imageChrono.getWidth() / desiredWidth), + BufferedImage.TYPE_INT_BGR); + + Graphics2D sourceG = (Graphics2D) imageChrono.getGraphics(); + Graphics2D targetG = (Graphics2D) image2.getGraphics(); + + int stepY = 0; + for (int offset = 0; offset < imageChrono.getWidth(); offset += desiredWidth) + { + targetG.drawImage(imageChrono, null, -offset, stepY * imageChrono.getHeight()); + stepY++; + } + + try + { + ImageIO.write(image2, "png", new File(file.getAbsolutePath() + ".2.png")); + } + catch (IOException e1) + { + e1.printStackTrace(); + } + + } + + } + + private void exportEventsAsXML() + { + + Document document = XMLUtil.createDocument(true); + + for (EventTimeLine eventTimeLine : animal.eventTimeLineList) + { + Element elementTimeLine = document.createElement("EventTimeLine"); + document.getDocumentElement().appendChild(elementTimeLine); + XMLUtil.setAttributeIntValue(elementTimeLine, "index", animal.eventTimeLineList.indexOf(eventTimeLine)); + XMLUtil.setAttributeValue(elementTimeLine, "name", eventTimeLine.criteriaName); + XMLUtil.setAttributeValue(elementTimeLine, "type", eventTimeLine.eventType.toString()); + XMLUtil.setAttributeValue(elementTimeLine, "timeLineCategory", + eventTimeLine.timeLineCategory.toString()); + + for (EventCriteria event : eventTimeLine.eventList) + { + Element elementEvent = document.createElement("event"); + elementTimeLine.appendChild(elementEvent); + XMLUtil.setAttributeIntValue(elementEvent, "startFrame", event.startFrame); + XMLUtil.setAttributeIntValue(elementEvent, "endFrame", event.endFrame); + } + } + + File xmlFile = new File(file.getAbsolutePath() + ".allEventsExported.xml"); + XMLUtil.saveDocument(document, xmlFile); + AnnounceFrame f = new AnnounceFrame("File exported: " + xmlFile.getAbsolutePath()); + } + + private void computeUSVStats() + { + + // designed for USVs + // given an event, let's say an USV event, this code provide the following ratio: + // The number of USV event that are correlated with the events of a specific timeEvent. + // 100% means all the USV event are overlapping with the candidate event. + // 50% means half the USV event are ... + + WritableWorkbook workbook; + + try + { + + workbook = XLSUtil.createWorkbook(new File(file.getAbsolutePath() + ".event.xls")); + WritableSheet page = XLSUtil.createNewPage(workbook, "result"); + + int currentColumn = 1; + for (int indexOfUSVEvent = 29; indexOfUSVEvent < animal.eventTimeLineList.size(); indexOfUSVEvent++) + { + + EventTimeLine eventTimeLineWatched = animal.eventTimeLineList.get(indexOfUSVEvent); + + XLSUtil.setCellString(page, 0, 0, file.getAbsolutePath()); + // XLSUtil.setCellString( page, 0, 1, "event watched: " + eventTimeLineWatched.criteriaName ); + // XLSUtil.setCellString( page, 0, 2, "nb event(s): " + eventTimeLineWatched.eventList.size() ); + + int row = 5; + + XLSUtil.setCellString(page, 0, row, "event"); + XLSUtil.setCellString(page, currentColumn, row - 2, "Event: " + eventTimeLineWatched.criteriaName); + XLSUtil.setCellString(page, currentColumn, row - 1, + "Nb event: " + eventTimeLineWatched.eventList.size()); + + XLSUtil.setCellString(page, currentColumn, row, "nb corr event "); + XLSUtil.setCellString(page, currentColumn + 1, row, "% corr event"); + // 1 + // 1 + // 2 + row += 2; + + for (EventTimeLine eventTimeLineCandidate : animal.eventTimeLineList) + { + XLSUtil.setCellString(page, 0, row, eventTimeLineCandidate.criteriaName); + + int nbEventCandidate = eventTimeLineCandidate.eventList.size(); + // XLSUtil.setCellNumber( page, currentColumn, row, nbEventCandidate ); + + int nbOccur = 0; + + // check how many time the eventUSV occurs at the same time as the candidateEvent + for (EventCriteria eventUSV : eventTimeLineWatched.eventList) + { + + for (EventCriteria eventCandidate : eventTimeLineCandidate.eventList) + { + if (isEventOverlapping(eventUSV, eventCandidate)) + { + nbOccur++; + break; + } + + } + + } + + float ratio = 100f * (float) nbOccur / (float) eventTimeLineWatched.eventList.size(); + XLSUtil.setCellNumber(page, currentColumn, row, nbOccur); + XLSUtil.setCellNumber(page, currentColumn + 1, row, ratio); + + row++; + } + currentColumn += 2; + } + + XLSUtil.saveAndClose(workbook); + + } + catch (IOException e) + { + e.printStackTrace(); + } + catch (WriteException e) + { + e.printStackTrace(); + } + + } + + /** + * check if a is overlapping b. + */ + private boolean isEventOverlapping(EventCriteria a, EventCriteria b) + { + + if (b.startFrame <= a.endFrame && b.endFrame >= a.startFrame) + { + return true; + } + + return false; + } + + /** + * @deprecated + * @param vocEventIndex + * @param candidateEventIndex + * @param sheet + */ + private void feedXLSWithIntersectingEvent(int vocEventIndex, int candidateEventIndex, WritableSheet sheet) + { + + /** Number of vocalization intersecting/overlapping with a contact */ + + EventTimeLine vocTimeLine = animal.eventTimeLineList.get(vocEventIndex); + EventTimeLine candidateTimeLine = animal.eventTimeLineList.get(candidateEventIndex); + + int totalNbVoc = vocTimeLine.eventList.size(); + + int nbVocWithEvent = getNumberOfEventOverlap(vocTimeLine, candidateTimeLine); + + int row = sheet.getRows(); + + XLSUtil.setCellString(sheet, 0, row, "nb Voc with event :" + candidateTimeLine.criteriaName); + XLSUtil.setCellNumber(sheet, 1, row, nbVocWithEvent); + XLSUtil.setCellString(sheet, 2, row, "percent:"); + XLSUtil.setCellNumber(sheet, 3, row++, nbVocWithEvent * 100f / totalNbVoc); + + } + + /** + * @deprected + * provides the number of event vocTimeLine overlapping with the candidate time line + */ + private int getNumberOfEventOverlap(EventTimeLine vocTimeLine, EventTimeLine candidateTimeLine) + { + + int nbEvent = 0; + + System.out.println("nb of event of type ** " + vocTimeLine.criteriaName + " ** matching ** " + + candidateTimeLine.criteriaName + " **"); + + for (EventCriteria vocEvent : vocTimeLine.eventList) + { + for (EventCriteria candidateEvent : animal.eventTimeLineList.get(1).eventList) + { + if (isEventOverlapping(vocEvent, candidateEvent)) + { + nbEvent++; + break; + } + } + + } + + return nbEvent; + } + + private void computeEventLocationHeatMap() + { + // red channel : contact events + // green channel : usv events + + // check if event is found + + // System.out.println( animal.eventTimeLineList.get( 29 ).criteriaName ); + + // create image + + // should parse the all data to find min/max or check video input size. + + SCALE = Float.parseFloat(scaleTextField.getText()); + + IcyBufferedImage image = new IcyBufferedImage(800, 600, 3, DataType.USHORT); + + // check < threshold 1 events + for (EventCriteria event : animal.eventTimeLineList.get(0).eventList) + { + for (int t = event.startFrame; t <= event.endFrame; t++) + { + MouseInfoRecord mouseA = mouseARecord.get(t); + additiveDrawMouse(mouseA, image, 0); + + MouseInfoRecord mouseB = mouseBRecord.get(t); + additiveDrawMouse(mouseB, image, 0); + } + } + + // check USV + for (EventCriteria event : animal.eventTimeLineList.get(29).eventList) + { + for (int t = event.startFrame; t <= event.endFrame; t++) + { + MouseInfoRecord mouseA = mouseARecord.get(t); + additiveDrawMouse(mouseA, image, 1); + + MouseInfoRecord mouseB = mouseBRecord.get(t); + additiveDrawMouse(mouseB, image, 1); + } + } + + image.dataChanged(); + + // display image + + Sequence outPutSequence = new Sequence(image); + // Icy.getMainInterface().addSequence( outPutSequence ); + + // save Image + + File heatMapFile = new File(FileUtil.setExtension(file.getAbsolutePath(), ".heatmap.event.tif")); + Saver.save(outPutSequence, heatMapFile); + new AnnounceFrame("HeatMapFile saved to " + heatMapFile.getAbsolutePath(), 5); + + } + + private void computeLocationHeatMap() + { + + // create image + + // should parse the all data to find min/max or check video input size. + + SCALE = Float.parseFloat(scaleTextField.getText()); + + IcyBufferedImage image = new IcyBufferedImage(800, 600, 4, DataType.USHORT); + + // render mice + + // mouse A + for (Integer t : mouseARecord.keySet()) + { + MouseInfoRecord mouseA = mouseARecord.get(t); + additiveDrawMouse(mouseA, image, 0); + } + + // mouse B + for (Integer t : mouseBRecord.keySet()) + { + MouseInfoRecord mouseB = mouseBRecord.get(t); + additiveDrawMouse(mouseB, image, 1); + } + + // voc event on blue channel. (test purposes) + for (Integer t : mouseBRecord.keySet()) + { + MouseInfoRecord mouseB = mouseBRecord.get(t); + MouseInfoRecord mouseA = mouseARecord.get(t); + + EventTimeLine eventTimeLineWatched = animal.eventTimeLineList.get(29); + if (eventTimeLineWatched.getNbEvent(t, t) == 1) + { + additiveDrawMouse(mouseA, image, 2); + additiveDrawMouse(mouseB, image, 3); + } + } + + image.dataChanged(); + + // display image + + Sequence outPutSequence = new Sequence(image); + // Icy.getMainInterface().addSequence( outPutSequence ); + + // save Image + + File heatMapFile = new File(FileUtil.setExtension(file.getAbsolutePath(), ".heatmap.tif")); + Saver.save(outPutSequence, heatMapFile); + new AnnounceFrame("HeatMapFile saved to " + heatMapFile.getAbsolutePath(), 5); + + } + + private void additiveDrawMouse(MouseInfoRecord mouse, IcyBufferedImage image, int channel) + { + + Ellipse2D head = new Ellipse2D.Float((float) mouse.headPosition.getX() - (40f * SCALE) / 2f, + (float) mouse.headPosition.getY() - (40f * SCALE) / 2f, 40 * SCALE, 40 * SCALE); // 9 + Ellipse2D body = new Ellipse2D.Float((float) mouse.bodyPosition.getX() - (77f * SCALE) / 2f, + (float) mouse.bodyPosition.getY() - (77f * SCALE) / 2f, 77 * SCALE, 77 * SCALE); // 17 + Ellipse2D tail = new Ellipse2D.Float((float) mouse.tailPosition.getX() - (13f * SCALE) / 2f, + (float) mouse.tailPosition.getY() - (13f * SCALE) / 2f, 13 * SCALE, 13 * SCALE); // 3 + + int centerX = 0; + int centerY = 0; + int ray = 30; + additiveDrawOverImage(image, (int) head.getCenterX(), (int) head.getCenterY(), (int) ((40f * SCALE) / 2f), + channel); + additiveDrawOverImage(image, (int) body.getCenterX(), (int) body.getCenterY(), (int) ((77f * SCALE) / 2f), + channel); + additiveDrawOverImage(image, (int) tail.getCenterX(), (int) tail.getCenterY(), (int) ((13f * SCALE) / 2f), + channel); + + } + + private void additiveDrawOverImage(IcyBufferedImage image, int ox, int oy, int r, int channel) + { + + short[] buffer = image.getDataXYAsShort(channel); + int width = image.getWidth(); + + for (int x = -r; x < r; x++) + { + int height = (int) Math.sqrt(r * r - x * x); + + for (int y = -height; y < height; y++) + { + // bmp.SetPixel(x + ox, y + oy, Color.Red); + buffer[(oy + y) * width + x + ox]++; + } + } + + } + + private void exportSpeed(XlsManager xls, HashMap<Integer, MouseInfoRecord> mouseRecord, String name) + { + + xls.createNewPage(name); + + int tMin = 0; + + START_MINUTE = Integer.parseInt(computeImageStartMinuteTextField.getText()); + NB_MINUTE = Integer.parseInt(computeImageNbMinuteTextField.getText()); + firstFrame = (int) (tMin + START_MINUTE * 60 * FPS); + lastFrame = (int) (firstFrame + NB_MINUTE * 60 * FPS); + + int tMax = lastFrame; + /** frameWindow est utilisé pour lisser le calcul de deplacement entre deux points de temps. t-framewindow et t+frameWindow */ + int frameWindow = 6; // 5 + + double speedFrame[] = new double[tMax - firstFrame]; // speed computed at each frame + + xls.setLabel(0, 0, "frame#"); + xls.setLabel(1, 0, "speed in px/frame time"); + xls.setLabel(2, 0, "cumulated distance in px"); + + { + float nbVal = 0; + double totalDistance = 0; + for (int t = 0; t < tMax; t++) + { + if (mouseRecord.containsKey(t - frameWindow)) + if (mouseRecord.containsKey(t + frameWindow)) + if (mouseRecord.containsKey(t)) + { + MouseInfoRecord mouseRecordPrev = mouseRecord.get(t - frameWindow); + MouseInfoRecord mouseRecordNext = mouseRecord.get(t + frameWindow); + MouseInfoRecord mouseRecordCurrentFrame = mouseRecord.get(t); + + float distance = (float) mouseRecordPrev.bodyPosition + .distance(mouseRecordNext.bodyPosition); + distance /= (float) (frameWindow * 2 + 1); // pour obtenir une vitesse par frame. + + totalDistance += distance; + + mouseRecordCurrentFrame.speed = distance; + + speedFrame[t - firstFrame] = distance; + xls.setNumber(0, (int) (nbVal + 1), nbVal); + xls.setNumber(1, (int) (nbVal + 1), distance); + xls.setNumber(2, (int) (nbVal + 1), totalDistance); + + nbVal++; + } + } + + } + + xls.setLabel(4, 0, "second#"); + xls.setLabel(5, 0, "speed in px/s"); + xls.setLabel(6, 0, "cumulated distance in px"); + + // System.out.println("tMax : " + tMax ); + { + int sec = 0; + int arrayCounter = 0; + double totalDistance = 0; + while (arrayCounter < tMax - FPS) + { + + double speedSec = 0; + + for (int i = 0; i < FPS; i++) + { + speedSec += speedFrame[arrayCounter]; + totalDistance += speedFrame[arrayCounter]; + arrayCounter++; + } + + // speedSec; + + System.out.println("sec:" + sec); + + xls.setNumber(4, sec + 1, sec); + xls.setNumber(5, sec + 1, speedSec); + xls.setNumber(6, sec + 1, totalDistance); + + sec++; + } + + } + } + + @Override + public void mouseClicked(MouseEvent e) + { + try + { + updateVideoImageAt(e.getX()); + } + catch (InterruptedException ex) + { + // ignore + } + } + + @Override + public void mouseEntered(MouseEvent e) + { + } + + @Override + public void mouseExited(MouseEvent e) + { + } + + @Override + public void mousePressed(MouseEvent e) + { + } + + @Override + public void mouseReleased(MouseEvent e) + { + } + + @Override + public void mouseDragged(MouseEvent e) + { + try + { + updateVideoImageAt(e.getX()); + } + catch (InterruptedException ex) + { + // ignore + ex.printStackTrace(); + } + } + + private void updateVideoImageAt(int x) throws InterruptedException + { + + x = x + firstFrame; + // x = x+ startOffset; + + if (frameAccess == null) + { + // check if file exists. + if (videoFile.exists()) + { + frameAccess = new FrameAccess(videoFile); + } + else + { + System.out.println("File specified in XML is not present. Checking in XML folder."); + videoFile = new File(FileUtil.getDirectory(file.getAbsolutePath()) + FileUtil.separator + + FileUtil.getFileName(videoFile.getName())); + frameAccess = new FrameAccess(videoFile); + } + + } + + videoImage = frameAccess.getImageAt(x + startOffset + 3); + + if (videoImage == null) + { + videoImage = IcyBufferedImageUtil.toBufferedImage(new IcyBufferedImage(640, 480, 1, DataType.BYTE), + null); + + } + + // draw over. + + Graphics2D g2 = (Graphics2D) videoImage.getGraphics(); + + // Mouse A + { + g2.setColor(Color.red); + MouseInfoRecord mouseA = mouseARecord.get(x); + MouseInfoRecord mouseB = mouseBRecord.get(x); + if (mouseA != null) + { + SCALE = Float.parseFloat(scaleTextField.getText()); + // Ellipse2D head = new Ellipse2D.Float( (float)mouseA.headPosition.getX()-4f , (float)mouseA.headPosition.getY() - (40f*SCALE)/2f , + // 40*SCALE , 40*SCALE ); //9 + // Ellipse2D body = new Ellipse2D.Float( (float)mouseA.bodyPosition.getX()-8f , (float)mouseA.bodyPosition.getY() - (77f*SCALE)/2f , + // 77*SCALE , 77*SCALE ); // 17 + // Ellipse2D tail = new Ellipse2D.Float( (float)mouseA.tailPosition.getX()-1f , (float)mouseA.tailPosition.getY() - (13f*SCALE)/2f , + // 13*SCALE , 13*SCALE ); // 3 + // System.out.println(SCALE); + Ellipse2D head = new Ellipse2D.Float((float) mouseA.headPosition.getX() - (40f * SCALE) / 2f, + (float) mouseA.headPosition.getY() - (40f * SCALE) / 2f, 40 * SCALE, 40 * SCALE); // 9 + Ellipse2D body = new Ellipse2D.Float((float) mouseA.bodyPosition.getX() - (77f * SCALE) / 2f, + (float) mouseA.bodyPosition.getY() - (77f * SCALE) / 2f, 77 * SCALE, 77 * SCALE); // 17 + Ellipse2D tail = new Ellipse2D.Float((float) mouseA.tailPosition.getX() - (13f * SCALE) / 2f, + (float) mouseA.tailPosition.getY() - (13f * SCALE) / 2f, 13 * SCALE, 13 * SCALE); // 3 + + g2.draw(head); + g2.draw(body); + g2.draw(tail); + + // draw eye view + + double VAx = mouseA.headPosition.getX() - mouseA.bodyPosition.getX(); + double VAy = mouseA.headPosition.getY() - mouseA.bodyPosition.getY(); + double angleA = Math.atan2(VAy, VAx); + + double departAngle1 = -8d * Math.PI / 9d; + double departAngle2 = 3d * Math.PI / 9d; + + // centre + g2.drawLine((int) mouseA.headPosition.getX(), (int) mouseA.headPosition.getY(), + (int) (mouseA.headPosition.getX() + Math.cos(angleA) * 100d), + (int) (mouseA.headPosition.getY() + Math.sin(angleA) * 100d)); + + // gauche + g2.drawLine((int) mouseA.headPosition.getX(), (int) mouseA.headPosition.getY(), + (int) (mouseA.headPosition.getX() + Math.cos(angleA - 1 * Math.PI / 3d) * 50d), + (int) (mouseA.headPosition.getY() + Math.sin(angleA - 1 * Math.PI / 3d) * 50d)); + + // gauche full + g2.drawLine((int) mouseA.headPosition.getX(), (int) mouseA.headPosition.getY(), + (int) (mouseA.headPosition.getX() + Math.cos(angleA - 1 * 2 * Math.PI / 3d) * 100d), + (int) (mouseA.headPosition.getY() + Math.sin(angleA - 1 * 2 * Math.PI / 3d) * 100d)); + + // droit + g2.drawLine((int) mouseA.headPosition.getX(), (int) mouseA.headPosition.getY(), + (int) (mouseA.headPosition.getX() + Math.cos(angleA + 1 * Math.PI / 3d) * 50d), + (int) (mouseA.headPosition.getY() + Math.sin(angleA + 1 * Math.PI / 3d) * 50d)); + + // droit full + g2.drawLine((int) mouseA.headPosition.getX(), (int) mouseA.headPosition.getY(), + (int) (mouseA.headPosition.getX() + Math.cos(angleA + 1 * 2 * Math.PI / 3d) * 100d), + (int) (mouseA.headPosition.getY() + Math.sin(angleA + 1 * 2 * Math.PI / 3d) * 100d)); + + // ------------------------ MOUSE A REGARDE B + + // teste A dans la vue. + + double VABx = -mouseA.headPosition.getX() + mouseB.headPosition.getX(); + double VABy = -mouseA.headPosition.getY() + mouseB.headPosition.getY(); + double angleBA = Math.atan2(VABy, VABx); // + Math.PI; + + boolean eventIsOk = true; + + if (angleMin(angleBA, angleA) < demiVisionDeSouris) + { + + } + else + { + eventIsOk = false; + } + + if (mouseA.distanceIsInferiorToThreshold2) + { + eventIsOk = false; + } + + g2.setColor(Color.black); + g2.drawLine((int) mouseA.headPosition.getX(), (int) mouseA.headPosition.getY(), + (int) (mouseA.headPosition.getX() + Math.cos(angleBA) * 100d), + (int) (mouseA.headPosition.getY() + Math.sin(angleBA) * 100d)); + + double angleDif = angleBA - angleA; + + int angleDifDegree = (int) (180d * angleDif / Math.PI); + + while (angleDifDegree > 180) + angleDifDegree -= 360; + while (angleDifDegree < -180) + angleDifDegree += 360; + + } + } + // MOUSE B + { + g2.setColor(Color.green); + MouseInfoRecord mouseB = mouseBRecord.get(x); + if (mouseB != null) + { + // Ellipse2D head = new Ellipse2D.Float( (float)mouseB.headPosition.getX()-4f , (float)mouseB.headPosition.getY() - 4f , 9 , 9 ); + // Ellipse2D body = new Ellipse2D.Float( (float)mouseB.bodyPosition.getX()-8f , (float)mouseB.bodyPosition.getY() - 8f , 17 , 17 ); + // Ellipse2D tail = new Ellipse2D.Float( (float)mouseB.tailPosition.getX()-1f , (float)mouseB.tailPosition.getY() - 1f , 3 , 3 ); + + Ellipse2D head = new Ellipse2D.Float((float) mouseB.headPosition.getX() - (40f * SCALE) / 2f, + (float) mouseB.headPosition.getY() - (40f * SCALE) / 2f, 40 * SCALE, 40 * SCALE); // 9 + Ellipse2D body = new Ellipse2D.Float((float) mouseB.bodyPosition.getX() - (77f * SCALE) / 2f, + (float) mouseB.bodyPosition.getY() - (77f * SCALE) / 2f, 77 * SCALE, 77 * SCALE); // 17 + Ellipse2D tail = new Ellipse2D.Float((float) mouseB.tailPosition.getX() - (13f * SCALE) / 2f, + (float) mouseB.tailPosition.getY() - (13f * SCALE) / 2f, 13 * SCALE, 13 * SCALE); // 3 + + g2.draw(head); + g2.draw(body); + g2.draw(tail); + + // draw eye view + + double VAx = mouseB.headPosition.getX() - mouseB.bodyPosition.getX(); + double VAy = mouseB.headPosition.getY() - mouseB.bodyPosition.getY(); + double angleA = Math.atan2(VAy, VAx); + + double departAngle1 = -8d * Math.PI / 9d; + double departAngle2 = 3d * Math.PI / 9d; + + // centre + g2.drawLine((int) mouseB.headPosition.getX(), (int) mouseB.headPosition.getY(), + (int) (mouseB.headPosition.getX() + Math.cos(angleA) * 100d), + (int) (mouseB.headPosition.getY() + Math.sin(angleA) * 100d)); + + // gauche + g2.drawLine((int) mouseB.headPosition.getX(), (int) mouseB.headPosition.getY(), + (int) (mouseB.headPosition.getX() + Math.cos(angleA - 1 * Math.PI / 3d) * 50d), + (int) (mouseB.headPosition.getY() + Math.sin(angleA - 1 * Math.PI / 3d) * 50d)); + + // gauche full + g2.drawLine((int) mouseB.headPosition.getX(), (int) mouseB.headPosition.getY(), + (int) (mouseB.headPosition.getX() + Math.cos(angleA - 2 * Math.PI / 3d) * 100d), + (int) (mouseB.headPosition.getY() + Math.sin(angleA - 2 * Math.PI / 3d) * 100d)); + + // droit + g2.drawLine((int) mouseB.headPosition.getX(), (int) mouseB.headPosition.getY(), + (int) (mouseB.headPosition.getX() + Math.cos(angleA + 1 * Math.PI / 3d) * 50d), + (int) (mouseB.headPosition.getY() + Math.sin(angleA + 1 * Math.PI / 3d) * 50d)); + + // droit full + g2.drawLine((int) mouseB.headPosition.getX(), (int) mouseB.headPosition.getY(), + (int) (mouseB.headPosition.getX() + Math.cos(angleA + 1 * 2 * Math.PI / 3d) * 100d), + (int) (mouseB.headPosition.getY() + Math.sin(angleA + 1 * 2 * Math.PI / 3d) * 100d)); + + } + } + + videoTimeLabel.setText("frame #" + x + + + " " + (int) (x / (FPS * 60)) + ":" + decimalFormat.format((int) (x / FPS % 60))); + + imageVideoComponent.setImage(videoImage); + + // ComponentUtil.setFixedWidth( imageVideoComponent , 400 ); + + // getImage + + imageVideoComponent.updateUI(); + + } + + public double angleMin(double a1, double a2) + { + double angleMin = Double.MAX_VALUE; + + a1 = angleToZeroTwoPi(a1); + a2 = angleToZeroTwoPi(a2); + + for (int i = -2; i < 3; i++) + { + double dif = Math.abs(a1 + (i * Math.PI * 2d) - a2); + if (dif < angleMin) + angleMin = dif; + } + + return angleMin; + } + + public double angleToZeroTwoPi(double a) + { + + while (a < 0) + { + a += 2 * Math.PI; + } + while (a > 2 * Math.PI) + { + a -= 2 * Math.PI; + } + return a; + } + + @Override + public void mouseMoved(MouseEvent arg0) + { + + } + + } + + @Override + public void keyPressed(KeyEvent arg0) + { + // TODO Auto-generated method stub + + } + + @Override + public void keyReleased(KeyEvent e) + { + + if (e.getSource() == scaleTextField) + { + try + { + float scale = Float.parseFloat(scaleTextField.getText()); + float ratio = scale / 0.22f; + + distance1TextField.setText("" + ratio * 22); + distance2TextField.setText("" + ratio * 40); + distanceHeadHeadTextField.setText("" + ratio * 15); + distanceHeadGenitalTextField.setText("" + ratio * 15); + seuilSideTextField.setText("" + ratio * 12); + speed_threshold1TextField.setText("" + ratio * 0.5); + speed_threshold2TextField.setText("" + ratio * 2); + speed_threshold3TextField.setText("" + ratio * 4); + } + catch (NumberFormatException e1) + { + + } + } + + } + + @Override + public void keyTyped(KeyEvent e) + { + + } +}