Skip to content

Commit

Permalink
fix!: improve types in zones functions
Browse files Browse the repository at this point in the history
  • Loading branch information
targos authored and lpatiny committed Feb 26, 2024
1 parent 034d68a commit 3c72b05
Show file tree
Hide file tree
Showing 3 changed files with 119 additions and 107 deletions.
128 changes: 63 additions & 65 deletions src/zones/__tests__/zonesWithPoints.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,75 +2,73 @@ import { FromTo } from 'cheminfo-types';

import { zonesWithPoints } from '../zonesWithPoints';

describe('zonesWithPoints', () => {
it('no zones', () => {
const zones: FromTo[] = [];
const result = zonesWithPoints(zones, 1024);
expect(result).toStrictEqual([]);
});
test('no zones', () => {
const zones: FromTo[] = [];
const result = zonesWithPoints(zones, 1024);
expect(result).toStrictEqual([]);
});

it('one zone', () => {
const zones = [{ from: 0, to: 10 }];
const result = zonesWithPoints(zones, 1024);
expect(result).toStrictEqual([{ from: 0, to: 10, numberOfPoints: 1024 }]);
});
test('one zone', () => {
const zones = [{ from: 0, to: 10 }];
const result = zonesWithPoints(zones, 1024);
expect(result).toStrictEqual([{ from: 0, to: 10, numberOfPoints: 1024 }]);
});

it('two zones', () => {
const zones = [
{ from: 0, to: 1 },
{ from: 4, to: 5 },
];
const result = zonesWithPoints(zones, 1024);
expect(result).toStrictEqual([
{ from: 0, to: 1, numberOfPoints: 512 },
{ from: 4, to: 5, numberOfPoints: 512 },
]);
});
test('two zones', () => {
const zones = [
{ from: 0, to: 1 },
{ from: 4, to: 5 },
];
const result = zonesWithPoints(zones, 1024);
expect(result).toStrictEqual([
{ from: 0, to: 1, numberOfPoints: 512 },
{ from: 4, to: 5, numberOfPoints: 512 },
]);
});

it('two asymmetric zones', () => {
const zones = [
{ from: 0, to: 1 },
{ from: 4, to: 7 },
];
const result = zonesWithPoints(zones, 1024);
expect(result).toStrictEqual([
{ from: 0, to: 1, numberOfPoints: 256 },
{ from: 4, to: 7, numberOfPoints: 768 },
]);
});
test('two asymmetric zones', () => {
const zones = [
{ from: 0, to: 1 },
{ from: 4, to: 7 },
];
const result = zonesWithPoints(zones, 1024);
expect(result).toStrictEqual([
{ from: 0, to: 1, numberOfPoints: 256 },
{ from: 4, to: 7, numberOfPoints: 768 },
]);
});

it('two asymmetric zones with from, to', () => {
const zones = [
{ from: 0, to: 1 },
{ from: 4, to: 7 },
];
const result = zonesWithPoints(zones, 1024, { from: 2, to: 10 });
expect(result).toStrictEqual([{ from: 4, to: 7, numberOfPoints: 1024 }]);
});
test('two asymmetric zones with from, to', () => {
const zones = [
{ from: 0, to: 1 },
{ from: 4, to: 7 },
];
const result = zonesWithPoints(zones, 1024, { from: 2, to: 10 });
expect(result).toStrictEqual([{ from: 4, to: 7, numberOfPoints: 1024 }]);
});

it('tree asymmetric zones with overlap', () => {
const zones = [
{ from: 0, to: 1 },
{ from: 0, to: 3 },
{ from: 4, to: 7 },
];
const result = zonesWithPoints(zones, 1024);
expect(result).toStrictEqual([
{ from: 0, to: 3, numberOfPoints: 512 },
{ from: 4, to: 7, numberOfPoints: 512 },
]);
});
test('tree asymmetric zones with overlap', () => {
const zones = [
{ from: 0, to: 1 },
{ from: 0, to: 3 },
{ from: 4, to: 7 },
];
const result = zonesWithPoints(zones, 1024);
expect(result).toStrictEqual([
{ from: 0, to: 3, numberOfPoints: 512 },
{ from: 4, to: 7, numberOfPoints: 512 },
]);
});

it('tree asymmetric zones with touch', () => {
const zones = [
{ from: 0, to: 1 },
{ from: 1, to: 3 },
{ from: 4, to: 7 },
];
const result = zonesWithPoints(zones, 1024);
expect(result).toStrictEqual([
{ from: 0, to: 3, numberOfPoints: 512 },
{ from: 4, to: 7, numberOfPoints: 512 },
]);
});
test('tree asymmetric zones with touch', () => {
const zones = [
{ from: 0, to: 1 },
{ from: 1, to: 3 },
{ from: 4, to: 7 },
];
const result = zonesWithPoints(zones, 1024);
expect(result).toStrictEqual([
{ from: 0, to: 3, numberOfPoints: 512 },
{ from: 4, to: 7, numberOfPoints: 512 },
]);
});
32 changes: 18 additions & 14 deletions src/zones/zonesNormalize.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,22 @@
/* eslint-disable max-lines-per-function */

import { FromTo } from 'cheminfo-types';

export interface ZonesNormalizeOptions {
/** specify min value of zones
* @default Number.NEGATIVE_INFINITY
*/
from?: number;
/** specify max value of zones
* @default Number.POSITIVE_INFINITY
*/
to?: number;
/**
* List of exclusion zones
*/
exclusions?: FromTo[];
}

/**
* Normalize an array of zones:
* - ensure than from < to
Expand All @@ -12,20 +29,7 @@ import { FromTo } from 'cheminfo-types';
*/
export function zonesNormalize(
zones: FromTo[] = [],
options: {
/** specify min value of zones
* @default Number.NEGATIVE_INFINITY
*/
from?: number;
/** specify max value of zones
* @default Number.POSITIVE_INFINITY
*/
to?: number;
/**
* List of exclusion zones
*/
exclusions?: FromTo[];
} = {},
options: ZonesNormalizeOptions = {},
): FromTo[] {
const { exclusions = [] } = options;
let { from = Number.NEGATIVE_INFINITY, to = Number.POSITIVE_INFINITY } =
Expand Down
66 changes: 38 additions & 28 deletions src/zones/zonesWithPoints.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,22 @@
import { FromTo } from 'cheminfo-types';

import { zonesNormalize } from './zonesNormalize';

export interface ZonesWithPointsOptions {
/** specify min value of zones
* @default Number.NEGATIVE_INFINITY
*/
from?: number;
/** specify max value of zones
* @default Number.POSITIVE_INFINITY
*/
to?: number;
}

export interface FromToWithNumberOfPoints extends FromTo {
numberOfPoints: number;
}

/**
* Add the number of points per zone to reach a specified total
*
Expand All @@ -9,49 +26,42 @@ import { zonesNormalize } from './zonesNormalize';
* @returns array of zones with points
*/
export function zonesWithPoints(
zones: Array<{
/** start of zone*/
from: number;
/** end of zone */
to: number;
}> = [],
zones: FromTo[] = [],
/**
* total number of points to distribute between zones
* @default 10
*/
numberOfPoints = 10,
options: {
/** specify min value of zones
* @default Number.NEGATIVE_INFINITY
*/
from?: number;
/** specify max value of zones
* @default Number.POSITIVE_INFINITY
*/
to?: number;
} = {},
): Array<{ from: number; to: number; numberOfPoints?: number }> {
if (zones.length === 0) return zones;
const returnZones = zonesNormalize(zones, options);

const totalSize = returnZones.reduce((previous, current) => {
options: ZonesWithPointsOptions = {},
): FromToWithNumberOfPoints[] {
if (zones.length === 0) return [];
const normalizedZones = zonesNormalize(zones, options);
const zonesWithNumberOfPoints: FromToWithNumberOfPoints[] = [];

const totalSize = normalizedZones.reduce((previous, current) => {
return previous + (current.to - current.from);
}, 0);

const unitsPerPoint = totalSize / numberOfPoints;
let currentTotal = 0;

for (let i = 0; i < returnZones.length - 1; i++) {
const tempZone: any = returnZones[i];
tempZone.numberOfPoints = Math.min(
for (let i = 0; i < normalizedZones.length - 1; i++) {
const tempZone = normalizedZones[i];
const tempZoneNumberOfPoints = Math.min(
Math.round((tempZone.to - tempZone.from) / unitsPerPoint),
numberOfPoints - currentTotal,
);
currentTotal += tempZone.numberOfPoints;
zonesWithNumberOfPoints.push({
...tempZone,
numberOfPoints: tempZoneNumberOfPoints,
});
currentTotal += tempZoneNumberOfPoints;
}

const zone: any = returnZones[returnZones.length - 1];
zone.numberOfPoints = numberOfPoints - currentTotal;
zonesWithNumberOfPoints.push({
...normalizedZones[normalizedZones.length - 1],
numberOfPoints: numberOfPoints - currentTotal,
});

return returnZones;
return zonesWithNumberOfPoints;
}

0 comments on commit 3c72b05

Please sign in to comment.