#!/usr/bin/env python # written by PA Taylor (NIMH, NIH), Feb 2017 # # find out a good ratio to make montage dimensions; if necessary, add # some to get closer to golden ratio, but we have a reasonable # tolerance, as well. ### [PT: July 17, 2018] CONVERTED__python__2to3 ### [PT: July 25, 2018] # + fixed upper limit to allow square values to be found. # ### [PT: Dec 5, 2018] # + reduce depencies: no scipy or numpy needed anymore # # -------------------------------------------------------------------- import sys as sys help_string = ''' Just a simple helper function for the fat_proc* scripts. Nuthin' to see here, folks! ''' GOLD = 1.618033988749895 # golden_ratio #MAX_NCOL = 8 check_dist = 4 OKOK_dist = 0.4 # allowable distance, to minimize adding def get_arg(aa): Narg = len(aa) if Narg < 2: print(help_string) sys.exit(0) elif aa[1] == '-help': print(help_string) sys.exit(0) elif Narg == 2: sys.exit("** ERROR: too few args! Need exactly one integer\n" " and an output filename (and one optional integer\n" " the max num of columns output).") elif Narg > 4: sys.exit("** ERROR: too many args! Need exactly one integer\n" " and an output filename (and one optional integer\n" " the max num of columns output).") else: aaint = int(aa[1]) apref = aa[2] print("++ OK, have my integer argument:", aaint) return aaint, apref def get_facs(AA): AA_facs1 = [] AA_facs2 = [] # [PT: Dec 5, 2018] new def of this val, no numpy used; also # adjust upper limit of fac_ceil bc of this fac_ceil = int(AA**0.5) + 1 for i in range(1, fac_ceil): if not(AA % i): AA_facs1.append(i) AA_facs2.append(AA // i) return AA_facs1, AA_facs2 def calc_ratios(AA_h, AA_l): La = len(AA_h) AA_rat = [] for i in range(La): AA_rat.append( float(AA_h[i])/float(AA_l[i]) ) return AA_rat def calc_rat_dist_from_gold(x): y = float(x)/GOLD return abs(y-1.) def find_best_rat( AA_rat ): dist = 10.**10 idx = -1 La = len(AA_rat) for i in range(La): rr = AA_rat[i] dd = calc_rat_dist_from_gold(rr) if dd < dist : idx = i dist = dd if idx < 0: sys.exit("**ERROR! negative index in find_best_rat()") return i, dist # now use lists instead of arrays def get_best_rat(AA): idx_fin = -1 min_dist = 10.**10 all_rats = [0] * check_dist # np.zeros(check_dist) all_vals = [] # np.zeros((check_dist,3), dtype=int) for i in range(check_dist): all_vals.append([0]*3) for j in range(check_dist): (AA_l, AA_h) = get_facs(AA+j) (idx, dist) = find_best_rat( calc_ratios(AA_h, AA_l) ) print(AA_l) print(AA_h) print(idx, AA_h[idx], AA_l[idx], dist) all_rats[j] = dist all_vals[j][0] = idx all_vals[j][1] = AA_h[idx] all_vals[j][2] = AA_l[idx] if all_rats[j] < min_dist: idx_fin = j min_dist = all_rats[j] # put this in as a "good enough" ratio, even if not ideal # within dist, so we don't needlessly add vols if min_dist < OKOK_dist: print("++ OK! Good enough") break if idx < 0: sys.exit("**ERROR! negative index in find_best_rat()") return AA+idx_fin, all_vals[idx_fin] ''' # old version: used numpy/arrays def get_best_rat(AA): idx_fin = -1 min_dist = 10.**10 all_rats = np.zeros(check_dist) all_vals = np.zeros((check_dist,3), dtype=int) for j in range(check_dist): (AA_l, AA_h) = get_facs(AA+j) (idx, dist) = find_best_rat( calc_ratios(AA_h, AA_l) ) print(AA_l) print(AA_h) print(idx, AA_h[idx], AA_l[idx], dist) all_rats[j] = dist all_vals[j, 0] = idx all_vals[j, 1] = AA_h[idx] all_vals[j, 2] = AA_l[idx] if all_rats[j] < min_dist: idx_fin = j min_dist = all_rats[j] # put this in as a "good enough" ratio, even if not ideal # within dist, so we don't needlessly add vols if min_dist < OKOK_dist: print("++ OK! Good enough") break if idx < 0: sys.exit("**ERROR! negative index in find_best_rat()") return AA+idx_fin, all_vals[idx_fin, :] ''' if __name__=="__main__": print("++ Command line:", sys.argv) (AA, Apref) = get_arg(sys.argv) (Afinal, Arats) = get_best_rat(AA) Apad = Afinal - AA Acol = Arats[1] Arow = Arats[2] print("\n---------------------------------------------") print("++ final Nslices = "+str(Afinal)+" (pad = "+str(Apad)+")") print("++ -> Ncol x Nrow = "+str(Acol)+" x "+str(Arow)) print("---------------------------------------------\n") f = open(Apref, 'w') f.write('# %10s %10s %10s %10s\n' % ("Final", "Pad", "Ncol", "Nrow")) f.write(' %10d %10d %10d %10d' % (Afinal, Apad, Acol, Arow)) f.close() sys.exit(0)