Skip to content
Snippets Groups Projects
Commit 4fa48983 authored by David Sehnal's avatar David Sehnal
Browse files

"nomial types" for Element and Element.Index

parent e0283d88
No related branches found
No related tags found
No related merge requests found
......@@ -50,11 +50,11 @@ export function projectValue({ segments }: Segmentation, set: OrderedSet, value:
return OrderedSet.findRange(set, OrderedSet.getAt(segments, idx), OrderedSet.getAt(segments, idx + 1) - 1);
}
export class SegmentIterator implements Iterator<Segs.Segment> {
export class SegmentIterator<T extends number = number> implements Iterator<Segs.Segment<T>> {
private segmentMin = 0;
private segmentMax = 0;
private setRange = Interval.Empty;
private value: Segs.Segment = { index: 0, start: 0, end: 0 };
private value: Segs.Segment<T> = { index: 0, start: 0, end: 0 };
hasNext: boolean = false;
......@@ -94,7 +94,7 @@ export class SegmentIterator implements Iterator<Segs.Segment> {
this.hasNext = this.segmentMax >= this.segmentMin;
}
setSegment(segment: Segs.Segment) {
setSegment(segment: Segs.Segment<T>) {
this.setRange = Interval.ofBounds(segment.start, segment.end);
this.updateSegmentRange();
}
......
......@@ -9,48 +9,48 @@ import * as Impl from './impl/interval'
namespace Interval {
export const Empty: Interval = Impl.Empty as any;
export const ofSingleton: (value: number) => Interval = (v) => Impl.ofRange(v, v) as any;
export const ofSingleton: <T extends number = number>(value: T) => Interval<T> = (v) => Impl.ofRange(v, v) as any;
/** Create interval from range [min, max] */
export const ofRange: (min: number, max: number) => Interval = Impl.ofRange as any;
export const ofRange: <T extends number = number>(min: T, max: T) => Interval<T> = Impl.ofRange as any;
/** Create interval from bounds [start, end), i.e. [start, end - 1] */
export const ofBounds: (start: number, end: number) => Interval = Impl.ofBounds as any;
export const is: (v: any) => v is Interval = Impl.is as any;
export const ofBounds: <T extends number = number>(start: T, end: T) => Interval<T> = Impl.ofBounds as any;
export const is: <T extends number = number>(v: any) => v is Interval<T> = Impl.is as any;
/** Test if a value is within the bounds of the interval */
export const has: (interval: Interval, x: number) => boolean = Impl.has as any;
export const indexOf: (interval: Interval, x: number) => number = Impl.indexOf as any;
export const getAt: (interval: Interval, i: number) => number = Impl.getAt as any;
/** Start value of the interval, same as min value */
export const start: (interval: Interval) => number = Impl.start as any;
/** End value of the interval, same as max + 1 */
export const end: (interval: Interval) => number = Impl.end as any;
/** Min value of the interval, same as start value */
export const min: (interval: Interval) => number = Impl.min as any;
/** Max value of the interval, same as end - 1 */
export const max: (interval: Interval) => number = Impl.max as any;
export const has: <T extends number = number>(interval: Interval<T>, x: T) => boolean = Impl.has as any;
export const indexOf: <T extends number = number>(interval: Interval<T>, x: T) => number = Impl.indexOf as any;
export const getAt: <T extends number = number>(interval: Interval<T>, i: number) => T = Impl.getAt as any;
/** Start value of the Interval<T>, same as min value */
export const start: <T extends number = number>(interval: Interval<T>) => T = Impl.start as any;
/** End value of the Interval<T>, same as max + 1 */
export const end: <T extends number = number>(interval: Interval<T>) => T = Impl.end as any;
/** Min value of the Interval<T>, same as start value */
export const min: <T extends number = number>(interval: Interval<T>) => T = Impl.min as any;
/** Max value of the Interval<T>, same as end - 1 */
export const max: <T extends number = number>(interval: Interval<T>) => T = Impl.max as any;
/** Number of values in the interval */
export const size: (interval: Interval) => number = Impl.size as any;
export const size: <T extends number = number>(interval: Interval<T>) => number = Impl.size as any;
/** Hash code describing the interval */
export const hashCode: (interval: Interval) => number = Impl.hashCode as any;
export const hashCode: <T extends number = number>(interval: Interval<T>) => number = Impl.hashCode as any;
/** Test if two intervals are identical */
export const areEqual: (a: Interval, b: Interval) => boolean = Impl.areEqual as any;
export const areEqual: <T extends number = number>(a: Interval<T>, b: Interval<T>) => boolean = Impl.areEqual as any;
/** Test if two intervals are intersecting, i.e. their bounds overlap */
export const areIntersecting: (a: Interval, b: Interval) => boolean = Impl.areIntersecting as any;
export const areIntersecting: <T extends number = number>(a: Interval<T>, b: Interval<T>) => boolean = Impl.areIntersecting as any;
/** Test if interval b is fully included in interval a */
export const isSubInterval: (a: Interval, b: Interval) => boolean = Impl.isSubInterval as any;
export const isSubInterval: <T extends number = number>(a: Interval<T>, b: Interval<T>) => boolean = Impl.isSubInterval as any;
export const findPredecessorIndex: (interval: Interval, x: number) => number = Impl.findPredecessorIndex as any;
export const findPredecessorIndexInInterval: (interval: Interval, x: number, bounds: Interval) => number = Impl.findPredecessorIndexInInterval as any;
export const findRange: (interval: Interval, min: number, max: number) => Interval = Impl.findRange as any;
export const findPredecessorIndex: <T extends number = number>(interval: Interval<T>, x: T) => number = Impl.findPredecessorIndex as any;
export const findPredecessorIndexInInterval: <T extends number = number>(interval: Interval<T>, x: T, bounds: Interval) => number = Impl.findPredecessorIndexInInterval as any;
export const findRange: <T extends number = number>(interval: Interval<T>, min: T, max: T) => Interval = Impl.findRange as any;
/** Get a new interval that is the intersection of the two intervals */
export const intersect: (a: Interval, b: Interval) => Interval = Impl.intersect as any;
export const intersect: <T extends number = number>(a: Interval<T>, b: Interval<T>) => Interval<T> = Impl.intersect as any;
}
/** Interval describing a range [min, max] of values */
interface Interval { '@type': 'int-interval' }
interface Interval<T extends number = number> { '@type': 'int-interval' }
export default Interval
\ No newline at end of file
......@@ -40,9 +40,17 @@ namespace OrderedSet {
export function forEach<T extends number, Ctx>(set: OrderedSet<T>, f: (v: T, i: number, ctx: Ctx) => void, ctx?: Ctx): Ctx {
return Base.forEach(set as any, f as any, ctx);
}
export function isInterval<T extends number = number>(set: OrderedSet<T>): set is Interval<T> {
return Interval.is(set);
}
export function isSortedArray<T extends number = number>(set: OrderedSet<T>): set is SortedArray<T> {
return !Interval.is(set);
}
}
type OrderedSet<T extends number = number> = Interval | SortedArray<T>
type OrderedSet<T extends number = number> = Interval<T> | SortedArray<T>
//{ '@type': 'int-interval' | 'int-sorted-array' }
export default OrderedSet
\ No newline at end of file
......@@ -9,22 +9,22 @@ import OrderedSet from './ordered-set'
import * as Impl from './impl/segmentation'
namespace Segmentation {
export interface Segment { index: number, start: number, end: number }
export interface Segment<T extends number = number> { index: number, start: number, end: number }
export const create: (segs: ArrayLike<number>) => Segmentation = Impl.create as any;
export const ofOffsets: (offsets: ArrayLike<number>, bounds: Interval) => Segmentation = Impl.ofOffsets as any;
export const create: <T extends number = number>(segs: ArrayLike<T>) => Segmentation<T> = Impl.create as any;
export const ofOffsets: <T extends number = number>(offsets: ArrayLike<T>, bounds: Interval) => Segmentation<T> = Impl.ofOffsets as any;
export const count: (segs: Segmentation) => number = Impl.count as any;
export const getSegment: (segs: Segmentation, value: number) => number = Impl.getSegment as any;
export const projectValue: (segs: Segmentation, set: OrderedSet, value: number) => Interval = Impl.projectValue as any;
export const count: <T extends number = number>(segs: Segmentation<T>) => number = Impl.count as any;
export const getSegment: <T extends number = number>(segs: Segmentation<T>, value: T) => number = Impl.getSegment as any;
export const projectValue: <T extends number = number>(segs: Segmentation<T>, set: OrderedSet<T>, value: T) => Interval = Impl.projectValue as any;
// Segment iterator that mutates a single segment object to mark all the segments.
export const transientSegments: (segs: Segmentation, set: OrderedSet, segment?: Segment) => Impl.SegmentIterator = Impl.segments as any;
export const transientSegments: <T extends number = number>(segs: Segmentation<T>, set: OrderedSet<T>, segment?: Segment<T>) => Impl.SegmentIterator = Impl.segments as any;
}
interface Segmentation {
interface Segmentation<T extends number = number> {
'@type': 'segmentation',
readonly segments: ArrayLike<number>,
readonly segments: ArrayLike<T>,
readonly segmentMap: ArrayLike<number>,
readonly count: number
}
......
......@@ -23,6 +23,7 @@ import { getSecondaryStructureMmCif } from './mmcif/secondary-structure';
import { getSequence } from './mmcif/sequence';
import { sortAtomSite } from './mmcif/sort';
import { mmCIF_Database, mmCIF_Schema } from 'mol-io/reader/cif/schema/mmcif';
import { Element } from '../../../structure'
import mmCIF_Format = Format.mmCIF
type AtomSite = mmCIF_Database['atom_site']
......@@ -40,7 +41,7 @@ function findHierarchyOffsets(atom_site: AtomSite) {
if (atom_site._rowCount === 0) return { residues: [], chains: [] };
const start = 0, end = atom_site._rowCount;
const residues = [start], chains = [start];
const residues = [start as Element], chains = [start as Element];
const { label_entity_id, label_asym_id, label_seq_id, auth_seq_id, pdbx_PDB_ins_code, label_comp_id } = atom_site;
......@@ -52,8 +53,8 @@ function findHierarchyOffsets(atom_site: AtomSite) {
|| !pdbx_PDB_ins_code.areValuesEqual(i - 1, i)
|| !label_comp_id.areValuesEqual(i - 1, i);
if (newResidue) residues[residues.length] = i;
if (newChain) chains[chains.length] = i;
if (newResidue) residues[residues.length] = i as Element;
if (newChain) chains[chains.length] = i as Element;
}
return { residues, chains };
}
......
......@@ -12,6 +12,7 @@ import { getCoarseKeys } from '../../properties/utils/coarse-keys';
import { UUID } from 'mol-util';
import { Segmentation, Interval } from 'mol-data/int';
import { Mat3, Tensor } from 'mol-math/linear-algebra';
import { Element } from '../../../structure'
export function getIHMCoarse(data: mmCIF, entities: Entities): { hierarchy: CoarseHierarchy, conformation: CoarseConformation } {
if (data.ihm_model_list._rowCount === 0) return { hierarchy: CoarseHierarchy.Empty, conformation: void 0 as any };
......@@ -71,9 +72,9 @@ function getGaussianConformation(data: mmCIF['ihm_gaussian_obj_site']): CoarseGa
}
function getChainSegments(asym_id: Column<string>) {
const offsets = [0];
const offsets = [0 as Element];
for (let i = 1, _i = asym_id.rowCount; i < _i; i++) {
if (!asym_id.areValuesEqual(i - 1, i)) offsets[offsets.length] = i;
if (!asym_id.areValuesEqual(i - 1, i)) offsets[offsets.length] = i as Element;
}
return Segmentation.ofOffsets(offsets, Interval.ofBounds(0, asym_id.rowCount));
......
......@@ -7,7 +7,8 @@
import { Column, Table } from 'mol-data/db'
import { Segmentation } from 'mol-data/int'
import { mmCIF_Schema as mmCIF } from 'mol-io/reader/cif/schema/mmcif'
import { ElementSymbol} from '../../types'
import { ElementSymbol } from '../../types'
import { Element } from '../../../structure'
export const AtomsSchema = {
type_symbol: Column.Schema.Aliased<ElementSymbol>(mmCIF.atom_site.type_symbol),
......@@ -47,8 +48,8 @@ export interface AtomicData {
}
export interface AtomicSegments {
residueSegments: Segmentation,
chainSegments: Segmentation
residueSegments: Segmentation<Element>,
chainSegments: Segmentation<Element>
// TODO: include entity segments?
}
......
......@@ -7,6 +7,7 @@
import { mmCIF_Database as mmCIF } from 'mol-io/reader/cif/schema/mmcif'
import { Column } from 'mol-data/db'
import { Segmentation } from 'mol-data/int';
import { Element } from '../../../structure'
export interface CoarsedElementKeys {
// assign a key to each element
......@@ -27,7 +28,7 @@ export interface CoarseElementData {
seq_id_begin: Column<number>,
seq_id_end: Column<number>,
chainSegments: Segmentation
chainSegments: Segmentation<Element>
}
export type CoarseElements = CoarsedElementKeys & CoarseElementData
......
......@@ -6,7 +6,7 @@
import { Segmentation } from 'mol-data/int';
import { RuntimeContext } from 'mol-task';
import { Structure, Unit, Element } from '../structure';
import { Structure, Unit } from '../structure';
import Query from './query';
import Selection from './selection';
import { UniqueStructuresBuilder } from './utils/builders';
......@@ -29,7 +29,7 @@ function getWholeResidues(ctx: RuntimeContext, source: Structure, structure: Str
while (residuesIt.hasNext) {
const rI = residuesIt.move().index;
for (let j = residueSegments.segments[rI], _j = residueSegments.segments[rI + 1]; j < _j; j++) {
builder.addElement(j as Element);
builder.addElement(j);
}
}
builder.commitUnit();
......
......@@ -17,18 +17,6 @@ namespace Element {
export type Index = { readonly '@type': 'element-index' } & number
export type Indices = OrderedSet<Index>
// export interface Packed { '@type': Tuple['@type'] }
// export namespace Packed {
// export const Zero: Packed = Tuple.Zero;
// export const create: (unit: number, index: number) => Packed = Tuple.create;
// export const is: (x: any) => x is Packed = Tuple.is;
// export const unitId: (e: Packed) => number = Tuple.fst;
// export const elementIndex: (e: Packed) => number = Tuple.snd;
// export const areEqual: (e: Packed, b: Packed) => boolean = Tuple.areEqual;
// export const hashCode: (e: Packed) => number = Tuple.hashCode;
// export function createEmptyArray(n: number): Packed[] { return new Float64Array(n) as any; }
// }
/** All the information required to access element properties */
export interface Location<U = Unit> {
unit: U,
......
......@@ -19,6 +19,7 @@ export class StructureLookup3D {
return this.unitLookup.find(x, y, z, radius);
}
// TODO: find another efficient way how to implement this instead of using "tuple".
// find(x: number, y: number, z: number, radius: number): Result<Element.Packed> {
// Result.reset(this.result);
// const { units } = this.structure;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment