예제 #1
0
  // methods
  public Detector calibrateParameters(Detector d) {

    if (d.getHealthStatus() != 100) { // assign NaN if detector is bad
      vf = Double.NaN;
      w = Double.NaN;
      q_max = Double.NaN;
    } else {
      // organize into an array of DataPoint
      ArrayList<DataPoint> datavec = new ArrayList<DataPoint>();
      int i;
      for (i = 0; i < d.getDensityData().size(); i++)
        datavec.add(
            new DataPoint(
                d.getDensityData().get(i), d.getFlowData().get(i), d.getSpeedData().get(i)));

      // maximum flow and its corresponding density
      DataPoint maxflw = new DataPoint(0, Double.NEGATIVE_INFINITY, 0);
      for (i = 0; i < d.getFlowData().size(); i++)
        if (datavec.get(i).flw > maxflw.flw) maxflw.setval(datavec.get(i));

      q_max = maxflw.flw;

      // split data into congested and freeflow regimes ...............
      ArrayList<DataPoint> congestion = new ArrayList<DataPoint>(); // congestion states
      ArrayList<DataPoint> freeflow = new ArrayList<DataPoint>(); // freeflow states
      for (i = 0; i < d.getDensityData().size(); i++)
        if (datavec.get(i).dty >= maxflw.dty) congestion.add(datavec.get(i));
        else freeflow.add(datavec.get(i));

      // vf is the average freeflow speed
      vf = percentile("spd", freeflow, 0.5f);

      // compute critical density
      rho_crit = q_max / vf;

      // BINNING
      ArrayList<DataPoint> supercritical = new ArrayList<DataPoint>(); // data points above rho_crit
      for (i = 0; i < d.getDensityData().size(); i++)
        if (datavec.get(i).dty >= rho_crit) supercritical.add(datavec.get(i));

      // sort supercritical w.r.t. density
      Collections.sort(supercritical);

      int numsupercritical = supercritical.size();
      int Bin_width = 10;
      int step = Bin_width;
      ArrayList<DataPoint> BinData = new ArrayList<DataPoint>();
      for (i = 0; i < numsupercritical; i += Bin_width) {

        if (i + Bin_width >= numsupercritical) step = numsupercritical - i;

        if (step != 0) {
          List<DataPoint> Bin = (List<DataPoint>) supercritical.subList(i, i + step);
          if (!Bin.isEmpty()) {
            double a = 2.5f * percentile("flw", Bin, 0.75f) - 1.5f * percentile("flw", Bin, 0.25f);
            double b = percentile("flw", Bin, 1f);
            BinData.add(new DataPoint(percentile("dty", Bin, 0.5f), Math.min(a, b), Float.NaN));
          }
        }
      }

      // Do constrained LS
      ArrayList<Double> ai = new ArrayList<Double>();
      ArrayList<Double> bi = new ArrayList<Double>();
      for (i = 0; i < BinData.size(); i++) {
        bi.add(q_max - BinData.get(i).flw);
        ai.add(BinData.get(i).dty - rho_crit);
      }

      if (BinData.size() > 0) {
        float sumaibi = 0;
        float sumaiai = 0;
        for (i = 0; i < BinData.size(); i++) {
          sumaibi += ai.get(i) * bi.get(i);
          sumaiai += ai.get(i) * ai.get(i);
        }
        w = (double) (sumaibi / sumaiai);
        w = Math.max(w, w_min);
        w = Math.min(w, w_max);
      } else {
        w = Double.NaN;
      }
    }
    // store parameters in sensor
    d.setFdParams(new FDParameters()); // assigns nominal
    d.getFdParams().setFD(vf, w, q_max); // assigns calculated values, keeps nominals if NaN
    return d;
  }