From a1dd5b409a8066c5fda34387922172aba21a0e79 Mon Sep 17 00:00:00 2001
From: Lauri Himanen <lauri.himanen@gmail.com>
Date: Thu, 28 Mar 2024 07:52:12 +0000
Subject: [PATCH] Removed unit_system from display annotation

---
 docs/reference/annotations.md                 |  39 +----
 gui/src/components/archive/ArchiveBrowser.js  |  26 +--
 .../components/archive/ArchiveBrowser.spec.js |   2 +-
 gui/src/components/archive/Browser.spec.js    |  60 +------
 .../archive/QuantityItemPreview.spec.js       |  68 +++-----
 gui/src/components/archive/Section.spec.js    | 155 +++---------------
 gui/src/components/archive/conftest.spec.js   |  59 ++++++-
 .../editQuantity/NumberEditQuantity.spec.js   |  19 +--
 gui/src/components/entry/OverviewView.js      |   2 -
 gui/src/components/units/useDisplayUnit.js    |  26 +--
 nomad/datamodel/metainfo/annotations.py       |  64 ++++++--
 11 files changed, 181 insertions(+), 339 deletions(-)

diff --git a/docs/reference/annotations.md b/docs/reference/annotations.md
index 0f985c5232..621fa7dd75 100644
--- a/docs/reference/annotations.md
+++ b/docs/reference/annotations.md
@@ -18,44 +18,11 @@ Many annotations control the representation of data in the GUI. This can be for
 
 {{ pydantic_model('nomad.datamodel.metainfo.annotations.BrowserAnnotation', heading='## Browser') }}
 
-{{ pydantic_model('nomad.datamodel.metainfo.annotations.BrowserAnnotation', heading='## browser') }}
+## Display annotations
 
