Browse Source

add prettier for js ts and vue files

Konstantin Ladutenko 3 years ago
parent
commit
5e18cfaed2
47 changed files with 3601 additions and 2745 deletions
  1. 20 1
      guiapp/package-lock.json
  2. 2 1
      guiapp/package.json
  3. 28 20
      guiapp/src/App.vue
  4. 166 165
      guiapp/src/components/InputWithUnits.vue
  5. 56 47
      guiapp/src/components/ReactiveChart.vue
  6. 39 27
      guiapp/src/components/ShowSpectrumRange.vue
  7. 21 19
      guiapp/src/components/config.ts
  8. 107 65
      guiapp/src/components/materials/MaterialsActivated.vue
  9. 225 161
      guiapp/src/components/materials/MaterialsSelector.vue
  10. 169 133
      guiapp/src/components/materials/PlotMaterials.vue
  11. 49 46
      guiapp/src/components/nearfield/GetNearFieldColorScale.vue
  12. 64 55
      guiapp/src/components/nearfield/GetNearFieldRefinedSettings.vue
  13. 83 57
      guiapp/src/components/nearfield/GetNearFieldSettings.vue
  14. 80 66
      guiapp/src/components/nearfield/GetWlFromPlot.vue
  15. 135 95
      guiapp/src/components/nearfield/PlotNearField.vue
  16. 114 77
      guiapp/src/components/nearfield/RunSimulationNearField.vue
  17. 92 79
      guiapp/src/components/nearfield/SaveSimulationNearField.vue
  18. 43 29
      guiapp/src/components/nearfield/ShowNearFieldWarning.vue
  19. 21 24
      guiapp/src/components/spectrum/GetHostIndex.vue
  20. 44 45
      guiapp/src/components/spectrum/GetModesToPlot.vue
  21. 242 179
      guiapp/src/components/spectrum/GetParticleParameters.vue
  22. 45 40
      guiapp/src/components/spectrum/GetPlotSettings.vue
  23. 119 84
      guiapp/src/components/spectrum/GetSourceParameters.vue
  24. 95 81
      guiapp/src/components/spectrum/GetUnits.vue
  25. 219 158
      guiapp/src/components/spectrum/PlotSelector.vue
  26. 54 42
      guiapp/src/components/spectrum/PlotSpectra.vue
  27. 246 187
      guiapp/src/components/spectrum/RunSimulationSpectrum.vue
  28. 91 88
      guiapp/src/components/utils.ts
  29. 70 60
      guiapp/src/layouts/MainLayout.vue
  30. 36 26
      guiapp/src/nmiejs.d.ts
  31. 8 10
      guiapp/src/pages/Error404.vue
  32. 26 22
      guiapp/src/pages/Far-field.vue
  33. 90 29
      guiapp/src/pages/Info.vue
  34. 27 22
      guiapp/src/pages/Materials.vue
  35. 38 38
      guiapp/src/pages/Near-field.vue
  36. 47 42
      guiapp/src/pages/Spectrum.vue
  37. 7 5
      guiapp/src/router/index.ts
  38. 67 53
      guiapp/src/store/gui-runtime/actions.ts
  39. 39 27
      guiapp/src/store/gui-runtime/mutations.ts
  40. 29 18
      guiapp/src/store/gui-runtime/state.ts
  41. 14 13
      guiapp/src/store/index.ts
  42. 119 70
      guiapp/src/store/plot-runtime/mutations.ts
  43. 107 86
      guiapp/src/store/plot-runtime/state.ts
  44. 13 14
      guiapp/src/store/simulation-setup/actions.ts
  45. 90 56
      guiapp/src/store/simulation-setup/mutations.ts
  46. 105 77
      guiapp/src/store/simulation-setup/state.ts
  47. 0 6
      tests/test_bulk_sphere.cc

+ 20 - 1
guiapp/package-lock.json

@@ -37,7 +37,8 @@
         "eslint": "^7.14.0",
         "eslint-config-prettier": "^8.1.0",
         "eslint-plugin-vue": "^7.0.0",
-        "node-polyfill-webpack-plugin": "^1.1.4"
+        "node-polyfill-webpack-plugin": "^1.1.4",
+        "prettier": "^2.5.1"
       },
       "engines": {
         "node": ">= 12.22.1",
@@ -11128,6 +11129,18 @@
         "node": ">=4"
       }
     },
+    "node_modules/prettier": {
+      "version": "2.5.1",
+      "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.5.1.tgz",
+      "integrity": "sha512-vBZcPRUR5MZJwoyi3ZoyQlc1rXeEck8KgeC9AwwOn+exuxLxq5toTRDTSaVrXHxelDMHy9zlicw8u66yxoSUFg==",
+      "dev": true,
+      "bin": {
+        "prettier": "bin-prettier.js"
+      },
+      "engines": {
+        "node": ">=10.13.0"
+      }
+    },
     "node_modules/pretty-error": {
       "version": "4.0.0",
       "resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-4.0.0.tgz",
@@ -22849,6 +22862,12 @@
       "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=",
       "dev": true
     },
+    "prettier": {
+      "version": "2.5.1",
+      "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.5.1.tgz",
+      "integrity": "sha512-vBZcPRUR5MZJwoyi3ZoyQlc1rXeEck8KgeC9AwwOn+exuxLxq5toTRDTSaVrXHxelDMHy9zlicw8u66yxoSUFg==",
+      "dev": true
+    },
     "pretty-error": {
       "version": "4.0.0",
       "resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-4.0.0.tgz",

+ 2 - 1
guiapp/package.json

@@ -39,7 +39,8 @@
     "eslint": "^7.14.0",
     "eslint-config-prettier": "^8.1.0",
     "eslint-plugin-vue": "^7.0.0",
-    "node-polyfill-webpack-plugin": "^1.1.4"
+    "node-polyfill-webpack-plugin": "^1.1.4",
+    "prettier": "^2.5.1"
   },
   "browserslist": [
     "last 10 Chrome versions",

+ 28 - 20
guiapp/src/App.vue

@@ -3,33 +3,41 @@
 </template>
 <script lang="ts">
 import { defineComponent, watch } from 'vue';
-import { useStore } from 'src/store'
+import { useStore } from 'src/store';
 
 export default defineComponent({
   name: 'App',
-  setup(){
-    const $store = useStore()
-    void (async () => $store.dispatch('simulationSetup/loadScattnlay'))()
-    void $store.dispatch('guiRuntime/activateMaterial', 'main/Ag/McPeak.yml')
-    void $store.dispatch('guiRuntime/activateMaterial', 'main/Au/McPeak.yml')
-    void $store.dispatch('guiRuntime/activateMaterial', 'main/Al/McPeak.yml')
-    void $store.dispatch('guiRuntime/activateMaterial', 'main/Cu/McPeak.yml')
-    void $store.dispatch('guiRuntime/activateMaterial', 'main/Si/Green-2008.yml')
-    void $store.dispatch('guiRuntime/activateMaterial', 'main/SiO2/Gao.yml')
-    void $store.dispatch('guiRuntime/activateMaterial', 'main/TiO2/Sarkar.yml')
+  setup() {
+    const $store = useStore();
+    void (async () => $store.dispatch('simulationSetup/loadScattnlay'))();
+    void $store.dispatch('guiRuntime/activateMaterial', 'main/Ag/McPeak.yml');
+    void $store.dispatch('guiRuntime/activateMaterial', 'main/Au/McPeak.yml');
+    void $store.dispatch('guiRuntime/activateMaterial', 'main/Al/McPeak.yml');
+    void $store.dispatch('guiRuntime/activateMaterial', 'main/Cu/McPeak.yml');
+    void $store.dispatch(
+      'guiRuntime/activateMaterial',
+      'main/Si/Green-2008.yml'
+    );
+    void $store.dispatch('guiRuntime/activateMaterial', 'main/SiO2/Gao.yml');
+    void $store.dispatch('guiRuntime/activateMaterial', 'main/TiO2/Sarkar.yml');
 
-    let isPlotInitialToggle = false
-    watch($store.state.guiRuntime.activatedMaterials, ()=>{
+    let isPlotInitialToggle = false;
+    watch($store.state.guiRuntime.activatedMaterials, () => {
       if (!isPlotInitialToggle) {
-        const indexToToggle = $store.state.guiRuntime.activatedMaterials.findIndex(val => val.name == 'Ag_McPeak')
+        const indexToToggle =
+          $store.state.guiRuntime.activatedMaterials.findIndex(
+            (val) => val.name == 'Ag_McPeak'
+          );
         // Materials are activated in async actions, so toggle Ag_McPeak to be plotted as soon as it is loaded.
         if (indexToToggle != -1) {
-          $store.commit('guiRuntime/toggleIsPlot', $store.state.guiRuntime.activatedMaterials[indexToToggle].name)
-          isPlotInitialToggle = true
+          $store.commit(
+            'guiRuntime/toggleIsPlot',
+            $store.state.guiRuntime.activatedMaterials[indexToToggle].name
+          );
+          isPlotInitialToggle = true;
         }
       }
-    })
-
-  }
-})
+    });
+  },
+});
 </script>

+ 166 - 165
guiapp/src/components/InputWithUnits.vue

@@ -1,88 +1,85 @@
 <template>
   <div class="q-pa-xs">
     <q-tooltip
-        v-model = "isShowingTooltip"
-        anchor="top middle"
-        self="center middle"
+      v-model="isShowingTooltip"
+      anchor="top middle"
+      self="center middle"
     >
-      {{formatNumber(localTooltipText,inputWithUnitsTooltipDigits)}}
+      {{ formatNumber(localTooltipText, inputWithUnitsTooltipDigits) }}
     </q-tooltip>
-    <q-tooltip v-if="isShowingHelp && !isInfoMode"
-               v-model = "isShowingHelpLocal"
-               anchor="bottom middle"
-               self="center middle"
+    <q-tooltip
+      v-if="isShowingHelp && !isInfoMode"
+      v-model="isShowingHelpLocal"
+      anchor="bottom middle"
+      self="center middle"
     >
-      Input example: <b>{{ helpExpr }}</b><br>
+      Input example: <b>{{ helpExpr }}</b
+      ><br />
     </q-tooltip>
-    <q-tooltip v-if="isInfoMode"
-               anchor="top middle"
-               self="center middle"
-    >
-      current settings<br>
+    <q-tooltip v-if="isInfoMode" anchor="top middle" self="center middle">
+      current settings<br />
     </q-tooltip>
-    <q-card
-        bordered
-        flat
-    >
-      <q-card-section
-          class="items-center bg-grey-2"
-          horizontal>
-        <div class="side_note text-grey-9 q-px-xs text-center"
-             :style="'width: '+inputWithUnitsTitleWidthStyle"
+    <q-card bordered flat>
+      <q-card-section class="items-center bg-grey-2" horizontal>
+        <div
+          class="side_note text-grey-9 q-px-xs text-center"
+          :style="'width: ' + inputWithUnitsTitleWidthStyle"
         >
-          {{title}}
+          {{ title }}
         </div>
         <div>
           <q-select
-              :model-value="localQSelectModel"
-              :options="qSelectOptions"
-              :disable="isInfoMode"
-              bg-color="white"
-              dense
-              fill-input
-              hide-selected
-              input-debounce="0"
-              options-dense
-              :style="'width: '+inputWithUnitsBodyWidthStyle"
-              use-input
-              behavior="menu"
-              @filter="filterQSelectOptions"
-              @blur="handleQSelectBlur"
-              @keydown.enter="handleQSelectBlur"
-              @input-value="localQSelectModel=$event"
+            :model-value="localQSelectModel"
+            :options="qSelectOptions"
+            :disable="isInfoMode"
+            bg-color="white"
+            dense
+            fill-input
+            hide-selected
+            input-debounce="0"
+            options-dense
+            :style="'width: ' + inputWithUnitsBodyWidthStyle"
+            use-input
+            behavior="menu"
+            @filter="filterQSelectOptions"
+            @blur="handleQSelectBlur"
+            @keydown.enter="handleQSelectBlur"
+            @input-value="localQSelectModel = $event"
           >
-            <template v-if="isError" #prepend >
+            <template v-if="isError" #prepend>
               <q-tooltip> Input conflict </q-tooltip>
-              <q-icon name="error" class="text-warning"/>
+              <q-icon name="error" class="text-warning" />
             </template>
             <template
-                v-if="isShowingTooltipAppend&&!isShowingTooltip"
-                #append
+              v-if="isShowingTooltipAppend && !isShowingTooltip"
+              #append
             >
-              <div
-                  style="font-size: 12px"
-                  class="q-py-sm"
-              >
-                {{formatNumber(localTooltipText,inputWithUnitsInlineDigits)}}
+              <div style="font-size: 12px" class="q-py-sm">
+                {{ formatNumber(localTooltipText, inputWithUnitsInlineDigits) }}
               </div>
             </template>
             <template #option="scope">
               <q-item v-bind="scope.itemProps" class="q-px-sm">
                 <q-item-section>
-                  {{scope.opt}}
+                  {{ scope.opt }}
                 </q-item-section>
                 <q-item-section side>
-                  {{formatNumber(evalString(scope.opt),inputWithUnitsInlineDigits)}}
+                  {{
+                    formatNumber(
+                      evalString(scope.opt),
+                      inputWithUnitsInlineDigits
+                    )
+                  }}
                 </q-item-section>
               </q-item>
             </template>
           </q-select>
         </div>
         <div
-            class="side_note text-grey-9 q-px-xs text-center"
-            :style="'width: '+inputWithUnitsUnitsWidthStyle"
+          class="side_note text-grey-9 q-px-xs text-center"
+          :style="'width: ' + inputWithUnitsUnitsWidthStyle"
         >
-          {{units}}
+          {{ units }}
         </div>
       </q-card-section>
     </q-card>
@@ -90,19 +87,16 @@
 </template>
 
 <script lang="ts">
-import {evaluate} from 'mathjs'
+import { evaluate } from 'mathjs';
+import { defineComponent, ref, watch } from 'vue';
 import {
-  defineComponent,
-  ref,
-  watch,
-  } from 'vue'
-import {inputWithUnitsTitleWidthStyle,
+  inputWithUnitsTitleWidthStyle,
   inputWithUnitsBodyWidthStyle,
   inputWithUnitsUnitsWidthStyle,
-    inputWithUnitsHistoryLength,
-    inputWithUnitsInlineDigits,
-    inputWithUnitsTooltipDigits
-} from 'components/config'
+  inputWithUnitsHistoryLength,
+  inputWithUnitsInlineDigits,
+  inputWithUnitsTooltipDigits,
+} from 'components/config';
 
 export default defineComponent({
   name: 'InputWithUnits',
@@ -110,186 +104,193 @@ export default defineComponent({
     inputResult: {
       type: Number,
       required: true,
-      default: 0
+      default: 0,
     },
     initialExpression: {
       type: String,
       required: true,
-      default: ''
+      default: '',
     },
     title: {
       type: String,
-      default: ''
+      default: '',
     },
     units: {
       type: String,
-      default: ''
+      default: '',
     },
     isShowingHelp: {
       type: Boolean,
-      default: false
+      default: false,
     },
     isError: {
       type: Boolean,
-      default:false
+      default: false,
     },
     isInfoMode: {
       type: Boolean,
-      default: false
+      default: false,
     },
   },
-  emits: [
-    'update:input-result',
-    'update:is-showing-help'
-  ],
-  setup(props, {emit}) {
+  emits: ['update:input-result', 'update:is-showing-help'],
+  setup(props, { emit }) {
+    let localQSelectModel = ref('');
+    let localTooltipText = ref('');
+    let isShowingTooltip = ref(false);
+    let isShowingTooltipAppend = ref(false);
+    let isShowingHelpLocal = ref(false);
+    let helpExpr = ref('(1+2)*sqrt(2)');
 
-    let localQSelectModel = ref('')
-    let localTooltipText = ref('')
-    let isShowingTooltip = ref(false)
-    let isShowingTooltipAppend = ref(false)
-    let isShowingHelpLocal = ref(false)
-    let helpExpr = ref('(1+2)*sqrt(2)')
-
-    let evaluated = ref(0)
-    let count_updates = 0
+    let evaluated = ref(0);
+    let count_updates = 0;
 
     // Set some random values to get correct typing with
     // TypeScript and remove them after initialization.
-    let qSelectOptions = ref(['a','b'])
-    let qSelectOptionsHistory = ref(['a','b'])
-    qSelectOptions.value.pop()
-    qSelectOptions.value.pop()
-    qSelectOptionsHistory.value.pop()
-    qSelectOptionsHistory.value.pop()
+    let qSelectOptions = ref(['a', 'b']);
+    let qSelectOptionsHistory = ref(['a', 'b']);
+    qSelectOptions.value.pop();
+    qSelectOptions.value.pop();
+    qSelectOptionsHistory.value.pop();
+    qSelectOptionsHistory.value.pop();
 
     // evaluate current input, keeps the previous evaluateValue for invalid input
     function runEvaluate() {
       // Using try{} block to drop silently invalid input
       try {
-        const tryEvaluate = Number(evaluate(localQSelectModel.value))
-        if (!isNaN(tryEvaluate)) evaluated.value = tryEvaluate
-      } catch { }
+        const tryEvaluate = Number(evaluate(localQSelectModel.value));
+        if (!isNaN(tryEvaluate)) evaluated.value = tryEvaluate;
+      } catch {}
     }
 
     watch(localQSelectModel, () => {
-      runEvaluate()
-    })
+      runEvaluate();
+    });
 
-    function setTooltipVisibility(){
+    function setTooltipVisibility() {
       if (evaluated.value != Number(localQSelectModel.value)) {
-        isShowingTooltip.value = true
-        isShowingTooltipAppend.value = true
+        isShowingTooltip.value = true;
+        isShowingTooltipAppend.value = true;
       } else {
-        isShowingTooltip.value = false
-        isShowingTooltipAppend.value = false
+        isShowingTooltip.value = false;
+        isShowingTooltipAppend.value = false;
       }
     }
 
-    watch(isShowingTooltip, ()=>{
+    watch(isShowingTooltip, () => {
       // For a trivial case we would like to switch off showing tooltip
-      if (isShowingTooltip.value) setTooltipVisibility()
-    })
+      if (isShowingTooltip.value) setTooltipVisibility();
+    });
 
-    function setTooltip(){
-      localTooltipText.value = evaluated.value.toString()
-      setTooltipVisibility()
+    function setTooltip() {
+      localTooltipText.value = evaluated.value.toString();
+      setTooltipVisibility();
     }
 
     watch(evaluated, () => {
-      emit('update:input-result', evaluated.value)
-      setTooltip()
+      emit('update:input-result', evaluated.value);
+      setTooltip();
       // Switch off showing help as soon as we have some input from user
-      const threshold = 1
-      if (count_updates < threshold+1) { // limit the unbound grow of count_updates
-        count_updates += 1
+      const threshold = 1;
+      if (count_updates < threshold + 1) {
+        // limit the unbound grow of count_updates
+        count_updates += 1;
         if (props.isShowingHelp && count_updates > threshold) {
-          qSelectOptionsHistory.value.unshift(helpExpr.value)
-          emit('update:is-showing-help', false)
+          qSelectOptionsHistory.value.unshift(helpExpr.value);
+          emit('update:is-showing-help', false);
         }
       }
-    })
+    });
 
-    watch(isShowingHelpLocal, ()=>{
+    watch(isShowingHelpLocal, () => {
       // isShowingHelpLocal.value is set to be
       // true on hover. Disable it if needed.
       if (isShowingHelpLocal.value) {
-        if (qSelectOptions.value.length>0) isShowingHelpLocal.value = false
+        if (qSelectOptions.value.length > 0) isShowingHelpLocal.value = false;
       }
-    })
+    });
 
-    watch(qSelectOptions, ()=>{
-      if (qSelectOptions.value.length>0) isShowingHelpLocal.value = false
-    })
+    watch(qSelectOptions, () => {
+      if (qSelectOptions.value.length > 0) isShowingHelpLocal.value = false;
+    });
 
-    watch(props, ()=> {
+    watch(props, () => {
       // Using try{} block to drop silently invalid input
       try {
         // If props.inputResults changed and is not equal to local
         // expression localQSelectModel.value, then update local expression
-        const tryEvaluate = Number(evaluate(localQSelectModel.value))
-        if ( !isNaN(tryEvaluate)
-            && props.inputResult != tryEvaluate) {
-          localQSelectModel.value = props.inputResult.toString()
+        const tryEvaluate = Number(evaluate(localQSelectModel.value));
+        if (!isNaN(tryEvaluate) && props.inputResult != tryEvaluate) {
+          localQSelectModel.value = props.inputResult.toString();
         }
-      } catch { }
-    })
+      } catch {}
+    });
 
-    localQSelectModel.value = props.initialExpression.toString()
-    runEvaluate()
-    localTooltipText.value = localQSelectModel.value
-    setTooltip()
-    isShowingTooltip.value = false
+    localQSelectModel.value = props.initialExpression.toString();
+    runEvaluate();
+    localTooltipText.value = localQSelectModel.value;
+    setTooltip();
+    isShowingTooltip.value = false;
 
     return {
-      inputWithUnitsTitleWidthStyle, inputWithUnitsBodyWidthStyle, inputWithUnitsUnitsWidthStyle,
-      inputWithUnitsHistoryLength, inputWithUnitsInlineDigits, inputWithUnitsTooltipDigits,
-      localTooltipText, isShowingTooltip,
-      isShowingTooltipAppend, isShowingHelpLocal,
+      inputWithUnitsTitleWidthStyle,
+      inputWithUnitsBodyWidthStyle,
+      inputWithUnitsUnitsWidthStyle,
+      inputWithUnitsHistoryLength,
+      inputWithUnitsInlineDigits,
+      inputWithUnitsTooltipDigits,
+      localTooltipText,
+      isShowingTooltip,
+      isShowingTooltipAppend,
+      isShowingHelpLocal,
       helpExpr,
-      qSelectOptions,  localQSelectModel,
+      qSelectOptions,
+      localQSelectModel,
 
-      handleQSelectBlur(){
-        isShowingTooltip.value = false
-        const expr = localQSelectModel.value
-        if (!qSelectOptionsHistory.value.includes(expr)) qSelectOptionsHistory.value.unshift(expr)
-        if (qSelectOptionsHistory.value.length > inputWithUnitsHistoryLength) qSelectOptionsHistory.value.pop()
+      handleQSelectBlur() {
+        isShowingTooltip.value = false;
+        const expr = localQSelectModel.value;
+        if (!qSelectOptionsHistory.value.includes(expr))
+          qSelectOptionsHistory.value.unshift(expr);
+        if (qSelectOptionsHistory.value.length > inputWithUnitsHistoryLength)
+          qSelectOptionsHistory.value.pop();
       },
 
-      filterQSelectOptions (val:string,
-                            update:(data: ()=>void) => void) {
+      filterQSelectOptions(val: string, update: (data: () => void) => void) {
         update(() => {
           // To remove the selection from previously
           // selected option - we refill the options list
-          qSelectOptions.value = qSelectOptionsHistory.value
-        })
+          qSelectOptions.value = qSelectOptionsHistory.value;
+        });
       },
 
-      formatNumber (value:string, digits:number, prepend:string):string {
-        if (!prepend) prepend = '='
-        if (value==='') return ''
-        const num = parseFloat(value)
-        if ( num < Math.pow(10, -digits) ||
-            num > 5*Math.pow(10,  digits+2)
-        ) return prepend+num.toExponential(digits)
-        return prepend+Number(Math.round(
-                parseFloat(value + 'e' + digits.toString())).toString()
-            + 'e-' + digits.toString()).toString()
+      formatNumber(value: string, digits: number, prepend: string): string {
+        if (!prepend) prepend = '=';
+        if (value === '') return '';
+        const num = parseFloat(value);
+        if (num < Math.pow(10, -digits) || num > 5 * Math.pow(10, digits + 2))
+          return prepend + num.toExponential(digits);
+        return (
+          prepend +
+          Number(
+            Math.round(parseFloat(value + 'e' + digits.toString())).toString() +
+              'e-' +
+              digits.toString()
+          ).toString()
+        );
       },
 
       // evaluate option items, returns empty string for trivial evaluations and errors
-      evalString(val:string):string {
+      evalString(val: string): string {
         // Using try{} block to drop silently invalid input
         try {
-          const tryEvaluate = Number(evaluate(val))
+          const tryEvaluate = Number(evaluate(val));
           if (!isNaN(tryEvaluate) && tryEvaluate != Number(val)) {
-            return tryEvaluate.toString()
+            return tryEvaluate.toString();
           }
-        } catch { }
-        return ''
+        } catch {}
+        return '';
       },
-
-    }
+    };
   },
-})
+});
 </script>

+ 56 - 47
guiapp/src/components/ReactiveChart.vue

@@ -3,8 +3,8 @@
 </template>
 
 <script lang="ts">
-import { newPlot, react } from 'plotly.js-dist-min'
-import { plotlyChart } from 'src/store/plot-runtime/state'
+import { newPlot, react } from 'plotly.js-dist-min';
+import { plotlyChart } from 'src/store/plot-runtime/state';
 import {
   defineComponent,
   PropType,
@@ -12,9 +12,9 @@ import {
   watch,
   onMounted,
   onUnmounted,
-} from 'vue'
-import {cloneDeep} from 'lodash'
-import { v4 as uuidv4 } from 'uuid'
+} from 'vue';
+import { cloneDeep } from 'lodash';
+import { v4 as uuidv4 } from 'uuid';
 
 export default defineComponent({
   name: 'ReactiveChart',
@@ -25,71 +25,80 @@ export default defineComponent({
     },
     windowWidthShare: {
       type: Number,
-      required:false,
-      default: 1
+      required: false,
+      default: 1,
     },
     windowHeightShare: {
       type: Number,
-      required:false,
-      default: 0.8
-    },  },
-  emits: [
-    'plotCreated'
-  ],
+      required: false,
+      default: 0.8,
+    },
+  },
+  emits: ['plotCreated'],
 
-  setup(props, {emit}) {
-    const chartUUID = uuidv4()
+  setup(props, { emit }) {
+    const chartUUID = uuidv4();
     // const chartUUID = 'plotly chart'
-    let chartLocal = cloneDeep(props.chart)
+    let chartLocal = cloneDeep(props.chart);
 
     // Update (or add if absent) width and height of the layout to fit current window
     // and replot it.
-    function plotlyReact () {
-      if (!document.getElementById(chartUUID)) return
-      const width = window.innerWidth*props.windowWidthShare
-      const height = window.innerHeight*props.windowHeightShare
-      chartLocal.layout.width = width * 0.92
-      chartLocal.layout.height = height * 0.95
-      if (height < 400) chartLocal.layout.height = height
+    function plotlyReact() {
+      if (!document.getElementById(chartUUID)) return;
+      const width = window.innerWidth * props.windowWidthShare;
+      const height = window.innerHeight * props.windowHeightShare;
+      chartLocal.layout.width = width * 0.92;
+      chartLocal.layout.height = height * 0.95;
+      if (height < 400) chartLocal.layout.height = height;
 
       // react(...) is a promise, but we do not care to await it, so mark it with `void` keyword
       if (chartLocal.config == undefined) {
-        void react(chartUUID, chartLocal.data, chartLocal.layout)
+        void react(chartUUID, chartLocal.data, chartLocal.layout);
       } else {
-        void react(chartUUID, chartLocal.data, chartLocal.layout, chartLocal.config)
+        void react(
+          chartUUID,
+          chartLocal.data,
+          chartLocal.layout,
+          chartLocal.config
+        );
       }
     }
 
     function plotlyNew() {
       if (chartLocal.config == undefined) {
-        void newPlot(chartUUID, chartLocal.data, chartLocal.layout)
+        void newPlot(chartUUID, chartLocal.data, chartLocal.layout);
       } else {
-        void newPlot(chartUUID, chartLocal.data, chartLocal.layout, chartLocal.config)
+        void newPlot(
+          chartUUID,
+          chartLocal.data,
+          chartLocal.layout,
+          chartLocal.config
+        );
       }
     }
-    onMounted( () => {
-      plotlyNew()
-      emit('plotCreated', chartUUID)
-    })
+    onMounted(() => {
+      plotlyNew();
+      emit('plotCreated', chartUUID);
+    });
 
-    window.addEventListener('resize', plotlyReact)
-    onUnmounted(()=>{
-      window.removeEventListener('resize', plotlyReact)
-    })
+    window.addEventListener('resize', plotlyReact);
+    onUnmounted(() => {
+      window.removeEventListener('resize', plotlyReact);
+    });
 
-    watch(props, ()=>{
-      chartLocal = cloneDeep(props.chart)
-      plotlyReact()
-    })
+    watch(props, () => {
+      chartLocal = cloneDeep(props.chart);
+      plotlyReact();
+    });
 
-    onActivated(()=>{
-      chartLocal = cloneDeep(props.chart)
-      plotlyReact()
-    })
+    onActivated(() => {
+      chartLocal = cloneDeep(props.chart);
+      plotlyReact();
+    });
 
     return {
-      chartUUID
-    }
-  }
-})
+      chartUUID,
+    };
+  },
+});
 </script>

+ 39 - 27
guiapp/src/components/ShowSpectrumRange.vue

@@ -1,29 +1,36 @@
 <template>
   <span>
-  <q-tooltip
-      v-if=" spectrumRangeStart > fromWavelengthStore ||
-             spectrumRangeEnd   <   toWavelengthStore"
-      anchor="top middle" self="bottom middle"
-      class="bg-red">
-    Mismatch with spectrum simulation
-  </q-tooltip>
-  <span :class="spectrumRangeStart > fromWavelengthStore?'text-red':'text-black'">
-              {{ Math.ceil(spectrumRangeStart) }}
-            </span>
-  &ndash;
-  <span :class="spectrumRangeEnd < toWavelengthStore?'text-red':'text-black'">
-              {{ Math.floor(spectrumRangeEnd) }}
-            </span>
-  &NonBreakingSpace;nm
+    <q-tooltip
+      v-if="
+        spectrumRangeStart > fromWavelengthStore ||
+        spectrumRangeEnd < toWavelengthStore
+      "
+      anchor="top middle"
+      self="bottom middle"
+      class="bg-red"
+    >
+      Mismatch with spectrum simulation
+    </q-tooltip>
+    <span
+      :class="
+        spectrumRangeStart > fromWavelengthStore ? 'text-red' : 'text-black'
+      "
+    >
+      {{ Math.ceil(spectrumRangeStart) }}
     </span>
+    &ndash;
+    <span
+      :class="spectrumRangeEnd < toWavelengthStore ? 'text-red' : 'text-black'"
+    >
+      {{ Math.floor(spectrumRangeEnd) }}
+    </span>
+    &NonBreakingSpace;nm
+  </span>
 </template>
 
 <script lang="ts">
-import {
-  computed,
-  defineComponent,
-} from 'vue'
-import { useStore } from 'src/store'
+import { computed, defineComponent } from 'vue';
+import { useStore } from 'src/store';
 
 export default defineComponent({
   name: 'ShowSpectrumRange',
@@ -38,13 +45,18 @@ export default defineComponent({
     },
   },
   setup() {
-    const $store = useStore()
-    const fromWavelengthStore = computed(()=>$store.state.simulationSetup.gui.fromWL)
-    const toWavelengthStore = computed(()=>$store.state.simulationSetup.gui.toWL)
+    const $store = useStore();
+    const fromWavelengthStore = computed(
+      () => $store.state.simulationSetup.gui.fromWL
+    );
+    const toWavelengthStore = computed(
+      () => $store.state.simulationSetup.gui.toWL
+    );
 
     return {
-      fromWavelengthStore, toWavelengthStore
-    }
-  }
-})
+      fromWavelengthStore,
+      toWavelengthStore,
+    };
+  },
+});
 </script>

+ 21 - 19
guiapp/src/components/config.ts

@@ -1,22 +1,24 @@
-export const flexRowTitleStyle = 'width:10em; margin: auto; color:black;'
-export const basicSelectorWidthStyle = '6.5em'
+export const flexRowTitleStyle = 'width:10em; margin: auto; color:black;';
+export const basicSelectorWidthStyle = '6.5em';
 
-export const inputWithUnitsHistoryLength = 5
-export const inputWithUnitsTooltipDigits = 2
-export const inputWithUnitsInlineDigits = 1
+export const inputWithUnitsHistoryLength = 5;
+export const inputWithUnitsTooltipDigits = 2;
+export const inputWithUnitsInlineDigits = 1;
 
-export const inputWithUnitsTitleWidthStyle = '4em'
-export const inputWithUnitsBodyWidthStyle = '10em'
-export const inputWithUnitsUnitsWidthStyle = '3em'
-function getInt(val:string) {return parseInt(val.slice(0,-2))}
-export const basicWidthStyle = (
-    getInt(inputWithUnitsBodyWidthStyle)
-    + getInt(inputWithUnitsTitleWidthStyle)
-    + getInt(inputWithUnitsUnitsWidthStyle)
-    + 0.71 // To get the same width in GUI as all three parts above joined in inputWithUnits component
-).toString()+'em'
-
-
-export const maxNumberOfModesToPlot = 10
-export const maxNumberOfLayers = 10
+export const inputWithUnitsTitleWidthStyle = '4em';
+export const inputWithUnitsBodyWidthStyle = '10em';
+export const inputWithUnitsUnitsWidthStyle = '3em';
+function getInt(val: string) {
+  return parseInt(val.slice(0, -2));
+}
+export const basicWidthStyle =
+  (
+    getInt(inputWithUnitsBodyWidthStyle) +
+    getInt(inputWithUnitsTitleWidthStyle) +
+    getInt(inputWithUnitsUnitsWidthStyle) +
+    0.71
+  ) // To get the same width in GUI as all three parts above joined in inputWithUnits component
+    .toString() + 'em';
 
+export const maxNumberOfModesToPlot = 10;
+export const maxNumberOfLayers = 10;

+ 107 - 65
guiapp/src/components/materials/MaterialsActivated.vue

@@ -1,19 +1,18 @@
 <template>
   <div class="col-12 q-pa-md">
     <q-table
-          :rows="$store.state.guiRuntime.activatedMaterials"
-          :columns="columns"
-          :rows-per-page-options="[0]"
-          hide-pagination
-          dense
-          title="Available materials"
-          title-class="text-h6"
-          row-key="name"
-      >
-
+      :rows="$store.state.guiRuntime.activatedMaterials"
+      :columns="columns"
+      :rows-per-page-options="[0]"
+      hide-pagination
+      dense
+      title="Available materials"
+      title-class="text-h6"
+      row-key="name"
+    >
       <template #header="props">
         <q-tr :props="props">
-          <q-th auto-width/>
+          <q-th auto-width />
           <q-th auto-width> Plot </q-th>
           <q-th auto-width class="text-left"> Label </q-th>
           <q-th auto-width class="text-left"> Range </q-th>
@@ -23,99 +22,142 @@
 
       <template #body="props">
         <q-tr
-            v-if="props.row.name!='link' && props.row.name!='nk-constant' && props.row.name!='PEC'"
-            :props="props"
+          v-if="
+            props.row.name != 'link' &&
+            props.row.name != 'nk-constant' &&
+            props.row.name != 'PEC'
+          "
+          :props="props"
         >
           <q-td auto-width>
-            <span v-if="!$store.state.simulationSetup.gui.layers.find(el=>el.material.name===props.row.name)">
-            <q-tooltip anchor="top middle" self="bottom middle" >
-              Delete</q-tooltip>
-            <q-btn size="sm" padding="5px" color="primary" round dense icon="delete"
-                   @click="deleteFromSimulation(props.row.name)"/>
+            <span
+              v-if="
+                !$store.state.simulationSetup.gui.layers.find(
+                  (el) => el.material.name === props.row.name
+                )
+              "
+            >
+              <q-tooltip anchor="top middle" self="bottom middle">
+                Delete</q-tooltip
+              >
+              <q-btn
+                size="sm"
+                padding="5px"
+                color="primary"
+                round
+                dense
+                icon="delete"
+                @click="deleteFromSimulation(props.row.name)"
+              />
             </span>
-            <span v-else >
-            <q-tooltip anchor="top start" self="bottom start" >
-              Used in spectrum simulation</q-tooltip>
-              <q-btn size="sm" padding="5px" text-color="primary" round dense flat icon="push_pin" to="/spectrum"/>
+            <span v-else>
+              <q-tooltip anchor="top start" self="bottom start">
+                Used in spectrum simulation</q-tooltip
+              >
+              <q-btn
+                size="sm"
+                padding="5px"
+                text-color="primary"
+                round
+                dense
+                flat
+                icon="push_pin"
+                to="/spectrum"
+              />
             </span>
           </q-td>
 
           <q-td auto-width>
-            <q-checkbox :model-value="props.row.isPlot" size="sm" color="primary" dense
-                        @click="$store.commit('guiRuntime/toggleIsPlot', props.row.name )"
+            <q-checkbox
+              :model-value="props.row.isPlot"
+              size="sm"
+              color="primary"
+              dense
+              @click="$store.commit('guiRuntime/toggleIsPlot', props.row.name)"
             />
           </q-td>
 
-
-          <q-td auto-width class=""
-                @click="$store.commit('guiRuntime/toggleIsPlot', props.row.name )"
+          <q-td
+            auto-width
+            class=""
+            @click="$store.commit('guiRuntime/toggleIsPlot', props.row.name)"
           >
-            {{composeLabelFromPageData(props.row.name)}}
+            {{ composeLabelFromPageData(props.row.name) }}
           </q-td>
 
-          <q-td auto-width
-                @click="$store.commit('guiRuntime/toggleIsPlot', props.row.name )"
+          <q-td
+            auto-width
+            @click="$store.commit('guiRuntime/toggleIsPlot', props.row.name)"
           >
             <ShowSpectrumRange
-                :spectrum-range-start="props.row.spectrumRangeStart"
-                :spectrum-range-end="props.row.spectrumRangeEnd"
+              :spectrum-range-start="props.row.spectrumRangeStart"
+              :spectrum-range-end="props.row.spectrumRangeEnd"
             />
           </q-td>
 
-          <q-td class=""
-                @click="$store.commit('guiRuntime/toggleIsPlot', props.row.name )"
+          <q-td
+            class=""
+            @click="$store.commit('guiRuntime/toggleIsPlot', props.row.name)"
           >
             <span v-if="props.row.nSpline && props.row.kSpline">
-              <q-icon size='sm' color="green" name="done" />
+              <q-icon size="sm" color="green" name="done" />
             </span>
             <span v-else>
-              <q-icon size='xs' color="red" name="do_not_disturb" />
+              <q-icon size="xs" color="red" name="do_not_disturb" />
             </span>
           </q-td>
-
         </q-tr>
       </template>
-
-      </q-table>
+    </q-table>
   </div>
 </template>
 
 <script lang="ts">
-import {
-  computed,
-  defineComponent,
-} from 'vue'
-import { useStore } from 'src/store'
-import { composeLabelFromPageData } from 'components/utils'
-import ShowSpectrumRange from 'components/ShowSpectrumRange.vue'
+import { computed, defineComponent } from 'vue';
+import { useStore } from 'src/store';
+import { composeLabelFromPageData } from 'components/utils';
+import ShowSpectrumRange from 'components/ShowSpectrumRange.vue';
 
 export default defineComponent({
-
   name: 'MaterialsActivated',
-  components: {ShowSpectrumRange},
+  components: { ShowSpectrumRange },
 
   setup: function () {
-    const $store = useStore()
+    const $store = useStore();
 
-    const fromWavelengthStore = computed(()=>$store.state.simulationSetup.gui.fromWL)
-    const toWavelengthStore = computed(()=>$store.state.simulationSetup.gui.toWL)
+    const fromWavelengthStore = computed(
+      () => $store.state.simulationSetup.gui.fromWL
+    );
+    const toWavelengthStore = computed(
+      () => $store.state.simulationSetup.gui.toWL
+    );
 
     const columns = [
       // do not change the order without updating the template
-      {name: 'spectrumRangeStart', label: 'RangeStart', field: 'spectrumRangeStart'},
-      {name: 'spectrumRangeEnd', label: 'RangeEnd', field: 'spectrumRangeEnd'},
-      {name: 'name', label: 'name', field: 'name'},
-      {name: 'nSpline', nSpline: 'nSpline', field: 'nSpline'},
-      {name: 'kSpline', kSpline: 'kSpline', field: 'kSpline'},
-    ]
-
-    return {columns,
-      fromWavelengthStore, toWavelengthStore,
+      {
+        name: 'spectrumRangeStart',
+        label: 'RangeStart',
+        field: 'spectrumRangeStart',
+      },
+      {
+        name: 'spectrumRangeEnd',
+        label: 'RangeEnd',
+        field: 'spectrumRangeEnd',
+      },
+      { name: 'name', label: 'name', field: 'name' },
+      { name: 'nSpline', nSpline: 'nSpline', field: 'nSpline' },
+      { name: 'kSpline', kSpline: 'kSpline', field: 'kSpline' },
+    ];
+
+    return {
+      columns,
+      fromWavelengthStore,
+      toWavelengthStore,
       composeLabelFromPageData,
-      deleteFromSimulation(name:string) {
-        $store.commit('guiRuntime/deleteMaterial', name)
-      }
-    }
+      deleteFromSimulation(name: string) {
+        $store.commit('guiRuntime/deleteMaterial', name);
+      },
+    };
   },
-})
+});
 </script>

+ 225 - 161
guiapp/src/components/materials/MaterialsSelector.vue

@@ -1,36 +1,39 @@
 <template>
   <div class="col-12 q-pa-md">
     <q-table
-          :rows="rows"
-          :columns="columns"
-          :filter="filter"
-          :loading="loading"
-          :rows-per-page-options="[3, 12, 24, 0]"
-          dense
-          title="Available materials"
-          title-class="text-h6"
-          row-key="id"
-      >
-        <template #top>
-          <div class="q-mr-md">
-            <q-tooltip anchor="top end" self="center middle" >
-              Using a copy of RefractiveIndex.info website.<br> Analytical models are not implemented.
-            </q-tooltip>
-            <q-icon size='sm' name="o_info" />
-          </div>
-
-          <q-input v-model="filter" dense  debounce="200" color="primary" >
-          <q-tooltip  v-if="!filter" anchor="top middle" self="center middle">filter by any string</q-tooltip>
-            <template #append>
-              <q-icon name="filter_alt" />
-            </template>
-            <template v-if="filter" #after>
-              <q-btn  flat round dense icon="cancel" @click="filter=''"/>
-            </template>
-          </q-input>
-
-          <q-space />
-        </template>
+      :rows="rows"
+      :columns="columns"
+      :filter="filter"
+      :loading="loading"
+      :rows-per-page-options="[3, 12, 24, 0]"
+      dense
+      title="Available materials"
+      title-class="text-h6"
+      row-key="id"
+    >
+      <template #top>
+        <div class="q-mr-md">
+          <q-tooltip anchor="top end" self="center middle">
+            Using a copy of RefractiveIndex.info website.<br />
+            Analytical models are not implemented.
+          </q-tooltip>
+          <q-icon size="sm" name="o_info" />
+        </div>
+
+        <q-input v-model="filter" dense debounce="200" color="primary">
+          <q-tooltip v-if="!filter" anchor="top middle" self="center middle"
+            >filter by any string</q-tooltip
+          >
+          <template #append>
+            <q-icon name="filter_alt" />
+          </template>
+          <template v-if="filter" #after>
+            <q-btn flat round dense icon="cancel" @click="filter = ''" />
+          </template>
+        </q-input>
+
+        <q-space />
+      </template>
 
       <template #header="props">
         <q-tr :props="props">
@@ -45,181 +48,234 @@
 
       <template #body="props">
         <q-tr :props="props">
-
           <q-td auto-width>
-            <q-tooltip anchor="top end" self="center middle" >
-              Add to simulation</q-tooltip>
-            <q-btn size="sm" color="primary" round dense icon="add" @click="addToSimulation(props.row.id)"/>
+            <q-tooltip anchor="top end" self="center middle">
+              Add to simulation</q-tooltip
+            >
+            <q-btn
+              size="sm"
+              color="primary"
+              round
+              dense
+              icon="add"
+              @click="addToSimulation(props.row.id)"
+            />
           </q-td>
 
           <q-td auto-width>
-            <q-tooltip anchor="top end" self="center middle" >
-              Download *.yml file</q-tooltip>
-            <q-btn flat
-                   size="md"
-                   color="primary"
-                   icon="download"
-                   padding="xs 2px"
-                   @click="downloadPageData(props.row.pageData)"
+            <q-tooltip anchor="top end" self="center middle">
+              Download *.yml file</q-tooltip
+            >
+            <q-btn
+              flat
+              size="md"
+              color="primary"
+              icon="download"
+              padding="xs 2px"
+              @click="downloadPageData(props.row.pageData)"
             />
           </q-td>
 
           <q-td class="">
-            {{composeLabelFromPageData(props.row.pageData)}}
+            {{ composeLabelFromPageData(props.row.pageData) }}
           </q-td>
 
           <q-td auto-width>
             <ShowSpectrumRange
-                :spectrum-range-start="props.row.spectrumRangeStart*1000"
-                :spectrum-range-end="props.row.spectrumRangeEnd*1000"
+              :spectrum-range-start="props.row.spectrumRangeStart * 1000"
+              :spectrum-range-end="props.row.spectrumRangeEnd * 1000"
             />
           </q-td>
 
           <q-td auto-width>
             <!-- eslint-disable-next-line vue/no-v-html -->
-            <div v-html="props.row.bookName"/>
-            <q-tooltip anchor="top middle" self="center middle" >
-              {{ props.row.shelfDivider }}</q-tooltip>
+            <div v-html="props.row.bookName" />
+            <q-tooltip anchor="top middle" self="center middle">
+              {{ props.row.shelfDivider }}</q-tooltip
+            >
           </q-td>
 
-          <q-td> {{ props.row.bookDivider}}<span v-if="props.row.bookDivider">;&nbsp;</span>{{props.row.pageName }} </q-td>
-
+          <q-td>
+            {{ props.row.bookDivider
+            }}<span v-if="props.row.bookDivider">;&nbsp;</span
+            >{{ props.row.pageName }}
+          </q-td>
         </q-tr>
       </template>
-
-      </q-table>
+    </q-table>
   </div>
 </template>
 
 <script lang="ts">
-import {
-  computed,
-  defineComponent,
-  reactive,
-  ref
-} from 'vue'
-import { useStore } from 'src/store'
-import { load } from 'js-yaml'
-import { composeLabelFromPageData } from 'components/utils'
-import ShowSpectrumRange from 'components/ShowSpectrumRange.vue'
-import { saveAs } from 'file-saver'
-
+import { computed, defineComponent, reactive, ref } from 'vue';
+import { useStore } from 'src/store';
+import { load } from 'js-yaml';
+import { composeLabelFromPageData } from 'components/utils';
+import ShowSpectrumRange from 'components/ShowSpectrumRange.vue';
+import { saveAs } from 'file-saver';
 
 export default defineComponent({
-
   name: 'MaterialsSelector',
-  components: {ShowSpectrumRange},
+  components: { ShowSpectrumRange },
 
   setup: function () {
-    const $store = useStore()
-    const loading = ref(true)
+    const $store = useStore();
+    const loading = ref(true);
 
-    const fromWavelengthStore = computed(()=>$store.state.simulationSetup.gui.fromWL)
-    const toWavelengthStore = computed(()=>$store.state.simulationSetup.gui.toWL)
+    const fromWavelengthStore = computed(
+      () => $store.state.simulationSetup.gui.fromWL
+    );
+    const toWavelengthStore = computed(
+      () => $store.state.simulationSetup.gui.toWL
+    );
 
     const columns = [
       // do not change the order without updating the template
-      {name: 'id', label: '', field: 'id'},
-      {name: 'bookDivider', label: 'State', field: 'bookDivider'},
-      {name: 'bookName', label: 'Material', field: 'bookName'},
-      {name: 'spectrumRangeStart', label: 'RangeStart', field: 'spectrumRangeStart'},
-      {name: 'spectrumRangeEnd', label: 'RangeEnd', field: 'spectrumRangeEnd'},
-      {name: 'pageName', label: 'Details', field: 'pageName'},
-      {name: 'shelfDivider', label: 'Group', field: 'shelfDivider'},
-      {name: 'pageData', label: 'file', field: 'pageData'},
-    ]
-
-    function GetRange(val:string) {
-      if (val.lastIndexOf('µm') == -1) return [val,'']
-      const rangeStartPosition = val.slice(0,val.lastIndexOf('µm')-1).lastIndexOf(' ')
-      const spectrumRange = val.slice(rangeStartPosition+1,val.lastIndexOf('µm')+2)
-      const newPageName = val.replace(spectrumRange,'')
-      const spectrumRangeStart = spectrumRange.slice(0, spectrumRange.lastIndexOf('-'))
-      const spectrumRangeEnd = spectrumRange.slice(spectrumRange.lastIndexOf('-')+1,
-          spectrumRange.lastIndexOf('µm')-1)
-      return [newPageName,spectrumRangeStart, spectrumRangeEnd]
+      { name: 'id', label: '', field: 'id' },
+      { name: 'bookDivider', label: 'State', field: 'bookDivider' },
+      { name: 'bookName', label: 'Material', field: 'bookName' },
+      {
+        name: 'spectrumRangeStart',
+        label: 'RangeStart',
+        field: 'spectrumRangeStart',
+      },
+      {
+        name: 'spectrumRangeEnd',
+        label: 'RangeEnd',
+        field: 'spectrumRangeEnd',
+      },
+      { name: 'pageName', label: 'Details', field: 'pageName' },
+      { name: 'shelfDivider', label: 'Group', field: 'shelfDivider' },
+      { name: 'pageData', label: 'file', field: 'pageData' },
+    ];
+
+    function GetRange(val: string) {
+      if (val.lastIndexOf('µm') == -1) return [val, ''];
+      const rangeStartPosition = val
+        .slice(0, val.lastIndexOf('µm') - 1)
+        .lastIndexOf(' ');
+      const spectrumRange = val.slice(
+        rangeStartPosition + 1,
+        val.lastIndexOf('µm') + 2
+      );
+      const newPageName = val.replace(spectrumRange, '');
+      const spectrumRangeStart = spectrumRange.slice(
+        0,
+        spectrumRange.lastIndexOf('-')
+      );
+      const spectrumRangeEnd = spectrumRange.slice(
+        spectrumRange.lastIndexOf('-') + 1,
+        spectrumRange.lastIndexOf('µm') - 1
+      );
+      return [newPageName, spectrumRangeStart, spectrumRangeEnd];
     }
 
-    function splitBookName(val:string) {
-      if (val.lastIndexOf('(') == -1) return val
-      const splitPosition = val.lastIndexOf('(')
-      const mainPart = val.slice(0,splitPosition-1)
-      const otherPart = val.slice(splitPosition+1, val.length-1)
-      return mainPart+'<br><span style="font-size: 0.5em;">'+otherPart+'</span>'
+    function splitBookName(val: string) {
+      if (val.lastIndexOf('(') == -1) return val;
+      const splitPosition = val.lastIndexOf('(');
+      const mainPart = val.slice(0, splitPosition - 1);
+      const otherPart = val.slice(splitPosition + 1, val.length - 1);
+      return (
+        mainPart +
+        '<br><span style="font-size: 0.5em;">' +
+        otherPart +
+        '</span>'
+      );
     }
 
-    async function GetPagesFromLib() { /* eslint-disable */
+    async function GetPagesFromLib() {
+      /* eslint-disable */
       //TODO enable eslint, which is disabled now due to unknown result type of load() from js-yaml
 
-      let rows = []
+      let rows = [];
       // lib has an irregular structure
-      const response = await fetch(process.env.publicPath+'refractiveindex.info-database/database/library.yml')
-      const data = await response.text()
+      const response = await fetch(
+        process.env.publicPath +
+          'refractiveindex.info-database/database/library.yml'
+      );
+      const data = await response.text();
 
-      const response2 = await fetch(process.env.publicPath+'tabulated.txt')
-      const tabulated = await response2.text()
+      const response2 = await fetch(process.env.publicPath + 'tabulated.txt');
+      const tabulated = await response2.text();
 
-      const lib = await load(data) as any
-      let i = 1
+      const lib = (await load(data)) as any;
+      let i = 1;
       for (const shelf of lib) {
-        let shelfDivider = ''
-        let bookName = ''
+        let shelfDivider = '';
+        let bookName = '';
         for (const bookOrDivider of shelf.content) {
           if (bookOrDivider.DIVIDER) {
-
-            shelfDivider = bookOrDivider.DIVIDER
-            continue
-
+            shelfDivider = bookOrDivider.DIVIDER;
+            continue;
           } else if (bookOrDivider.name) {
-
-            bookName = splitBookName(bookOrDivider.name)
-            let bookDivider = ''
-            let pageName = ''
-            let pageData = ''
+            bookName = splitBookName(bookOrDivider.name);
+            let bookDivider = '';
+            let pageName = '';
+            let pageData = '';
             for (const pageOrDivider of bookOrDivider.content) {
               if (pageOrDivider.DIVIDER) {
-
-                bookDivider = pageOrDivider.DIVIDER.replace('Experimental data:','').replace('Experimental data','')
-                continue
-
+                bookDivider = pageOrDivider.DIVIDER.replace(
+                  'Experimental data:',
+                  ''
+                ).replace('Experimental data', '');
+                continue;
               } else if (pageOrDivider.name) {
-
-                pageName = pageOrDivider.name
-                pageData = pageOrDivider.data
-                if (tabulated.indexOf(pageData) == -1) continue
-                if (bookDivider.includes('Model') || bookDivider.includes('model')
-                    || pageName.includes('Model') || pageName.includes('model')) continue
-                const pageNameSplit = GetRange(pageName)
-                rows.push({ id: i, shelfDivider: shelfDivider, bookName: bookName, bookDivider: bookDivider,
-                  pageName: pageNameSplit[0], spectrumRangeStart: pageNameSplit[1],
-                  spectrumRangeEnd: pageNameSplit[2], pageData: pageData })
-                i = i + 1
-
+                pageName = pageOrDivider.name;
+                pageData = pageOrDivider.data;
+                if (tabulated.indexOf(pageData) == -1) continue;
+                if (
+                  bookDivider.includes('Model') ||
+                  bookDivider.includes('model') ||
+                  pageName.includes('Model') ||
+                  pageName.includes('model')
+                )
+                  continue;
+                const pageNameSplit = GetRange(pageName);
+                rows.push({
+                  id: i,
+                  shelfDivider: shelfDivider,
+                  bookName: bookName,
+                  bookDivider: bookDivider,
+                  pageName: pageNameSplit[0],
+                  spectrumRangeStart: pageNameSplit[1],
+                  spectrumRangeEnd: pageNameSplit[2],
+                  pageData: pageData,
+                });
+                i = i + 1;
               } else {
-                console.log('###################### Unknown type in pageOrDivider', pageOrDivider)
+                console.log(
+                  '###################### Unknown type in pageOrDivider',
+                  pageOrDivider
+                );
               }
             }
-
           } else {
-            console.log('###################### Unknown type in bookOrDivider', bookOrDivider)
+            console.log(
+              '###################### Unknown type in bookOrDivider',
+              bookOrDivider
+            );
           }
         }
       }
-      return rows
+      return rows;
     }
 
-
-    let rowsProto:{
-      shelfDivider: string, bookName: string,
-      bookDivider: string, pageName: string, pageData: string
-    }[] = []
-    const rows= reactive(rowsProto)
-    GetPagesFromLib().then(val => {
+    let rowsProto: {
+      shelfDivider: string;
+      bookName: string;
+      bookDivider: string;
+      pageName: string;
+      pageData: string;
+    }[] = [];
+    const rows = reactive(rowsProto);
+    GetPagesFromLib().then((val) => {
       rows.push(...val);
-      loading.value = false
-    })
+      loading.value = false;
+    });
 
-    const activatedMaterials = computed(() => $store.state.guiRuntime.activatedMaterials)
+    const activatedMaterials = computed(
+      () => $store.state.guiRuntime.activatedMaterials
+    );
     // const columnsQ = computed(()=>{
     //   return [
     //     { name: 'name', label: '',  align: 'left', field: 'name', headerStyle:''},
@@ -229,26 +285,34 @@ export default defineComponent({
     //   ]
     // })
 
+    const filter = ref('');
 
-    const filter = ref('')
-
-    return {columns, rows, loading, filter,
-      fromWavelengthStore, toWavelengthStore,
+    return {
+      columns,
+      rows,
+      loading,
+      filter,
+      fromWavelengthStore,
+      toWavelengthStore,
       composeLabelFromPageData,
-      addToSimulation(val:number) {
-        $store.dispatch('guiRuntime/activateMaterial', rows[val-1].pageData)
+      addToSimulation(val: number) {
+        $store.dispatch('guiRuntime/activateMaterial', rows[val - 1].pageData);
       },
-      async downloadPageData(filepath:string) {
-        const response = await fetch(process.env.publicPath+'refractiveindex.info-database/database/data/'+filepath)
-        const data = await response.text()
-
-        const scattnlaySpectra = new Blob([data],
-            {type: 'text/plain;charset=utf-8',
-              endings: 'native'}  //TODO test if newline is correctly written in Windows, MacOS
-        )
+      async downloadPageData(filepath: string) {
+        const response = await fetch(
+          process.env.publicPath +
+            'refractiveindex.info-database/database/data/' +
+            filepath
+        );
+        const data = await response.text();
+
+        const scattnlaySpectra = new Blob(
+          [data],
+          { type: 'text/plain;charset=utf-8', endings: 'native' } //TODO test if newline is correctly written in Windows, MacOS
+        );
         saveAs(scattnlaySpectra, composeLabelFromPageData(filepath));
-      }
-    }
+      },
+    };
   },
-})
+});
 </script>

+ 169 - 133
guiapp/src/components/materials/PlotMaterials.vue

@@ -1,240 +1,276 @@
 <template>
   <div>
     <div class="row items-baseline">
-      <div class="col-xs-12 col-sm-auto text-weight-bold text-center q-px-md q-py-sm">
-        <div :style="flexRowTitleStyle">
-          Plot options
-        </div>
+      <div
+        class="col-xs-12 col-sm-auto text-weight-bold text-center q-px-md q-py-sm"
+      >
+        <div :style="flexRowTitleStyle">Plot options</div>
       </div>
       <div class="col-xs-grow col-sm">
         <div class="row justify-xs-center justify-sm-start items-center">
-          <div class="col-auto" >select data: </div>
-          <div class="col-auto" ><q-toggle v-model="isPlotReN">Re(n)</q-toggle></div>
-          <div class="col-auto" ><q-toggle v-model="isPlotImN">Im(n)</q-toggle></div>
-          <div class="col-auto" ><q-toggle v-model="isPlotInterpolation">Interpolation</q-toggle></div>
-
+          <div class="col-auto">select data:</div>
+          <div class="col-auto">
+            <q-toggle v-model="isPlotReN">Re(n)</q-toggle>
+          </div>
+          <div class="col-auto">
+            <q-toggle v-model="isPlotImN">Im(n)</q-toggle>
+          </div>
+          <div class="col-auto">
+            <q-toggle v-model="isPlotInterpolation">Interpolation</q-toggle>
+          </div>
         </div>
       </div>
     </div>
 
     <div class="row items-baseline">
-      <div class="col-xs-12 col-sm-auto text-weight-bold text-center q-px-md q-py-sm">
-        <div :style="flexRowTitleStyle">
-
-        </div>
+      <div
+        class="col-xs-12 col-sm-auto text-weight-bold text-center q-px-md q-py-sm"
+      >
+        <div :style="flexRowTitleStyle"></div>
       </div>
       <div class="col-xs-grow col-sm">
         <div class="row justify-xs-center justify-sm-start items-baseline">
-          <div class="col-auto q-pr-md" >interpolation range from: </div>
+          <div class="col-auto q-pr-md">interpolation range from:</div>
           <div class="col-auto">
             <div class="q-gutter-x-md">
-              <q-radio v-model="plotRange" dense size='sm' val="material data" label="material data" />
-              <q-radio v-model="plotRange" dense size='sm' val="simulation settings" label="simulation settings" />
+              <q-radio
+                v-model="plotRange"
+                dense
+                size="sm"
+                val="material data"
+                label="material data"
+              />
+              <q-radio
+                v-model="plotRange"
+                dense
+                size="sm"
+                val="simulation settings"
+                label="simulation settings"
+              />
             </div>
           </div>
         </div>
       </div>
     </div>
 
-    <ReactiveChart :chart="materialPlots"/>
+    <ReactiveChart :chart="materialPlots" />
   </div>
 </template>
 
 <script lang="ts">
-import ReactiveChart from 'components/ReactiveChart.vue'
-import { useStore } from 'src/store'
+import ReactiveChart from 'components/ReactiveChart.vue';
+import { useStore } from 'src/store';
 import {
   defineComponent,
   onActivated,
   ref,
-    reactive,
+  reactive,
   computed,
-  watch
-} from 'vue'
-import { flexRowTitleStyle } from 'components/config'
-import { plotlyChart } from 'src/store/plot-runtime/state'
-import { material } from 'src/store/simulation-setup/state'
-import { Data, DataTitle } from 'plotly.js-dist-min'
-import { toUnits } from 'components/utils'
-
+  watch,
+} from 'vue';
+import { flexRowTitleStyle } from 'components/config';
+import { plotlyChart } from 'src/store/plot-runtime/state';
+import { material } from 'src/store/simulation-setup/state';
+import { Data, DataTitle } from 'plotly.js-dist-min';
+import { toUnits } from 'components/utils';
 
 export default defineComponent({
   name: 'PlotMaterials',
   components: {
     ReactiveChart,
   },
-  setup () {
-    const $store = useStore()
-    const materialPlotsInit:plotlyChart = {
+  setup() {
+    const $store = useStore();
+    const materialPlotsInit: plotlyChart = {
       data: [],
       layout: {
         margin: {
           l: 0,
           r: 40,
           b: 50,
-          t: 30
+          t: 30,
         },
         xaxis: {
-          title: ''
+          title: '',
         },
         yaxis: {
-          title: 'Refractive index'
+          title: 'Refractive index',
         },
         showlegend: true,
         legend: {
           orientation: 'h',
-          x: -.1,
-          y: 1.05
+          x: -0.1,
+          y: 1.05,
         },
       },
-      config: {responsive: true,
+      config: {
+        responsive: true,
         // showEditInChartStudio: true,
-        displaylogo: false}
-    }
+        displaylogo: false,
+      },
+    };
 
-    const materialPlots = reactive(materialPlotsInit)
+    const materialPlots = reactive(materialPlotsInit);
 
-    const sourceUnits = computed( ()=>$store.state.guiRuntime.sourceUnits)
+    const sourceUnits = computed(() => $store.state.guiRuntime.sourceUnits);
 
-    const xaxisTitle = computed(()=>{
-      let title:string|Partial<DataTitle> = ''
+    const xaxisTitle = computed(() => {
+      let title: string | Partial<DataTitle> = '';
       if ($store.state.plotRuntime.spectrumPlots.layout.xaxis?.title) {
-        title = $store.state.plotRuntime.spectrumPlots.layout.xaxis.title
+        title = $store.state.plotRuntime.spectrumPlots.layout.xaxis.title;
       }
-      return title
-    })
-    if (materialPlots.layout.xaxis) materialPlots.layout.xaxis.title = xaxisTitle.value
-    watch( xaxisTitle, ()=>{
-      if (materialPlots.layout.xaxis) materialPlots.layout.xaxis.title = xaxisTitle.value
-    })
-
-    const plotRange=ref('material data')
-    const isPlotReN = ref(true)
-    const isPlotImN = ref(true)
-    const isPlotInterpolation = ref(true)
-
-    const fromWL = computed(()=>$store.state.simulationSetup.gui.fromWL)
-    const toWL = computed(()=>$store.state.simulationSetup.gui.toWL)
-    const pointsWL = computed(()=>$store.state.simulationSetup.gui.pointsWL)
+      return title;
+    });
+    if (materialPlots.layout.xaxis)
+      materialPlots.layout.xaxis.title = xaxisTitle.value;
+    watch(xaxisTitle, () => {
+      if (materialPlots.layout.xaxis)
+        materialPlots.layout.xaxis.title = xaxisTitle.value;
+    });
+
+    const plotRange = ref('material data');
+    const isPlotReN = ref(true);
+    const isPlotImN = ref(true);
+    const isPlotInterpolation = ref(true);
+
+    const fromWL = computed(() => $store.state.simulationSetup.gui.fromWL);
+    const toWL = computed(() => $store.state.simulationSetup.gui.toWL);
+    const pointsWL = computed(() => $store.state.simulationSetup.gui.pointsWL);
 
     // updateMaterialPlots used to be a Vuex mutation with a single argument. As
     // long as it is in the component feel free as many arguments as needed.
-    function updateMaterialPlots( val:{activatedMaterials:material[], sourceUnits:string,
-        fromWL:number, toWL:number, pointsWL:number, plotRange: string,
-        isPlotReN: boolean, isPlotImN: boolean, isPlotInterpolation: boolean })
-    {
-      materialPlots.data.length = 0
+    function updateMaterialPlots(val: {
+      activatedMaterials: material[];
+      sourceUnits: string;
+      fromWL: number;
+      toWL: number;
+      pointsWL: number;
+      plotRange: string;
+      isPlotReN: boolean;
+      isPlotImN: boolean;
+      isPlotInterpolation: boolean;
+    }) {
+      materialPlots.data.length = 0;
       for (const material of val.activatedMaterials) {
-        if (!material.isPlot) continue
+        if (!material.isPlot) continue;
 
-        if (!material.nSpline) continue
+        if (!material.nSpline) continue;
         if (val.isPlotReN) {
           const traceDataReN: Partial<Data> = {
-            x: material.nSpline.xs.map(x => toUnits(x, val.sourceUnits)),
+            x: material.nSpline.xs.map((x) => toUnits(x, val.sourceUnits)),
             y: material.nSpline.ys,
             mode: 'markers',
-            marker:{size:5},
+            marker: { size: 5 },
             type: 'scatter',
-            name: 'Re(n) ' + material.name + ' data'
-          }
-          materialPlots.data.push(traceDataReN)
+            name: 'Re(n) ' + material.name + ' data',
+          };
+          materialPlots.data.push(traceDataReN);
         }
 
-        if (!material.kSpline) continue
+        if (!material.kSpline) continue;
         if (val.isPlotImN) {
           const traceDataImN: Partial<Data> = {
-            x: material.kSpline.xs.map(x => toUnits(x, val.sourceUnits)),
+            x: material.kSpline.xs.map((x) => toUnits(x, val.sourceUnits)),
             y: material.kSpline.ys,
             mode: 'markers',
-            marker:{size:5},
+            marker: { size: 5 },
             type: 'scatter',
-            name: 'Im(n) ' + material.name + ' data'
-          }
-          materialPlots.data.push(traceDataImN)
+            name: 'Im(n) ' + material.name + ' data',
+          };
+          materialPlots.data.push(traceDataImN);
         }
 
         if (val.isPlotInterpolation) {
-          let fromWL = val.fromWL
-          let toWL = val.toWL
-          let pointsWL = val.pointsWL-1
-          if (materialPlots.layout.xaxis) materialPlots.layout.xaxis.range = [fromWL, toWL]
+          let fromWL = val.fromWL;
+          let toWL = val.toWL;
+          let pointsWL = val.pointsWL - 1;
+          if (materialPlots.layout.xaxis)
+            materialPlots.layout.xaxis.range = [fromWL, toWL];
           if (val.plotRange == 'material data') {
-            fromWL = material.nSpline.xs[0]
-            toWL = material.nSpline.xs[material.nSpline.xs.length-1]
-            pointsWL = 1000
-            if (materialPlots.layout.xaxis) materialPlots.layout.xaxis.range = undefined
+            fromWL = material.nSpline.xs[0];
+            toWL = material.nSpline.xs[material.nSpline.xs.length - 1];
+            pointsWL = 1000;
+            if (materialPlots.layout.xaxis)
+              materialPlots.layout.xaxis.range = undefined;
           }
-          const stepWL = (toWL-fromWL)/pointsWL
-
-          const WLs:number[] =[]
-          const nSpline:number[] = []
-          const kSpline:number[] = []
-          for (let i=0; i<pointsWL; ++i) {
-            WLs.push(fromWL+i*stepWL)
-            nSpline.push(material.nSpline.at(fromWL+i*stepWL))
-            kSpline.push(material.kSpline.at(fromWL+i*stepWL))
+          const stepWL = (toWL - fromWL) / pointsWL;
+
+          const WLs: number[] = [];
+          const nSpline: number[] = [];
+          const kSpline: number[] = [];
+          for (let i = 0; i < pointsWL; ++i) {
+            WLs.push(fromWL + i * stepWL);
+            nSpline.push(material.nSpline.at(fromWL + i * stepWL));
+            kSpline.push(material.kSpline.at(fromWL + i * stepWL));
           }
-          WLs.push(toWL)
-          nSpline.push(material.nSpline.at(toWL))
-          kSpline.push(material.kSpline.at(toWL))
+          WLs.push(toWL);
+          nSpline.push(material.nSpline.at(toWL));
+          kSpline.push(material.kSpline.at(toWL));
 
           if (val.isPlotReN) {
-            if (!material.nSpline) continue
+            if (!material.nSpline) continue;
             const traceDataReNi: Partial<Data> = {
-              x: WLs.map(x => toUnits(x, val.sourceUnits)),
+              x: WLs.map((x) => toUnits(x, val.sourceUnits)),
               y: nSpline,
               type: 'scatter',
-              name: 'Re(n) ' + material.name + ' interpolate'
-            }
-            materialPlots.data.push(traceDataReNi)
+              name: 'Re(n) ' + material.name + ' interpolate',
+            };
+            materialPlots.data.push(traceDataReNi);
           }
 
           if (val.isPlotImN) {
-            if (!material.nSpline) continue
+            if (!material.nSpline) continue;
             const traceDataImNi: Partial<Data> = {
-              x: WLs.map(x => toUnits(x, val.sourceUnits)),
+              x: WLs.map((x) => toUnits(x, val.sourceUnits)),
               y: kSpline,
               type: 'scatter',
-              name: 'Im(n) ' + material.name + ' interpolate'
-            }
-            materialPlots.data.push(traceDataImNi)
+              name: 'Im(n) ' + material.name + ' interpolate',
+            };
+            materialPlots.data.push(traceDataImNi);
           }
-
         }
       }
     }
 
     function updateSpectraPlot() {
-      updateMaterialPlots(
-          {
-            activatedMaterials: $store.state.guiRuntime.activatedMaterials,
-            sourceUnits: sourceUnits.value,
-            fromWL: fromWL.value,
-            toWL: toWL.value,
-            pointsWL: pointsWL.value,
-            plotRange: plotRange.value,
-            isPlotReN: isPlotReN.value,
-            isPlotImN: isPlotImN.value,
-            isPlotInterpolation: isPlotInterpolation.value
-          })
+      updateMaterialPlots({
+        activatedMaterials: $store.state.guiRuntime.activatedMaterials,
+        sourceUnits: sourceUnits.value,
+        fromWL: fromWL.value,
+        toWL: toWL.value,
+        pointsWL: pointsWL.value,
+        plotRange: plotRange.value,
+        isPlotReN: isPlotReN.value,
+        isPlotImN: isPlotImN.value,
+        isPlotInterpolation: isPlotInterpolation.value,
+      });
     }
 
-    updateSpectraPlot()
+    updateSpectraPlot();
 
-    const materialsToPlot=computed(()=>$store.state.guiRuntime.activatedMaterials
-        .filter((val)=>val.isPlot)
-        .map(val=>val.name))
+    const materialsToPlot = computed(() =>
+      $store.state.guiRuntime.activatedMaterials
+        .filter((val) => val.isPlot)
+        .map((val) => val.name)
+    );
 
-    watch ([materialsToPlot, plotRange, isPlotReN, isPlotImN, isPlotInterpolation], ()=>{
-      updateSpectraPlot()
-    })
+    watch(
+      [materialsToPlot, plotRange, isPlotReN, isPlotImN, isPlotInterpolation],
+      () => {
+        updateSpectraPlot();
+      }
+    );
 
-    onActivated(()=>updateSpectraPlot())
+    onActivated(() => updateSpectraPlot());
 
-    return { flexRowTitleStyle,
+    return {
+      flexRowTitleStyle,
       materialPlots,
-    isPlotReN, isPlotImN, isPlotInterpolation,
-    plotRange}
-  }
-})
+      isPlotReN,
+      isPlotImN,
+      isPlotInterpolation,
+      plotRange,
+    };
+  },
+});
 </script>

+ 49 - 46
guiapp/src/components/nearfield/GetNearFieldColorScale.vue

@@ -7,87 +7,90 @@
     </div>
     <div class="col-xs-grow col-sm">
       <div class="row justify-xs-center justify-sm-start items-center">
-
-        <div class="col-auto"><input-with-units
+        <div class="col-auto">
+          <input-with-units
             v-model:input-result="limitFrom"
             v-model:is-showing-help="isShowingHelpForInputWithUnits"
             :initial-expression="limitFrom.toString()"
             title="from"
             units=""
-        /></div>
-        <div class="col-auto"><input-with-units
+          />
+        </div>
+        <div class="col-auto">
+          <input-with-units
             v-model:input-result="limitTo"
             v-model:is-showing-help="isShowingHelpForInputWithUnits"
             :initial-expression="limitTo.toString()"
             title="to"
             units=""
-        /></div>
-        <div class="col-auto q-pa-xs"><q-btn
+          />
+        </div>
+        <div class="col-auto q-pa-xs">
+          <q-btn
             no-caps
             flat
             icon="restart_alt"
             color="primary"
             label="reset"
             @click="resetLimits()"
-        /></div>
-     </div>
+          />
+        </div>
+      </div>
     </div>
   </div>
-
 </template>
 
 <script lang="ts">
-import {
-  defineComponent,
-  watch,
-  computed,
-  } from 'vue'
-import { useStore } from 'src/store'
-import InputWithUnits from 'components/InputWithUnits.vue'
-import { flexRowTitleStyle } from 'components/config'
+import { defineComponent, watch, computed } from 'vue';
+import { useStore } from 'src/store';
+import InputWithUnits from 'components/InputWithUnits.vue';
+import { flexRowTitleStyle } from 'components/config';
 
 export default defineComponent({
-
   name: 'GetNearFieldColorScale',
-  components: {InputWithUnits,},
+  components: { InputWithUnits },
 
   setup() {
-    const $store = useStore()
+    const $store = useStore();
 
     const isShowingHelpForInputWithUnits = computed({
       get: () => $store.state.guiRuntime.isShowingHelpForInputWithUnits,
-      set: val => $store.commit('guiRuntime/setIsShowingHelpForInputWithUnits', val)
-    })
+      set: (val) =>
+        $store.commit('guiRuntime/setIsShowingHelpForInputWithUnits', val),
+    });
 
-    const dataFrom = computed(()=>$store.state.plotRuntime.nearFieldDataFrom)
-    const dataTo = computed(()=>$store.state.plotRuntime.nearFieldDataTo)
+    const dataFrom = computed(() => $store.state.plotRuntime.nearFieldDataFrom);
+    const dataTo = computed(() => $store.state.plotRuntime.nearFieldDataTo);
     const limitFrom = computed({
-      get: ()=>$store.state.plotRuntime.nearFieldLimitFrom,
-      set: val => $store.commit('plotRuntime/setNearFieldLimitFrom',val)
-    })
+      get: () => $store.state.plotRuntime.nearFieldLimitFrom,
+      set: (val) => $store.commit('plotRuntime/setNearFieldLimitFrom', val),
+    });
     const limitTo = computed({
-      get: ()=>$store.state.plotRuntime.nearFieldLimitTo,
-      set: val => $store.commit('plotRuntime/setNearFieldLimitTo',val)
-    })
+      get: () => $store.state.plotRuntime.nearFieldLimitTo,
+      set: (val) => $store.commit('plotRuntime/setNearFieldLimitTo', val),
+    });
 
-    limitFrom.value = dataFrom.value
-    limitTo.value = dataTo.value
+    limitFrom.value = dataFrom.value;
+    limitTo.value = dataTo.value;
 
-    watch(dataFrom, ()=>{
-      if(dataFrom.value > limitFrom.value) limitFrom.value = dataFrom.value
-    })
-    watch(dataTo, ()=>{
-      if(dataTo.value < limitTo.value) limitTo.value = dataTo.value
-    })
+    watch(dataFrom, () => {
+      if (dataFrom.value > limitFrom.value) limitFrom.value = dataFrom.value;
+    });
 
-    return { isShowingHelpForInputWithUnits, flexRowTitleStyle,
-      limitFrom, limitTo,
-      resetLimits(){
-        limitTo.value = dataTo.value
-        limitFrom.value = dataFrom.value
-      }
+    watch(dataTo, () => {
+      if (dataTo.value < limitTo.value) limitTo.value = dataTo.value;
+    });
 
-       }
+    return {
+      isShowingHelpForInputWithUnits,
+      flexRowTitleStyle,
+      limitFrom,
+      limitTo,
+      resetLimits() {
+        limitTo.value = dataTo.value;
+        limitFrom.value = dataFrom.value;
+      },
+    };
   },
-})
+});
 </script>

+ 64 - 55
guiapp/src/components/nearfield/GetNearFieldRefinedSettings.vue

@@ -1,74 +1,70 @@
 <template>
   <div class="row items-baseline">
-    <div class="col-xs-12 col-sm-auto text-weight-bold text-center q-pr-md q-py-sm">
-      <div :style="flexRowTitleStyle">
-        Plot
-      </div>
+    <div
+      class="col-xs-12 col-sm-auto text-weight-bold text-center q-pr-md q-py-sm"
+    >
+      <div :style="flexRowTitleStyle">Plot</div>
     </div>
     <div class="col-xs-grow col-sm">
       <div class="row justify-center items-baseline">
         <div class="col-auto text-center q-py-xs q-pr-md">
-          <div :style="flexRowTitleStyle">
-            y-side resolution
-          </div>
+          <div :style="flexRowTitleStyle">y-side resolution</div>
         </div>
         <div class="col-xs-grow col-sm">
           <div class="row justify-xs-center justify-sm-start items-center">
             <input-with-units
