# Unit conversion

> Convert between the canonical SI units of .well files and the units people read and type, with the conversion helpers of @welldot/core.

A `.well` file always stores canonical SI units: meters, millimeters, m³/h, kW, m³ ([Units](/format/spec/v2/format-reference#units)). People read and type inches, feet, gallons and horsepower. `@welldot/core` provides the conversions so that every program converts the same way: to SI when writing, from SI when displaying.

```ts
import { inchesToMm, metersToFeet, slotNumberToMm } from '@welldot/core';

inchesToMm(10); // 254, for a 10 in borehole
slotNumberToMm(20); // 0.508, a slot-20 screen
metersToFeet(60); // 196.85…
```

Results are not rounded; format them for display (for example with `formatNumber` from [`@welldot/utils`](/utils/guides/formatting)).

## The helpers

| Quantity       | Functions                                                                                                                                                    |
| -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| Length         | `metersToFeet`, `feetToMeters`                                                                                                                               |
| Diameter       | `mmToInches`, `inchesToMm`                                                                                                                                   |
| Screen slot    | `slotNumberToMm`, `mmToSlotNumber`                                                                                                                           |
| Flow           | `cubicMeterPerHourToLitersPerSecond`, `litersPerSecondToCubicMeterPerHour`, `cubicMeterPerHourToUsGallonsPerMinute`, `usGallonsPerMinuteToCubicMeterPerHour` |
| Power          | `cvToKilowatts`, `kilowattsToCv`, `hpToKilowatts`, `kilowattsToHp`                                                                                           |
| Volume         | `litersToCubicMeters`, `cubicMetersToLiters`, `cubicMetersToCubicFeet`, `cubicFeetToCubicMeters`, `cubicMetersToUsGallons`, `usGallonsToCubicMeters`         |
| Time           | `minutesToHours`, `hoursToMinutes`                                                                                                                           |
| Pressure       | `kilopascalToPsi`, `psiToKilopascal`                                                                                                                         |
| Transmissivity | `squareMeterPerSecondToSquareMeterPerDay`, `squareMeterPerDayToSquareMeterPerSecond`                                                                         |
| Coordinates    | `decimalDegreesToDms`, `dmsToDecimalDegrees`                                                                                                                 |
| Concentration  | `concentrationToCanonical`, `concentrationFromCanonical` (mg/L, µg/L, ng/L, g/L)                                                                             |
| Conductivity   | `milliSiemensPerMeterToMicroSiemensPerCm`, `milliSiemensPerCmToMicroSiemensPerCm`                                                                            |

Every function has a page in the [API reference](/core/api).

## Converting by a user's preference

For flow, power and volume there are paired helpers that take the display unit as an argument. They fit a settings screen where the user picks units once:

```ts
import {
  flowFromCanonical,
  flowToCanonical,
  type FlowUnits,
} from '@welldot/core';

const unit: FlowUnits = 'L/s'; // 'm3/h' | 'L/s' | 'gpm'

flowFromCanonical(36, unit); // 10, to show a stored 36 m³/h
flowToCanonical(10, 'gpm'); // 2.27…, to store a typed 10 gpm
```

`powerFromCanonical` / `powerToCanonical` take `'kW' | 'cv' | 'hp'`, and `volumeFromCanonical` / `volumeToCanonical` take `'m3' | 'L' | 'ft3' | 'gal'` (US gallon). The `Units` type groups the preferences (`length`, `diameter`, `flow`, `power`, `volume`) and is what `@welldot/render` accepts.

## Diameters and slots: the traps

- **Nominal sizes are not diameters.** `inchesToMm(6)` is 152.4 mm, but 6 in steel pipe has an outer diameter of 168.3 mm, and the file stores the real outer diameter ([as-built convention](/format/spec/v2/format-reference#diameter-and-the-as-built-convention)). Use the conversion for boreholes and true measurements; map trade sizes to real diameters in your input form.
- **Slot numbers** are thousandths of an inch: `slotNumberToMm(20)` is 0.508 mm ([screen slot](/format/spec/v2/format-reference#screen-slot)).

## Coordinates

```ts
import { decimalDegreesToDms, dmsToDecimalDegrees } from '@welldot/core';

decimalDegreesToDms(-1.4558, 'lat');
// { degrees: 1, minutes: 27, seconds: 20.88, direction: 'S' }

dmsToDecimalDegrees({
  degrees: 1,
  minutes: 27,
  seconds: 20.88,
  direction: 'S',
});
// -1.4558
```

Projected coordinates (UTM) are out of scope: convert them with a projection library such as `proj4` before writing `location` ([CRS scope](/format/spec/v2/format-reference#crs-scope)).

## Laboratory reports

Lab reports use many unit spellings. These helpers map them onto the file's conventions ([water quality units](/format/spec/v2/water-quality#units)):

```ts
import {
  concentrationToCanonical,
  expandedToStandardUncertainty,
  normalizeColorUnit,
  turbidityCodeForUnit,
} from '@welldot/core';

concentrationToCanonical(50, 'ug/L'); // 0.05 mg/L
turbidityCodeForUnit('NTU'); // 'turbidity_ntu', the parameter code to use
normalizeColorUnit('mg Pt-Co/L'); // 'uH'
expandedToStandardUncertainty(0.04); // 0.02, U / k with k = 2, for value_precision
```

The last one implements the spec's rule that `value_precision` is one standard deviation, not the expanded uncertainty ([precision](/format/spec/v2/format-reference#precision-and-uncertainty)).
