public void train(List<Sample> samples) {
   BLEBeacon.setBLEBeaconIdsToSamples(bleBeacons, samples);
   List<List<Sample>> samplesList = Sample.samplesToConsecutiveSamplesList(samples);
   if (doHyperParameterOptimize) {
     doHyperParameterOptimize = false;
     trainWithHyperParameters(samplesList);
   }
   List<Sample> samplesAvaragedTrain = Sample.meanTrimList(samplesList, minRssi);
   this.trainByAveragedSamples(samplesAvaragedTrain);
 }
 boolean isSingleFloor(List<Sample> samples) {
   Set<Double> floorSet = new HashSet<>();
   for (Sample s : samples) {
     Location loc = s.getLocation();
     double z = loc.getZ();
     floorSet.add(z);
   }
   if (floorSet.size() == 1) {
     return true;
   } else {
     return false;
   }
 }
  protected void trainWithHyperParameters(List<List<Sample>> samplesListTrainParent) {
    List<Sample> samplesAvaragedTrain = Sample.meanTrimList(samplesListTrainParent, minRssi);
    this.train(samplesAvaragedTrain);
    // Update active beacon list about actually observed beacons
    Sample samplesAllAverage = Sample.mean(samplesAvaragedTrain, minRssi);
    List<Beacon> observedBeacons = samplesAllAverage.getBeacons();
    this.setActiveBeaconList(ModelAdaptUtils.beaconsToActiveBeaconArray(observedBeacons));

    double stdevTmp = stdev;
    this.setStdev(0.0); // stdev is set to be zero before optimization of LDPL model
    this.optimizeForLDPLModel();

    this.setStdev(stdevTmp); // stdev must be updated before optimization of GP
    this.optimizeForGPIsoScaleLOOMSE(); // optimize for lx(=ly) and stdev
    this.optimizeEstimateSigmaN(
        Sample.samplesListToSamples(samplesListTrainParent)); // estimate sigmaN

    this.train(samplesAvaragedTrain);
  }