-                v-model:input-result="plotYSideResolution"
-                v-model:is-showing-help="isShowingHelpForInputWithUnits"
-                :initial-expression="plotYSideResolution.toString()"
-                title="points"
-                units=""
-            /></div>
+              v-model:input-result="plotYSideResolution"
+              v-model:is-showing-help="isShowingHelpForInputWithUnits"
+              :initial-expression="plotYSideResolution.toString()"
+              title="points"
+              units=""
+            />
+          </div>
         </div>
       </div>
       <div class="row justify-center items-baseline">
         <div class="col-auto text-center q-py-xs q-pr-md">
-          <div :style="flexRowTitleStyle" >
-        relative center
-          </div>
+          <div :style="flexRowTitleStyle">relative center</div>
         </div>
         <div class="col-xs-grow col-sm">
           <div class="row justify-xs-center justify-sm-start items-center">
             <div class="col-auto">
-              <q-tooltip anchor="center start" self="center end" >
-                E-field vector direction
-              </q-tooltip><input-with-units
-                  v-model:input-result="atRelativeX0"
-                  v-model:is-showing-help="isShowingHelpForInputWithUnits"
-                  :initial-expression="atRelativeX0.toString()"
-                  title="𝑋𝑜&thinsp;/&hairsp;𝑅"
-                  units=""
+              <q-tooltip anchor="center start" self="center end">
+                E-field vector direction </q-tooltip
+              ><input-with-units
+                v-model:input-result="atRelativeX0"
+                v-model:is-showing-help="isShowingHelpForInputWithUnits"
+                :initial-expression="atRelativeX0.toString()"
+                title="𝑋𝑜&thinsp;/&hairsp;𝑅"
+                units=""
               />
             </div>
             <div class="col-auto">
-              <q-tooltip anchor="center start" self="center end" >
-                H-field vector direction
-              </q-tooltip><input-with-units
+              <q-tooltip anchor="center start" self="center end">
+                H-field vector direction </q-tooltip
+              ><input-with-units
                 v-model:input-result="atRelativeY0"
                 v-model:is-showing-help="isShowingHelpForInputWithUnits"
                 :initial-expression="atRelativeY0.toString()"
                 title="𝑌𝑜&thinsp;/&hairsp;𝑅"
                 units=""
-            />
+              />
             </div>
             <div class="col-auto">
-              <q-tooltip anchor="center start" self="center end" >
-                k-vector direction
-              </q-tooltip><input-with-units
+              <q-tooltip anchor="center start" self="center end">
+                k-vector direction </q-tooltip
+              ><input-with-units
                 v-model:input-result="atRelativeZ0"
                 v-model:is-showing-help="isShowingHelpForInputWithUnits"
                 :initial-expression="atRelativeZ0.toString()"
                 title="𝑍𝑜&thinsp;/&hairsp;𝑅"
                 units=""
-            />
+              />
             </div>
           </div>
         </div>
       </div>
-      <div class="q-ma-xs"/>
-
+      <div class="q-ma-xs" />
     </div>
   </div>
 </template>
@@ -78,45 +74,58 @@ import {
   defineComponent,
   computed,
   // watch
-  } from 'vue'
-import { useStore } from 'src/store'
-import InputWithUnits from 'components/InputWithUnits.vue'
-import { flexRowTitleStyle } from 'components/config'
+} from 'vue';
+import { useStore } from 'src/store';
+import InputWithUnits from 'components/InputWithUnits.vue';
+import { flexRowTitleStyle } from 'components/config';
 
 export default defineComponent({
-
   name: 'GetNearFieldRefinedSettings',
-  components: {InputWithUnits,},
+  components: { InputWithUnits },
 
   setup() {
-    const $store = useStore()
+    const $store = useStore();
 
     const isShowingHelpForInputWithUnits = computed({
       get: () => $store.state.guiRuntime.isShowingHelpForInputWithUnits,
-      set: val => $store.commit('guiRuntime/setIsShowingHelpForInputWithUnits', val)
-    })
+      set: (val) =>
+        $store.commit('guiRuntime/setIsShowingHelpForInputWithUnits', val),
+    });
 
     const atRelativeX0 = computed({
       get: () => $store.state.simulationSetup.gui.nearFieldSetup.atRelativeX0,
-      set: val => $store.commit('simulationSetup/setNearFieldAtRelativeX0', val)
-    })
+      set: (val) =>
+        $store.commit('simulationSetup/setNearFieldAtRelativeX0', val),
+    });
     const atRelativeY0 = computed({
       get: () => $store.state.simulationSetup.gui.nearFieldSetup.atRelativeY0,
-      set: val => $store.commit('simulationSetup/setNearFieldAtRelativeY0', val)
-    })
+      set: (val) =>
+        $store.commit('simulationSetup/setNearFieldAtRelativeY0', val),
+    });
     const atRelativeZ0 = computed({
       get: () => $store.state.simulationSetup.gui.nearFieldSetup.atRelativeZ0,
-      set: val => $store.commit('simulationSetup/setNearFieldAtRelativeZ0', val)
-    })
+      set: (val) =>
+        $store.commit('simulationSetup/setNearFieldAtRelativeZ0', val),
+    });
 
     const plotYSideResolution = computed({
-      get: () => $store.state.simulationSetup.gui.nearFieldSetup.plotYSideResolution,
-      set: val => $store.commit('simulationSetup/setNearFieldPlotYSideResolution', Math.floor(val))
-    })
+      get: () =>
+        $store.state.simulationSetup.gui.nearFieldSetup.plotYSideResolution,
+      set: (val) =>
+        $store.commit(
+          'simulationSetup/setNearFieldPlotYSideResolution',
+          Math.floor(val)
+        ),
+    });
 
-    return {isShowingHelpForInputWithUnits, flexRowTitleStyle,
+    return {
+      isShowingHelpForInputWithUnits,
+      flexRowTitleStyle,
       plotYSideResolution,
-      atRelativeX0, atRelativeY0, atRelativeZ0}
+      atRelativeX0,
+      atRelativeY0,
+      atRelativeZ0,
+    };
   },
-})
+});
 </script>

+ 83 - 57
guiapp/src/components/nearfield/GetNearFieldSettings.vue

@@ -1,100 +1,112 @@
 <template>
   <div class="row items-baseline">
-    <div class="col-xs-12 col-sm-auto text-weight-bold text-center q-pr-md q-py-sm">
-      <div :style="flexRowTitleStyle">
-        Plot
-      </div>
+    <div
+      class="col-xs-12 col-sm-auto text-weight-bold text-center q-pr-md q-py-sm"
+    >
+      <div :style="flexRowTitleStyle">Plot</div>
     </div>
     <div class="col-xs-grow col-sm">
       <div class="row justify-center items-baseline">
         <div class="col-auto text-center q-py-xs q-pr-md">
-          <div :style="flexRowTitleStyle" >
-            side resolution
-          </div>
+          <div :style="flexRowTitleStyle">side resolution</div>
         </div>
         <div class="col-xs-grow col-sm">
           <div class="row justify-xs-center justify-sm-start items-center">
             <input-with-units
-                v-model:input-result="plotXSideResolution"
-                v-model:is-showing-help="isShowingHelpForInputWithUnits"
-                :initial-expression="plotXSideResolution.toString()"
-                title="points"
-                units=""
-            /></div>
+              v-model:input-result="plotXSideResolution"
+              v-model:is-showing-help="isShowingHelpForInputWithUnits"
+              :initial-expression="plotXSideResolution.toString()"
+              title="points"
+              units=""
+            />
+          </div>
         </div>
       </div>
       <div class="row justify-center items-baseline">
         <div class="col-auto text-center q-py-xs q-pr-md">
-          <div :style="flexRowTitleStyle" >
-        relative side length
-          </div>
+          <div :style="flexRowTitleStyle">relative side length</div>
         </div>
         <div class="col-xs-grow col-sm">
           <div class="row justify-xs-center justify-sm-start items-center">
             <input-with-units
-            v-model:input-result="relativePlotSize"
-            v-model:is-showing-help="isShowingHelpForInputWithUnits"
-            :initial-expression="relativePlotSize.toString()"
-            title="𝐿&thinsp;/&hairsp;𝟐𝑅"
-            units=""
-            /></div>
+              v-model:input-result="relativePlotSize"
+              v-model:is-showing-help="isShowingHelpForInputWithUnits"
+              :initial-expression="relativePlotSize.toString()"
+              title="𝐿&thinsp;/&hairsp;𝟐𝑅"
+              units=""
+            />
+          </div>
         </div>
       </div>
-      <div class="q-ma-xs"/>
+      <div class="q-ma-xs" />
       <div class="row justify-center items-center">
         <div class="col-auto text-center q-py-xs q-pr-md">
-          <div :style="flexRowTitleStyle" >
-            cross-section
-          </div>
+          <div :style="flexRowTitleStyle">cross-section</div>
         </div>
         <div class="col-xs-grow col-sm">
           <div class="row justify-xs-center justify-sm-start items-center">
             <div class="q-gutter-md q-py-sm q-px-xs">
-              <q-radio v-model="crossSection" dense size='sm' :val="nearFieldPlane.Ek" label="Ek" />
-              <q-radio v-model="crossSection" dense size='sm' :val="nearFieldPlane.Hk" label="Hk" />
-              <q-radio v-model="crossSection" dense size='sm' :val="nearFieldPlane.EH" label="EH" />
+              <q-radio
+                v-model="crossSection"
+                dense
+                size="sm"
+                :val="nearFieldPlane.Ek"
+                label="Ek"
+              />
+              <q-radio
+                v-model="crossSection"
+                dense
+                size="sm"
+                :val="nearFieldPlane.Hk"
+                label="Hk"
+              />
+              <q-radio
+                v-model="crossSection"
+                dense
+                size="sm"
+                :val="nearFieldPlane.EH"
+                label="EH"
+              />
             </div>
           </div>
         </div>
       </div>
-
     </div>
   </div>
 </template>
 
 <script lang="ts">
-import {
-  defineComponent,
-  computed,
-  watch
-  } from 'vue'
-import { useStore } from 'src/store'
-import InputWithUnits from 'components/InputWithUnits.vue'
-import { flexRowTitleStyle } from 'components/config'
+import { defineComponent, computed, watch } from 'vue';
+import { useStore } from 'src/store';
+import InputWithUnits from 'components/InputWithUnits.vue';
+import { flexRowTitleStyle } from 'components/config';
 import { nearFieldPlane } from 'src/store/simulation-setup/state';
 
 export default defineComponent({
-
   name: 'GetNearFieldSettings',
-  components: {InputWithUnits,},
+  components: { InputWithUnits },
 
   setup() {
-    const $store = useStore()
+    const $store = useStore();
 
     const isShowingHelpForInputWithUnits = computed({
       get: () => $store.state.guiRuntime.isShowingHelpForInputWithUnits,
-      set: val => $store.commit('guiRuntime/setIsShowingHelpForInputWithUnits', val)
-    })
+      set: (val) =>
+        $store.commit('guiRuntime/setIsShowingHelpForInputWithUnits', val),
+    });
 
     const crossSection = computed({
       get: () => $store.state.simulationSetup.gui.nearFieldSetup.crossSection,
-      set: val => $store.commit('simulationSetup/setNearFieldCrossSection', val)
-    })
+      set: (val) =>
+        $store.commit('simulationSetup/setNearFieldCrossSection', val),
+    });
 
     const relativePlotSize = computed({
-      get: () => $store.state.simulationSetup.gui.nearFieldSetup.relativePlotSize,
-      set: val => $store.commit('simulationSetup/setNearFieldRelativePlotSize', val)
-    })
+      get: () =>
+        $store.state.simulationSetup.gui.nearFieldSetup.relativePlotSize,
+      set: (val) =>
+        $store.commit('simulationSetup/setNearFieldRelativePlotSize', val),
+    });
 
     // const maxComputeTime = computed({
     //   get: () => $store.state.simulationSetup.gui.nearFieldSetup.maxComputeTime,
@@ -102,18 +114,32 @@ export default defineComponent({
     // })
 
     const plotXSideResolution = computed({
-      get: () => $store.state.simulationSetup.gui.nearFieldSetup.plotXSideResolution,
+      get: () =>
+        $store.state.simulationSetup.gui.nearFieldSetup.plotXSideResolution,
       // TODO: make InputWithUnits to handle integer input, so no need to use floor() in the next line.
-      set: val => $store.commit('simulationSetup/setNearFieldPlotXSideResolution', Math.floor(val))
-    })
+      set: (val) =>
+        $store.commit(
+          'simulationSetup/setNearFieldPlotXSideResolution',
+          Math.floor(val)
+        ),
+    });
+
+    watch(plotXSideResolution, () => {
+      $store.commit(
+        'simulationSetup/setNearFieldPlotYSideResolution',
+        plotXSideResolution.value
+      );
+    });
 
-    watch(plotXSideResolution, ()=>{
-      $store.commit('simulationSetup/setNearFieldPlotYSideResolution', plotXSideResolution.value)
-    })
-    return { crossSection, isShowingHelpForInputWithUnits, flexRowTitleStyle,
+    return {
+      crossSection,
+      isShowingHelpForInputWithUnits,
+      flexRowTitleStyle,
       relativePlotSize,
       // maxComputeTime,
-      plotXSideResolution, nearFieldPlane}
+      plotXSideResolution,
+      nearFieldPlane,
+    };
   },
-})
+});
 </script>

+ 80 - 66
guiapp/src/components/nearfield/GetWlFromPlot.vue

@@ -1,101 +1,115 @@
 <template>
   <div>
     <div class="row items-baseline">
-
-      <div class="col-xs-12 col-sm-auto text-weight-bold text-center q-pr-md q-py-sm">
-        <div :style="flexRowTitleStyle"> Source plane wave </div>
+      <div
+        class="col-xs-12 col-sm-auto text-weight-bold text-center q-pr-md q-py-sm"
+      >
+        <div :style="flexRowTitleStyle">Source plane wave</div>
       </div>
       <div class="col-xs-grow col-sm">
         <div class="row justify-xs-center justify-sm-start items-baseline">
-
-          <div class="col-auto"><input-with-units
+          <div class="col-auto">
+            <input-with-units
               v-model:input-result="currentWavelengthInSourceUnits"
               v-model:is-showing-help="isShowingHelpForInputWithUnits"
               :initial-expression="currentWavelengthInSourceUnits.toString()"
               :units="sourceUnits"
               title="at"
-          /></div>
-          <div class="col-auto q-px-sm"> or <span class="text-bold">click on plot</span> below to select a data point</div>
-
+            />
+          </div>
+          <div class="col-auto q-px-sm">
+            or <span class="text-bold">click on plot</span> below to select a
+            data point
+          </div>
         </div>
       </div>
     </div>
-    <div class="q-ma-xs"/>
+    <div class="q-ma-xs" />
     <ReactiveChart
-        :chart="chartContent"
-        :window-height-share="0.4"
-        @plotCreated="mangeID($event)"
+      :chart="chartContent"
+      :window-height-share="0.4"
+      @plotCreated="mangeID($event)"
     />
   </div>
 </template>
 
 <script lang="ts">
-import ReactiveChart from 'components/ReactiveChart.vue'
-import { useStore } from 'src/store'
-import {
-  defineComponent,
-  computed,
-    // onActivated,
-  // watch,
-  //   ref,
-} from 'vue'
-import { fromUnits, toUnits } from 'components/utils'
-import InputWithUnits from 'components/InputWithUnits.vue'
-import { flexRowTitleStyle } from 'components/config'
-import { PlotlyHTMLElement } from 'plotly.js-dist-min'
-import { cloneDeep } from 'lodash'
+import ReactiveChart from 'components/ReactiveChart.vue';
+import { useStore } from 'src/store';
+import { defineComponent, computed } from 'vue';
+import { fromUnits, toUnits } from 'components/utils';
+import InputWithUnits from 'components/InputWithUnits.vue';
+import { flexRowTitleStyle } from 'components/config';
+import { PlotlyHTMLElement } from 'plotly.js-dist-min';
+import { cloneDeep } from 'lodash';
 
 export default defineComponent({
   name: 'GetWlFromPlot',
   components: {
-    ReactiveChart, InputWithUnits
+    ReactiveChart,
+    InputWithUnits,
   },
-  setup () {
-    const $store = useStore()
+  setup() {
+    const $store = useStore();
 
-    const sourceUnits = computed( ()=>$store.state.guiRuntime.sourceUnits)
+    const sourceUnits = computed(() => $store.state.guiRuntime.sourceUnits);
     const isShowingHelpForInputWithUnits = computed({
       get: () => $store.state.guiRuntime.isShowingHelpForInputWithUnits,
-      set: val => $store.commit('guiRuntime/setIsShowingHelpForInputWithUnits', val)
-    })
-
+      set: (val) =>
+        $store.commit('guiRuntime/setIsShowingHelpForInputWithUnits', val),
+    });
 
     const currentWavelengthInSourceUnits = computed({
-      get: () => toUnits($store.state.simulationSetup.gui.nearFieldSetup.atWL, sourceUnits.value),
-      set: val => $store.commit('simulationSetup/setNearFieldWL', fromUnits(sourceUnits.value, val))
-    })
+      get: () =>
+        toUnits(
+          $store.state.simulationSetup.gui.nearFieldSetup.atWL,
+          sourceUnits.value
+        ),
+      set: (val) =>
+        $store.commit(
+          'simulationSetup/setNearFieldWL',
+          fromUnits(sourceUnits.value, val)
+        ),
+    });
 
-    const chartContent = computed( ()=>{
-      let content = cloneDeep($store.state.plotRuntime.spectrumPlots)
-      if (content.layout.yaxis) content.layout.yaxis.title = 'Cross-section'
-      content.layout['shapes'] = [{
-        type: 'line',
-        x0: currentWavelengthInSourceUnits.value,
-        y0: 0,
-        x1: currentWavelengthInSourceUnits.value,
-        yref: 'paper',
-        y1: 1,
-        line: {
-          color: 'red',
-          width: 1.5,
-          dash: 'dot'
+    const chartContent = computed(() => {
+      let content = cloneDeep($store.state.plotRuntime.spectrumPlots);
+      if (content.layout.yaxis) content.layout.yaxis.title = 'Cross-section';
+      content.layout['shapes'] = [
+        {
+          type: 'line',
+          x0: currentWavelengthInSourceUnits.value,
+          y0: 0,
+          x1: currentWavelengthInSourceUnits.value,
+          yref: 'paper',
+          y1: 1,
+          line: {
+            color: 'red',
+            width: 1.5,
+            dash: 'dot',
+          },
+        },
+      ];
+      return content;
+    });
+    function mangeID(chartID: string) {
+      const myPlot = document.getElementById(chartID) as PlotlyHTMLElement;
+      myPlot.on('plotly_click', function (data) {
+        for (let i = 0; i < data.points.length; i++) {
+          let val = data.points[i].x;
+          if (val)
+            currentWavelengthInSourceUnits.value = parseFloat(val.toString());
         }
-      }]
-      return content
-    })
-    function mangeID(chartID:string) {
-      const myPlot = document.getElementById(chartID) as PlotlyHTMLElement
-      myPlot.on('plotly_click', function(data){
-        for(let i=0; i < data.points.length; i++){
-          let val = data.points[i].x
-          if (val) currentWavelengthInSourceUnits.value = parseFloat(val.toString())
-        }
-      })
+      });
     }
-    return {currentWavelengthInSourceUnits, sourceUnits,
-      chartContent, flexRowTitleStyle, isShowingHelpForInputWithUnits,
+    return {
+      currentWavelengthInSourceUnits,
+      sourceUnits,
+      chartContent,
+      flexRowTitleStyle,
+      isShowingHelpForInputWithUnits,
       mangeID,
-    }
-  }
-})
+    };
+  },
+});
 </script>

+ 135 - 95
guiapp/src/components/nearfield/PlotNearField.vue

@@ -1,39 +1,38 @@
 <template>
   <div>
-    <ReactiveChart :chart="nearFieldPlot"/>
+    <ReactiveChart :chart="nearFieldPlot" />
   </div>
 </template>
 
 <script lang="ts">
-import ReactiveChart from 'components/ReactiveChart.vue'
-import { useStore } from 'src/store'
+import ReactiveChart from 'components/ReactiveChart.vue';
+import { useStore } from 'src/store';
 import {
   defineComponent,
-  // onActivated,
   // ref,
-    reactive,
+  reactive,
   computed,
-  watch
-} from 'vue'
+  watch,
+} from 'vue';
 // import { flexRowTitleStyle } from 'components/config'
-import { toUnits,
+import {
+  toUnits,
   getMaxFromHeatmap,
   getMinFromHeatmap,
-  limitMap
-} from 'components/utils'
-import { plotlyChart } from 'src/store/plot-runtime/state'
-import { PlotData, DataTitle } from 'plotly.js-dist-min'
-import {nearFieldPlane} from 'src/store/simulation-setup/state';
-
+  limitMap,
+} from 'components/utils';
+import { plotlyChart } from 'src/store/plot-runtime/state';
+import { PlotData, DataTitle } from 'plotly.js-dist-min';
+import { nearFieldPlane } from 'src/store/simulation-setup/state';
 
 export default defineComponent({
   name: 'PlotNearField',
   components: {
     ReactiveChart,
   },
-  setup () {
-    const $store = useStore()
-    const nearFieldPlotInit:plotlyChart = {
+  setup() {
+    const $store = useStore();
+    const nearFieldPlotInit: plotlyChart = {
       data: [],
       layout: {
         shapes: [],
@@ -41,91 +40,130 @@ export default defineComponent({
           l: 0,
           r: 40,
           b: 50,
-          t: 30
+          t: 30,
         },
         xaxis: {
-          title: ''
+          title: '',
         },
         yaxis: {
           scaleanchor: 'x',
-          title: ''
+          title: '',
         },
         showlegend: false,
       },
-      config: {responsive: true,
+      config: {
+        responsive: true,
         // showEditInChartStudio: true,
-        displaylogo: false}
-    }
+        displaylogo: false,
+      },
+    };
 
-    const nearFieldPlot = reactive(nearFieldPlotInit)
-    const crossSection = computed(()=>$store.state.simulationSetup.current.nearFieldSetup.crossSection)
-    const relativePlotSize = computed(()=>$store.state.simulationSetup.current.nearFieldSetup.relativePlotSize)
-    const plotYSideResolution = computed(()=>$store.state.simulationSetup.current.nearFieldSetup.plotYSideResolution)
-    const plotXSideResolution = computed(()=>$store.state.simulationSetup.current.nearFieldSetup.plotXSideResolution)
-    const layerWidths = computed(()=>$store.state.simulationSetup.current.layers.map(x=>x.layerWidth))
-    const totalR = computed(()=>layerWidths.value.reduce((a, b) => a + b, 0))
-    const x0 = computed(()=>totalR.value*relativePlotSize.value)
-    const dx = computed(()=>x0.value*2.0/(plotXSideResolution.value-1))
-    const units = computed(()=>$store.state.guiRuntime.units)
-    const at_x = computed(()=>{
-      if (crossSection.value == nearFieldPlane.Ek || crossSection.value == nearFieldPlane.Hk) {
-        return $store.state.simulationSetup.current.nearFieldSetup.atRelativeZ0
+    const nearFieldPlot = reactive(nearFieldPlotInit);
+    const crossSection = computed(
+      () => $store.state.simulationSetup.current.nearFieldSetup.crossSection
+    );
+    const relativePlotSize = computed(
+      () => $store.state.simulationSetup.current.nearFieldSetup.relativePlotSize
+    );
+    const plotYSideResolution = computed(
+      () =>
+        $store.state.simulationSetup.current.nearFieldSetup.plotYSideResolution
+    );
+    const plotXSideResolution = computed(
+      () =>
+        $store.state.simulationSetup.current.nearFieldSetup.plotXSideResolution
+    );
+    const layerWidths = computed(() =>
+      $store.state.simulationSetup.current.layers.map((x) => x.layerWidth)
+    );
+    const totalR = computed(() => layerWidths.value.reduce((a, b) => a + b, 0));
+    const x0 = computed(() => totalR.value * relativePlotSize.value);
+    const dx = computed(
+      () => (x0.value * 2.0) / (plotXSideResolution.value - 1)
+    );
+    const units = computed(() => $store.state.guiRuntime.units);
+    const at_x = computed(() => {
+      if (
+        crossSection.value == nearFieldPlane.Ek ||
+        crossSection.value == nearFieldPlane.Hk
+      ) {
+        return $store.state.simulationSetup.current.nearFieldSetup.atRelativeZ0;
       }
-      return $store.state.simulationSetup.current.nearFieldSetup.atRelativeY0
-    })
+      return $store.state.simulationSetup.current.nearFieldSetup.atRelativeY0;
+    });
 
-    const at_y = computed(()=>{
+    const at_y = computed(() => {
       if (crossSection.value == nearFieldPlane.Hk) {
-        return $store.state.simulationSetup.current.nearFieldSetup.atRelativeY0
+        return $store.state.simulationSetup.current.nearFieldSetup.atRelativeY0;
       }
-      return $store.state.simulationSetup.current.nearFieldSetup.atRelativeX0
-    })
+      return $store.state.simulationSetup.current.nearFieldSetup.atRelativeX0;
+    });
 
-    const xy = computed(()=> {
-      let x:number[] = []
-      let y:number[] = []
-      const xi = at_x.value*totalR.value - dx.value*(plotXSideResolution.value-1)/2;
-      const yi = at_y.value*totalR.value - dx.value*(plotYSideResolution.value-1)/2;
+    const xy = computed(() => {
+      let x: number[] = [];
+      let y: number[] = [];
+      const xi =
+        at_x.value * totalR.value -
+        (dx.value * (plotXSideResolution.value - 1)) / 2;
+      const yi =
+        at_y.value * totalR.value -
+        (dx.value * (plotYSideResolution.value - 1)) / 2;
 
-      for (let j = 0; j< plotYSideResolution.value; ++j) {
-        for (let i = 0; i< plotXSideResolution.value; ++i) {
-          x.push(toUnits(xi + i * dx.value, units.value))
-          y.push(toUnits(yi + j * dx.value, units.value))
+      for (let j = 0; j < plotYSideResolution.value; ++j) {
+        for (let i = 0; i < plotXSideResolution.value; ++i) {
+          x.push(toUnits(xi + i * dx.value, units.value));
+          y.push(toUnits(yi + j * dx.value, units.value));
         }
       }
-      $store.commit('plotRuntime/setNearFieldCoords',{x:x, y:y})
-      return {x:x, y:y}
-    })
+      $store.commit('plotRuntime/setNearFieldCoords', { x: x, y: y });
+      return { x: x, y: y };
+    });
 
-    const limitFrom = computed( ()=>$store.state.plotRuntime.nearFieldLimitFrom )
-    const limitTo = computed(()=>$store.state.plotRuntime.nearFieldLimitTo )
+    const limitFrom = computed(
+      () => $store.state.plotRuntime.nearFieldLimitFrom
+    );
+    const limitTo = computed(() => $store.state.plotRuntime.nearFieldLimitTo);
 
-    const nearFieldStore = computed(()=>{
-      let nearFieldStoreLocal = $store.state.plotRuntime.nearFieldEabs
-      $store.commit('plotRuntime/setNearFieldDataTo', getMaxFromHeatmap(nearFieldStoreLocal))
-      $store.commit('plotRuntime/setNearFieldDataFrom', getMinFromHeatmap(nearFieldStoreLocal))
-      $store.commit('plotRuntime/setNearFieldLimitTo', $store.state.plotRuntime.nearFieldDataTo)
-      $store.commit('plotRuntime/setNearFieldLimitFrom', $store.state.plotRuntime.nearFieldDataFrom)
-      return nearFieldStoreLocal
-    })
-    const nearFieldProc = computed( ()=>{
-      if (!nearFieldStore.value) return nearFieldStore.value
-      return limitMap(nearFieldStore.value, limitFrom.value, limitTo.value)
+    const nearFieldStore = computed(() => {
+      let nearFieldStoreLocal = $store.state.plotRuntime.nearFieldEabs;
+      $store.commit(
+        'plotRuntime/setNearFieldDataTo',
+        getMaxFromHeatmap(nearFieldStoreLocal)
+      );
+      $store.commit(
+        'plotRuntime/setNearFieldDataFrom',
+        getMinFromHeatmap(nearFieldStoreLocal)
+      );
+      $store.commit(
+        'plotRuntime/setNearFieldLimitTo',
+        $store.state.plotRuntime.nearFieldDataTo
+      );
+      $store.commit(
+        'plotRuntime/setNearFieldLimitFrom',
+        $store.state.plotRuntime.nearFieldDataFrom
+      );
+      return nearFieldStoreLocal;
+    });
+    const nearFieldProc = computed(() => {
+      if (!nearFieldStore.value) return nearFieldStore.value;
+      return limitMap(nearFieldStore.value, limitFrom.value, limitTo.value);
       // return nearFieldStore.map(x=>x>limitTo.value?limitTo.value:x)
-    })
-    watch([nearFieldProc, xy], ()=>{
-      nearFieldPlot.data.length = 0
-      const heatMapSettings: Partial<PlotData> = {type: 'heatmap',
-        colorscale: 'Jet', colorbar:{title:'|𝐸|∕|𝐸𝜊|'},
-        z: nearFieldProc.value
-      }
-      nearFieldPlot.data.push({...xy.value, ...heatMapSettings})
+    });
+    watch([nearFieldProc, xy], () => {
+      nearFieldPlot.data.length = 0;
+      const heatMapSettings: Partial<PlotData> = {
+        type: 'heatmap',
+        colorscale: 'Jet',
+        colorbar: { title: '|𝐸|∕|𝐸𝜊|' },
+        z: nearFieldProc.value,
+      };
+      nearFieldPlot.data.push({ ...xy.value, ...heatMapSettings });
 
       if (nearFieldPlot.layout.shapes) {
-        nearFieldPlot.layout.shapes.length = 0
-        let r = 0
+        nearFieldPlot.layout.shapes.length = 0;
+        let r = 0;
         for (let widthLayer of layerWidths.value) {
-          r += widthLayer
+          r += widthLayer;
           nearFieldPlot.layout.shapes.push({
             type: 'circle',
             xref: 'x',
@@ -136,26 +174,28 @@ export default defineComponent({
             y1: toUnits(r, units.value),
             line: {
               color: 'rgba(235, 235, 235, 0.8)',
-              width: 3
-            }
-          })
+              width: 3,
+            },
+          });
         }
       }
-    })
+    });
 
-    const xaxisTitle = computed(()=>{
-      let title:string|Partial<DataTitle> = 'x ['+units.value+']'
-      return title
-    })
-    if (nearFieldPlot.layout.xaxis) nearFieldPlot.layout.xaxis.title = xaxisTitle.value
-    watch( xaxisTitle, ()=>{
-      if (nearFieldPlot.layout.xaxis) nearFieldPlot.layout.xaxis.title = xaxisTitle.value
-    })
+    const xaxisTitle = computed(() => {
+      let title: string | Partial<DataTitle> = 'x [' + units.value + ']';
+      return title;
+    });
+    if (nearFieldPlot.layout.xaxis)
+      nearFieldPlot.layout.xaxis.title = xaxisTitle.value;
+    watch(xaxisTitle, () => {
+      if (nearFieldPlot.layout.xaxis)
+        nearFieldPlot.layout.xaxis.title = xaxisTitle.value;
+    });
 
     return {
-      nearFieldPlot, totalR
-
-    }
-  }
-})
+      nearFieldPlot,
+      totalR,
+    };
+  },
+});
 </script>

+ 114 - 77
guiapp/src/components/nearfield/RunSimulationNearField.vue

@@ -1,28 +1,39 @@
 <template>
   <div class="row items-baseline">
-    <div class="col-xs-12 col-sm-auto text-weight-bold text-center q-px-md q-py-sm">
+    <div
+      class="col-xs-12 col-sm-auto text-weight-bold text-center q-px-md q-py-sm"
+    >
       <q-tooltip
-          v-if=" $store.state.guiRuntime.safeFromWL > $store.state.simulationSetup.gui.nearFieldSetup.atWL ||
-                 $store.state.guiRuntime.safeToWL < $store.state.simulationSetup.gui.nearFieldSetup.atWL "
-          anchor="top middle" self="center middle"
-          class="bg-amber-4 text-black shadow-4">
-        Will use materials<br> spectrum range.
+        v-if="
+          $store.state.guiRuntime.safeFromWL >
+            $store.state.simulationSetup.gui.nearFieldSetup.atWL ||
+          $store.state.guiRuntime.safeToWL <
+            $store.state.simulationSetup.gui.nearFieldSetup.atWL
+        "
+        anchor="top middle"
+        self="center middle"
+        class="bg-amber-4 text-black shadow-4"
+      >
+        Will use materials<br />
+        spectrum range.
       </q-tooltip>
-        <q-btn :loading="isRunning"
-               :disable="isRunning||!isNmieLoaded"
-               color="primary"
-               no-caps
-               :label="isNmieLoaded ? 'Run simulation' : 'Loading...'"
-               @click="runNearFieldSimulation">
-          <template #loading>
-            <q-spinner-gears />
-          </template>
-        </q-btn>
+      <q-btn
+        :loading="isRunning"
+        :disable="isRunning || !isNmieLoaded"
+        color="primary"
+        no-caps
+        :label="isNmieLoaded ? 'Run simulation' : 'Loading...'"
+        @click="runNearFieldSimulation"
+      >
+        <template #loading>
+          <q-spinner-gears />
+        </template>
+      </q-btn>
     </div>
     <div class="col-xs-grow col-sm q-px-xs">
       <div class="row justify-xs-center justify-sm-start items-baseline">
         <div class="col-auto">
-          <SaveSimulationNearField/>
+          <SaveSimulationNearField />
         </div>
       </div>
     </div>
@@ -30,94 +41,120 @@
 </template>
 
 <script lang="ts">
-import {computed, defineComponent, nextTick} from 'vue'
-import {useStore} from 'src/store'
-import {cloneDeep} from 'lodash'
-import SaveSimulationNearField from 'components/nearfield/SaveSimulationNearField.vue'
-
+import { computed, defineComponent, nextTick } from 'vue';
+import { useStore } from 'src/store';
+import { cloneDeep } from 'lodash';
+import SaveSimulationNearField from 'components/nearfield/SaveSimulationNearField.vue';
 
 export default defineComponent({
   name: 'RunSimulationNearField',
-  components: {SaveSimulationNearField},
+  components: { SaveSimulationNearField },
   setup() {
-    const $store = useStore()
+    const $store = useStore();
 
     const isRunning = computed({
-      get: ()=> $store.state.simulationSetup.nmies.nearField.isNmieRunning,
-      set: val => {
-        val ? $store.commit('simulationSetup/markNmieNearFieldAsStarted') : $store.commit('simulationSetup/markNmieNearFieldAsFinished')
-      }
-    })
+      get: () => $store.state.simulationSetup.nmies.nearField.isNmieRunning,
+      set: (val) => {
+        val
+          ? $store.commit('simulationSetup/markNmieNearFieldAsStarted')
+          : $store.commit('simulationSetup/markNmieNearFieldAsFinished');
+      },
+    });
 
-    const isNmieLoaded = computed(()=>{ return $store.state.simulationSetup.nmies.nearField.instance })
+    const isNmieLoaded = computed(() => {
+      return $store.state.simulationSetup.nmies.nearField.instance;
+    });
 
     const atWL = computed(
-        () => $store.state.simulationSetup.current.nearFieldSetup.atWL)
+      () => $store.state.simulationSetup.current.nearFieldSetup.atWL
+    );
     //-------------------------------------------------------------------------//
     //---------------------  Main  --------------------------------------------//
     //-------------------------------------------------------------------------//
     function runNearFieldSimulation() {
       if (isRunning.value) {
-        console.log('Some Nmie is already running!')
-        return
+        console.log('Some Nmie is already running!');
+        return;
       }
-      isRunning.value = true
-      void setTimeout(()=> {
-        void nextTick(()=> {
-          $store.commit('simulationSetup/copySetupFromGuiToCurrent')
+      isRunning.value = true;
+      void setTimeout(() => {
+        void nextTick(() => {
+          $store.commit('simulationSetup/copySetupFromGuiToCurrent');
 
-          const host = $store.state.simulationSetup.current.hostIndex
-          const plotXSideResolution = $store.state.simulationSetup.current.nearFieldSetup.plotXSideResolution
-          const plotYSideResolution = $store.state.simulationSetup.current.nearFieldSetup.plotYSideResolution
-          const relativePlotSize = $store.state.simulationSetup.current.nearFieldSetup.relativePlotSize
-          const crossSection = $store.state.simulationSetup.current.nearFieldSetup.crossSection
-          const atX = $store.state.simulationSetup.current.nearFieldSetup.atRelativeX0
-          const atY = $store.state.simulationSetup.current.nearFieldSetup.atRelativeY0
-          const atZ = $store.state.simulationSetup.current.nearFieldSetup.atRelativeZ0
-          const isMarkUnconvergedAsNaN = 1 // 0 - do not mark, else do mark
+          const host = $store.state.simulationSetup.current.hostIndex;
+          const plotXSideResolution =
+            $store.state.simulationSetup.current.nearFieldSetup
+              .plotXSideResolution;
+          const plotYSideResolution =
+            $store.state.simulationSetup.current.nearFieldSetup
+              .plotYSideResolution;
+          const relativePlotSize =
+            $store.state.simulationSetup.current.nearFieldSetup
+              .relativePlotSize;
+          const crossSection =
+            $store.state.simulationSetup.current.nearFieldSetup.crossSection;
+          const atX =
+            $store.state.simulationSetup.current.nearFieldSetup.atRelativeX0;
+          const atY =
+            $store.state.simulationSetup.current.nearFieldSetup.atRelativeY0;
+          const atZ =
+            $store.state.simulationSetup.current.nearFieldSetup.atRelativeZ0;
+          const isMarkUnconvergedAsNaN = 1; // 0 - do not mark, else do mark
           try {
-            if (!$store.state.simulationSetup.nmies.nearField.instance) throw 'ERROR! Scattnlay module was not loaded'
-            const nmie = $store.state.simulationSetup.nmies.nearField.instance
-            const layers = cloneDeep($store.state.simulationSetup.current.layers)
-            const nmieStartedTime = performance.now()
+            if (!$store.state.simulationSetup.nmies.nearField.instance)
+              throw 'ERROR! Scattnlay module was not loaded';
+            const nmie = $store.state.simulationSetup.nmies.nearField.instance;
+            const layers = cloneDeep(
+              $store.state.simulationSetup.current.layers
+            );
+            const nmieStartedTime = performance.now();
 
-            nmie.SetWavelength(atWL.value)
-            nmie.ClearTarget()
+            nmie.SetWavelength(atWL.value);
+            nmie.ClearTarget();
             for (const layer of layers) {
-              if (layer.material.nSpline) layer.n = layer.material.nSpline.at(atWL.value)
-              if (layer.material.kSpline) layer.k = layer.material.kSpline.at(atWL.value)
-              nmie.AddTargetLayerReIm(layer.layerWidth * host, layer.n / host, layer.k / host)
+              if (layer.material.nSpline)
+                layer.n = layer.material.nSpline.at(atWL.value);
+              if (layer.material.kSpline)
+                layer.k = layer.material.kSpline.at(atWL.value);
+              nmie.AddTargetLayerReIm(
+                layer.layerWidth * host,
+                layer.n / host,
+                layer.k / host
+              );
             }
 
-            nmie.SetModeNmaxAndType(-1, -1)
+            nmie.SetModeNmaxAndType(-1, -1);
 
             nmie.RunFieldCalculationCartesian(
-                plotYSideResolution,
-                plotXSideResolution, // in simulation z-axis resolution for Ek and Hk cross-sections
-                relativePlotSize,
-                crossSection,
-                atX, atY, atZ,
-                isMarkUnconvergedAsNaN
-            )
-            const Eabs = nmie.GetFieldEabs()
-            $store.commit('plotRuntime/setNearField', Eabs)
-            const nmieTotalRunTime = (performance.now() - nmieStartedTime) / 1000
+              plotYSideResolution,
+              plotXSideResolution, // in simulation z-axis resolution for Ek and Hk cross-sections
+              relativePlotSize,
+              crossSection,
+              atX,
+              atY,
+              atZ,
+              isMarkUnconvergedAsNaN
+            );
+            const Eabs = nmie.GetFieldEabs();
+            $store.commit('plotRuntime/setNearField', Eabs);
+            const nmieTotalRunTime =
+              (performance.now() - nmieStartedTime) / 1000;
             // console.log('Total simulation time:', nmieTotalRunTime, 's')
-            $store.commit('simulationSetup/setNmieNearFieldTotalRunTime', nmieTotalRunTime)
-
+            $store.commit(
+              'simulationSetup/setNmieNearFieldTotalRunTime',
+              nmieTotalRunTime
+            );
           } catch (e) {
-            console.log('Some error:', e)
+            console.log('Some error:', e);
           }
-          isRunning.value = false
-        })
-      }, 100)
+          isRunning.value = false;
+        });
+      }, 100);
     }
 
