Each sample in a Sample Type must have a unique name/id. If your data does not already contain unique identifiers for each row, the system can generate them upon import using a Naming Pattern (previously referred to as a name expression).


Administrators can customize name generation using templates that build a unique name from syntax elements, such as:

  • string constants
  • incrementing numbers
  • random numbers
  • dates and partial dates
  • values from the imported data, such as tissue types, lab names, subject ids, etc.
For example the template


generates names from two elements, a string constant plus an incrementing number

and so on...

Naming Pattern Elements/Tokens

Naming patterns, or name expressions, can incorporate the following elements. When surrounded by ${ } syntax, they will be substituted during sample creation.

Name ElementDescriptionScope0000000000000000000000000
genIdAn incrementing number starting from 1. This counter is specific to the individual Sample Type or Data Class.Current Sample Type / Data Class
dailySampleCountAn incrementing counter, starting with the integer '1', that resets each day.All Sample Types across the entire server
weeklySampleCountAn incrementing counter, starting with the integer '1', that resets each week.All Sample Types across the entire server
monthlySampleCountAn incrementing counter, starting with the integer '1', that resets each month.All Sample Types across the entire server
yearlySampleCountAn incrementing counter, starting with the integer '1', that resets each year.All Sample Types across the entire server
randomIdA four digit random number for each sample row.Current Sample Type / Data Class
batchRandomIdA four digit random number applied to the entire set of incoming sample records. On each import event, this random batch number will be regenerated.Current Sample Type / Data Class
nowThe current date, which you can format using string String Expression Format Functions.Current Sample Type / Data Class
InputsA collection of all DataInputs and MaterialInputs for the current sample. You can concatenate using one or more value from the collection.Current Sample Type / Data Class
DataInputsA collection of all DataInputs for the current sample. You can concatenate using one or more value from the collection.Current Sample Type / Data Class
MaterialInputsA collection of all MaterialInputs for the current sample. You can concatenate using one or more value from the collection.Current Sample Type / Data Class
<SomeDataColumn>Loads data from some field in the data being imported. For example, if the data being imported has a column named "SampleType", use the element/token "${SampleType}"Current Sample Type / Data Class

Default Values

When you are using a data column in your string expression, you can specify a default to use if no value is provided. Use the defaultValue modifier with the following syntax. The 'value' argument provided must be a String in ' single quotes.


Incrementing Sample Counters

The sample counters are incremented for the date when the sample is inserted, but can use a different date by attaching the counter to a date column. For example, ${SampleDate:dailySampleCount} will use the date found in the row's "SampleDate" column or today's date if the column has no value. It can be especially useful to attach the sample counters to a date column to create accurate labels for samples that were collected in the past or are expected to be collected in the future.

To construct a unique sample name when using one of the date based incrementing counters (dailySampleCount, **weeklySampleCount**, monthlySampleCount, or yearlySampleCount) you will need to include the corresponding date string in the name as well. For example, to create unique sample names that include monthlySampleCount, you will need to include the year and month in the name expression as well, e.g. ${date:format('yyyy-MM')} or ${date:format('yyyy-LLL')}.

Some auto-incrementing counters calculate the next value based on all samples in a given container, while others calculate based on only the current sample type. See the Scope column for the specific incrementing behavior. When the scope is container-based, within a given sample type, values will be sequential but not necessarily contiguous.


Name ExpressionExample OutputDescription
S- + a simple sequence
The originating Lab + a simple sequence. If the Lab value is null, then use the string 'Unknown'.
S_ + random numbers
S_ + the current date + daily resetting incrementing integer
S_ + the draw date month + year + monthly incrementing counter zero padded
S_${Column1}_${Column2}S_Blood_PT101Create an id from the letter 'S' and two values from the current row of data, separated by underscore characters.

String Modifiers

The following name expressions are used in combination with string modifiers.

Name Expression00000000000000000000000000000000000000000000000Example Output000000000000000000Description
${Column1:defaultValue('S')} means 'Use the value of Column1, but if that is null, then use the default: the letter S'
${DataInputs:first:defaultValue('S')} means 'Use the first DataInput value, but if that is null, use the default: the letter S'
${DataInputs:join('_'):defaultValue('S')}-${Column1}Nucleotide1_Nucleotide2-1${DataInputs:join('_'):defaultValue('S')} means 'Join together all of the DataInputs separated by undescores, but if that is null, then use the default: the letter S'

Advanced Options: XML Counter Columns

If you want a sequential counter based on values in other columns, such as an incrementing series for each lot of material on a plate, you can use XML metadata to define a new "counter" column paired with one or more existing columns to provide and store this incrementing value. You then use the new column in your name expression.

For example, consider that you would like to generate the following sample type for a given plate:

Name (from expression)LotSampleInLotPlate Id

The "SampleInLot" column contains a value that increments from 1 independently for each value in the "Lot" column. In this example, the name expression would be S-${Lot}-${SampleInLot}. To define the "SampleInLot" column, you would create it with data type integer, then use XML metadata similar to this:

<tables xmlns="http://labkey.org/data/xml">
<table tableName="MySampType" tableDbType="NOT_IN_DB">
<javaCustomizer class="org.labkey.experiment.api.CountOfUniqueValueTableCustomizer">
<property name="counterName">SampleCounter</property>
<property name="counterType">org.labkey.api.data.UniqueValueCounterDefinition</property>
<!-- one or more pairedColumns used to derive the unique value -->
<property name="pairedColumn">Lot</property>
<!-- one or more attachedColumns where the incrementing counter value is placed -->
<property name="attachedColumn">SampleInLot</property>

The following rules apply to these unique value counters:

  • The counter you create is scoped to a single Sample Type.
  • The definition of the counter column uses one or more columns to determine the unique value. When you use the counter in a name expression, be sure to also include all the paired columns in addition to your counter column to ensure the sample name generated will be unique.
  • The incrementing counter is maintained within the LabKey database.
  • Gaps in the counter's sequence are possible because it is incremented outside the transaction. It will be sequential, but not necessarily contiguous.
  • When you insert into a sample type with a unique counter column defined, you can supply a value for this unique counter column, but the value must be equal to or less than the current counter value for the given paired column.

Related Topics


Was this content helpful?

Log in or register an account to provide feedback

expand all collapse all