Non-Compartmental Analysis (NCA)

NCA in Pumas is conducted in the following steps:

  1. Read source data (.csv, .xlxs, .xpt, sas7bdata)
  2. Create an NCAPopulation by mapping variables from source data to Pumas-NCA data format - PumasNCADF
  3. Exploratory data analysis
  4. Run NCA analysis
  5. Generate report

Read Source Data

The Pumas-NCA data format - PumasNCADF provides the specification requirements of the source data. Currently, four file formats can be read in for analysis.

  • .csv (using CSV)
  • .xslx (using XSLX)
  • .sas7bdat / .xpt (using ReadStats)

A comprehensive discussion on reading files into Julia using one of these packages for Pumas workflows is listed here. A simple example for reading a CSV file is provided below:

using CSV
pkdata ="./drugY_pk_sad.csv", DataFrame)

The file can be found here. Reading files as specified above generates a DataFrame object in the working environment, i.e. pkdata is of type DataFrame.

Create a NCAPopulation

The generated DataFrame object now needs to be mapped to the requirements of Pumas-NCA. Mappping is done using the read_nca function that is described in detail later. An example for read_nca is the following:

using NCA
ncapop = read_nca(pkdata,
                observations = :dv,
                group = [:doselevel])

Mapping a DataFrame to the Pumas-NCA requirements using read_nca generates an object called NCAPopulation, which is collection of NCASubject's, i.e., ncapop is of type NCAPopulation.

Exploratory Data Analysis

Exploratory analysis of the NCAPopulation can be performed using the built in plotting ecosystem. The Plotting for NCA section provides more details, but here are some example syntax and the corresponding plots.

Observations-time plots

We can produce a plot of the concentration against time using observations_vs_time. The plotting recipes for NCA analyses are fund in the NCAUtilities package. Below is the code for generating this plot for the first subject found using ncapop[1].

using NCAUtilities
    axis = (xlabel = "Time (hours)",
            ylabel = "CTM Concentration (mg L⁻¹)",),


We can also use log-scale for the concentrations such that exponential decay shows as a straight line. Below is the code to set the y-scale to use the natural logarithm.

    axis = (xlabel = "Time (hours)",
            ylabel = "CTM Concentration (mg L⁻¹)",
            yscale = log),

Other options are yscale = log10 and yscale = log2 for a base-10 and base-2 logarithm. Observations-time

To generate these plots side-by-side we have to create a Figure-object first, and then pass fig[row,column] as the first argument. row specifies which row of the figure the element should be added to and column specifies the column number.

using CairoMakie
fig = Figure()
    axis = (xlabel = "Time (hours)",
            ylabel = "CTM Concentration (mg L⁻¹)",),
    axis = (xlabel = "Time (hours)",
            ylabel = "CTM Concentration (mg L⁻¹)",
            yscale = log),


Summary plots

    axis = (xlabel = "Time (hours)",
            ylabel = "CTM Concentration (mg L⁻¹)",),


Subject fit plots

sf = subject_fits(
    axis = (yscale = log,),
    rows = 3,
    columns = 3,)

Subject fit

Run Analysis

The NCAPopulation object is the processed version of the DataFrame that is amenable for a complete NCA analysis via run_nca or individual parameter results through a collection of functions described in the NCA Function List. Example syntax to perform a complete NCA analysis is below

pk_nca = run_nca(
   studytitle="Phase 1 SAD of Drug Y",
   author = [("John Smith", "Pumas-AI"),("Joe Smith", "Pumas-AI") ],
   sponsor = "PumasAI",,
   conclabel="CTMX Concentration (mg/L)",
   grouplabel = "Dose (mg)",
   timelabel="Time (Hr)",

The result of a complete NCA analysis using run_nca is an object called NCAReport, i.e., pk_nca is of type NCAReport. This object carries the result of the analysis in a DataFrame called reportdf and corresponding metadata information that are used for post-processing the results.

Summarize results

The per subject results in the DataFrame component of NCAReport, reportdf, can be be summarized using the summarize function. Example syntax:

parms = [:cmax, :aucinf_obs]
summary_output = summarize(pk_nca.reportdf; parameters = parms)

2×8 DataFrame
 Row │ parameters  extrema             geomean    geomeanCV  geostd   mean       numsamples  std      
     │ String      Tuple…              Float64    Float64    Float64  Float64    Int64       Float64  
   1 │ cmax        (141.561, 2232.39)    567.003   0.34413   1.95123    696.203          18    494.54
   2 │ aucinf_obs  (5600.54, 75366.4)  18871.8     0.012325  2.32595  26073.4            18  21115.9

The output generated above is of type DataFrame.

Plot results

Subject fits

subfts = subject_fits(
   columns = 2,
   rows = 3,

Subject fit

Parameter distributions

    parameter = :aucinf_obs,

Params dist

Parameter distribution by groups (ID or covariates)

    parameter = :aucinf_obs)

Params grp

Generate Report

The report function takes in either a NCAPopulation or a NCAReport object to generate a comprehensive, currently only PDF, report. This generated PDF file has all the necessary information including tables, listings and figures that are required for NCA analysis. Example syntax:

report(pk_nca, output="my_nca_report")

You can view the report generated here. As you can see, the generated PDF carries a name that matches the studytitle given to the run_nca function ("Phase 1 SAD of Drug Y" leads to Phase_1_SAD_of_Drug_Y.pdf).