-    runNearFieldSimulation()
+    runNearFieldSimulation();
 
-    return { isRunning, isNmieLoaded,
-      runNearFieldSimulation
-    }
+    return { isRunning, isNmieLoaded, runNearFieldSimulation };
   },
-})
+});
 </script>

+ 92 - 79
guiapp/src/components/nearfield/SaveSimulationNearField.vue

@@ -1,109 +1,122 @@
 <template>
   <q-btn
-      color="primary"
-      no-caps
-      :disable="data ? false : true"
-      @click="saveSpectrumSimulation"
-  >Save</q-btn>
+    color="primary"
+    no-caps
+    :disable="data ? false : true"
+    @click="saveSpectrumSimulation"
+    >Save</q-btn
+  >
 </template>
 
 <script lang="ts">
 import {
   computed,
   defineComponent,
-    // ref,
+  // ref,
   // watch
   // nextTick
-} from 'vue'
-import {useStore} from 'src/store'
+} from 'vue';
+import { useStore } from 'src/store';
 // import {getModeName, range, rangeInt} from 'components/utils'
 // import {cloneDeep} from 'lodash'
-import {saveAs} from 'file-saver'
+import { saveAs } from 'file-saver';
 // import {nearFieldPlane} from 'src/store/simulation-setup/state';
 
-
 export default defineComponent({
   name: 'SaveSimulationNearField',
 
   setup() {
-    const $store = useStore()
-
+    const $store = useStore();
 
-    const coordX = computed(() => $store.state.plotRuntime.nearFieldCoordX)
-    const coordY = computed(() => $store.state.plotRuntime.nearFieldCoordY)
-    const data = computed(() => $store.state.plotRuntime.nearFieldEabs)
-    const layerWidths = computed(()=>$store.state.simulationSetup.current.layers.map(x=>x.layerWidth))
-    const crossSection = computed(()=>{
-      let val = $store.state.simulationSetup.current.nearFieldSetup.crossSection
-      if (val == 0) return 'Ek'
-      if (val == 1) return 'Hk'
-      return 'EH'
-    })
-    const radii = computed(()=>{
-      let r = 0
-      let radiiLocal=''
+    const coordX = computed(() => $store.state.plotRuntime.nearFieldCoordX);
+    const coordY = computed(() => $store.state.plotRuntime.nearFieldCoordY);
+    const data = computed(() => $store.state.plotRuntime.nearFieldEabs);
+    const layerWidths = computed(() =>
+      $store.state.simulationSetup.current.layers.map((x) => x.layerWidth)
+    );
+    const crossSection = computed(() => {
+      let val =
+        $store.state.simulationSetup.current.nearFieldSetup.crossSection;
+      if (val == 0) return 'Ek';
+      if (val == 1) return 'Hk';
+      return 'EH';
+    });
+    const radii = computed(() => {
+      let r = 0;
+      let radiiLocal = '';
       for (let widthLayer of layerWidths.value) {
-        r += widthLayer
-        radiiLocal += r.toString()+','
+        r += widthLayer;
+        radiiLocal += r.toString() + ',';
       }
-      return radiiLocal
-    })
-    const lengthUnits = computed(()=>$store.state.guiRuntime.units )
+      return radiiLocal;
+    });
+    const lengthUnits = computed(() => $store.state.guiRuntime.units);
     return {
       data,
-      saveSpectrumSimulation(){
-        if (!data.value) return
-        const fileHeader ='# You can open and plot this file using Python\n' +
-            '# (without manually removing this header, it will be skipped), see example below.\n' +
-            'import numpy as np\n' +
-            'from matplotlib import pyplot as plt\n' +
-            'data = np.genfromtxt(\'scattnlay-near-field.txt\', skip_header=32, names=True, delimiter=\', \')\n' +
-            'x = data[data.dtype.names[0]] # x-axis has units\n' +
-            'y = data[data.dtype.names[1]] # x-axis has units\n' +
-            'x_size = len(np.unique(x))\n' +
-            'y_size = len(np.unique(y))\n' +
-            'x_min = np.min(x)\n' +
-            'y_min = np.min(y)\n' +
-            'x_max = np.max(x)\n' +
-            'y_max = np.max(y)\n' +
-            'dx = (x_max-x_min)/(x_size-1)\n' +
-            'dy = (y_max-y_min)/(y_size-1)\n' +
-            'Eabs = data[\'Eabs\'].reshape((y_size,x_size))\n' +
-            '\n' +
-            'plt.figure()\n' +
-            'plt.imshow(Eabs, cmap=\'jet\', origin=\'lower\',\n' +
-            '           extent=(x_min-dx/2, x_max+dx/2, y_min-dy/2, y_max+dy/2))\n' +
-            'cbar = plt.colorbar(shrink=0.7)\n' +
-            'cbar.ax.set_title(r\'$|E|/|E_0|$\')\n' +
-            'plt.xlabel(data.dtype.names[0].replace(\'_\',\', \'))\n' +
-            'plt.ylabel(data.dtype.names[1].replace(\'_\',\', \'))\n' +
-            'fig = plt.gcf()\n' +
-            'ax = fig.gca()\n' +
-            'radii = ['+radii.value+']\n' +
-            'for r in radii:\n' +
-            '    ax.add_patch(plt.Circle((0, 0), r, color=\'w\', alpha=0.7, lw=3, fill=False))\n' +
-            'plt.title(\''+crossSection.value+' cross-section\')\n'+
-            'plt.show()\n\n'
+      saveSpectrumSimulation() {
+        if (!data.value) return;
+        const fileHeader =
+          '# You can open and plot this file using Python\n' +
+          '# (without manually removing this header, it will be skipped), see example below.\n' +
+          'import numpy as np\n' +
+          'from matplotlib import pyplot as plt\n' +
+          "data = np.genfromtxt('scattnlay-near-field.txt', skip_header=32, names=True, delimiter=', ')\n" +
+          'x = data[data.dtype.names[0]] # x-axis has units\n' +
+          'y = data[data.dtype.names[1]] # x-axis has units\n' +
+          'x_size = len(np.unique(x))\n' +
+          'y_size = len(np.unique(y))\n' +
+          'x_min = np.min(x)\n' +
+          'y_min = np.min(y)\n' +
+          'x_max = np.max(x)\n' +
+          'y_max = np.max(y)\n' +
+          'dx = (x_max-x_min)/(x_size-1)\n' +
+          'dy = (y_max-y_min)/(y_size-1)\n' +
+          "Eabs = data['Eabs'].reshape((y_size,x_size))\n" +
+          '\n' +
+          'plt.figure()\n' +
+          "plt.imshow(Eabs, cmap='jet', origin='lower',\n" +
+          '           extent=(x_min-dx/2, x_max+dx/2, y_min-dy/2, y_max+dy/2))\n' +
+          'cbar = plt.colorbar(shrink=0.7)\n' +
+          "cbar.ax.set_title(r'$|E|/|E_0|$')\n" +
+          "plt.xlabel(data.dtype.names[0].replace('_',', '))\n" +
+          "plt.ylabel(data.dtype.names[1].replace('_',', '))\n" +
+          'fig = plt.gcf()\n' +
+          'ax = fig.gca()\n' +
+          'radii = [' +
+          radii.value +
+          ']\n' +
+          'for r in radii:\n' +
+          "    ax.add_patch(plt.Circle((0, 0), r, color='w', alpha=0.7, lw=3, fill=False))\n" +
+          "plt.title('" +
+          crossSection.value +
+          " cross-section')\n" +
+          'plt.show()\n\n';
 
-        let columnNames = '# X ['+lengthUnits.value.toString()
-            + '] , Y ['+lengthUnits.value.toString()+'], Eabs\n'
-        let body = ''
+        let columnNames =
+          '# X [' +
+          lengthUnits.value.toString() +
+          '] , Y [' +
+          lengthUnits.value.toString() +
+          '], Eabs\n';
+        let body = '';
         for (let i = 0; i < data.value.length; ++i) {
-          let row = coordX.value[i].toString() + ', '
-              + coordY.value[i].toString() + ', '
-              + data.value[i].toString()
-          row += '\n'
-          body += row
+          let row =
+            coordX.value[i].toString() +
+            ', ' +
+            coordY.value[i].toString() +
+            ', ' +
+            data.value[i].toString();
+          row += '\n';
+          body += row;
         }
 
-        const scattnlayNearField = new Blob([fileHeader+columnNames+body
-            ],
-            {type: 'text/plain;charset=utf-8',
-              endings: 'native'}  //TODO test if newline is correctly written in Windows, MacOS
-        )
+        const scattnlayNearField = new Blob(
+          [fileHeader + columnNames + body],
+          { type: 'text/plain;charset=utf-8', endings: 'native' } //TODO test if newline is correctly written in Windows, MacOS
+        );
         saveAs(scattnlayNearField, 'scattnlay-near-field.txt');
-      }
-    }
+      },
+    };
   },
-})
+});
 </script>

+ 43 - 29
guiapp/src/components/nearfield/ShowNearFieldWarning.vue

@@ -1,40 +1,55 @@
 <template>
-  <div v-if="count<2">
+  <div v-if="count < 2">
     <q-card>
       <div class="q-pa-sm">
-      <div class="text-h6 q-ml-sm"><q-icon name="warning"/> Warning</div>
-      <div class="q-ma-sm">Near-field evaluation is an experimental feature. In general, it provides a correct result. However, it is not as tested as spectrum computations, especially for the case of large, multilayer, and absorbing spheres. Please, verify the result before using it.</div>
-      <div class="q-ma-xs"/>
-      <div class="q-ml-sm text-h6"><q-icon size='sm' name="o_info"/> Usage</div>
-      <div class="q-ma-sm">Near-field simulation uses settings from spectrum simulation.</div>
-              <q-separator inset/>
-        <div class="q-ma-sm"/>
-        <q-btn icon="settings" flat text-color="primary"
-               label="Change spectrum settings"
-               @click="void router.push({path: '/spectrum'})"/>
-      <q-btn icon="close" flat text-color="primary"
-               label="Close"
-               @click="count=2"/>
+        <div class="text-h6 q-ml-sm"><q-icon name="warning" /> Warning</div>
+        <div class="q-ma-sm">
+          Near-field evaluation is an experimental feature. In general, it
+          provides a correct result. However, it is not as tested as spectrum
+          computations, especially for the case of large, multilayer, and
+          absorbing spheres. Please, verify the result before using it.
+        </div>
+        <div class="q-ma-xs" />
+        <div class="q-ml-sm text-h6">
+          <q-icon size="sm" name="o_info" /> Usage
+        </div>
+        <div class="q-ma-sm">
+          Near-field simulation uses settings from spectrum simulation.
+        </div>
+        <q-separator inset />
+        <div class="q-ma-sm" />
+        <q-btn
+          icon="settings"
+          flat
+          text-color="primary"
+          label="Change spectrum settings"
+          @click="void router.push({ path: '/spectrum' })"
+        />
+        <q-btn
+          icon="close"
+          flat
+          text-color="primary"
+          label="Close"
+          @click="count = 2"
+        />
       </div>
     </q-card>
-    <div class="q-ma-md"/>
+    <div class="q-ma-md" />
   </div>
 </template>
 
 <script lang="ts">
-import { useRouter } from 'vue-router'
-import {
-  defineComponent,
-  onActivated,
-  ref,
-} from 'vue'
+import { useRouter } from 'vue-router';
+import { defineComponent, onActivated, ref } from 'vue';
 
 export default defineComponent({
   name: 'ShowNearFieldWarning',
-  setup () {
-    const router = useRouter()
-    let count = ref(0)
-    onActivated(()=> { count.value = count.value + 1 })
+  setup() {
+    const router = useRouter();
+    let count = ref(0);
+    onActivated(() => {
+      count.value = count.value + 1;
+    });
     // import { useQuasar } from 'quasar'
     // const $q = useQuasar()
     // onActivated(()=>{
@@ -59,8 +74,7 @@ export default defineComponent({
     //   }
     // })
     //
-
-    return { count, router }
-  }
-})
+    return { count, router };
+  },
+});
 </script>

+ 21 - 24
guiapp/src/components/spectrum/GetHostIndex.vue

@@ -1,54 +1,51 @@
 <template>
   <div class="row items-baseline">
-    <div class="col-xs-12 col-sm-auto text-weight-bold text-center q-px-md q-py-sm">
-      <div :style="flexRowTitleStyle">
-        Host media
-      </div>
+    <div
+      class="col-xs-12 col-sm-auto text-weight-bold text-center q-px-md q-py-sm"
+    >
+      <div :style="flexRowTitleStyle">Host media</div>
     </div>
     <div class="col-xs-grow col-sm">
       <div class="row justify-xs-center justify-sm-start items-center">
-
-        <div class="col-auto" ><input-with-units
+        <div class="col-auto">
+          <input-with-units
             v-model:input-result="hostIndex"
             v-model:is-showing-help="isShowingHelpForInputWithUnits"
             :initial-expression="hostIndex.toString()"
             title="Re(n)"
             units=""
-        /></div>
-
+          />
+        </div>
       </div>
     </div>
   </div>
 </template>
 
 <script lang="ts">
-import {
-  defineComponent,
-  computed,
-  } from 'vue'
-import { useStore } from 'src/store'
-import InputWithUnits from 'components/InputWithUnits.vue'
-import { flexRowTitleStyle } from 'components/config'
+import { defineComponent, computed } from 'vue';
+import { useStore } from 'src/store';
+import InputWithUnits from 'components/InputWithUnits.vue';
+import { flexRowTitleStyle } from 'components/config';
 
 export default defineComponent({
-
   name: 'GetHostIndex',
-  components: {InputWithUnits,},
+  components: { InputWithUnits },
 
   setup() {
-    const $store = useStore()
+    const $store = useStore();
 
     const isShowingHelpForInputWithUnits = computed({
       get: () => $store.state.guiRuntime.isShowingHelpForInputWithUnits,
-      set: val => $store.commit('guiRuntime/setIsShowingHelpForInputWithUnits', val)
-    })
+      set: (val) =>
+        $store.commit('guiRuntime/setIsShowingHelpForInputWithUnits', val),
+    });
 
     const hostIndex = computed({
       get: () => $store.state.simulationSetup.gui.hostIndex,
-      set: val => $store.commit('simulationSetup/setHostIndex', val)
-    })
+      set: (val) => $store.commit('simulationSetup/setHostIndex', val),
+    });
 
-    return { hostIndex, isShowingHelpForInputWithUnits, flexRowTitleStyle}
+    return { hostIndex, isShowingHelpForInputWithUnits, flexRowTitleStyle };
   },
-})
+});
 </script>

+ 44 - 45
guiapp/src/components/spectrum/GetModesToPlot.vue

@@ -1,24 +1,23 @@
 <template>
   <div class="row items-baseline">
-    <div class="col-xs-12 col-sm-auto text-weight-bold text-center q-px-md q-py-sm">
-      <div :style="flexRowTitleStyle">
-        Modes to plot
-      </div>
+    <div
+      class="col-xs-12 col-sm-auto text-weight-bold text-center q-px-md q-py-sm"
+    >
+      <div :style="flexRowTitleStyle">Modes to plot</div>
     </div>
     <div class="col-xs-grow col-sm q-px-xs">
       <div class="row justify-xs-center justify-sm-start items-center">
-
         <div class="col-auto">
-              <q-input
-                  v-model.number="numberOfModesToPlot"
-                  outlined
-                  type="number"
-                  min=1
-                  :max='maxModes'
-                  step=1
-                  dense
-                  :style="'width: '+basicSelectorWidthStyle"
-              />
+          <q-input
+            v-model.number="numberOfModesToPlot"
+            outlined
+            type="number"
+            min="1"
+            :max="maxModes"
+            step="1"
+            dense
+            :style="'width: ' + basicSelectorWidthStyle"
+          />
         </div>
       </div>
     </div>
@@ -26,47 +25,47 @@
 </template>
 
 <script lang="ts">
-import {
-  defineComponent,
-  computed,
-  watch,
-  } from 'vue'
+import { defineComponent, computed, watch } from 'vue';
 
-import { useStore } from 'src/store'
-import { flexRowTitleStyle,
+import { useStore } from 'src/store';
+import {
+  flexRowTitleStyle,
   maxNumberOfModesToPlot as maxModes,
   basicSelectorWidthStyle,
-    basicWidthStyle
-} from 'components/config'
+  basicWidthStyle,
+} from 'components/config';
 
 export default defineComponent({
   name: 'GetModesToPlot',
 
   setup() {
-    const $store = useStore()
+    const $store = useStore();
     const numberOfModesToPlot = computed({
       get: () => $store.state.simulationSetup.gui.numberOfModesToPlot,
-      set: val => {
-        let intVal = parseInt(val.toString())
-        if (isNaN(intVal)) return
-        if (intVal<1) intVal = 1
-        if (intVal>maxModes) intVal = maxModes
-        $store.commit('simulationSetup/setNumberOfModesToPlot', intVal)
-        $store.commit('plotRuntime/resizeSelectorIsPlotMode',intVal)
-      }
-    })
-
-    watch(numberOfModesToPlot, ()=>{
-      const intVal = parseInt(numberOfModesToPlot.value.toString())
-      if (isNaN(intVal)) return
-      if (intVal<1) numberOfModesToPlot.value = 1
-      if (intVal>maxModes) numberOfModesToPlot.value = maxModes
-    })
+      set: (val) => {
+        let intVal = parseInt(val.toString());
+        if (isNaN(intVal)) return;
+        if (intVal < 1) intVal = 1;
+        if (intVal > maxModes) intVal = maxModes;
+        $store.commit('simulationSetup/setNumberOfModesToPlot', intVal);
+        $store.commit('plotRuntime/resizeSelectorIsPlotMode', intVal);
+      },
+    });
 
-    return { flexRowTitleStyle, basicSelectorWidthStyle, basicWidthStyle,
-      numberOfModesToPlot, maxModes,
+    watch(numberOfModesToPlot, () => {
+      const intVal = parseInt(numberOfModesToPlot.value.toString());
+      if (isNaN(intVal)) return;
+      if (intVal < 1) numberOfModesToPlot.value = 1;
+      if (intVal > maxModes) numberOfModesToPlot.value = maxModes;
+    });
 
-    }
+    return {
+      flexRowTitleStyle,
+      basicSelectorWidthStyle,
+      basicWidthStyle,
+      numberOfModesToPlot,
+      maxModes,
+    };
   },
-})
+});
 </script>

+ 242 - 179
guiapp/src/components/spectrum/GetParticleParameters.vue

@@ -1,220 +1,267 @@
 <template>
   <div class="row items-baseline">
-    <div class="col-xs-12 col-sm-auto text-weight-bold text-center q-px-md q-py-sm">
-      <div :style="flexRowTitleStyle">
-        Spherical particle
-      </div>
+    <div
+      class="col-xs-12 col-sm-auto text-weight-bold text-center q-px-md q-py-sm"
+    >
+      <div :style="flexRowTitleStyle">Spherical particle</div>
     </div>
-    <div class="col-xs-grow col-sm  q-px-xs">
+    <div class="col-xs-grow col-sm q-px-xs">
       <div class="row justify-xs-center justify-sm-start items-baseline">
-
-        <div class="col-auto" >
+        <div class="col-auto">
           <div class="q-gutter-x-md">
-            <q-radio v-model="particleType" dense size='sm' val="bulk" label="bulk" />
-            <q-radio v-model="particleType" dense size='sm' val="core-shell" label="core-shell" />
+            <q-radio
+              v-model="particleType"
+              dense
+              size="sm"
+              val="bulk"
+              label="bulk"
+            />
+            <q-radio
+              v-model="particleType"
+              dense
+              size="sm"
+              val="core-shell"
+              label="core-shell"
+            />
           </div>
-
         </div>
 
         <div class="col-auto q-px-md">
           <div class="row justify-xs-center justify-sm-start items-baseline">
-            <div class="col-auto" >
-              <q-radio v-model="particleType" dense size='sm' val="multilayer" label="multilayer" />
+            <div class="col-auto">
+              <q-radio
+                v-model="particleType"
+                dense
+                size="sm"
+                val="multilayer"
+                label="multilayer"
+              />
             </div>
-            <div class="col-auto" >
+            <div class="col-auto">
               <q-input
-                  v-model.number="numberOfLayers"
-                  :disable="particleType!='multilayer'"
-                  :outlined="particleType=='multilayer'"
-                  :filled="particleType!='multilayer'"
-                  type="number"
-                  class="q-px-sm"
-                  min=1
-                  :max="maxNumberOfLayers"
-                  step=1
-                  dense
-                  :style="'width: '+basicSelectorWidthStyle"
+                v-model.number="numberOfLayers"
+                :disable="particleType != 'multilayer'"
+                :outlined="particleType == 'multilayer'"
+                :filled="particleType != 'multilayer'"
+                type="number"
+                class="q-px-sm"
+                min="1"
+                :max="maxNumberOfLayers"
+                step="1"
+                dense
+                :style="'width: ' + basicSelectorWidthStyle"
               />
             </div>
           </div>
         </div>
-
       </div>
     </div>
   </div>
 
-  <div v-for="(layer, index) in layers" :key="index" class="row items-baseline q-py-xs">
+  <div
+    v-for="(layer, index) in layers"
+    :key="index"
+    class="row items-baseline q-py-xs"
+  >
     <div class="col-xs-12 col-sm-auto text-center q-px-md q-py-sm">
       <div :style="flexRowTitleStyle">
-        {{getLayerTitle(particleType, index)}}
+        {{ getLayerTitle(particleType, index) }}
       </div>
     </div>
     <div class="col-xs-grow col-sm">
       <div class="row justify-xs-center justify-sm-start items-baseline">
-
         <div class="col-auto">
           <q-tooltip
-              class="bg-primary shadow-4"
-              anchor="center left"
-              self="center middle">
-            {{getTooltipText(index)}}
+            class="bg-primary shadow-4"
+            anchor="center left"
+            self="center middle"
+          >
+            {{ getTooltipText(index) }}
           </q-tooltip>
           <input-with-units
             v-model:is-showing-help="isShowingHelpForInputWithUnits"
             :initial-expression="toUnits(layer.layerWidth, units).toString()"
             :units="units"
-            :title=" index==0 ? 'R' : 'h' "
+            :title="index == 0 ? 'R' : 'h'"
             :input-result="toUnits(layer.layerWidth, units)"
-            @update:input-result="layer.layerWidth = fromUnits(units,$event)"
+            @update:input-result="layer.layerWidth = fromUnits(units, $event)"
           />
         </div>
 
         <div class="col-auto">
           <q-select
-              v-model="layer.material"
-              :options="activatedMaterials"
-              :style="'min-width: '+basicWidthStyle"
-              class="q-px-xs"
-              dense
-              options-dense
-              outlined
-              options-value="name"
-              options-label="name"
+            v-model="layer.material"
+            :options="activatedMaterials"
+            :style="'min-width: ' + basicWidthStyle"
+            class="q-px-xs"
+            dense
+            options-dense
+            outlined
+            options-value="name"
+            options-label="name"
           >
             <template
-                v-if=" layer.material.spectrumRangeStart > fromWavelengthStore ||
-                       layer.material.spectrumRangeEnd   <   toWavelengthStore"
-                #after
+              v-if="
+                layer.material.spectrumRangeStart > fromWavelengthStore ||
+                layer.material.spectrumRangeEnd < toWavelengthStore
+              "
+              #after
             >
               <q-tooltip> Input conflict </q-tooltip>
-              <q-icon name="error" class="text-warning"/>
+              <q-icon name="error" class="text-warning" />
             </template>
 
             <template #selected>
-              <q-item dense class="q-pa-none" style="margin-top: -1px; margin-bottom: -1px;">
+              <q-item
+                dense
+                class="q-pa-none"
+                style="margin-top: -1px; margin-bottom: -1px"
+              >
                 <q-item-section class="q-pa-none">
-                {{ layer.material.name }}
+                  {{ layer.material.name }}
                 </q-item-section>
-                <q-item-section v-if="!(layer.material.name=='nk-constant' || layer.material.name=='PEC')" side>
+                <q-item-section
+                  v-if="
+                    !(
+                      layer.material.name == 'nk-constant' ||
+                      layer.material.name == 'PEC'
+                    )
+                  "
+                  side
+                >
                   <ShowSpectrumRange
-                      class="text-caption"
-                      :spectrum-range-start="layer.material.spectrumRangeStart"
-                      :spectrum-range-end="layer.material.spectrumRangeEnd"
+                    class="text-caption"
+                    :spectrum-range-start="layer.material.spectrumRangeStart"
+                    :spectrum-range-end="layer.material.spectrumRangeEnd"
                   />
                 </q-item-section>
               </q-item>
-
             </template>
             <template #option="scope">
-              <span v-if="scope.opt.name =='link'">
-                <q-item clickable dense
-                        to="/materials"
-                >
+              <span v-if="scope.opt.name == 'link'">
+                <q-item clickable dense to="/materials">
                   <q-item-section side>
-                    <q-icon size="xs" name="settings"/>
+                    <q-icon size="xs" name="settings" />
                   </q-item-section>
                   <q-item-section>
-                    <q-item-label >Manage materials...</q-item-label>
+                    <q-item-label>Manage materials...</q-item-label>
                   </q-item-section>
                 </q-item>
                 <q-separator inset />
               </span>
               <span v-else>
                 <q-item
-                    v-bind="scope.itemProps"
-                    :disable="(!scope.opt.kSpline || !scope.opt.kSpline)
-                     && !(scope.opt.name=='nk-constant' || scope.opt.name=='PEC')"
+                  v-bind="scope.itemProps"
+                  :disable="
+                    (!scope.opt.kSpline || !scope.opt.kSpline) &&
+                    !(
+                      scope.opt.name == 'nk-constant' || scope.opt.name == 'PEC'
+                    )
+                  "
                 >
                   <q-item-section>
-                    <q-item-label>{{ scope.opt.name }}
-
-                    </q-item-label>
+                    <q-item-label>{{ scope.opt.name }} </q-item-label>
                     <!--                  <q-item-label caption>{{ scope.opt.description }}</q-item-label>-->
                   </q-item-section>
-                  <q-item-section v-if="!(scope.opt.name=='nk-constant' || scope.opt.name=='PEC')" side>
-                                                  <ShowSpectrumRange
-                                                      class="text-caption"
-                                                      :spectrum-range-start="scope.opt.spectrumRangeStart"
-                                                      :spectrum-range-end="scope.opt.spectrumRangeEnd"
-                                                  />
+                  <q-item-section
+                    v-if="
+                      !(
+                        scope.opt.name == 'nk-constant' ||
+                        scope.opt.name == 'PEC'
+                      )
+                    "
+                    side
+                  >
+                    <ShowSpectrumRange
+                      class="text-caption"
+                      :spectrum-range-start="scope.opt.spectrumRangeStart"
+                      :spectrum-range-end="scope.opt.spectrumRangeEnd"
+                    />
                   </q-item-section>
-
                 </q-item>
               </span>
             </template>
           </q-select>
         </div>
-
       </div>
-      <div v-if="layer.material.name=='nk-constant'"
-               class="row justify-xs-center justify-sm-start items-baseline">
-
-        <div class="col-auto"> <input-with-units
+      <div
+        v-if="layer.material.name == 'nk-constant'"
+        class="row justify-xs-center justify-sm-start items-baseline"
+      >
+        <div class="col-auto">
+          <input-with-units
             v-model:is-showing-help="isShowingHelpForInputWithUnits"
             v-model:input-result="layer.n"
             :initial-expression="layer.n.toString()"
             title="Re(n)"
-        /></div>
-        <div class="col-auto"> <input-with-units
+          />
+        </div>
+        <div class="col-auto">
+          <input-with-units
             v-model:is-showing-help="isShowingHelpForInputWithUnits"
             v-model:input-result="layer.k"
             :initial-expression="layer.k.toString()"
             title="Im(n)"
-
-        /></div>
+          />
+        </div>
       </div>
     </div>
   </div>
 </template>
 
 <script lang="ts">
+import { defineComponent, ref, reactive, computed, watch } from 'vue';
+import { useStore } from 'src/store';
+import { fromUnits, isAlmostSame, toUnits } from 'components/utils';
 import {
-  defineComponent,
-  ref,
-  reactive,
-  computed,
-  watch
-  } from 'vue'
-import { useStore } from 'src/store'
-import { fromUnits, isAlmostSame, toUnits } from 'components/utils'
-import { flexRowTitleStyle, basicWidthStyle, basicSelectorWidthStyle, maxNumberOfLayers } from 'components/config'
-import { cloneDeep } from 'lodash'
+  flexRowTitleStyle,
+  basicWidthStyle,
+  basicSelectorWidthStyle,
+  maxNumberOfLayers,
+} from 'components/config';
+import { cloneDeep } from 'lodash';
 import InputWithUnits from 'components/InputWithUnits.vue';
-import ShowSpectrumRange from 'components/ShowSpectrumRange.vue'
+import ShowSpectrumRange from 'components/ShowSpectrumRange.vue';
 
 export default defineComponent({
   name: 'GetParticleParameters',
   components: {
     InputWithUnits,
-    ShowSpectrumRange
+    ShowSpectrumRange,
   },
 
   setup() {
-    const $store = useStore()
-
-    const fromWavelengthStore = computed(()=>$store.state.simulationSetup.gui.fromWL)
-    const toWavelengthStore = computed(()=>$store.state.simulationSetup.gui.toWL)
-
-
-    const numberOfLayers=ref($store.state.simulationSetup.gui.layers.length)
-    const particleType=ref('bulk')
-    if (numberOfLayers.value == 1) particleType.value='bulk'
-    if (numberOfLayers.value == 2) particleType.value='core-shell'
-    if (numberOfLayers.value == 3) particleType.value='multilayer'
+    const $store = useStore();
+
+    const fromWavelengthStore = computed(
+      () => $store.state.simulationSetup.gui.fromWL
+    );
+    const toWavelengthStore = computed(
+      () => $store.state.simulationSetup.gui.toWL
+    );
+
+    const numberOfLayers = ref($store.state.simulationSetup.gui.layers.length);
+    const particleType = ref('bulk');
+    if (numberOfLayers.value == 1) particleType.value = 'bulk';
+    if (numberOfLayers.value == 2) particleType.value = 'core-shell';
+    if (numberOfLayers.value == 3) particleType.value = 'multilayer';
     // Initially we set numberOfLayers and particleType to match layers in store.
     // Later on changes to numberOfLayers and particleType lead to update of layers in store.
 
     const isShowingHelpForInputWithUnits = computed({
       get: () => $store.state.guiRuntime.isShowingHelpForInputWithUnits,
-      set: val => $store.commit('guiRuntime/setIsShowingHelpForInputWithUnits', val)
-    })
+      set: (val) =>
+        $store.commit('guiRuntime/setIsShowingHelpForInputWithUnits', val),
+    });
 
     const units = computed({
       get: () => $store.state.guiRuntime.units,
-      set: val => $store.commit('guiRuntime/setUnits', val)
-    })
+      set: (val) => $store.commit('guiRuntime/setUnits', val),
+    });
 
-    const activatedMaterials = computed(() => $store.state.guiRuntime.activatedMaterials)
+    const activatedMaterials = computed(
+      () => $store.state.guiRuntime.activatedMaterials
+    );
     // const activatedMaterialsOptions = computed(() => {
     //   let list = activatedMaterials.value.map(x=>{
     //     return {
@@ -227,51 +274,59 @@ export default defineComponent({
     //   return list
     // })
 
-    let layers = reactive( cloneDeep($store.state.simulationSetup.gui.layers) )
+    let layers = reactive(cloneDeep($store.state.simulationSetup.gui.layers));
 
-    watch($store.state.simulationSetup.gui.layers,
-        ()=>{
-          layers.splice(0, layers.length,
-              ...($store.state.simulationSetup.gui.layers.map(layer=>cloneDeep(layer)))
+    watch(
+      $store.state.simulationSetup.gui.layers,
+      () => {
+        layers.splice(
+          0,
+          layers.length,
+          ...$store.state.simulationSetup.gui.layers.map((layer) =>
+            cloneDeep(layer)
           )
-          numberOfLayers.value = $store.state.simulationSetup.gui.layers.length
-        },
-        { deep: true }
-    )
-
-    watch(layers,
-        ()=>{
-          const storeLayers = $store.state.simulationSetup.gui.layers
-          let safeFromWL = 0
-          let safeToWL = 1e300
-          for (let i = 0; i<layers.length && i<storeLayers.length; i++) {
-            if (isAlmostSame(storeLayers[i].layerWidth, layers[i].layerWidth)) {
-              layers[i].layerWidth = storeLayers[i].layerWidth
-            }
-            let layerFromWL = layers[i].material.spectrumRangeStart
-            let layerToWL = layers[i].material.spectrumRangeEnd
-            if (layerFromWL && layerFromWL > safeFromWL) safeFromWL = layerFromWL
-            if (layerToWL && layerToWL < safeToWL) safeToWL = layerToWL
-
-
+        );
+        numberOfLayers.value = $store.state.simulationSetup.gui.layers.length;
+      },
+      { deep: true }
+    );
+
+    watch(
+      layers,
+      () => {
+        const storeLayers = $store.state.simulationSetup.gui.layers;
+        let safeFromWL = 0;
+        let safeToWL = 1e300;
+        for (let i = 0; i < layers.length && i < storeLayers.length; i++) {
+          if (isAlmostSame(storeLayers[i].layerWidth, layers[i].layerWidth)) {
+            layers[i].layerWidth = storeLayers[i].layerWidth;
           }
-          $store.commit('simulationSetup/setLayers', layers)
-          $store.commit('guiRuntime/setSafeWL', {safeFromWL:safeFromWL, safeToWL:safeToWL})
-        },
-        { deep: true }
-    )
-
-    watch(particleType, ()=>{
-      if (particleType.value=='bulk') numberOfLayers.value = 1
-      if (particleType.value=='core-shell') numberOfLayers.value = 2
-      if (particleType.value=='multilayer') numberOfLayers.value = 3
-    })
-
-    watch(numberOfLayers, ()=>{
-      numberOfLayers.value = parseInt(numberOfLayers.value.toString())
-      if (isNaN(numberOfLayers.value)) return
-      if (numberOfLayers.value < 1) numberOfLayers.value = 1
-      if (numberOfLayers.value > maxNumberOfLayers) numberOfLayers.value = maxNumberOfLayers
+          let layerFromWL = layers[i].material.spectrumRangeStart;
+          let layerToWL = layers[i].material.spectrumRangeEnd;
+          if (layerFromWL && layerFromWL > safeFromWL) safeFromWL = layerFromWL;
+          if (layerToWL && layerToWL < safeToWL) safeToWL = layerToWL;
+        }
+        $store.commit('simulationSetup/setLayers', layers);
+        $store.commit('guiRuntime/setSafeWL', {
+          safeFromWL: safeFromWL,
+          safeToWL: safeToWL,
+        });
+      },
+      { deep: true }
+    );
+
+    watch(particleType, () => {
+      if (particleType.value == 'bulk') numberOfLayers.value = 1;
+      if (particleType.value == 'core-shell') numberOfLayers.value = 2;
+      if (particleType.value == 'multilayer') numberOfLayers.value = 3;
+    });
+
+    watch(numberOfLayers, () => {
+      numberOfLayers.value = parseInt(numberOfLayers.value.toString());
+      if (isNaN(numberOfLayers.value)) return;
+      if (numberOfLayers.value < 1) numberOfLayers.value = 1;
+      if (numberOfLayers.value > maxNumberOfLayers)
+        numberOfLayers.value = maxNumberOfLayers;
 
       while (layers.length > numberOfLayers.value) {
         layers.pop();
@@ -279,38 +334,46 @@ export default defineComponent({
       let coreR = layers[0].layerWidth;
       while (layers.length < numberOfLayers.value) {
         // r_prev = r_prev*1.1;
-        layers.push(
-            {
-              layerWidth: coreR*0.1,
-              material: $store.state.guiRuntime.activatedMaterials[1], //nk-constant
-              n: 4.0,
-              k: 0.01,
-            }
-        );
+        layers.push({
+          layerWidth: coreR * 0.1,
+          material: $store.state.guiRuntime.activatedMaterials[1], //nk-constant
+          n: 4.0,
+          k: 0.01,
+        });
       }
-    })
-
-    function getLayerTitle (particleType:string, index:number) {
-      if (particleType=='core-shell'  && index == 0) return 'core'
-      if (particleType=='core-shell'  && index == 1) return 'shell'
-      if (particleType=='multilayer') return 'layer '+ (index+1).toString()
-      return 'bulk'
+    });
+
+    function getLayerTitle(particleType: string, index: number) {
+      if (particleType == 'core-shell' && index == 0) return 'core';
+      if (particleType == 'core-shell' && index == 1) return 'shell';
+      if (particleType == 'multilayer')
+        return 'layer ' + (index + 1).toString();
+      return 'bulk';
     }
 
-    function getTooltipText(index:number) {
-      if (index == 0) return 'radius'
-      return 'thickness'
-
+    function getTooltipText(index: number) {
+      if (index == 0) return 'radius';
+      return 'thickness';
     }
 
-    return { flexRowTitleStyle, basicWidthStyle,
-      basicSelectorWidthStyle, maxNumberOfLayers,
-      fromWavelengthStore, toWavelengthStore,
+    return {
+      flexRowTitleStyle,
+      basicWidthStyle,
+      basicSelectorWidthStyle,
+      maxNumberOfLayers,
+      fromWavelengthStore,
+      toWavelengthStore,
       particleType,
-      numberOfLayers, layers, getLayerTitle, getTooltipText,
-      units, toUnits, fromUnits, isShowingHelpForInputWithUnits,
-      activatedMaterials
-      }
+      numberOfLayers,
+      layers,
+      getLayerTitle,
+      getTooltipText,
+      units,
+      toUnits,
+      fromUnits,
+      isShowingHelpForInputWithUnits,
+      activatedMaterials,
+    };
   },
-})
+});
 </script>

+ 45 - 40
guiapp/src/components/spectrum/GetPlotSettings.vue

@@ -8,14 +8,17 @@
     <div class="col-xs-grow col-sm q-px-xs">
       <div class="row justify-xs-center justify-sm-start items-center">
         <div class="col-auto">
-          <q-input  v-model="plotLabel"
-                    :shadow-text="plotLabel=='' ? shadowText+' (Tab to complete)' : ''"
-                    outlined
-                    dense
-                    class="q-py-xs"
-                    :style="'width: '+basicWidthStyle"
-                    @keydown="processInputFill"
-                    @focus="processInputFill"
+          <q-input
+            v-model="plotLabel"
+            :shadow-text="
+              plotLabel == '' ? shadowText + ' (Tab to complete)' : ''
+            "
+            outlined
+            dense
+            class="q-py-xs"
+            :style="'width: ' + basicWidthStyle"
+            @keydown="processInputFill"
+            @focus="processInputFill"
           />
         </div>
       </div>
@@ -24,56 +27,58 @@
 </template>
 
 <script lang="ts">
-import {
-  defineComponent,
-  computed,
-  } from 'vue'
-import { event } from 'quasar'
-const { stopAndPrevent } = event
+import { defineComponent, computed } from 'vue';
+import { event } from 'quasar';
+const { stopAndPrevent } = event;
 
-import { useStore } from 'src/store'
-import { flexRowTitleStyle,
+import { useStore } from 'src/store';
+import {
+  flexRowTitleStyle,
   basicSelectorWidthStyle,
-    basicWidthStyle
-} from 'components/config'
+  basicWidthStyle,
+} from 'components/config';
 
 export default defineComponent({
   name: 'GetPlotSettings',
 
   setup() {
-    const $store = useStore()
+    const $store = useStore();
 
     const plotLabel = computed({
-      get: ()=> $store.state.simulationSetup.gui.plotLabel,
-      set: val => $store.commit('simulationSetup/setPlotLabel', val)
-    })
+      get: () => $store.state.simulationSetup.gui.plotLabel,
+      set: (val) => $store.commit('simulationSetup/setPlotLabel', val),
+    });
 
-    const shadowText = computed(()=>{
-      const numberOfLayers = $store.state.simulationSetup.gui.layers.length
-      let particleType = 'bulk'
-      if (numberOfLayers == 2) return 'core-shell'
-      if (numberOfLayers > 2) return 'multilayer'
-      const R = $store.state.simulationSetup.gui.layers[0].layerWidth.toString()
-      const units = $store.state.guiRuntime.units
-      return particleType+' R='+R+units
-    })
+    const shadowText = computed(() => {
+      const numberOfLayers = $store.state.simulationSetup.gui.layers.length;
+      let particleType = 'bulk';
+      if (numberOfLayers == 2) return 'core-shell';
+      if (numberOfLayers > 2) return 'multilayer';
+      const R =
+        $store.state.simulationSetup.gui.layers[0].layerWidth.toString();
+      const units = $store.state.guiRuntime.units;
+      return particleType + ' R=' + R + units;
+    });
 
-    return { flexRowTitleStyle, basicSelectorWidthStyle, basicWidthStyle,
-      plotLabel, shadowText,
+    return {
+      flexRowTitleStyle,
+      basicSelectorWidthStyle,
+      basicWidthStyle,
+      plotLabel,
+      shadowText,
 
-      processInputFill (e:KeyboardEvent) {
+      processInputFill(e: KeyboardEvent) {
         if (e === void 0) {
-          return
+          return;
         }
         if (e.code === 'Tab') {
           if (shadowText.value.length > 0 && plotLabel.value == '') {
-            stopAndPrevent(e)
-            plotLabel.value = shadowText.value
+            stopAndPrevent(e);
+            plotLabel.value = shadowText.value;
           }
         }
       },
-
-    }
+    };
   },
-})
+});
 </script>

+ 119 - 84
guiapp/src/components/spectrum/GetSourceParameters.vue

@@ -1,36 +1,37 @@
 <template>
   <div class="row items-baseline">
-
-    <div class="col-xs-12 col-sm-auto text-weight-bold text-center q-px-md q-py-sm">
-      <q-tooltip v-if="isInfoMode"
-                 anchor="top middle"
-                 self="center middle"
-      >
-        current  source settings<br>
+    <div
+      class="col-xs-12 col-sm-auto text-weight-bold text-center q-px-md q-py-sm"
+    >
+      <q-tooltip v-if="isInfoMode" anchor="top middle" self="center middle">
+        current source settings<br />
       </q-tooltip>
-      <div :style="flexRowTitleStyle"> {{rowTitle}} </div>
+      <div :style="flexRowTitleStyle">{{ rowTitle }}</div>
     </div>
     <div class="col-xs-grow col-sm">
       <div class="row justify-xs-center justify-sm-start items-baseline">
-
-        <div class="col-auto"><input-with-units
+        <div class="col-auto">
+          <input-with-units
             v-model:input-result="fromSource"
             v-model:is-showing-help="isShowingHelpForInputWithUnits"
             :initial-expression="fromSource.toString()"
             :units="sourceUnits"
             :is-info-mode="isInfoMode"
-            :is-error="fromSource<$store.state.guiRuntime.safeFromWL"
+            :is-error="fromSource < $store.state.guiRuntime.safeFromWL"
             title="from"
-        /></div>
-        <div class="col-auto"><input-with-units
+          />
+        </div>
+        <div class="col-auto">
+          <input-with-units
             v-model:input-result="toSource"
             v-model:is-showing-help="isShowingHelpForInputWithUnits"
             :initial-expression="toSource.toString()"
             :units="sourceUnits"
             :is-info-mode="isInfoMode"
-            :is-error="toSource>$store.state.guiRuntime.safeToWL"
+            :is-error="toSource > $store.state.guiRuntime.safeToWL"
             title="to"
-        /></div>
+          />
+        </div>
         <div v-if="!isInfoMode" class="col-auto">
           <input-with-units
             v-model:input-result="pointsSource"
@@ -39,118 +40,152 @@
             :title="isPointsToggle ? `points` : `step`"
             :units="isPointsToggle ? `` : sourceUnits"
           />
-          <q-toggle v-model="isPointsToggle" dense class="q-ml-md"/>
+          <q-toggle v-model="isPointsToggle" dense class="q-ml-md" />
         </div>
-
       </div>
     </div>
   </div>
 </template>
 
 <script lang="ts">
-import {
-  defineComponent,
-  computed,
-  ref
-  } from 'vue'
-import { useStore } from 'src/store'
-import InputWithUnits from 'components/InputWithUnits.vue'
-import { fromUnits, toUnits, isAlmostSame } from 'components/utils'
-import { flexRowTitleStyle } from 'components/config'
+import { defineComponent, computed, ref } from 'vue';
+import { useStore } from 'src/store';
+import InputWithUnits from 'components/InputWithUnits.vue';
+import { fromUnits, toUnits, isAlmostSame } from 'components/utils';
+import { flexRowTitleStyle } from 'components/config';
 
 export default defineComponent({
-
   name: 'GetSourceParameters',
-  components: {InputWithUnits,},
+  components: { InputWithUnits },
   props: {
     isInfoMode: {
       type: Boolean,
-      default: false
+      default: false,
     },
   },
 
   setup() {
-    const isPointsToggle = ref(true)
+    const isPointsToggle = ref(true);
 
-    const $store = useStore()
+    const $store = useStore();
 
     const isShowingHelpForInputWithUnits = computed({
       get: () => $store.state.guiRuntime.isShowingHelpForInputWithUnits,
-      set: val => $store.commit('guiRuntime/setIsShowingHelpForInputWithUnits', val)
-    })
+      set: (val) =>
+        $store.commit('guiRuntime/setIsShowingHelpForInputWithUnits', val),
+    });
 
-    const sourceUnits = computed(()=>{
-      return $store.state.guiRuntime.sourceUnits
-    })
+    const sourceUnits = computed(() => {
+      return $store.state.guiRuntime.sourceUnits;
+    });
 
     const fromWavelengthInSourceUnits = computed({
-      get: () => toUnits($store.state.simulationSetup.gui.fromWL, sourceUnits.value),
-      set: val => {
-        if (!isAlmostSame($store.state.simulationSetup.gui.fromWL, fromUnits(sourceUnits.value, val))) {
-          $store.commit('simulationSetup/setFromWL', fromUnits(sourceUnits.value, val))
+      get: () =>
+        toUnits($store.state.simulationSetup.gui.fromWL, sourceUnits.value),
+      set: (val) => {
+        if (
+          !isAlmostSame(
+            $store.state.simulationSetup.gui.fromWL,
+            fromUnits(sourceUnits.value, val)
+          )
+        ) {
+          $store.commit(
+            'simulationSetup/setFromWL',
+            fromUnits(sourceUnits.value, val)
+          );
         }
-      }
-    })
+      },
+    });
 
     const toWavelengthInSourceUnits = computed({
-      get: () => toUnits($store.state.simulationSetup.gui.toWL, sourceUnits.value),
-      set: val => {
-        if (!isAlmostSame($store.state.simulationSetup.gui.toWL, fromUnits(sourceUnits.value, val))) {
-          $store.commit('simulationSetup/setToWL', fromUnits(sourceUnits.value, val))
+      get: () =>
+        toUnits($store.state.simulationSetup.gui.toWL, sourceUnits.value),
+      set: (val) => {
+        if (
+          !isAlmostSame(
+            $store.state.simulationSetup.gui.toWL,
+            fromUnits(sourceUnits.value, val)
+          )
+        ) {
+          $store.commit(
+            'simulationSetup/setToWL',
+            fromUnits(sourceUnits.value, val)
+          );
         }
-      }
-    })
+      },
+    });
 
-    const rowTitle = computed(()=>{
-      if (sourceUnits.value.endsWith('Hz')) {return 'Frequency'}
-      if (sourceUnits.value.endsWith('eV')) {return 'Energy'}
-      if (sourceUnits.value.endsWith('s')) {return 'Period'}
-      return 'Wavelength'
-    })
+    const rowTitle = computed(() => {
+      if (sourceUnits.value.endsWith('Hz')) {
+        return 'Frequency';
+      }
+      if (sourceUnits.value.endsWith('eV')) {
+        return 'Energy';
+      }
+      if (sourceUnits.value.endsWith('s')) {
+        return 'Period';
+      }
+      return 'Wavelength';
+    });
 
-    const directOrder = computed(()=>{
-      if (['Frequency','Energy'].includes(rowTitle.value)) return false
-      return true
-    })
+    const directOrder = computed(() => {
+      if (['Frequency', 'Energy'].includes(rowTitle.value)) return false;
+      return true;
+    });
 
     const fromSource = computed({
       get: () => {
-        if (directOrder.value) return fromWavelengthInSourceUnits.value
-        return toWavelengthInSourceUnits.value
+        if (directOrder.value) return fromWavelengthInSourceUnits.value;
+        return toWavelengthInSourceUnits.value;
       },
-      set: val => {
-        if (directOrder.value) fromWavelengthInSourceUnits.value = val
-        else toWavelengthInSourceUnits.value = val
-      }
-    })
+      set: (val) => {
+        if (directOrder.value) fromWavelengthInSourceUnits.value = val;
+        else toWavelengthInSourceUnits.value = val;
+      },
+    });
 
     const toSource = computed({
       get: () => {
-        if (!directOrder.value) return fromWavelengthInSourceUnits.value
-        return toWavelengthInSourceUnits.value
+        if (!directOrder.value) return fromWavelengthInSourceUnits.value;
+        return toWavelengthInSourceUnits.value;
       },
-      set: val => {
-        if (!directOrder.value) fromWavelengthInSourceUnits.value = val
-        else toWavelengthInSourceUnits.value = val
-      }
-    })
+      set: (val) => {
+        if (!directOrder.value) fromWavelengthInSourceUnits.value = val;
+        else toWavelengthInSourceUnits.value = val;
+      },
+    });
 
     const pointsSource = computed({
       get: () => {
-        if (isPointsToggle.value) return $store.state.simulationSetup.gui.pointsWL
-        return (toSource.value-fromSource.value)/($store.state.simulationSetup.gui.pointsWL-1)
+        if (isPointsToggle.value)
+          return $store.state.simulationSetup.gui.pointsWL;
+        return (
+          (toSource.value - fromSource.value) /
+          ($store.state.simulationSetup.gui.pointsWL - 1)
+        );
       },
-      set: val => {
-        if (isPointsToggle.value) $store.commit('simulationSetup/setPointsWL', val)
+      set: (val) => {
+        if (isPointsToggle.value)
+          $store.commit('simulationSetup/setPointsWL', val);
         else {
-          $store.commit('simulationSetup/setPointsWL', 1+(toSource.value-fromSource.value)/val)
+          $store.commit(
+            'simulationSetup/setPointsWL',
+            1 + (toSource.value - fromSource.value) / val
+          );
         }
-      }
-    })
-
-    return { fromSource, toSource, pointsSource, isShowingHelpForInputWithUnits,
-      flexRowTitleStyle, rowTitle,
-      sourceUnits, isPointsToggle,  }
+      },
+    });
+
+    return {
+      fromSource,
+      toSource,
+      pointsSource,
+      isShowingHelpForInputWithUnits,
+      flexRowTitleStyle,
+      rowTitle,
+      sourceUnits,
+      isPointsToggle,
+    };
   },
-})
+});
 </script>

+ 95 - 81
guiapp/src/components/spectrum/GetUnits.vue

@@ -1,139 +1,153 @@
 <template>
   <div class="row items-baseline">
-    <div class="col-xs-12 col-sm-auto text-weight-bold text-center q-px-md q-py-sm">
-      <div :style="flexRowTitleStyle">
-        Units
-      </div>
+    <div
+      class="col-xs-12 col-sm-auto text-weight-bold text-center q-px-md q-py-sm"
+    >
+      <div :style="flexRowTitleStyle">Units</div>
     </div>
-    <div class="col-xs-grow col-sm  q-px-xs">
+    <div class="col-xs-grow col-sm q-px-xs">
       <div class="row justify-xs-center justify-sm-start items-center">
-
-        <div class="col-auto" >
+        <div class="col-auto">
           <div class="row items-center justify-center">
-            <div class="text-right"> length </div>
-          <q-select
+            <div class="text-right">length</div>
+            <q-select
               v-model="units"
               :options="unitsOptions"
               class="q-pa-xs"
               outlined
               dense
               options-dense
-              :style="'width: '+basicSelectorWidthStyle"
+              :style="'width: ' + basicSelectorWidthStyle"
               behavior="menu"
-          >
-          </q-select>
-            <div/>
+            >
+            </q-select>
+            <div />
           </div>
         </div>
 
-        <div class="col-auto" >
+        <div class="col-auto">
           <div class="row items-center justify-center">
-            <div class="text-right q-pl-md">  plane wave </div>
+            <div class="text-right q-pl-md">plane wave</div>
 
             <q-select
-                v-model="sourceUnits"
-                :options="sourceUnitsOptions"
-                :style="'width: '+basicSelectorWidthStyle"
-                class="q-pa-xs"
-                :disable="isSourceSameUnits"
-                :outlined="!isSourceSameUnits"
-                :filled="isSourceSameUnits"
-                dense
-                options-dense
-                option-value="label"
-                option-label="label"
-                behavior="menu"
+              v-model="sourceUnits"
+              :options="sourceUnitsOptions"
+              :style="'width: ' + basicSelectorWidthStyle"
+              class="q-pa-xs"
+              :disable="isSourceSameUnits"
+              :outlined="!isSourceSameUnits"
+              :filled="isSourceSameUnits"
+              dense
+              options-dense
+              option-value="label"
+              option-label="label"
+              behavior="menu"
             >
               <template #option="scope">
                 <q-item :label="scope.opt.title" dense>
-                  <q-item-section class="text-weight-bold">{{ scope.opt.title }}</q-item-section>
+                  <q-item-section class="text-weight-bold">{{
+                    scope.opt.title
+                  }}</q-item-section>
                 </q-item>
-                <template v-for="child in scope.opt.children" :key="child.label">
-                  <q-item v-close-popup dense clickable
-                          @click="sourceUnits = child"
+                <template
+                  v-for="child in scope.opt.children"
+                  :key="child.label"
+                >
+                  <q-item
+                    v-close-popup
+                    dense
+                    clickable
+                    @click="sourceUnits = child"
                   >
-                    <q-item-section> <q-item-label class="q-ml-md"> {{child.label}} </q-item-label> </q-item-section>
+                    <q-item-section>
+                      <q-item-label class="q-ml-md">
+                        {{ child.label }}
+                      </q-item-label>
+                    </q-item-section>
                   </q-item>
                 </template>
               </template>
             </q-select>
 
-
             <div class="row q-pa-xs items-center">
-              <q-checkbox v-model="isSourceSameUnits" size="sm"/>
+              <q-checkbox v-model="isSourceSameUnits" size="sm" />
               <div>same</div>
             </div>
           </div>
         </div>
 
-<!--        <div class="col-auto" >-->
-<!--          units: {{sourceUnits}}-->
-<!--          <br> store: {{$store.state.guiRuntime}}-->
-<!--        </div>-->
+        <!--        <div class="col-auto" >-->
+        <!--          units: {{sourceUnits}}-->
+        <!--          <br> store: {{$store.state.guiRuntime}}-->
+        <!--        </div>-->
       </div>
     </div>
   </div>
 </template>
 
 <script lang="ts">
-import {
-  defineComponent,
-  computed,
-  watch
-  } from 'vue'
-import { useStore } from 'src/store'
-import { flexRowTitleStyle, basicSelectorWidthStyle } from 'components/config'
+import { defineComponent, computed, watch } from 'vue';
+import { useStore } from 'src/store';
+import { flexRowTitleStyle, basicSelectorWidthStyle } from 'components/config';
 
 export default defineComponent({
-
   name: 'GetUnits',
   components: {},
 
   setup() {
-    const unitsOptions = [ 'nm', 'µm', 'mm', 'cm', 'm']
+    const unitsOptions = ['nm', 'µm', 'mm', 'cm', 'm'];
     const sourceUnitsOptions = [
-      { title: 'Frequency',
-        children: [{label: 'MHz'},{label: 'GHz'},{label: 'THz'}]},
-      { title: 'Energy',
-        children: [{label: 'meV'}, {label: 'eV'}]},
-      { title: 'Period duration',
-        children: [{label: 'ps'}, {label: 'fs'}]}
-    ]
-    const $store = useStore()
+      {
+        title: 'Frequency',
+        children: [{ label: 'MHz' }, { label: 'GHz' }, { label: 'THz' }],
+      },
+      { title: 'Energy', children: [{ label: 'meV' }, { label: 'eV' }] },
+      {
+        title: 'Period duration',
+        children: [{ label: 'ps' }, { label: 'fs' }],
+      },
+    ];
+    const $store = useStore();
 
     const isSourceSameUnits = computed({
       get: () => $store.state.guiRuntime.isSourceSameUnits,
-      set: val => $store.commit('guiRuntime/setIsSourceSameUnits', val)
-    })
-
+      set: (val) => $store.commit('guiRuntime/setIsSourceSameUnits', val),
+    });
 
     const units = computed({
       get: () => $store.state.guiRuntime.units,
-      set: val => $store.commit('guiRuntime/setUnits', val)
-    })
+      set: (val) => $store.commit('guiRuntime/setUnits', val),
+    });
 
     const sourceUnits = computed({
-      get: () => {return {label:$store.state.guiRuntime.sourceUnits}},
-      set: val => $store.commit('guiRuntime/setSourceUnits', val.label)
-    })
-
-    let prevCustomSourceUnits = 'THz'
-    watch(isSourceSameUnits, ()=>{
+      get: () => {
+        return { label: $store.state.guiRuntime.sourceUnits };
+      },
+      set: (val) => $store.commit('guiRuntime/setSourceUnits', val.label),
+    });
+
+    let prevCustomSourceUnits = 'THz';
+    watch(isSourceSameUnits, () => {
       if (isSourceSameUnits.value) {
-        prevCustomSourceUnits = $store.state.guiRuntime.sourceUnits
-        $store.commit('guiRuntime/setSourceUnits',units.value)
-      }
-      else $store.commit('guiRuntime/setSourceUnits',prevCustomSourceUnits)
-    })
-
-    watch(units, ()=>{
-      if (isSourceSameUnits.value) $store.commit('guiRuntime/setSourceUnits',units.value)
-    })
-
-
-    return { isSourceSameUnits, flexRowTitleStyle, basicSelectorWidthStyle,
-      unitsOptions, units,
-      sourceUnits, sourceUnitsOptions }
+        prevCustomSourceUnits = $store.state.guiRuntime.sourceUnits;
+        $store.commit('guiRuntime/setSourceUnits', units.value);
+      } else $store.commit('guiRuntime/setSourceUnits', prevCustomSourceUnits);
+    });
+
+    watch(units, () => {
+      if (isSourceSameUnits.value)
+        $store.commit('guiRuntime/setSourceUnits', units.value);
+    });
+
+    return {
+      isSourceSameUnits,
+      flexRowTitleStyle,
+      basicSelectorWidthStyle,
+      unitsOptions,
+      units,
+      sourceUnits,
+      sourceUnitsOptions,
+    };
   },
-})
+});
 </script>

+ 219 - 158
guiapp/src/components/spectrum/PlotSelector.vue

@@ -14,54 +14,62 @@
   <div class="row items-baseline">
     <div class="col-xs-grow col-sm-auto q-px-sm">
       <q-table
-              title="Values to plot"
-              title-class="text-body1 text-bold"
-              :rows="rowsQ"
-              :columns="columnsQ"
-              hide-bottom
-              dense
-              flat
-              row-key="name"
-          >
-            <template #body="props">
-              <q-tr :props="props">
-                <q-th key="name" :props="props">
-                  {{ props.row.name }}
-                </q-th>
-                <template v-for="(val, index) in props.row" :key="index" :props="props">
-                  <q-td v-if="index!='name'">
-                    <q-checkbox
-                        v-model="props.row[index]"
-                        dense
-                    />
-                  </q-td>
-                </template>
-              </q-tr>
+        title="Values to plot"
+        title-class="text-body1 text-bold"
+        :rows="rowsQ"
+        :columns="columnsQ"
+        hide-bottom
+        dense
+        flat
+        row-key="name"
+      >
+        <template #body="props">
+          <q-tr :props="props">
+            <q-th key="name" :props="props">
+              {{ props.row.name }}
+            </q-th>
+            <template
+              v-for="(val, index) in props.row"
+              :key="index"
+              :props="props"
+            >
+              <q-td v-if="index != 'name'">
+                <q-checkbox v-model="props.row[index]" dense />
+              </q-td>
             </template>
-          </q-table>
+          </q-tr>
+        </template>
+      </q-table>
     </div>
-    <div v-if="isPlotQabs||isPlotQsca||isPlotQext"  class="col-xs-grow col-sm-auto q-px-sm">
+    <div
+      v-if="isPlotQabs || isPlotQsca || isPlotQext"
+      class="col-xs-grow col-sm-auto q-px-sm"
+    >
       <q-table
-          title="Modes to plot"
-          title-class="text-body1 text-bold"
-          :rows="rows"
-          :columns="columns"
-          hide-bottom
-          dense
-          flat
-          row-key="name"
+        title="Modes to plot"
+        title-class="text-body1 text-bold"
+        :rows="rows"
+        :columns="columns"
+        hide-bottom
+        dense
+        flat
+        row-key="name"
       >
         <template #body="props">
           <q-tr :props="props">
             <q-th key="name" :props="props">
               {{ props.row.name }}
             </q-th>
-            <template v-for="(val, index) in props.row" :key="index" :props="props">
-              <q-td v-if="index!='name'">
+            <template
+              v-for="(val, index) in props.row"
+              :key="index"
+              :props="props"
+            >
+              <q-td v-if="index != 'name'">
                 <q-checkbox
-                    v-model="props.row[index.toString()]"
-                    dense
-                    :disable="index>simulatedNumberOfModes"
+                  v-model="props.row[index.toString()]"
+                  dense
+                  :disable="index > simulatedNumberOfModes"
                 />
               </q-td>
             </template>
@@ -73,175 +81,228 @@
 </template>
 
 <script lang="ts">
-import {
-  defineComponent,
-  computed,
-  ref,
-  watch
-  } from 'vue'
-import { useStore } from 'src/store'
-import { cloneDeep } from 'lodash'
-import { getModeName} from 'components/utils'
-import { flexRowTitleStyle,
-} from 'components/config'
-
+import { defineComponent, computed, ref, watch } from 'vue';
+import { useStore } from 'src/store';
+import { cloneDeep } from 'lodash';
+import { getModeName } from 'components/utils';
+import { flexRowTitleStyle } from 'components/config';
 
 export default defineComponent({
   name: 'GetPlotSettings',
 
   setup() {
-    const $store = useStore()
+    const $store = useStore();
 
     const isRemovePlots = computed({
-      get: ()=> $store.state.plotRuntime.isRemovePlots,
-      set: val => {
-        $store.commit('plotRuntime/setIsRemovePlots', val)
-        $store.commit('plotRuntime/updateSpectrumPlots')
-      }
-    })
+      get: () => $store.state.plotRuntime.isRemovePlots,
+      set: (val) => {
+        $store.commit('plotRuntime/setIsRemovePlots', val);
+        $store.commit('plotRuntime/updateSpectrumPlots');
+      },
+    });
 
     const isLogPlot = computed({
-      get: ()=> $store.state.plotRuntime.isLogPlot,
-      set: val => {
-        $store.commit('plotRuntime/setIsLogPlot', val)
-        $store.commit('plotRuntime/updateSpectrumPlots')
-      }
-    })
+      get: () => $store.state.plotRuntime.isLogPlot,
+      set: (val) => {
+        $store.commit('plotRuntime/setIsLogPlot', val);
+        $store.commit('plotRuntime/updateSpectrumPlots');
+      },
+    });
 
     const isPlotQsca = computed({
       get: () => $store.state.plotRuntime.isPlotQsca,
-      set: val => $store.commit('plotRuntime/setQscaPlotToggle', val)
-    })
+      set: (val) => $store.commit('plotRuntime/setQscaPlotToggle', val),
+    });
     const isPlotQabs = computed({
       get: () => $store.state.plotRuntime.isPlotQabs,
-      set: val => $store.commit('plotRuntime/setQabsPlotToggle', val)
-    })
+      set: (val) => $store.commit('plotRuntime/setQabsPlotToggle', val),
+    });
     const isPlotQext = computed({
       get: () => $store.state.plotRuntime.isPlotQext,
-      set: val => $store.commit('plotRuntime/setQextPlotToggle', val)
-    })
+      set: (val) => $store.commit('plotRuntime/setQextPlotToggle', val),
+    });
 
     const isPlotQscaTotal = computed({
       get: () => $store.state.plotRuntime.isPlotQscaTotal,
-      set: val => $store.commit('plotRuntime/setQscaTotalPlotToggle', val)
-    })
+      set: (val) => $store.commit('plotRuntime/setQscaTotalPlotToggle', val),
+    });
     const isPlotQabsTotal = computed({
       get: () => $store.state.plotRuntime.isPlotQabsTotal,
-      set: val => $store.commit('plotRuntime/setQabsTotalPlotToggle', val)
-    })
+      set: (val) => $store.commit('plotRuntime/setQabsTotalPlotToggle', val),
+    });
     const isPlotQextTotal = computed({
       get: () => $store.state.plotRuntime.isPlotQextTotal,
-      set: val => $store.commit('plotRuntime/setQextTotalPlotToggle', val)
-    })
+      set: (val) => $store.commit('plotRuntime/setQextTotalPlotToggle', val),
+    });
 
-    const columnsQ = computed(()=>{
+    const columnsQ = computed(() => {
       return [
-        { name: 'name', label: '',  align: 'left', field: 'name', headerStyle:''},
-        { name: 'Qsca', label: 'Qsca',  align: 'left', field: 'Qsca', headerStyle:''},
-        { name: 'Qabs', label: 'Qabs',  align: 'left', field: 'Qabs', headerStyle:''},
-        { name: 'Qext', label: 'Qext',  align: 'left', field: 'Qext', headerStyle:''},
-      ]
-    })
+        {
+          name: 'name',
+          label: '',
+          align: 'left',
+          field: 'name',
+          headerStyle: '',
+        },
+        {
+          name: 'Qsca',
+          label: 'Qsca',
+          align: 'left',
+          field: 'Qsca',
+          headerStyle: '',
+        },
+        {
+          name: 'Qabs',
+          label: 'Qabs',
+          align: 'left',
+          field: 'Qabs',
+          headerStyle: '',
+        },
+        {
+          name: 'Qext',
+          label: 'Qext',
+          align: 'left',
+          field: 'Qext',
+          headerStyle: '',
+        },
+      ];
+    });
 
     const rowsQ_store = computed({
-    get: ()=>[
-        { name: 'total', Qsca: isPlotQscaTotal.value, Qabs: isPlotQabsTotal.value, Qext: isPlotQextTotal.value},
-        { name: 'modes', Qsca: isPlotQsca.value, Qabs: isPlotQabs.value, Qext: isPlotQext.value},
-    ],
-      set: val =>{
-        $store.commit('plotRuntime/setQscaTotalPlotToggle', val[0].Qsca)
-        $store.commit('plotRuntime/setQabsTotalPlotToggle', val[0].Qabs)
-        $store.commit('plotRuntime/setQextTotalPlotToggle', val[0].Qext)
-        $store.commit('plotRuntime/setQscaPlotToggle', val[1].Qsca)
-        $store.commit('plotRuntime/setQabsPlotToggle', val[1].Qabs)
-        $store.commit('plotRuntime/setQextPlotToggle', val[1].Qext)
-        // console.log(val)
-      }
-    })
-    const rowsQ = ref(rowsQ_store.value)
-    watch(rowsQ_store, ()=>{
-          rowsQ.value = rowsQ_store.value
+      get: () => [
+        {
+          name: 'total',
+          Qsca: isPlotQscaTotal.value,
+          Qabs: isPlotQabsTotal.value,
+          Qext: isPlotQextTotal.value,
         },
-        { deep: true }
-    )
-    watch(rowsQ, ()=>{
-          rowsQ_store.value = rowsQ.value
+        {
+          name: 'modes',
+          Qsca: isPlotQsca.value,
+          Qabs: isPlotQabs.value,
+          Qext: isPlotQext.value,
         },
-        { deep: true }
-    )
+      ],
+      set: (val) => {
+        $store.commit('plotRuntime/setQscaTotalPlotToggle', val[0].Qsca);
+        $store.commit('plotRuntime/setQabsTotalPlotToggle', val[0].Qabs);
+        $store.commit('plotRuntime/setQextTotalPlotToggle', val[0].Qext);
+        $store.commit('plotRuntime/setQscaPlotToggle', val[1].Qsca);
+        $store.commit('plotRuntime/setQabsPlotToggle', val[1].Qabs);
+        $store.commit('plotRuntime/setQextPlotToggle', val[1].Qext);
+        // console.log(val)
+      },
+    });
+    const rowsQ = ref(rowsQ_store.value);
+    watch(
+      rowsQ_store,
+      () => {
+        rowsQ.value = rowsQ_store.value;
+      },
+      { deep: true }
+    );
+    watch(
+      rowsQ,
+      () => {
+        rowsQ_store.value = rowsQ.value;
+      },
+      { deep: true }
+    );
 
-    const guiNumberOfModes = computed(()=> $store.state.simulationSetup.gui.numberOfModesToPlot)
-    const simulatedNumberOfModes = computed(()=> $store.state.simulationSetup.current.numberOfModesToPlot)
+    const guiNumberOfModes = computed(
+      () => $store.state.simulationSetup.gui.numberOfModesToPlot
+    );
+    const simulatedNumberOfModes = computed(
+      () => $store.state.simulationSetup.current.numberOfModesToPlot
+    );
 
-    const columns = computed(()=> {
-      let columns = [{ name: 'name', label: '',  align: 'left', field: '', headerStyle:''}]
-      for (let i=1; i<=guiNumberOfModes.value; ++i) {
-        let label_computed = getModeName(i)
-        let text_color = ''
-        if (i > simulatedNumberOfModes.value ) text_color='color:LightGray'
+    const columns = computed(() => {
+      let columns = [
+        { name: 'name', label: '', align: 'left', field: '', headerStyle: '' },
+      ];
+      for (let i = 1; i <= guiNumberOfModes.value; ++i) {
+        let label_computed = getModeName(i);
+        let text_color = '';
+        if (i > simulatedNumberOfModes.value) text_color = 'color:LightGray';
         columns.push({
           name: i.toString(),
           label: label_computed,
-          align:'left',
+          align: 'left',
           field: i.toString(),
-          headerStyle: text_color
-        })
+          headerStyle: text_color,
+        });
       }
-      return columns
-    })
+      return columns;
+    });
 
-    $store.commit('plotRuntime/resizeSelectorIsPlotMode', guiNumberOfModes.value)
+    $store.commit(
+      'plotRuntime/resizeSelectorIsPlotMode',
+      guiNumberOfModes.value
+    );
 
     const rows_store = computed({
-      get: ()=> {
-        let rows = []
-        let rowE = {name: 'E'}
-        let rowH = {name: 'H'}
+      get: () => {
+        let rows = [];
+        let rowE = { name: 'E' };
+        let rowH = { name: 'H' };
         for (let i = 0; i < guiNumberOfModes.value; ++i) {
           // eslint-disable-next-line
-          (rowE as any)[(i+1).toString()] = $store.state.plotRuntime.isPlotModeE[i];
+          (rowE as any)[(i + 1).toString()] =
+            $store.state.plotRuntime.isPlotModeE[i];
           // eslint-disable-next-line
-          (rowH as any)[(i+1).toString()] = $store.state.plotRuntime.isPlotModeH[i]
+          (rowH as any)[(i + 1).toString()] =
+            $store.state.plotRuntime.isPlotModeH[i];
         }
-        rows.push(cloneDeep(rowE))
-        rows.push(cloneDeep(rowH))
-        return rows
+        rows.push(cloneDeep(rowE));
+        rows.push(cloneDeep(rowH));
+        return rows;
       },
-      set: val => {
-        let isPlotModeE: boolean[] = []
-        let isPlotModeH: boolean[] = []
-        const rowE = val[0]
-        const rowH = val[1]
+      set: (val) => {
+        let isPlotModeE: boolean[] = [];
+        let isPlotModeH: boolean[] = [];
+        const rowE = val[0];
+        const rowH = val[1];
         for (let i = 0; i < guiNumberOfModes.value; ++i) {
           // eslint-disable-next-line
-          isPlotModeE.push((rowE as any)[(i+1).toString()])
+          isPlotModeE.push((rowE as any)[(i + 1).toString()]);
           // eslint-disable-next-line
-          isPlotModeH.push((rowH as any)[(i+1).toString()])
-        }
-        $store.commit('plotRuntime/setIsPlotModeE', isPlotModeE)
-        $store.commit('plotRuntime/setIsPlotModeH', isPlotModeH)
+          isPlotModeH.push((rowH as any)[(i + 1).toString()]);
         }
-    })
+        $store.commit('plotRuntime/setIsPlotModeE', isPlotModeE);
+        $store.commit('plotRuntime/setIsPlotModeH', isPlotModeH);
+      },
+    });
 
-    const rows = ref(rows_store.value)
-    watch(rows_store, ()=>{
-      rows.value = rows_store.value
-        },
-        { deep: true }
-    )
-    watch(rows, ()=>{
-      rows_store.value = rows.value
-        },
-        { deep: true }
-    )
+    const rows = ref(rows_store.value);
+    watch(
+      rows_store,
+      () => {
+        rows.value = rows_store.value;
+      },
+      { deep: true }
+    );
+    watch(
+      rows,
+      () => {
+        rows_store.value = rows.value;
+      },
+      { deep: true }
+    );
 
-    return {flexRowTitleStyle,
-      isRemovePlots, isLogPlot,
-      isPlotQsca, isPlotQabs, isPlotQext,
-      guiNumberOfModes, simulatedNumberOfModes,
-      columns, rows,
-      columnsQ, rowsQ
-      }
+    return {
+      flexRowTitleStyle,
+      isRemovePlots,
+      isLogPlot,
+      isPlotQsca,
+      isPlotQabs,
+      isPlotQext,
+      guiNumberOfModes,
+      simulatedNumberOfModes,
+      columns,
+      rows,
+      columnsQ,
+      rowsQ,
+    };
   },
-})
+});
 </script>

+ 54 - 42
guiapp/src/components/spectrum/PlotSpectra.vue

@@ -1,69 +1,81 @@
 <template>
   <div>
-    <ReactiveChart :chart="$store.state.plotRuntime.spectrumPlots"/>
+    <ReactiveChart :chart="$store.state.plotRuntime.spectrumPlots" />
   </div>
 </template>
 
 <script>
