Got feedback or spotted a mistake?

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

Skip to end of metadata
Go to start of metadata

You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 38 Current »

OpenSpecimen allows configuring calculated fields to be displayed on overview pages.

Note

  • We do not recommend storing any calculated field values since it is duplicate information.

  • You can configure the code in JSON workflow within the 'Dictionary' section.

Example 1: Display participant concatenated first name and last name

 Click here to expand...
{
        "name": "calcCpr.name",
        "displayExpr": "cpr.participant.firstName + ' ' + cpr.participant.lastName",
        "caption": "Name",
        "type": "span"
}

A more robust example of the above is no blank space when either first name or last name is not specified.

{
        "name": "calcCpr.name",
        "displayExpr": "fns.concat(cpr.participant.firstName, cpr.participant.lastName)",
        "caption": "Name",
        "type": "span"
}


Example 2: Display Visit Clinical Diagnosis Values concatenated with their Concept code 

 Click here to expand...
 {
  "name": "calcVisit.diagnosisList",
  "caption": "Clinical Diagnosis",
  "type": "span",
  "displayExpr": "fns.concatList(visit.diagnosisList, '!!value && value != \"Not Specified\" ? value + (!!conceptCode ? \" (\" + conceptCode + \")\" : \"\") : \"\"', ', ')"
}

Example 3: Display age as of today

 Click here to expand...
 {
  "name": "calcCpr.birthDate",
  "displayExpr": "fns.dateDiffInYears(cpr.participant.birthDate, fns.now()) + ' years'",
  "caption": "Age",
  "type": "span"
}

Example 4: Display age at the time of visit

 Click here to expand...
{
"name": "calcVisit.age",
"displayExpr": "fns.ifNotNull(cpr.participant.birthDate,  fns.dateDiffInYears(cpr.participant.birthDate, visit.visitDate) + ' years', 'Not Applicable')",
"caption": "Age at the time of Visit",
"type": "span"
}  

Example 5: Display age at the time of specimen creation

 Click here to expand...
{
"name": "calcSpecimen.age",
"displayExpr": "fns.ifNotNull(cpr.participant.birthDate,  fns.dateDiffInYears(cpr.participant.birthDate, specimen.createdOn) + ' years', 'Not Applicable')",
"caption": "Age at collection",
"type": "span"
}

Example 6: Display the multiplication of 2 Custom fields

 Click here to expand...
{
     "name": "calcSpecimen.concentration",
     "displayExpr": "fns.ifNotNull(specimen.extensionDetail.attrsMap.wbc && specimen.extensionDetail.attrsMap.volsus,(specimen.extensionDetail.attrsMap.wbc * specimen.extensionDetail.attrsMap.volsus).toFixed(2),'Not Specified')",
     "caption": "Total WBC Count (10^6)",
     "type": "span"
},

Example 7: Adding 2 Number fields

 Click here to expand...
  {
      "name" : "calcCpr.NumbersAddition",
      "displayExpr" : "fns.ifNotNull(cpr.participant.extensionDetail.attrsMap.number_field_1 &&  cpr.participant.extensionDetail.attrsMap.number_field_2,+cpr.participant.extensionDetail.attrsMap.number_field_1 + +cpr.participant.extensionDetail.attrsMap.number_field_2, 'Not Specified')",
      "caption" : "Sum of Numbers",
      "type" : "span"
    }

Example 8: Average of 2 Number fields

 Click here to expand...
  {
      "name" : "calcCpr.numberFieldAverage",
      "displayExpr" : "fns.ifNotNull(cpr.participant.extensionDetail.attrsMap.number_field_1 &&  cpr.participant.extensionDetail.attrsMap.number_field_2,((+cpr.participant.extensionDetail.attrsMap.number_field_1 + +cpr.participant.extensionDetail.attrsMap.number_field_2)/2), 'Not Specified')",
      "caption" : "Number fields Average",
      "type" : "span"
    }

Example 9: Return the array of substring and display it on child specimen overview page

 Click here to expand...
{
  "name": "calcSpecimen.parentLabel",
  "displayExpr": "fns.split(specimen.parentLabel, ':')[0]",
  "caption": "Part-Subpart",
  "type": "span"
}

Example 10: Display quantity (ug) field on the specimen overview page

 Click here to expand...

Note: If one of the fields is left blank, the calculated value would be '0' since this is a multiplication field.

  {
            "name": "calcSpecimen.volume",
            "displayExpr": "(specimen.initialQty * specimen.concentration) / 1000",
            "caption": "Quantity(ug)",
            "type": "span"
    }

Example 11: Display if the patient consented or not based on consent responses

 Click here to expand...
{
      "name" : "calcCpr.isPartial",
      "caption" : "Is Consented?",
      "type" : "span",
      "displayExpr" : "consents != null ? (((consents['GEN-001'] != null && consents['GEN-001'] == 'Yes') || consents['GEN-002'] == 'Yes')?'Yes':'No') : '###'"
    }

Example 12: Display BMI of participant

 Click here to expand...
{
"name" : "calcCpr.bmi",
"displayExpr" : "+cpr.participant.extensionDetail.attrsMap.weight_kg > 0 && +cpr.participant.extensionDetail.attrsMap.height_kg > 0 ? cpr.participant.extensionDetail.attrsMap.weight_kg / (cpr.participant.extensionDetail.attrsMap.height_kg *2 ) : 'NA'",
"caption" : "BMI",
"type" : "span"
}

Example 13: Display Participant custom field on Visit/Specimen Overview Page as Read-Only

 Click here to expand...
...
},
{
      "name" : "calcVisit.partComment",
      "displayExpr" : "fns.ifNotNull(cpr.participant.extensionDetail.attrsMap.comments,  cpr.participant.extensionDetail.attrsMap.comments, 'Not-Specified')",
      "caption" : "Participant Custom Field (Participant Comments)",
      "type" : "span"
},
...
...
...
{
      "name" : "calcSpecimen.partComment",
      "displayExpr" : "fns.ifNotNull(cpr.participant.extensionDetail.attrsMap.comments,  cpr.participant.extensionDetail.attrsMap.comments, 'Not-Specified')",
      "caption" : "Participant Custom Field (Participant Comments)",
      "type" : "span"
},
...

Participant Overview Page

Visit Overview Page

Specimen Overview Page

Example 14: Display Participant Yes/No and Date custom field on Specimen Overview Page as Read-Only

 Click here to expand...
...
,
{
      "name" : "calcSpecimen.partGenetic Testing Decline",  
      "displayExpr": "cpr.participant.extensionDetail.attrsMap.genetic_testing_decline_02a != null ? ((cpr.participant.extensionDetail.attrsMap.genetic_testing_decline_02a == 1)?'Yes':'No') : 'No'",
      "caption" : "Genetic Testing Decline",
      "type" : "span"
},
...
...
...
{
      "name" : "calcSpecimen.partWithdrawal Date",
      "displayExpr" : "fns.ifNotNull(fns.toDateStr(cpr.participant.extensionDetail.attrsMap.withdrawal_date), fns.toDateStr(cpr.participant.extensionDetail.attrsMap.withdrawal_date), 'Not-Specified')",
      "caption" : "Withdrawal Date", 
      "type" : "span"
}
, 
...

Participant Overview Page

Specimen Overview Page

Example 15: Display Visit default field on Specimen Overview Page as Read-Only

 Click here to expand...
{
           "name" : "calcSpecimen.visitName",
           "displayExpr" : "fns.ifNotNull(visit.name,  visit.name, 'Not-Specified')",
           "caption" : "Visit Name",
           "type" : "span"
}

Visit Overview Page

Specimen Overview Page

Example 16: Display Visit custom field on Specimen Overview Page as Read-Only

 Click here to expand...
{
      "name" : "calcSpecimen.visitAnatomicalSiteCode",
      "displayExpr" : "fns.ifNotNull(visit.extensionDetail.attrsMap.site_code,  visit.extensionDetail.attrsMap.site_code, 'Not-Specified')",
      "caption" : "Visit Custom Field (Anatomical Site Code) as Read-Only",
      "type" : "span"
}

Visit Overview Page

Specimen Overview Page

Example 17: Display age as of today in Months

 Click here to expand...
{
  "name": "calcCpr.birthDate",
  "displayExpr": "(fns.dateDiffInDays(cpr.participant.birthDate, fns.now()) * 12 / 365).toFixed(0)+ ' months'",
  "caption": "Age",
  "type": "span"
},

Example 18: Calculating the months remaining after counting the completed years

 Click here to expand...
{
  "name": "calcCpr.birthDate",
  "displayExpr": "(fns.dateDiffInDays(cpr.participant.birthDate, fns.now()) / 365 * 12 -fns.ageInYears(cpr.participant.birthDate, fns.now()) * 12).toFixed(0) + ' months'",
  "caption": "Age",
  "type": "span"
},

Example 19: Calculating the Cohort field based on the consent signature date.

 Click here to expand...
      "name" : "calcCpr.cohort",
      "displayExpr" : "consents.consentSignatureDate > 1502841600000 && consents.consentSignatureDate < 1582588800000 ? 'Cohort 1' : (consents.consentSignatureDate > 1582675200000 && consents.consentSignatureDate < 1672531200000 ? 'Cohort 2' : (consents.consentSignatureDate > 1672617600000 ? 'Cohort 3' : 'Unknown'))",
      "caption" : "Cohort",
      "type" : "span"
    }

  • image-20240215-142634.png

Example 20: Calculating the Field based on Custom Number field divided by user input value.

 Click here to expand...
{
      "name" : "calcSpecimen.numberField",
      "displayExpr" : "fns.ifNotNull(specimen.extensionDetail.attrsMap.number1,((+specimen.extensionDetail.attrsMap.number1)/100), 'Not Specified')",
      "caption" : "Divided Cal Field",
      "type" : "span"
    },

image-20240306-044650.png

Inbuilt Functions

 Click here to expand...

Note: Currently, the only collection and received event fields can be used for calculated fields. Fields of other events cannot be used.

Function

Description

fns.ifNull(cond, 'truthValue', 'falseValue')

Returns truthValue when 'cond' is evaluated to either null or undefined. Otherwise, it returns falseValue.

fns.ifNotNull(cond, 'truthValue', 'falseValue')

Returns truthValue when 'cond' is evaluated to non-null or a defined value. Otherwise, it returns falseValue.

fns.concatList(coll, expr, separator)

Concatenates the elements of the collection 'coll' and joins them using the input 'separator'. e.g. fns.concatList(persons, "\'firstName\' + ' ' + \'lastName\'", ",") yields Virat Kohli, Dhanraj Pillay, Atul Bedade

fns.concat(varargs)

Concatenates input arguments using the separator ' '

fns.minValue(coll, expr)

Returns the min value of the 'expr' in the input collection 'coll'

fns.toDateStr(dateObj, [fmt])

Returns date string in locale format or requested format 'fmt'

fns.toDateTimeStr(dateObj, [fmt])

Returns date-time string in locale format or requested format 'fmt'

fns.now() fns.currentTime()

Returns current time in number of milliseconds elapsed since Epoch.

fns.dateDiffInYears(d1, d2)

Returns the number of completed years between d1 and d2.

fns.ageInYears(d1)

Convenience function, which is equivalent to fns.dateDiffInYears(d1, fns.now())

fns.dateDiffInDays(d1, d2)

Returns the number of completed days between d1 and d2.

fns.dateDiffInMinutes(d1, d2)

Returns the number of minutes elapsed between d1 and d2 where d1 < d2

fns.dateDiffInSeconds(d1, d2)

Returns the number of seconds elapsed between d1 and d2 where d1 < d2

fns.split(str, regex) 

Returns an array of substrings that are delimited by the regex in the input string.

fns.join(strArray, separator)

Returns concatenation of array of substrings delimited by the separator.

Example JSON Download

Calculated URL

From v10.2 onwards, on the JSON configured overview page, calculated fields can be used to display the hyperlinked URLs.

//Example Code
{
      "name" : "calcSpecimen.computedUrl",
      "caption" : "Specimen overview page",
      "type" : "text",
      "displayExpr" : "https://test.openspecimen.org/#/cp-view/{{cpr.cpId}}/participants/{{cpr.id}}/visits/specimens/detail/overview?specimenId={{specimen.id}}&visitId={{specimen.visitId}}",
      "linkText" : "View Image"
}

Below is the list of fields that are available to be used in the JSON

Field

Syntax

Collection Protocol Identifier

cpr.cpId

Participant Registration Identifier

participant.id

Participant Identifier

cpr.id

Visit Identifier

specimen.visitId

Specimen Identifier

specimen.id

  • No labels