public double NburstsError() {
   PatternFeature feature = expSpikePatternData.getnBursts();
   double error =
       patternClassifier.getDynamicFeatWeightMatrix().get(PatternFeatureID.nbursts)
           * NormalizedErrorObsNormed(feature, modelSpikePattern.getBurstPattern().getNBursts());
   displayRoutine(
       PatternFeatureID.nbursts, feature, modelSpikePattern.getBurstPattern().getNBursts(), error);
   return error;
 }
 public double NSpikesErrorObsNormed() {
   PatternFeature feature = expSpikePatternData.getnSpikes();
   // double minError = 0;
   // double maxError = expSpikePatternData.getCurrentDuration();
   double error =
       patternClassifier.getDynamicFeatWeightMatrix().get(PatternFeatureID.n_spikes)
           * NormalizedErrorObsNormed(feature, modelSpikePattern.getNoOfSpikes());
   displayRoutine(PatternFeatureID.n_spikes, feature, modelSpikePattern.getNoOfSpikes(), error);
   return error;
 }
 public double PSSError() {
   PatternFeature feature = expSpikePatternData.getPss();
   double minError = 0;
   double maxError = expSpikePatternData.getCurrentDuration();
   double error =
       patternClassifier.getDynamicFeatWeightMatrix().get(PatternFeatureID.pss)
           * NormalizedError(feature, modelSpikePattern.getPSS(), minError, maxError);
   displayRoutine(PatternFeatureID.pss, feature, modelSpikePattern.getPSS(), error);
   return error;
 }
 public double FSLErrorObsNormed() {
   //	System.out.println("SPE:: fsl Error entry..");
   PatternFeature feature = expSpikePatternData.getFsl();
   // double minError = 0;
   // double maxError = expSpikePatternData.getCurrentDuration();
   double error =
       patternClassifier.getDynamicFeatWeightMatrix().get(PatternFeatureID.fsl)
           * NormalizedErrorObsNormed(feature, modelSpikePattern.getFSL());
   displayRoutine(PatternFeatureID.fsl, feature, modelSpikePattern.getFSL(), error);
   return error;
 }
  public double sfaError() {

    int nPieceWiseParmsExp = expSpikePatternData.getSpikePatternClass().getnPieceWiseParms();
    int nPieceWiseParmsModel = patternClassifier.getSpikePatternClass().getnPieceWiseParms();
    double possibleWeightForFutureNEAR = nPieceWiseParmsExp - nPieceWiseParmsModel; // coarse!!

    double error = 0;
    double minError = 0;
    double maxMerror = 1;
    double maxCerror = 2;
    double maxNsfaError = expSpikePatternData.getCurrentDuration() * 0.3;

    SolverResultsStat modelStats =
        patternClassifier.getSolverResultsStats()[nPieceWiseParmsExp - 1];
    int modelNsfaISIs1 = modelStats.getBreakPoint();
    int modelNsfaISIs2 = modelSpikePattern.getISIs().length - modelNsfaISIs1;
    double[] model =
        new double[] {
          modelStats.getM1(),
          modelStats.getM2(),
          modelStats.getC1(),
          modelStats.getC2(),
          modelNsfaISIs1,
          modelNsfaISIs2
        };
    double[] exp =
        new double[] {
          expSpikePatternData.getSfaLinearM1().getValue(),
          expSpikePatternData.getSfaLinearM2().getValue(),
          expSpikePatternData.getSfaLinearb1().getValue(),
          expSpikePatternData.getSfaLinearb2().getValue(),
          expSpikePatternData.getNSfaISIs1().getValue(),
          expSpikePatternData.getNSfaISIs2().getValue(),
        };

    for (int i = 0; i < 6; i++) {
      if (i < 2) { // slopes
        error += StatUtil.calculate0to1NormalizedError(exp[i], model[i], minError, maxMerror);
      } else {
        if (i < 4) { // intercepts
          error += StatUtil.calculate0to1NormalizedError(exp[i], model[i], minError, maxCerror);
        } else {
          error += StatUtil.calculate0to1NormalizedError(exp[i], model[i], minError, maxNsfaError);
        }
      }
    }

    error =
        patternClassifier.getDynamicFeatWeightMatrix().get(PatternFeatureID.n_sfa_isis2) * error;

    if (display) {
      displayRoutineForSFA(null, model, error);
    }
    return error;
  }
  public SpikePatternEvaluatorV2(
      SpikePatternAdapting modelSpikePattern,
      InputSpikePatternConstraint expSpikePatternData,
      double[] patternRepWeights,
      double modelVmin,
      double modelVr,
      double modelVt,
      boolean display,
      boolean displayOnlyClass,
      boolean externalSimUsed) {
    this.modelSpikePattern = modelSpikePattern;
    this.expSpikePatternData = expSpikePatternData;
    this.patternRepairWeights = patternRepWeights;
    this.modelVmin = modelVmin;
    this.modelVr = modelVr;
    this.modelVt = modelVt;
    this.display = display;

    /*if(display){
    	StatAnalyzer.display_stats = true;
    }*/
    patternClassifier = new SpikePatternClassifier(modelSpikePattern);
    if (externalSimUsed) { // HACK!!! no voltage for swa
      modelSpikePattern.setSwa(1);
    } else {
      modelSpikePattern.setSwa(measureSWA());
    }

    double swa = modelSpikePattern.getSwa(); // 1;//

    patternClassifier.classifySpikePattern(swa, true); // 1);//
    if (display || displayOnlyClass) {
      patternClassifier.getSpikePatternClass().display();
    }

    if (!ECJStarterV2.TURN_OFF_CLASSIFIER) {
      patternClassifier.determineWeightsForFeatures(expSpikePatternData.getSpikePatternClass());
    } else {
      patternClassifier.populateNullWeights();
    }
  }
  public double reboundVmaxErrorObsNormed() {
    PatternFeature feature = expSpikePatternData.getReboundVmax();
    double timeStart = expSpikePatternData.getTimeMin() + expSpikePatternData.getCurrentDuration();
    double timeEnd =
        (expSpikePatternData.getTimeMin() * 2) + expSpikePatternData.getCurrentDuration();
    double modelReboundVmax =
        modelSpikePattern.getSpikePatternData().getPeakVoltage(timeStart, timeEnd, 10);
    modelReboundVmax = modelReboundVmax - modelVr;
    double rBoundFeatWeight = 1;

    if (modelReboundVmax <= 0) {
      rBoundFeatWeight += 1;
    }

    double error = rBoundFeatWeight * NormalizedErrorObsNormed(feature, modelReboundVmax);
    displayRoutine(PatternFeatureID.rebound_VMax, feature, modelReboundVmax, error);
    return error;
  }
 private double measureSWA() {
   double swa = 0;
   double[] ISIs = modelSpikePattern.getISIs();
   if (ISIs == null || ISIs.length == 0) {
     return swa;
   }
   double timeMin = modelSpikePattern.getTimeMin() + modelSpikePattern.getFSL();
   double timeMax =
       modelSpikePattern.getTimeMin() + modelSpikePattern.getDurationOfCurrentInjection() - 5;
   double minVolt =
       modelSpikePattern.getModelSpikePatternData().getMinVoltage(timeMin, timeMax, 1);
   swa = modelVmin - minVolt;
   return swa;
 }
 private float spikesBelowVrestError(float vR) {
   double avgBelowVrestOffset = modelSpikePattern.calculateAvgBelowVrest(vR);
   return (float) StatUtil.calculateObsNormalizedError(0, avgBelowVrestOffset);
 }
 /*
  * other non-feature errors; like avoid bursting...
  */
 private float nonBurstBelowVminError(float vMin) {
   double avgBelowVminOffset = modelSpikePattern.calculateAvgBelowVminAfterLastSpike(vMin, 200);
   return (float) StatUtil.calculateObsNormalizedError(0, avgBelowVminOffset);
 }
  private double singleBurstError(
      int burstIdx, HashMap<BurstFeatureID, Double> expSingleBurstFeatures) {
    if (burstIdx >= modelSpikePattern.getBurstPattern().getNBursts()) {
      return 1;
    }

    double errorBW = 0;
    double errorIBI = 0;
    double errorNspikes = 0;

    // 2. BW error
    double bw = -1;
    if (expSingleBurstFeatures.containsKey(BurstFeatureID.b_w)) {
      bw = expSingleBurstFeatures.get(BurstFeatureID.b_w);
      double modelBw = modelSpikePattern.getBurstPattern().getBW(burstIdx);
      errorBW = StatUtil.calculateObsNormalizedError(bw, modelBw);
    }

    // 3. IBI error
    double pbi = -1;
    if (expSingleBurstFeatures.containsKey(BurstFeatureID.pbi)) {
      pbi = expSingleBurstFeatures.get(BurstFeatureID.pbi);
      double modelPbi = modelSpikePattern.getBurstPattern().getIBI(burstIdx);
      errorIBI = StatUtil.calculateObsNormalizedError(pbi, modelPbi);
    }

    // 4. N spikes error
    double nspikes = expSingleBurstFeatures.get(BurstFeatureID.nspikes);
    errorNspikes =
        StatUtil.calculateObsNormalizedError(
            nspikes, modelSpikePattern.getBurstPattern().getNSpikes(burstIdx));

    /*
     * display
     */
    if (display) {
      System.out.print("\t");
      if (expSingleBurstFeatures.containsKey(BurstFeatureID.b_w)) {
        String displayString = "\tb_w\t" + GeneralUtils.formatTwoDecimal(bw);
        displayString +=
            "\t"
                + GeneralUtils.formatTwoDecimal(
                    modelSpikePattern.getBurstPattern().getBW(burstIdx));
        displayString += "\t" + GeneralUtils.formatThreeDecimal(errorBW) + "\t/";
        System.out.print(displayString);
      }

      if (expSingleBurstFeatures.containsKey(BurstFeatureID.pbi)) {
        String displayString = "\tibi\t" + GeneralUtils.formatTwoDecimal(pbi);
        displayString +=
            "\t"
                + GeneralUtils.formatTwoDecimal(
                    modelSpikePattern.getBurstPattern().getIBI(burstIdx));
        displayString += "\t" + GeneralUtils.formatThreeDecimal(errorIBI) + "\t/";
        System.out.print(displayString);
      }

      String displayString = "\tnspikes\t" + GeneralUtils.formatTwoDecimal(nspikes);
      displayString +=
          "\t"
              + GeneralUtils.formatTwoDecimal(
                  modelSpikePattern.getBurstPattern().getNSpikes(burstIdx));
      displayString += "\t" + GeneralUtils.formatThreeDecimal(errorNspikes) + "\t/";
      System.out.print(displayString + "\n");
    }

    return ((expSpikePatternData.getBurstFeatures().getFeatureWeight(BurstFeatureID.b_w) * errorBW)
        + (expSpikePatternData.getBurstFeatures().getFeatureWeight(BurstFeatureID.pbi) * errorIBI)
        + (expSpikePatternData.getBurstFeatures().getFeatureWeight(BurstFeatureID.nspikes)
            * errorNspikes));
  }
 public double fsl() {
   return modelSpikePattern.getFSL();
 }
  public double sfaErrorObsNormed() {
    // System.out.println("****"+sfa()+"****");
    // int nPieceWiseParmsExp = expSpikePatternData.getSpikePatternClass().getnPieceWiseParms();
    int nPieceWiseParmsModel = patternClassifier.getSpikePatternClass().getnPieceWiseParms();
    double error = 0;
    SolverResultsStat modelStats = null;
    if (nPieceWiseParmsModel > 0) { // ASP, NASP, X
      modelStats = patternClassifier.getSolverResultsStats()[nPieceWiseParmsModel - 1];
    } else { // ASP error for other comps. for example, TSWB
      patternClassifier.calculateAdaptationForNonSP(0);
      modelStats = patternClassifier.getSolverResultsStats()[1]; // idx 1 for linear regression
    }

    int modelNsfaISIs1 = 1 + modelStats.getBreakPoint(); // 0-based idx ; hence +1
    int modelNsfaISIs2 = modelSpikePattern.getISIs().length - modelNsfaISIs1; // remaining
    double[] model =
        new double[] {
          modelStats.getM1(),
          modelStats.getC1(),
          modelNsfaISIs1,
          modelStats.getM2(),
          modelStats.getC2(),
          modelNsfaISIs2
        };
    PatternFeature[] exp =
        new PatternFeature[] {
          expSpikePatternData.getSfaLinearM1(),
          expSpikePatternData.getSfaLinearb1(),
          expSpikePatternData.getNSfaISIs1(),
          expSpikePatternData.getSfaLinearM2(),
          expSpikePatternData.getSfaLinearb2(),
          expSpikePatternData.getNSfaISIs2()
        };

    // System.out.println(patternClassifier.getDynamicFeatWeightMatrix().size());
    float sfa1Weight =
        patternClassifier.getDynamicFeatWeightMatrix().get(PatternFeatureID.n_sfa_isis1);
    float sfa2weight =
        patternClassifier.getDynamicFeatWeightMatrix().get(PatternFeatureID.n_sfa_isis2);

    for (int i = 0; i < 6; i++) {
      // SFA 1
      if (i == 0) { // m1
        error += sfa1Weight * NormalizedErrorObsNormed(exp[i], model[i]);
        continue;
      }
      if (i == 1) { // b1
        error += sfa1Weight * NormalizedErrorObsNormed(exp[i], model[i]);
        continue;
      }
      if (i == 2) { // nsfaisis1		
        error += sfa1Weight * NormalizedErrorObsNormed(exp[i], model[i]);
        continue;
      }
      // SFA 2
      if (i == 3) { // m2
        error += sfa2weight * NormalizedErrorObsNormed(exp[i], model[i]);
        continue;
      }
      if (i == 4) { // b2
        error += sfa2weight * NormalizedErrorObsNormed(exp[i], model[i]);
        continue;
      }
      if (i == 5) { // nsfaisis 2
        error += sfa2weight * NormalizedErrorObsNormed(exp[i], model[i]);
        continue;
      }
    }

    if (display) {
      displayRoutineForSFA(exp, model, error);
    }
    return error;
  }
  private float patternWeightedAvgError() {
    float weightedError = 0;
    int count = 0;
    // SpikePatternEvaluator evaluator = new SpikePatternEvaluator(modelSpikePattern,
    // expSpikePatternData, display);
    Set<PatternFeatureID> patternFeatureIDs = expSpikePatternData.getFeaturesToEvaluate();
    if (patternFeatureIDs.contains(PatternFeatureID.bursts)
        || patternFeatureIDs.contains(PatternFeatureID.nbursts)
        || patternFeatureIDs.contains(PatternFeatureID.stuts)) {
      modelSpikePattern.initBurstPattern(2d);
    }
    for (PatternFeatureID feature : patternFeatureIDs) {
      /*
       * non spiking
       */
      if (feature == PatternFeatureID.fsl) {
        weightedError += FSLErrorObsNormed();
        // System.out.println("SPE:: fsl Error done..");
        count++;
      }
      if (feature == PatternFeatureID.pss) {
        weightedError += PSSErrorObsNormed();
        // System.out.println("SPE:: pss Error done..");
        count++;
      }

      /*
       * regular / Adaptation
       */
      if (feature == PatternFeatureID.n_sfa_isis1) {
        weightedError += sfaErrorObsNormed();
        // System.out.println("SPE:: n_sfa1 Error done.."+weightedError);
        count++;
      }

      if (feature == PatternFeatureID.n_spikes) {
        weightedError += NSpikesErrorObsNormed();
        // System.out.println("SPE:: nspikes Error done..");
        count++;
      }
      /*
       * stut
       */
      if (feature == PatternFeatureID.nbursts) {
        weightedError += NburstsError();
        count++;
      }
      if (feature == PatternFeatureID.bursts || feature == PatternFeatureID.stuts) {
        weightedError += burstFeatureError();
        count++;
      }
      if (feature == PatternFeatureID.vmin_offset) {
        weightedError += vMinOffsetError(modelVmin - modelVr);
        count++;
      }
      if (feature == PatternFeatureID.rebound_VMax) {
        weightedError += reboundVmaxErrorObsNormed();
        count++;
      }
      if (feature == PatternFeatureID.swa) {
        weightedError += swaErrorObsNormed();
        count++;
      }
    }

    return weightedError;
    //	return (weightedError/(count*1.0f));
  }
  public float calculatePatternError() {
    float patternError = Float.MAX_VALUE;
    float patternValidityErrorVmin = 0;
    float patternValidityErrorVrest = 0;

    if (modelSpikePattern == null) {
      if (display) {
        System.out.println(
            "**NULL compartment SPIKE PATTERN** SPEvaluatorV2:calculatePatternError()");
      }
      return patternError;
    }
    // && Math.abs(Float.MAX_VALUE - modelError)>10.0f
    if (checkForPatternValidity) {
      if (expSpikePatternData.getType() == PatternType.SPIKES) {
        // if(!modelSpikePattern.isValidSpikesPattern(modelVmin, modelVr)) { if(display) {
        // System.out.println("**Invalid SPIKEs Pattern**");	   }
        if (!modelSpikePattern.isValidSpikesPattern()) {
          if (display) {
            System.out.println("**Invalid SPIKEs Pattern** SPEvaluatorV2:calculatePatternError()");
          }
          return patternError;
        }
        /*else{
        //	    	if(!expSpikePatternData.getFeaturesToEvaluate().contains(PatternFeatureID.bursts))
        	    	{
        	    		patternValidityErrorVmin = nonBurstBelowVminError(modelVmin);
        	    	}
        	        patternValidityErrorVrest = spikesBelowVrestError(modelVr);
        	    }*/
        if (modelSpikePattern.getISIs() == null) {
          if (display) {
            System.out.println("**Null ISIs** SPEvaluatorV2:calculatePatternError()");
          }
          return patternError;
        }
      }
    } /*else{

        	if(modelSpikePattern.getSpikeTimes().length < 1
        			||
        		(modelSpikePattern.getSpikeTimes()[modelSpikePattern.getSpikeTimes().length-1] - modelSpikePattern.getTimeMin()) > (modelSpikePattern.getDurationOfCurrentInjection()+10))  {
      	return patternError;
      }
        	if(modelSpikePattern.getISIs() == null ) { if(display) {System.out.println("**Null ISIs**");      }
       			return patternError;
        	}
        }*/
    // System.out.println("SPE:: patternWeighted Avg Error will..");

    patternError = patternWeightedAvgError();
    // System.out.println("SPE:: patternWeighted Avg Error done..");

    float avgPatternError;
    if (expSpikePatternData.getType() == PatternType.SPIKES
        || expSpikePatternData.getType() == PatternType.RBASE) {
      avgPatternError =
          (float)
              (patternRepairWeights[0] * patternError
                  + patternRepairWeights[1] * patternValidityErrorVmin
                  + patternRepairWeights[2] * patternValidityErrorVrest);
    } else {
      avgPatternError = patternError;
    }
    if (display) {
      System.out.print(
          "\nPatternFeatError\t"
              + GeneralUtils.formatThreeDecimal(patternError)
              + "\nPatternValidityErrorVmin\t"
              + GeneralUtils.formatThreeDecimal(patternValidityErrorVmin)
              + "\nPatternValidityErrorVrest\t"
              + GeneralUtils.formatThreeDecimal(patternValidityErrorVrest));
    }
    return avgPatternError * expSpikePatternData.getPatternWeight();
  }