Skip to main content

Optics units converter

· 3 min read

There are many physical units converters on the internet. Here we made one for our optics THz lab in University of Augsburg 🇩🇪

Features Bidirectional convertion between

  • Energy units (ev, cm, Hartree...)
  • Wavelengths
  • Frequency
  • Temperature
  • Magnetic fields

Download App v.02

note

For magnetic field units we assume spin 1/2

How it works​

As a base we define a general transformation rules for units as follows

Then one can naturally use NSolve to get this or that unit.

tip

Change the extension to wln to see the source code

For the inputs we designed a custom input element using WLX and JS following this guide

.wlx

CustomInput[sym_, OptionsPattern[]] := Module[{
Label = OptionValue["Label"],
Ev = OptionValue["Event"],
Pattern = OptionValue["Pattern"],
Handler
},

With[{Template =
<div class="mt-2 flex">
<div style="width: 7rem" class="flex shrink-0 items-center rounded-l-md bg-white px-3 text-base text-gray-500 outline outline-1 -outline-offset-1 outline-gray-300 sm:text-sm/6"><Label/></div>
<input type="number" step="1" class="-ml-px block w-full grow rounded-r-md bg-white px-3 py-1.5 text-base text-gray-900 outline outline-1 -outline-offset-1 outline-gray-300 placeholder:text-gray-400 focus:outline focus:outline-2 focus:-outline-offset-2 focus:outline-indigo-600 sm:text-sm/6" placeholder="0.0"/>
<script type="module">
core['<Handler/>'] = async (args, env) => {
const input = env.element.getElementsByTagName('input')[0];


const data = await interpretate(args[0], env);
input.value = +data.toFixed(4);
env.local.input = input;

input.addEventListener('change', () => {

console.warn(input.value);
env.local.skip = true;
server.kernel.emitt('<Ev/>', input.value, '<Pattern/>');
});
}

core['<Handler/>'].update = async (args, env) => {
if (env.local.skip) {
env.local.skip = false;
return;
}

console.log('Update');
env.local.input.value = +(await interpretate(args[0], env)).toFixed(4);
}

core['<Handler/>'].destroy = () => {
delete core['<Handler/>'];
}

core['<Handler/>'].virtual = true;
</script>
</div>
},
HTMLView[Template, Epilog->(Handler[sym])]
]
]

Options[CustomInput] = {"Label"->"", "Event"->"", "Pattern"->"Default"};

what happens here:

  1. we define a template for our custom input field
  2. we define a support script with a generated Handler function, which reads and updates this input field
  3. we pack in into HTMLView, which calls our Handler on a provided argument after this component has been mounted

For example