def generate_v1(name, description, options):
    input_block_size = int(options["input_block_size"])
    hidden_size = int(options["hidden_block_size"])
    layer_shape = map(lambda x: int(x), options["layer_shapes"])
    readout_block_size = map(lambda x: int(x), options["readout_block_size"])
    readout_layer = map(lambda x: x == "1", options["enable_readout"])
    lateral_radius = float(options["lateral_radius"])
    fan_in_square_size = int(options["fan_in_square_size"])
    fan_in_radius = int(options["fan_in_radius"])
    readout_depth = int(options["readout_depth"])
    ex_module = options["ex_module"]
    exclude_self = (options["context_exclude_self"] == '1')
    last_layer_context_to_all = (options["last_layer_context_to_all"] == '1')
    send_context_two_layers_back = (
        options["send_context_two_layers_back"] == '1')
    simulation_dict = create_blank_dictionary(
        name=name,
        description=description,
        save_sources=(options["save_source_files"] == '1'))
    simulation_dict['stages'] = 1
    simulation_dict['num_proc'] = 2 * mp.cpu_count() / 3
    simulation_dict['stage0'] = []
    simulation_dict['execution_unit_module'] = ex_module
    simulation_dict['version_major'] = 1
    simulation_dict['version_minor'] = 0
    unit = importlib.import_module(simulation_dict['execution_unit_module'])
    blocks_per_dim = layer_shape
    layers = len(blocks_per_dim)
    error_log = SharedArray.SharedNumpyArray((layers + 1, 1000000), np.float)
    simulation_dict['error_log'] = error_log

    simulation_dict['input_block_size'] = input_block_size
    simulation_dict['hidden_size'] = hidden_size
    simulation_dict['learning_rates'] = []
    simulation_dict['momenta'] = []
    simulation_dict['taus'] = []
    simulation_dict['predicted_arrays'] = []
    simulation_dict['predicted_arrays_t2'] = []
    simulation_dict['predicted_readout_arrays'] = []
    simulation_dict['readout_arrays'] = []
    simulation_dict['state_arrays'] = []
    simulation_dict['delta_arrays'] = []

    input_array = SharedArray.SharedNumpyArray(
        (input_block_size * blocks_per_dim[0],
         input_block_size * blocks_per_dim[0], 3), np.uint8)
    simulation_dict['input_array'] = input_array
    input_array_float = SharedArray.SharedNumpyArray(
        (input_block_size * blocks_per_dim[0],
         input_block_size * blocks_per_dim[0], 3), np.float)
    simulation_dict['input_array_float'] = input_array_float

    for (i, bpd) in enumerate(blocks_per_dim):
        if readout_layer[i]:
            readout_array_float00 = SharedArray.SharedNumpyArray(
                (bpd * readout_block_size[i], bpd * readout_block_size[i],
                 readout_depth), np.float)
            simulation_dict['readout_arrays'].append(readout_array_float00)
            predicted_readout_array_float00 = SharedArray.SharedNumpyArray(
                (bpd * readout_block_size[i], bpd * readout_block_size[i],
                 readout_depth), np.float)
            simulation_dict['predicted_readout_arrays'].append(
                predicted_readout_array_float00)

    # input array 0 is a special case, 3 dimensions because of color input
    predicted_array0 = SharedArray.SharedNumpyArray(
        (input_block_size * blocks_per_dim[0],
         input_block_size * blocks_per_dim[0], 3), np.float)
    simulation_dict['predicted_arrays'].append(predicted_array0)
    predicted_array2 = SharedArray.SharedNumpyArray(
        (input_block_size * blocks_per_dim[0],
         input_block_size * blocks_per_dim[0], 3), np.float)
    simulation_dict['predicted_arrays_t2'].append(predicted_array2)
    delta_array0 = SharedArray.SharedNumpyArray(
        (input_block_size * blocks_per_dim[0],
         input_block_size * blocks_per_dim[0], 3), np.float)
    simulation_dict['delta_arrays'].append(delta_array0)
    # All the rest is generic
    for (i, bpd) in enumerate(blocks_per_dim[:-1]):
        predicted_array1 = SharedArray.SharedNumpyArray(
            (hidden_size * bpd, hidden_size * bpd), np.float)
        simulation_dict['predicted_arrays'].append(predicted_array1)
        predicted_array2 = SharedArray.SharedNumpyArray(
            (hidden_size * bpd, hidden_size * bpd), np.float)
        simulation_dict['predicted_arrays_t2'].append(predicted_array2)
        delta_array1 = SharedArray.SharedNumpyArray(
            (hidden_size * bpd, hidden_size * bpd), np.float)
        simulation_dict['delta_arrays'].append(delta_array1)
    for (i, bpd) in enumerate(blocks_per_dim):
        state_array0 = SharedArray.SharedNumpyArray(
            (hidden_size * bpd, hidden_size * bpd), np.float)
        simulation_dict['state_arrays'].append(state_array0)

    # Base learning rate
    for (i, bpd) in enumerate(blocks_per_dim):
        learning_rate = SharedArray.SharedNumpyArray((1, ), np.float)
        learning_rate[0] = 0.0
        simulation_dict['learning_rates'].append(learning_rate)
    additional_learning_rate = SharedArray.SharedNumpyArray((1, ), np.float)
    additional_learning_rate[0] = 0.0
    simulation_dict['readout_learning_rate'] = additional_learning_rate
    # Momentum is the same everywhere.
    momentum = SharedArray.SharedNumpyArray((1, ), np.float)
    momentum[0] = float(options["momentum"])
    simulation_dict['momentum'] = momentum
    # Tau is the integration constant for the signal integral
    tau = SharedArray.SharedNumpyArray((1, ), np.float)
    tau[0] = float(options['tau'])
    simulation_dict['tau'] = tau
    context_factor_lateral = SharedArray.SharedNumpyArray((1, ), np.float)
    context_factor_lateral[0] = 0.0
    simulation_dict['context_factor_lateral'] = context_factor_lateral
    context_factor_feedback = SharedArray.SharedNumpyArray((1, ), np.float)
    context_factor_feedback[0] = 0.0
    simulation_dict['context_factor_feedback'] = context_factor_feedback
    base_index = [0]
    for bpd in blocks_per_dim:
        base_index.append(base_index[-1] + bpd * bpd)

    # Layer 0 is specific and has to be constructed separately
    for i in xrange(blocks_per_dim[0] * blocks_per_dim[0]):
        unit_parameters = create_basic_unit_v1(
            simulation_dict['learning_rates'][0], momentum, tau,
            additional_learning_rate)
        x = (i / blocks_per_dim[0]) * input_block_size
        y = (i % blocks_per_dim[0]) * input_block_size
        dx = input_block_size
        dy = input_block_size
        input_block = SharedArray.DynamicView(input_array_float)[x:x + dx,
                                                                 y:y + dy]
        predicted_block = SharedArray.DynamicView(
            simulation_dict['predicted_arrays'][0])[x:x + dx, y:y + dy]
        predicted_block_2 = SharedArray.DynamicView(
            simulation_dict['predicted_arrays_t2'][0])[x:x + dx, y:y + dy]
        delta_block = SharedArray.DynamicView(
            simulation_dict['delta_arrays'][0])[x:x + dx, y:y + dy]
        if not (predicted_block.shape == (dx, dy, 3)):
            print predicted_block.shape
            raise Exception("Block sizes don't agree")
        k = (i / blocks_per_dim[0]) * hidden_size
        l = (i % blocks_per_dim[0]) * hidden_size
        output_block = SharedArray.DynamicView(
            simulation_dict['state_arrays'][0])[k:k + hidden_size,
                                                l:l + hidden_size]
        unit_parameters['signal_blocks'].append(
            (input_block, delta_block, predicted_block, predicted_block_2))
        unit_parameters['output_block'] = output_block
        if readout_layer[0]:
            # Motor heatmap prediction
            layer = 0
            bpd = blocks_per_dim[layer]
            readout_teaching_block = SharedArray.DynamicView(
                simulation_dict['readout_arrays']
                [layer])[(i / bpd) * readout_block_size[0]:(i / bpd + 1) *
                         readout_block_size[0],
                         (i % bpd) * readout_block_size[0]:(i % bpd + 1) *
                         readout_block_size[0]]
            readout_delta_block = SharedArray.SharedNumpyArray_like(
                readout_teaching_block)
            predicted_readout_block = SharedArray.DynamicView(
                simulation_dict['predicted_readout_arrays']
                [layer])[(i / bpd) * readout_block_size[0]:(i / bpd + 1) *
                         readout_block_size[0],
                         (i % bpd) * readout_block_size[0]:(i % bpd + 1) *
                         readout_block_size[0]]
            unit_parameters['readout_blocks'] = [
                (readout_teaching_block, readout_delta_block,
                 predicted_readout_block)
            ]
            unit_parameters["layer"] = 0
            # End motor heatmap prediction
        simulation_dict['stage0'].append(unit_parameters)
    # Layer 0 surround
    gather_surround(simulation_dict, (base_index[0], blocks_per_dim[0]),
                    radius=lateral_radius,
                    context_factor=context_factor_lateral,
                    exclude_self=exclude_self)

    # The following layers are more generic
    for layer in range(1, layers):
        for i in xrange(blocks_per_dim[layer] * blocks_per_dim[layer]):
            unit_parameters = create_basic_unit_v1(
                simulation_dict['learning_rates'][layer], momentum, tau,
                additional_learning_rate)
            k = (i / blocks_per_dim[layer]) * hidden_size
            l = (i % blocks_per_dim[layer]) * hidden_size
            output_block = SharedArray.DynamicView(
                simulation_dict['state_arrays'][layer])[k:k + hidden_size,
                                                        l:l + hidden_size]
            unit_parameters['output_block'] = output_block
            if readout_layer[layer]:
                # Motor heatmap prediction
                bpd = blocks_per_dim[layer]
                readout_teaching_block = SharedArray.DynamicView(
                    simulation_dict['readout_arrays'][layer])[
                        (i / bpd) * readout_block_size[layer]:(i / bpd + 1) *
                        readout_block_size[layer],
                        (i % bpd) * readout_block_size[layer]:(i % bpd + 1) *
                        readout_block_size[layer]]
                readout_delta_block = SharedArray.SharedNumpyArray_like(
                    readout_teaching_block)
                predicted_readout_block = SharedArray.DynamicView(
                    simulation_dict['predicted_readout_arrays'][layer])[
                        (i / bpd) * readout_block_size[layer]:(i / bpd + 1) *
                        readout_block_size[layer],
                        (i % bpd) * readout_block_size[layer]:(i % bpd + 1) *
                        readout_block_size[layer]]
                unit_parameters['readout_blocks'] = [
                    (readout_teaching_block, readout_delta_block,
                     predicted_readout_block)
                ]
                unit_parameters["layer"] = layer
                # End motor heatmap prediction
            simulation_dict['stage0'].append(unit_parameters)
        # Connect to the previous layer
        connect_forward_and_back_v1(
            simulation_dict, (base_index[layer - 1], blocks_per_dim[layer - 1],
                              simulation_dict['predicted_arrays'][layer],
                              simulation_dict['predicted_arrays_t2'][layer]),
            (base_index[layer], blocks_per_dim[layer]),
            square_size=fan_in_square_size,
            radius=fan_in_radius,
            context_factor=context_factor_feedback)
        # Layer surround
        gather_surround(simulation_dict,
                        (base_index[layer], blocks_per_dim[layer]),
                        radius=lateral_radius,
                        context_factor=context_factor_lateral,
                        exclude_self=exclude_self)
        if send_context_two_layers_back and layer > 1:
            connect_back(simulation_dict,
                         (base_index[layer], blocks_per_dim[layer]),
                         (base_index[layer - 2], blocks_per_dim[layer - 2]),
                         square_size=2 * fan_in_square_size,
                         radius=2 * fan_in_radius,
                         context_factor=context_factor_feedback)

    # Add the global feedback from the top layer
    if last_layer_context_to_all:
        logging.info("Connecting last layer back to everyone")
        for to_idx in xrange(base_index[layers - 1]):
            for from_idx in range(base_index[layers - 1],
                                  len(simulation_dict["stage0"])):
                context_block = simulation_dict['stage0'][from_idx][
                    'output_block']
                delta_block2 = SharedArray.SharedNumpyArray_like(context_block)
                simulation_dict['stage0'][from_idx]['delta_blocks'].append(
                    delta_block2)
                # Connect the context block to the source
                simulation_dict['stage0'][to_idx]['context_blocks'].append(
                    (context_block, delta_block2, context_factor_feedback))

    simulation_dict['stage0_size'] = len(simulation_dict['stage0'])
    for i in range(simulation_dict['stage0_size']):
        simulation_dict['stage0'][i]['flags'] = simulation_dict['flags']
        unit.ExecutionUnit.generate_missing_parameters(
            simulation_dict['stage0'][i], options=options)
    return simulation_dict
                simulation_dict['stage0'][source]['delta_blocks'].append(
                    delta_block)
                # Prepare the context and corresonding delta block at destination
                context_block = simulation_dict['stage0'][dest]['output_block']
                delta_block2 = SharedArray.SharedNumpyArray_like(context_block)
                simulation_dict['stage0'][dest]['delta_blocks'].append(
                    delta_block2)
                # Connect the context block to the source
                simulation_dict['stage0'][source]['context_blocks'].append(
                    (context_block, delta_block2, context_factor))
                # Prepare the predicted blocks
                xx = xy[0] * hidden_size
                yy = xy[1] * hidden_size
                assert (predicted_array[xx:xx + dx, yy:yy +
                                        dy].shape == context_block.shape)
                predicted_block = SharedArray.DynamicView(predicted_array)[
                    xx:xx + dx, yy:yy + dy]
                if not (predicted_block.shape == (dx, dy)):
                    print predicted_block.shape
                    raise
                # Connect the input to the destination together with its predicted blocks and so on.
                past_block = SharedArray.SharedNumpyArray_like(input_block)
                derivative_block = SharedArray.SharedNumpyArray_like(
                    input_block)
                integral_block = SharedArray.SharedNumpyArray_like(input_block)
                pred_block_local = SharedArray.SharedNumpyArray_like(
                    input_block)
                simulation_dict['stage0'][dest]['signal_blocks'].append(
                    (input_block, delta_block, predicted_block, past_block,
                     derivative_block, integral_block, pred_block_local))