-import ReactiveChart from 'components/ReactiveChart.vue'
-import { useStore } from 'src/store'
-import {
-  defineComponent,
-  computed,
-  watch
-} from 'vue'
+import ReactiveChart from 'components/ReactiveChart.vue';
+import { useStore } from 'src/store';
+import { defineComponent, computed, watch } from 'vue';
 
 export default defineComponent({
   name: 'PlotSpectra',
   components: {
     ReactiveChart,
   },
-  setup () {
-    const $store = useStore()
-    const isPlotQsca = computed( ()=>$store.state.plotRuntime.isPlotQsca)
-    watch(isPlotQsca, ()=>$store.commit('plotRuntime/updateSpectrumPlots'))
-    const isPlotQabs = computed( ()=>$store.state.plotRuntime.isPlotQabs)
-    watch(isPlotQabs, ()=>$store.commit('plotRuntime/updateSpectrumPlots'))
-    const isPlotQext = computed( ()=>$store.state.plotRuntime.isPlotQext)
-    watch(isPlotQext, ()=>$store.commit('plotRuntime/updateSpectrumPlots'))
+  setup() {
+    const $store = useStore();
+    const isPlotQsca = computed(() => $store.state.plotRuntime.isPlotQsca);
+    watch(isPlotQsca, () => $store.commit('plotRuntime/updateSpectrumPlots'));
+    const isPlotQabs = computed(() => $store.state.plotRuntime.isPlotQabs);
+    watch(isPlotQabs, () => $store.commit('plotRuntime/updateSpectrumPlots'));
+    const isPlotQext = computed(() => $store.state.plotRuntime.isPlotQext);
+    watch(isPlotQext, () => $store.commit('plotRuntime/updateSpectrumPlots'));
 
-    const isPlotQscaTotal = computed( ()=>$store.state.plotRuntime.isPlotQscaTotal)
-    watch(isPlotQscaTotal, ()=>$store.commit('plotRuntime/updateSpectrumPlots'))
-    const isPlotQabsTotal = computed( ()=>$store.state.plotRuntime.isPlotQabsTotal)
-    watch(isPlotQabsTotal, ()=>$store.commit('plotRuntime/updateSpectrumPlots'))
-    const isPlotQextTotal = computed( ()=>$store.state.plotRuntime.isPlotQextTotal)
-    watch(isPlotQextTotal, ()=>$store.commit('plotRuntime/updateSpectrumPlots'))
+    const isPlotQscaTotal = computed(
+      () => $store.state.plotRuntime.isPlotQscaTotal
+    );
+    watch(isPlotQscaTotal, () =>
+      $store.commit('plotRuntime/updateSpectrumPlots')
+    );
+    const isPlotQabsTotal = computed(
+      () => $store.state.plotRuntime.isPlotQabsTotal
+    );
+    watch(isPlotQabsTotal, () =>
+      $store.commit('plotRuntime/updateSpectrumPlots')
+    );
+    const isPlotQextTotal = computed(
+      () => $store.state.plotRuntime.isPlotQextTotal
+    );
+    watch(isPlotQextTotal, () =>
+      $store.commit('plotRuntime/updateSpectrumPlots')
+    );
 
-    const isPlotModeE = computed( ()=>$store.state.plotRuntime.isPlotModeE)
-    watch(isPlotModeE, ()=>$store.commit('plotRuntime/updateSpectrumPlots'), { deep: true })
-    const isPlotModeH = computed( ()=>$store.state.plotRuntime.isPlotModeH)
-    watch(isPlotModeH, ()=>$store.commit('plotRuntime/updateSpectrumPlots'), { deep: true })
+    const isPlotModeE = computed(() => $store.state.plotRuntime.isPlotModeE);
+    watch(isPlotModeE, () => $store.commit('plotRuntime/updateSpectrumPlots'), {
+      deep: true,
+    });
+    const isPlotModeH = computed(() => $store.state.plotRuntime.isPlotModeH);
+    watch(isPlotModeH, () => $store.commit('plotRuntime/updateSpectrumPlots'), {
+      deep: true,
+    });
 
-    const sourceUnits = computed( ()=>$store.state.guiRuntime.sourceUnits)
+    const sourceUnits = computed(() => $store.state.guiRuntime.sourceUnits);
     function setPlotTitle() {
-      let title=''
+      let title = '';
       if (sourceUnits.value.endsWith('Hz')) {
-        title = 'Frequency [' + sourceUnits.value + ']'
+        title = 'Frequency [' + sourceUnits.value + ']';
       } else if (sourceUnits.value.endsWith('eV')) {
-        title = 'Energy [' + sourceUnits.value + ']'
+        title = 'Energy [' + sourceUnits.value + ']';
       } else if (sourceUnits.value.endsWith('s')) {
-        title = 'Period [' + sourceUnits.value + ']'
+        title = 'Period [' + sourceUnits.value + ']';
       } else {
-        title = 'Wavelength [' + sourceUnits.value + ']'
+        title = 'Wavelength [' + sourceUnits.value + ']';
       }
-      $store.commit('plotRuntime/updateXAxisTitle', title)
+      $store.commit('plotRuntime/updateXAxisTitle', title);
     }
 
-    function updateSpectraPlotsUnits(){
-      setPlotTitle()
-      $store.commit('plotRuntime/setWLsInUnits', sourceUnits.value)
-      $store.commit('plotRuntime/updateSpectrumPlots')
+    function updateSpectraPlotsUnits() {
+      setPlotTitle();
+      $store.commit('plotRuntime/setWLsInUnits', sourceUnits.value);
+      $store.commit('plotRuntime/updateSpectrumPlots');
     }
 
-    updateSpectraPlotsUnits()
-    watch(sourceUnits, ()=> updateSpectraPlotsUnits())
+    updateSpectraPlotsUnits();
+    watch(sourceUnits, () => updateSpectraPlotsUnits());
 
-    return {}
-  }
-})
+    return {};
+  },
+});
 </script>

+ 246 - 187
guiapp/src/components/spectrum/RunSimulationSpectrum.vue

@@ -1,101 +1,112 @@
 <template>
   <div class="row items-baseline">
-    <div class="col-xs-12 col-sm-auto text-weight-bold text-center q-px-md q-py-sm">
+    <div
+      class="col-xs-12 col-sm-auto text-weight-bold text-center q-px-md q-py-sm"
+    >
       <q-tooltip
-          v-if=" $store.state.guiRuntime.safeFromWL > $store.state.simulationSetup.gui.fromWL ||
-                 $store.state.guiRuntime.safeToWL < $store.state.simulationSetup.gui.toWL "
-          anchor="top middle" self="center middle"
-          class="bg-amber-4 text-black shadow-4">
-        Will use materials<br> spectrum range.
+        v-if="
+          $store.state.guiRuntime.safeFromWL >
+            $store.state.simulationSetup.gui.fromWL ||
+          $store.state.guiRuntime.safeToWL <
+            $store.state.simulationSetup.gui.toWL
+        "
+        anchor="top middle"
+        self="center middle"
+        class="bg-amber-4 text-black shadow-4"
+      >
+        Will use materials<br />
+        spectrum range.
       </q-tooltip>
-        <q-btn :loading="isRunning"
-               :disable="isRunning||!isNmieLoaded"
-               color="primary"
-               no-caps
-               :label="isNmieLoaded ? 'Run simulation' : 'Loading...'"
-               @click="runSpectrumSimulation">
-          <template #loading>
-            <q-spinner-gears />
-          </template>
-        </q-btn>
+      <q-btn
+        :loading="isRunning"
+        :disable="isRunning || !isNmieLoaded"
+        color="primary"
+        no-caps
+        :label="isNmieLoaded ? 'Run simulation' : 'Loading...'"
+        @click="runSpectrumSimulation"
+      >
+        <template #loading>
+          <q-spinner-gears />
+        </template>
+      </q-btn>
     </div>
     <div class="col-xs-grow col-sm q-px-xs">
       <div class="row justify-xs-center justify-sm-start items-baseline">
-
         <div class="col-auto">
-          <q-btn
-              color="primary"
-              no-caps
-              @click="saveSpectrumSimulation"
-          >Save</q-btn>
+          <q-btn color="primary" no-caps @click="saveSpectrumSimulation"
+            >Save</q-btn
+          >
         </div>
-
       </div>
     </div>
   </div>
 </template>
 
 <script lang="ts">
-import {
-  defineComponent,
-  computed, watch,
-    onActivated,
-    nextTick
-} from 'vue'
-import { useStore } from 'src/store'
-import { getModeName, range, rangeInt} from 'components/utils'
-import { cloneDeep } from 'lodash'
-import { saveAs } from 'file-saver'
+import { defineComponent, computed, watch, onActivated, nextTick } from 'vue';
+import { useStore } from 'src/store';
+import { getModeName, range, rangeInt } from 'components/utils';
+import { cloneDeep } from 'lodash';
+import { saveAs } from 'file-saver';
 
 export default defineComponent({
   name: 'RunSimulationSpectrum',
 
   setup() {
-    const $store = useStore()
+    const $store = useStore();
 
     const isRunning = computed({
-      get: ()=> $store.state.simulationSetup.nmies.spectrum.isNmieRunning,
-      set: val => {
-        val ? $store.commit('simulationSetup/markNmieAsStarted') : $store.commit('simulationSetup/markNmieAsFinished')
-      }
-    })
+      get: () => $store.state.simulationSetup.nmies.spectrum.isNmieRunning,
+      set: (val) => {
+        val
+          ? $store.commit('simulationSetup/markNmieAsStarted')
+          : $store.commit('simulationSetup/markNmieAsFinished');
+      },
+    });
 
-    const isNmieLoaded = computed(()=>{ return $store.state.simulationSetup.nmies.spectrum.instance })
+    const isNmieLoaded = computed(() => {
+      return $store.state.simulationSetup.nmies.spectrum.instance;
+    });
 
-    const sourceUnits = computed( ()=>$store.state.guiRuntime.sourceUnits)
+    const sourceUnits = computed(() => $store.state.guiRuntime.sourceUnits);
 
-    function getWLs(safeFromWL:number, safeToWL:number){
-      let fromWL = $store.state.simulationSetup.current.fromWL
-      let toWL = $store.state.simulationSetup.current.toWL
-      if (fromWL < safeFromWL) fromWL=safeFromWL
-      if (toWL > safeToWL) toWL=safeToWL
-      const pointsWL = $store.state.simulationSetup.current.pointsWL
-      if (sourceUnits.value.endsWith('Hz') || sourceUnits.value.endsWith('eV')) {
-        const fromF = 1./fromWL
-        const toF = 1./toWL
-        const stepF = (fromF-toF)/(pointsWL-1)
+    function getWLs(safeFromWL: number, safeToWL: number) {
+      let fromWL = $store.state.simulationSetup.current.fromWL;
+      let toWL = $store.state.simulationSetup.current.toWL;
+      if (fromWL < safeFromWL) fromWL = safeFromWL;
+      if (toWL > safeToWL) toWL = safeToWL;
+      const pointsWL = $store.state.simulationSetup.current.pointsWL;
+      if (
+        sourceUnits.value.endsWith('Hz') ||
+        sourceUnits.value.endsWith('eV')
+      ) {
+        const fromF = 1 / fromWL;
+        const toF = 1 / toWL;
+        const stepF = (fromF - toF) / (pointsWL - 1);
         const Fs = range(toF, fromF, stepF);
-        let WLs = []
-        for (const f of Fs) WLs.push(1./f)
-        return WLs
+        let WLs = [];
+        for (const f of Fs) WLs.push(1 / f);
+        return WLs;
       }
-      const stepWL = (toWL-fromWL)/(pointsWL-1)
-      return range(fromWL, toWL, stepWL)
+      const stepWL = (toWL - fromWL) / (pointsWL - 1);
+      return range(fromWL, toWL, stepWL);
     }
 
-    function initQ(mode_n:number[], mode_types:number[]) {
-      let Qsca:number[] = [], Qabs:number[] = [], Qext:number[] = []
-      let Qsca_n:number[][][] = [[], []]
-      let Qabs_n:number[][][] = [[], []]
-      let Qext_n:number[][][] = [[], []]
+    function initQ(mode_n: number[], mode_types: number[]) {
+      let Qsca: number[] = [],
+        Qabs: number[] = [],
+        Qext: number[] = [];
+      let Qsca_n: number[][][] = [[], []];
+      let Qabs_n: number[][][] = [[], []];
+      let Qext_n: number[][][] = [[], []];
       mode_types.forEach(function (mode_type) {
         mode_n.forEach(function () {
-          Qsca_n[mode_type].push([])
-          Qabs_n[mode_type].push([])
-          Qext_n[mode_type].push([])
-        })
-      })
-      return {Qsca, Qabs, Qext, Qsca_n, Qabs_n, Qext_n}
+          Qsca_n[mode_type].push([]);
+          Qabs_n[mode_type].push([]);
+          Qext_n[mode_type].push([]);
+        });
+      });
+      return { Qsca, Qabs, Qext, Qsca_n, Qabs_n, Qext_n };
     }
 
     //-------------------------------------------------------------------------//
@@ -103,162 +114,210 @@ export default defineComponent({
     //-------------------------------------------------------------------------//
     function runSpectrumSimulation() {
       if (isRunning.value) {
-        console.log('Some Nmie is already running!')
-        return
+        console.log('Some Nmie is already running!');
+        return;
       }
-      isRunning.value = true
-      setTimeout(()=>{
-      void nextTick(()=> {
-        $store.commit('simulationSetup/copySetupFromGuiToCurrent')
+      isRunning.value = true;
+      setTimeout(() => {
+        void nextTick(() => {
+          $store.commit('simulationSetup/copySetupFromGuiToCurrent');
 
-        const host = $store.state.simulationSetup.current.hostIndex
-        const safeFromWL = $store.state.guiRuntime.safeFromWL
-        const safeToWL = $store.state.guiRuntime.safeToWL
-        const WLs = getWLs(safeFromWL, safeToWL)
-        const mode_n = rangeInt($store.state.simulationSetup.current.numberOfModesToPlot, 1);
-        const mode_types = range(0, 1);
-        let {Qsca, Qabs, Qext, Qsca_n, Qabs_n, Qext_n} = initQ(mode_n, mode_types)
+          const host = $store.state.simulationSetup.current.hostIndex;
+          const safeFromWL = $store.state.guiRuntime.safeFromWL;
+          const safeToWL = $store.state.guiRuntime.safeToWL;
+          const WLs = getWLs(safeFromWL, safeToWL);
+          const mode_n = rangeInt(
+            $store.state.simulationSetup.current.numberOfModesToPlot,
+            1
+          );
+          const mode_types = range(0, 1);
+          let { Qsca, Qabs, Qext, Qsca_n, Qabs_n, Qext_n } = initQ(
+            mode_n,
+            mode_types
+          );
 
-        try {
-          if (!$store.state.simulationSetup.nmies.spectrum.instance) throw 'ERROR! Scattnlay module was not loaded'
-          const nmie = $store.state.simulationSetup.nmies.spectrum.instance
-          const layers = cloneDeep($store.state.simulationSetup.current.layers)
-          const nmieStartedTime = performance.now()
-          for (const WL of WLs) {
-            nmie.SetWavelength(WL)
+          try {
+            if (!$store.state.simulationSetup.nmies.spectrum.instance)
+              throw 'ERROR! Scattnlay module was not loaded';
+            const nmie = $store.state.simulationSetup.nmies.spectrum.instance;
+            const layers = cloneDeep(
+              $store.state.simulationSetup.current.layers
+            );
+            const nmieStartedTime = performance.now();
+            for (const WL of WLs) {
+              nmie.SetWavelength(WL);
 
-            nmie.ClearTarget()
-            for (const layer of layers) {
-              if (layer.material.nSpline) layer.n = layer.material.nSpline.at(WL)
-              if (layer.material.kSpline) layer.k = layer.material.kSpline.at(WL)
-              nmie.AddTargetLayerReIm(layer.layerWidth * host, layer.n / host, layer.k / host)
-            }
+              nmie.ClearTarget();
+              for (const layer of layers) {
+                if (layer.material.nSpline)
+                  layer.n = layer.material.nSpline.at(WL);
+                if (layer.material.kSpline)
+                  layer.k = layer.material.kSpline.at(WL);
+                nmie.AddTargetLayerReIm(
+                  layer.layerWidth * host,
+                  layer.n / host,
+                  layer.k / host
+                );
+              }
 
-            nmie.SetModeNmaxAndType(-1, -1)
-            nmie.RunMieCalculation()
-            Qsca.push(nmie.GetQsca())
-            Qabs.push(nmie.GetQabs())
-            Qext.push(nmie.GetQext())
+              nmie.SetModeNmaxAndType(-1, -1);
+              nmie.RunMieCalculation();
+              Qsca.push(nmie.GetQsca());
+              Qabs.push(nmie.GetQabs());
+              Qext.push(nmie.GetQext());
 
-            for (const mode_type of mode_types) {
-              for (const n of mode_n) {
-                nmie.SetModeNmaxAndType(n, mode_type)
-                nmie.RunMieCalculation()
-                Qsca_n[mode_type][n - 1].push(nmie.GetQsca())
-                Qabs_n[mode_type][n - 1].push(nmie.GetQabs())
-                Qext_n[mode_type][n - 1].push(nmie.GetQext())
+              for (const mode_type of mode_types) {
+                for (const n of mode_n) {
+                  nmie.SetModeNmaxAndType(n, mode_type);
+                  nmie.RunMieCalculation();
+                  Qsca_n[mode_type][n - 1].push(nmie.GetQsca());
+                  Qabs_n[mode_type][n - 1].push(nmie.GetQabs());
+                  Qext_n[mode_type][n - 1].push(nmie.GetQext());
+                }
               }
             }
-          }
-          const nmieTotalRunTime = (performance.now()-nmieStartedTime)/1000
-          // console.log('Total simulation time:', nmieTotalRunTime, 's')
-          $store.commit('simulationSetup/setNmieTotalRunTime', nmieTotalRunTime)
 
-          $store.commit('plotRuntime/setQ', {WLs, Qsca, Qabs, Qext, Qsca_n, Qabs_n, Qext_n})
-          $store.commit('plotRuntime/setWLsInUnits', sourceUnits.value)
+            const nmieTotalRunTime =
+              (performance.now() - nmieStartedTime) / 1000;
+            // console.log('Total simulation time:', nmieTotalRunTime, 's')
+            $store.commit(
+              'simulationSetup/setNmieTotalRunTime',
+              nmieTotalRunTime
+            );
 
-          $store.commit('plotRuntime/updateNumberOfPlotsFromPreviousSimulations')
-          $store.commit('plotRuntime/setCommonLabel', $store.state.simulationSetup.current.plotLabel)
-          $store.commit('simulationSetup/setPlotLabel', '')
-          $store.commit('plotRuntime/updateSpectrumPlots')
-        } catch (e) {
-          console.log(e)
-        }
-        isRunning.value = false
-      })
-      }, 100)
+            $store.commit('plotRuntime/setQ', {
+              WLs,
+              Qsca,
+              Qabs,
+              Qext,
+              Qsca_n,
+              Qabs_n,
+              Qext_n,
+            });
+            $store.commit('plotRuntime/setWLsInUnits', sourceUnits.value);
+
+            $store.commit(
+              'plotRuntime/updateNumberOfPlotsFromPreviousSimulations'
+            );
+            $store.commit(
+              'plotRuntime/setCommonLabel',
+              $store.state.simulationSetup.current.plotLabel
+            );
+            $store.commit('simulationSetup/setPlotLabel', '');
+            $store.commit('plotRuntime/updateSpectrumPlots');
+          } catch (e) {
+            console.log(e);
+          }
+          isRunning.value = false;
+        });
+      }, 100);
     }
 
-    watch(isNmieLoaded, ()=>{
-      if (isNmieLoaded.value) runSpectrumSimulation()
-    })
+    watch(isNmieLoaded, () => {
+      if (isNmieLoaded.value) runSpectrumSimulation();
+    });
 
-    onActivated(()=>{
+    onActivated(() => {
       if (isNmieLoaded.value) {
-        if ($store.state.plotRuntime.spectrumPlots.data.length == 0) runSpectrumSimulation()
+        if ($store.state.plotRuntime.spectrumPlots.data.length == 0)
+          runSpectrumSimulation();
         else {
+          // prettier-ignore
           // eslint-disable-next-line @typescript-eslint/ban-ts-comment
           // @ts-ignore
           // eslint-disable-next-line
-          const data_x_length = $store.state.plotRuntime.spectrumPlots.data[0].x.length
-          if (!data_x_length) runSpectrumSimulation()
+          const data_x_length = $store.state.plotRuntime.spectrumPlots.data[0].x.length;
+          if (!data_x_length) runSpectrumSimulation();
         }
       }
-    })
+    });
 
-    return { isRunning, isNmieLoaded,
+    return {
+      isRunning,
+      isNmieLoaded,
       runSpectrumSimulation,
-      saveSpectrumSimulation(){
-        const fileHeader = '# # You can open and plot this file using Python\n' +
-            '# # (without manually removing this header, it will be skipped), see example below.\n' +
-            '# import numpy as np\n' +
-            '# from matplotlib import pyplot as plt\n' +
-            '# data = np.genfromtxt(\'scattnlay-spectra.txt\', skip_header=21, names=True, delimiter=\', \')\n' +
-            '# x = data[data.dtype.names[0]] # x-axis has units\n' +
-            '# # Possible labels for spectrum data: Qsca, Qabs, Qext,\n' +
-            '# # Qsca_E_dipole, etc. (see last comment before spectra data)\n' +
-            '# a = data[\'Qsca\']\n' +
-            '# b = data[\'Qsca_E_dipole\']\n' +
-            '# c = data[\'Qsca_H_dipole\']\n' +
-            '# \n' +
-            '# plt.figure()\n' +
-            '# plt.plot(x, a, label=\'Qsca\')\n' +
-            '# plt.plot(x, b, label=\'Qsca E dipole\')\n' +
-            '# plt.plot(x, c, label=\'Qsca H dipole\')\n' +
-            '# plt.legend()\n' +
-            '# plt.xlabel(data.dtype.names[0].replace(\'_\', \', \'))\n' +
-            '# plt.ylabel(\'Normalized cross-sections\')\n' +
-            '# plt.show()\n\n'
-        let xTitle = 'x'
-        if ( $store.state.plotRuntime.spectrumPlots.layout.xaxis ) {
-          xTitle = String($store.state.plotRuntime.spectrumPlots.layout.xaxis.title)
+      saveSpectrumSimulation() {
+        const fileHeader =
+          '# # You can open and plot this file using Python\n' +
+          '# # (without manually removing this header, it will be skipped), see example below.\n' +
+          '# import numpy as np\n' +
+          '# from matplotlib import pyplot as plt\n' +
+          "# data = np.genfromtxt('scattnlay-spectra.txt', skip_header=21, names=True, delimiter=', ')\n" +
+          '# x = data[data.dtype.names[0]] # x-axis has units\n' +
+          '# # Possible labels for spectrum data: Qsca, Qabs, Qext,\n' +
+          '# # Qsca_E_dipole, etc. (see last comment before spectra data)\n' +
+          "# a = data['Qsca']\n" +
+          "# b = data['Qsca_E_dipole']\n" +
+          "# c = data['Qsca_H_dipole']\n" +
+          '# \n' +
+          '# plt.figure()\n' +
+          "# plt.plot(x, a, label='Qsca')\n" +
+          "# plt.plot(x, b, label='Qsca E dipole')\n" +
+          "# plt.plot(x, c, label='Qsca H dipole')\n" +
+          '# plt.legend()\n' +
+          "# plt.xlabel(data.dtype.names[0].replace('_', ', '))\n" +
+          "# plt.ylabel('Normalized cross-sections')\n" +
+          '# plt.show()\n\n';
+        let xTitle = 'x';
+        if ($store.state.plotRuntime.spectrumPlots.layout.xaxis) {
+          xTitle = String(
+            $store.state.plotRuntime.spectrumPlots.layout.xaxis.title
+          );
         }
 
-        let columnNames = '# ' + xTitle + ', Qsca, Qabs, Qext, '
-        const mode_n = rangeInt($store.state.simulationSetup.current.numberOfModesToPlot, 1);
+        let columnNames = '# ' + xTitle + ', Qsca, Qabs, Qext, ';
+        const mode_n = rangeInt(
+          $store.state.simulationSetup.current.numberOfModesToPlot,
+          1
+        );
         const mode_types = range(0, 1);
         for (const n of mode_n) {
           for (const mode_type of mode_types) {
-            const modeTypeName = mode_type == 0 ? 'E' : 'H'
-            columnNames += 'Qsca_' + modeTypeName + '_' +getModeName(n)+', '
-            columnNames += 'Qabs_' + modeTypeName + '_' +getModeName(n)+', '
-            columnNames += 'Qext_' + modeTypeName + '_' +getModeName(n)+', '
+            const modeTypeName = mode_type == 0 ? 'E' : 'H';
+            columnNames += 'Qsca_' + modeTypeName + '_' + getModeName(n) + ', ';
+            columnNames += 'Qabs_' + modeTypeName + '_' + getModeName(n) + ', ';
+            columnNames += 'Qext_' + modeTypeName + '_' + getModeName(n) + ', ';
           }
         }
-        columnNames = columnNames.slice(0, -2)
-        columnNames += '\n'
-        let body = ''
-        const WLs = $store.state.plotRuntime.WLsInUnits
-        const Qsca = $store.state.plotRuntime.Qsca
-        const Qabs = $store.state.plotRuntime.Qabs
-        const Qext = $store.state.plotRuntime.Qext
-        const Qsca_n = $store.state.plotRuntime.Qsca_n
-        const Qabs_n = $store.state.plotRuntime.Qabs_n
-        const Qext_n = $store.state.plotRuntime.Qext_n
+        columnNames = columnNames.slice(0, -2);
+        columnNames += '\n';
+        let body = '';
+        const WLs = $store.state.plotRuntime.WLsInUnits;
+        const Qsca = $store.state.plotRuntime.Qsca;
+        const Qabs = $store.state.plotRuntime.Qabs;
+        const Qext = $store.state.plotRuntime.Qext;
+        const Qsca_n = $store.state.plotRuntime.Qsca_n;
+        const Qabs_n = $store.state.plotRuntime.Qabs_n;
+        const Qext_n = $store.state.plotRuntime.Qext_n;
         for (let i = 0; i < WLs.length; ++i) {
-          let row = WLs[i].toString() + ', '
-              + Qsca[i].toString() + ', '
-              + Qabs[i].toString() + ', '
-              + Qext[i].toString() + ', '
+          let row =
+            WLs[i].toString() +
+            ', ' +
+            Qsca[i].toString() +
+            ', ' +
+            Qabs[i].toString() +
+            ', ' +
+            Qext[i].toString() +
+            ', ';
           for (const n of mode_n) {
             for (const mode_type of mode_types) {
-              row += Qsca_n[mode_type][n - 1][i].toString() + ', '
-              row += Qabs_n[mode_type][n - 1][i].toString() + ', '
-              row += Qext_n[mode_type][n - 1][i].toString() + ', '
+              row += Qsca_n[mode_type][n - 1][i].toString() + ', ';
+              row += Qabs_n[mode_type][n - 1][i].toString() + ', ';
+              row += Qext_n[mode_type][n - 1][i].toString() + ', ';
             }
           }
-          row = row.slice(0, -2)
-          row += '\n'
-          body += row
+          row = row.slice(0, -2);
+          row += '\n';
+          body += row;
         }
 
-        const scattnlaySpectra = new Blob([fileHeader+columnNames+body],
-            {type: 'text/plain;charset=utf-8',
-              endings: 'native'}  //TODO test if newline is correctly written in Windows, MacOS
-        )
+        const scattnlaySpectra = new Blob(
+          [fileHeader + columnNames + body],
+          { type: 'text/plain;charset=utf-8', endings: 'native' } //TODO test if newline is correctly written in Windows, MacOS
+        );
         saveAs(scattnlaySpectra, 'scattnlay-spectra.txt');
-      }
-    }
+      },
+    };
   },
-})
+});
 </script>

+ 91 - 88
guiapp/src/components/utils.ts

@@ -1,112 +1,115 @@
-export function limitMap(arr:Float64Array, minVal:number, maxVal:number) {
-    return arr.map(x=>x>maxVal?maxVal:x).map(x=>x<minVal?minVal:x)
+export function limitMap(arr: Float64Array, minVal: number, maxVal: number) {
+  return arr
+    .map((x) => (x > maxVal ? maxVal : x))
+    .map((x) => (x < minVal ? minVal : x));
 }
 
 // According to https://stackoverflow.com/questions/1669190/find-the-min-max-element-of-an-array-in-javascript
 // getting max and min element is non trivial for large arrays (e.g. 512x512 points heatmap)
-export function getMaxFromHeatmap(val:Float64Array|undefined) {
-    let max = -Infinity
-    if (!val) return max
-    for (let i = 0; i < val.length; ++i) {
-        if (val[i] > max) {
-            max = val[i]
-        }
+export function getMaxFromHeatmap(val: Float64Array | undefined) {
+  let max = -Infinity;
+  if (!val) return max;
+  for (let i = 0; i < val.length; ++i) {
+    if (val[i] > max) {
+      max = val[i];
     }
-    return max
+  }
+  return max;
 }
-export function getMinFromHeatmap(val:Float64Array|undefined) {
-    let min = Infinity
-    if (!val) return min
-    for (let i = 0; i < val.length; ++i) {
-        if (val[i] < min) {
-            min = val[i]
-        }
+export function getMinFromHeatmap(val: Float64Array | undefined) {
+  let min = Infinity;
+  if (!val) return min;
+  for (let i = 0; i < val.length; ++i) {
+    if (val[i] < min) {
+      min = val[i];
     }
-    return min
+  }
+  return min;
 }
 
-
-export function composeLabelFromPageData (val:string) {
-    const shelfName = val.slice(0, val.indexOf('/')+1)
-    return val.replace(shelfName, ''
-    ).replace('.yml',''
-    ).replace(new RegExp('[ /-]', 'g'),'_'
-    )
+export function composeLabelFromPageData(val: string) {
+  const shelfName = val.slice(0, val.indexOf('/') + 1);
+  return val
+    .replace(shelfName, '')
+    .replace('.yml', '')
+    .replace(new RegExp('[ /-]', 'g'), '_');
 }
 
-export function getModeName(i:number) {
-    if (i == 1) return 'dipole'
-    if (i == 2) return 'quadrupole'
-    if (i == 3) return 'octupole'
-    return  Math.pow(2, i).toString()
+export function getModeName(i: number) {
+  if (i == 1) return 'dipole';
+  if (i == 2) return 'quadrupole';
+  if (i == 3) return 'octupole';
+  return Math.pow(2, i).toString();
 }
 
-export function isAlmostSame(a:number,b:number) {
-    if ( Math.abs((a-b)/(a+b)) < 1e-15) return true
-    return false
+export function isAlmostSame(a: number, b: number) {
+  if (Math.abs((a - b) / (a + b)) < 1e-15) return true;
+  return false;
 }
 
-export function range(start:number, stop:number, step = 1) {
-    return Array(Math.round(((stop - start) / step)+1)).fill(start).map((x:number, y:number) => x + y * step)
+export function range(start: number, stop: number, step = 1) {
+  return Array(Math.round((stop - start) / step + 1))
+    .fill(start)
+    .map((x: number, y: number) => x + y * step);
 }
 
-export function rangeInt(size:number, startAt = 0) {
-    return [...Array(size).keys()].map(i => i + startAt)
+export function rangeInt(size: number, startAt = 0) {
+  return [...Array(size).keys()].map((i) => i + startAt);
 }
 
 // convert value to nm from some units
-export function fromUnits(fromU:string, val:number):number {
-    if (fromU === 'nm') return val
-    if (fromU === 'µm') return val*1e3
-    if (fromU === 'mm') return val*1e6
-    if (fromU === 'cm') return val*1e7
-    if (fromU === 'm') return val*1e9
-    if (fromU === 'km') return val*1e12
-
-    const c = 299792458 // m/s
-    const hc = 1239841930.092394328e-15 // m*eV
-    if (fromU === 'THz') return c/(val*1e12)*1e9
-    if (fromU === 'GHz') return c/(val*1e9)*1e9
-    if (fromU === 'MHz') return c/(val*1e6)*1e9
-    if (fromU === 'kHz') return c/(val*1e3)*1e9
-    if (fromU === 'Hz') return c/(val*1e0)*1e9
-
-    if (fromU === 'eV') return hc/(val*1e0)*1e9
-    if (fromU === 'meV') return hc/(val/1e3)*1e9
-
-    if (fromU === 'fs') return (val/1e12)*c*1e9
-    if (fromU === 'ps') return (val/1e15)*c*1e9
-
-    return val
+export function fromUnits(fromU: string, val: number): number {
+  if (fromU === 'nm') return val;
+  if (fromU === 'µm') return val * 1e3;
+  if (fromU === 'mm') return val * 1e6;
+  if (fromU === 'cm') return val * 1e7;
+  if (fromU === 'm') return val * 1e9;
+  if (fromU === 'km') return val * 1e12;
+
+  const c = 299792458; // m/s
+  const hc = 1239841930.092394328e-15; // m*eV
+  if (fromU === 'THz') return (c / (val * 1e12)) * 1e9;
+  if (fromU === 'GHz') return (c / (val * 1e9)) * 1e9;
+  if (fromU === 'MHz') return (c / (val * 1e6)) * 1e9;
+  if (fromU === 'kHz') return (c / (val * 1e3)) * 1e9;
+  if (fromU === 'Hz') return (c / (val * 1)) * 1e9;
+
+  if (fromU === 'eV') return (hc / (val * 1)) * 1e9;
+  if (fromU === 'meV') return (hc / (val / 1e3)) * 1e9;
+
+  if (fromU === 'fs') return (val / 1e12) * c * 1e9;
+  if (fromU === 'ps') return (val / 1e15) * c * 1e9;
+
+  return val;
 }
 
 // convert value from nm to some units
-export function toUnits(val:number, toU:string):number {
-    if (toU === 'nm') return val
-    if (toU === 'µm') return val/1e3
-    if (toU === 'mm') return val/1e6
-    if (toU === 'cm') return val/1e7
-    if (toU === 'm') return val/1e9
-    if (toU === 'km') return val/1e12
-
-    const c = 299792458 // m/s
-    const hc = 1239841930.092394328e-15 // m*eV
-    if (toU === 'THz') return c/(val/1e9)/1e12
-    if (toU === 'GHz') return c/(val/1e9)/1e9
-    if (toU === 'MHz') return c/(val/1e9)/1e6
-    if (toU === 'kHz') return c/(val/1e9)/1e3
-    if (toU === 'Hz') return c/(val/1e9)/1e0
-
-    if (toU === 'eV') return hc/(val/1e9)
-    if (toU === 'meV') return hc/(val/1e9)*1e3
-
-    if (toU === 'fs') return (val/1e9)/c*1e12
-    if (toU === 'ps') return (val/1e9)/c*1e15
-
-    // if (fromU === 'eV') return hc/(val*1e0)*1e9
-    // if (fromU === 'meV') return hc/(val/1e3)*1e9
-    //
-    // if (fromU === 'fs') return (val/1e12)/c*1e9
-    // if (fromU === 'ps') return (val/1e15)/c*1e9
-    return val
+export function toUnits(val: number, toU: string): number {
+  if (toU === 'nm') return val;
+  if (toU === 'µm') return val / 1e3;
+  if (toU === 'mm') return val / 1e6;
+  if (toU === 'cm') return val / 1e7;
+  if (toU === 'm') return val / 1e9;
+  if (toU === 'km') return val / 1e12;
+
+  const c = 299792458; // m/s
+  const hc = 1239841930.092394328e-15; // m*eV
+  if (toU === 'THz') return c / (val / 1e9) / 1e12;
+  if (toU === 'GHz') return c / (val / 1e9) / 1e9;
+  if (toU === 'MHz') return c / (val / 1e9) / 1e6;
+  if (toU === 'kHz') return c / (val / 1e9) / 1e3;
+  if (toU === 'Hz') return c / (val / 1e9) / 1;
+
+  if (toU === 'eV') return hc / (val / 1e9);
+  if (toU === 'meV') return (hc / (val / 1e9)) * 1e3;
+
+  if (toU === 'fs') return (val / 1e9 / c) * 1e12;
+  if (toU === 'ps') return (val / 1e9 / c) * 1e15;
+
+  // if (fromU === 'eV') return hc/(val*1e0)*1e9
+  // if (fromU === 'meV') return hc/(val/1e3)*1e9
+  //
+  // if (fromU === 'fs') return (val/1e12)/c*1e9
+  // if (fromU === 'ps') return (val/1e15)/c*1e9
+  return val;
 }

+ 70 - 60
guiapp/src/layouts/MainLayout.vue

@@ -1,6 +1,6 @@
 <template>
   <q-layout view="lHh lpR fFf">
-<!--  <q-layout view="hHh Lpr lFr">-->
+    <!--  <q-layout view="hHh Lpr lFr">-->
     <q-header elevated>
       <q-toolbar>
         <q-btn
@@ -12,113 +12,123 @@
           @click="toggleLeftDrawer"
         />
         <q-tabs align="right">
-          <q-route-tab to="/spectrum" label="Spectrum" name="spectrum"/>
-          <q-route-tab to="/nearfield" label="Near-field" name="nearfield"/>
-<!--          <q-route-tab to="/farfield" label="Far-field" name="farfield"/>-->
+          <q-route-tab to="/spectrum" label="Spectrum" name="spectrum" />
+          <q-route-tab to="/nearfield" label="Near-field" name="nearfield" />
+          <!--          <q-route-tab to="/farfield" label="Far-field" name="farfield"/>-->
         </q-tabs>
       </q-toolbar>
     </q-header>
 
-    <q-drawer
-      v-model="leftDrawerOpen"
-      bordered
-    >
+    <q-drawer v-model="leftDrawerOpen" bordered>
       <q-list>
         <q-item clickable @click="toggleLeftDrawer">
           <q-item-section></q-item-section>
           <q-item-section avatar side> <q-icon name="close" /> </q-item-section>
         </q-item>
 
-        <q-item
-            clickable
-            to="/materials"
-            @click="toggleLeftDrawer"
-        >
-          <q-item-section
-              avatar
-          >
+        <q-item clickable to="/materials" @click="toggleLeftDrawer">
+          <q-item-section avatar>
             <q-icon name="o_tune" />
           </q-item-section>
           <q-item-section>
-            <q-item-label>            Materials
-            </q-item-label>
+            <q-item-label> Materials </q-item-label>
           </q-item-section>
         </q-item>
 
-        <q-item
-            clickable
-            to="/info"
-            @click="toggleLeftDrawer"
-        >
-          <q-item-section
-              avatar
-          >
+        <q-item clickable to="/info" @click="toggleLeftDrawer">
+          <q-item-section avatar>
             <q-icon name="o_info" />
           </q-item-section>
           <q-item-section>
-            <q-item-label>            Info
-            </q-item-label>
+            <q-item-label> Info </q-item-label>
           </q-item-section>
         </q-item>
 
-        <q-separator inset spaced/>
-        <q-item> <q-item-section> <q-item-label> External links</q-item-label> </q-item-section> </q-item>
-        <q-item clickable tag="a" target="_blank" href="https://github.com/ovidiopr/scattnlay" >
-          <q-item-section avatar > <q-icon name="code" /> </q-item-section>
-          <q-item-section> <q-item-label>Project at GitHub</q-item-label>
+        <q-separator inset spaced />
+        <q-item>
+          <q-item-section>
+            <q-item-label> External links</q-item-label>
+          </q-item-section>
+        </q-item>
+        <q-item
+          clickable
+          tag="a"
+          target="_blank"
+          href="https://github.com/ovidiopr/scattnlay"
+        >
+          <q-item-section avatar> <q-icon name="code" /> </q-item-section>
+          <q-item-section>
+            <q-item-label>Project at GitHub</q-item-label>
             <q-item-label caption> Open-source software </q-item-label>
           </q-item-section>
         </q-item>
-        <q-item clickable tag="a" target="_blank" href="https://github.com/ovidiopr/scattnlay/issues/new?title=[webapp]" >
-          <q-item-section avatar > <q-icon name="support" /> </q-item-section>
-          <q-item-section> <q-item-label>Support</q-item-label>
-            <q-item-label caption> Requires a GitHub account</q-item-label></q-item-section>
+        <q-item
+          clickable
+          tag="a"
+          target="_blank"
+          href="https://github.com/ovidiopr/scattnlay/issues/new?title=[webapp]"
+        >
+          <q-item-section avatar> <q-icon name="support" /> </q-item-section>
+          <q-item-section>
+            <q-item-label>Support</q-item-label>
+            <q-item-label caption>
+              Requires a GitHub account</q-item-label
+            ></q-item-section
+          >
         </q-item>
-        <q-separator inset spaced/>
+        <q-separator inset spaced />
         <q-item class="q-mt-auto text-body2">
-          Last simulation took ...<br>
-           - spectrum  {{$store.state.simulationSetup.nmies.spectrum.nmieTotalRunTime.toFixed(2)}} s.<br>
-           - near-field  {{$store.state.simulationSetup.nmies.nearField.nmieTotalRunTime.toFixed(2)}} s.
+          Last simulation took ...<br />
+          - spectrum
+          {{
+            $store.state.simulationSetup.nmies.spectrum.nmieTotalRunTime.toFixed(
+              2
+            )
+          }}
+          s.<br />
+          - near-field
+          {{
+            $store.state.simulationSetup.nmies.nearField.nmieTotalRunTime.toFixed(
+              2
+            )
+          }}
+          s.
         </q-item>
       </q-list>
-
     </q-drawer>
 
     <q-page-container>
-<!--      <router-view />-->
+      <!--      <router-view />-->
       <router-view v-slot="{ Component }">
-<!--        <transition name="fade">-->
-          <keep-alive>
-            <component :is="Component" />
-          </keep-alive>
-<!--        </transition>-->
+        <!--        <transition name="fade">-->
+        <keep-alive>
+          <component :is="Component" />
+        </keep-alive>
+        <!--        </transition>-->
       </router-view>
-
     </q-page-container>
   </q-layout>
 </template>
 
 <script lang="ts">
-
-import { defineComponent, ref } from 'vue'
+import { defineComponent, ref } from 'vue';
 
 export default defineComponent({
   name: 'MainLayout',
   components: {},
 
-
   // components: {
   //   EssentialLink
   // },
 
-  setup () {
-    const leftDrawerOpen = ref(false)
+  setup() {
+    const leftDrawerOpen = ref(false);
     return {
       leftDrawerOpen,
-      toggleLeftDrawer () {
-        leftDrawerOpen.value = !leftDrawerOpen.value
-      }
-    }
-  }
-})
+      toggleLeftDrawer() {
+        leftDrawerOpen.value = !leftDrawerOpen.value;
+      },
+    };
+  },
+});
 </script>

+ 36 - 26
guiapp/src/nmiejs.d.ts

@@ -1,34 +1,44 @@
 export default function nmiejs(): Promise<nmieModule>;
 
-
 declare interface nmieModule {
-    nmie: new () => nmie_class;
+  nmie: new () => nmie_class;
 }
 
-
 export class nmie_class {
-    constructor(path?: string);
-    SetWavelength(wavelength: number): void;
-    AddTargetLayerReIm(layer_width: number,
-                       re_layer_index: number,
-                       im_layer_index: number): void;
-    SetModeNmaxAndType(mode_n: number, mode_type: number): void;
-    ClearTarget(): void;
-    RunMieCalculation(): void;
-    RunFieldCalculationPolar(outer_arc_pos: number,
-                             radius_pos: number,
-                             from_Rho: number,   to_Rho: number,
-                             from_Theta: number,   to_Theta: number,
-                             from_Phi: number,   to_Phi: number,
-                             isIgnoreAvailableNmax: number): void;
-    RunFieldCalculationCartesian( side_1_points: number, side_2_points: number,
-                                  relative_side_length: number, plane_selected: number,
-                                  at_x: number, at_y: number, at_z: number,
-                                  isIgnoreAvailableNmax: number): void;
+  constructor(path?: string);
+  SetWavelength(wavelength: number): void;
+  AddTargetLayerReIm(
+    layer_width: number,
+    re_layer_index: number,
+    im_layer_index: number
+  ): void;
+  SetModeNmaxAndType(mode_n: number, mode_type: number): void;
+  ClearTarget(): void;
+  RunMieCalculation(): void;
+  RunFieldCalculationPolar(
+    outer_arc_pos: number,
+    radius_pos: number,
+    from_Rho: number,
+    to_Rho: number,
+    from_Theta: number,
+    to_Theta: number,
+    from_Phi: number,
+    to_Phi: number,
+    isIgnoreAvailableNmax: number
+  ): void;
+  RunFieldCalculationCartesian(
+    side_1_points: number,
+    side_2_points: number,
+    relative_side_length: number,
+    plane_selected: number,
+    at_x: number,
+    at_y: number,
+    at_z: number,
+    isIgnoreAvailableNmax: number
+  ): void;
 
-    GetFieldEabs(): Float64Array;
-    GetQsca(): number;
-    GetQabs(): number;
-    GetQext(): number;
+  GetFieldEabs(): Float64Array;
+  GetQsca(): number;
+  GetQabs(): number;
+  GetQext(): number;
 }
-

+ 8 - 10
guiapp/src/pages/Error404.vue

@@ -1,13 +1,11 @@
 <template>
-  <div class="fullscreen bg-blue text-white text-center q-pa-md flex flex-center">
+  <div
+    class="fullscreen bg-blue text-white text-center q-pa-md flex flex-center"
+  >
     <div>
-      <div style="font-size: 30vh">
-        404
-      </div>
+      <div style="font-size: 30vh">404</div>
 
-      <div class="text-h2" style="opacity:.4">
-        Oops. Nothing here...
-      </div>
+      <div class="text-h2" style="opacity: 0.4">Oops. Nothing here...</div>
 
       <q-btn
         class="q-mt-xl"
@@ -23,9 +21,9 @@
 </template>
 
 <script lang="ts">
-import { defineComponent } from 'vue'
+import { defineComponent } from 'vue';
 
 export default defineComponent({
-  name: 'Error404'
-})
+  name: 'Error404',
+});
 </script>

+ 26 - 22
guiapp/src/pages/Far-field.vue

@@ -1,44 +1,48 @@
 <template>
   <q-page class="column q-px-md">
-<!--    <img src="https://www.pikpng.com/pngl/m/8-80773_new-content-coming-soon-website-under-construction-banner.png" alt="New Content Coming Soon - Website Under Construction">-->
-    <q-img :src="img_path"  />
-    <div class="q-ma-sm"/>
+    <!--    <img src="https://www.pikpng.com/pngl/m/8-80773_new-content-coming-soon-website-under-construction-banner.png" alt="New Content Coming Soon - Website Under Construction">-->
+    <q-img :src="img_path" />
+    <div class="q-ma-sm" />
     Under construction!
 
-    <div class="q-ma-sm"/>
-    <GetSourceParameters/>
-    <GetHostIndex/>
+    <div class="q-ma-sm" />
+    <GetSourceParameters />
+    <GetHostIndex />
     <div class="col-auto">
-      Input result: {{$store.state.simulationSetup.gui.fromWL}}
+      Input result: {{ $store.state.simulationSetup.gui.fromWL }}
     </div>
     <!-- place QPageScroller at end of page -->
-    <div class="q-ma-lg"/>
-    <q-page-scroller position="bottom-right" :scroll-offset="150" :offset="[18, 18]">
+    <div class="q-ma-lg" />
+    <q-page-scroller
+      position="bottom-right"
+      :scroll-offset="150"
+      :offset="[18, 18]"
+    >
       <q-btn size="xs" fab icon="keyboard_arrow_up" color="primary" />
     </q-page-scroller>
   </q-page>
 </template>
 
-<script lang='ts'>
-import {
-  defineComponent
-} from 'vue'
-import GetHostIndex from 'components/spectrum/GetHostIndex.vue'
-import GetSourceParameters from 'components/spectrum/GetSourceParameters.vue'
+<script lang="ts">
+import { defineComponent } from 'vue';
+import GetHostIndex from 'components/spectrum/GetHostIndex.vue';
+import GetSourceParameters from 'components/spectrum/GetSourceParameters.vue';
 // import GetParticleParameters from 'components/GetParticleParameters.vue'
 // import { useStore } from 'src/store'
 
-
 export default defineComponent({
   name: 'FarFieldPage',
-  components: {GetHostIndex, GetSourceParameters,
+  components: {
+    GetHostIndex,
+    GetSourceParameters,
     // GetParticleParameters
   },
   setup() {
-    let img_path = 'underconstruction.jpg'
-    if (process.env.publicPath) img_path = process.env.publicPath.toString()+'underconstruction.jpg'
+    let img_path = 'underconstruction.jpg';
+    if (process.env.publicPath)
+      img_path = process.env.publicPath.toString() + 'underconstruction.jpg';
     // const $store = useStore()
-    return {img_path}
-  }
-})
+    return { img_path };
+  },
+});
 </script>

+ 90 - 29
guiapp/src/pages/Info.vue

@@ -4,48 +4,109 @@
     <q-card class="q-mt-sm q-mx-sm">
       <q-card-section>
         <div class="text-h6">Usage:</div>
-<!--        <div class="text-subtitle2">by John Doe</div>-->
+        <!--        <div class="text-subtitle2">by John Doe</div>-->
       </q-card-section>
       <q-card-section>
-      Feel free to use provided software, however, use it at your own risk. We made our best effort to verify
-      it is correct, however, we do not provide any warranty.
-      <br><br> Report bugs, issues, and feature requests at project's
-      <a href="https://github.com/ovidiopr/scattnlay">GitHub<q-icon name="launch" style="padding-left: 0.1rem; padding-bottom: 1rem" /></a>
-      (preferred) or mail to <a href="mailto:k.ladutenko@metalab.ifmo.ru?subject=Mie calculator webapp (Scattnlay)">k.ladutenko@metalab.ifmo.ru</a>.
-      <br><br>
-      If it was useful for your project, please, cite the following reference:
-      <br><br>
-      <article style="margin-left: 1rem">
-        <div style="font-style: italic; padding-bottom: 0.5rem">"Mie calculation of electromagnetic near-field
-          for a multilayered sphere"</div>
-        Konstantin Ladutenko, Umapada Pal, Antonio Rivera, Ovidio Peña-Rodríguez<br>
-        <span style="font-weight: bold">Comp. Phys. Comm., vol. 214, pp. 225–230, 2017</span>
-      </article>
-      <br>
-      and the related URL:
+        Feel free to use provided software, however, use it at your own risk. We
+        made our best effort to verify it is correct, however, we do not provide
+        any warranty.
+        <br /><br />
+        Report bugs, issues, and feature requests at project's
+        <a href="https://github.com/ovidiopr/scattnlay"
+          >GitHub<q-icon
+            name="launch"
+            style="padding-left: 0.1rem; padding-bottom: 1rem"
+        /></a>
+        (preferred) or mail to
+        <a
+          href="mailto:k.ladutenko@metalab.ifmo.ru?subject=Mie calculator webapp (Scattnlay)"
+          >k.ladutenko@metalab.ifmo.ru</a
+        >. <br /><br />
+        If it was useful for your project, please, cite the following reference:
+        <br /><br />
+        <article style="margin-left: 1rem">
+          <div style="font-style: italic; padding-bottom: 0.5rem">
+            "Mie calculation of electromagnetic near-field for a multilayered
+            sphere"
+          </div>
+          Konstantin Ladutenko, Umapada Pal, Antonio Rivera, Ovidio
+          Peña-Rodríguez<br />
+          <span style="font-weight: bold"
+            >Comp. Phys. Comm., vol. 214, pp. 225–230, 2017</span
+          >
+        </article>
+        <br />
+        and the related URL:
 
-      <article style="margin: 1rem">
-        <div style="font-style: italic">https://physics.itmo.ru/mie/</div>
-      </article>
+        <article style="margin: 1rem">
+          <div style="font-style: italic">https://physics.itmo.ru/mie/</div>
+        </article>
       </q-card-section>
     </q-card>
-    <q-card class="q-mt-md  q-mx-sm">
+    <q-card class="q-mt-md q-mx-sm">
       <q-card-section>
         <div class="text-h6">Alternatives:</div>
       </q-card-section>
       <q-card-section>
         <ul>
-          <li><a href="https://nanocomposix.com/pages/mie-theory-calculator">Bulk or core-shell<q-icon name="launch" style="padding-left: 0.1rem; padding-bottom: 1rem" />,</a>   only dipole and quadrupole contributions by Nanocomposix. </li>
-          <li><a href="https://de.ifmo.ru/miecalculator/">Bulk particles<q-icon name="launch" style="padding-left: 0.1rem; padding-bottom: 1rem" /></a>   by Ivan Toftul.</li>
-          <li><a href="https://saviot.cnrs.fr/mie/index.en.html">Bulk<q-icon name="launch" style="padding-left: 0.1rem; padding-bottom: 1rem" /></a> and <a href="https://saviot.cnrs.fr/miecoat/index.en.html">core-shell<q-icon name="launch" style="padding-left: 0.1rem; padding-bottom: 1rem" /></a> calculators by Lucien Saviot.</li>
-          <li><a href="https://omlc.org/calc/mie_calc.html">Angle distribution<q-icon name="launch" style="padding-left: 0.1rem; padding-bottom: 1rem" /></a>  by Scott Prahl.</li>
-          <li><a href="http://www.philiplaven.com/mieplot.htm">Mie theory and Debye series<q-icon name="launch" style="padding-left: 0.1rem; padding-bottom: 1rem" /></a> mostly for atmospheric optical effects, by Philip Laven (Windows OS only)</li>
+          <li>
+            <a href="https://nanocomposix.com/pages/mie-theory-calculator"
+              >Bulk or core-shell<q-icon
+                name="launch"
+                style="padding-left: 0.1rem; padding-bottom: 1rem"
+              />,</a
+            >
+            only dipole and quadrupole contributions by Nanocomposix.
+          </li>
+          <li>
+            <a href="https://de.ifmo.ru/miecalculator/"
+              >Bulk particles<q-icon
+                name="launch"
+                style="padding-left: 0.1rem; padding-bottom: 1rem"
+            /></a>
+            by Ivan Toftul.
+          </li>
+          <li>
+            <a href="https://saviot.cnrs.fr/mie/index.en.html"
+              >Bulk<q-icon
+                name="launch"
+                style="padding-left: 0.1rem; padding-bottom: 1rem"
+            /></a>
+            and
+            <a href="https://saviot.cnrs.fr/miecoat/index.en.html"
+              >core-shell<q-icon
+                name="launch"
+                style="padding-left: 0.1rem; padding-bottom: 1rem"
+            /></a>
+            calculators by Lucien Saviot.
+          </li>
+          <li>
+            <a href="https://omlc.org/calc/mie_calc.html"
+              >Angle distribution<q-icon
+                name="launch"
+                style="padding-left: 0.1rem; padding-bottom: 1rem"
+            /></a>
+            by Scott Prahl.
+          </li>
+          <li>
+            <a href="http://www.philiplaven.com/mieplot.htm"
+              >Mie theory and Debye series<q-icon
+                name="launch"
+                style="padding-left: 0.1rem; padding-bottom: 1rem"
+            /></a>
+            mostly for atmospheric optical effects, by Philip Laven (Windows OS
+            only)
+          </li>
         </ul>
       </q-card-section>
     </q-card>
     <!-- place QPageScroller at end of page -->
-    <div class="q-ma-xl"/>
-    <q-page-scroller position="bottom-right" :scroll-offset="150" :offset="[18, 18]">
+    <div class="q-ma-xl" />
+    <q-page-scroller
+      position="bottom-right"
+      :scroll-offset="150"
+      :offset="[18, 18]"
+    >
       <q-btn size="xs" fab icon="keyboard_arrow_up" color="primary" />
     </q-page-scroller>
   </q-page>
@@ -54,5 +115,5 @@
 <script>
 export default {
   name: 'InfoPage',
-}
+};
 </script>

+ 27 - 22
guiapp/src/pages/Materials.vue

@@ -1,38 +1,43 @@
 <template>
   <q-page class="col-12 q-px-md">
-    <div class="q-ma-sm"/>
-    <MaterialsSelector/>
-    <div class="q-ma-xs"/>
-    <router-link to="/spectrum"> <GetSourceParameters :is-info-mode="true"/> </router-link>
-    <MaterialsActivated/>
-    <div class="q-ma-xs"/>
-    <PlotMaterials/>
-    <div class="q-ma-xs"/>
+    <div class="q-ma-sm" />
+    <MaterialsSelector />
+    <div class="q-ma-xs" />
+    <router-link to="/spectrum">
+      <GetSourceParameters :is-info-mode="true" />
+    </router-link>
+    <MaterialsActivated />
+    <div class="q-ma-xs" />
+    <PlotMaterials />
+    <div class="q-ma-xs" />
     <!-- place QPageScroller at end of page -->
-    <div class="q-ma-lg"/>
-    <q-page-scroller position="bottom-right" :scroll-offset="150" :offset="[18, 18]">
+    <div class="q-ma-lg" />
+    <q-page-scroller
+      position="bottom-right"
+      :scroll-offset="150"
+      :offset="[18, 18]"
+    >
       <q-btn size="xs" fab icon="keyboard_arrow_up" color="primary" />
     </q-page-scroller>
   </q-page>
 </template>
 
-<script lang='ts'>
-import {
-  defineComponent,
-} from 'vue'
+<script lang="ts">
+import { defineComponent } from 'vue';
 
-import MaterialsSelector from 'components/materials/MaterialsSelector.vue'
-import MaterialsActivated from 'components/materials/MaterialsActivated.vue'
-import GetSourceParameters from 'components/spectrum/GetSourceParameters.vue'
-import PlotMaterials from 'components/materials/PlotMaterials.vue'
+import MaterialsSelector from 'components/materials/MaterialsSelector.vue';
+import MaterialsActivated from 'components/materials/MaterialsActivated.vue';
+import GetSourceParameters from 'components/spectrum/GetSourceParameters.vue';
+import PlotMaterials from 'components/materials/PlotMaterials.vue';
 // import { useStore } from 'src/store'
 
-
 export default defineComponent({
   name: 'MaterialsPage',
   components: {
-    MaterialsSelector, GetSourceParameters,
-    MaterialsActivated, PlotMaterials
+    MaterialsSelector,
+    GetSourceParameters,
+    MaterialsActivated,
+    PlotMaterials,
   },
-})
+});
 </script>

+ 38 - 38
guiapp/src/pages/Near-field.vue

@@ -1,47 +1,48 @@
 <template>
   <q-page class="column q-px-md">
-    <div class="q-ma-md"/>
-    <ShowNearFieldWarning/>
-    <RunSimulationSpectrum v-show="false"/>
-    <GetWlFromPlot/>
-    <div class="q-ma-xs"/>
-    <GetNearFieldSettings/>
-    <div class="q-ma-xs"/>
-    <RunSimulationNearField/>
-    <div class="q-ma-xs"/>
-    <PlotNearField/>
-    <div class="q-ma-xs"/>
-    <GetNearFieldColorScale/>
-    <div class="q-ma-xs"/>
-    <GetNearFieldRefinedSettings/>
-<!--    <div class="col-auto">-->
-<!--      Input result: {{$store.state.simulationSetup.gui.nearFieldSetup.plotYSideResolution}}-->
-<!--    </div>-->
+    <div class="q-ma-md" />
+    <ShowNearFieldWarning />
+    <RunSimulationSpectrum v-show="false" />
+    <GetWlFromPlot />
+    <div class="q-ma-xs" />
+    <GetNearFieldSettings />
+    <div class="q-ma-xs" />
+    <RunSimulationNearField />
+    <div class="q-ma-xs" />
+    <PlotNearField />
+    <div class="q-ma-xs" />
+    <GetNearFieldColorScale />
+    <div class="q-ma-xs" />
+    <GetNearFieldRefinedSettings />
+    <!--    <div class="col-auto">-->
+    <!--      Input result: {{$store.state.simulationSetup.gui.nearFieldSetup.plotYSideResolution}}-->
+    <!--    </div>-->
 
-    <div class="q-ma-lg"/>
+    <div class="q-ma-lg" />
     <!-- place QPageScroller at end of page -->
-    <q-page-scroller position="bottom-right" :scroll-offset="150" :offset="[18, 18]">
+    <q-page-scroller
+      position="bottom-right"
+      :scroll-offset="150"
+      :offset="[18, 18]"
+    >
       <q-btn size="xs" fab icon="keyboard_arrow_up" color="primary" />
     </q-page-scroller>
   </q-page>
 </template>
 
-<script lang='ts'>
-import {
-  defineComponent
-} from 'vue'
-import GetWlFromPlot from 'components/nearfield/GetWlFromPlot.vue'
-import GetNearFieldSettings from 'components/nearfield/GetNearFieldSettings.vue'
-import RunSimulationSpectrum from 'components/spectrum/RunSimulationSpectrum.vue'
-import RunSimulationNearField from 'components/nearfield/RunSimulationNearField.vue'
-import PlotNearField from 'components/nearfield/PlotNearField.vue'
-import ShowNearFieldWarning from 'components/nearfield/ShowNearFieldWarning.vue'
-import GetNearFieldColorScale from 'components/nearfield/GetNearFieldColorScale.vue'
-import GetNearFieldRefinedSettings from 'components/nearfield/GetNearFieldRefinedSettings.vue'
+<script lang="ts">
+import { defineComponent } from 'vue';
+import GetWlFromPlot from 'components/nearfield/GetWlFromPlot.vue';
+import GetNearFieldSettings from 'components/nearfield/GetNearFieldSettings.vue';
+import RunSimulationSpectrum from 'components/spectrum/RunSimulationSpectrum.vue';
+import RunSimulationNearField from 'components/nearfield/RunSimulationNearField.vue';
+import PlotNearField from 'components/nearfield/PlotNearField.vue';
+import ShowNearFieldWarning from 'components/nearfield/ShowNearFieldWarning.vue';
+import GetNearFieldColorScale from 'components/nearfield/GetNearFieldColorScale.vue';
+import GetNearFieldRefinedSettings from 'components/nearfield/GetNearFieldRefinedSettings.vue';
 
 // import { useStore } from 'src/store'
 
-
 export default defineComponent({
   name: 'NearField',
   components: {
@@ -50,15 +51,14 @@ export default defineComponent({
     ShowNearFieldWarning,
     PlotNearField,
     RunSimulationNearField,
-    GetWlFromPlot, RunSimulationSpectrum,
+    GetWlFromPlot,
+    RunSimulationSpectrum,
     GetNearFieldSettings,
   },
   setup() {
-
     // const $store = useStore()
 
-    return {
-    }
-  }
-})
+    return {};
+  },
+});
 </script>

+ 47 - 42
guiapp/src/pages/Spectrum.vue

@@ -1,63 +1,68 @@
 <template>
   <q-page class="column q-px-md">
-    <div class="q-ma-md"/>
-    <GetHostIndex/>
-    <div class="q-ma-xs"/>
-    <GetUnits/>
-    <div id="GetSourceParametersHref" class="q-ma-xs"/>
-    <GetSourceParameters/>
-    <div class="q-ma-xs"/>
-    <GetParticleParameters/>
-    <div class="q-ma-xs"/>
-    <GetModesToPlot/>
-    <div class="q-ma-xs"/>
-    <GetPlotSettings/>
-    <div class="q-ma-xs"/>
-    <RunSimulationSpectrum/>
-<!--    <div class="col-auto q-pa-md">-->
-<!--      Input result: {{$store.state.plotRuntime.isPlotQabs}}-->
-<!--    </div>-->
-    <div class="q-ma-sm"/>
-    <PlotSelector/>
-    <div class="q-ma-xs"/>
-    <PlotSpectra/>
+    <div class="q-ma-md" />
+    <GetHostIndex />
+    <div class="q-ma-xs" />
+    <GetUnits />
+    <div id="GetSourceParametersHref" class="q-ma-xs" />
+    <GetSourceParameters />
+    <div class="q-ma-xs" />
+    <GetParticleParameters />
+    <div class="q-ma-xs" />
+    <GetModesToPlot />
+    <div class="q-ma-xs" />
+    <GetPlotSettings />
+    <div class="q-ma-xs" />
+    <RunSimulationSpectrum />
+    <!--    <div class="col-auto q-pa-md">-->
+    <!--      Input result: {{$store.state.plotRuntime.isPlotQabs}}-->
+    <!--    </div>-->
+    <div class="q-ma-sm" />
+    <PlotSelector />
+    <div class="q-ma-xs" />
+    <PlotSpectra />
 
     <!-- place QPageScroller at end of page -->
-    <div class="q-ma-lg"/>
-    <q-page-scroller position="bottom-right" :scroll-offset="150" :offset="[18, 18]">
+    <div class="q-ma-lg" />
+    <q-page-scroller
+      position="bottom-right"
+      :scroll-offset="150"
+      :offset="[18, 18]"
+    >
       <q-btn size="xs" fab icon="keyboard_arrow_up" color="primary" />
     </q-page-scroller>
   </q-page>
 </template>
 
-<script lang='ts'>
-import {
-  defineComponent,
-} from 'vue'
+<script lang="ts">
+import { defineComponent } from 'vue';
 
-import GetUnits from 'components/spectrum/GetUnits.vue'
-import GetHostIndex from 'components/spectrum/GetHostIndex.vue'
-import GetSourceParameters from 'components/spectrum/GetSourceParameters.vue'
-import GetParticleParameters from 'components/spectrum/GetParticleParameters.vue'
-import GetModesToPlot from 'components/spectrum/GetModesToPlot.vue'
-import RunSimulationSpectrum from 'components/spectrum/RunSimulationSpectrum.vue'
-import GetPlotSettings from 'components/spectrum/GetPlotSettings.vue'
-import PlotSelector from 'components/spectrum/PlotSelector.vue'
-import PlotSpectra from 'components/spectrum/PlotSpectra.vue'
+import GetUnits from 'components/spectrum/GetUnits.vue';
+import GetHostIndex from 'components/spectrum/GetHostIndex.vue';
+import GetSourceParameters from 'components/spectrum/GetSourceParameters.vue';
+import GetParticleParameters from 'components/spectrum/GetParticleParameters.vue';
+import GetModesToPlot from 'components/spectrum/GetModesToPlot.vue';
+import RunSimulationSpectrum from 'components/spectrum/RunSimulationSpectrum.vue';
+import GetPlotSettings from 'components/spectrum/GetPlotSettings.vue';
+import PlotSelector from 'components/spectrum/PlotSelector.vue';
+import PlotSpectra from 'components/spectrum/PlotSpectra.vue';
 // import { useStore } from 'src/store'
 
-
 export default defineComponent({
   name: 'SpectrumPage',
   components: {
     GetModesToPlot,
-    RunSimulationSpectrum, GetUnits, GetHostIndex,
-    GetSourceParameters, GetParticleParameters,
-    GetPlotSettings, PlotSelector,
-    PlotSpectra
+    RunSimulationSpectrum,
+    GetUnits,
+    GetHostIndex,
+    GetSourceParameters,
+    GetParticleParameters,
+    GetPlotSettings,
+    PlotSelector,
+    PlotSpectra,
   },
   // setup() {
   //   const $store = useStore()
   // }
-})
+});
 </script>

+ 7 - 5
guiapp/src/router/index.ts

@@ -1,12 +1,12 @@
-import { route } from 'quasar/wrappers'
+import { route } from 'quasar/wrappers';
 import {
   createMemoryHistory,
   createRouter,
   createWebHashHistory,
   createWebHistory,
-} from 'vue-router'
-import { StateInterface } from '../store'
-import routes from './routes'
+} from 'vue-router';
+import { StateInterface } from '../store';
+import routes from './routes';
 // import { nextTick } from 'vue'
 
 /*
@@ -21,7 +21,9 @@ import routes from './routes'
 export default route<StateInterface>(function (/* { store, ssrContext } */) {
   const createHistory = process.env.SERVER
     ? createMemoryHistory
-    : (process.env.VUE_ROUTER_MODE === 'history' ? createWebHistory : createWebHashHistory);
+    : process.env.VUE_ROUTER_MODE === 'history'
+    ? createWebHistory
+    : createWebHashHistory;
 
   const Router = createRouter({
     // scrollBehavior (to, from, savedPosition) {

+ 67 - 53
guiapp/src/store/gui-runtime/actions.ts

@@ -1,84 +1,98 @@
-import { ActionTree } from 'vuex'
-import { StateInterface } from '../index'
-import { guiRuntimeStateInterface } from './state'
-import { composeLabelFromPageData } from 'components/utils'
-import { load } from 'js-yaml'
-import Spline from 'cubic-spline-ts'
+import { ActionTree } from 'vuex';
+import { StateInterface } from '../index';
+import { guiRuntimeStateInterface } from './state';
+import { composeLabelFromPageData } from 'components/utils';
+import { load } from 'js-yaml';
+import Spline from 'cubic-spline-ts';
 
-
-async function loadMaterialData(filename:string):Promise<number[][] | undefined>{ /* eslint-disable */
+async function loadMaterialData(
+  filename: string
+): Promise<number[][] | undefined> {
+  /* eslint-disable */
   // TODO enable eslint, which is disabled now due to unknown result type of load() from js-yaml
   // TODO implement formulas
   // TODO implement multiple '- type:' in one file (e.g. it can be 'tabulated n' and 'tabulated k'
 
-  let Ag_data
+  let Ag_data;
 
   try {
-    const response = await fetch(process.env.publicPath+'refractiveindex.info-database/database/data/'+filename)
-    const Ag_data = await response.text()
+    const response = await fetch(
+      process.env.publicPath +
+        'refractiveindex.info-database/database/data/' +
+        filename
+    );
+    const Ag_data = await response.text();
 
-    const doc = await load(Ag_data) as any
-    if (doc.DATA[0].type == 'tabulated nk' || doc.DATA[0].type == 'tabulated n') {
-      const csv = doc.DATA[0].data
-      const rows:string[] = csv.split("\n")
-      let data =  rows.map(row =>row.split(" "))
-      data.pop()
-      let data_num = data.map(elem => elem.map(elem2 => parseFloat(elem2)))
+    const doc = (await load(Ag_data)) as any;
+    if (
+      doc.DATA[0].type == 'tabulated nk' ||
+      doc.DATA[0].type == 'tabulated n'
+    ) {
+      const csv = doc.DATA[0].data;
+      const rows: string[] = csv.split('\n');
+      let data = rows.map((row) => row.split(' '));
+      data.pop();
+      let data_num = data.map((elem) => elem.map((elem2) => parseFloat(elem2)));
 
-      function transpose(array:number[][]) {
-        return array[0].map((col, i) => array.map(row => row[i]));
+      function transpose(array: number[][]) {
+        return array[0].map((col, i) => array.map((row) => row[i]));
       }
 
-      let data_columns = transpose(data_num)
+      let data_columns = transpose(data_num);
       // Convert from default refractiveindex.info mkm to nm
 
-      for (let i=0; i<data_columns[0].length; i++)
-        data_columns[0][i] *= 1000
-      return data_columns
+      for (let i = 0; i < data_columns[0].length; i++)
+        data_columns[0][i] *= 1000;
+      return data_columns;
     }
   } catch (e) {
-    console.log(e)
+    console.log(e);
   }
-  return undefined
+  return undefined;
 }
 
-
 const actions: ActionTree<guiRuntimeStateInterface, StateInterface> = {
-  async activateMaterial({commit,state}/* context */, filepath:string) {
-    const data_columns:number[][]|undefined = await loadMaterialData(filepath)
-    if (!data_columns) return
-    let xs:number[] = data_columns[0]
-    let ys1:number[] = data_columns[1]
-    let ys2:number[] = data_columns[1].map(()=>0)
-    if (data_columns[2]) ys2 = data_columns[2]
-    const maxVal = 350 // TODO move it to config.ts
+  async activateMaterial({ commit, state } /* context */, filepath: string) {
+    const data_columns: number[][] | undefined = await loadMaterialData(
+      filepath
+    );
+    if (!data_columns) return;
+    let xs: number[] = data_columns[0];
+    let ys1: number[] = data_columns[1];
+    let ys2: number[] = data_columns[1].map(() => 0);
+    if (data_columns[2]) ys2 = data_columns[2];
+    const maxVal = 350; // TODO move it to config.ts
     if (xs.length > maxVal) {
       const delta = Math.floor(xs.length / maxVal);
-      let tmp_xs:number[] = []
-      let tmp_ys1:number[] = []
-      let tmp_ys2:number[] = []
+      let tmp_xs: number[] = [];
+      let tmp_ys1: number[] = [];
+      let tmp_ys2: number[] = [];
       for (let i = 0; i < xs.length; i = i + delta) {
-        tmp_xs.push(xs[i])
-        tmp_ys1.push(ys1[i])
-        tmp_ys2.push(ys2[i])
+        tmp_xs.push(xs[i]);
+        tmp_ys1.push(ys1[i]);
+        tmp_ys2.push(ys2[i]);
       }
-      xs = tmp_xs
-      ys1 = tmp_ys1
-      ys2 = tmp_ys2
+      xs = tmp_xs;
+      ys1 = tmp_ys1;
+      ys2 = tmp_ys2;
     }
 
     // TODO use 10.1016/j.cagd.2010.10.002 or https://en.wikipedia.org/wiki/Monotone_cubic_interpolation
     const spline_n = new Spline(xs, ys1);
     const spline_k = new Spline(xs, ys2);
 
-    const name = composeLabelFromPageData(filepath)
-    const spectrumRangeStart = xs[0]
-    const spectrumRangeEnd = xs[xs.length-1]
-    commit('addMaterial', {name:name,
-      spectrumRangeStart:spectrumRangeStart, spectrumRangeEnd:spectrumRangeEnd,
-      nSpline:spline_n, kSpline:spline_k, isPlot:false})
+    const name = composeLabelFromPageData(filepath);
+    const spectrumRangeStart = xs[0];
+    const spectrumRangeEnd = xs[xs.length - 1];
+    commit('addMaterial', {
+      name: name,
+      spectrumRangeStart: spectrumRangeStart,
+      spectrumRangeEnd: spectrumRangeEnd,
+      nSpline: spline_n,
+      kSpline: spline_k,
+      isPlot: false,
+    });
   },
+};
 
-}
-
-export default actions
+export default actions;

+ 39 - 27
guiapp/src/store/gui-runtime/mutations.ts

@@ -1,46 +1,58 @@
-import { MutationTree } from 'vuex'
-import { guiRuntimeStateInterface as grsi} from './state'
-import { material } from 'src/store/simulation-setup/state'
-
-function compare( a:material, b:material ) {
-  if (a.name == 'link') return -1
-  if (b.name == 'link') return 1
-  if (a.name == 'nk-constant') return -1
-  if (b.name == 'nk-constant') return 1
-
-  if (a.name < b.name ) return -1
-  if (a.name > b.name) return 1
+import { MutationTree } from 'vuex';
+import { guiRuntimeStateInterface as grsi } from './state';
+import { material } from 'src/store/simulation-setup/state';
+
+function compare(a: material, b: material) {
+  if (a.name == 'link') return -1;
+  if (b.name == 'link') return 1;
+  if (a.name == 'nk-constant') return -1;
+  if (b.name == 'nk-constant') return 1;
+
+  if (a.name < b.name) return -1;
+  if (a.name > b.name) return 1;
   return 0;
 }
 
 const mutation: MutationTree<grsi> = {
-  setIsShowingHelpForInputWithUnits (state: grsi, val: boolean) {state.isShowingHelpForInputWithUnits = val},
-  setUnits             (state: grsi, val: string ) {state.units             = val},
-  setSourceUnits       (state: grsi, val: string ) {state.sourceUnits       = val},
-  setIsSourceSameUnits (state: grsi, val: boolean) {state.isSourceSameUnits = val},
+  setIsShowingHelpForInputWithUnits(state: grsi, val: boolean) {
+    state.isShowingHelpForInputWithUnits = val;
+  },
+  setUnits(state: grsi, val: string) {
+    state.units = val;
+  },
+  setSourceUnits(state: grsi, val: string) {
+    state.sourceUnits = val;
+  },
+  setIsSourceSameUnits(state: grsi, val: boolean) {
+    state.isSourceSameUnits = val;
+  },
 
-  setSafeWL            (state: grsi, val: {safeFromWL:number, safeToWL:number}) {
-    state.safeFromWL = val.safeFromWL
-    state.safeToWL = val.safeToWL
+  setSafeWL(state: grsi, val: { safeFromWL: number; safeToWL: number }) {
+    state.safeFromWL = val.safeFromWL;
+    state.safeToWL = val.safeToWL;
   },
 
-  addMaterial(state: grsi, material:material) {
-    state.activatedMaterials.push(material)
-    state.activatedMaterials.sort( compare );
+  addMaterial(state: grsi, material: material) {
+    state.activatedMaterials.push(material);
+    state.activatedMaterials.sort(compare);
   },
 
   deleteMaterial(state: grsi, label: string) {
-    const indexToDelete = state.activatedMaterials.findIndex(val => val.name==label)
-    state.activatedMaterials.splice(indexToDelete,1)
+    const indexToDelete = state.activatedMaterials.findIndex(
+      (val) => val.name == label
+    );
+    state.activatedMaterials.splice(indexToDelete, 1);
   },
   // @click="$store.commit('guiRuntime/toggleIsPlot',
   // props.row.name
 
   toggleIsPlot(state: grsi, label: string) {
-    const indexToToggle = state.activatedMaterials.findIndex(val => val.name==label)
-    state.activatedMaterials[indexToToggle].isPlot = !state.activatedMaterials[indexToToggle].isPlot
+    const indexToToggle = state.activatedMaterials.findIndex(
+      (val) => val.name == label
+    );
+    state.activatedMaterials[indexToToggle].isPlot =
+      !state.activatedMaterials[indexToToggle].isPlot;
   },
-
 };
 
 export default mutation;

+ 29 - 18
guiapp/src/store/gui-runtime/state.ts

@@ -1,16 +1,15 @@
-import { material } from 'src/store/simulation-setup/state'
+import { material } from 'src/store/simulation-setup/state';
 
 // All numbers with units (e.g. size, radius, wavelength, e.g.) are given in nanometers.
 
-
 export interface guiRuntimeStateInterface {
-  isShowingHelpForInputWithUnits: boolean
-  units: string
-  sourceUnits: string
-  isSourceSameUnits: boolean
-  activatedMaterials: material[]
-  safeFromWL:number
-  safeToWL:number
+  isShowingHelpForInputWithUnits: boolean;
+  units: string;
+  sourceUnits: string;
+  isSourceSameUnits: boolean;
+  activatedMaterials: material[];
+  safeFromWL: number;
+  safeToWL: number;
 }
 
 function state(): guiRuntimeStateInterface {
@@ -19,16 +18,28 @@ function state(): guiRuntimeStateInterface {
     units: 'nm',
     sourceUnits: 'nm',
     isSourceSameUnits: true,
-    safeFromWL:0,
-    safeToWL:1e300,
+    safeFromWL: 0,
+    safeToWL: 1e300,
     activatedMaterials: [
-        // 'PEC',
-      {name:'link',  spectrumRangeStart:0, spectrumRangeEnd:1e300,
-        nSpline: undefined, kSpline: undefined, isPlot:false},
-      {name:'nk-constant',  spectrumRangeStart:0, spectrumRangeEnd:1e300,
-        nSpline: undefined, kSpline: undefined, isPlot:false},
-    ]
-  }
+      // 'PEC',
+      {
+        name: 'link',
+        spectrumRangeStart: 0,
+        spectrumRangeEnd: 1e300,
+        nSpline: undefined,
+        kSpline: undefined,
+        isPlot: false,
+      },
+      {
+        name: 'nk-constant',
+        spectrumRangeStart: 0,
+        spectrumRangeEnd: 1e300,
+        nSpline: undefined,
+        kSpline: undefined,
+        isPlot: false,
+      },
+    ],
+  };
 }
 
 export default state;

+ 14 - 13
guiapp/src/store/index.ts

@@ -1,18 +1,18 @@
-import { store } from 'quasar/wrappers'
-import { InjectionKey } from 'vue'
+import { store } from 'quasar/wrappers';
+import { InjectionKey } from 'vue';
 import {
   createStore,
   Store as VuexStore,
   useStore as vuexUseStore,
-} from 'vuex'
+} from 'vuex';
 
-import guiRuntime from './gui-runtime'
+import guiRuntime from './gui-runtime';
 import { guiRuntimeStateInterface } from './gui-runtime/state';
 
-import plotRuntime from './plot-runtime'
+import plotRuntime from './plot-runtime';
 import { plotRuntimeStateInterface } from './plot-runtime/state';
 
-import simulationSetup from './simulation-setup'
+import simulationSetup from './simulation-setup';
 import { simulationSetupStateInterface } from './simulation-setup/state';
 
 /*
@@ -36,29 +36,30 @@ export interface StateInterface {
 // provide typings for `this.$store`
 declare module '@vue/runtime-core' {
   interface ComponentCustomProperties {
-    $store: VuexStore<StateInterface>
+    $store: VuexStore<StateInterface>;
   }
 }
 
 // provide typings for `useStore` helper
-export const storeKey: InjectionKey<VuexStore<StateInterface>> = Symbol('vuex-key')
+export const storeKey: InjectionKey<VuexStore<StateInterface>> =
+  Symbol('vuex-key');
 
 export default store(function (/* { ssrContext } */) {
   const Store = createStore<StateInterface>({
     modules: {
       guiRuntime,
       plotRuntime,
-      simulationSetup
+      simulationSetup,
     },
 
     // enable strict mode (adds overhead!)
     // for dev mode and --debug builds only
-    strict: !!process.env.DEBUGGING
-  })
+    strict: !!process.env.DEBUGGING,
+  });
 
   return Store;
-})
+});
 
 export function useStore() {
-  return vuexUseStore(storeKey)
+  return vuexUseStore(storeKey);
 }

