Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
M
Molstar
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package Registry
Container Registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Terms and privacy
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Michal Malý
Molstar
Commits
7bf4fe13
Commit
7bf4fe13
authored
6 years ago
by
Alexander Rose
Browse files
Options
Downloads
Patches
Plain Diff
wip, data format registry
parent
a2ba753a
No related branches found
Branches containing commit
No related tags found
Tags containing commit
No related merge requests found
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
src/mol-plugin/context.ts
+5
-0
5 additions, 0 deletions
src/mol-plugin/context.ts
src/mol-plugin/state/actions/basic.ts
+163
-74
163 additions, 74 deletions
src/mol-plugin/state/actions/basic.ts
with
168 additions
and
74 deletions
src/mol-plugin/context.ts
+
5
−
0
View file @
7bf4fe13
...
...
@@ -30,6 +30,7 @@ import { PLUGIN_VERSION, PLUGIN_VERSION_DATE } from './version';
import
{
PluginLayout
}
from
'
./layout
'
;
import
{
List
}
from
'
immutable
'
;
import
{
StateTransformParameters
}
from
'
./ui/state/common
'
;
import
{
DataFormatRegistry
}
from
'
./state/actions/basic
'
;
export
class
PluginContext
{
private
disposed
=
false
;
...
...
@@ -87,6 +88,10 @@ export class PluginContext {
themeCtx
:
{
colorThemeRegistry
:
ColorTheme
.
createRegistry
(),
sizeThemeRegistry
:
SizeTheme
.
createRegistry
()
}
as
ThemeRegistryContext
}
readonly
dataFormat
=
{
registry
:
new
DataFormatRegistry
()
}
readonly
customModelProperties
=
new
CustomPropertyRegistry
();
readonly
customParamEditors
=
new
Map
<
string
,
StateTransformParameters
.
Class
>
();
...
...
This diff is collapsed.
Click to expand it.
src/mol-plugin/state/actions/basic.ts
+
163
−
74
View file @
7bf4fe13
...
...
@@ -6,7 +6,7 @@
*/
import
{
PluginContext
}
from
'
mol-plugin/context
'
;
import
{
StateTree
,
Transformer
}
from
'
mol-state
'
;
import
{
StateTree
,
Transformer
,
StateObject
}
from
'
mol-state
'
;
import
{
StateAction
}
from
'
mol-state/action
'
;
import
{
StateSelection
}
from
'
mol-state/state/selection
'
;
import
{
StateTreeBuilder
}
from
'
mol-state/tree/builder
'
;
...
...
@@ -15,7 +15,7 @@ import { PluginStateObject } from '../objects';
import
{
StateTransforms
}
from
'
../transforms
'
;
import
{
Download
}
from
'
../transforms/data
'
;
import
{
StructureRepresentation3DHelpers
}
from
'
../transforms/representation
'
;
import
{
getFileInfo
,
FileIn
put
}
from
'
mol-util/file-info
'
;
import
{
getFileInfo
,
FileIn
fo
}
from
'
mol-util/file-info
'
;
import
{
Task
}
from
'
mol-task
'
;
// TODO: "structure/volume parser provider"
...
...
@@ -170,55 +170,128 @@ export const UpdateTrajectory = StateAction.build({
//
const
VolumeFormats
=
{
'
ccp4
'
:
''
,
'
mrc
'
:
''
,
'
map
'
:
''
,
'
dsn6
'
:
''
,
'
brix
'
:
''
,
'
dscif
'
:
''
}
type
VolumeFormat
=
keyof
typeof
VolumeFormats
function
getVolumeData
(
format
:
VolumeFormat
,
b
:
StateTreeBuilder
.
To
<
PluginStateObject
.
Data
.
Binary
|
PluginStateObject
.
Data
.
String
>
)
{
switch
(
format
)
{
case
'
ccp4
'
:
case
'
mrc
'
:
case
'
map
'
:
return
b
.
apply
(
StateTransforms
.
Data
.
ParseCcp4
).
apply
(
StateTransforms
.
Model
.
VolumeFromCcp4
);
case
'
dsn6
'
:
case
'
brix
'
:
return
b
.
apply
(
StateTransforms
.
Data
.
ParseDsn6
).
apply
(
StateTransforms
.
Model
.
VolumeFromDsn6
);
case
'
dscif
'
:
return
b
.
apply
(
StateTransforms
.
Data
.
ParseCif
).
apply
(
StateTransforms
.
Model
.
VolumeFromDensityServerCif
);
export
class
DataFormatRegistry
<
D
extends
PluginStateObject
.
Data
.
Binary
|
PluginStateObject
.
Data
.
String
,
M
extends
StateObject
>
{
private
_list
:
{
name
:
string
,
provider
:
DataFormatProvider
<
D
,
M
>
}[]
=
[]
private
_map
=
new
Map
<
string
,
DataFormatProvider
<
D
,
M
>>
()
get
default
()
{
return
this
.
_list
[
0
];
}
get
types
():
[
string
,
string
][]
{
return
this
.
_list
.
map
(
e
=>
[
e
.
name
,
e
.
provider
.
label
]
as
[
string
,
string
]);
}
}
function
createVolumeTree
(
format
:
VolumeFormat
,
ctx
:
PluginContext
,
b
:
StateTreeBuilder
.
To
<
PluginStateObject
.
Data
.
Binary
|
PluginStateObject
.
Data
.
String
>
):
StateTree
{
return
getVolumeData
(
format
,
b
)
.
apply
(
StateTransforms
.
Representation
.
VolumeRepresentation3D
)
// the parameters will be used automatically by the reconciler and the IsoValue object
// will get the correct Stats object instead of the empty one
// VolumeRepresentation3DHelpers.getDefaultParamsStatic(ctx, 'isosurface'))
.
getTree
();
}
constructor
()
{
this
.
add
(
'
ccp4
'
,
Ccp4Provider
)
this
.
add
(
'
dsn6
'
,
Dsn6Provider
)
this
.
add
(
'
dscif
'
,
DscifProvider
)
};
add
(
name
:
string
,
provider
:
DataFormatProvider
<
D
,
M
>
)
{
this
.
_list
.
push
({
name
,
provider
})
this
.
_map
.
set
(
name
,
provider
)
}
remove
(
name
:
string
)
{
this
.
_list
.
splice
(
this
.
_list
.
findIndex
(
e
=>
e
.
name
===
name
),
1
)
this
.
_map
.
delete
(
name
)
}
function
getFileFormat
(
format
:
VolumeFormat
|
'
auto
'
,
file
:
FileInput
,
data
?:
Uint8Array
):
VolumeFormat
{
if
(
format
===
'
auto
'
)
{
const
fileFormat
=
getFileInfo
(
file
).
ext
if
(
fileFormat
in
VolumeFormats
)
{
return
fileFormat
as
VolumeFormat
auto
(
info
:
FileInfo
,
dataStateObject
:
D
)
{
for
(
let
i
=
0
,
il
=
this
.
list
.
length
;
i
<
il
;
++
i
)
{
const
{
provider
}
=
this
.
_list
[
i
]
if
(
provider
.
isApplicable
(
info
,
dataStateObject
.
data
))
return
provider
}
throw
new
Error
(
'
no compatible data format provider available
'
)
}
get
(
name
:
string
):
DataFormatProvider
<
D
,
M
>
{
if
(
this
.
_map
.
has
(
name
))
{
return
this
.
_map
.
get
(
name
)
!
}
else
{
throw
new
Error
(
'
un
supported format
'
)
throw
new
Error
(
`
un
known data format name '
${
name
}
'`
)
}
}
else
{
return
format
}
get
list
()
{
return
this
.
_list
}
}
interface
DataFormatProvider
<
D
extends
PluginStateObject
.
Data
.
Binary
|
PluginStateObject
.
Data
.
String
,
M
extends
StateObject
>
{
label
:
string
description
:
string
fileExtensions
:
string
[]
isApplicable
(
info
:
FileInfo
,
data
:
string
|
Uint8Array
):
boolean
getDefaultBuilder
(
b
:
StateTreeBuilder
.
To
<
D
>
):
StateTreeBuilder
.
To
<
M
>
}
const
Ccp4Provider
:
DataFormatProvider
<
any
,
any
>
=
{
label
:
'
CCP4/MRC/BRIX
'
,
description
:
'
CCP4/MRC/BRIX
'
,
fileExtensions
:
[
'
ccp4
'
,
'
mrc
'
,
'
map
'
],
isApplicable
:
(
info
:
FileInfo
,
data
:
Uint8Array
)
=>
{
return
info
.
ext
===
'
ccp4
'
||
info
.
ext
===
'
mrc
'
||
info
.
ext
===
'
map
'
},
getDefaultBuilder
:
(
b
:
StateTreeBuilder
.
To
<
PluginStateObject
.
Data
.
Binary
>
)
=>
{
return
b
.
apply
(
StateTransforms
.
Data
.
ParseCcp4
)
.
apply
(
StateTransforms
.
Model
.
VolumeFromCcp4
)
.
apply
(
StateTransforms
.
Representation
.
VolumeRepresentation3D
)
}
}
const
Dsn6Provider
:
DataFormatProvider
<
any
,
any
>
=
{
label
:
'
DSN6/BRIX
'
,
description
:
'
DSN6/BRIX
'
,
fileExtensions
:
[
'
dsn6
'
,
'
brix
'
],
isApplicable
:
(
info
:
FileInfo
,
data
:
Uint8Array
)
=>
{
return
info
.
ext
===
'
dsn6
'
||
info
.
ext
===
'
brix
'
},
getDefaultBuilder
:
(
b
:
StateTreeBuilder
.
To
<
PluginStateObject
.
Data
.
Binary
>
)
=>
{
return
b
.
apply
(
StateTransforms
.
Data
.
ParseDsn6
)
.
apply
(
StateTransforms
.
Model
.
VolumeFromDsn6
)
.
apply
(
StateTransforms
.
Representation
.
VolumeRepresentation3D
)
}
}
const
DscifProvider
:
DataFormatProvider
<
any
,
any
>
=
{
label
:
'
DensityServer CIF
'
,
description
:
'
DensityServer CIF
'
,
fileExtensions
:
[
'
cif
'
],
isApplicable
:
(
info
:
FileInfo
,
data
:
Uint8Array
)
=>
{
return
info
.
ext
===
'
cif
'
},
getDefaultBuilder
:
(
b
:
StateTreeBuilder
.
To
<
PluginStateObject
.
Data
.
Binary
>
)
=>
{
return
b
.
apply
(
StateTransforms
.
Data
.
ParseCif
,
{
})
.
apply
(
StateTransforms
.
Model
.
VolumeFromDensityServerCif
)
.
apply
(
StateTransforms
.
Representation
.
VolumeRepresentation3D
)
}
}
//
function
getDataFormatExtensionsOptions
(
dataFormatRegistry
:
DataFormatRegistry
<
any
,
any
>
)
{
const
extensions
:
string
[]
=
[]
const
options
:
[
string
,
string
][]
=
[[
'
auto
'
,
'
Automatic
'
]]
dataFormatRegistry
.
list
.
forEach
(({
name
,
provider
})
=>
{
extensions
.
push
(...
provider
.
fileExtensions
)
options
.
push
([
name
,
provider
.
label
])
})
return
{
extensions
,
options
}
}
export
const
OpenVolume
=
StateAction
.
build
({
display
:
{
name
:
'
Open Volume
'
,
description
:
'
Load a volume from file and create its default visual
'
},
from
:
PluginStateObject
.
Root
,
params
:
{
file
:
PD
.
File
({
accept
:
'
.ccp4,.mrc,.map,.dsn6,.brix,.cif
'
}),
isBinary
:
PD
.
Boolean
(
true
),
format
:
PD
.
Select
(
'
auto
'
,
[
[
'
auto
'
,
'
Automatic
'
],
[
'
ccp4
'
,
'
CCP4
'
],
[
'
mrc
'
,
'
MRC
'
],
[
'
map
'
,
'
MAP
'
],
[
'
dsn6
'
,
'
DSN6
'
],
[
'
brix
'
,
'
BRIX
'
],
[
'
dscif
'
,
'
densityServerCIF
'
]
]),
params
:
(
a
,
ctx
:
PluginContext
)
=>
{
const
{
extensions
,
options
}
=
getDataFormatExtensionsOptions
(
ctx
.
dataFormat
.
registry
)
return
{
file
:
PD
.
File
({
accept
:
extensions
.
map
(
e
=>
`.
${
e
}
`
).
join
(
'
,
'
)}),
format
:
PD
.
Select
(
'
auto
'
,
options
),
isBinary
:
PD
.
Boolean
(
true
),
// TOOD should take selected format into account
}
}
})(({
params
,
state
},
ctx
:
PluginContext
)
=>
Task
.
create
(
'
Open Volume
'
,
async
taskCtx
=>
{
const
data
Tree
=
state
.
build
().
toRoot
().
apply
(
StateTransforms
.
Data
.
ReadFile
,
{
file
:
params
.
file
,
isBinary
:
true
});
const
volumeData
=
await
state
.
updateTree
(
data
Tree
).
runInContext
(
taskCtx
);
const
data
=
state
.
build
().
toRoot
().
apply
(
StateTransforms
.
Data
.
ReadFile
,
{
file
:
params
.
file
,
isBinary
:
params
.
isBinary
});
const
dataStateObject
=
await
state
.
updateTree
(
data
).
runInContext
(
taskCtx
);
// Alternative for more complex states where the builder is not a simple StateTreeBuilder.To<>:
/*
...
...
@@ -227,10 +300,11 @@ export const OpenVolume = StateAction.build({
const dataCell = state.select(dataRef)[0];
*/
const
format
=
getFileFormat
(
params
.
format
,
params
.
file
,
volumeData
.
data
as
Uint8Array
);
const
volumeTree
=
state
.
build
().
to
(
dataTree
.
ref
);
const
provider
=
params
.
format
===
'
auto
'
?
ctx
.
dataFormat
.
registry
.
auto
(
getFileInfo
(
params
.
file
),
dataStateObject
)
:
ctx
.
dataFormat
.
registry
.
get
(
params
.
format
)
const
b
=
state
.
build
().
to
(
data
.
ref
);
const
tree
=
provider
.
getDefaultBuilder
(
b
).
getTree
()
// need to await the 2nd update the so that the enclosing Task finishes after the update is done.
await
state
.
updateTree
(
createVolumeTree
(
format
,
ctx
,
volumeTree
)
).
runInContext
(
taskCtx
);
await
state
.
updateTree
(
tree
).
runInContext
(
taskCtx
);
}));
export
{
DownloadDensity
};
...
...
@@ -238,41 +312,40 @@ type DownloadDensity = typeof DownloadDensity
const
DownloadDensity
=
StateAction
.
build
({
from
:
PluginStateObject
.
Root
,
display
:
{
name
:
'
Download Density
'
,
description
:
'
Load a density from the provided source and create its default visual.
'
},
params
:
{
source
:
PD
.
MappedStatic
(
'
rcsb
'
,
{
'
pdbe
'
:
PD
.
Group
({
id
:
PD
.
Text
(
'
1tqn
'
,
{
label
:
'
Id
'
}),
type
:
PD
.
Select
(
'
2fofc
'
,
[[
'
2fofc
'
,
'
2Fo-Fc
'
],
[
'
fofc
'
,
'
Fo-Fc
'
]]),
},
{
isFlat
:
true
}),
'
rcsb
'
:
PD
.
Group
({
id
:
PD
.
Text
(
'
1tqn
'
,
{
label
:
'
Id
'
}),
type
:
PD
.
Select
(
'
2fofc
'
,
[[
'
2fofc
'
,
'
2Fo-Fc
'
],
[
'
fofc
'
,
'
Fo-Fc
'
]]),
},
{
isFlat
:
true
}),
'
url
'
:
PD
.
Group
({
url
:
PD
.
Text
(
''
),
isBinary
:
PD
.
Boolean
(
true
),
format
:
PD
.
Select
(
'
auto
'
,
[
[
'
auto
'
,
'
Automatic
'
],
[
'
ccp4
'
,
'
CCP4
'
],
[
'
mrc
'
,
'
MRC
'
],
[
'
map
'
,
'
MAP
'
],
[
'
dsn6
'
,
'
DSN6
'
],
[
'
brix
'
,
'
BRIX
'
],
[
'
dscif
'
,
'
densityServerCIF
'
]
]),
},
{
isFlat
:
true
})
},
{
options
:
[
[
'
pdbe
'
,
'
PDBe X-ray maps
'
],
[
'
rcsb
'
,
'
RCSB X-ray maps
'
],
[
'
url
'
,
'
URL
'
]
]
})
params
:
(
a
,
ctx
:
PluginContext
)
=>
{
const
{
options
}
=
getDataFormatExtensionsOptions
(
ctx
.
dataFormat
.
registry
)
return
{
source
:
PD
.
MappedStatic
(
'
rcsb
'
,
{
'
pdbe
'
:
PD
.
Group
({
id
:
PD
.
Text
(
'
1tqn
'
,
{
label
:
'
Id
'
}),
type
:
PD
.
Select
(
'
2fofc
'
,
[[
'
2fofc
'
,
'
2Fo-Fc
'
],
[
'
fofc
'
,
'
Fo-Fc
'
]]),
},
{
isFlat
:
true
}),
'
rcsb
'
:
PD
.
Group
({
id
:
PD
.
Text
(
'
1tqn
'
,
{
label
:
'
Id
'
}),
type
:
PD
.
Select
(
'
2fofc
'
,
[[
'
2fofc
'
,
'
2Fo-Fc
'
],
[
'
fofc
'
,
'
Fo-Fc
'
]]),
},
{
isFlat
:
true
}),
'
url
'
:
PD
.
Group
({
url
:
PD
.
Text
(
''
),
isBinary
:
PD
.
Boolean
(
false
),
format
:
PD
.
Select
(
'
auto
'
,
options
),
},
{
isFlat
:
true
})
},
{
options
:
[
[
'
pdbe
'
,
'
PDBe X-ray maps
'
],
[
'
rcsb
'
,
'
RCSB X-ray maps
'
],
[
'
url
'
,
'
URL
'
]
]
})
}
}
})(({
params
,
state
},
ctx
:
PluginContext
)
=>
{
const
b
=
state
.
build
();
})(({
params
,
state
},
ctx
:
PluginContext
)
=>
Task
.
create
(
'
Download Density
'
,
async
taskCtx
=>
{
const
src
=
params
.
source
;
let
downloadParams
:
Transformer
.
Params
<
Download
>
;
let
format
:
VolumeFormat
let
provider
:
DataFormatProvider
<
any
,
any
>
switch
(
src
.
name
)
{
case
'
url
'
:
downloadParams
=
src
.
params
;
format
=
getFileFormat
(
src
.
params
.
format
,
src
.
params
.
url
)
break
;
case
'
pdbe
'
:
downloadParams
=
{
...
...
@@ -282,7 +355,6 @@ const DownloadDensity = StateAction.build({
isBinary
:
true
,
label
:
`PDBe X-ray map:
${
src
.
params
.
id
}
`
};
format
=
'
ccp4
'
break
;
case
'
rcsb
'
:
downloadParams
=
{
...
...
@@ -292,11 +364,28 @@ const DownloadDensity = StateAction.build({
isBinary
:
true
,
label
:
`RCSB X-ray map:
${
src
.
params
.
id
}
`
};
format
=
'
dsn6
'
break
;
default
:
throw
new
Error
(
`
${(
src
as
any
).
name
}
not supported.`
);
}
const
data
=
b
.
toRoot
().
apply
(
StateTransforms
.
Data
.
Download
,
downloadParams
);
return
state
.
updateTree
(
createVolumeTree
(
format
,
ctx
,
data
));
});
\ No newline at end of file
const
data
=
state
.
build
().
toRoot
().
apply
(
StateTransforms
.
Data
.
Download
,
downloadParams
);
const
dataStateObject
=
await
state
.
updateTree
(
data
).
runInContext
(
taskCtx
);
switch
(
src
.
name
)
{
case
'
url
'
:
downloadParams
=
src
.
params
;
provider
=
src
.
params
.
format
===
'
auto
'
?
ctx
.
dataFormat
.
registry
.
auto
(
getFileInfo
(
downloadParams
.
url
),
dataStateObject
)
:
ctx
.
dataFormat
.
registry
.
get
(
src
.
params
.
format
)
break
;
case
'
pdbe
'
:
provider
=
ctx
.
dataFormat
.
registry
.
get
(
'
ccp4
'
)
break
;
case
'
rcsb
'
:
provider
=
ctx
.
dataFormat
.
registry
.
get
(
'
dsn6
'
)
break
;
default
:
throw
new
Error
(
`
${(
src
as
any
).
name
}
not supported.`
);
}
const
b
=
state
.
build
().
to
(
data
.
ref
);
const
tree
=
provider
.
getDefaultBuilder
(
b
).
getTree
()
await
state
.
updateTree
(
tree
).
runInContext
(
taskCtx
);
}));
\ No newline at end of file
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment