<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def read_param_file(FileName, parameters, bp, bp_range, word=False, startBP=1):
 """ Read parameters from do_x3dna file. It is the main function, which is used to read and extract the parameters values from the do_x3dna output files. Parameters FileName : str Parameter file produced from do_x3dna. parameters : list List of column indices that has to be extracted. indices here start with one. bp : 1D list or array base-pairs to analyze Example: :: bp = [6] # bp_range = False bp = [4,15] # bp_range = True bp = range(4,15) # bp_range = False bp = np.arange(4,15) # bp_range = False bp = [2,5,6,7,9,12,18] # bp_range = False bp_range : bool ``Default=True``: As shown above, if ``True``, bp is taken as a range otherwise list or numpy array. word : bool In some parameters, in place of value, ``'---'`` is present in the file. If parameter values contain this, use ``True``. startBP : int Number ID of first base-pair. Returns ------- data : 3D array Extracted parameters as a 3D array of shape (bp, parameters, time). time : 1D array Time of each frame """


    sys.stdout.write("\nReading file : %s\n" % FileName)
    sys.stdout.flush()

    def get_frame_data(block, parameters, bp_idx):
        block = np.array(block).T
        temp_data = (block[parameters, :])[:, bp_idx].copy()
        return temp_data

    def get_time(line):
        dummy, temp_time = line.split('=')
        return float( temp_time )

    infile = open(FileName, 'r')
    data = []
    time = []
    frame_number = 0

    bp_idx, param_idx = get_idx_of_bp_parameters(bp, parameters, bp_range, startBP=startBP)

    block = []
    for line in infile:

        # Removing last new line character
        line = line.rstrip('\n')

        # Skipping blank/empty line
        if not line.strip():
            continue

        # Getting Time tag and time => Starting of new frame
        if(re.match('# Time', line) != None):

            if((frame_number < 100) and (frame_number % 10 == 0)) or ((frame_number < 1000) and (frame_number % 100 == 0)) or ((frame_number < 10000) and (frame_number % 1000 == 0)) or ((frame_number < 100000) and (frame_number % 10000 == 0)) or ((frame_number < 1000000) and (frame_number % 100000 == 0)):
                sys.stdout.write("\rReading frame %d" % frame_number)
                sys.stdout.flush()

            frame_number += 1

            # if(frame_number==5000):
            # break

            # Getting time
            time.append(get_time(line))

            # Getting parameters/values for base-pairs
            if(len(block) > 0):
                data.append(get_frame_data(block, param_idx, bp_idx))
            block = []
            continue

        # Skipping other lines starting with '#' tag
        if(re.match('#', line) != None):
            continue

        if not word:
            block.append(list(map(float, line.split())))
        else:
            temp = []
            split_line = line.split()
            for word in split_line:
                if word != '---':
                    temp.append(float(word))
                else:
                    temp.append(None)
            block.append(temp)

    # For last frame
    data.append(get_frame_data(block, param_idx, bp_idx))
    block = []
    data_transpose = np.array(data).T

    sys.stdout.write(
        "\nFinished reading.... Total number of frame read =  %d\n" % frame_number)
    sys.stdout.flush()

    return data_transpose, time