+ 119 - 70
guiapp/src/store/plot-runtime/mutations.ts

@@ -1,83 +1,114 @@
-import { MutationTree } from 'vuex'
-import { cloneDeep } from 'lodash'
-import { AxisType, Data } from 'plotly.js-dist-min'
-import { plotRuntimeStateInterface as prsi, spectraData } from './state'
-import { getModeName, toUnits } from 'components/utils'
-
+import { MutationTree } from 'vuex';
+import { cloneDeep } from 'lodash';
+import { AxisType, Data } from 'plotly.js-dist-min';
+import { plotRuntimeStateInterface as prsi, spectraData } from './state';
+import { getModeName, toUnits } from 'components/utils';
 
 const mutation: MutationTree<prsi> = {
-  setNearField (state: prsi, val: Float64Array) {state.nearFieldEabs = cloneDeep(val)},
-  setNearFieldCoords (state: prsi, val: {x:number[], y:number[]} ) {
-    state.nearFieldCoordX = cloneDeep(val.x)
-    state.nearFieldCoordY = cloneDeep(val.y)
-  },
-  setNearFieldDataFrom (state: prsi, val: number) {state.nearFieldDataFrom = val},
-  setNearFieldDataTo (state: prsi, val: number) {state.nearFieldDataTo = val},
-  setNearFieldLimitFrom (state: prsi, val: number) {state.nearFieldLimitFrom = val},
-  setNearFieldLimitTo (state: prsi, val: number) {state.nearFieldLimitTo = val},
+  setNearField(state: prsi, val: Float64Array) {
+    state.nearFieldEabs = cloneDeep(val);
+  },
+  setNearFieldCoords(state: prsi, val: { x: number[]; y: number[] }) {
+    state.nearFieldCoordX = cloneDeep(val.x);
+    state.nearFieldCoordY = cloneDeep(val.y);
+  },
+  setNearFieldDataFrom(state: prsi, val: number) {
+    state.nearFieldDataFrom = val;
+  },
+  setNearFieldDataTo(state: prsi, val: number) {
+    state.nearFieldDataTo = val;
+  },
+  setNearFieldLimitFrom(state: prsi, val: number) {
+    state.nearFieldLimitFrom = val;
+  },
+  setNearFieldLimitTo(state: prsi, val: number) {
+    state.nearFieldLimitTo = val;
+  },
 
-  setQ (state: prsi, val: spectraData) {
-    state.WLs    = cloneDeep(val.WLs)
-    state.Qsca   = cloneDeep(val.Qsca)
-    state.Qabs   = cloneDeep(val.Qabs)
-    state.Qext   = cloneDeep(val.Qext)
-    state.Qsca_n = cloneDeep(val.Qsca_n)
-    state.Qabs_n = cloneDeep(val.Qabs_n)
-    state.Qext_n = cloneDeep(val.Qext_n)
+  setQ(state: prsi, val: spectraData) {
+    state.WLs = cloneDeep(val.WLs);
+    state.Qsca = cloneDeep(val.Qsca);
+    state.Qabs = cloneDeep(val.Qabs);
+    state.Qext = cloneDeep(val.Qext);
+    state.Qsca_n = cloneDeep(val.Qsca_n);
+    state.Qabs_n = cloneDeep(val.Qabs_n);
+    state.Qext_n = cloneDeep(val.Qext_n);
   },
 
-  setWLsInUnits (state:prsi, sourceUnits:string) {
-    const converted:number[] = []
-    for (const WL of state.WLs) converted.push(toUnits(WL, sourceUnits))
-    state.WLsInUnits = converted //assign it once to avoid multiple reactivity updates of the spectra plot
+  setWLsInUnits(state: prsi, sourceUnits: string) {
+    const converted: number[] = [];
+    for (const WL of state.WLs) converted.push(toUnits(WL, sourceUnits));
+    state.WLsInUnits = converted; //assign it once to avoid multiple reactivity updates of the spectra plot
   },
 
-  setQscaPlotToggle (state: prsi, val: boolean) {state.isPlotQsca = val},
-  setQabsPlotToggle (state: prsi, val: boolean) {state.isPlotQabs = val},
-  setQextPlotToggle (state: prsi, val: boolean) {state.isPlotQext = val},
-  setQscaTotalPlotToggle (state: prsi, val: boolean) {state.isPlotQscaTotal = val},
-  setQabsTotalPlotToggle (state: prsi, val: boolean) {state.isPlotQabsTotal = val},
-  setQextTotalPlotToggle (state: prsi, val: boolean) {state.isPlotQextTotal = val},
-  setIsRemovePlots (state:prsi, val:boolean) {state.isRemovePlots = val},
-  setIsLogPlot (state:prsi, val:boolean) {state.isLogPlot = val},
-  setCommonLabel  (state:prsi, val:string) {state.commonLabel = val},
+  setQscaPlotToggle(state: prsi, val: boolean) {
+    state.isPlotQsca = val;
+  },
+  setQabsPlotToggle(state: prsi, val: boolean) {
+    state.isPlotQabs = val;
+  },
+  setQextPlotToggle(state: prsi, val: boolean) {
+    state.isPlotQext = val;
+  },
+  setQscaTotalPlotToggle(state: prsi, val: boolean) {
+    state.isPlotQscaTotal = val;
+  },
+  setQabsTotalPlotToggle(state: prsi, val: boolean) {
+    state.isPlotQabsTotal = val;
+  },
+  setQextTotalPlotToggle(state: prsi, val: boolean) {
+    state.isPlotQextTotal = val;
+  },
+  setIsRemovePlots(state: prsi, val: boolean) {
+    state.isRemovePlots = val;
+  },
+  setIsLogPlot(state: prsi, val: boolean) {
+    state.isLogPlot = val;
+  },
+  setCommonLabel(state: prsi, val: string) {
+    state.commonLabel = val;
+  },
 
-  resizeSelectorIsPlotMode (state:prsi, val:number) {
+  resizeSelectorIsPlotMode(state: prsi, val: number) {
     while (state.isPlotModeE.length > val) state.isPlotModeE.pop();
     while (state.isPlotModeH.length > val) state.isPlotModeH.pop();
     while (state.isPlotModeE.length < val) state.isPlotModeE.push(false);
     while (state.isPlotModeH.length < val) state.isPlotModeH.push(false);
   },
-  setIsPlotModeE (state:prsi, val:boolean[]) {
-    for (let i = 0; i< val.length; ++i) state.isPlotModeE[i] = val[i]
+  setIsPlotModeE(state: prsi, val: boolean[]) {
+    for (let i = 0; i < val.length; ++i) state.isPlotModeE[i] = val[i];
   },
-  setIsPlotModeH (state:prsi, val:boolean[]) {
-    for (let i = 0; i< val.length; ++i) state.isPlotModeH[i] = val[i]
+  setIsPlotModeH(state: prsi, val: boolean[]) {
+    for (let i = 0; i < val.length; ++i) state.isPlotModeH[i] = val[i];
   },
 
-  updateXAxisTitle (state:prsi, val:string) {
-    if (state.spectrumPlots.layout.xaxis) state.spectrumPlots.layout.xaxis.title = val
+  updateXAxisTitle(state: prsi, val: string) {
+    if (state.spectrumPlots.layout.xaxis)
+      state.spectrumPlots.layout.xaxis.title = val;
   },
 
   updateNumberOfPlotsFromPreviousSimulations(state: prsi) {
-    state.numberOfPlotsFromPreviousSimulations = state.spectrumPlots.data.length
-  },
-  updateSpectrumPlots (state: prsi) {
-    if (state.isRemovePlots) state.numberOfPlotsFromPreviousSimulations = 0
-    state.spectrumPlots.data.length = state.numberOfPlotsFromPreviousSimulations
-    let logState:AxisType|undefined = undefined
-    if (state.isLogPlot) logState = 'log'
-    if (state.spectrumPlots.layout.yaxis) state.spectrumPlots.layout.yaxis.type = logState
+    state.numberOfPlotsFromPreviousSimulations =
+      state.spectrumPlots.data.length;
+  },
+  updateSpectrumPlots(state: prsi) {
+    if (state.isRemovePlots) state.numberOfPlotsFromPreviousSimulations = 0;
+    state.spectrumPlots.data.length =
+      state.numberOfPlotsFromPreviousSimulations;
+    let logState: AxisType | undefined = undefined;
+    if (state.isLogPlot) logState = 'log';
+    if (state.spectrumPlots.layout.yaxis)
+      state.spectrumPlots.layout.yaxis.type = logState;
 
-    const label:string = state.commonLabel
+    const label: string = state.commonLabel;
     if (state.isPlotQscaTotal) {
       const traceQsca: Partial<Data> = {
         x: state.WLsInUnits,
         y: state.Qsca,
         type: 'scatter',
-        name: 'Qsca '+label
-      }
-      state.spectrumPlots.data.push(traceQsca)
+        name: 'Qsca ' + label,
+      };
+      state.spectrumPlots.data.push(traceQsca);
     }
 
     if (state.isPlotQabsTotal) {
@@ -85,9 +116,9 @@ const mutation: MutationTree<prsi> = {
         x: state.WLsInUnits,
         y: state.Qabs,
         type: 'scatter',
-        name: 'Qabs '+label
-      }
-      state.spectrumPlots.data.push(traceQabs)
+        name: 'Qabs ' + label,
+      };
+      state.spectrumPlots.data.push(traceQabs);
     }
 
     if (state.isPlotQextTotal) {
@@ -95,24 +126,31 @@ const mutation: MutationTree<prsi> = {
         x: state.WLsInUnits,
         y: state.Qext,
         type: 'scatter',
-        name: 'Qext '+label
-      }
-      state.spectrumPlots.data.push(traceQext)
+        name: 'Qext ' + label,
+      };
+      state.spectrumPlots.data.push(traceQext);
     }
 
-    const typeNames = ['E', 'H']
-    const totalEvaluatedModes = state.Qsca_n[0].length
+    const typeNames = ['E', 'H'];
+    const totalEvaluatedModes = state.Qsca_n[0].length;
 
     for (let modeType = 0; modeType < 2; ++modeType) {
       for (let mode_n = 0; mode_n < totalEvaluatedModes; ++mode_n) {
-        const isPlotMode = modeType === 0 ? state.isPlotModeE : state.isPlotModeH;
+        const isPlotMode =
+          modeType === 0 ? state.isPlotModeE : state.isPlotModeH;
         if (!isPlotMode[mode_n]) continue;
         if (state.isPlotQsca) {
           const traceQsca: Partial<Data> = {
             x: state.WLsInUnits,
             y: state.Qsca_n[modeType][mode_n],
             type: 'scatter',
-            name: 'Qsca ' + typeNames[modeType] + ' ' + getModeName(mode_n + 1)+' '+label
+            name:
+              'Qsca ' +
+              typeNames[modeType] +
+              ' ' +
+              getModeName(mode_n + 1) +
+              ' ' +
+              label,
           };
           state.spectrumPlots.data.push(traceQsca);
         }
@@ -121,7 +159,13 @@ const mutation: MutationTree<prsi> = {
             x: state.WLsInUnits,
             y: state.Qabs_n[modeType][mode_n],
             type: 'scatter',
-            name: 'Qabs ' + typeNames[modeType] + ' ' + getModeName(mode_n + 1)+' '+label
+            name:
+              'Qabs ' +
+              typeNames[modeType] +
+              ' ' +
+              getModeName(mode_n + 1) +
+              ' ' +
+              label,
           };
           state.spectrumPlots.data.push(traceQabs);
         }
@@ -130,14 +174,19 @@ const mutation: MutationTree<prsi> = {
             x: state.WLsInUnits,
             y: state.Qext_n[modeType][mode_n],
             type: 'scatter',
-            name: 'Qext ' + typeNames[modeType] + ' ' + getModeName(mode_n + 1)+' '+label
+            name:
+              'Qext ' +
+              typeNames[modeType] +
+              ' ' +
+              getModeName(mode_n + 1) +
+              ' ' +
+              label,
           };
           state.spectrumPlots.data.push(traceQext);
         }
       }
     }
   },
+};
 
-}
-
-export default mutation
+export default mutation;

+ 107 - 86
guiapp/src/store/plot-runtime/state.ts

@@ -1,127 +1,148 @@
-import { Data, Layout, Config } from 'plotly.js-dist-min'
+import { Data, Layout, Config } from 'plotly.js-dist-min';
 
 export interface plotlyChart {
-  data: Data[],
-  layout: Partial<Layout>,
-  config: Partial<Config>|undefined
+  data: Data[];
+  layout: Partial<Layout>;
+  config: Partial<Config> | undefined;
 }
 
 export interface spectraData {
-  WLs: number[]
-  Qsca:number[]
-  Qabs:number[]
-  Qext:number[]
-  Qsca_n:number[][][]
-  Qabs_n:number[][][]
-  Qext_n:number[][][]
+  WLs: number[];
+  Qsca: number[];
+  Qabs: number[];
+  Qext: number[];
+  Qsca_n: number[][][];
+  Qabs_n: number[][][];
+  Qext_n: number[][][];
 }
 
 export interface plotRuntimeStateInterface {
   // Near field
-  nearFieldEabs:Float64Array|undefined
-  nearFieldCoordX: number []
-  nearFieldCoordY: number []
-  nearFieldDataFrom: number
-  nearFieldDataTo: number
-  nearFieldLimitFrom: number
-  nearFieldLimitTo: number
+  nearFieldEabs: Float64Array | undefined;
+  nearFieldCoordX: number[];
+  nearFieldCoordY: number[];
+  nearFieldDataFrom: number;
+  nearFieldDataTo: number;
+  nearFieldLimitFrom: number;
+  nearFieldLimitTo: number;
   // Spectra plots
-  WLs: number[]
-  WLsInUnits: number[]
-  Qsca:number[]
-  Qabs:number[]
-  Qext:number[]
-  Qsca_n:number[][][]
-  Qabs_n:number[][][]
-  Qext_n:number[][][]
-  spectrumPlots: plotlyChart
-  isPlotQsca: boolean
-  isPlotQabs: boolean
-  isPlotQext: boolean
-  isPlotQscaTotal: boolean
-  isPlotQabsTotal: boolean
-  isPlotQextTotal: boolean
-  isPlotModeE: boolean[]
-  isPlotModeH: boolean[]
-  isRemovePlots: boolean
-  isLogPlot:boolean
-  numberOfPlotsFromPreviousSimulations:number
-  commonLabel:string
+  WLs: number[];
+  WLsInUnits: number[];
+  Qsca: number[];
+  Qabs: number[];
+  Qext: number[];
+  Qsca_n: number[][][];
+  Qabs_n: number[][][];
+  Qext_n: number[][][];
+  spectrumPlots: plotlyChart;
+  isPlotQsca: boolean;
+  isPlotQabs: boolean;
+  isPlotQext: boolean;
+  isPlotQscaTotal: boolean;
+  isPlotQabsTotal: boolean;
+  isPlotQextTotal: boolean;
+  isPlotModeE: boolean[];
+  isPlotModeH: boolean[];
+  isRemovePlots: boolean;
+  isLogPlot: boolean;
+  numberOfPlotsFromPreviousSimulations: number;
+  commonLabel: string;
 }
 
 function state(): plotRuntimeStateInterface {
-  const nearFieldEabs = undefined
-  const nearFieldCoordX:number[] = []
-  const nearFieldCoordY:number[] = []
-  const nearFieldDataFrom = 0
-  const nearFieldDataTo = 1e300
-  const nearFieldLimitFrom = 0
-  const nearFieldLimitTo = 1e300
+  const nearFieldEabs = undefined;
+  const nearFieldCoordX: number[] = [];
+  const nearFieldCoordY: number[] = [];
+  const nearFieldDataFrom = 0;
+  const nearFieldDataTo = 1e300;
+  const nearFieldLimitFrom = 0;
+  const nearFieldLimitTo = 1e300;
 
-  const WLs:number[] = []
-  const WLsInUnits:number[] = []
-  const Qsca:number[] = [], Qabs:number[] = [], Qext:number[] = []
-  const Qsca_n:number[][][] = [[], []]
-  const Qabs_n:number[][][] = [[], []]
-  const Qext_n:number[][][] = [[], []]
-  const isPlotQsca = true
-  const isPlotQabs = false
-  const isPlotQext = false
-  const isPlotQscaTotal = true
-  const isPlotQabsTotal = false
-  const isPlotQextTotal = false
-  const isPlotModeE:boolean[] = [true]
-  const isPlotModeH:boolean[] = [true]
-  const numberOfPlotsFromPreviousSimulations = 0
-  const commonLabel=''
+  const WLs: number[] = [];
+  const WLsInUnits: number[] = [];
+  const Qsca: number[] = [],
+    Qabs: number[] = [],
+    Qext: number[] = [];
+  const Qsca_n: number[][][] = [[], []];
+  const Qabs_n: number[][][] = [[], []];
+  const Qext_n: number[][][] = [[], []];
+  const isPlotQsca = true;
+  const isPlotQabs = false;
+  const isPlotQext = false;
+  const isPlotQscaTotal = true;
+  const isPlotQabsTotal = false;
+  const isPlotQextTotal = false;
+  const isPlotModeE: boolean[] = [true];
+  const isPlotModeH: boolean[] = [true];
+  const numberOfPlotsFromPreviousSimulations = 0;
+  const commonLabel = '';
 
-  const spectrumPlots:plotlyChart = {
+  const spectrumPlots: plotlyChart = {
     data: [],
     layout: {
       margin: {
         l: 0,
         r: 40,
         b: 50,
-        t: 0
+        t: 0,
       },
       // paper_bgcolor: '#7f7f7f',
       // plot_bgcolor: '#c7c7c7',
       // title: 'reactive charts',
       xaxis: {
         // will be set on mount
-        title: 'Wavelength, nm'
+        title: 'Wavelength, nm',
       },
       yaxis: {
-        title: 'Normalized cross-sections'
+        title: 'Normalized cross-sections',
       },
       showlegend: true,
       legend: {
         orientation: 'h',
-        x: -.15,
-        y: 1.12
+        x: -0.15,
+        y: 1.12,
       },
     },
-    config: {responsive: true,
+    config: {
+      responsive: true,
       // showEditInChartStudio: true,
-      displaylogo: false}
-  }
-  const isRemovePlots = true
-  const isLogPlot = false
+      displaylogo: false,
+    },
+  };
+
+  const isRemovePlots = true;
+  const isLogPlot = false;
 
   return {
-    nearFieldEabs: nearFieldEabs,
-    nearFieldCoordX, nearFieldCoordY,
-    nearFieldDataFrom,  nearFieldDataTo,
-    nearFieldLimitFrom, nearFieldLimitTo,
-    WLs, WLsInUnits,
-    Qsca, Qabs, Qext, Qsca_n, Qabs_n, Qext_n,
+    nearFieldEabs,
+    nearFieldCoordX,
+    nearFieldCoordY,
+    nearFieldDataFrom,
+    nearFieldDataTo,
+    nearFieldLimitFrom,
+    nearFieldLimitTo,
+    WLs,
+    WLsInUnits,
+    Qsca,
+    Qabs,
+    Qext,
+    Qsca_n,
+    Qabs_n,
+    Qext_n,
     spectrumPlots,
-    isPlotQsca, isPlotQabs, isPlotQext,
-    isPlotQscaTotal, isPlotQabsTotal, isPlotQextTotal,
-    isPlotModeE, isPlotModeH,
-    isRemovePlots, isLogPlot, numberOfPlotsFromPreviousSimulations,
-    commonLabel
-  }
+    isPlotQsca,
+    isPlotQabs,
+    isPlotQext,
+    isPlotQscaTotal,
+    isPlotQabsTotal,
+    isPlotQextTotal,
+    isPlotModeE,
+    isPlotModeH,
+    isRemovePlots,
+    isLogPlot,
+    numberOfPlotsFromPreviousSimulations,
+    commonLabel,
+  };
 }
 
-export default state
+export default state;

+ 13 - 14
guiapp/src/store/simulation-setup/actions.ts

@@ -2,23 +2,23 @@ import { ActionTree } from 'vuex';
 import { StateInterface } from '../index';
 import { simulationSetupStateInterface } from './state';
 import nmiejs from 'src/nmiejs.js';
-import { useQuasar } from 'quasar'
-
+import { useQuasar } from 'quasar';
 
 const actions: ActionTree<simulationSetupStateInterface, StateInterface> = {
-  async loadScattnlay ({commit,/*state*/}/* context */) {
-    const $q = useQuasar()
+  async loadScattnlay({ commit /*state*/ } /* context */) {
+    const $q = useQuasar();
     $q.loading.show({
       message: 'Loading Mie calculator. Please wait...',
       boxClass: 'bg-grey-2 text-grey-9',
-      spinnerColor: 'primary'
-    })
-    const module = await nmiejs()
-    const nmies = {spectrum: new module.nmie(),
+      spinnerColor: 'primary',
+    });
+    const module = await nmiejs();
+    const nmies = {
+      spectrum: new module.nmie(),
       nearField: new module.nmie(),
-      farField: new module.nmie()}
-    commit('setNmies', nmies)
-
+      farField: new module.nmie(),
+    };
+    commit('setNmies', nmies);
 
     // // Test nmiejs if working
     // if (state.nmies.spectrum.instance && !state.nmies.spectrum.isNmieRunning) {
@@ -42,9 +42,8 @@ const actions: ActionTree<simulationSetupStateInterface, StateInterface> = {
     //   commit('markNmieAsFinished')
     // }
 
-
-    $q.loading.hide()
-  }
+    $q.loading.hide();
+  },
 };
 
 export default actions;

+ 90 - 56
guiapp/src/store/simulation-setup/mutations.ts

@@ -1,85 +1,119 @@
 import { MutationTree } from 'vuex';
-import { simulationSetupStateInterface as sssi, simulationSetup, layer, nearFieldPlane } from './state';
-import { cloneDeep } from 'lodash'
-import { markRaw} from 'vue'
+import {
+  simulationSetupStateInterface as sssi,
+  simulationSetup,
+  layer,
+  nearFieldPlane,
+} from './state';
+import { cloneDeep } from 'lodash';
+import { markRaw } from 'vue';
 
 const mutation: MutationTree<sssi> = {
-  setNmies (state: sssi,
-           newVal: {spectrum: import('src/nmiejs').nmie_class,
-             nearField: import('src/nmiejs').nmie_class,
-             farField: import('src/nmiejs').nmie_class
-           }) {
-    state.nmies.spectrum.instance = markRaw(newVal.spectrum)
-    state.nmies.nearField.instance = markRaw(newVal.nearField)
-    state.nmies.farField.instance = markRaw(newVal.farField)
-  },
-  markNmieAsStarted (state: sssi) {
-    state.nmies.spectrum.isNmieRunning = true
+  setNmies(
+    state: sssi,
+    newVal: {
+      spectrum: import('src/nmiejs').nmie_class;
+      nearField: import('src/nmiejs').nmie_class;
+      farField: import('src/nmiejs').nmie_class;
+    }
+  ) {
+    state.nmies.spectrum.instance = markRaw(newVal.spectrum);
+    state.nmies.nearField.instance = markRaw(newVal.nearField);
+    state.nmies.farField.instance = markRaw(newVal.farField);
+  },
+  markNmieAsStarted(state: sssi) {
+    state.nmies.spectrum.isNmieRunning = true;
   },
   markNmieAsFinished(state: sssi) {
-    state.nmies.spectrum.isNmieRunning = false
+    state.nmies.spectrum.isNmieRunning = false;
   },
-  setNmieTotalRunTime(state: sssi, val:number) {
-    state.nmies.spectrum.nmieTotalRunTime = val
+  setNmieTotalRunTime(state: sssi, val: number) {
+    state.nmies.spectrum.nmieTotalRunTime = val;
   },
 
-  markNmieNearFieldAsStarted (state: sssi) {
-    state.nmies.nearField.isNmieRunning = true
+  markNmieNearFieldAsStarted(state: sssi) {
+    state.nmies.nearField.isNmieRunning = true;
   },
   markNmieNearFieldAsFinished(state: sssi) {
-    state.nmies.nearField.isNmieRunning = false
+    state.nmies.nearField.isNmieRunning = false;
   },
-  setNmieNearFieldTotalRunTime(state: sssi, val:number) {
-    state.nmies.nearField.nmieTotalRunTime = val
+  setNmieNearFieldTotalRunTime(state: sssi, val: number) {
+    state.nmies.nearField.nmieTotalRunTime = val;
   },
 
-  markNmieFarFieldAsStarted (state: sssi) {
-    state.nmies.farField.isNmieRunning = true
+  markNmieFarFieldAsStarted(state: sssi) {
+    state.nmies.farField.isNmieRunning = true;
   },
   markNmieFarFieldAsFinished(state: sssi) {
-    state.nmies.farField.isNmieRunning = false
+    state.nmies.farField.isNmieRunning = false;
   },
-  setNmieFarFieldTotalRunTime(state: sssi, val:number) {
-    state.nmies.farField.nmieTotalRunTime = val
+  setNmieFarFieldTotalRunTime(state: sssi, val: number) {
+    state.nmies.farField.nmieTotalRunTime = val;
   },
 
-  setCurrentState (state: sssi,
-                   newVal: simulationSetup) {
-    state.current = cloneDeep(newVal)
+  setCurrentState(state: sssi, newVal: simulationSetup) {
+    state.current = cloneDeep(newVal);
   },
 
-  copySetupFromGuiToCurrent (state: sssi) {
-    state.current = cloneDeep(state.gui)
+  copySetupFromGuiToCurrent(state: sssi) {
+    state.current = cloneDeep(state.gui);
   },
 
   // Mutations for simulation setup as represented\set in GUI
-  setGuiState (state: sssi,
-               newVal: simulationSetup) {
-    state.gui = cloneDeep(newVal)
-  },
-  setLayers    (state: sssi,
-                newVal: layer[]) {
-    state.gui.layers = cloneDeep(newVal)
-  },
-  setHostIndex (state: sssi, val: number) {state.gui.hostIndex = val},
-  setFromWL    (state: sssi, val: number) {state.gui.fromWL    = val},
-  setToWL      (state: sssi, val: number) {state.gui.toWL      = val},
-  setPointsWL  (state: sssi, val: number) {state.gui.pointsWL  = val},
-  setPlotLabel (state: sssi, val: string) {state.gui.plotLabel = val},
-  setNumberOfModesToPlot  (state: sssi, val: number) {state.gui.numberOfModesToPlot  = val},
+  setGuiState(state: sssi, newVal: simulationSetup) {
+    state.gui = cloneDeep(newVal);
+  },
+  setLayers(state: sssi, newVal: layer[]) {
+    state.gui.layers = cloneDeep(newVal);
+  },
+  setHostIndex(state: sssi, val: number) {
+    state.gui.hostIndex = val;
+  },
+  setFromWL(state: sssi, val: number) {
+    state.gui.fromWL = val;
+  },
+  setToWL(state: sssi, val: number) {
+    state.gui.toWL = val;
+  },
+  setPointsWL(state: sssi, val: number) {
+    state.gui.pointsWL = val;
+  },
+  setPlotLabel(state: sssi, val: string) {
+    state.gui.plotLabel = val;
+  },
+  setNumberOfModesToPlot(state: sssi, val: number) {
+    state.gui.numberOfModesToPlot = val;
+  },
 
-  setNearFieldWL                 (state: sssi, val: number)         {state.gui.nearFieldSetup.atWL               = val},
-  setNearFieldRelativePlotSize   (state: sssi, val: number)         {state.gui.nearFieldSetup.relativePlotSize   = val},
-  setNearFieldAtRelativeX0       (state: sssi, val: number)         {state.gui.nearFieldSetup.atRelativeX0   = val},
-  setNearFieldAtRelativeY0       (state: sssi, val: number)         {state.gui.nearFieldSetup.atRelativeY0   = val},
-  setNearFieldAtRelativeZ0       (state: sssi, val: number)         {state.gui.nearFieldSetup.atRelativeZ0   = val},
-  setNearFieldPlotXSideResolution (state: sssi, val: number)      {state.gui.nearFieldSetup.plotXSideResolution = val},
-  setNearFieldPlotYSideResolution (state: sssi, val: number)      {state.gui.nearFieldSetup.plotYSideResolution = val},
-  setNearFieldCrossSection       (state: sssi, val: nearFieldPlane) {state.gui.nearFieldSetup.crossSection       = val},
+  setNearFieldWL(state: sssi, val: number) {
+    state.gui.nearFieldSetup.atWL = val;
+  },
+  setNearFieldRelativePlotSize(state: sssi, val: number) {
+    state.gui.nearFieldSetup.relativePlotSize = val;
+  },
+  setNearFieldAtRelativeX0(state: sssi, val: number) {
+    state.gui.nearFieldSetup.atRelativeX0 = val;
+  },
+  setNearFieldAtRelativeY0(state: sssi, val: number) {
+    state.gui.nearFieldSetup.atRelativeY0 = val;
+  },
+  setNearFieldAtRelativeZ0(state: sssi, val: number) {
+    state.gui.nearFieldSetup.atRelativeZ0 = val;
+  },
+  setNearFieldPlotXSideResolution(state: sssi, val: number) {
+    state.gui.nearFieldSetup.plotXSideResolution = val;
+  },
+  setNearFieldPlotYSideResolution(state: sssi, val: number) {
+    state.gui.nearFieldSetup.plotYSideResolution = val;
+  },
+  setNearFieldCrossSection(state: sssi, val: nearFieldPlane) {
+    state.gui.nearFieldSetup.crossSection = val;
+  },
   // setNearFieldMaxComputeTime     (state: sssi, val: number)         {state.gui.nearFieldSetup.maxComputeTime     = val},
 
-  setFarFieldWL    (state: sssi, val: number) { state.gui.farFieldWL  = val},
-
+  setFarFieldWL(state: sssi, val: number) {
+    state.gui.farFieldWL = val;
+  },
 };
 
 export default mutation;

+ 105 - 77
guiapp/src/store/simulation-setup/state.ts

@@ -1,123 +1,151 @@
-import { cloneDeep } from 'lodash'
-import Spline from 'cubic-spline-ts'
+import { cloneDeep } from 'lodash';
+import Spline from 'cubic-spline-ts';
 
 // All numbers with units (e.g. size, radius, wavelength, e.g.) are given in nanometers.
 
 export interface material {
-  name: string
-  spectrumRangeStart:number|undefined
-  spectrumRangeEnd:number|undefined
-  nSpline: Spline|undefined
-  kSpline: Spline|undefined
-  isPlot: boolean|undefined
+  name: string;
+  spectrumRangeStart: number | undefined;
+  spectrumRangeEnd: number | undefined;
+  nSpline: Spline | undefined;
+  kSpline: Spline | undefined;
+  isPlot: boolean | undefined;
 }
 
 export interface layer {
-  layerWidth: number
-  material: material
-  n: number
-  k: number
+  layerWidth: number;
+  material: material;
+  n: number;
+  k: number;
 }
 
 export enum nearFieldPlane {
   Ek = 0,
   Hk,
-  EH = 2
+  EH = 2,
 }
 
 export interface nearFieldSetup {
-  atWL:number
-  relativePlotSize: number
+  atWL: number;
+  relativePlotSize: number;
   // X0, Y0, and Z0 refers to simulation
-  atRelativeX0: number
-  atRelativeY0: number
-  atRelativeZ0: number
+  atRelativeX0: number;
+  atRelativeY0: number;
+  atRelativeZ0: number;
   // X and Y refers to plot
-  plotXSideResolution: number
-  plotYSideResolution: number
-  crossSection: nearFieldPlane
+  plotXSideResolution: number;
+  plotYSideResolution: number;
+  crossSection: nearFieldPlane;
   // maxComputeTime: number //in seconds
 }
 
 export interface simulationSetup {
-  hostIndex: number
-  fromWL: number; toWL:number; pointsWL:number
-  layers: layer[]
-  numberOfModesToPlot: number
-  plotLabel: string
-
-  nearFieldSetup: nearFieldSetup,
-  farFieldWL:number
+  hostIndex: number;
+  fromWL: number;
+  toWL: number;
+  pointsWL: number;
+  layers: layer[];
+  numberOfModesToPlot: number;
+  plotLabel: string;
+
+  nearFieldSetup: nearFieldSetup;
+  farFieldWL: number;
 }
 
 export interface nmieModule {
   //nmie instance
-  instance: import('src/nmiejs').nmie_class|undefined
-  isNmieRunning: boolean
-  nmieTotalRunTime: number
+  instance: import('src/nmiejs').nmie_class | undefined;
+  isNmieRunning: boolean;
+  nmieTotalRunTime: number;
 }
 
 export interface simulationSetupStateInterface {
-  library: Map<string,simulationSetup>
-  gui: simulationSetup
-  current: simulationSetup
-  nmies: {spectrum: nmieModule, nearField: nmieModule, farField:nmieModule}
+  library: Map<string, simulationSetup>;
+  gui: simulationSetup;
+  current: simulationSetup;
+  nmies: { spectrum: nmieModule; nearField: nmieModule; farField: nmieModule };
 }
 
-function setupFactory(hostIndex = 1,
-                      fromWL = 400, toWL=1000, pointsWL=201,
-                      layers = [
-                        {layerWidth:100, n:4, k:0.01,
-                          material: {name:'nk-constant',
-                            spectrumRangeStart:undefined, spectrumRangeEnd: undefined,
-                            nSpline: undefined, kSpline: undefined, isPlot:false},
-                        },
-                      ],
-                      numberOfModesToPlot = 4,
-                      plotLabel = '',
-
-                      nearFieldSetup = {
-                        atWL: 619.3885178,
-                        relativePlotSize: 2,
-                        atRelativeX0: 0,
-                        atRelativeY0: 0,
-                        atRelativeZ0: 0,
-                        plotXSideResolution: 64,
-                        plotYSideResolution: 64,
-                        crossSection: nearFieldPlane.Ek,
-                        // maxComputeTime: 5 //in seconds
-                      },
-
-                      farFieldWL = 619,
-
-):simulationSetup {
-  return {hostIndex:hostIndex,
-    fromWL:fromWL, toWL:toWL, pointsWL:pointsWL,
+function setupFactory(
+  hostIndex = 1,
+  fromWL = 400,
+  toWL = 1000,
+  pointsWL = 201,
+  layers = [
+    {
+      layerWidth: 100,
+      n: 4,
+      k: 0.01,
+      material: {
+        name: 'nk-constant',
+        spectrumRangeStart: undefined,
+        spectrumRangeEnd: undefined,
+        nSpline: undefined,
+        kSpline: undefined,
+        isPlot: false,
+      },
+    },
+  ],
+  numberOfModesToPlot = 4,
+  plotLabel = '',
+
+  nearFieldSetup = {
+    atWL: 619.3885178,
+    relativePlotSize: 2,
+    atRelativeX0: 0,
+    atRelativeY0: 0,
+    atRelativeZ0: 0,
+    plotXSideResolution: 64,
+    plotYSideResolution: 64,
+    crossSection: nearFieldPlane.Ek,
+    // maxComputeTime: 5 //in seconds
+  },
+
+  farFieldWL = 619
+): simulationSetup {
+  return {
+    hostIndex: hostIndex,
+    fromWL: fromWL,
+    toWL: toWL,
+    pointsWL: pointsWL,
     layers: cloneDeep(layers),
     numberOfModesToPlot: numberOfModesToPlot,
     plotLabel: plotLabel,
 
-    nearFieldSetup:nearFieldSetup,
+    nearFieldSetup: nearFieldSetup,
 
-    farFieldWL:farFieldWL,
-  }
+    farFieldWL: farFieldWL,
+  };
 }
 
 function state(): simulationSetupStateInterface {
-
-  const gui = setupFactory()
-  const current = cloneDeep(gui)
-  const library = new Map<string,simulationSetup>()
-  library.set('default', cloneDeep(gui))
-  const nmies = {spectrum: {instance:undefined, isNmieRunning:false, nmieTotalRunTime:0},
-    nearField: {instance:undefined, isNmieRunning:false, nmieTotalRunTime:0},
-    farField: {instance:undefined, isNmieRunning:false, nmieTotalRunTime:0}}
+  const gui = setupFactory();
+  const current = cloneDeep(gui);
+  const library = new Map<string, simulationSetup>();
+  library.set('default', cloneDeep(gui));
+  const nmies = {
+    spectrum: {
+      instance: undefined,
+      isNmieRunning: false,
+      nmieTotalRunTime: 0,
+    },
+    nearField: {
+      instance: undefined,
+      isNmieRunning: false,
+      nmieTotalRunTime: 0,
+    },
+    farField: {
+      instance: undefined,
+      isNmieRunning: false,
+      nmieTotalRunTime: 0,
+    },
+  };
   return {
     library,
     gui, // simulation setup config as shown in GUI
     current, // simulation setup used for the latest simulation
     nmies,
-  }
+  };
 }
 
 export default state;

+ 0 - 6
tests/test_bulk_sphere.cc

@@ -50,13 +50,7 @@ TEST(BulkSphere, HandlesInput) {
           {100,   {10,  10,},  2.071124, 1.836785, 'l'},
           {10000, {1.33,1e-5}, 2.004089, 1.723857, 'f'},
           {10000, {1.5, 1},    2.004368, 1.236574, 'j'},
-//          {10000, {10,  10},   2.005914, 1.791, 'm'},
           {10000, {10,  10},   2.005914, 1.795393, 'm'},
-#ifndef MULTI_PRECISION
-          {10000, {1.33,1e-5}, 2.004089, 1.723857, 'f'},
-          {10000, {1.5, 1},    2.004368, 1.236574, 'j'},
-          {10000, {10,  10},   2.005914, 1.795393, 'm'},
-#endif
       };
   for (const auto &data : parameters_and_results) {
     auto x = std::get<0>(data);