-### `display unit system`
-The unit system to override the global or the unit system determined by parent. It could be used in the level of Package, Section, or Quantity.
-One can use the supported [unit systems](./config.md#unitsystems) such as `SI` or `AU`.
+{{ pydantic_model('nomad.datamodel.metainfo.annotations.QuantityDisplayAnnotation', heading='### Display annotation for quantities') }}
 
-```yaml
-definitions:
-  name: 'Sun'
-  m_annotations:
-    display:
-      unit_system: SI
-  sections:
-    SolarSystem:
-      quantities:
-        total_energy:
-          type: float
-          description: The total energy in SI unit system, energy unit
-      sub_sections:
-        Electrons:
-          section:
-            m_annotations:
-              display:
-                unit_system: AU
-            quantities:
-              free_energy:
-                type: float
-                description: The electron energy in AU unit system, energy unit
-              energy:
-                m_annotations:
-                  display:
-                    unit: erg
-                type: float
-                description: The electron energy in a custom unit
-```
-
-### `display unit`
-To determine the desired unit to override the global or the unit determined by parent. See the example in [display unit system](#display_unit_system).
+{{ pydantic_model('nomad.datamodel.metainfo.annotations.SectionDisplayAnnotation', heading='### Display annotation for sections') }}
 
 ### `label_quantity`
 
diff --git a/gui/src/components/archive/ArchiveBrowser.js b/gui/src/components/archive/ArchiveBrowser.js
index e76c966844..e33394ef49 100644
--- a/gui/src/components/archive/ArchiveBrowser.js
+++ b/gui/src/components/archive/ArchiveBrowser.js
@@ -71,6 +71,7 @@ import { useEntryStore } from '../entry/EntryContext'
 import ArchiveSearchBar from './ArchiveSearchBar'
 import DOMPurify from 'dompurify'
 import XYPlot from "./XYPlot"
+import { useDisplayUnit } from '../units/useDisplayUnit'
 
 export const configState = atom({
   key: 'config',
@@ -649,7 +650,8 @@ const convertComplexArray = (real, imag) => {
 }
 
 export function QuantityItemPreview({value, def}) {
-  const {units, unitSystems, isReset} = useUnitContext()
+  const displayUnit = useDisplayUnit(def)
+
   if (isReference(def)) {
     return <Box component="span" fontStyle="italic">
       <Typography component="span">reference ...</Typography>
@@ -707,27 +709,12 @@ export function QuantityItemPreview({value, def}) {
       finalValue = value
     }
 
-    let finalUnit
-    if (def.unit) {
-      let a
-      const section_default_unit_system = def?._parent?.m_annotations?.display?.[0]?.unit_system
-      const quantity_default_unit = def?.m_annotations?.display?.[0]?.unit
-      if (isReset && (section_default_unit_system || quantity_default_unit)) {
-        if (section_default_unit_system && unitSystems[section_default_unit_system]) {
-          a = new Q(finalValue, def.unit).toSystem(unitSystems[section_default_unit_system].units)
-        }
-        if (quantity_default_unit) {
-          a = new Q(finalValue, def.unit).to(quantity_default_unit)
-        }
-      } else {
-        a = new Q(finalValue, def.unit).toSystem(units)
-      }
-      finalValue = a.value()
-      finalUnit = a.label()
+    if (displayUnit) {
+      finalValue = new Q(finalValue, def.unit).to(displayUnit).value()
     }
     return <Box component="span" whiteSpace="nowarp">
       <Number component="span" variant="body1" value={finalValue} exp={8}/>
-      {finalUnit && <Typography component="span">&nbsp;{finalUnit}</Typography>}
+      {displayUnit && <Typography component="span">&nbsp;{displayUnit.label()}</Typography>}
     </Box>
   }
 }
@@ -922,7 +909,6 @@ export function Section({section, def, parentRelation, sectionIsEditable, sectio
   const [showJson, setShowJson] = useState(false)
   const lane = useContext(laneContext)
   const history = useHistory()
-  useUnitContext(def._package.name, def?._package?.m_annotations?.display?.[0]?.unit_system)
 
   const isEditable = useMemo(() => {
     let editableExcluded = false
diff --git a/gui/src/components/archive/ArchiveBrowser.spec.js b/gui/src/components/archive/ArchiveBrowser.spec.js
index 25552ff37c..ccb2e447d9 100644
--- a/gui/src/components/archive/ArchiveBrowser.spec.js
+++ b/gui/src/components/archive/ArchiveBrowser.spec.js
@@ -17,6 +17,7 @@
  */
 import React from 'react'
 import { range } from 'lodash'
+import { TestAdaptor } from './conftest.spec'
 import { screen, renderNoAPI, render } from '../conftest.spec'
 import { expectPagination } from '../visualization/conftest.spec'
 import { PropertyValuesList, Section } from './ArchiveBrowser'
@@ -24,7 +25,6 @@ import { laneContext } from './Browser'
 import {waitFor} from "@testing-library/dom"
 import {Metainfo} from './metainfo'
 import {systemMetainfoUrl} from '../../utils'
-import {TestAdaptor} from './Browser.spec'
 
 test.each([
   [15, 10, 5],
diff --git a/gui/src/components/archive/Browser.spec.js b/gui/src/components/archive/Browser.spec.js
index 997e5e5bf5..319f5cbf72 100644
--- a/gui/src/components/archive/Browser.spec.js
+++ b/gui/src/components/archive/Browser.spec.js
@@ -15,67 +15,11 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-import { join, basename } from 'path'
 import React from 'react'
-import PropTypes from 'prop-types'
 import { waitFor } from '@testing-library/dom'
 import { blockConsoleOutput, expectNoConsoleOutput, filteredConsoleOutput, consoleSpies, render, screen, within } from '../conftest.spec'
-import { itemsInTreePath, checkLanes, navigateTo, selectItemAndWaitForRender, getLane } from './conftest.spec'
-import Browser, { Item, Content, Compartment, Adaptor, Title, laneErrorBoundryMessage } from './Browser'
-
-function checkTestLane({lane, laneIndex, lanePath, lastSegment, browserTree, rootTitle}) {
-  expect(within(lane).getByText(laneIndex === 0 ? rootTitle : lastSegment)).toBeVisible() // Lane title
-
-  itemsInTreePath(browserTree, lanePath).forEach(item => {
-    expect(within(lane).getByText(item)).toBeVisible()
-  })
-}
-
-const browserTree = {
-  '': {cb: checkTestLane},
-  'dir1': {cb: checkTestLane},
-  'dir1/success': {cb: checkTestLane},
-  'dir1/fail': {cb: checkTestLane}
-}
-
-export class TestAdaptor extends Adaptor {
-  constructor(path, title) {
-    super()
-    this.path = path
-    this.title = title
-    this.parsedObjUrl = {entryId: 'entryID1'}
-  }
-
-  itemAdaptor(key) {
-    return new TestAdaptor(join(this.path, key))
-  }
-
-  render() {
-    return <TestContent path={this.path} title={this.title} />
-  }
-}
-
-function TestContent({path, title}) {
-  if (path.endsWith('/fail')) {
-    throw new Error('mocked render error')
-  }
-  return <Content key={path}>
-    <Title title={title || basename(path)} label="test" />
-    <Compartment>
-      {
-        itemsInTreePath(browserTree, path).map(itemKey => (
-          <Item itemKey={itemKey} key={join(path, itemKey)}>
-            {itemKey}
-          </Item>
-        ))
-      }
-    </Compartment>
-  </Content>
-}
-TestContent.propTypes = {
-  path: PropTypes.string.isRequired,
-  title: PropTypes.string
-}
+import { checkLanes, navigateTo, selectItemAndWaitForRender, getLane, TestAdaptor, browserTree } from './conftest.spec'
+import Browser, { laneErrorBoundryMessage } from './Browser'
 
 test('Test browser lane error boundry', async () => {
   blockConsoleOutput()
diff --git a/gui/src/components/archive/QuantityItemPreview.spec.js b/gui/src/components/archive/QuantityItemPreview.spec.js
index e23099e11f..cb2aa4c661 100644
--- a/gui/src/components/archive/QuantityItemPreview.spec.js
+++ b/gui/src/components/archive/QuantityItemPreview.spec.js
@@ -20,45 +20,31 @@ import React from 'react'
 import {render} from "../conftest.spec"
 import {QuantityItemPreview} from "./ArchiveBrowser"
 
-describe('Test QuantityItemPreview', () => {
-  it('without default display unit', async () => {
-    render(
-      <QuantityItemPreview
-        def={{
-          unit: 'meter',
-          type: {type_kind: 'python', type_data: 'float'},
-          shape: [],
-          m_annotations: {}
-        }}
-        value={3.5}
-      />
-    )
-    // should be rendered in default unit system
-    const span = document.querySelector('span')
-    expect(span.textContent).toContain('3.5')
-    expect(span.textContent).toContain('·10')
-    const sup = document.querySelector('sup')
-    expect(sup.textContent).toContain('+10')
-  })
-
-  it('with default display unit', async () => {
-    render(
-      <QuantityItemPreview
-        def={{
-          unit: 'meter',
-          type: {type_kind: 'python', type_data: 'float'},
-          shape: [],
-          m_annotations: {
-            display: [{
-              unit: 'mm'
-            }]
-          }
-        }}
-        value={3.5}
-      />
-    )
-    // should be rendered in default unit provided by schema
-    const span = document.querySelector('span')
-    expect(span.textContent).toContain('3500 mm')
-  })
+test.each([
+  [
+    'without unit',
+    3.5,
+    {},
+    '3.50000'],
+  [
+    'without display unit',
+    3.5,
+    {unit: 'meter'},
+    '3.5·10+10 Å'
+  ],
+  [
+    'with default display unit',
+    3.5,
+    {unit: 'meter', m_annotations: {display: [{unit: 'mm'}]}},
+    '3500 mm'
+  ]
+])('Test QuantityItemPreview %s', async (name, value, def, expected) => {
+  render(
+    <QuantityItemPreview
+      def={{name: 'value1', shape: [], type: {type_kind: 'python', type_data: 'float'}, ...def}}
+      value={value}
+    />
+  )
+  const span = document.querySelector('span')
+  expect(span.textContent).toContain(expected)
 })
diff --git a/gui/src/components/archive/Section.spec.js b/gui/src/components/archive/Section.spec.js
index 1994faf6c2..c6933438cc 100644
--- a/gui/src/components/archive/Section.spec.js
+++ b/gui/src/components/archive/Section.spec.js
@@ -24,7 +24,7 @@ import {Section} from "./ArchiveBrowser"
 import {Metainfo} from "./metainfo"
 import {systemMetainfoUrl} from "../../utils"
 import {laneContext} from './Browser'
-import {TestAdaptor} from "./Browser.spec"
+import {TestAdaptor} from "./conftest.spec"
 
 async function createMetainfo(data, parent, url = systemMetainfoUrl) {
   data._url = url
@@ -36,11 +36,6 @@ const mockPackage = ({
   packages: [
     {
       name: 'testPackage',
-      m_annotations: {
-        display: [{
-          unit_system: 'AU'
-        }]
-      },
       section_definitions: [
         {
           name: 'TestSection',
@@ -53,42 +48,7 @@ const mockPackage = ({
             },
             {
               name: 'value2',
-              m_annotations: {
-                eln: [
-                  {
-                    component: "NumberEditQuantity"
-                  }
-                ]
-              },
-              type: { type_kind: 'python', type_data: 'float' },
-              unit: 'meter',
-              m_parent_sub_section: 'quantities'
-            }
-          ]
-        },
-        {
-          name: 'TestSection',
-          m_annotations: {
-            display: [{
-              unit_system: 'SI'
-            }]
-          },
-          quantities: [
-            {
-              name: 'value3',
-              type: { type_kind: 'python', type_data: 'float' },
-              unit: 'meter',
-              m_parent_sub_section: 'quantities'
-            },
-            {
-              name: 'value4',
-              m_annotations: {
-                eln: [
-                  {
-                    component: "NumberEditQuantity"
-                  }
-                ]
-              },
+              m_annotations: {eln: [{component: "NumberEditQuantity"}]},
               type: { type_kind: 'python', type_data: 'float' },
               unit: 'meter',
               m_parent_sub_section: 'quantities'
@@ -100,95 +60,32 @@ const mockPackage = ({
   ]
 })
 
-describe('Test interaction between unit menu and quantities', () => {
-  it('Package with display unit_system', async () => {
-    const metainfo = await createMetainfo(mockPackage)
-    const defsByName = await metainfo.getDefsByName()
-    const def = defsByName.TestSection[0]
-    const adaptor = new TestAdaptor('', 'Data')
-
-    render(
-      <laneContext.Provider value={{next: {}, adaptor: adaptor}}>
-        <Section
-          section={{value1: 7.5}}
-          def={def}
-          sectionIsInEln={false}
-          sectionIsEditable={false}
-        />
-      </laneContext.Provider>
-    )
-    // should be rendered in package default unit system
-    const numberWithUnit = document.querySelector('[data-testid="scientific-number-with-unit"]')
-    const span = numberWithUnit.querySelector('span')
-    expect(span.textContent).toContain('1.41729459')
-    expect(span.textContent).toContain('·10')
-    const sup = document.querySelector('sup')
-    expect(sup.textContent).toContain('+11')
-  })
-
-  it('Editable package with display unit_system', async () => {
-    const metainfo = await createMetainfo(mockPackage)
-    const defsByName = await metainfo.getDefsByName()
-    const def = defsByName.TestSection[0]
-    const adaptor = new TestAdaptor('', 'Data')
+test.each([
+  ['non-editable, no display unit', {value1: 7.5}, false, '7.5·10+10'],
+  ['editable, no display unit', {value2: 7.5}, true, '75000000000']
+])('Test editable/uneditable sections: %s', async (name, section, editable, expected) => {
+  const metainfo = await createMetainfo(mockPackage)
+  const defsByName = await metainfo.getDefsByName()
+  const def = defsByName.TestSection[0]
+  const adaptor = new TestAdaptor('', 'Data')
 
-    render(
-      <laneContext.Provider value={{next: {}, adaptor: adaptor}}>
-        <Section
-          section={{value2: 8.5}}
-          def={def}
-          sectionIsInEln={true}
-          sectionIsEditable={true}
-        />
-      </laneContext.Provider>
-    )
-    // should be rendered in package default unit system
+  render(
+    <laneContext.Provider value={{next: {}, adaptor: adaptor}}>
+      <Section
+        section={section}
+        def={def}
+        sectionIsInEln={editable}
+        sectionIsEditable={editable}
+      />
+    </laneContext.Provider>
+  )
+  if (editable) {
     const numberFieldValue = screen.getByTestId('number-edit-quantity-value')
     const numberFieldValueInput = within(numberFieldValue).getByRole('textbox')
-    // should be rendered in default unit system
-    await waitFor(() => expect(numberFieldValueInput.value).toEqual('160626720592.894'))
-  })
-
-  it('Section with display unit_system', async () => {
-    const metainfo = await createMetainfo(mockPackage)
-    const defsByName = await metainfo.getDefsByName()
-    const def = defsByName.TestSection[1]
-    const adaptor = new TestAdaptor('', 'Data')
-
-    render(
-      <laneContext.Provider value={{next: {}, adaptor: adaptor}}>
-        <Section
-          section={{value3: 7.5}}
-          def={def}
-          sectionIsInEln={false}
-          sectionIsEditable={false}
-        />
-      </laneContext.Provider>
-    )
-    // Should be rendered in section default unit system, The determined package default unit system should be overridden.
+    await waitFor(() => expect(numberFieldValueInput.value).toEqual(expected))
+  } else {
     const numberWithUnit = document.querySelector('[data-testid="scientific-number-with-unit"]')
-    expect(numberWithUnit.textContent).toContain('7.50000')
-  })
-
-  it('Editable Section with display unit_system', async () => {
-    const metainfo = await createMetainfo(mockPackage)
-    const defsByName = await metainfo.getDefsByName()
-    const def = defsByName.TestSection[1]
-    const adaptor = new TestAdaptor('', 'Data')
-
-    render(
-      <laneContext.Provider value={{next: {}, adaptor: adaptor}}>
-        <Section
-          section={{value4: 8.5}}
-          def={def}
-          sectionIsInEln={true}
-          sectionIsEditable={true}
-        />
-      </laneContext.Provider>
-    )
-    // Should be rendered in section default unit system, The determined package default unit system should be overridden.
-    const numberFieldValue = screen.getByTestId('number-edit-quantity-value')
-    const numberFieldValueInput = within(numberFieldValue).getByRole('textbox')
-    await waitFor(() => expect(numberFieldValueInput.value).toEqual('8.5'))
-  })
+    const span = numberWithUnit.querySelector('span')
+    expect(span.textContent).toContain(expected)
+  }
 })
diff --git a/gui/src/components/archive/conftest.spec.js b/gui/src/components/archive/conftest.spec.js
index 46a0ac05ca..f032be159d 100644
--- a/gui/src/components/archive/conftest.spec.js
+++ b/gui/src/components/archive/conftest.spec.js
@@ -19,8 +19,11 @@ import { join, basename } from 'path'
 import { waitFor } from '@testing-library/dom'
 import { screen, within, expectNoConsoleOutput } from '../conftest.spec'
 import userEvent from '@testing-library/user-event'
-import { laneErrorBoundryMessage } from './Browser'
+import { Item, Content, Compartment, Title, laneErrorBoundryMessage, Adaptor } from './Browser'
 import { isWaitingForUpdateTestId } from '../../utils'
+import React from 'react'
+import PropTypes from 'prop-types'
+
 const crypto = require('crypto')
 
 /*****************************************************************************************
@@ -326,3 +329,57 @@ export function pseudoRandomNumberGenerator(seed = 7) {
     return ((t ^ t >>> 14) >>> 0) / 4294967296
   }
 }
+
+function checkTestLane({lane, laneIndex, lanePath, lastSegment, browserTree, rootTitle}) {
+  expect(within(lane).getByText(laneIndex === 0 ? rootTitle : lastSegment)).toBeVisible() // Lane title
+
+  itemsInTreePath(browserTree, lanePath).forEach(item => {
+    expect(within(lane).getByText(item)).toBeVisible()
+  })
+}
+
+export const browserTree = {
+  '': {cb: checkTestLane},
+  'dir1': {cb: checkTestLane},
+  'dir1/success': {cb: checkTestLane},
+  'dir1/fail': {cb: checkTestLane}
+}
+
+export class TestAdaptor extends Adaptor {
+  constructor(path, title) {
+    super()
+    this.path = path
+    this.title = title
+    this.parsedObjUrl = {entryId: 'entryID1'}
+  }
+
+  itemAdaptor(key) {
+    return new TestAdaptor(join(this.path, key))
+  }
+
+  render() {
+    return <TestContent path={this.path} title={this.title} />
+  }
+}
+
+export function TestContent({path, title}) {
+  if (path.endsWith('/fail')) {
+    throw new Error('mocked render error')
+  }
+  return <Content key={path}>
+    <Title title={title || basename(path)} label="test" />
+    <Compartment>
+      {
+        itemsInTreePath(browserTree, path).map(itemKey => (
+          <Item itemKey={itemKey} key={join(path, itemKey)}>
+            {itemKey}
+          </Item>
+        ))
+      }
+    </Compartment>
+  </Content>
+}
+TestContent.propTypes = {
+  path: PropTypes.string.isRequired,
+  title: PropTypes.string
+}
diff --git a/gui/src/components/editQuantity/NumberEditQuantity.spec.js b/gui/src/components/editQuantity/NumberEditQuantity.spec.js
index 879ac150d6..6479defbef 100644
--- a/gui/src/components/editQuantity/NumberEditQuantity.spec.js
+++ b/gui/src/components/editQuantity/NumberEditQuantity.spec.js
@@ -53,25 +53,18 @@ describe('Test numberEditQuantity', () => {
   })
 
   test.each([
-    ['no default unit or unit system, defaults to global scope units', 'm', undefined, undefined, undefined, '100000000000'],
-    ['with display unit', 'm', 'mm', undefined, undefined, '10000'],
-    ['with display unit system', 'm', undefined, 'AU', undefined, '188972612462.228'],
-    ['with display unit and unit system', 'm', 'mm', 'AU', undefined, '10000'],
-    ['complex unit with no display unit', 'm**2 / second**2', undefined, undefined, undefined, '1e-9'],
-    ['complex unit with display unit', 'm**2 / second**2', 'Å**2 / fs**2', undefined, undefined, '1e-9'],
-    ['deprecated display unit in eln annotation', 'm', undefined, undefined, 'mm', '10000']
-  ])('%s', async (name, unit, displayUnit, displayUnitSystem, elnUnit, expected) => {
+    ['no default unit or unit system, defaults to global scope units', 'm', undefined, undefined, '100000000000'],
+    ['with display unit', 'm', 'mm', undefined, '10000'],
+    ['complex unit with no display unit', 'm**2 / second**2', undefined, undefined, '1e-9'],
+    ['complex unit with display unit', 'm**2 / second**2', 'Å**2 / fs**2', undefined, '1e-9'],
+    ['deprecated display unit in eln annotation', 'm', undefined, 'mm', '10000']
+  ])('%s', async (name, unit, displayUnit, elnUnit, expected) => {
     render(
       <NumberEditQuantity
         quantityDef={{
           name: 'name',
           m_def: 'nomad.metainfo.metainfo.Quantity',
           unit: unit,
-          _parent: displayUnitSystem && {
-            m_annotations: {
-              display: [{unit_system: displayUnitSystem}]
-            }
-          },
           m_annotations: {
             display: displayUnit && [{
               unit: displayUnit
diff --git a/gui/src/components/entry/OverviewView.js b/gui/src/components/entry/OverviewView.js
index 060e677cee..2d80f11d71 100644
--- a/gui/src/components/entry/OverviewView.js
+++ b/gui/src/components/entry/OverviewView.js
@@ -52,7 +52,6 @@ import ReferenceUsingCard from "./properties/ReferenceCard"
 import SampleHistoryUsingCard from "./properties/SampleHistoryCard"
 import { useEntryStore, useEntryContext, useIndex } from './EntryContext'
 import DeleteEntriesButton from '../uploads/DeleteEntriesButton'
-import {useUnitContext} from "../units/UnitContext"
 
 function MetadataSection({title, children}) {
   return <Box marginTop={2} marginBottom={2}>
@@ -145,7 +144,6 @@ const OverviewView = React.memo(() => {
   const { data: index, response: indexApiData } = useIndex()
   const { url, exists, editable, archive: archiveTmp, archiveApiData } = useEntryStore(required)
   const [sections, setSections] = useState([])
-  useUnitContext(sections?.[0]?.sectionDef?._package?.name, sections?.[0]?.sectionDef?._package?.m_annotations?.display?.[0]?.unit_system)
 
   // The archive is accepted only once it is synced with the index. Notice that
   // we need to get the entry_id from data.entry_id, as some older entries will
diff --git a/gui/src/components/units/useDisplayUnit.js b/gui/src/components/units/useDisplayUnit.js
index f9dbc89e6d..8036688340 100644
--- a/gui/src/components/units/useDisplayUnit.js
+++ b/gui/src/components/units/useDisplayUnit.js
@@ -4,24 +4,8 @@ import {Unit} from "./Unit"
 import {useUnitContext} from "./UnitContext"
 import {getFieldProps} from "../editQuantity/StringEditQuantity"
 
-function getUnitSystem(def) {
-  let unit_system
-  if (def?.m_def === "nomad.metainfo.metainfo.Quantity") {
-    unit_system = def?._parent?.m_annotations?.display?.[0]?.unit_system
-    if (!unit_system && def?._section?._parentSections?.[0]) {
-      unit_system = getUnitSystem(def._section._parentSections[0])
-    }
-  } else if (def?.m_def === "nomad.metainfo.metainfo.Section") {
-    unit_system = def?.m_annotations?.display?.[0]?.unit_system
-    if (!unit_system && def?._parentSections?.[0]) {
-      unit_system = getUnitSystem(def._parentSections[0])
-    }
-  }
-  return unit_system
-}
-
 export function useDisplayUnit(quantityDef) {
-  const {units, unitSystems} = useUnitContext()
+  const {units} = useUnitContext()
   const {raiseError} = useErrors()
   const defaultUnit = useMemo(() => quantityDef.unit && new Unit(quantityDef.unit), [quantityDef])
   const dimension = defaultUnit && defaultUnit.dimension(false)
@@ -31,7 +15,6 @@ export function useDisplayUnit(quantityDef) {
   const displayUnitObj = useMemo(() => {
     if (!dimension) return
     let defaultDisplayUnitObj
-    const section_default_unit_system = getUnitSystem(quantityDef)
 
     // TODO: If we enable the new 'Schema' scope in the unit context, we should
     // prioritize those values there. But for now we just read unit info from
@@ -47,16 +30,13 @@ export function useDisplayUnit(quantityDef) {
       if (defaultDisplayUnitObj.dimension(true) !== defaultUnit.dimension(true)) {
         raiseError(`The provided defaultDisplayUnit for ${quantityDef.name} has incorrect dimensionality for this field.`)
       }
-    // If a unit system has been defined, use it
-    } else if (section_default_unit_system && unitSystems[section_default_unit_system]) {
-      defaultDisplayUnitObj = new Unit(unitSystems[section_default_unit_system].units[dimension].definition)
-    // Fallback option is the unit system in the global unit scope
+    // Use the global unit system defined in the schema
     } else {
       defaultDisplayUnitObj = new Unit(defaultUnit).toSystem(units)
     }
 
     return defaultDisplayUnitObj
-  }, [defaultDisplayUnit, defaultUnit, dimension, quantityDef, raiseError, unitSystems, units])
+  }, [defaultDisplayUnit, defaultUnit, dimension, quantityDef, raiseError, units])
 
   return displayUnitObj
 }
diff --git a/nomad/datamodel/metainfo/annotations.py b/nomad/datamodel/metainfo/annotations.py
index f0c3b7953a..afce100b56 100644
--- a/nomad/datamodel/metainfo/annotations.py
+++ b/nomad/datamodel/metainfo/annotations.py
@@ -126,7 +126,27 @@ class DisplayAnnotation(BaseModel):
 
 
 class QuantityDisplayAnnotation(DisplayAnnotation):
-    """The display settings for quantities."""
+    """
+    This annotations control how quantities are displayed in the GUI.  Use the
+    key `display` to add this annotation. For example in Python:
+
+    ```python
+    class Example(EntryData):
+        sample_id = Quantity(type=str, a_display={'visible': False})
+    ```
+
+    or in YAML:
+    ```yaml
+    definitions:
+      Example:
+        quantities:
+          sample_id:
+            type: str
+            m_annotations:
+              display:
+                visible: false
+    ```
+    """
 
     display_unit: Optional[str] = Field(
         None,
@@ -139,16 +159,28 @@ class QuantityDisplayAnnotation(DisplayAnnotation):
 
 
 class SectionDisplayAnnotation(DisplayAnnotation):
-    """The display settings for sections and packages."""
+    """
+    This annotations control how sections are displayed in the GUI. Use the
+    key `display` to add this annotation. For example in Python:
+
+    ```python
+    class Example(MSection):
+        m_def = Section(a_display={
+            'visible': False
+        })
+    ```
+
+    or in YAML:
+    ```yaml
+    definitions:
+      sections:
+        Example:
+          m_annotations:
+            display:
+              visible: false
+    ```
+    """
 
-    display_unit_system: Optional[str] = Field(
-        None,
-        description=strip(
-            """
-            To determine the default display unit system for section.
-        """
-        ),
-    )
     order: Optional[List[str]] = Field(
         None,
         description=strip(
@@ -265,11 +297,13 @@ class ELNAnnotation(AnnotationModel):
     defaultDisplayUnit: str = Field(
         None,
         description="""
-        Allows to define a default unit to initialize a `NumberEditQuantity` with. The
-        unit has to be compatible with the unit of the annotation quantity and the annotated
-        quantity must have a unit. Only applies to quantities and with
-        `component=NumberEditQuantity`.
+        This attribute is deprecated, use the `unit` attribute of `display`
+        annotation instead. Allows to define a default unit to initialize a
+        `NumberEditQuantity` with. The unit has to be compatible with the unit
+        of the annotation quantity and the annotated quantity must have a unit.
+        Only applies to quantities and with `component=NumberEditQuantity`.
     """,
+        deprecated=True,
     )
 
     minValue: Union[int, float] = Field(
@@ -301,7 +335,7 @@ class ELNAnnotation(AnnotationModel):
     hide: List[str] = Field(
         None,
         description="""
-        The annotation "hide" is deprecated. Use "visible" key of "properties" annotation instead.
+        This attribute is deprecated. Use `visible` attribute of `display` annotation instead.
         Allows you to hide certain quantities from a section editor. Give a list
         of quantity names. Quantities must exist in the section that this annotation
         is added to. Can only be used in section annotations.
-- 
GitLab