Ejemplo n.º 1
0
  public void addImageTab(Path imagePath) {

    TabPane previewTabPane = controller.getPreviewTabPane();

    ImageTab tab = new ImageTab();
    tab.setPath(imagePath);
    tab.setText(imagePath.getFileName().toString());

    if (previewTabPane.getTabs().contains(tab)) {
      previewTabPane.getSelectionModel().select(tab);
      return;
    }

    Image image = new Image(IOHelper.pathToUrl(imagePath));
    ImageView imageView = new ImageView(image);
    imageView.setPreserveRatio(true);

    imageView.setFitWidth(previewTabPane.getWidth());

    previewTabPane
        .widthProperty()
        .addListener(
            (observable, oldValue, newValue) -> {
              imageView.setFitWidth(previewTabPane.getWidth());
            });

    Tooltip tip = new Tooltip(imagePath.toString());
    Tooltip.install(tab.getGraphic(), tip);

    ScrollPane scrollPane = new ScrollPane();
    scrollPane.setVbarPolicy(ScrollPane.ScrollBarPolicy.AS_NEEDED);
    scrollPane.setHbarPolicy(ScrollPane.ScrollBarPolicy.AS_NEEDED);
    scrollPane.setContent(imageView);
    scrollPane.addEventFilter(
        ScrollEvent.SCROLL,
        e -> {
          if (e.isControlDown() && e.getDeltaY() > 0) {
            // zoom in
            imageView.setFitWidth(imageView.getFitWidth() + 16.0);
          } else if (e.isControlDown() && e.getDeltaY() < 0) {
            // zoom out
            imageView.setFitWidth(imageView.getFitWidth() - 16.0);
          }
        });

    tab.setContent(scrollPane);

    TabPane tabPane = previewTabPane;
    tabPane.getTabs().add(tab);
    tabPane.getSelectionModel().select(tab);
  }
  /**
   * Called after the controls have been parsed from the XML. Sets up logic and components that
   * could not be set up using the GUI builder.
   */
  @Override
  public void initialize(URL url, ResourceBundle rb) {

    // the transformedTrajectory provides a view of the trajectory that reflects the selected
    // transformedTrajectory
    transformedTrajectory =
        new Cacheable<double[][]>() {
          private int eachKthPoint;
          private int embeddingDimension, embeddingDelay;
          private double noiseRatio;

          private int getSubsampleLength() {
            int prefixLength = (int) (subsampleLengthSlider.getValue() * trajectory[0].length);
            // per started block of k elements, one output element will be generated
            int k = getEachKthPoint();
            // full blocks + 1 block if there is a fractional block
            return prefixLength / k + (prefixLength % k > 0 ? 1 : 0);
          }

          @Override
          public synchronized boolean isValid() {
            if (cachedValue == null) return false;
            if (eachKthPoint != getEachKthPoint()) return false;
            // any embedding dimension <= 0 signifies that no embedding should be used, thus the
            // actual dimension does not matter
            if (getEmbeddingDimension() > 0 && (embeddingDimension != getEmbeddingDimension()))
              return false;
            // for an embedding dimension of <= 1, the delay is insignificant
            if (getEmbeddingDimension() > 1 && (embeddingDelay != getEmbeddingDelay()))
              return false;
            if (getNoiseRatio() != noiseRatio) return false;
            return trajectory == null
                || cachedValue == null
                || getSubsampleLength() == cachedValue[0].length;
          }

          @Override
          public synchronized void recompute() {
            if (trajectory == null) cachedValue = null;
            else {
              // create an empty array with the desired number of dimensions
              cachedValue = new double[trajectory.length][];
              eachKthPoint = getEachKthPoint();

              // crop to sampling size
              int newLength = getSubsampleLength();
              for (int dimIdx = 0; dimIdx < trajectory.length; dimIdx++) {
                cachedValue[dimIdx] =
                    new double[newLength]; // Arrays.copyOf(trajectory[dimIdx], newLength);
                for (int i = 0, t = 0; i < newLength; i++, t += eachKthPoint) {
                  cachedValue[dimIdx][i] = trajectory[dimIdx][t];
                }
              }

              int dim = getEmbeddingDimension();
              int tau = getEmbeddingDelay();
              double noiseRatio = getNoiseRatio();

              if (dim > 0 && tau > 0) {
                cachedValue = PhaseSpaceReconstructed.embed(cachedValue[0], dim, tau);
              }

              cachedValue = TimeSeriesGenerator.addNoise(cachedValue, 0.05, noiseRatio);

              this.noiseRatio = noiseRatio;
              this.embeddingDimension = dim;
              this.embeddingDelay = tau;
            }
          }
        };

    // sync recurrence threshold slider and text field
    Bindings.bindBidirectional(
        recurrenceThresholdTextField.textProperty(),
        recurrenceThresholdSlider.valueProperty(),
        DecimalFormat.getInstance());
    // sync GUI and model recurrence threshold
    Bindings.bindBidirectional(
        recurrenceThresholdTextField.textProperty(),
        recurrenceThresholdProperty(),
        DecimalFormat.getInstance());

    // sync GUI and model embedding parameters
    Bindings.bindBidirectional(
        embeddingDimensionTextField.textProperty(),
        embeddingDimensionProperty(),
        DecimalFormat.getIntegerInstance());
    Bindings.bindBidirectional(
        embeddingDelayTextField.textProperty(),
        embeddingDelayProperty(),
        DecimalFormat.getIntegerInstance());

    // sync GUI and noise parameter
    Bindings.bindBidirectional(noiseSlider.valueProperty(), noiseRatioProperty());

    Bindings.bindBidirectional(
        eachKthPointTextField.textProperty(),
        eachKthPointProperty(),
        DecimalFormat.getIntegerInstance());

    // enable the compute button only if the auto-update checkbox is not on.
    computeRPButton.disableProperty().bind(sliderAutoUpdate.selectedProperty());

    // recompute RP on parameter changes
    subsampleLengthSlider.valueProperty().addListener(this::parametersChanged);
    eachKthPointTextField
        .textProperty()
        .addListener(
            (obs, ov, nv) -> {
              parametersChanged(null, null, null);
            });
    recurrenceThresholdProperty().addListener(this::parametersChanged);
    embeddingDimensionProperty().addListener(this::parametersChanged);
    embeddingDelayProperty().addListener(this::parametersChanged);
    noiseRatioProperty().addListener(this::parametersChanged);

    // Make CRT controls update the computation
    // size of the CRT histogram
    crtLimit
        .textProperty()
        .addListener(
            new ChangeListener<String>() {
              @Override
              public void changed(
                  ObservableValue<? extends String> observable, String oldValue, String newValue) {
                parametersChanged(null, Integer.parseInt(oldValue), Integer.parseInt(newValue));
              }
            });
    // CRT log scale option
    logScaleCheckBox
        .selectedProperty()
        .addListener(
            new ChangeListener<Boolean>() {
              @Override
              public void changed(
                  ObservableValue<? extends Boolean> observable,
                  Boolean oldValue,
                  Boolean newValue) {
                if (oldValue != newValue) parametersChanged(null, 0, 0);
              }
            });

    // make the CRT image use all the available vertical space
    crtImageView.fitWidthProperty().bind(crtTabPane.widthProperty().subtract(20));
    crtImageView.fitHeightProperty().bind(crtTabPane.heightProperty());

    // swap the data of the line length histogram upon selecting another line type
    lineLengthTypeSelector.setItems(
        FXCollections.observableArrayList(
            "DIAGONAL",
            "VERTICAL",
            "WHITE_VERTICAL",
            "ORTHOGONAL")); // DRQA.LineType.DIAGONAL, DRQA.LineType.VERTICAL,
                            // DRQA.LineType.WHITE_VERTICAL, DRQA.LineType.ORTHOGONAL
    lineLengthTypeSelector
        .getSelectionModel()
        .selectedIndexProperty()
        .addListener(this::updateLineLengthHistogram);
    lineLengthTypeSelector.getSelectionModel().select(0);

    distanceDistributionSelector.setItems(FXCollections.observableArrayList("SUBSEQ", "PAIRWISE"));
    distanceDistributionSelector
        .getSelectionModel()
        .selectedIndexProperty()
        .addListener((obs, ov, nv) -> updateDistanceDistributionChart());
    distanceDistributionSelector.getSelectionModel().select(0);

    useDRQA
        .selectedProperty()
        .addListener(
            (obs, ov, nv) ->
                updateLineLengthHistogram(
                    null, null, lineLengthTypeSelector.getSelectionModel().getSelectedIndex()));
  }