Switch to side-by-side view

--- a
+++ b/gen_unfold_template/gen_adaptivesurfs.py
@@ -0,0 +1,146 @@
+import numpy as np
+import scipy
+import nibabel as nib
+import matplotlib.pyplot as plt
+from scipy.spatial import Delaunay
+import matplotlib
+matplotlib.use('Agg')
+from scipy.interpolate import RegularGridInterpolator
+
+
+# this script creates a mesh with triangulation density locally-adaptive based on an average surface area.
+
+# the original grid spacing was 128 points over 20mm (or 20/128)
+
+# since surf vertex area is proportional to grid spacing squared,
+# if S_target and S_in are the target and input surface areas, then,
+# adjustment to get corrected grid spacing: 
+
+# (20/N)^2 = (S_target / S_in)  * (20/128)^2
+
+# equiv to:
+# N = 128 * sqrt(S_in / S_target)
+
+
+# the approach this script takes is to create a set of grids at diff resolutions, and pick the grid points based on the binned input surface area..
+
+# all the points from the different resolutions are then triangulated
+
+target_surfarea = snakemake.params.targetarea
+num_bins = snakemake.params.nbins
+
+n_ap = snakemake.config['in_surfarea']['dims'][0]
+n_pd = snakemake.config['in_surfarea']['dims'][1]
+start_ap = snakemake.config['in_surfarea']['start'][0]
+end_ap = snakemake.config['in_surfarea']['end'][0]
+start_pd = snakemake.config['in_surfarea']['start'][1]
+end_pd = snakemake.config['in_surfarea']['end'][1]
+
+N_pd = n_pd+2 # i.e. 128 for hipp, 32 for dentate
+aspect_ratio = int((n_ap+2) / (n_pd+2)) # e.g. 256/128 = 2 for hipp, and 256/32 = 5 for dentate
+
+#load average surface area metric
+surfarea_gii = nib.load(snakemake.input.surfarea_gii)
+arr_surfarea = surfarea_gii.get_arrays_from_intent('NIFTI_INTENT_NORMAL')[0].data.reshape(n_pd,n_ap)
+
+
+#replace nan with 0.01 (actually, shouldn't be any nans with the latest workflow) 
+arr_surfarea = np.nan_to_num(arr_surfarea,nan=0.01)
+
+#bin the image into discrete regions using histogram
+(histval,histedges) = np.histogram(arr_surfarea.flat,bins=num_bins)
+binned_area = np.zeros(arr_surfarea.shape)
+
+for i in range(len(histedges)-1):
+
+    masked = np.logical_and(arr_surfarea>=histedges[i],arr_surfarea<histedges[i+1])
+    binned_area[masked] = i
+
+print(binned_area.shape)
+
+
+
+# create an interpolator to sample the surfarea on each new grid
+
+orig_x = np.linspace(start_ap,end_ap,n_ap) #since the original flat space was offset a bit from 0-40,0-20
+orig_y = np.linspace(start_pd,end_pd,n_pd)
+print(orig_x)
+print(orig_y)
+
+#now, for each multi-res grid, interpolate the bin value
+interpolator = RegularGridInterpolator((orig_y, orig_x), binned_area,method='nearest')
+
+
+
+
+multires_points = list()
+
+#create grid for each bin centre
+for i in range(len(histedges)-1):
+    
+    in_surfarea = (histedges[i] + histedges[i+1]) * 0.5 # histogram bin centre 
+    #bin_centre is the mean vertex area for those vertices
+
+
+    # adjustment to get corrected grid spacing (1/N)
+    # 1/N = (S_target / S_in)^2  * (1/128)
+
+    # equiv to:
+    # N = 128 * sqrt(S_in / S_target)
+
+    print(f'input surf area at bin {i}: {in_surfarea}')
+
+    
+    N = int(N_pd * np.sqrt(in_surfarea/ target_surfarea))
+    #N = int(snakemake.params.scaling_factor * np.power(in_surfarea / target_surfarea,snakemake.params.power_factor))
+    print(f'N for gridding is: {N}')
+    print(N)
+
+    nx, ny = (aspect_ratio*N,N)
+    x = np.linspace(start_ap,end_ap, nx)
+    y = np.linspace(start_pd,end_pd, ny)
+    #print(x)
+    #print(y)
+    xv, yv = np.meshgrid(y,x)
+
+   # print(xv.max())
+   # print(yv.max())
+    binval = interpolator((xv,yv))
+
+    #now get points for the binval
+    #coords = np.unravel_index(np.where(binval==i),xv.shape)
+    #print(coords)
+
+    coords_x = xv[np.where(binval==i)]
+   # print(coords_x)
+
+    coords_y = yv[np.where(binval==i)]
+   # print(coords_y)
+
+    multires_points.append(np.transpose(np.vstack((coords_x,coords_y))))
+
+
+all_points = np.vstack(multires_points)
+print(all_points.shape)
+
+#plot a grid
+tri = Delaunay(all_points)
+plt.figure(figsize=(50,100))
+plt.triplot(all_points[:,0], all_points[:,1], tri.simplices)
+plt.plot(all_points[:,0], all_points[:,1], '.')
+plt.savefig(snakemake.output.grid_png)
+
+
+#write the vertices and triangles as csv 
+#so we can create gifti from matlab
+
+nverts = all_points.shape[0]
+print(f'nverts: {nverts}')
+nbins = num_bins
+vertices_fname = snakemake.output.points_csv
+triangles_fname = snakemake.output.triangles_csv
+
+
+np.savetxt(vertices_fname,tri.points,fmt='%f')
+np.savetxt(triangles_fname,tri.simplices,fmt='%u')
+