There are a few changes while editing including:

Automatic Capitalization

While editing a control stream, Emacs Speaks NONMEM figures out what type of capitalization needs to be present. Capitalization occurs outside of comments, and file names to conform with NONMEM's needs. In case your implementation of NONMEM doesn't require capitalization (like wings for NONMEM), you can turn this off at:

  • Automation
    • Changes While Editing
      • Smart Capitalization

Count of Input/Output items

NONMEM can have 20/50 input items, and 20/50 PRED generated output items. Emacs Speaks NONMEM can automatically count the number of INPUT items read in while typing. A typical example is (under NONMEM 7 which supports 50 input items):

;| Variables 57/50 |;
$INPUT ID DV TIME CMT MDV EVID II SS V0 V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 V11 V12
       V13 V14 V15 V16 V17 V18 V19 V20 V21 V22 V23 V24 V25 V26 V27 V28 V29 V30
       V31 V32 V33 V34 V35 V36 V37 V38 V39 V40 V41 V42 V43 V44 V45 V46 V47 V48

If seven of these variables are dropped or skipped, this input would be sufficient for NONMEM 7.1.0:

;| Variables 50/50 |;
$INPUT ID DV TIME CMT MDV EVID II SS V0 V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 V11 V12
       V13=DROP V14=SKIP V15=DROP V16=SKIP V17=DROP V18=SKIP V19=DROP V20 V21
       V22 V23 V24 V25 V26 V27 V28 V29 V30 V31 V32 V33 V34 V35 V36 V37 V38 V39
       V40 V41 V42 V43 V44 V45 V46 V47 V48

This automatic count can be toggled at:

  • Automation
    • Changes While Editing
      • Update $INPUT's number of variables

This is also performed on the number of variables output to a table:

For example:

;| Variables 50/50 |;
$INPUT ID DV TIME CMT MDV EVID II SS V0 V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 V11 V12
       V13=DROP V14=SKIP V15=DROP V16=SKIP V17=DROP V18=SKIP V19=DROP V20 V21
       V22 V23 V24 V25 V26 V27 V28 V29 V30 V31 V32 V33 V34 V35 V36 V37 V38 V39
       V40 V41 V42 V43 V44 V45 V46 V47 V48

;; Other code skipped

;| Pred Variables 7/50 |;
$TABLE ID NUM EVID MDV V2 CL TVCL V TVV Q TVQ FILE=test.tbl

Notice that the variables in the $INPUT record do not count to the total number of variables (since they are not generated by PRED).

This automatic counting may be toggled at:

  • Automation
    • Changes While Editing
      • Update $TABLE's number of PRED variables

Tab completion

Another feature that may be useful is Tab-completion. Tab completion tries to guess what you are going to be typing based on the position you are in your control stream. There is general tab completion, and tab completion for the following situations:

General Tab completion

The most common type of tab completion is completing records and similar types of completions. For Example, if you start to type:

$EST

And then press tab, the record is filled out to be

$ESTIMATION

If however, you don't input anything or you just press tab, the message bar below shows that you are in the process of completing:

Starting Tab Completion
Starting Tab Completion

By pressing tab again, it gives a list of options for that record:

Tab completion listing options
Tab completion listing options

you can select any of these options by clicking and then pressing return (or switching to the buffer through the keyboard, and pressing return near the point of interest)

This also occurs when there is more than one possible completion to what you are typing. For example when tying:

$ESTIMATION L

and then pressing tab, it brings up a list of options that begin with L:

Completing the L in the $ESTIMATION record
Completing the L in the $ESTIMATION record

At this point the user can select the completion by the mouse and return, or just press A or I to finish typing LAPLACIAN or LIKELIHOOD, respectively. If the user had typed:

$ESTIMATION LI

and then pressed tab, it would fill out the record option completely without any lists or extra tabs since LIKELIHOOD is the only option.

$ESTIMATION LIKELIHOOD

Tab completion may be turned on or off at:

  • Automation
    • While Editing
      • Tab Completion

File Completion

When completing a known file, Emacs Speaks NONMEM allows you to browse for a file. Under windows, there is an option to have a dialog to browse for the file. This only occurs when there is no information about the file. For example:

$DATA

Pressing a tab after this will bring up file prompt. This can be toggled with:

Completing the $INPUT record

Another possibility is completing the $INPUT completely based on a dataset specified. This requires:

  • The input data to be a CSV file with a header
  • The data file to be already specified in the control stream

Therefore, for completion of a dataset, say data.csv, the by typing the following,

$DATA data.csv
$INPUT

And Pressing a tab, gives:

;| Variables 10/50 |;
$INPUT C PAT TIME=TSFD AMT EVID SS II DV ID BLQ
;C ----------------------------------------------------------------------------
;C                                INPUT Variables
;C ----------------------------------------------------------------------------
;C C:     C
;C PAT:   PAT
;C TIME:  Time of Event (hr)
;C AMT:   Amount of Dose
;C EVID:  Event ID (0: Obs., 1: dose, 2: other, 3: reset, 4: reset & dose)
;C SS:    Steady State (0: Not steady-state, 1: steady-state, 2:steady-state superpositioned)
;C II:    Interdose Interval
;C DV:    Dependent Variable
;C ID:    NONMEM ID
;C BLQ:   BLQ
;C ----------------------------------------------------------------------------
$DATA data.csv IGNORE=C
After pressing tab:
  • Fills in the $INPUT record
    • Some variables are translated, such as TSFD, based on the user options
    • If there are too many variables, Emacs Speaks NONMEM will automatically drop/skip records.
  • Optionally places the $DATA record after the $INPUT record
    • Useful for NONMEM 6+'s ACCEPT and IGNORE statements such as IGNORE=(ID.EQ.2)
  • Puts the IGNORE=C option on the $DATA record. This C is the first character of the header, and will be used to ignore the header any anything else that begins with C.
  • Optionally adds comments about the variables within the dataset
    • Used in EsN's Xpose script to add labels to the Xpose object to have more customizable plots.
  • Optionally moves the cursor to the $DATA record (may not move it if there are variables that should be dropped.

Overall, tab completion of the $INPUT record may be turned on or off by:

  • Automation
    • Changes While Editing
      • Tab Completion Options
        • Use ESN's tab completion to fill in INPUT with CSV files

The moving of the $DATA record before the $INPUT record can be toggled by:

  • Automation
    • Changes While Editing
      • Tab Completion Options
        • After INPUT is tab completed, move $DATA before $INPUT and go to end of $DATA

The variable comments that can be used by the Xpose script can be toggled by:

  • Automation
    • Changes While Editing
      • Tab Completion Options
        • When completing $INPUT, comment about variable translation

The automatic variable labels may be changed/modified by the following menu/customization:

  • Automation
    • Changes While Editing
      • Tab Completion Options
        • Customize the comments for of the input variable translation

The variable translation (i.e. DV=CP) for DV can be customized at:

  • Automation
    • Changes While Editing
      • Tab Completion Options
        • Customize assumed DV variable

The variable translation (i.e. TIME=TSFD) for TIME can be customized at:

  • Automation
    • Changes While Editing
      • Tab Completion Options
        • Customize assumed Time variable

Also when there are too many variables some variables are always kept. The list of these variables can be customized by:

  • Automation
    • Changes While Editing
      • Tab Completion Options
        • Customize assumed variables that are kept by default

Completing the Scaling parameter

Another feature is tab-completion of the scale parameter. When the scale parameter is not filled in, Emacs Speaks NONMEM prompts for the unit assumptions (sometimes defaults are detected from your control stream), and then calculates the scale factor. For example,

$PK
  S1 =
Tab Completion first step
Tab Completion first step

After following the prompts, Emacs speaks NONMEM fills in the scale parameter and the assumptions:

$PK
  S1 = V1/1000 ; Dose: mg; Volume: L; Conc: ng/mL

Note the scale factor calculation currently only works with oral doses. Support for some other dosage forms may be added in the future.

Seed Generation

When typing in the $SIMULATION block, often you have to choose a seed. Emacs Speaks NONMEM can choose this seed for you if you wish it to. It chooses the seed based on a uniform distribution of all numbers between 1 and 2,147,483,647, the possible values of the $SIMULATION seed. All this occurs if you press the "(" key. Therefore,

$SIMULATE

by just pressing the ( key becomes:

$SIMULATE (1584308708

or some other random number between 1 and 2147483647. This can be toggled at:

  • Automation
    • Changes While Editing
      • Generate Seed with "(" in $SIM record

Emacs Speaks NONMEM aligns records based on the record name, and record type

Record Indentation

By default a record is a hanging indent with a variable number of spaces based on how many characters are record itself. For example an $INPUT record may be aligned differently based on if the record specification is $INPUT or $INP. For $INPUT the hanging indent is 7 characters:

$INPUT ID NUM DV TIME CMT CRCL WTKG RACE RIMP SEXF LBW IBW BSA SMOK TBIL ALT
       AST

For $INP the hanging indent is 5 characters:

$INP ID NUM DV TIME CMT CRCL WTKG RACE RIMP SEXF LBW IBW BSA SMOK TBIL ALT
     AST

In addition there are records who do not follow this procedure (like $PK) — they are automatically indented to 2 characters. Which records are only indented to two characters may be customized by the following menu:

  • Automation
    • Changes While Editing
      • Alignment Options
        • Customize records not indented to record-length

There are also records that are not indented at all — by default the $TABLE record. Which records are not indented may be changed in

  • Automation
    • Changes While Editing
      • Alignment Options
        • Customize records with no indentation

Overall, this automatic record indentation may be toggled at:

  • Automation
    • Changes While Editing
      • Automatically indent

$THETA/$OMEGA/$SIGMA alignment

Another option that Emacs Speaks NONMEM supports is the alignment of $THETA, $OMEGA, and $SIGMA records. In addition to the standard hanging indent, the estimates are aligned by commas and semi-colons add continuity to the display of the estimates.

For example, the $THETA record may be aligned as:

$THETA (0,    30)       ; 1 -  Cl (L/hr)
       (0,    40)       ; 2 -  Vc (L)
       (-200, 0.1, 200) ; 3 - Cov1 (L)

The numbers are aligned in a column-like fashion. The estimates themselves are also aligned in a similar fashion.

Estimates for $OMEGA and $SIGMA records, are aligned at the "." point whether present or assumed. For example

$OMEGA BLOCK(4)
     0                 ; 1 - BSV_Var1
      .0002 4          ; 2 - BSV_Var2
 20000    400.     3   ; 3 - BSV_Var3
     2       .0003 4 5 ; 4 - BSV_var4

This may be toggled at:

  • Automation
    • Changes While Editing
      • Align THETA,OMEGA & SIGMA

$PK/$DES/$AES alignment

For code-based sections, indentation rules are automatically applied. The comments are aligned, the code itself is aligned at the = sign (for the current indentation level), and appropriate blocks (like IF ... THEN, ENDIF) are indented, all without much user intervention. An example of this is the $PK block:

$PK
  TVCL = THETA(1)          ; Clearance (Population)
  IF (RACE.EQ.1) THEN
    TVCL = TVCL + THETA(2) ; Shift for Race 1.
  ENDIF
  CL   = TVCL*DEXP(ETA(1)) ; Individual Clearance

Note that the alignment is based on the level of the variable, with the exception of IF statements, for example:

$PK
  TVCL = THETA(1)                       ; Clearance (Population)
  IF (RACE.EQ.1) TVCL = TVCL + THETA(2) ; Shift for Race 1.
  CL   = TVCL*DEXP(ETA(1))              ; Individual Clearance

Does not change the alignment, but a long variable changes the alignment:

$PK
  TVCL       = THETA(1)
  THISISLONG = THETA(2)
  CL         = TVCL*DEXP(ETA(1))

This automatic alignment of equal signs and alignments may be toggled with the menu:

  • Automation
    • Changes While Editing
      • Align Code at = and comments

When disabled, Emacs Speaks NONMEM only indents the blocks of code.

Wrapping

One of the possible features of NONMEM is to automatically wrap NONMEM code at the 80 character mark. As an example the following $INPUT record has been typed.

$INPUT ID NUM DV TIME CMT CRCL WTKG RACE RIMP SEXF LBW IBW BSA SMOK TBIL ALT

When automatic indentation is enabled, typing AST at the of the $INPUT field gives the following automatic wrapping and indentation:

$INPUT ID NUM DV TIME CMT CRCL WTKG RACE RIMP SEXF LBW IBW BSA SMOK TBIL ALT
       AST

When automatic indentation is disabled, typing AST at the end of the $INPUT field wraps, but does not indent, as follows:

$INPUT ID NUM DV TIME CMT CRCL WTKG RACE RIMP SEXF LBW IBW BSA SMOK TBIL ALT
AST

Wrapping may be toggled at:

  • Automation
    • Changes While Editing
      • Automatic Wrapping of Records

Some records are not wrapped by default (for example the $PK record). Which records may be customized in Emacs speaks NONMEM by the following menu:

  • Automation
    • Changes While Editing
      • Customize records not wrapped

Numbering of Estimates

Emacs Speaks NONMEM can automatically number the estimates of the $THETA, $OMEGA, and $SIGMA blocks. This is done automatically by pressing the semi-colon. For example:

$THETA (0 1)

By pressing the semi-colon can give the following (depending on the options enabled):

$THETA (0 1) ; 1 -
or
$THETA (0 1) ;C 1 -
or
$THETA (0 1); THETA(1) -
or
$THETA (0 1) ;C THETA(1) -
These numbers update automatically. Therefore,
$THETA (0 1) ; 1 -
       (0 2) ; 2 -

       (0 3) ; 3 -
       (0 4) ; 4 -

by typing an estimate between two and three will renumber the estimates accordingly:

$THETA (0 1) ; 1 -
       (0 2) ; 2 -
       (0 100)
       (0 3) ; 4 -
       (0 4) ; 5 -

Also note that this works on $OMEGA and $SIGMA records with block statements. Therefore,

$OMEGA
 1 ; 1 - One
 2 ; 2 - Two
 3 ; 3 - Three
 4 ; 4 - Four
 5 ; 5 - Five
 6 ; 6 - Six

would automatically be renumbered when adding a BLOCK statement to the beginning of the $OMEGA record:

$OMEGA BLOCK(3)
 1 ; 1 - One
 2 ; Two
 3 ; 2 - Three
 4 ; Four
 5 ; Five
 6 ; 3 - Six

This is a option that depends on the type of control stream you are editing; one that is intended for census, PDx Pop, PLT tools, Pirana, or all other control streams have different options. Therefore, by default census and Pirana do not update numbers, but PDx Pop, PLT tools, and all other control streams update numbers.

To toggle numbering of estimates for the type of control stream that you are currently editing, this may be done at:

  • Automation
    • Changes While Editing
      • Number Estimates

To change it in the various modes you must find the option under

  • Automation
    • Changes While Editing
      • Program Specific Options

This is true of all other options discussed for estimate numbering. The other options for estimate numbering are for using full labels (i.e. "THETA(1) -" instead of "1 -"), and putting a C after the comment line (useful for PLT tools). The full variable label may be toggled at:

  • Automation
    • Changes While Editing
      • Options
        • Use full labels for numbering (i.e. instead of "1 -", use "THETA(1) -") *

The extra C may be toggled at:

  • Automation
    • Changes While Editing
      • Options
        • Use ;C for numbered comments (i.e. ";C 1 -" or ";C THETA(1) -") *

Updating BLOCK statements

Emacs Speaks NONMEM also numbers $OMEGA, and $SIGMA, block statements automatically. This is required for proper numbering, and updating covariance labels. Currently there is no toggle for this option, though it may be missing if alignment, estimate numbering and covariance labels are all turned off (haven't tested).

When the following $OMEGA block exists:

$OMEGA BLOCK(1)
 1 ; 1 -
 2 ;

Adding an estimate will automatically update the BLOCK number:

$OMEGA BLOCK(2)
 1 ; 1 -
 2 ;
 3

Updating ADVAN/TRANS descriptions

Emacs Speaks NONMEM can automatically number the label the ADVAN/TRANS descriptions. For example:

;| Two Compartment Linear Mammillary Model w/First Order Absorpt. |;
;| In terms of CL, V, Q, VSS, and KA                              |;
$SUBROUTINES ADVAN4 TRANS3

becomes

;| Two Compartment Linear Mammillary Model                        |;
;| In terms of CL, V, Q, and VSS                                  |;
$SUBROUTINES ADVAN3 TRANS3

when changing ADVAN4 to ADVAN3. There are also larger descriptions of ADVAN/TRANS combination that may be used. For example, with large descriptions, this becomes:

;| -------------------------------------------------------------- |;
;| Two Compartment Linear Mammillary Model (ADVAN3)               |;
;| -------------------------------------------------------------- |;
;|                                                                |;
;| +---+---------+-----+-----+-----+-----+-----+                  |;
;| | # | CMPTNME | INI | AOn | ADs | DDs | DOb |                  |;
;| +---+---------+-----+-----+-----+-----+-----+    |             |;
;| | 1 | Central | On. | No. | Yes | Yes | Yes |  +-+-+   +-+-+   |;
;| +---+---------+-----+-----+-----+-----+-----+  | 1 |<=>| 2 |   |;
;| | 2 | Periph. | On. | No. | Yes | No. | No. |  +-+-+   +-+-+   |;
;| +---+---------+-----+-----+-----+-----+-----+    |             |;
;| | 3 | Output. | Off | Yes | No. | No. | No. |    V             |;
;| +---+---------+-----+-----+-----+-----+-----+    3             |;
;|                                                                |;
;|                                                                |;
;| #         = Compartment Number                                 |;
;| CMPTNAME  = Compartment Name                                   |;
;| INI       = Initial Status                                     |;
;| AOn       = Allowed On/Off                                     |;
;| ADs       = Dose Allowed                                       |;
;| DDs       = Default for Dose                                   |;
;| DOb       = Default for Observation                            |;
;|                                                                |;
;| -------------------------------------------------------------- |;
;|                                                                |;
;| Shared PK parameters:                                          |;
;|                                                                |;
;|   S1         - Scale for central compartment (also called SC)  |;
;|   S2         - Scale for peripheral compartment                |;
;|   S3         - Scale for output compartment (also called S0)   |;
;|   F1         - Bioavailability for central compartment         |;
;|   F2         - Bioavailability for peripheral compartment      |;
;|   R1         - Rate for central compartment                    |;
;|   R2         - Rate for peripheral compartment                 |;
;|   D1         - Duration for central compartment                |;
;|   D2         - Duration for peripheral compartment             |;
;|   ALAG1      - Absorption lag for central compartment          |;
;|   ALAG2      - Absorption lag for peripheral compartment       |;
;|   F0         - Output fraction (also called F3, FO)            |;
;|   XSCALE     - X parameter                                     |;
;|                                                                |;
;| -------------------------------------------------------------- |;
;| TRANS3                                                         |;
;| -------------------------------------------------------------- |;
;|                                                                |;
;| CL   = Clearance                                               |;
;| V    = Central Volume                                          |;
;| Q    = Inter-compartmental clearance                           |;
;| VSS  = Volume of distribution at steady-state                  |;
;|                                                                |;
;| Relationships:                                                 |;
;|                                                                |;
;| K    = CL/V                                                    |;
;| K12  = Q/V                                                     |;
;| K21  = Q/(Vss-V)                                               |;
;|                                                                |;
;| -------------------------------------------------------------- |;
$SUBROUTINES ADVAN3 TRANS3