Got feedback or spotted a mistake?

Leave a comment at the end of this page or email contact@krishagni.com

Administrative screen configurations - (Auto allocation, Rule based Label Format, Lock Fields)

Rule-based specimen label format (v6.0)

By default, when label formats are defined in the CP, it applies to all the specimens in that CP irrespective of other conditions like specimen type. Admins can configure conditional rules to generate the specimen label formats.

Examples:

  1. Configure different formats for tissue specimens vs. fluid specimens
  2. Different format for baseline event vs. surgery event

Rules are defined in JSON. Each rule should specify the criteria that the specimen should satisfy and the specimen label format. The first matching rule is used for generating the label. Any specimen attributes, including custom attributes, can be used in the rules. The rules can be configured either at the CP or system level.

The order of label formats to use should be:

  1. SR level
  2. If the SR level is not specified, use lineage-based formats specified at the CP level.
  3. If lineage-based formats are not specified, use the rules-based format.


 Example Code...
Example 1
    {
      "name": "labelSettings",
      "data": {
        "specimen": {
          "rules": [
          
            {
              "criteria": "#specimen.lineage == 'Derived' && #specimen.type == 'Serum'",
              "format": "%PSPEC_LABEL%-S%PSPEC_UID%"
            },
            {
              "criteria": "#specimen.lineage == 'Derived' && #specimen.type == 'Plasma' && #specimen.pathology == 'Malignant'",
              "format": "%PSPEC_LABEL%-PMD%PSPEC_UID%"
            },
            {
              "criteria": "#specimen.lineage == 'Aliquot' && #specimen.type == 'DNA'",
              "format": "%PSPEC_LABEL%-DNA%PSPEC_UID%"
            },
            {
              "criteria": "#specimen.lineage == 'Aliquot' && #specimen.type == 'RNA'",
              "format": "%PSPEC_LABEL%-RNA%PSPEC_UID%"
            },
            {
              "init": "#specimen.extensionDetail.getAttrsMap()",
              "criteria": "#specimen.extensionDetail.attrsMap['ST2'] == 'XYZ'",
              "format": "%PSPEC_LABEL%-XYZ%PSPEC_UID%"
            },
            {
              "format": "%PSPEC_LABEL%-A%PSPEC_UID%"
            }
          ]
        }
      }
    }

Labels generated

 



Example 2
    {
      "name": "labelSettings",
      "data": {
        "specimen": {
          "rules": [
          
            {
              "criteria": "#specimen.lineage == 'Derived' && #specimen.type == 'Serum'",
              "format": "%PPI%-%SP_TYPE%-%PPI_SPEC_TYPE_UID(1, output_one)%"
            },
            {
              "criteria": "#specimen.type == 'Fresh Tissue'",
              "format": "%PPI%-%EVAL(#specimen.visit.surgicalPathologyNumber)%-%CUSTOM_FIELD(specimen, block_id)%"
            }
          ]
        }
      }
    }

Labels generated

Example 3
 {
  "name" : "labelSettings",
  "view" : null,
  "ctrl" : null,
  "data" : {
    "specimen" : {
      "rules" : [ {
        "criteria" : "#specimen.lineage =='Aliquot' && (#specimen.type == 'Plasma' || #specimen.type == 'Serum')",
        "format" : "MCH%SYS_UID(5)%"
      }, {
        "criteria" : "#specimen.lineage =='Derived' && (#specimen.type == 'Plasma' || #specimen.type == 'Serum')",
        "format" : "%PPI%_%EVENT_LABEL%_%SP_TYPE%.%PPI_UID%-Clone%CUSTOM_FIELD(specimen,ST6)%"
      } ]
    }
  }
}

Labels generated: The label setting will be applied to more than one specimen type

Advanced container auto-allocation

Per protocol, administrators can configure to auto-allocate containers as per different parameters. Basic settings can be achieved using the 'Collection Protocol' UI settings. Refer to 'Auto Container Allocation' a page for more details.

Complex auto allocation strategies can be set using the JSON workflow. Specimens can be auto-allocated to different storage container types during specimen collection. This can be achieved by setting up criteria in various fields, as listed below.

From V10.3 it's possible to include dimensionless container types for condition-based auto allocation. Refer to wiki page to create dimensionless container type.

LevelFieldVariable to be used
VisitEvent labelspecimen.eventLabel
SpecimenQuantity

specimen.initialQty

SpecimenTypespecimen.type
SpecimenLineagespecimen.lineage
SpecimenRequirement codespecimen.reqCode
 Click here for JSON examples...
Example 1
{
      "name": "auto-allocation",
      "data": {
        "rules": [
          {
            "criteria": "specimen.eventLabel == 'Visit' && specimen.initialQty == 1 && specimen.type == 'Plasma' && ['EP01', 'LP01'].indexOf(specimen.reqCode) != -1",
            "name": "ContainerType",
            "params": {
              "name": "-10G_Box"
            }
          },
          {
            "criteria": "specimen.eventLabel == 'Visit' && specimen.initialQty == 1 && specimen.type == 'Plasma' && ['EP02', 'LP02'].indexOf(specimen.reqCode) != -1",
            "name": "ContainerType",
            "params": {
              "name": "-10B_Box"
            }
          },
          {
            "criteria": "specimen.initialQty == 0.1 && specimen.type == 'Serum' && ['S02', 'S03', 'S04'].indexOf(specimen.reqCode) != -1",
            "name": "ContainerType",
            "params": {
              "name": "-10G_Box"
            }
          },
          {
            "criteria": "specimen.initialQty == 0.1 && specimen.type == 'Serum' && ['S18', 'S19'].indexOf(specimen.reqCode) != -1 && visit.site == 'USB Biobank'",
            "name": "ContainerType",
            "params": {
              "name": "-10R_Box"
            }
          },
          {
            "criteria": "specimen.initialQty == 0.1 && specimen.type == 'Plasma' && ['EP14', 'LP15'].indexOf(specimen.reqCode) != -1",
            "name": "ContainerType",
            "params": {
              "name": "-10W_Box"
            }
          },
          {
            "criteria": "specimen.initialQty == 2.5 && specimen.reqCode=='RNA'",
            "name": "ContainerType",
            "params": {
              "name": "-7Y_Box"
            }
          },
          {
            "criteria": "specimen.type == 'Urine (complete)' && specimen.initialQty == 20",
            "name": "ContainerType",
            "params": {
              "name": "-4W_Box"
            }
          }
     }
  ]
}
Example 2
{
      "name": "auto-allocation",
      "view": null,
      "ctrl": null,
      "data": {
        "rules": [
          {
            "criteria": "specimen.initialQty == 1 && specimen.type == 'Plasma' && ['EP21', 'EP20', 'LP21'].indexOf(specimen.reqCode) != -1",
            "name": "ContainerType",
            "params": {
              "name": "-10G_Box"
            }
          },
          {
            "criteria": "specimen.initialQty == 1 && specimen.type == 'Plasma' && ['EP19', 'LP20'].indexOf(specimen.reqCode) != -1",
            "name": "ContainerType",
            "params": {
              "name": "-10B_Box"
            }
          },
          {
            "criteria": "specimen.initialQty == 0.1 && specimen.type == 'Plasma' && ['EP01', 'EP02', 'EP03', 'EP04', 'EP05', 'EP06', 'EP07', 'EP08', 'LP01', 'LP02', 'LP03', 'LP04', 'LP05', 'LP06', 'LP07', 'LP08', 'LP09'].indexOf(specimen.reqCode) != -1",
            "name": "ContainerType",
            "params": {
              "name": "-10G_Box"
            }
          },
          {
            "criteria": "specimen.initialQty == 0.1 && specimen.type == 'Serum' && ['S02', 'S03', 'S04', 'S05', 'S06', 'S07', 'S08', 'S09', 'S10', 'S11', 'S12', 'S13', 'S14', 'S15', 'S16', 'S17'].indexOf(specimen.reqCode) != -1",
            "name": "ContainerType",
            "params": {
              "name": "-10G_Box"
            }
          },
          {
            "criteria": "specimen.initialQty == 1 && specimen.type == 'Serum' && ['S48', 'S49', 'S50', 'S51'].indexOf(specimen.reqCode) != -1",
            "name": "ContainerType",
            "params": {
              "name": "-10G_Box"
            }
          },
          {
            "criteria": "specimen.initialQty == 0.1 && specimen.type == 'Plasma' && ['EP09', 'EP10', 'EP11', 'EP12', 'EP13', 'LP10', 'LP11', 'LP12', 'LP13', 'LP14'].indexOf(specimen.reqCode) != -1",
            "name": "ContainerType",
            "params": {
              "name": "-10R_Box"
            }
          },
          {
            "criteria": "specimen.initialQty == 0.1 && specimen.type == 'Serum' && ['S18', 'S19', 'S20', 'S21', 'S22', 'S23', 'S24', 'S25', 'S26', 'S27'].indexOf(specimen.reqCode) != -1",
            "name": "ContainerType",
            "params": {
              "name": "-10R_Box"
            }
          },
          {
            "criteria": "specimen.initialQty == 0.1 && specimen.type == 'Plasma' && ['EP14', 'EP15', 'EP16', 'EP17', 'EP18', 'LP15', 'LP16', 'LP17', 'LP18', 'LP19'].indexOf(specimen.reqCode) != -1",
            "name": "ContainerType",
            "params": {
              "name": "-10W_Box"
            }
          },
          {
            "criteria": "specimen.initialQty == 0.1 && specimen.type == 'Serum' && ['S28', 'S29', 'S30', 'S31', 'S32', 'S33', 'S34', 'S35', 'S36', 'S37'].indexOf(specimen.reqCode) != -1",
            "name": "ContainerType",
            "params": {
              "name": "-10W_Box"
            }
          },
          {
            "criteria": "specimen.initialQty == 0.1 && specimen.type == 'Serum' && ['S38', 'S39', 'S40', 'S41', 'S42', 'S43', 'S44', 'S45', 'S46','S47'].indexOf(specimen.reqCode) != -1",
            "name": "ContainerType",
            "params": {
              "name": "-10Y_Box"
            }
          },
 
          {
            "criteria": "specimen.initialQty == 1 && specimen.type == 'Serum' && ['S'].indexOf(specimen.reqCode) != -1",
            "name": "ContainerType",
            "params": {
              "name": "-7B_Box"
            }
          },
          {
            "criteria": "specimen.initialQty == 2.5 && specimen.reqCode=='RNA'",
            "name": "ContainerType",
            "params": {
              "name": "-7Y_Box"
            }
          },
          {
            "criteria": "specimen.type == 'Urine (complete)' && specimen.initialQty == 20",
            "name": "ContainerType",
            "params": {
              "name": "-4W_Box"
            }
          },
          {
            "criteria": "['U02', 'U03', 'U04', 'U05', 'U06'].indexOf(specimen.reqCode) != -1",
            "name": "ContainerType",
            "params": {
              "name": "-10G_Box"
            }
          },
          {
            "criteria": "['U07', 'U08', 'U09', 'U10', 'U11'].indexOf(specimen.reqCode) != -1",
            "name": "ContainerType",
            "params": {
              "name": "-10R_Box"
            }
          },
          {
            "criteria": "['U12', 'U13', 'U14', 'U15', 'U16'].indexOf(specimen.reqCode) != -1",
            "name": "ContainerType",
            "params": {
              "name": "-10W_Box"
            }
          },
          {
            "criteria": "['U17', 'U18', 'U19'].indexOf(specimen.reqCode) != -1",
            "name": "ContainerType",
            "params": {
              "name": "-10Y_Box"
            }
          },
          {
            "criteria": "['U20'].indexOf(specimen.reqCode) != -1",
            "name": "ContainerType",
            "params": {
              "name": "-10B_Box"
            }
          },
          {
            "criteria": "['U'].indexOf(specimen.reqCode) != -1",
            "name": "ContainerType",
            "params": {
              "name": "-7B_Box"
            }
          },
          {
            "criteria": "['WB1', 'WB2'].indexOf(specimen.reqCode) != -1",
            "name": "ContainerType",
            "params": {
              "name": "-7R_Box"
            }
          },
          {
            "criteria": "specimen.type == 'Cell-free (spun) Urine' && ['FU01', 'FU02', 'FU03', 'FU04', 'FU05'].indexOf(specimen.reqCode) != -1",
            "name": "ContainerType",
            "params": {
              "name": "-10G_Box"
            }
          },
          {
            "criteria": "specimen.type == 'Cell-free (spun) Urine' && ['FU06', 'FU07', 'FU08', 'FU09', 'FU10'].indexOf(specimen.reqCode) != -1",
            "name": "ContainerType",
            "params": {
              "name": "-10R_Box"
            }
          },
          {
            "criteria": "specimen.type == 'Cell-free (spun) Urine' && ['FU11', 'FU12', 'FU13', 'FU14', 'FU15'].indexOf(specimen.reqCode) != -1",
            "name": "ContainerType",
            "params": {
              "name": "-10W_Box"
            }
          }
        ]
      }
    }

