Skip to content

Commit

Permalink
refactor: removed offline fingerprint node
Browse files Browse the repository at this point in the history
  • Loading branch information
Maximvdw committed Mar 5, 2021
1 parent 44f675b commit c2282a5
Show file tree
Hide file tree
Showing 29 changed files with 18,527 additions and 169,060 deletions.
6 changes: 6 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@
"@commitlint/config-conventional": "^11.0.0",
"@openhps/core": "^0.3.0-alpha.7",
"@openhps/csv": "0.1.0-alpha.61",
"@openhps/imu": "0.1.0-alpha.1",
"@types/chai": "^4.2.14",
"@types/mocha": "^8.2.0",
"@types/node": "^12.19.9",
Expand Down
14 changes: 7 additions & 7 deletions src/data/Fingerprint.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { SerializableMember, SerializableObject, DataObject, RelativePosition } from '@openhps/core';
import { v4 as uuidv4 } from 'uuid';
import { FingerprintValue } from './FingerprintValue';
import { FingerprintFeature } from './FingerprintFeature';

@SerializableObject()
export class Fingerprint extends DataObject {
Expand All @@ -15,8 +15,8 @@ export class Fingerprint extends DataObject {
}

public addRelativePosition(rel: RelativePosition<any>): void {
if (rel instanceof FingerprintValue) {
rel.referenceValue.forEach(val => {
if (rel instanceof FingerprintFeature) {
rel.referenceValue.forEach((val) => {
this.addValue(rel.referenceObjectUID, val);
});
} else {
Expand All @@ -25,9 +25,9 @@ export class Fingerprint extends DataObject {
}

public addValue(key: string, value: number): void {
let fingerprintValue: FingerprintValue = this.getRelativePosition(key);
let fingerprintValue: FingerprintFeature = this.getRelativePosition(key);
if (!fingerprintValue) {
fingerprintValue = new FingerprintValue(key, []);
fingerprintValue = new FingerprintFeature(key, []);
super.addRelativePosition(fingerprintValue);
}
fingerprintValue.referenceValue.push(value);
Expand All @@ -52,10 +52,10 @@ export class Fingerprint extends DataObject {
this.vector = [];
super.relativePositions
// Sort alphabetically
.sort((a: FingerprintValue, b: FingerprintValue) =>
.sort((a: FingerprintFeature, b: FingerprintFeature) =>
a.referenceObjectUID.localeCompare(b.referenceObjectUID),
)
.map((rel: FingerprintValue) => {
.map((rel: FingerprintFeature) => {
this.vector.push(aggFn(rel.referenceValue, rel.referenceObjectUID));
});
}
Expand Down
10 changes: 8 additions & 2 deletions src/data/FingerprintValue.ts → src/data/FingerprintFeature.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,18 @@
import { RelativePosition, SerializableObject, SerializableMember, SerializableArrayMember, DataSerializer } from '@openhps/core';
import {
RelativePosition,
SerializableObject,
SerializableMember,
SerializableArrayMember,
DataSerializer,
} from '@openhps/core';

/**
* Relative value to another reference object.
*
* @category Position
*/
@SerializableObject()
export class FingerprintValue implements RelativePosition<number[]> {
export class FingerprintFeature implements RelativePosition<number[]> {
/**
* Position recording timestamp
*/
Expand Down
2 changes: 1 addition & 1 deletion src/data/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
export * from './Fingerprint';
export * from './FingerprintValue';
export * from './FingerprintFeature';
52 changes: 49 additions & 3 deletions src/nodes/FingerprintingNode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import { FingerprintingOptions, FingerprintService } from '../service/Fingerprin
*
* @category Processing node
*/
export abstract class FingerprintingNode<
export class FingerprintingNode<
InOut extends DataFrame,
F extends Fingerprint = Fingerprint
> extends ObjectProcessingNode<InOut> {
Expand Down Expand Up @@ -56,14 +56,30 @@ export abstract class FingerprintingNode<
return this.service.cachedReferences;
}

public processObject(dataObject: DataObject, dataFrame: InOut): Promise<DataObject> {
return new Promise((resolve, reject) => {
if (dataObject.position !== undefined && !this.options.locked) {
this.offlineFingerprinting(dataObject, dataFrame).then(resolve).catch(reject);
} else if (dataObject.relativePositions.length > 0) {
this.onlineFingerprinting(dataObject, dataFrame).then(resolve).catch(reject);
} else {
resolve(dataObject);
}
});
}

/**
* Online fingerprinting
* Use relative positions to retrieve a position.
*
* @param {DataObject} dataObject Data object to reverse fingerprint
* @param {DataFrame} dataFrame Data frame this data object was included in
*/
protected abstract onlineFingerprinting(dataObject: DataObject, dataFrame: InOut): Promise<DataObject>;
protected onlineFingerprinting(dataObject: DataObject, dataFrame: InOut): Promise<DataObject> {
return new Promise((resolve) => {
resolve(dataObject);
});
}

/**
* Offline fingerprinting
Expand All @@ -73,7 +89,36 @@ export abstract class FingerprintingNode<
* @param {DataFrame} dataFrame Data frame this data object was included in
* @returns {Promise<DataObject>} Data object promise
*/
protected abstract offlineFingerprinting(dataObject: DataObject, dataFrame: InOut): Promise<DataObject>;
protected offlineFingerprinting(dataObject: DataObject, dataFrame: InOut): Promise<DataObject> {
return new Promise((resolve, reject) => {
// Create a fingerprint at the current position
const fingerprint = new Fingerprint();
fingerprint.source = dataObject;
fingerprint.createdTimestamp = dataFrame.createdTimestamp;
fingerprint.position = dataObject.position;
fingerprint.classifier = this.serviceOptions.classifier;

// Add relative positions that will define the fingerprint
dataObject.relativePositions.filter(this.options.valueFilter).forEach((relativePosition) => {
// Do not add relative position if reference value is unusable
if (relativePosition.referenceValue !== undefined && !isNaN(relativePosition.referenceValue)) {
fingerprint.addRelativePosition(relativePosition);
}
});

if (fingerprint.relativePositions.length > 0) {
// Store the fingerprint
this.service
.insertObject(fingerprint as any)
.then(() => {
resolve(dataObject);
})
.catch(reject);
} else {
resolve(dataObject);
}
});
}

public on(name: string | symbol, listener: (...args: any[]) => void): this;
/**
Expand All @@ -90,6 +135,7 @@ export abstract class FingerprintingNode<
}

export interface FingerprintingNodeOptions extends ObjectProcessingNodeOptions {
locked?: boolean;
/**
* Fingerprint classifier
*
Expand Down
11 changes: 4 additions & 7 deletions src/nodes/KNNFingerprintingNode.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,23 @@
import { FingerprintingNodeOptions } from './FingerprintingNode';
import { FingerprintingNode, FingerprintingNodeOptions } from './FingerprintingNode';
import { DataFrame, DataObject, RelativePosition, AbsolutePosition, Vector3, RelativeValue } from '@openhps/core';
import { WeightFunction } from './WeightFunction';
import { KDTree } from '../utils/KDTree';
import { OnlineFingerprintingNode } from './OnlineFingerprintingNode';
import { DistanceFunction } from './DistanceFunction';

/**
* KNN Fingerprinting processing node
*
* @category Processing node
*/
export class KNNFingerprintingNode<InOut extends DataFrame> extends OnlineFingerprintingNode<InOut> {
export class KNNFingerprintingNode<InOut extends DataFrame> extends FingerprintingNode<InOut> {
protected options: KNNFingerprintingOptions;
protected kdtree: KDTree;

constructor(options: KNNFingerprintingOptions) {
super(options);

// Default options
this.options.locked = this.options['locked'] !== undefined ? this.options['locked'] : true;
this.options.k = this.options.k || 1;
this.options.similarityFunction = this.options.similarityFunction || DistanceFunction.EUCLIDEAN;
this.options.weightFunction = this.options.weightFunction || WeightFunction.DEFAULT;
Expand All @@ -40,10 +40,7 @@ export class KNNFingerprintingNode<InOut extends DataFrame> extends OnlineFinger
// used for the fingerprinting
this.cachedReferences.forEach((relativeObject) => {
if (!dataObject.hasRelativePosition(relativeObject)) {
dataObject.addRelativePosition(new RelativeValue(
relativeObject,
this.serviceOptions.defaultValue
));
dataObject.addRelativePosition(new RelativeValue(relativeObject, this.serviceOptions.defaultValue));
}
});

Expand Down
58 changes: 0 additions & 58 deletions src/nodes/OfflineFingerprintingNode.ts

This file was deleted.

18 changes: 0 additions & 18 deletions src/nodes/OnlineFingerprintingNode.ts

This file was deleted.

2 changes: 0 additions & 2 deletions src/nodes/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
export * from './FingerprintingNode';
export * from './KNNFingerprintingNode';
export * from './OfflineFingerprintingNode';
export * from './WeightFunction';
export * from './OnlineFingerprintingNode';
export * from './DistanceFunction';
16 changes: 3 additions & 13 deletions src/service/FingerprintService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ export class FingerprintService<T extends Fingerprint = Fingerprint> extends Dat
super(dataServiceDriver);
this.options = options || {};
this.name = this.options.classifier.length > 0 ? this.options.classifier : this.name;
this.options.aggFn = this.options.aggFn || ((values: number[]) => values.reduce((a, b) => a + b) / values.length);
this.options.aggFn =
this.options.aggFn || ((values: number[]) => values.reduce((a, b) => a + b) / values.length);
this.once('ready', this.update.bind(this));
}

Expand Down Expand Up @@ -61,9 +62,6 @@ export class FingerprintService<T extends Fingerprint = Fingerprint> extends Dat
this.cachedReferences = new Set();

fingerprints.forEach((fingerprint) => {
// Extract features
fingerprint.relativePositions = this.featureExtraction(fingerprint.relativePositions);

// Cache all known reference objects
fingerprint.relativePositions.forEach((relativePosition) => {
if (!this.cachedReferences.has(relativePosition.referenceObjectUID))
Expand Down Expand Up @@ -104,22 +102,14 @@ export class FingerprintService<T extends Fingerprint = Fingerprint> extends Dat
// Complete missing references
this.cachedReferences.forEach((relativeObject) => {
if (!fingerprint.hasRelativePosition(relativeObject)) {
fingerprint.addRelativePosition(
new RelativeValue(
relativeObject,
this.options.defaultValue
));
fingerprint.addRelativePosition(new RelativeValue(relativeObject, this.options.defaultValue));
}
});
fingerprint.computeVector(this.options.aggFn);
this.cache.push(fingerprint);
});
}
}

protected featureExtraction(rel: Array<RelativeValue>): Array<RelativeValue> {
return rel;
}
}

export interface FingerprintingOptions {
Expand Down
22 changes: 8 additions & 14 deletions src/service/MagFingerprintService.ts
Original file line number Diff line number Diff line change
@@ -1,31 +1,25 @@
import { DataServiceDriver, RelativeValue } from "@openhps/core";
import { Fingerprint } from "../data";
import { FingerprintingOptions, FingerprintService } from "./FingerprintService";
import { DataServiceDriver, RelativeValue } from '@openhps/core';
import { Fingerprint } from '../data';
import { FingerprintingOptions, FingerprintService } from './FingerprintService';

export class MagFingerprintService extends FingerprintService<Fingerprint> {

constructor(driver: DataServiceDriver<string, Fingerprint>, options?: FingerprintingOptions) {
super(driver, options)
super(driver, options);
this.options.aggFn = this.aggregationFn;
}

protected featureExtraction(rel: Array<RelativeValue>): Array<RelativeValue> {
return rel;
}

protected aggregationFn(values: number[], key: string): number {
switch (key) {
case "MAG_X":
case "MAG_Y":
case "MAG_Z":
case 'MAG_X':
case 'MAG_Y':
case 'MAG_Z':
// Apply gaussian distribution filtering

// Use the mean value after gaussian filter
return values.reduce((a, b) => a + b, 0) / values.length;
default:
// Use mean value for all other features
return values.reduce((a, b) => a + b, 0) / values.length;
}
}

}
Loading

0 comments on commit c2282a5

Please sign in to comment.