Author: Virginia Liu, Andrew Turpin
Date: 2020-03-04

# Depth-dependent integrated visual fields

#### Virginia Liu, Andrew Turpin

#### 2020-03-04

Standard visual field testing is typically monocular using the 24-2 pattern. However, binocular visual field results are more closely related to patients’ subjective experience and their visual function in daily activities. This vignette demonstrates how to calculate depth-dependent integrated visual field data from standard monocular threshold sensitivity (dB) data and visualize both using a set of functions included in this package. Please also see shiny app demos included in the package.

## Load a visual field csv file

A visual field csv file can be loaded using the generic function `read.csv(filename)`. The csv file should contain a minimum number of variables needed for the simulation:

- ID: patient ID
- pd: pupil distance (mm)
- gender: patient gender is used to estimate pupil distance when pupil distance data is not available
- eye : left (OS) or right (OD) eye
- 24-2 visual field data (54 data points)

    atbino.df <- read.csv(system.file("extdata", "atbinocular.csv",
                                       package = "binovisualfields"))
    #yourdf <- read.csv("yourdata.csv"")  specify path and data file name to load your own data
    at_id <- unique(atbino.df$id)
    at_gender <- atbino.df$gender[1:length(at_id)]

## Create visual field matrices

The left and right visual field data can be extracted from the loaded `atbino.df` data frame.

    at_left_visual_fields <- atbino.df[atbino.df$seye=="OS", 4:ncol(atbino.df)]
    at_rght_visual_fields <- atbino.df[atbino.df$seye=="OD", 4:ncol(atbino.df)]

After initializing the left and right visual field array for all patients, visual field matrices can be obtained using the function `makevf` and stored in data arrays.

    #initialize vf array for all patients
    vf_matrix <- matrix(NA, ncol=10, nrow = 8)
    at_rght_vf_array <- replicate(nrow(at_rght_visual_fields), vf_matrix)
    for (i in 1:nrow(at_rght_visual_fields)){
      at_rght_vf_array[,,i] <- makevf(unlist(at_rght_visual_fields[i,], use.names = F), eye="right")
    }

    at_left_vf_array <- replicate(nrow(at_left_visual_fields), vf_matrix)
    for (i in 1:nrow(at_rght_visual_fields)){
      at_left_vf_array[,,i] <- makevf(unlist(at_left_visual_fields[i,], use.names = F), eye="left")
    }

## Plot individual dataset by ID

### Extract individual data

Extract all values needed for calculating binocular visual fields by ID.

    id <- 3
    pindex  <- match(id, at_id)
    left_vf <- at_left_vf_array[, , pindex]
    rght_vf <- at_rght_vf_array[, , pindex]
    gender  <- at_gender[pindex]

### Calculate angle of convergence

The left and right eye rotate an angle when they converge to fix on a distance plane from looking into far distance. This angle of convergence is labelled theta. To calculate this angle, pupil distance and fixation distance are required. When pupil distance is unavailable, provide gender (female or male) and respective default value will be used.

    fix_dist <- c(600, 0)
    theta_left <- caltheta(fix_dist, gender = gender, eye = "left")
    theta_rght <- caltheta(fix_dist, gender = gender, eye = "right")

### Calculate integrated visual field for all distance planes

The function `binovfcal` returns simulated binocular visual field data in an array for the all object distances specified in the `dist_planes` vector.

    object_distances <- seq(300, 1000, 100)
    c_vf  <- binovfcal(left_vf, rght_vf, theta_left, theta_rght, object_distances, gender=gender)

## Subsetting

Each matrix in the integrated visual field array is named by it corresponding object distance. For example, to extract the integrated visual field for the object distance of 500 mm, one way is as the following

    c_vf <- c_vf[, , as.character(500)]

# plot the figures

The function `plotvfray` plots the interaction between the left and right visual field from a top view. The function `plotvf` plots both monocular visual field or simulated integrated visual field. The following code output all plots for each distance plane specified in the `dist_planes` vector into a pdf file.

    filename <- paste0("archetypes", id, ".pdf")
    pdf(filename, width=16)
    options(error=dev.off)

    layout(matrix(c(1, 1, 1, 1, 1, 1, 2, 4, 5, 3, 4, 5), 3, 4),  heights = c(3, 3, 1))
    m_xs <- seq(-27, 27, length.out = 10)
    c_xs <- seq(-63, 63, 6)
    for (i in object_distances) {
      plotvfray (left_vf, rght_vf, theta_left, theta_rght, fix_dist, i)
      plotvf(m_xs, left_vf, "Left Monocular")
      plotvf(m_xs, rght_vf, "Right Monocular")
      plotvf(c_xs, c_vf[, , as.character(i)],
            paste0("DD-IVF Fixation Distance = ", fix_dist[1], "mm, Object Distance = ", i, "mm"))
      colorkey()
    }
    dev.off()
    options(error=NULL)