Skip to content

Map Units & Conversions

Map raw rows into the scenario's unit conversions table: what a quantity of a product in one unit is in another unit. 1 pallet of cement is 24 bags; 3 pieces of nails are 1 kg.

Conversions are what let quantities stated in different units meet. A carrier quotes lane capacity in pallets, demand is in bags, a truck has a weight limit in tonnes. With the conversions mapped, Network Optimization relates them correctly, and the scenario reports every quantity in its one unit.

When to use this

  • Any quantity in the scenario is stated in a unit other than the scenario's Unit on Create Scenario
  • A lane limit covers several products that are counted differently
  • An Add Constraint rule is stated in a unit of its own, such as a weight limit

A scenario whose every quantity is already in the scenario's unit needs no conversions.

What you need

  • An upstream Import Data node with one row per conversion
  • A product column, or All products for the whole file. A product is a product the scenario lists, a filter over products such as product.product_group == "Cement", or ALL
  • A quantity and a unit on each side of the statement

Field mapping

Fields are matched by name unless you set them. When the workflow runs, every field you have not set a column for is matched against the headers listed below, case-insensitively and ignoring spaces around the header, and a space inside your header reads as an underscore, so Site Name matches site_name. Setting a column for one field fixes that field only; the others keep following your file's headers, so a renamed column is still found. A required field that no column supplies — no header matched, or you set none or one your table lacks — is reported once, with the headers your table does have.

Set mappings in the node's panel. Connect an upstream table and select the mapping node. A field matched by name is marked Matched by name; pick a column to set it yourself, and Match by name puts it back. Match all by name clears every field you set. Required fields without a match are marked in the panel.

Reshape rows in a Script first. A mapping node only says which column is which field. To drop rows, recode values, or split or combine columns, connect a Script node before it and map the columns the Script returns.

Field Type Required Example What it is Auto-detected headers
Product text Yes Cement X Product the conversion holds for; a filter over products, such as "Chilled" in product.tags or product.product_group == "Chilled", for each product it matches; or ALL for every product. Every row covering a product applies to it, and rows that disagree about one product are refused naming both. Any other value must match a Product name. product, sku, item, material, product_id
From Quantity number Yes 1.0 How many of the From Unit the row states. A number above zero; required, never assumed to be 1. Must be greater than 0. from_quantity, from_qty, quantity_from, qty_from
From Unit text Yes pallet The unit on the first side of the statement. from_unit, unit_from, from_uom
To Quantity number Yes 24.0 How many of the To Unit the From Quantity equals. A number above zero; required, never assumed to be 1. Must be greater than 0. to_quantity, to_qty, quantity_to, qty_to, equals, equals_quantity
To Unit text Yes bag The unit on the second side. The reverse reading follows; state each pair once. to_unit, unit_to, to_uom, equals_unit

How it works

Each row is a sentence: From Quantity From Unit of the Product is To Quantity To Unit. Write it the way you would say it; a third is 3 and 1, not a rounded decimal.

Product From Quantity From Unit To Quantity To Unit
Cement X 1 pallet 24 bag
Cement X 1 bag 25 kg
Nails Y 1 pallet 10000 piece
Nails Y 3 piece 1 kg
  • A conversion belongs to a product. A pallet of cement and a pallet of nails share a name and nothing else. One is never converted through the other.
  • Every direction and every chain follows. From the rows above, a pallet of Cement X is also 600 kg, and a bag is one twenty-fourth of a pallet. State each pair of units once.
  • ALL states a conversion for every product, and a filter's row for each product it matches. The filter is written as in an Add Constraint rule, with product as its only name: product.product_group == "Cement" for every product whose Product Group is Cement, or "Bagged" in product.tags for every product tagged Bagged. A cell such as All Cement, written for earlier versions, is refused with a hint to write product.product_group == "Cement".
  • Every row that covers a product applies to it. Its own rows, the rows whose filter matches it and the ALL rows are read together, and none of them replaces another. A product row may repeat what the ALL row says. If it says something else, the two rows contradict each other and the scenario is refused, naming both. Where one product really differs, state its conversion on its own row and leave it out of the ALL and filter rows.
  • Metric units are built in. t, kg, g and mg convert among themselves, as do m3, l and ml, for every product and with no row. One row from a product's own unit to any of them is enough to reach the rest. Only these spellings are built in; any other unit is yours to define.

Nothing is assumed. Two units with no stated path between them are not related, and a quantity left blank is not read as 1.

What is refused

Create Scenario refuses a scenario whose conversions cannot be used as written, and reads the rows back to you:

  • A row with a blank product, quantity or unit
  • A quantity that is not a number above zero
  • A row that converts a unit to itself
  • A row that restates or changes a built-in metric conversion
  • A product that is not a product of the scenario, a filter over products or ALL
  • A filter that cannot be read, or that matches none of the scenario's products
  • Rows that contradict each other for one product, whether two of its own rows or its own row and an ALL or filter row: the finding names the row, the rows of the other path between the same units, and what that path says instead

It also refuses a quantity whose unit has no path to the scenario's Unit for its product, and says which conversion is missing.

Workflow wiring

flowchart LR
    n1["Import Data (conversions.csv)"] --> n2["Map Units & Conversions"]
    n2 --> n3["Create Scenario"]
    n4["Import Data (products.csv)"] --> n5["Map Products"]
    n5 --> n3

Common mistakes

  • Leaving a quantity blank. 1 is never assumed; write 1, pallet, 24, bag.
  • Stating one pair twice. The reverse of a row already follows from it. A second row for the same two units is only ever the same fact again or a contradiction.
  • Relying on a shared unit name. A conversion for one product says nothing about another. Use ALL or a filter only where the statement really holds for every product it covers.
  • Overriding an ALL row for one product. A product row never replaces an ALL row; the two are refused as a contradiction. Replace the ALL row with a filter that leaves the product out, such as product.name != "Cement X".
  • Adding a row for kg to t. Metric steps are built in and a row that restates one is refused.

Messages this node can show

The table this node makes is checked again with the rest of the scenario when Create Scenario assembles it: see messages about the scenario.

A run gives this node 5 minutes. A node that takes longer stops with Time limit reached.

Like every node, it can also stop on the checks before a run and the run's limits.