def __init__(self, env=None, viewer=None, result_file=None): self.env = None self.smallest = 99999.0 self.largest = 0.0 if env: self.env = env self.smallest, self.largest = self.getMinMaxProteinSize() self.afviewer = viewer self.helper = None if viewer: self.helper = self.afviewer.vi self.resutl_file = result_file self.center = [0, 0, 0] self.bbox = [[0, 0, 0], [1, 1, 1]] self.g = GeometriTools() self.g.Resolution = 1.0 #or grid step?
def __init__(self, env=None, viewer=None, result_file=None): self.env=None self.smallest=99999.0 self.largest = 0.0 if env : self.env = env self.smallest,self.largest = self.getMinMaxProteinSize() self.afviewer = viewer self.helper = None if viewer : self.helper = self.afviewer.vi self.resutl_file = result_file self.center=[0,0,0] self.bbox=[[0,0,0],[1,1,1]] self.g=GeometriTools() self.g.Resolution = 1.0#or grid step?
class AnalyseAP: def __init__(self, env=None, viewer=None, result_file=None): self.env = None self.smallest = 99999.0 self.largest = 0.0 if env: self.env = env self.smallest, self.largest = self.getMinMaxProteinSize() self.afviewer = viewer self.helper = None if viewer: self.helper = self.afviewer.vi self.resutl_file = result_file self.center = [0, 0, 0] self.bbox = [[0, 0, 0], [1, 1, 1]] self.g = GeometriTools() self.g.Resolution = 1.0 #or grid step? def getMinMaxProteinSize(self): smallest = 999999.0 largest = 0.0 for organelle in self.env.compartments: mini, maxi = organelle.getMinMaxProteinSize() if mini < smallest: smallest = mini if maxi > largest: largest = maxi if self.env.exteriorRecipe: mini, maxi = self.env.exteriorRecipe.getMinMaxProteinSize() if mini < smallest: smallest = mini if maxi > largest: largest = maxi return smallest, largest def getPositionsFromResFile(self, ): #could actually restore file using histoVol. #or not #need to parse apr file here anyway return [] def getPositionsFromObject(self, parents): positions = [] for parent in parents: obparent = self.helper.getObject(parent) childs = self.helper.getChilds(obparent) for ch in childs: ingr_name = self.helper.getName(ch) meshp = self.helper.getObject("Meshs_" + ingr_name.split("_")[0]) if meshp is None: c = self.helper.getChilds(ch) if not len(c): continue meshpchilds = self.helper.getChilds( c[0]) #continue #should get sphere/cylnder parent ? else: meshpchilds = self.helper.getChilds(meshp) for cc in meshpchilds: pos = self.helper.ToVec(self.helper.getTranslation(cc)) positions.append(pos) return positions def getDistanceFrom(self, target, parents=None, **options): """ target : name or host object target or target position parent : name of host parent object for the list of object to measre distance from objects : list of object or list of points """ #get distance from object to the target. #all object are in h.molecules and orga.molecules #get options targetPos = [0, 0, 0] usePoint = False threshold = 99999. if "usePoint" in options: usePoint = options["usePoint"] if "threshold" in options: threshold = options["threshold"] if type(target) == list or type(target) == tuple: targetPos = target elif type(target) == unicode or type(target) == str: o = self.helper.getObject(target) if o is not None: targetPos = self.helper.ToVec( self.helper.getTranslation(o)) #hostForm else: o = self.helper.getObject(target) if o is not None: targetPos = self.helper.ToVec( self.helper.getTranslation(o)) #hostForm listeObjs = [] listeDistances = [] listeCenters = [] if self.resutl_file is None: if parents is None and self.resutl_file is None: listeParent = [self.env.name + "_cytoplasm"] for o in self.env.compartments: listeParent.append(o.name + "_Matrix") listeParent.append(o.name + "_surface") elif parents is not None and self.resutl_file is None: listeParent = parents listeCenters = self.getPositionsFromObject(listeParent) else: #use data from file listeCenters = self.getPositionsFromResFile(listeParent) delta = numpy.array(listeCenters) - numpy.array(targetPos) delta *= delta distA = numpy.sqrt(delta.sum(1)) return distA def getClosestDistance(self, parents=None, **options): if self.resutl_file is None: if parents is None and self.resutl_file is None: listeParent = [self.env.name + "_cytoplasm"] for o in self.env.compartments: listeParent.append(o.name + "_Matrix") listeParent.append(o.name + "_surface") elif parents is not None and self.resutl_file is None: listeParent = parents listeCenters = self.getPositionsFromObject(listeParent) else: #use data from file listeCenters = self.getPositionsFromResFile(listeParent) #is the distance in the result array ? listeDistance = numpy.zeros(len(listeCenters)) + 99999 for i in range(len(listeCenters)): for j in range(i + 1, len(listeCenters)): #should use point d = self.helper.measure_distance(listeCenters[i], listeCenters[j]) if d < listeDistance[i]: listeDistance[i] = d return listeDistance def displayDistance(self, ramp_color1=[1, 0, 0], ramp_color2=[0, 0, 1], ramp_color3=None, cutoff=60.0): distances = self.env.grid.distToClosestSurf[:] positions = self.env.grid.masterGridPositions[:] #map the color as well ? from upy import colors as col from DejaVu.colorTool import Map ramp = col.getRamp([[1, 0, 0], [0, 0, 1]], size=255) #color mask = distances > cutoff ind = numpy.nonzero(mask)[0] distances[ind] = cutoff mask = distances < -cutoff ind = numpy.nonzero(mask)[0] distances[ind] = cutoff colors = Map(distances, ramp) # sphs = self.helper.Spheres("distances",vertices=numpy.array(positions),radii=distances,colors=colors) base = self.helper.getObject(self.env.name + "distances_base") if base is None: base = self.helper.Sphere(self.env.name + "distances_base")[0] p = self.helper.getObject(self.env.name + "distances") if p is not None: self.helper.deleteObject(p) #recursif? p = self.helper.newEmpty(self.env.name + "distances") sphs = self.helper.instancesSphere(self.env.name + "distances", positions, distances, base, colors, None, parent=self.env.name + "distances") def loadJSON(self, filename): import json with open(filename) as data_file: data = json.load(data_file) #should take any type of list... def save_csv(self, data, filename=None): if filename is None: filename = "output.csv" resultFile = open(filename, 'wb') wr = csv.writer(resultFile, dialect='excel') #wr.writerows(data) list of list ? #resultFile.close() for item in data: wr.writerow([ item, ]) resultFile.close() def rectangle_circle_area(self, bbox, center, radius): #http://www.eex-dev.net/index.php?id=100 #[[0.,0,0],[1000,1000,1]] rect = Rectangle(bbox[0][0], bbox[1][0], bbox[0][1], bbox[1][1]) #top,bottom, right, left # rect=Rectangle(bbox[1][1],bbox[0][1],bbox[1][0],bbox[0][0])#top,bottom, right, left m = [center[0], center[1]] r = radius area = 0.0 chs = self.g.check_sphere_inside(rect, m, r) if chs: # print "sphere go outside ",r ch = self.g.check_rectangle_oustide(rect, m, r) if ch: leftBound, rightBound = self.g.getBoundary(rect, m, r) area = self.g.get_rectangle_cercle_area( rect, m, r, rightBound, leftBound) # print area,leftBound,rightBound return area def getDistance(self, ingrname, center): distA = [] ingrpositions = [ self.env.molecules[i][0] for i in xrange(len(self.env.molecules)) if self.env.molecules[i][2].name == ingrname ] ingrpositions = numpy.array(ingrpositions) if len(ingrpositions): delta = numpy.array(ingrpositions) - numpy.array(center) delta *= delta distA = numpy.sqrt(delta.sum(1)) return ingrpositions, distA def getAxeValue(self, ingrname, axe=0): ingrpositions = [ self.env.molecules[i][0][axe] for i in xrange(len(self.env.molecules)) if self.env.molecules[i][2].name == ingrname ] return ingrpositions def getAxesValues(self, positions): pp = numpy.array(positions).transpose() px = pp[0] py = pp[1] pz = pp[2] return px, py, pz def getVolumeShell(self, bbox, radii, center): #rectangle_circle_area volumes = [] box_size0 = bbox[1][0] - bbox[0][0] for i in range(len(radii) - 1): r1 = radii[i] r2 = radii[i + 1] v1 = self.g.calc_volume(r1, box_size0 / 2.) v2 = self.g.calc_volume(r2, box_size0 / 2.) # if v1 == 0 or v2 == 0 : # volumes.append((4./3.)*numpy.pi*(numpy.power(r2,3)-numpy.power(r1, 3))) # else : volumes.append(v2 - v1) return volumes def rdf_3d(self, ingr): #see for intersection volume here http://crowsandcats.blogspot.com/2013/04/cube-sphere-intersection-volume.html #and here http://crowsandcats.blogspot.com/2013/05/extending-radial-distributions.html #will require scipy...worth it ? #should be pairewise distance ? or not ? distances = numpy.array(self.env.distances[ingr.name]) basename = self.env.basename numpy.savetxt(basename + ingr.name + "_pos.csv", numpy.array(self.env.ingrpositions[ingr.name]), delimiter=",") self.histo(distances, basename + ingr.name + "_histo.png") numpy.savetxt(basename + ingr.name + "_distances.csv", numpy.array(distances), delimiter=",") # the bin should be not less than the biggest ingredient radius #b=int(distances.max()/self.largest) b = 100 #bin_edges = numpy.arange(0, min(box_size) / 2, bin_width) new_rdf, edges = numpy.histogramdd(distances, bins=b, range=[(distances.min(), distances.max())]) radii = edges[0] #from http://isaacs.sourceforge.net/phys/rdfs.html dnr = new_rdf N = len(distances) V = self.env.grid.nbGridPoints[0] * self.env.grid.nbGridPoints[ 1] * self.env.grid.nbGridPoints[2] * self.env.grid.gridSpacing**3 density = 1 #len(x)/1000.0**2 # Vshell = (4./3.)*numpy.pi*(numpy.power(radii[1:],3)-numpy.power(radii[:-1], 3)) Vshell = numpy.array(self.getVolumeShell(self.bbox, radii, self.center)) gr = (dnr * V) / (N * Vshell) numpy.savetxt(basename + ingr.name + "_rdf.csv", numpy.array(gr), delimiter=",") self.plot(gr, radii[:-1], basename + ingr.name + "_rdf.png") def getAreaShell(self, bbox, radii, center): #rectangle_circle_area areas = [] for i in range(len(radii) - 1): r1 = radii[i] r2 = radii[i + 1] area1 = self.rectangle_circle_area(bbox, center, r1) area2 = self.rectangle_circle_area(bbox, center, r2) if area1 == 0 or area2 == 0: areas.append(numpy.pi * (numpy.power(r2, 2) - numpy.power(r1, 2))) else: areas.append(area2 - area1) return areas def rdf_2d(self, ingr): distances = numpy.array(self.env.distances[ingr.name]) basename = self.env.basename numpy.savetxt(basename + ingr.name + "_pos.csv", numpy.array(self.env.ingrpositions[ingr.name]), delimiter=",") self.histo(distances, basename + ingr.name + "_histo.png") numpy.savetxt(basename + ingr.name + "_distances.csv", numpy.array(distances), delimiter=",") # the bin should be not less than the biggest ingredient radius # b=int(distances.max()/self.largest) b = 100 new_rdf, edges = numpy.histogramdd( distances ) #, bins=b, range=[(distances.min(), distances.max())],normed=0) radii = edges[0] # r=radii.tolist() # r.insert(0,0.0) # radii = numpy.array(r) # rdf= new_rdf.tolist() # rdf.insert(0,0) # new_rdf = numpy.array(rdf) #from http://isaacs.sourceforge.net/phys/rdfs.html dnr = new_rdf[:] N = len(distances) V = self.env.grid.nbGridPoints[0] * self.env.grid.nbGridPoints[ 1] * self.env.grid.gridSpacing**2 density = 1 #len(x)/1000.0**2 Vshell = numpy.array(self.getAreaShell(self.bbox, radii, self.center)) # print Vshell # Vshell1 = numpy.pi*density*(numpy.power(radii[1:],2)-numpy.power(radii[:-1], 2)) # print Vshell1 # print radii gr = (dnr * V) / (N * Vshell) numpy.savetxt(basename + ingr.name + "_rdf.csv", numpy.array(gr), delimiter=",") self.plot(gr, radii[:-1], basename + ingr.name + "_rdf.png") #simpl approach Ni/Areai G = dnr / Vshell numpy.savetxt(basename + ingr.name + "_rdf_simple.csv", numpy.array(G), delimiter=",") self.plot(numpy.array(G), radii[:-1], basename + ingr.name + "_rdf_simple.png") print G def axis_distribution(self, ingr): basename = self.env.basename px, py, pz = self.getAxesValues(self.env.ingrpositions[ingr.name]) self.histo(px, basename + ingr.name + "_histo_X.png", bins=20) self.histo(py, basename + ingr.name + "_histo_Y.png", bins=20) self.histo(pz, basename + ingr.name + "_histo_Z.png", bins=20) def correlation(self, ingr): basename = self.env.basename posxyz = numpy.array(self.env.ingrpositions[ingr.name]).transpose() g_average, radii, x, y, z = self.PairCorrelationFunction_3D( posxyz, 1000, 900, 100) self.plot(g_average, radii, basename + ingr.name + "_corr.png") def PairCorrelationFunction_3D(self, data, S, rMax, dr): """Compute the three-dimensional pair correlation function for a set of spherical particles contained in a cube with side length S. This simple function finds reference particles such that a sphere of radius rMax drawn around the particle will fit entirely within the cube, eliminating the need to compensate for edge effects. If no such particles exist, an error is returned. Try a smaller rMax...or write some code to handle edge effects! ;) Arguments: x an array of x positions of centers of particles y an array of y positions of centers of particles z an array of z positions of centers of particles S length of each side of the cube in space rMax outer diameter of largest spherical shell dr increment for increasing radius of spherical shell Returns a tuple: (g, radii, interior_x, interior_y, interior_z) g(r) a numpy array containing the correlation function g(r) radii a numpy array containing the radii of the spherical shells used to compute g(r) interior_x x coordinates of reference particles interior_y y coordinates of reference particles interior_z z coordinates of reference particles """ from numpy import zeros, sqrt, where, pi, average, arange, histogram x = data[0] y = data[1] z = data[2] # Find particles which are close enough to the cube center that a sphere of radius # rMax will not cross any face of the cube bools1 = x > rMax bools2 = x < (S - rMax) bools3 = y > rMax bools4 = y < (S - rMax) bools5 = z > rMax bools6 = z < (S - rMax) interior_indices, = where(bools1 * bools2 * bools3 * bools4 * bools5 * bools6) num_interior_particles = len(interior_indices) if num_interior_particles < 1: raise RuntimeError( "No particles found for which a sphere of radius rMax\ will lie entirely within a cube of side length S. Decrease rMax\ or increase the size of the cube.") edges = arange(0., rMax + 1.1 * dr, dr) num_increments = len(edges) - 1 g = zeros([num_interior_particles, num_increments]) radii = zeros(num_increments) numberDensity = len(x) / S**3 # Compute pairwise correlation for each interior particle for p in range(num_interior_particles): index = interior_indices[p] d = sqrt((x[index] - x)**2 + (y[index] - y)**2 + (z[index] - z)**2) d[index] = 2 * rMax (result, bins) = histogram(d, bins=edges, normed=False) g[p, :] = result / numberDensity # Average g(r) for all interior particles and compute radii g_average = zeros(num_increments) for i in range(num_increments): radii[i] = (edges[i] + edges[i + 1]) / 2. rOuter = edges[i + 1] rInner = edges[i] g_average[i] = average(g[:, i]) / (4. / 3. * pi * (rOuter**3 - rInner**3)) return (g_average, radii, x[interior_indices], y[interior_indices], z[interior_indices]) # Number of particles in shell/total number of particles/volume of shell/number density # shell volume = 4/3*pi(r_outer**3-r_inner**3) def histo(self, distances, filename, bins=100): pylab.clf() mu, sigma = numpy.mean(distances), numpy.std(distances) ## the histogram of the data b = numpy.arange(distances.min(), distances.max(), 2) n, bins, patches = pyplot.hist(distances, bins=bins, normed=0, facecolor='green') #, alpha=0.75) # add a 'best fit' line? y = mlab.normpdf(bins, mu, sigma) #should be the excepted distribution l = pyplot.plot(bins, y, 'r--', linewidth=1) pyplot.savefig(filename) pylab.close() # closes the current figure def plot(self, rdf, radii, filname): pylab.clf() matplotlib.rc('font', size=14) matplotlib.rc('figure', figsize=(5, 4)) # pylab.clf() pylab.plot(radii, rdf, linewidth=3) pylab.xlabel(r"distance $r$ in $\AA$") pylab.ylabel(r"radial distribution function $g(r)$") pylab.savefig(filname) pylab.close() # closes the current figure def grid_pack(self, bb, wrkDir, forceBuild=True, fill=0, seed=20, vTestid=3, vAnalysis=0): t1 = time() # if bbox is None : # box=self.helper.getCurrentSelection()[0] # else : # box = bbox[0] # bb=self.helper.getCornerPointCube(box) gridFileIn = None gridFileOut = None # if forceBuild : # gridFileOut=wrkDir+os.sep+"fill_grid" # else : # gridFileIn=wrkDir+os.sep+"fill_grid" print(gridFileIn, gridFileOut) self.env.buildGrid(boundingBox=bb, gridFileIn=gridFileIn, rebuild=forceBuild, gridFileOut=gridFileOut, previousFill=False) # h.buildGrid(gridFileIn=gridFileIn, # gridFileOut=gridFileOut) t2 = time() gridTime = t2 - t1 if fill: self.pack(seed=seed, vTestid=vTestid, vAnalysis=vAnalysis) print('time to Build Grid', gridTime) # afviewer.displayOrganellesPoints() #return #actine.updateFromBB(h.grid) def pack(self, seed=20, forceBuild=True, vTestid=3, vAnalysis=0): t1 = time() print "seed is ", seed self.env.fill5(seedNum=seed, verbose=4, vTestid=vTestid, vAnalysis=vAnalysis) t2 = time() print('time to run Fill5', t2 - t1) def calcDistanceMatrixFastEuclidean2(self, nDimPoints): nDimPoints = numpy.array(nDimPoints) n, m = nDimPoints.shape delta = numpy.zeros((n, n), 'd') for d in xrange(m): data = nDimPoints[:, d] delta += (data - data[:, numpy.newaxis])**2 return numpy.sqrt(delta) def doloop(self, n, bbox, wrkDir, output, rdf=True, render=False, plot=True, twod=True): # doLoop automatically produces result files, images, and documents from the recipe while adjusting parameters # To run doLoop, 1) in your host's python console type: # execfile(pathothis recipe) # for example, on my computer: # " execfile("/Users/grahamold/Dev/autoFillSVN/autofillSVNversions/trunk/AutoFillClean/autoFillRecipeScripts/2DsphereFill/2DSpheres_setup_recipe.py") # 2) prepare your scene for the rendering->render output should be 640,480 but you can change the size in the script at then end. Set up textures lights, and effects as you wish # Results will appear in the result folder of your recipe path # where n is the number of loop, seed = i #analyse.doloop(n) rangeseed = range(n) distances = {} ingrpositions = {} self.bbox = bbox rebuild = True for i in rangeseed: if i > 0: rebuild = False basename = output + os.sep + "results_seed_" + str(i) # self.env.saveResult = False resultfilename = self.env.resultfile = basename #Clear if self.afviewer: self.afviewer.clearFill("Test_Spheres2D") else: self.env.reset() #no need to rebuild the grid ? self.env.saveResult = True self.env.resultfile = basename self.grid_pack(bbox, output, seed=i, fill=1, vTestid=i, vAnalysis=1, forceBuild=rebuild) #build grid and fill #store the result # self.env.store_asJson(resultfilename=basename) self.center = self.env.grid.getCenter() if render: #render/save scene if hosted otherwise nothing self.helper.render(basename + ".jpg", 640, 480) self.helper.write(basename + ".c4d", []) if rdf: if plot and twod: width = 1000.0 fig = pyplot.figure() ax = fig.add_subplot(111) center = self.env.grid.getCenter( ) #[500,500,0.5]#center of the grid r = self.env.exteriorRecipe d = {} if r: for ingr in r.ingredients: if ingr.name not in distances: distances[ingr.name] = [] ingrpositions[ingr.name] = [] if ingr.packingMode == 'gradient' and self.env.use_gradient: self.center = center = self.env.gradients[ ingr.gradient].direction ingrpos, d = self.getDistance(ingr.name, center) distances[ingr.name].extend(d) ingrpositions[ingr.name].extend(ingrpos) #print plot,twod if plot and twod: for i, p in enumerate(ingrpos): ax.add_patch( Circle((p[0], p[1]), ingr.minRadius, edgecolor="black", facecolor=ingr.color)) if i == 0: #len(ingrpos)-1: continue if ingr.Type == "Grow": pyplot.plot( [ingrpos[-i][0], ingrpos[-i - 1][0]], [ingrpos[-i][1], ingrpos[-i - 1][1]], 'k-', lw=2) #plot the sphere if ingr.use_rbsphere: r, pts = ingr.getInterpolatedSphere( ingrpos[-i - 1], ingrpos[-i]) for pt in pts: ax.add_patch( Circle((pt[0], pt[1]), ingr.minRadius, edgecolor="black", facecolor=ingr.color)) for o in self.env.compartments: rs = o.surfaceRecipe if rs: for ingr in rs.ingredients: if ingr.name not in distances: distances[ingr.name] = [] ingrpositions[ingr.name] = [] if ingr.packingMode == 'gradient' and self.env.use_gradient: center = self.env.gradients[ ingr.gradient].direction ingrpos, d = self.getDistance(ingr.name, center) distances[ingr.name].extend(d) ingrpositions[ingr.name].extend(ingrpos) if plot and twod: for p in ingrpos: ax.add_patch( Circle((p[0], p[1]), ingr.minRadius, edgecolor="black", facecolor=ingr.color)) ri = o.innerRecipe if ri: for ingr in ri.ingredients: if ingr.name not in distances: distances[ingr.name] = [] ingrpositions[ingr.name] = [] if ingr.packingMode == 'gradient' and self.env.use_gradient: center = self.env.gradients[ ingr.gradient].direction ingrpos, d = self.getDistance(ingr.name, center) distances[ingr.name].extend(d) ingrpositions[ingr.name].extend(ingrpos) if plot and twod: for p in ingrpos: ax.add_patch( Circle((p[0], p[1]), ingr.minRadius, edgecolor="black", facecolor=ingr.color)) if plot and twod: ax.set_aspect(1.0) pyplot.axhline(y=0, color='k') pyplot.axhline(y=width, color='k') pyplot.axvline(x=0, color='k') pyplot.axvline(x=width, color='k') pyplot.axis( [-0.1 * width, width * 1.1, -0.1 * width, width * 1.1]) pyplot.savefig(basename + ".png") pylab.close() # closes the current figure #plot(x) self.env.ingrpositions = ingrpositions self.env.distances = distances self.env.basename = basename if rdf: if twod: self.env.loopThroughIngr(self.rdf_2d) else: self.env.loopThroughIngr(self.rdf_3d) # do the X Y histo averge ! self.env.loopThroughIngr(self.axis_distribution) # self.env.loopThroughIngr(self.correlation) return distances
class AnalyseAP: def __init__(self, env=None, viewer=None, result_file=None): self.env=None self.smallest=99999.0 self.largest = 0.0 if env : self.env = env self.smallest,self.largest = self.getMinMaxProteinSize() self.afviewer = viewer self.helper = None if viewer : self.helper = self.afviewer.vi self.resutl_file = result_file self.center=[0,0,0] self.bbox=[[0,0,0],[1,1,1]] self.g=GeometriTools() self.g.Resolution = 1.0#or grid step? def getMinMaxProteinSize(self): smallest=999999.0 largest= 0.0 for organelle in self.env.compartments: mini, maxi = organelle.getMinMaxProteinSize() if mini < smallest: smallest = mini if maxi > largest: largest = maxi if self.env.exteriorRecipe: mini, maxi = self.env.exteriorRecipe.getMinMaxProteinSize() if mini < smallest: smallest = mini if maxi > largest: largest = maxi return smallest,largest def getPositionsFromResFile(self,): #could actually restore file using histoVol. #or not #need to parse apr file here anyway return [] def getPositionsFromObject(self,parents): positions=[] for parent in parents: obparent = self.helper.getObject(parent) childs = self.helper.getChilds(obparent) for ch in childs: ingr_name = self.helper.getName(ch) meshp = self.helper.getObject("Meshs_"+ingr_name.split("_")[0]) if meshp is None : c = self.helper.getChilds(ch) if not len(c) : continue meshpchilds = self.helper.getChilds(c[0])#continue #should get sphere/cylnder parent ? else : meshpchilds = self.helper.getChilds(meshp) for cc in meshpchilds: pos = self.helper.ToVec(self.helper.getTranslation(cc)) positions.append(pos) return positions def getDistanceFrom(self,target,parents=None,**options): """ target : name or host object target or target position parent : name of host parent object for the list of object to measre distance from objects : list of object or list of points """ #get distance from object to the target. #all object are in h.molecules and orga.molecules #get options targetPos = [0,0,0] usePoint = False threshold = 99999. if "usePoint" in options: usePoint = options["usePoint"] if "threshold" in options: threshold = options["threshold"] if type(target) == list or type(target) == tuple: targetPos = target elif type(target) == unicode or type(target) == str : o = self.helper.getObject(target) if o is not None : targetPos = self.helper.ToVec(self.helper.getTranslation(o)) #hostForm else : o = self.helper.getObject(target) if o is not None : targetPos = self.helper.ToVec(self.helper.getTranslation(o)) #hostForm listeObjs=[] listeDistances = [] listeCenters =[] if self.resutl_file is None : if parents is None and self.resutl_file is None: listeParent = [self.env.name+"_cytoplasm"] for o in self.env.compartments : listeParent.append(o.name+"_Matrix") listeParent.append(o.name+"_surface") elif parents is not None and self.resutl_file is None: listeParent = parents listeCenters =self.getPositionsFromObject(listeParent) else : #use data from file listeCenters =self.getPositionsFromResFile(listeParent) delta = numpy.array(listeCenters)-numpy.array(targetPos) delta *= delta distA = numpy.sqrt( delta.sum(1) ) return distA def getClosestDistance(self,parents=None,**options): if self.resutl_file is None : if parents is None and self.resutl_file is None: listeParent = [self.env.name+"_cytoplasm"] for o in self.env.compartments : listeParent.append(o.name+"_Matrix") listeParent.append(o.name+"_surface") elif parents is not None and self.resutl_file is None: listeParent = parents listeCenters =self.getPositionsFromObject(listeParent) else : #use data from file listeCenters =self.getPositionsFromResFile(listeParent) #is the distance in the result array ? listeDistance=numpy.zeros(len(listeCenters))+99999 for i in range(len(listeCenters) ): for j in range(i+1,len(listeCenters)): #should use point d = self.helper.measure_distance(listeCenters[i],listeCenters[j]) if d < listeDistance[i] : listeDistance[i] = d return listeDistance def displayDistance(self,ramp_color1=[1,0,0],ramp_color2=[0,0,1], ramp_color3=None,cutoff=60.0): distances = self.env.grid.distToClosestSurf[:] positions = self.env.grid.masterGridPositions[:] #map the color as well ? from upy import colors as col from DejaVu.colorTool import Map ramp = col.getRamp([[1,0,0],[0,0,1]],size=255) #color mask = distances > cutoff ind=numpy.nonzero(mask)[0] distances[ind]=cutoff mask = distances < -cutoff ind=numpy.nonzero(mask)[0] distances[ind]=cutoff colors = Map(distances, ramp) # sphs = self.helper.Spheres("distances",vertices=numpy.array(positions),radii=distances,colors=colors) base=self.helper.getObject(self.env.name+"distances_base") if base is None : base=self.helper.Sphere(self.env.name+"distances_base")[0] p=self.helper.getObject(self.env.name+"distances") if p is not None : self.helper.deleteObject(p)#recursif? p = self.helper.newEmpty(self.env.name+"distances") sphs=self.helper.instancesSphere(self.env.name+"distances",positions,distances,base,colors,None,parent=self.env.name+"distances") def loadJSON(self,filename): import json with open(filename) as data_file: data = json.load(data_file) #should take any type of list... def save_csv(self,data,filename=None): if filename is None : filename = "output.csv" resultFile = open(filename,'wb') wr = csv.writer(resultFile, dialect='excel') #wr.writerows(data) list of list ? #resultFile.close() for item in data: wr.writerow([item,]) resultFile.close() def rectangle_circle_area(self,bbox,center,radius): #http://www.eex-dev.net/index.php?id=100 #[[0.,0,0],[1000,1000,1]] rect=Rectangle(bbox[0][0],bbox[1][0],bbox[0][1],bbox[1][1])#top,bottom, right, left # rect=Rectangle(bbox[1][1],bbox[0][1],bbox[1][0],bbox[0][0])#top,bottom, right, left m=[center[0],center[1]] r=radius area = 0.0 chs = self.g.check_sphere_inside(rect,m,r) if chs : # print "sphere go outside ",r ch=self.g.check_rectangle_oustide(rect,m,r) if ch : leftBound,rightBound = self.g.getBoundary(rect,m,r) area = self.g.get_rectangle_cercle_area(rect,m,r,rightBound,leftBound) # print area,leftBound,rightBound return area def getDistance(self,ingrname, center): distA=[] ingrpositions=[self.env.molecules[i][0] for i in xrange(len(self.env.molecules)) if self.env.molecules[i][2].name == ingrname] ingrpositions=numpy.array(ingrpositions) if len(ingrpositions) : delta = numpy.array(ingrpositions)-numpy.array(center) delta *= delta distA = numpy.sqrt( delta.sum(1) ) return ingrpositions,distA def getAxeValue(self,ingrname,axe=0): ingrpositions=[self.env.molecules[i][0][axe] for i in xrange(len(self.env.molecules)) if self.env.molecules[i][2].name == ingrname] return ingrpositions def getAxesValues(self,positions): pp = numpy.array(positions).transpose() px=pp[0] py=pp[1] pz=pp[2] return px,py,pz def getVolumeShell(self,bbox,radii,center): #rectangle_circle_area volumes=[] box_size0 = bbox[1][0] - bbox[0][0] for i in range(len(radii)-1): r1=radii[i] r2=radii[i+1] v1 = self.g.calc_volume(r1, box_size0 / 2.) v2 = self.g.calc_volume(r2, box_size0 / 2.) # if v1 == 0 or v2 == 0 : # volumes.append((4./3.)*numpy.pi*(numpy.power(r2,3)-numpy.power(r1, 3))) # else : volumes.append(v2-v1) return volumes def rdf_3d(self,ingr): #see for intersection volume here http://crowsandcats.blogspot.com/2013/04/cube-sphere-intersection-volume.html #and here http://crowsandcats.blogspot.com/2013/05/extending-radial-distributions.html #will require scipy...worth it ? #should be pairewise distance ? or not ? distances = numpy.array(self.env.distances[ingr.name]) basename = self.env.basename numpy.savetxt(basename+ingr.name+"_pos.csv", numpy.array(self.env.ingrpositions[ingr.name]), delimiter=",") self.histo(distances,basename+ingr.name+"_histo.png") numpy.savetxt(basename+ingr.name+"_distances.csv", numpy.array(distances), delimiter=",") # the bin should be not less than the biggest ingredient radius #b=int(distances.max()/self.largest) b=100 #bin_edges = numpy.arange(0, min(box_size) / 2, bin_width) new_rdf, edges = numpy.histogramdd(distances, bins=b, range=[(distances.min(), distances.max())]) radii = edges[0] #from http://isaacs.sourceforge.net/phys/rdfs.html dnr=new_rdf N=len(distances) V=self.env.grid.nbGridPoints[0]*self.env.grid.nbGridPoints[1]*self.env.grid.nbGridPoints[2]*self.env.grid.gridSpacing**3 density = 1#len(x)/1000.0**2 # Vshell = (4./3.)*numpy.pi*(numpy.power(radii[1:],3)-numpy.power(radii[:-1], 3)) Vshell = numpy.array(self.getVolumeShell(self.bbox,radii,self.center)) gr = (dnr*V)/(N*Vshell) numpy.savetxt(basename+ingr.name+"_rdf.csv", numpy.array(gr), delimiter=",") self.plot(gr,radii[:-1],basename+ingr.name+"_rdf.png") def getAreaShell(self,bbox,radii,center): #rectangle_circle_area areas=[] for i in range(len(radii)-1): r1=radii[i] r2=radii[i+1] area1=self.rectangle_circle_area(bbox,center,r1) area2=self.rectangle_circle_area(bbox,center,r2) if area1 == 0 or area2 == 0 : areas.append(numpy.pi*(numpy.power(r2,2)-numpy.power(r1, 2))) else : areas.append(area2-area1) return areas def rdf_2d(self,ingr): distances = numpy.array(self.env.distances[ingr.name]) basename = self.env.basename numpy.savetxt(basename+ingr.name+"_pos.csv", numpy.array(self.env.ingrpositions[ingr.name]), delimiter=",") self.histo(distances,basename+ingr.name+"_histo.png") numpy.savetxt(basename+ingr.name+"_distances.csv", numpy.array(distances), delimiter=",") # the bin should be not less than the biggest ingredient radius # b=int(distances.max()/self.largest) b=100 new_rdf, edges = numpy.histogramdd(distances)#, bins=b, range=[(distances.min(), distances.max())],normed=0) radii = edges[0] # r=radii.tolist() # r.insert(0,0.0) # radii = numpy.array(r) # rdf= new_rdf.tolist() # rdf.insert(0,0) # new_rdf = numpy.array(rdf) #from http://isaacs.sourceforge.net/phys/rdfs.html dnr=new_rdf[:] N=len(distances) V=self.env.grid.nbGridPoints[0]*self.env.grid.nbGridPoints[1]*self.env.grid.gridSpacing**2 density = 1#len(x)/1000.0**2 Vshell = numpy.array(self.getAreaShell(self.bbox,radii,self.center)) # print Vshell # Vshell1 = numpy.pi*density*(numpy.power(radii[1:],2)-numpy.power(radii[:-1], 2)) # print Vshell1 # print radii gr = (dnr*V)/(N*Vshell) numpy.savetxt(basename+ingr.name+"_rdf.csv", numpy.array(gr), delimiter=",") self.plot(gr,radii[:-1],basename+ingr.name+"_rdf.png") #simpl approach Ni/Areai G=dnr/Vshell numpy.savetxt(basename+ingr.name+"_rdf_simple.csv", numpy.array(G), delimiter=",") self.plot(numpy.array(G),radii[:-1],basename+ingr.name+"_rdf_simple.png") print G def axis_distribution(self,ingr): basename = self.env.basename px,py,pz = self.getAxesValues(self.env.ingrpositions[ingr.name]) self.histo(px,basename+ingr.name+"_histo_X.png",bins=20) self.histo(py,basename+ingr.name+"_histo_Y.png",bins=20) self.histo(pz,basename+ingr.name+"_histo_Z.png",bins=20) def correlation(self,ingr): basename = self.env.basename posxyz = numpy.array(self.env.ingrpositions[ingr.name]).transpose() g_average, radii, x,y,z=self.PairCorrelationFunction_3D(posxyz,1000,900,100) self.plot(g_average,radii,basename+ingr.name+"_corr.png") def PairCorrelationFunction_3D(self,data,S,rMax,dr): """Compute the three-dimensional pair correlation function for a set of spherical particles contained in a cube with side length S. This simple function finds reference particles such that a sphere of radius rMax drawn around the particle will fit entirely within the cube, eliminating the need to compensate for edge effects. If no such particles exist, an error is returned. Try a smaller rMax...or write some code to handle edge effects! ;) Arguments: x an array of x positions of centers of particles y an array of y positions of centers of particles z an array of z positions of centers of particles S length of each side of the cube in space rMax outer diameter of largest spherical shell dr increment for increasing radius of spherical shell Returns a tuple: (g, radii, interior_x, interior_y, interior_z) g(r) a numpy array containing the correlation function g(r) radii a numpy array containing the radii of the spherical shells used to compute g(r) interior_x x coordinates of reference particles interior_y y coordinates of reference particles interior_z z coordinates of reference particles """ from numpy import zeros, sqrt, where, pi, average, arange, histogram x=data[0] y=data[1] z=data[2] # Find particles which are close enough to the cube center that a sphere of radius # rMax will not cross any face of the cube bools1 = x>rMax bools2 = x<(S-rMax) bools3 = y>rMax bools4 = y<(S-rMax) bools5 = z>rMax bools6 = z<(S-rMax) interior_indices, = where(bools1*bools2*bools3*bools4*bools5*bools6) num_interior_particles = len(interior_indices) if num_interior_particles < 1: raise RuntimeError ("No particles found for which a sphere of radius rMax\ will lie entirely within a cube of side length S. Decrease rMax\ or increase the size of the cube.") edges = arange(0., rMax+1.1*dr, dr) num_increments = len(edges)-1 g = zeros([num_interior_particles, num_increments]) radii = zeros(num_increments) numberDensity = len(x)/S**3 # Compute pairwise correlation for each interior particle for p in range(num_interior_particles): index = interior_indices[p] d = sqrt((x[index]-x)**2 + (y[index]-y)**2 + (z[index]-z)**2) d[index] = 2*rMax (result,bins) = histogram(d, bins=edges, normed=False) g[p,:] = result/numberDensity # Average g(r) for all interior particles and compute radii g_average = zeros(num_increments) for i in range(num_increments): radii[i] = (edges[i] + edges[i+1])/2. rOuter = edges[i+1] rInner = edges[i] g_average[i] = average(g[:,i])/(4./3.*pi*(rOuter**3 - rInner**3)) return (g_average, radii, x[interior_indices], y[interior_indices], z[interior_indices]) # Number of particles in shell/total number of particles/volume of shell/number density # shell volume = 4/3*pi(r_outer**3-r_inner**3) def histo(self,distances,filename,bins=100): pylab.clf() mu, sigma = numpy.mean(distances) , numpy.std(distances) ## the histogram of the data b=numpy.arange(distances.min(), distances.max(), 2) n, bins, patches = pyplot.hist(distances, bins=bins, normed=0, facecolor='green')#, alpha=0.75) # add a 'best fit' line? y = mlab.normpdf( bins, mu, sigma)#should be the excepted distribution l = pyplot.plot(bins, y, 'r--', linewidth=1) pyplot.savefig(filename) pylab.close() # closes the current figure def plot(self,rdf,radii,filname): pylab.clf() matplotlib.rc('font', size=14) matplotlib.rc('figure', figsize=(5, 4)) # pylab.clf() pylab.plot(radii, rdf, linewidth=3) pylab.xlabel(r"distance $r$ in $\AA$") pylab.ylabel(r"radial distribution function $g(r)$") pylab.savefig(filname) pylab.close() # closes the current figure def grid_pack(self,bb,wrkDir,forceBuild=True, fill=0,seed=20,vTestid = 3,vAnalysis = 0): t1 = time() # if bbox is None : # box=self.helper.getCurrentSelection()[0] # else : # box = bbox[0] # bb=self.helper.getCornerPointCube(box) gridFileIn=None gridFileOut=None # if forceBuild : # gridFileOut=wrkDir+os.sep+"fill_grid" # else : # gridFileIn=wrkDir+os.sep+"fill_grid" print (gridFileIn,gridFileOut) self.env.buildGrid(boundingBox=bb,gridFileIn=gridFileIn,rebuild=forceBuild , gridFileOut=gridFileOut,previousFill=False) # h.buildGrid(gridFileIn=gridFileIn, # gridFileOut=gridFileOut) t2 = time() gridTime = t2-t1 if fill : self.pack(seed=seed,vTestid = vTestid,vAnalysis = vAnalysis) print ('time to Build Grid', gridTime) # afviewer.displayOrganellesPoints() #return #actine.updateFromBB(h.grid) def pack(self,seed=20,forceBuild=True,vTestid = 3,vAnalysis = 0): t1 = time() print "seed is ",seed self.env.fill5(seedNum=seed,verbose=4, vTestid = vTestid,vAnalysis = vAnalysis) t2 = time() print('time to run Fill5', t2-t1) def calcDistanceMatrixFastEuclidean2(self,nDimPoints): nDimPoints = numpy.array(nDimPoints) n,m = nDimPoints.shape delta = numpy.zeros((n,n),'d') for d in xrange(m): data = nDimPoints[:,d] delta += (data - data[:,numpy.newaxis])**2 return numpy.sqrt(delta) def doloop(self,n,bbox,wrkDir,output,rdf=True, render=False, plot = True,twod=True): # doLoop automatically produces result files, images, and documents from the recipe while adjusting parameters # To run doLoop, 1) in your host's python console type: # execfile(pathothis recipe) # for example, on my computer: # " execfile("/Users/grahamold/Dev/autoFillSVN/autofillSVNversions/trunk/AutoFillClean/autoFillRecipeScripts/2DsphereFill/2DSpheres_setup_recipe.py") # 2) prepare your scene for the rendering->render output should be 640,480 but you can change the size in the script at then end. Set up textures lights, and effects as you wish # Results will appear in the result folder of your recipe path # where n is the number of loop, seed = i #analyse.doloop(n) rangeseed=range(n) distances={} ingrpositions={} self.bbox = bbox rebuild = True for i in rangeseed: if i > 0 : rebuild = False basename = output+os.sep+"results_seed_"+str(i) # self.env.saveResult = False resultfilename = self.env.resultfile = basename #Clear if self.afviewer : self.afviewer.clearFill("Test_Spheres2D") else : self.env.reset() #no need to rebuild the grid ? self.env.saveResult = True self.env.resultfile = basename self.grid_pack(bbox,output,seed=i, fill=1,vTestid = i,vAnalysis = 1,forceBuild=rebuild)#build grid and fill #store the result # self.env.store_asJson(resultfilename=basename) self.center = self.env.grid.getCenter() if render : #render/save scene if hosted otherwise nothing self.helper.render(basename+".jpg",640,480) self.helper.write(basename+".c4d",[]) if rdf : if plot and twod: width = 1000.0 fig = pyplot.figure() ax = fig.add_subplot(111) center = self.env.grid.getCenter()#[500,500,0.5]#center of the grid r = self.env.exteriorRecipe d={} if r : for ingr in r.ingredients: if ingr.name not in distances : distances[ingr.name]=[] ingrpositions[ingr.name]=[] if ingr.packingMode=='gradient' and self.env.use_gradient: self.center = center = self.env.gradients[ingr.gradient].direction ingrpos,d=self.getDistance(ingr.name, center) distances[ingr.name].extend(d) ingrpositions[ingr.name].extend(ingrpos) #print plot,twod if plot and twod: for i,p in enumerate(ingrpos): ax.add_patch(Circle((p[0], p[1]), ingr.minRadius, edgecolor="black", facecolor=ingr.color)) if i == 0:#len(ingrpos)-1: continue if ingr.Type== "Grow": pyplot.plot([ingrpos[-i][0], ingrpos[-i-1][0]], [ingrpos[-i][1], ingrpos[-i-1][1]], 'k-', lw=2) #plot the sphere if ingr.use_rbsphere : r,pts = ingr.getInterpolatedSphere(ingrpos[-i-1],ingrpos[-i]) for pt in pts : ax.add_patch(Circle((pt[0], pt[1]), ingr.minRadius, edgecolor="black", facecolor=ingr.color)) for o in self.env.compartments: rs = o.surfaceRecipe if rs : for ingr in rs.ingredients: if ingr.name not in distances : distances[ingr.name]=[] ingrpositions[ingr.name]=[] if ingr.packingMode=='gradient' and self.env.use_gradient : center = self.env.gradients[ingr.gradient].direction ingrpos,d=self.getDistance(ingr.name, center) distances[ingr.name].extend(d) ingrpositions[ingr.name].extend(ingrpos) if plot and twod: for p in ingrpos: ax.add_patch(Circle((p[0], p[1]), ingr.minRadius, edgecolor="black", facecolor=ingr.color)) ri = o.innerRecipe if ri : for ingr in ri.ingredients: if ingr.name not in distances : distances[ingr.name]=[] ingrpositions[ingr.name]=[] if ingr.packingMode=='gradient' and self.env.use_gradient: center = self.env.gradients[ingr.gradient].direction ingrpos,d=self.getDistance(ingr.name, center) distances[ingr.name].extend(d) ingrpositions[ingr.name].extend(ingrpos) if plot and twod: for p in ingrpos: ax.add_patch(Circle((p[0], p[1]), ingr.minRadius, edgecolor="black", facecolor=ingr.color)) if plot and twod: ax.set_aspect(1.0) pyplot.axhline(y=0, color='k') pyplot.axhline(y=width, color='k') pyplot.axvline(x=0, color='k') pyplot.axvline(x=width, color='k') pyplot.axis([-0.1*width, width*1.1, -0.1*width, width*1.1]) pyplot.savefig(basename+".png") pylab.close() # closes the current figure #plot(x) self.env.ingrpositions=ingrpositions self.env.distances = distances self.env.basename = basename if rdf : if twod : self.env.loopThroughIngr(self.rdf_2d) else : self.env.loopThroughIngr(self.rdf_3d) # do the X Y histo averge ! self.env.loopThroughIngr(self.axis_distribution) # self.env.loopThroughIngr(self.correlation) return distances