<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def gqrs_detect(sig=None, fs=None, d_sig=None, adc_gain=None, adc_zero=None, threshold=1.0, hr=75, RRdelta=0.2, RRmin=0.28, RRmax=2.4, QS=0.07, QT=0.35, RTmin=0.25, RTmax=0.33, QRSa=750, QRSamin=130):
 """ Detect qrs locations in a single channel ecg. Functionally, a direct port of the gqrs algorithm from the original wfdb package. Accepts either a physical signal, or a digital signal with known adc_gain and adc_zero. See the notes below for a summary of the program. This algorithm is not being developed/supported. Parameters sig : 1d numpy array, optional The input physical signal. The detection algorithm which replicates the original, works using digital samples, and this physical option is provided as a convenient interface. If this is the specified input signal, automatic adc is performed using 24 bit precision, to obtain the `d_sig`, `adc_gain`, and `adc_zero` parameters. There may be minor differences in detection results (ie. an occasional 1 sample difference) between using `sig` and `d_sig`. To replicate the exact output of the original gqrs algorithm, use the `d_sig` argument instead. fs : int, or float The sampling frequency of the signal. d_sig : 1d numpy array, optional The input digital signal. If this is the specified input signal rather than `sig`, the `adc_gain` and `adc_zero` parameters must be specified. adc_gain : int, or float, optional The analogue to digital gain of the signal (the number of adus per physical unit). adc_zero: int, optional The value produced by the ADC given a 0 volt input. threshold : int, or float, optional The relative amplitude detection threshold. Used to initialize the peak and qrs detection threshold. hr : int, or float, optional Typical heart rate, in beats per minute. RRdelta : int or float, optional Typical difference between successive RR intervals in seconds. RRmin : int or float, optional Minimum RR interval ("refractory period"), in seconds. RRmax : int or float, optional Maximum RR interval, in seconds. Thresholds will be adjusted if no peaks are detected within this interval. QS : int or float, optional Typical QRS duration, in seconds. QT : int or float, optional Typical QT interval, in seconds. RTmin : int or float, optional Minimum interval between R and T peaks, in seconds. RTmax : int or float, optional Maximum interval between R and T peaks, in seconds. QRSa : int or float, optional Typical QRS peak-to-peak amplitude, in microvolts. QRSamin : int or float, optional Minimum QRS peak-to-peak amplitude, in microvolts. Returns ------- qrs_locs : numpy array Detected qrs locations Notes ----- This function should not be used for signals with fs <= 50Hz The algorithm theoretically works as follows: - Load in configuration parameters. They are used to set/initialize the: * allowed rr interval limits (fixed) * initial recent rr interval (running) * qrs width, used for detection filter widths (fixed) * allowed rt interval limits (fixed) * initial recent rt interval (running) * initial peak amplitude detection threshold (running) * initial qrs amplitude detection threshold (running) * `Note`: this algorithm does not normalize signal amplitudes, and hence is highly dependent on configuration amplitude parameters. - Apply trapezoid low-pass filtering to the signal - Convolve a QRS matched filter with the filtered signal - Run the learning phase using a calculated signal length: detect qrs and non-qrs peaks as in the main detection phase, without saving the qrs locations. During this phase, running parameters of recent intervals and peak/qrs thresholds are adjusted. - Run the detection:: if a sample is bigger than its immediate neighbors and larger than the peak detection threshold, it is a peak. if it is further than RRmin from the previous qrs, and is a *primary peak. if it is further than 2 standard deviations from the previous qrs, do a backsearch for a missed low amplitude beat return the primary peak between the current sample and the previous qrs if any. if it surpasses the qrs threshold, it is a qrs complex save the qrs location. update running rr and qrs amplitude parameters. look for the qrs complex's t-wave and mark it if found. else if it is not a peak lower the peak detection threshold if the last peak found was more than RRmax ago, and not already at its minimum. *A peak is secondary if there is a larger peak within its neighborhood (time +- rrmin), or if it has been identified as a T-wave associated with a previous primary peak. A peak is primary if it is largest in its neighborhood, or if the only larger peaks are secondary. The above describes how the algorithm should theoretically work, but there are bugs which make the program contradict certain parts of its supposed logic. A list of issues from the original c, code and hence this python implementation can be found here: https://github.com/bemoody/wfdb/issues/17 gqrs will not be supported/developed in this library. Examples -------- fs=record_2.fs, adc_gain=record_2.adc_gain[0], adc_zero=record_2.adc_zero[0]) """

    # Perform adc if input signal is physical
    if sig is not None:
        record = Record(p_signal=sig.reshape([-1,1]), fmt=['24'])
        record.set_d_features(do_adc=True)
        d_sig = record.d_signal[:,0]
        adc_zero = 0
        adc_gain = record.adc_gain[0]

    conf = GQRS.Conf(fs=fs, adc_gain=adc_gain, hr=hr, RRdelta=RRdelta, RRmin=RRmin,
                RRmax=RRmax, QS=QS, QT=QT, RTmin=RTmin, RTmax=RTmax, QRSa=QRSa,
                QRSamin=QRSamin, thresh=threshold)
    gqrs = GQRS()

    annotations = gqrs.detect(x=d_sig, conf=conf, adc_zero=adc_zero)

    return np.array([a.time for a in annotations])