Converter Operator Documentation


Backend

Overview

The converter can apply additional calculations to the selected x-values and y-values. These calculations are stored in xOperations and yOperations and are executed when an output table is processed.

There are two layers involved:

  1. Four operation types, which define where the right-hand value comes from.
  2. Four mathematical operators, which define how that value is applied to the current x- or y-value.

The four operation types are:

The four mathematical operators are:

In other words:
A profile can say things like:


Data Structures Involved

For each output table, the converter uses these fields in the table configuration:

Each entry in xOperations or yOperations contains at least:

Depending on the type, additional fields are used, such as column, value, table, regex, line, and ignore_missing_values.


Method: process(self)

Purpose

Prepare the raw x/y data, apply all configured x/y operations, and build the final output table.

Step-by-step behavior

  1. Read the base x and y columns
    The converter reads the values from xColumn into x_rows and from yColumn into y_rows.
  2. Prepare data for column-based operations
    If an operation has type column, the converter preloads the referenced column values into operation['rows'].
  3. Apply x-operations
    All entries from xOperations are executed in their stored order.
  4. Apply y-operations
    All entries from yOperations are executed in their stored order.
  5. Handle calculation failures
    If an operation fails and the failure must not be ignored, the converter marks the calculation as failed and clears the output rows.

Important consequence

The order of operations matters.
If several operations are configured, each one works on the result of the previous one. So * 2 followed by + 5 is not the same as + 5 followed by * 2.


Method: _run_operation(self, rows, operation)

Purpose

Execute one configured operation on all values of one target row set, meaning either all x-values or all y-values.

For each row, the method first determines the right-hand operand based on operation.type. Then it applies the selected mathematical operator by calling apply_operation.


The four operation types

1. column – Value from another table column

Plain-language interpretation:
The current x- or y-value is combined with the value from another column at the same row index.


2. value – Fixed scalar value

Plain-language interpretation:
All x- or y-values are modified by the same fixed number, such as + 5 or * 1000.


3. metadata_value – Value from table metadata

Plain-language interpretation:
The current x- or y-value is combined with a numeric value taken from the metadata of a selected input table.


4. header_value – Value extracted from the table header via regex

Plain-language interpretation:
The current x- or y-value is combined with a number that is found somewhere in the selected table header.


How missing or invalid values are handled

After the right-hand value has been determined, the converter tries to convert it to a float.

This special handling is mainly relevant for metadata_value and header_value, because those two types may depend on metadata or free text that is missing or non-numeric.


Method: apply_operation(self, value, op_value, op_operator)

Purpose

Apply the mathematical operator to the current row value (value) and the resolved operation value (op_value).

Supported operators

if op_operator == '+':
    return float_value + float(op_value)
if op_operator == '-':
    return float_value - float(op_value)
if op_operator == '*':
    return float_value * float(op_value)
if op_operator == ':':
    return float_value / float(op_value)

Meaning of the operators

Important implementation detail

The current implementation only applies the operation when op_value is truthy. This means that a right-hand value of 0 will not be applied and will leave the current row unchanged.


Overall Summary

So the backend logic can be summarized like this:

  1. Start with the selected x/y column values.
  2. For each configured operation, determine where the right-hand value comes from.
  3. Apply one of the four mathematical operators.
  4. Store the updated x/y values in the final output table.

Frontend

This part of the frontend is the visual configuration for the x/y operations you saw in the backend.

It lets a user decide:

  1. Which column should be used as the base x- or y-values, and
  2. Which additional operations should be applied to those values before export.

1. Choosing the base x- and y-columns

<TableColumn
  table={table.table}
  label="Which column should be used as x-values?"
  columnKey="xColumn"
  operationsKey="xOperations"
  ...
/>

<TableColumn
  table={table.table}
  label="Which column should be used as y-values?"
  columnKey="yColumn"
  operationsKey="yOperations"
  ...
/>

What the user sees

A selection field for the x-column and a selection field for the y-column.

These define the starting values before any operation is applied.

How this relates to the backend

The selections are stored as:

The backend reads these values first, then applies xOperations and yOperations on top of them.

Special case:
If the table header says DATA CLASS = XYDATA, the x-values are configured differently in the frontend, via metadata-related identifiers such as FIRSTX, LASTX, and DELTAX, instead of the normal x-column operation block.


2. The operator dropdown

<Form.Select size="sm" value={value} onChange={event => onChange(event.target.value)}>
  <option value="+">+</option>
  <option value="-">-</option>
  <option value="*">*</option>
  <option value=":">:</option>
</Form.Select>

What the user sees

Each configured operation row starts with a small dropdown containing:

How this relates to the backend

The selected symbol is stored in operation.operator. In the backend, this value is passed to apply_operation, where it determines whether the calculation becomes addition, subtraction, multiplication, or division.


3. The four operation types

The frontend offers four buttons for creating operations. Each new operation is added either to xOperations or to yOperations.

<Button onClick={() => addOperation(operationsKey, 'column')}>
  Add column operation
</Button>
<Button onClick={() => addOperation(operationsKey, 'value')}>
  Add scalar operation
</Button>
<Button onClick={() => addOperation(operationsKey, 'metadata_value')}>
  Add table metadata operation
</Button>
<Button onClick={() => addOperation(operationsKey, 'header_value')}>
  Add table header operation
</Button>

These correspond directly to the four backend operation types.


3.1 Column operation: column

What the user sees

After adding a column operation, the user sees:

How this relates to the backend

The selected column is stored in:

operation = {
  type: 'column',
  operator: '+',
  column: {
    tableIndex: ...,
    columnIndex: ...
  }
}

The backend then reads the referenced column values row by row and combines them with the current x- or y-values.


3.2 Scalar operation: value

What the user sees

After adding a scalar operation, the user sees:

How this relates to the backend

The entered value is stored in:

operation = {
  type: 'value',
  operator: '+',
  value: '...'
}

The backend uses this same scalar for every row.


3.3 Table metadata operation: metadata_value

What the user sees

After adding a metadata operation, the user sees:

How this relates to the backend

The selected metadata field is stored using fields such as metadata, value, and table. The backend uses value as the metadata key and table as the table reference.

If the metadata is missing or not numeric:


3.4 Table header operation: header_value

What the user sees

After adding a header operation, the user sees:

How this relates to the backend

The entered fields are stored in something like:

operation = {
  type: 'header_value',
  operator: '+',
  table: '0',
  line: '...',
  regex: '...',
  ignore_missing_values: false
}

The backend uses _search_regex to search the selected table header. If the regex returns a numeric match, that value is used in the calculation.


4. Operation description

The frontend also shows an operation description area when operations are configured.

What the user sees

How this relates to the backend

The summary is stored in:

This description is later included in the exported JCAMP comment.


Putting it all together

From the user’s perspective:

  1. Select the base x-column and y-column.
  2. Add zero or more operations to x and/or y.
  3. For each operation, choose:
  4. which mathematical operator should be used, and
  5. which kind of source should provide the right-hand value:
  6. Optionally provide an explanation of the operation chain.

From the backend’s perspective:

In short:
The frontend provides a user-friendly way to build a calculation chain for x- and y-values, while the backend executes that chain using one of four operation types and one of four mathematical operators.