def generate_example(ivel):

    SIM_NUM = ivel
    VEL_FILE = VEL_DIR + "velocity_%.8i.txt" % (ivel)

    if SIM_NUM % QC_FREQ == 0: OUTPUT_WAVEFIELD = 1
    else: OUTPUT_WAVEFIELD = 0  # whether to output wavefield (I/O heavy!)

    # run a separate simulation for each source
    for isource, source_i in enumerate(source_is[SIM_NUM]):

        # create a temporary directory for simulation output (prevent I/O clash between processes)
        TEMP_OUT_SIM_DIR = OUT_SIM_DIR + str(SIM_NUM) + "/"
        io_utils.get_dir(TEMP_OUT_SIM_DIR)

        # create receiver file
        RECEIVER_FILE = TEMP_OUT_SIM_DIR + "receiver_ijs_%s_%i.txt" % (SIM_RUN,
                                                                       SIM_NUM)
        with open(RECEIVER_FILE, 'w') as f:
            f.write("%i\n" % (N_REC))
            for rec_i in receiver_is:
                f.write("%i %i\n" %
                        (rec_i[0] + 1, rec_i[1] +
                         1))  # SEISMIC CPML uses indices starting at 1

        # create source file (single source)
        SOURCE_FILE = TEMP_OUT_SIM_DIR + "source_ijs_%s_%i.txt" % (SIM_RUN,
                                                                   SIM_NUM)
        with open(SOURCE_FILE, 'w') as f:
            f.write("%i\n" % (1))
            f.write("%i %i\n" % (source_i[0] + 1, source_i[1] +
                                 1))  # SEISMIC CPML uses indices starting at 1

        # RUN FORWARD SIMULATION

        cmd = "./xmodified_seismic_CPML_2D_pressure_second_order " + \
            "%s %s %s %s %s %s %s %s %s %s %s %s %s %s %s"%(
            NSTEPS,
            NX,
            NY,
            DELTAX,
            DELTAY,
            DELTAT,
            NPOINTS_PML,
            0,# SOURCE_X (m)
            0,# SOURCE_Z (m)
            SOURCE_FILE,
            VEL_FILE,
            TEMP_OUT_SIM_DIR,
            SIM_NUM,
            RECEIVER_FILE,
            OUTPUT_WAVEFIELD)

        return_code = run_command(cmd.split(" "), verbose=False)  # run

        if return_code != 0:
            print("ERROR: Simulation %i, %i broke, check stderr" %
                  (ivel, isource))
            # CLEAR INTERMEDIARY FILES (CAREFUL !)
            io_utils.remove_dir(TEMP_OUT_SIM_DIR)
            return False

        # IMPORT GATHER INTO NUMPY

        gather = np.zeros((N_REC, NSTEPS), dtype=np.float32)
        file = TEMP_OUT_SIM_DIR + "gather_%.8i.bin" % (SIM_NUM)
        # Read each binary gather file (MUCH QUICKER THAN READING TEXT FILES, beacause its directed)
        with open(file, 'rb') as f:
            #Note SEISMIC_CPML double precision saved to 64 bit floats (!) we DOWNSAMPLE to 32 bit floats
            # count = number of items (==np.float64 values) to process)
            for irec in np.arange(N_REC):
                gather[irec, :] = np.fromfile(f,
                                              dtype=np.float64,
                                              count=NSTEPS).astype(np.float32)

        # PRE-PROCESSING
        gather_decimated = np.copy(gather)  # important to copy
        gather_decimated = gather_decimated[:, ::ds]  # DOWNSAMPLE GATHER

        # SAVE
        np.save(OUT_SIM_DIR + "gather_%.8i_%.8i.npy" % (SIM_NUM, isource),
                gather_decimated)

        # IMPORT WAVEFIELDS INTO NUMPY (for QC)
        if OUTPUT_WAVEFIELD:
            wavefields = np.zeros((NSTEPS, NX, NY), dtype=np.float32)
            files = [
                TEMP_OUT_SIM_DIR + "wavefield_%.8i_%.8i.bin" % (SIM_NUM, i + 1)
                for i in range(NSTEPS)
            ]  # SEISMIC CPML uses indices starting at 1
            for i in range(NSTEPS):
                # Read each binary wavefield file (MUCH QUICKER THAN READING TEXT FILES, beacause its directed)
                with open(files[i], 'rb') as f:
                    #Note SEISMIC_CPML double precision saved to 64 bit floats (!) we DOWNSAMPLE to 32 bit floats
                    # count = number of items (==np.float64 values) to process)
                    for iz in np.arange(NY):
                        wavefields[i, :, iz] = np.fromfile(f,
                                                           dtype=np.float64,
                                                           count=NX).astype(
                                                               np.float32)

            np.save(
                OUT_SIM_DIR + "wavefields_%.8i_%.8i.npy" % (SIM_NUM, isource),
                wavefields)
            np.save(
                OUT_SIM_DIR + "gather_raw_%.8i_%.8i.npy" % (SIM_NUM, isource),
                gather)

        # CLEAR INTERMEDIARY FILES (CAREFUL !)
        io_utils.remove_dir(TEMP_OUT_SIM_DIR)

    return True
    0,# SOURCE_Z (m)
    SOURCE_FILE,
    VEL_FILE,
    TEMP_OUT_SIM_DIR,
    SIM_NUM,
    RECEIVER_FILE,
    OUTPUT_WAVEFIELD)

# Inference
times = []
for i in range(25):
    start = time.time()
    for i in range(100):
        return_code = run_command(cmd.split(" "),verbose=False) # run
    end = time.time()
    times.append(end-start)
    print(end-start)
    
    if return_code != 0:
        print("ERROR: Simulation broke, check stderr")
    
times = np.array(times)[5:]
print(times)
print("Total time: %.4f +/- %.4f"%(times.mean(), times.std()))


io_utils.remove_dir(TEMP_OUT_SIM_DIR)