def frame_rti(detectorrows, ampcolumns, colstart, colstop, rowstart, rowstop,
              sampleskip, refpixsampleskip, samplesum, resetwidth,
              resetoverhead, burst_mode):
    """
    
    Helper function which calculates the number of clock cycles, or RTI,
    needed to read out the detector with a given a list of FPGA parameters.
    This function can be used to test the frame time calculation over a
    wide range of scenarios.
    
    :Reference:
    
    JPL MIRI DFM 478 04.02, MIRI FPS Exposure Time Calculations,
    M. E. Ressler, October 2014

    :Parameters:
    
    detectorrows:
        Total number of detector rows.
    ampcolumns
        Total number of amplifier columns (including reference columns).
        = Total number of detector columns / Number of amplifiers.
    colstart: int
        Amplifier column at which readout starts.
        Derived from the subarray mode.
    colstop: int
        Amplifier column at which readout stops.
        Derived from the subarray mode.
    rowstart: int
        Detector row at which readout starts.
        Derived from the subarray mode.
    rowstop: int
        Detector row at which readout stops.
        Derived from the subarray mode.
    sampleskip: int
        Number of clock cycles to dwell on a pixel before reading it.
        Derived from the readout mode.
    refpixsampleskip: int
        Number of clock cycles to dwell on a reference pixel before reading it.
        Derived from the readout mode.
    samplesum: int
        Number of clock cycles to sample a pixel during readout.
    resetwidth: int
        Width of the reset pulse in clock cycles.
        Derived from the readout mode.
    resetoverhead: int
        The overhead, in clock cycles, associated with setting shift
        registers back to zero.
    burst_mode: boolean, optional, default is False
        True if a subarray is being read out in burst mode,
        which skips quickly over unwanted columns.
        
    :Returns:
    
    frame_rti: float
        Number of clock cycles (RTI) for readout.
    
    """            
    # The time taken to skip a row not contained in a subarray is the
    # row reset overhead, which is the reset pulse width plus the overhead
    # to reset the shift registers.
    row_reset = resetwidth + resetoverhead
    rti_row_non_roi = row_reset

    # The number of clock cycles needed to read a pixel is the         
    pix_clocks = sampleskip + samplesum
    refpix_clocks = refpixsampleskip + samplesum
    
    if (colstart == 1) or (not burst_mode):
        # For a row within a subarray (if burst_mode is False or the subarray
        # begins at column 1), we start with the row reset overheads, then add
        # the reference pixel time, refpix_clocks, then add the science pixel
        # time, n * pix_clocks.
        rti_row_roi = row_reset
#         strg = "rti_row_roi=%d " % row_reset
        if colstart == 1:
            rti_row_roi += refpix_clocks
#             strg += " + %d " % refpix_clocks
        else:
            rti_row_roi += resetwidth
        if colstop == ampcolumns:
            rti_row_roi += (colstop-2) * pix_clocks
#             strg += " + (%d * %d) " % ((colstop-2), pix_clocks)
            rti_row_roi += refpix_clocks
#             strg += " + %d " % refpix_clocks
        else:
            rti_row_roi += (colstop-1) * pix_clocks
#             strg += " + (%d * %d) " % ((colstop-1), pix_clocks)
#             print(strg)
    else:
        # In burst_mode, when a subarray does not touch the left hand edge,
        # each row begins with the same reset overhead, then the left hand
        # pixels are clocked at 5 times the normal rate until the subarray
        # is reached. If the number of burst columns is not an even multiple
        # of 5, the readout is paused until a normal clock boundary.
        rti_row_roi = row_reset
#         strg = "rti_row_roi=%d " % row_reset
        if colstart == 1:
            rti_row_roi += refpix_clocks
#             strg += " + %d " % refpix_clocks
        else:
            rti_row_roi += refpix_clocks + ((colstart-2)*pix_clocks+4)//5
#             strg += " + %d + %d " % (refpix_clocks,
#                                      ((colstart-2)*pix_clocks+4)//5)
            
        if colstop == ampcolumns:
            rti_row_roi += ((colstop-2)-colstart+1) * pix_clocks
#             strg += " + (%d * %d) " % (((colstop-2)-colstart+1), pix_clocks)
            rti_row_roi += refpix_clocks
#            strg += " + %d " % refpix_clocks
        else:
            rti_row_roi += (colstop-colstart+1) * pix_clocks
#             strg += " + (%d * %d) " % ((colstop-colstart+1), pix_clocks)
#             print(strg)

    # The total number of clock cycles to read the frame is the sum
    # of the portion before the ROI, after the ROI and during the ROI.
#         print("rti_row_non_roi=", rti_row_non_roi, "rti_row_roi=", rti_row_roi)
    frame_rti = (rowstart-1) * rti_row_non_roi + \
        (rowstop-rowstart+1) * rti_row_roi + \
        (detectorrows-rowstop) * rti_row_non_roi
    return frame_rti