-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathDictionary.ts
141 lines (127 loc) · 4.17 KB
/
Dictionary.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
/*
* Copyright (c) 2016 - now David Sehnal, licensed under MIT License, See LICENSE file for more info.
*/
namespace CIFTools {
"use strict";
/**
* Represents a "CIF FILE" with one or more data blocks.
*/
export interface File {
dataBlocks: DataBlock[];
toJSON(): any;
}
/**
* Represents a single CIF data block that contains categories and possibly
* additonal data such as save frames.
*
* Example:
* data_HEADER
* _category1.field1
* ...
* ...
* _categoryN.fieldN
*/
export interface DataBlock {
header: string;
categories: Category[];
additionalData: { [name: string]: any };
getCategory(name: string): Category | undefined;
toJSON(): any;
}
/**
* Represents that CIF category with multiple fields represented as columns.
*
* Example:
* _category.field1
* _category.field2
* ...
*/
export interface Category {
name: string;
rowCount: number;
columnCount: number;
columnNames: string[];
/**
* If a field with the given name is not present, returns UndefinedColumn.
*
* Columns are accessed by their field name only, i.e.
* _category.field is accessed by
* category.getColumn('field')
*
* Note that column are created on demand and there is some computational
* cost when creating a new column. Therefore, if you need to reuse a column,
* it is a good idea to cache it.
*/
getColumn(name: string): Column;
toJSON(): any;
}
export const enum ValuePresence {
Present = 0,
NotSpecified = 1,
Unknown = 2
}
/**
* A columns represents a single field of a CIF category.
*/
export interface Column {
isDefined: boolean;
getString(row: number): string | null;
getInteger(row: number): number;
getFloat(row: number): number;
getValuePresence(row: number): ValuePresence;
areValuesEqual(rowA: number, rowB: number): boolean;
stringEquals(row: number, value: string): boolean;
}
/**
* Represents a column that is not present.
*/
class _UndefinedColumn implements Column {
isDefined = false;
getString(row: number): string | null { return null; };
getInteger(row: number): number { return 0; }
getFloat(row: number): number { return 0.0; }
getValuePresence(row: number): ValuePresence { return ValuePresence.NotSpecified; }
areValuesEqual(rowA: number, rowB: number): boolean { return true; }
stringEquals(row: number, value: string): boolean { return value === null; }
}
export const UndefinedColumn = <Column>new _UndefinedColumn();
/**
* Helper functions for categoies.
*/
export namespace Category {
/**
* Extracts a matrix from a category from a specified rowIndex.
*
* _category.matrix[1][1] v11
* ....
* ....
* _category.matrix[rows][cols] vRowsCols
*/
export function getMatrix(category: Category, field: string, rows: number, cols: number, rowIndex: number) {
let ret: number[][] = [];
for (let i = 1; i <= rows; i++) {
let row: number[] = [];
for (let j = 1; j <= cols; j++) {
row[j - 1] = category.getColumn(field + "[" + i + "][" + j + "]").getFloat(rowIndex);
}
ret[i - 1] = row;
}
return ret;
}
/**
* Extracts a vector from a category from a specified rowIndex.
*
* _category.matrix[1][1] v11
* ....
* ....
* _category.matrix[rows][cols] vRowsCols
*/
export function getVector(category: Category, field: string, rows: number, cols: number, rowIndex: number): number[] {
let ret: number[] = [];
for (let i = 1; i <= rows; i++) {
ret[i - 1] = category.getColumn(field + "[" + i + "]").getFloat(rowIndex);
}
return ret;
}
}
}