/** * Iterates through the provided list and classifies the mobility mode for each list item. * * @param sensorDataPoints the data points to classify * @return a list of ClassifiedPoints. The list will be in the same order as the provided list. * @throws IllegalArgumentException if the provided list is null */ public static List<ClassifiedPoint> classify(List<SensorDataPoint> sensorDataPoints) { if (sensorDataPoints == null) { throw new IllegalArgumentException("sensorDataPoints is required"); } if (sensorDataPoints.contains(null)) { throw new IllegalArgumentException("sensorDataPoints contains null"); } List<ClassifiedPoint> classifiedPoints = new ArrayList<ClassifiedPoint>(); // This could be an instance variable because it is stateless MobilityClassifier mobilityClassifier = new MobilityClassifier(); WifiScan previousWifiScan = null; String previousMode = null; for (SensorDataPoint sensorDataPoint : sensorDataPoints) { Classification classification = mobilityClassifier.classify( sensorDataPoint.getAccelerometerSamples(), sensorDataPoint.getSpeed(), sensorDataPoint.getWifiScan(), previousWifiScan, previousMode); previousWifiScan = sensorDataPoint.getWifiScan(); previousMode = classification.getMode(); classifiedPoints.add(new ClassifiedPoint(sensorDataPoint.getId(), classification)); } return classifiedPoints; }
/** * Runs the classifier against all of the Mobility points in the list. * * @param mobilityPoints The Mobility points that are to be classified by the server. * @throws ServiceException Thrown if there is an error with the classification service. */ public void classifyData(final String uploadersUsername, final List<MobilityPoint> mobilityPoints) throws ServiceException { // If the list is empty, just exit. if (mobilityPoints == null) { return; } // Create a new classifier. MobilityClassifier classifier = new MobilityClassifier(); // Create place holders for the previous data. String previousWifiMode = null; List<WifiScan> previousWifiScans = new LinkedList<WifiScan>(); // This is a bit more involved now that we are doing everything through // the observers. /* if(mobilityPoints.size() > 0) { try { MobilityPoint firstPoint = mobilityPoints.get(0); DateTime startDate = new DateTime(); startDate = new DateTime( firstPoint.getTime() - MAX_MILLIS_OF_PREVIOUS_WIFI_DATA); List<MobilityPoint> previousPoints = userMobilityQueries.getMobilityInformation( uploadersUsername, startDate, new DateTime(firstPoint.getTime()), null, null, null); for(MobilityPoint previousPoint : previousPoints) { try { previousWifiScans.add(previousPoint.getWifiScan()); } catch(DomainException e) { // This point does not have a WifiScan, so we will skip // it. } } } catch(DataAccessException e) { throw new ServiceException(e); } } */ // For each of the Mobility points, for (MobilityPoint mobilityPoint : mobilityPoints) { // If the data point is of type error, don't attempt to classify // it. if (mobilityPoint.getMode().equals(Mode.ERROR)) { continue; } // If the SubType is sensor data, if (MobilityPoint.SubType.SENSOR_DATA.equals(mobilityPoint.getSubType())) { SensorData currSensorData = mobilityPoint.getSensorData(); // Get the Samples from this new point. List<Sample> samples; try { samples = mobilityPoint.getSamples(); } catch (DomainException e) { throw new ServiceException("There was a problem retrieving the samples.", e); } // Get the new WifiScan from this new point. WifiScan wifiScan; if (mobilityPoint.getSensorData().getWifiData() == null) { wifiScan = null; } else { try { wifiScan = mobilityPoint.getWifiScan(); } catch (DomainException e) { throw new ServiceException("The Mobility point does not contain WiFi data.", e); } } // Prune out the old WifiScans that are more than 10 minutes // old. long minPreviousTime = mobilityPoint.getTime() - MAX_MILLIS_OF_PREVIOUS_WIFI_DATA; Iterator<WifiScan> previousWifiScansIter = previousWifiScans.iterator(); while (previousWifiScansIter.hasNext()) { if (previousWifiScansIter.next().getTime() < minPreviousTime) { previousWifiScansIter.remove(); } else { // Given the fact that the list is ordered, we can now // be assured that all of the remaining WiFi scans are // invalid. break; } } // Classify the data. Classification classification = classifier.classify( samples, currSensorData.getSpeed(), wifiScan, previousWifiScans, previousWifiMode); // Update the place holders for the previous data. if (wifiScan != null) { previousWifiScans.add(wifiScan); } previousWifiMode = classification.getWifiMode(); // If the classification generated some results, pull them out // and store them in the Mobility point. if (classification.hasFeatures()) { try { mobilityPoint.setClassifierData( classification.getFft(), classification.getVariance(), classification.getAverage(), MobilityPoint.Mode.valueOf(classification.getMode().toUpperCase())); } catch (DomainException e) { throw new ServiceException( "There was a problem reading the classification's information.", e); } } // If the features don't exist, then create the classifier data // with only the mode. else { try { mobilityPoint.setClassifierModeOnly( MobilityPoint.Mode.valueOf(classification.getMode().toUpperCase())); } catch (DomainException e) { throw new ServiceException("There was a problem reading the classification's mode.", e); } } } } }