Commit 21af1a25 authored by Lauri Himanen's avatar Lauri Himanen
Browse files

Fixed the range for vibrational dispersion/dos.

parent 38640e0c
Pipeline #92973 passed with stages
in 32 minutes and 2 seconds
......@@ -25,6 +25,7 @@ import { ApiDialog } from '../ApiDialogButton'
import { Structure } from '../visualization/Structure'
import Actions from '../Actions'
import Quantity from '../Quantity'
import { RecoilRoot } from 'recoil'
import { Link as RouterLink } from 'react-router-dom'
import { DOI } from '../search/DatasetList'
import { domains } from '../domains'
......@@ -147,7 +148,6 @@ export default function DFTEntryOverview({data}) {
const [electronicStructure, setElectronicStructure] = useState(null)
const [vibrationalData, setVibrationalData] = useState(null)
const [geoOpt, setGeoOpt] = useState(null)
// const [shownSystem, setShownSystem] = useState('original')
const [structures, setStructures] = useState(null)
const materialType = data?.encyclopedia?.material?.material_type
const [method, setMethod] = useState(null)
......@@ -383,136 +383,138 @@ export default function DFTEntryOverview({data}) {
}, [data, showAPIDialog])
return (
<Grid container spacing={0} className={classes.root}>
<RecoilRoot>
<Grid container spacing={0} className={classes.root}>
{/* Left column */}
<Grid item xs={4} className={classes.sidebar}>
<ApiDialog data={data} open={showAPIDialog} onClose={() => { setShowAPIDialog(false) }}></ApiDialog>
<Actions className={classes.actions} justifyContent='flex-start' variant='contained' size='medium' actions={actions}></Actions>
<SidebarCard title='Method'>
<Quantity flex>
<Quantity quantity="dft.code_name" label='code name' noWrap {...quantityProps}/>
<Quantity quantity="dft.code_version" label='code version' noWrap {...quantityProps}/>
<Quantity
quantity="electronic_structure_method"
label='electronic structure method'
loading={loading}
description="The used electronic structure method."
noWrap
data={method}
/>
<Quantity quantity="dft.xc_functional" label='xc functional family' noWrap {...quantityProps}/>
<Quantity quantity="dft.xc_functional_names" label='xc functional names' noWrap {...quantityProps}/>
<Quantity quantity="dft.basis_set" label='basis set type' noWrap {...quantityProps}/>
<Quantity quantity="basis_set" label='basis set name' noWrap hideIfUnavailable data={method}/>
{method?.van_der_Waals_method && <Quantity quantity="van_der_Waals_method" label='van der Waals method' noWrap {...quantityProps}/>}
{method?.relativity_method && <Quantity quantity="relativity_method" label='relativity method' noWrap data={method}/>}
</Quantity>
</SidebarCard>
<Divider className={classes.divider} />
<SidebarCard title='Author metadata'>
<Quantity flex>
<Quantity quantity='comment' placeholder='no comment' {...quantityProps} />
<Quantity quantity='references' placeholder='no references' {...quantityProps}>
{data.references &&
<div style={{display: 'inline-grid'}}>
{data.references.map(ref => <Typography key={ref} noWrap>
<Link href={ref}>{ref}</Link>
</Typography>)}
</div>}
{/* Left column */}
<Grid item xs={4} className={classes.sidebar}>
<ApiDialog data={data} open={showAPIDialog} onClose={() => { setShowAPIDialog(false) }}></ApiDialog>
<Actions className={classes.actions} justifyContent='flex-start' variant='contained' size='medium' actions={actions}></Actions>
<SidebarCard title='Method'>
<Quantity flex>
<Quantity quantity="dft.code_name" label='code name' noWrap {...quantityProps}/>
<Quantity quantity="dft.code_version" label='code version' noWrap {...quantityProps}/>
<Quantity
quantity="electronic_structure_method"
label='electronic structure method'
loading={loading}
description="The used electronic structure method."
noWrap
data={method}
/>
<Quantity quantity="dft.xc_functional" label='xc functional family' noWrap {...quantityProps}/>
<Quantity quantity="dft.xc_functional_names" label='xc functional names' noWrap {...quantityProps}/>
<Quantity quantity="dft.basis_set" label='basis set type' noWrap {...quantityProps}/>
<Quantity quantity="basis_set" label='basis set name' noWrap hideIfUnavailable data={method}/>
{method?.van_der_Waals_method && <Quantity quantity="van_der_Waals_method" label='van der Waals method' noWrap {...quantityProps}/>}
{method?.relativity_method && <Quantity quantity="relativity_method" label='relativity method' noWrap data={method}/>}
</Quantity>
<Quantity quantity='authors' {...quantityProps}>
<Typography>
{authorList(data || [])}
</Typography>
</SidebarCard>
<Divider className={classes.divider} />
<SidebarCard title='Author metadata'>
<Quantity flex>
<Quantity quantity='comment' placeholder='no comment' {...quantityProps} />
<Quantity quantity='references' placeholder='no references' {...quantityProps}>
{data.references &&
<div style={{display: 'inline-grid'}}>
{data.references.map(ref => <Typography key={ref} noWrap>
<Link href={ref}>{ref}</Link>
</Typography>)}
</div>}
</Quantity>
<Quantity quantity='authors' {...quantityProps}>
<Typography>
{authorList(data || [])}
</Typography>
</Quantity>
<Quantity quantity='datasets' placeholder='no datasets' {...quantityProps}>
{data.datasets &&
<div>
{data.datasets.map(ds => (
<Typography key={ds.dataset_id}>
<Link component={RouterLink} to={`/dataset/id/${ds.dataset_id}`}>{ds.name}</Link>
{ds.doi ? <span>&nbsp; (<DOI doi={ds.doi}/>)</span> : ''}
</Typography>))}
</div>}
</Quantity>
</Quantity>
<Quantity quantity='datasets' placeholder='no datasets' {...quantityProps}>
{data.datasets &&
<div>
{data.datasets.map(ds => (
<Typography key={ds.dataset_id}>
<Link component={RouterLink} to={`/dataset/id/${ds.dataset_id}`}>{ds.name}</Link>
{ds.doi ? <span>&nbsp; (<DOI doi={ds.doi}/>)</span> : ''}
</Typography>))}
</div>}
</SidebarCard>
<Divider className={classes.divider}/>
<SidebarCard title='Processing information'>
<Quantity column style={{maxWidth: 350}}>
<Quantity quantity="mainfile" noWrap ellipsisFront withClipboard {...quantityProps}/>
<Quantity quantity="calc_id" label={`${domain ? domain.entryLabel : 'entry'} id`} noWrap withClipboard {...quantityProps}/>
<Quantity quantity="encyclopedia.material.material_id" label='material id' noWrap withClipboard {...quantityProps}/>
<Quantity quantity="upload_id" label='upload id' noWrap withClipboard {...quantityProps}/>
<Quantity quantity="upload_time" label='upload time' noWrap {...quantityProps}>
<Typography noWrap>
{new Date(data.upload_time).toLocaleString()}
</Typography>
</Quantity>
<Quantity quantity="raw_id" label='raw id' noWrap hideIfUnavailable withClipboard {...quantityProps}/>
<Quantity quantity="external_id" label='external id' hideIfUnavailable noWrap withClipboard {...quantityProps}/>
<Quantity quantity="last_processing" label='last processing' placeholder="not processed" noWrap {...quantityProps}>
<Typography noWrap>
{new Date(data.last_processing).toLocaleString()}
</Typography>
</Quantity>
<Quantity quantity="last_processing" label='processing version' noWrap placeholder="not processed" {...quantityProps}>
<Typography noWrap>
{data.nomad_version}/{data.nomad_commit}
</Typography>
</Quantity>
</Quantity>
</Quantity>
</SidebarCard>
<Divider className={classes.divider}/>
<SidebarCard title='Processing information'>
<Quantity column style={{maxWidth: 350}}>
<Quantity quantity="mainfile" noWrap ellipsisFront withClipboard {...quantityProps}/>
<Quantity quantity="calc_id" label={`${domain ? domain.entryLabel : 'entry'} id`} noWrap withClipboard {...quantityProps}/>
<Quantity quantity="encyclopedia.material.material_id" label='material id' noWrap withClipboard {...quantityProps}/>
<Quantity quantity="upload_id" label='upload id' noWrap withClipboard {...quantityProps}/>
<Quantity quantity="upload_time" label='upload time' noWrap {...quantityProps}>
<Typography noWrap>
{new Date(data.upload_time).toLocaleString()}
</Typography>
</Quantity>
<Quantity quantity="raw_id" label='raw id' noWrap hideIfUnavailable withClipboard {...quantityProps}/>
<Quantity quantity="external_id" label='external id' hideIfUnavailable noWrap withClipboard {...quantityProps}/>
<Quantity quantity="last_processing" label='last processing' placeholder="not processed" noWrap {...quantityProps}>
<Typography noWrap>
{new Date(data.last_processing).toLocaleString()}
</Typography>
</Quantity>
<Quantity quantity="last_processing" label='processing version' noWrap placeholder="not processed" {...quantityProps}>
<Typography noWrap>
{data.nomad_version}/{data.nomad_commit}
</Typography>
</Quantity>
</Quantity>
</SidebarCard>
</Grid>
</SidebarCard>
</Grid>
{/* Right column */}
<Grid item xs={8}>
<PropertyCard title="Material">
<Grid container spacing={1}>
<Grid item xs={5}>
<Box>
<Quantity column>
<Quantity quantity="formula" label='formula' noWrap {...quantityProps}/>
<Quantity quantity="dft.system" label='material type' noWrap {...quantityProps}/>
<Quantity quantity="encyclopedia.material.material_name" label='material name' noWrap {...quantityProps}/>
<Quantity row>
{materialType === 'bulk' && <Quantity quantity="dft.crystal_system" label='crystal system' noWrap {...quantityProps}/>}
{materialType === 'bulk' && <Quantity quantity="dft.spacegroup_symbol" label="spacegroup" noWrap {...quantityProps}>
<Typography noWrap>
{normalizeDisplayValue(_.get(data, 'dft.spacegroup_symbol'))} ({normalizeDisplayValue(_.get(data, 'dft.spacegroup'))})
</Typography>
</Quantity>}
{/* Right column */}
<Grid item xs={8}>
<PropertyCard title="Material">
<Grid container spacing={1}>
<Grid item xs={5}>
<Box>
<Quantity column>
<Quantity quantity="formula" label='formula' noWrap {...quantityProps}/>
<Quantity quantity="dft.system" label='material type' noWrap {...quantityProps}/>
<Quantity quantity="encyclopedia.material.material_name" label='material name' noWrap {...quantityProps}/>
<Quantity row>
{materialType === 'bulk' && <Quantity quantity="dft.crystal_system" label='crystal system' noWrap {...quantityProps}/>}
{materialType === 'bulk' && <Quantity quantity="dft.spacegroup_symbol" label="spacegroup" noWrap {...quantityProps}>
<Typography noWrap>
{normalizeDisplayValue(_.get(data, 'dft.spacegroup_symbol'))} ({normalizeDisplayValue(_.get(data, 'dft.spacegroup'))})
</Typography>
</Quantity>}
</Quantity>
</Quantity>
</Quantity>
</Box>
</Box>
</Grid>
<Grid item xs={7} style={{marginTop: '-2rem'}}>
<Structure systems={structures} aspectRatio={1.5} />
</Grid>
</Grid>
<Grid item xs={7} style={{marginTop: '-2rem'}}>
<Structure systems={structures} aspectRatio={1.5} />
</Grid>
</Grid>
</PropertyCard>
{electronicStructure &&
<PropertyCard title="Electronic properties">
<ElectronicStructureOverview
data={electronicStructure}>
</ElectronicStructureOverview>
</PropertyCard>
}
{geoOpt && structures &&
<PropertyCard title="Geometry optimization">
<GeoOptOverview data={geoOpt}></GeoOptOverview>
</PropertyCard>
}
{vibrationalData &&
<PropertyCard title="Vibrational properties">
<VibrationalOverview
data={vibrationalData}>
</VibrationalOverview>
</PropertyCard>
}
{electronicStructure &&
<PropertyCard title="Electronic properties">
<ElectronicStructureOverview
data={electronicStructure}>
</ElectronicStructureOverview>
</PropertyCard>
}
{geoOpt && structures &&
<PropertyCard title="Geometry optimization">
<GeoOptOverview data={geoOpt}></GeoOptOverview>
</PropertyCard>
}
{vibrationalData &&
<PropertyCard title="Vibrational properties">
<VibrationalOverview
data={vibrationalData}>
</VibrationalOverview>
</PropertyCard>
}
</Grid>
</Grid>
</Grid>
</RecoilRoot>
)
}
......
......@@ -44,7 +44,7 @@ function ElectronicStructureOverview({data, range, className, classes, raiseErro
row: {
display: 'flex',
flexDirection: 'row',
justifyContent: 'center',
justifyContent: 'flex-start',
alignItems: 'center',
width: '100%',
height: '100%',
......
......@@ -22,7 +22,6 @@ import {
Typography,
useTheme
} from '@material-ui/core'
import { RecoilRoot } from 'recoil'
import { makeStyles } from '@material-ui/core/styles'
import Plot from '../visualization/Plot'
import { Structure } from '../visualization/Structure'
......@@ -49,8 +48,6 @@ function GeoOptOverview({data, className, classes}) {
const style = useStyles(classes)
const theme = useTheme()
const plotData = useMemo(() => {
// See if energies are present. If not, still do an empty plot to allow user
// to navigate the steps.
let steps = [...Array(data.structures.length).keys()]
let energies = data.energies
const diff = [0]
......@@ -110,8 +107,11 @@ function GeoOptOverview({data, className, classes}) {
y: 0.5
},
xaxis: {
showexponent: 'first',
title: 'Step number',
tickmode: 'auto',
tickformat: ',d',
autorange: false,
range: [0, data.structures.length - 1],
zeroline: false,
showspikes: true,
......@@ -133,32 +133,30 @@ function GeoOptOverview({data, className, classes}) {
}, [])
return (
<RecoilRoot>
<Box className={style.root}>
<Box className={style.energies}>
<Typography variant="subtitle1" align='center'>Energy convergence</Typography>
<ErrorHandler message='Could not load energies.'>
<Plot
data={plotData}
layout={plotLayout}
aspectRatio={1.5}
onHover={handleHover}
floatTitle="Energy convergence"
>
</Plot>
</ErrorHandler>
</Box>
<Box className={style.structure}>
<Typography variant="subtitle1" align='center'>Optimization trajectory</Typography>
<Structure
system={data.structures[step]}
aspectRatio={0.75}
options={{view: {fitMargin: 0.75}}}
positionsOnly={true}
></Structure>
</Box>
<Box className={style.root}>
<Box className={style.energies}>
<Typography variant="subtitle1" align='center'>Energy convergence</Typography>
<ErrorHandler message='Could not load energies.'>
<Plot
data={plotData}
layout={plotLayout}
aspectRatio={1.5}
onHover={handleHover}
floatTitle="Energy convergence"
>
</Plot>
</ErrorHandler>
</Box>
</RecoilRoot>
<Box className={style.structure}>
<Typography variant="subtitle1" align='center'>Optimization trajectory</Typography>
<Structure
system={data.structures[step]}
aspectRatio={0.75}
options={{view: {fitMargin: 0.75}}}
positionsOnly={true}
></Structure>
</Box>
</Box>
)
}
......
......@@ -71,7 +71,7 @@ export default function Plot({data, layout, config, floatTitle, capture, aspectR
right: 0,
position: 'absolute'
},
plot: {
floatable: {
visibility: loading ? 'hidden' : 'visible'
},
spacer: {
......@@ -256,7 +256,7 @@ export default function Plot({data, layout, config, floatTitle, capture, aspectR
// these HTML nodes and their sizes when the plots are loading.
return <Box className={clsx(className, styles.root)} position='relative' width='100%'>
{loading && <Placeholder className={styles.placeHolder} variant="rect" aspectRatio={aspectRatio}></Placeholder>}
<Floatable className={styles.plot} float={float} onFloat={() => setFloat(!float)} aspectRatio={aspectRatio}>
<Floatable className={styles.floatable} float={float} onFloat={() => setFloat(!float)} aspectRatio={aspectRatio}>
{float && <Typography variant="h6">{floatTitle}</Typography>}
<div ref={canvasRef} style={{width: '100%', height: '100%'}}></div>
<div className={styles.header}>
......
......@@ -25,23 +25,30 @@ import {
import DOS from './DOS'
import BandStructure from './BandStructure'
import Placeholder from '../visualization/Placeholder'
import { RecoilRoot } from 'recoil'
import { useRecoilValue, RecoilRoot } from 'recoil'
import { convertSI } from '../../utils'
import { unitsState } from '../archive/ArchiveBrowser'
import { makeStyles } from '@material-ui/core/styles'
import { ErrorHandler } from '../ErrorHandler'
import Plot from '../visualization/Plot'
function VibrationalOverview({data, range, className, classes, raiseError}) {
const [dosLayout, setDosLayout] = useState({
yaxis: {
autorange: true
export default function VibrationalOverview({data, className, classes, raiseError}) {
// Find minimum and maximum from DOS/BS. Use this range for both plots.
const units = useRecoilValue(unitsState)
const range = useMemo(() => {
let min
let max
const energies = data?.dos?.section_dos?.dos_energies
if (energies) {
min = Math.min(...energies)
max = Math.max(...energies)
}
})
const [bsLayout, setBsLayout] = useState({
yaxis: {
autorange: true
}
})
return convertSI([min, max], 'joule', units, false)
}, [data, units])
// States
const [dosLayout, setDosLayout] = useState({yaxis: {range: range}})
const [bsLayout, setBsLayout] = useState({yaxis: {range: range}})
// Styles
const useStyles = makeStyles((theme) => {
......@@ -73,23 +80,27 @@ function VibrationalOverview({data, range, className, classes, raiseError}) {
// Synchronize panning between BS/DOS plots
const handleBSRelayouting = useCallback((event) => {
let update = {
yaxis: {
autorange: false,
range: [event['yaxis.range[0]'], event['yaxis.range[1]']]
if (data.dos) {
let update = {
yaxis: {
autorange: false,
range: [event['yaxis.range[0]'], event['yaxis.range[1]']]
}
}
setDosLayout(update)
}
setDosLayout(update)
}, [])
}, [data])
const handleDOSRelayouting = useCallback((event) => {
let update = {
yaxis: {
autorange: false,
range: [event['yaxis.range[0]'], event['yaxis.range[1]']]
if (data.bs) {
let update = {
yaxis: {
autorange: false,
range: [event['yaxis.range[0]'], event['yaxis.range[1]']]
}
}
setBsLayout(update)
}
setBsLayout(update)
}, [])
}, [data])
const theme = useTheme()
const heatCapacityData = useMemo(() => {
......@@ -112,6 +123,7 @@ function VibrationalOverview({data, range, className, classes, raiseError}) {
zeroline: false
},
yaxis: {
autorange: true,
title: 'Heat capacity (J/K)',
zeroline: false
}
......@@ -137,6 +149,7 @@ function VibrationalOverview({data, range, className, classes, raiseError}) {
zeroline: false
},
yaxis: {
autorange: true,
title: 'Helmholtz free energy (J)',
zeroline: false
}
......@@ -156,7 +169,7 @@ function VibrationalOverview({data, range, className, classes, raiseError}) {
aspectRatio={1.2}
unitsState={unitsState}
onRelayouting={handleBSRelayouting}
onReset={() => { setDosLayout({yaxis: {autorange: true}}) }}
onReset={() => { setDosLayout({yaxis: {range: range}}) }}
></BandStructure>
: <Placeholder className={null} aspectRatio={1.1} variant="rect"></Placeholder>
}
......@@ -172,7 +185,7 @@ function VibrationalOverview({data, range, className, classes, raiseError}) {
layout={dosLayout}
aspectRatio={0.6}
onRelayouting={handleDOSRelayouting}
onReset={() => { setBsLayout({yaxis: {autorange: true}}) }}
onReset={() => { setBsLayout({yaxis: {range: range}}) }}
unitsState={unitsState}
></DOS>
: <Placeholder className={null} aspectRatio={1.1} variant="rect"></Placeholder>
......@@ -222,8 +235,3 @@ VibrationalOverview.propTypes = {
classes: PropTypes.object,
raiseError: PropTypes.func
}
VibrationalOverview.defaultProps = {
range: [-10, 20]
}
export default VibrationalOverview
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment