These methods aim to set a one-dimensional gate (cutpoint) near the edge of a peak in the density specified by a channel of a flowFrame to isolate the tail population. They allow two approaches to do this, both beginning by obtaining a smoothened kernel density estimate (KDE) of the original density and then utilizing either its first or second derivative.

We determine a gating cutpoint using either the first or second derivative of the kernel density estimate (KDE) of the x.

  filterId = "",
  num_peaks = 1,
  ref_peak = 1,
  strict = TRUE,
  tol = 0.01,
  side = "right",
  min = NULL,
  max = NULL,
  bias = 0,

  num_peaks = 1,
  ref_peak = 1,
  method = c("first_deriv", "second_deriv"),
  tol = 0.01,
  adjust = 1,
  side = "right",
  strict = TRUE,
  plot = FALSE,
  auto_tol = FALSE,



a flowFrame object


the channel from which the cytokine gate is constructed


the name of the filter


the number of peaks expected to see. This effectively removes any peaks that are artifacts of smoothing


After num_peaks are found, this argument provides the index of the reference population from which a gate will be obtained. By default, the peak farthest to the left is used.


logical when the actual number of peaks detected is less than ref_peak. an error is reported by default. But if strict is set to FALSE, then the reference peak will be reset to the peak of the far right.


the tolerance value


On which side of the density do we want to gate the tail, the


a numeric value that sets the lower boundary for data filtering


a numeric value that sets the upper boundary for data filtering


a numeric value that adds a constant to the calculated cutpoint(threshold). Default is 0.


additional arguments passed to .deriv_density


a numeric vector used as input data


the method used to select the cutpoint. See details.


the scaling adjustment applied to the bandwidth used in the first derivative of the kernel density estimate


logical specifying whether to plot the peaks found 'right' (default) or 'left'?


when TRUE, it tries to set the tolerance automatically.


a filterList containing the gates (cutpoints) for each sample with the corresponding rectangleGate objects defining the tail as the positive population.

the cutpoint along the x-axis


The default behavior of the first approach, specified by method = "first_deriv", finds valleys in the first derivative of the KDE and uses the lowest such valley to place the cutpoint on the steep right shoulder of the largest peak in the original density.

The default behavior of the second approach, specified by method = "second_deriv", is to find peaks in the second derivative of the KDE and use the largest such peak to place the cutpoint at the point on the right shoulder of the largest peak in the original density where it is most rapidly flattening (the first derivative is rapidly growing less negative).

Both approach can be significantly modified from defaults with a number of optional arguments. The num_peaks argument specifes how many peaks should be found in the smoothened KDE and ref_peak specifies around which peak the gate's cutpoint should be placed (starting from the leftmost peak). Setting the side argument to "left" modifies the procedure to put the cutpoint on the left side of the reference peak to isolate a left tail. The max and min arguments allow for pre-filtering extreme values in the channel of interest (keeping only observations with channel values less than max and/or more than min). The bandwidth used for kernel density estimation can be proportionally scaled using adjust (e.g. adjust = 0.5 will use a bandwidth that is half of the default). This allows for tuning the level of smoothing applied in the estimation.

Lastly, the tol, auto_tol, and bias arguments allow for adjustments to be made to the cutpoint that would otherwise be returned. tol provides a tolerance value that the absolute value of the KDE derivative at the cutpoint must be under. If the derivative at the original cutpoint is greater than tol in magnitude, the returned cutpoint will be the first point to the right of the original cutpoint (or to the left in the case of side = "left") with corresponding derivative within tol. Thus in practice, a smaller value for tol effectively pushes the cutpoint further down the shoulder of the peak towards the flat tail. tol is set to 0.01 by default but setting auto_tol = TRUE will set the tolerance to a reasonable estimate of 1% of the maximum absolute value of the first derivative of the KDE. tol and auto_tol are only used for method = "first_deriv". Additionally, the bias argument allows for directly shifting the returned cutpoint left or right.

It is also possible to pass additional arguments to control the calculation of the derivative, which will have some effect on the resulting cutpoint determination, but this should usually not be needed. By default the number of grid points for the derivative calculation will be 10,000, but this can be changed with num_points. The default bandwidth can also be directly adjusted with bandwidth, where the final value used will be given by adjust*bandwidth

By default, we compute the first derivative of the kernel density estimate. Next, we determine the lowest valley from the derivative, which corresponds to the density's mode for cytokines. We then contruct a gating cutpoint as the value less than the tolerance value tol in magnitude and is also greater than the lowest valley.

Alternatively, if the method is selected as second_deriv, we select a cutpoint from the second derivative of the KDE. Specifically, we choose the cutpoint as the largest peak of the second derivative of the KDE density which is greater than the reference peak.


if (FALSE) { gate <- gate_tail(fr, Channel = "APC-A") # fr is a flowFrame }