def phantom_generation(tracts, std_noise_perc, range_tract_perc, true_value, folder_out, value_gm, value_csf):
    """
    :param tracts: np array
    :param std_noise: std of noise to generate pseudo-random gaussianly-distributed noise
    :param range_tract: range of value to generate pseudo-random uniformly-distributed tract value
    :param true_value: true value of the tract
    :param folder_out: output folder
    :param zero_last_tract: assign value 0 to last tract (corresponds to CSF)
    :return: synthetic_vol, synthetic_voln, values_synthetic_data, tracts_sum
    """

    fname_phantom = folder_out+'phantom_values.txt'
    #value_gm = 30
    #value_csf = 0

    # Transform std noise and range tract to a percentage of the true value
    range_tract = float(range_tract_perc) / 100 * true_value
    std_noise = float(std_noise_perc) / 100 * true_value

    # Generate synthetic Volume  
    numtracts = len(tracts)
    nx, ny, nz = tracts[0][0].shape

   # open txt file that includes true values per tract
    fid_file = open(fname_phantom, 'w+')
    print >> fid_file, 'std_noise='+str(std_noise_perc)+'%, range_tract='+str(range_tract_perc)+'%, true_value='+str(true_value)

    # create volume of tracts with randomly-assigned values
    tracts_weighted = np.zeros([numtracts, nx, ny, nz])
    synthetic_vol = np.zeros([nx, ny, nz])
    synthetic_voln = np.zeros([nx, ny, nz])
    values_synthetic_data = np.zeros([numtracts])
    for i in range(0, numtracts):
        if i == numtracts-2:
            values_synthetic_data[i] = value_gm
        elif i == numtracts-1:
            values_synthetic_data[i] = value_csf
        else:
            values_synthetic_data[i] = (true_value - range_tract + random.uniform(0, 2-range_tract))  # true_value - range_tract <= values_synthetic_data <= true_value + range_tract
        print >> fid_file, 'label=' + str(i) + ', value=' + str(values_synthetic_data[i])
        tracts_weighted[i, :, :, :] = values_synthetic_data[i] * tracts[i, 0]
        # add tract to volume
        synthetic_vol = synthetic_vol + tracts_weighted[i, :, :, :]

    # sum all tracts
    tracts_sum = np.zeros([nx, ny, nz])
    for i in range(0, numtracts):
        tracts_sum = tracts_sum + tracts[i, 0]

    # close txt file
    fid_file.close()

    # add gaussian noise
    if not std_noise == 0:
        synthetic_voln = synthetic_vol + np.random.normal(loc=0, scale=std_noise, size=(nx, ny, nz))
    else:
        synthetic_voln = synthetic_vol

    return[synthetic_vol, synthetic_voln, values_synthetic_data, tracts_sum]


#=======================================================================================================================
# Save 3D numpy array to a nifti
#=======================================================================================================================
dataset/ETHPy150Open neuropoly/spinalcordtoolbox/dev/atlas/validate_atlas/generate_phantom.py/phantom_generation/operator `*` -> `-`