Screenshot: Auto allocation

Example 3: Dimensionless container type
{
  "name" : "auto-allocation",
  "view" : null,
  "ctrl" : null,
  "data" : {
    "rules" : [
    {
          "criteria": "['PD1','PD2'].indexOf(specimen.reqCode) != -1",
          "name": "ContainerType",
          "params": {
            "name": "Aditi JSON Box"
          }
        },
    {
          "criteria": "specimen.type == 'Urine (complete)' && specimen.initialQty == 20",
          "name": "ContainerType",
          "params": {
            "name": "Ahk -20 box"
          }
        },
        {
              "criteria": "specimen.type == 'Serum' && specimen.lineage == 'New'",
              "name": "ContainerType",
              "params": {
                "name": "Dimensionless_CT2"
              }
            },
            {
          "criteria" : "specimen.biohazards.indexOf('Tuberculosis') != -1",
          "name" : "ContainerType",
          "params" : {
            "name" : "Dimensionless_CT"
          }
        }
   ]
  }
}

Screenshot: Auto allocation

Lock fields at the participant level

Using SDE, you can lock the participant fields on the Openspecimen UI. These fields are populated from an external source, due to which biobanks want these fields to be non-editable.

The source of the fields is the name of the DB from where the participant data is being populated. In the example below, the source is 'ASIG'. In the OpenSpecimen database table catissue_participant, the source column for the participants should be 'ASIG' so that the fields will be locked.

This JSON should be set at the system level since the participants are registered across CPs.

Once the JSON is configured, the participant edit page will be displayed as the screenshot below.

 Click here to see the JSON code and screenshot
Lock fields
{
    "name": "locked-fields",
    "data": {
        "participant": {
          "ASIG": [          //this is the source from where the data is populated 
              "cpr.ppid",
              "cpr.participant.vitalStatus",
              "cpr.participant.deathDate"
          ]
        }
    }
}

Screenshot:

Got feedback or spotted a mistake?

Leave a comment at the end of this page or email contact@krishagni.com