def printFormMatrix(cell): faces = qd.CellFaceIterator(cell) face = faces.next() while face != None: faceid = face.getID() print " ========================================================================================" print faceid print "MU ", [ face.getMu1(), face.getMu2(), face.getMu3(), face.getMu4() ] print "CF ", [ qd.getCurrentFormMatrix(face, 0, 0), (qd.getCurrentFormMatrix(face, 0, 1)), qd.getCurrentFormMatrix(face, 1, 0), (qd.getCurrentFormMatrix(face, 1, 1)) ] print "TF ", [ qd.getTargetFormMatrix(face, 0, 0), (qd.getTargetFormMatrix(face, 0, 1)), qd.getTargetFormMatrix(face, 1, 0), (qd.getTargetFormMatrix(face, 1, 1)) ] face = faces.next() return
def getFormMatrix(cell, targetfaceid): faces = qd.CellFaceIterator(cell) face = faces.next() while face != None: faceid = face.getID() if faceid != targetfaceid: face = faces.next() continue targetForm = np.array([[ qd.getTargetFormMatrix(face, 0, 0), qd.getTargetFormMatrix(face, 0, 1) ], [ qd.getTargetFormMatrix(face, 1, 0), qd.getTargetFormMatrix(face, 1, 1) ]]) currentForm = np.array([[ qd.getCurrentFormMatrix(face, 0, 0), qd.getCurrentFormMatrix(face, 0, 1) ], [ qd.getCurrentFormMatrix(face, 1, 0), qd.getCurrentFormMatrix(face, 1, 1) ]]) break return targetForm, currentForm
def printareaofface(): global cell faces = qd.CellFaceIterator(cell) face = faces.next() while face != None: print "Face ID : ", face.getID(), "Area : ", face.getAreaOfFace() face = faces.next()
def getMatrixDifferenceEllipsePoints(cell,targetface, diffmatrix,primordialfaceid = 135,zoomfactor=1.): #getting the Target Form Matrix faces = qd.CellFaceIterator(cell) face = faces.next() while True: if face.getID() == targetface: break face = faces.next() #print "Face Id : ", face.getID() targetformmatrix = diffmatrix unitx = face.getUnitx() unity = face.getUnity() unitz = face.getUnitz() unit_mat = np.matrix([[qd.doublearray_getitem(unitx,0),qd.doublearray_getitem(unitx,1),qd.doublearray_getitem(unitx,2)], [qd.doublearray_getitem(unity,0),qd.doublearray_getitem(unity,1),qd.doublearray_getitem(unity,2)], [qd.doublearray_getitem(unitz,0),qd.doublearray_getitem(unitz,1),qd.doublearray_getitem(unitz,2)]]) #transposing unitmatrix transpose_unitmat = np.matrix(np.transpose(unit_mat)) #Getting Centroid of face xcent = face.getXCentralised() ycent = face.getYCentralised() zcent = face.getZCentralised() ##### getting data from ellipse & getting transformed coordinate to 3d Cartesian data = ep.plot_ellipse(cov=targetformmatrix, data_out=True,norm = True) points = zoomfactor*np.matrix(np.vstack((data,np.zeros(len(data[0]))))) transformedpoints = transpose_unitmat*points transformedpoints[0]+= xcent transformedpoints[1]+= ycent transformedpoints[2]+= zcent return transformedpoints
def getFaceAreaData(cell,faceidarray): cell.setParameters() facearea = 0. tfmDet = 0. ###################################### slowfacearea = 0. fastfacearea = 0. ###################################### faces = qd.CellFaceIterator(cell) face = faces.next() numfaces = 0. fastnum = 0. while face != None: if face.getID() == 1 : face = faces.next() continue tfmDet += face.getTargetFormMatrixDeterminant() #print face.getID(), area0 facearea+= face.getAreaOfFace() if np.isnan(face.getAreaOfFace()): print "Step :", i, "face ID : ", face.getID() ################################################### # Saving in slow and fast array ################################################### if face.getID() in faceidarray: fastfacearea += face.getAreaOfFace() fastnum += 1 else: slowfacearea += face.getAreaOfFace() numfaces += 1. face = faces.next() return tfmDet,slowfacearea,fastfacearea,fastfacearea
def plotMeanTargetArea(cell, meandeterminantarray, timearray): faces = qd.CellFaceIterator(cell) face = faces.next() sumtargetdeterminant = 0. numofface = 0. while face != None: if face.getID() == 1: face = faces.next() continue sumtargetdeterminant += face.getTargetFormMatrixDeterminant() numofface += 1. face = faces.next() meandeterminant = sumtargetdeterminant / numofface meandeterminantarray.append(meandeterminant) ###now plotting plt.figure(10) plt.title("Mean determinant of Target Form Matrix ") plt.ylabel("Mean determinant") plt.xlabel("time") plt.plot(timearray, meandeterminantarray, '-x') plt.savefig('mean_target_form_determinant.png', transparent=True) plt.clf() plt.close() ############### return meandeterminantarray
def plotMatrices(cell, targetfaceid,matrixarray,growthtimearray, stepgrowtharray): #getting the matrix array mudeterminant = matrixarray[0] currentFormdeterminant = matrixarray[1] targetFormdeterminant = matrixarray[2] #calculating the matrices faces = qd.CellFaceIterator(cell) face = faces.next() while face!=None: faceid = face.getID() if faceid != targetfaceid: face= faces.next() continue mudeterminant.append((face.getMu1()*face.getMu4()-face.getMu2()*face.getMu3())) currentFormdeterminant.append((qd.getCurrentFormMatrix(face,0,0)*(qd.getCurrentFormMatrix(face,1,1))-qd.getCurrentFormMatrix(face,1,0)*(qd.getCurrentFormMatrix(face,0,1)))) targetFormdeterminant.append((qd.getTargetFormMatrix(face,0,0)*(qd.getTargetFormMatrix(face,1,1))-qd.getTargetFormMatrix(face,1,0)*(qd.getTargetFormMatrix(face,0,1)))) break #face = faces.next() #starting the plot plt.figure(21) plt.title("Determinant of Matrices for Face : %d"%targetfaceid) plt.plot(growthtimearray, mudeterminant,'-s',color='k', label="Mu") plt.plot(growthtimearray, currentFormdeterminant,'-*',color='m', label="CF") plt.plot(growthtimearray, targetFormdeterminant,'-1', color='b',label="TF") #making verticle lines for growthsteps for vline in stepgrowtharray: plt.axvline(x=vline, c = 'r') plt.legend(loc='best') plt.savefig('matrix_plot_faceid_%d.png'%targetfaceid,transparent=True) plt.clf() plt.close('all') ###### return [mudeterminant,currentFormdeterminant,targetFormdeterminant]
def loadCellFromFile(step,numOfLayer = 8,eta = 1.,kappa = 0.2,fastkappa = 2.0, targetid = 135): #################################### loadedcell = qd.objReadCell("qdObject_step=%03d.obj"%step) loadedcell.setInitialParameters() # Flipping the Face ID after Loading to cell so that the face id before and after matches faces = qd.CellFaceIterator(loadedcell) facecount = loadedcell.countFaces() face= faces.next() while face != None: faceid = face.getID() face.setID(facecount-faceid+1) #print face.getID() face = faces.next() ###################################################### #print "######################################################" #print "#"," "*10, "step %d"%step #print "######################################################" #settig target Form Matrix : #TMF step corresponds to coordinate step #### sf.setTargetFormMatrix(loadedcell,step) #### CELL PARAMETERS #### loadedcell.setKappa(kappa) loadedcell.setEta(eta) #setTargetFormMatrix(loadedcell,step) loadedcell.setParameters() #calculating forces, stress-matrix and strain-matrix loadedcell.calculateStressStrain() loadedcell = fastGrowth(loadedcell,targetid,fastkappa = fastkappa) ###################################################### #latdev.plotSurface(loadedcell,numOfLayer,name="dome_remake_%03d.png"%step,ids=False,alpha = 1.,elev = 7) #plotTargetFaceArrayGrowSurface(loadedcell,numOfLayer) return loadedcell
def getFastAndSlowFaceArea(cell,targetid = 135): ################################################ # Getting neighbours of the fast growing face ################################################ faceidarray = getNeighbourFaces(cell,targetid) ################################################ # Iterating faces and plotting the two separately ################################################ faces = qd.CellFaceIterator(cell) fastfaceareaarray = [] slowfaceareaarray = [] face = faces.next() while face != None: if face.getID() == 1 : face = faces.next() continue area = face.getAreaOfFace() if face.getID() in faceidarray: fastfaceareaarray.append(facearea) else: slowfaceareaarray.append(facearea) face =faces.next() ######################################################################## # returning the mean of fast and slow array ######################################################################## return np.mean(np.array(fastfaceareaarray)), np.mean(np.array(slowfaceareaarray))
def divideCells(cell): #global cell faces = qd.CellFaceIterator(cell) face = faces.next() while face != None: face.divideRandom() face = faces.next() return cell
def plotSurface(cell, ax, color, surface=False, alpha=0.6, zorder=10): from mpl_toolkits.mplot3d import Axes3D import matplotlib as mpl from mpl_toolkits.mplot3d.art3d import Poly3DCollection import numpy as np import matplotlib.pyplot as plt ############################################################### # Plotting the Cell # ############################################################### faces = qd.CellFaceIterator(cell) ################### face = faces.next() faceCounter = 0 xcenarray = [] ycenarray = [] zcenarray = [] while (face != None): if face.getID() == 1: face = faces.next() continue faceid = face.getID() #grabbing face id xlist = [] ylist = [] zlist = [] #print "== Face ID : ", faceid, "==" edges = qd.FaceEdgeIterator(face) edge = edges.next() while edge != None: ####grabbing the origin of edge#### #centralised coordiante vertex = edge.Org() #print vertex.getID() xCoord1 = vertex.getXcoordinate() yCoord1 = vertex.getYcoordinate() zCoord1 = vertex.getZcoordinate() xlist.append(xCoord1) ylist.append(yCoord1) zlist.append(zCoord1) edge = edges.next() xlist.append(xlist[0]) ylist.append(ylist[0]) zlist.append(zlist[0]) verts = [zip(xlist, ylist, zlist)] if surface: pc = Poly3DCollection(verts, alpha=alpha, facecolor=color, linewidths=1, zorder=zorder) pc.set_edgecolor(color) ax.add_collection3d(pc) else: ax.plot(xlist, ylist, zlist, c=color, lw=3) face = faces.next() faceCounter += 1 return
def getMeristemFaces(cell, primordialfaceids): meristemfaces = [] faces = qd.CellFaceIterator(cell) face = faces.next() while face != None: if (face.getID() in primordialfaceids) or sf.checkExternalFace(face) or (face.getID() == 1): face = faces.next() continue meristemfaces.append(face) face = faces.next() return meristemfaces
def plotMeanTargetArea(cell): faces = qd.CellFaceIterator(cell) face = faces.next() sumtargetarea = 0 numofface = 0 while face != None: if face.getID() == 1: face = faces.next() continue sumtargetarea += face.getTargetArea() return
def termsofenergy(inputcoordinates): global maincounter, numOfLayer, alpha, beta, pressure, cell #making of hexagonal lattice maincounter += 1 #Reshape the tempcoordinates, to x-y-z arrays tempcoordinates = inputcoordinates.reshape((3, numberofvertices)) #to store the deformation on the cells faceids = [] deformations = [] ####iterating the vertices to feed the new coordinates in vertices = qd.CellVertexIterator(cell) vertex = vertices.next() counter = 0 #counter to change vertex positions while vertex != None: vertex.setXcoordinate(tempcoordinates[0, counter]) #setting x coordinate vertex.setYcoordinate(tempcoordinates[1, counter]) #setting y coordinate vertex.setZcoordinate(tempcoordinates[2, counter]) #setting z coordinate counter += 1 vertex = vertices.next() ##################################################### #cell = settingParameters(cell) cell.setParameters() ##################################################### #calculating the deformation of Area faces = qd.CellFaceIterator(cell) face1 = faces.next() while face1 != None: if face1.getID() == 1: face1 = faces.next() continue #print face1.getID() targetarea = face1.getTargetArea() currentarea = face1.getAreaOfFace() #print "targetarea :", targetarea, "current area: ",currentarea, "difference :",targetarea-currentarea #change of area (strain on area %) faceids.append(face1.getID()) deformations.append(100 * (currentarea - targetarea) / targetarea) face1 = faces.next() ###################################################### #returning the total energy first = cell.getFirstTerm() second = cell.getSecondTerm() third = cell.getThirdTerm() fourth = cell.getFourthTerm() volume = cell.getVolume() #release the current cell #printing the counter and if the passed value is different than the previous values passed #print maincounter, energyvalue #print np.subtract(tempcoordinates, tempcoordstore) return [first, second, third, volume, [faceids, deformations], fourth]
def plotAverageGrowthRate(endStep,areaDerivativePlot, faceAreaDerivativePlot,targetid, startStep=1,norm=True, fastid = 0,azim = -60, elev = 50,stepsize = 1): import matplotlib.colors as colors import matplotlib.cm as cmx import math ###################################################### # Getting the first step ###################################################### if not os.path.isfile("qdObject_step=%03d.obj"%startStep): return cell = sf.loadCellFromFile(startStep) ###################################################### # dict of area ###################################################### dAreaCellDict = {} areaCellDict= {} surfaceAreaArray = np.zeros(endStep-startStep) faces = qd.CellFaceIterator(cell) face = faces.next() surfaceAreaArray[0] = cell.getSurfaceArea() ###################################################### stepcounter = 0 while face != None: if face.getID() == 1 : face = faces.next() continue areaCellDict[face.getID()] = np.zeros(int(math.ceil((float(endStep)-startStep)/stepsize))+1) dAreaCellDict[face.getID()] = np.zeros(int(math.ceil((float(endStep)-startStep)/stepsize))) areaCellDict[face.getID()][stepcounter] = face.getAreaOfFace() face =faces.next() ###################################################### # Gathering face area ###################################################### stepcounter += 1 ######################################## for i in range(startStep+stepsize,endStep+stepsize,stepsize): if not os.path.isfile("qdObject_step=%03d.obj"%i):#check if file exists break cell = sf.loadCellFromFile(i) ###################################### getAreaGrowthData(cell, areaCellDict, surfaceAreaArray,dAreaCellDict,stepcounter) ###################################################### stepcounter += 1 ###################################################### ######################## # plotting ######################## plotFaceAreaDerivative(faceAreaDerivativePlot,cell,dAreaCellDict,targetid,azim = azim, elev = elev) ######################## return
def getFaceAreaArray(totalstep): # Preparing the facearea dictionary step = 0 cell = sf.loadCellFromFile(step) facearea = {} faces = qd.CellFaceIterator(cell) face = faces.next() while face != None: if face.getID() == 1: face = faces.next() continue """if sf.checkExternalFace(face): face = faces.next() continue """ facearea[face.getID()] = [] face = faces.next() ############################################# # Loading the cells for steps till totalstep ############################################# for step in range(totalstep + 1): cell = sf.loadCellFromFile(step) cell.setParameters() cell.calculateStrain() ######################################################## faces = qd.CellFaceIterator(cell) face = faces.next() while face != None: if face.getID() == 1: face = faces.next() continue """if sf.checkExternalFace(face): face = faces.next() continue """ facearea[face.getID()].append(face.getAreaOfFace()) face = faces.next() return facearea
def getNeighbourFaces(cell,faceid): faces = qd.CellFaceIterator(cell) face = faces.next() faceidarray = [faceid] while face != None: if face.getID() == faceid : edges = qd.FaceEdgeIterator(face) edge = edges.next() while edge != None: faceidarray.append(edge.Right().getID()) edge = edges.next() break face =faces.next() return faceidarray
def getStrainMatrix(cell, targetid): cell.calculateStressStrain() # Stress-Strain calculation faces = qd.CellFaceIterator(cell) #performing growth in the face face = faces.next() while face != None: if face.getID() != targetid: face = faces.next() continue strainmatrix = np.array( [[face.getStrainValue(0, 0), face.getStrainValue(0, 1)], [face.getStrainValue(1, 0), face.getStrainValue(1, 1)]]) break return strainmatrix
def targetedFeedbackStrainGrowFaces(cell, targetid): #cell.calculateVertexForce()# Vertex Force calculation cell.calculateStressStrain() # Stress-Strain calculation faces = qd.CellFaceIterator(cell) #performing growth in the face face = faces.next() while face != None: if face.getID() != targetid: face = faces.next() continue face.feedbackStrainGrow() break #now setting new parameters on the cell #cell = settingParameters(cell) cell.setParameters() return
def checkFastGrowing(targetid, i): fastGrowing = [targetid] faces = qd.CellFaceIterator(cell) face = faces.next() while (face != None): if face.getID() == targetid: edges = qd.FaceEdgeIterator(face) edge = edges.next() while edge != None: rightFace = edge.Right() fastGrowing.append(rightFace.getID()) edge = edges.next() #print "kappa for this face : ", face.getKappa() face = faces.next() if i in fastGrowing: return True return False
def printmatrixenergy(cell): faces = qd.CellFaceIterator(cell) face1 = faces.next() while face1 != None: #print face1.getID() print "*****************************************" face1.printTargetFormMatrix() print "Face ID : ", face1.getID() print "first term : ", face1.getFirstTerm() print "second term : ", face1.getSecondTerm() print "third term : ", face1.getThirdTerm() print "energy of face :", face1.getEnergy() face1 = faces.next() print "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%" print "total Energy : ", cell.getEnergy() print "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%" return
def setOldTargetFormMatrix(cell, growthcounter): ### Loading the TargetFormMatrix loadedDictionary = np.load("TargetFormMatrix_step=%d.npy" % growthcounter).item() faces = qd.CellFaceIterator(cell) face = faces.next() while face != None: faceid = face.getID() matrixArray = loadedDictionary[faceid] qd.setTargetFormMatrix(face, 0, 0, matrixArray[1][1]) qd.setTargetFormMatrix(face, 1, 1, matrixArray[0][0]) qd.setTargetFormMatrix(face, 0, 1, matrixArray[0][1]) qd.setTargetFormMatrix(face, 1, 0, matrixArray[1][0]) face = faces.next() cell.setParameters() ###### return cell
def slowGrowth(cell,faceid): faces = qd.CellFaceIterator(cell) face = faces.next() while (face != None): if face.getID() == faceid: print "Slowed Growth ID :", faceid #print face.getKappa() face.setKappa(1.5) face.setGrowthVar(0.5) edges = qd.FaceEdgeIterator(face) edge = edges.next() while edge != None: rightFace = edge.Right() rightFace.setKappa(1.5) rightFace.setGrowthVar(0.5) edge = edges.next() face = faces.next() return
def fastGrowth(cell,faceid,fastkappa): faces = qd.CellFaceIterator(cell) face = faces.next() while (face != None): if face.getID() == faceid: print "Setting Fast Kappa Growth for Face ID :", faceid #print face.getKappa() face.setKappa(fastkappa) face.setGrowthVar(0.) """edges = qd.FaceEdgeIterator(face) edge = edges.next() while edge != None: rightFace = edge.Right() rightFace.setKappa(1.5) rightFace.setGrowthVar(0.5) edge = edges.next()""" print "kappa for this face : ", face.getKappa() face = faces.next() return cell
def getAreaGrowthData(cell, areaCellDict, surfaceAreaArray,dAreaCellDict,counter): surfaceAreaArray[counter] = cell.getSurfaceArea() dareaTissue = surfaceAreaArray[counter]-surfaceAreaArray[counter-1] ################################################ faces = qd.CellFaceIterator(cell) face = faces.next() while face != None: faceid = face.getID() if faceid == 1: face = faces.next() continue ######################################## areaCellDict[faceid][counter] = face.getAreaOfFace() dareaCell = areaCellDict[faceid][counter]-areaCellDict[faceid][counter-1] dAreaCellDict[faceid][counter-1] = dareaCell/dareaTissue ######################################## face = faces.next() ######################################## return
def targetFaceGrow(cell, faceid): faces = qd.CellFaceIterator(cell) face = faces.next() while (face != None): if face.getID() == faceid: print "###################################################################################################" print "Growing face %d & the neighbourhoodwith kappa : %.3f and growthvar : %.3f" % ( faceid, face.getKappa(), face.getGrowthVar()) print "###################################################################################################" face.feedbackInflatedGrow() edges = qd.FaceEdgeIterator(face) edge = edges.next() while edge != None: rightFace = edge.Right() rightFace.feedbackInflatedGrow() edge = edges.next() face = faces.next() cell.setParameters() return cell
def cartesianEnergyObjective(inputcoordinates, grad): global numOfLayer, alpha, beta, pressure, cell, functionCallCounter, bendingThreshold, meanFormMatrix #making of hexagonal lattic #Reshape the tempcoordinates, to x-y-z arrays ####iterating the vertices to feed the new coordinates in tempcoordinates = inputcoordinates.reshape((3, numberofvertices)) ####iterating the vertices to feed the new coordinates in vertices = qd.CellVertexIterator(cell) vertex = vertices.next() counter = 0 #counter to change vertex positions while vertex != None: vertex.setXcoordinate(tempcoordinates[0, counter]) #setting x coordinate vertex.setYcoordinate(tempcoordinates[1, counter]) #setting y coordinate vertex.setZcoordinate(tempcoordinates[2, counter]) #setting z coordinate counter += 1 vertex = vertices.next() ###################################################### #cell = settingParameters(cell) cell.setParameters() ###################################################### faces = qd.CellFaceIterator(cell) face = faces.next() faceFormMatrix = np.zeros((2, 2)) energyvalue = 0. while face != None: faceFormMatrix[0, 0] = qd.getCurrentFormMatrix(face, 0, 0) faceFormMatrix[0, 1] = qd.getCurrentFormMatrix(face, 0, 1) faceFormMatrix[1, 0] = qd.getCurrentFormMatrix(face, 1, 0) faceFormMatrix[1, 1] = qd.getCurrentFormMatrix(face, 1, 1) ##################### differenceMatrix = faceFormMatrix - meanFormMatrix ##################### differenceMatrix = np.power(differenceMatrix, 2) energyvalue += np.sum(differenceMatrix) face = faces.next() ###################################################### #returning the total energy return energyvalue
def getIntrinsicCoordinates(cell, targetfaceid): faces = qd.CellFaceIterator(cell) face = faces.next() while face != None: faceid = face.getID() if faceid != targetfaceid: face = faces.next() continue edges = qd.FaceEdgeIterator(face) edge = edges.next() x = [] y = [] while edge != None: vertex = edge.Dest() ## Getting coordinates x.append(vertex.getProjectedXcoordinate(targetfaceid)) y.append(vertex.getProjectedYcoordinate(targetfaceid)) edge = edges.next() break x.append(x[0]) y.append(y[0]) return x, y
def getCurrentFormMatrix(cell): #getting all the target form matrix formmatrixDictionary = {}#dictionary to save all the targetformmatrix ## Getting and saving matrix in array faces = qd.CellFaceIterator(cell) face = faces.next() matrixArray = np.zeros((2,2)) #starting Iteration while face != None: faceid = face.getID() if faceid == 1: face = faces.next() continue matrixArray[0,0] = qd.getCurrentFormMatrix(face, 0,0) matrixArray[0,1] = qd.getCurrentFormMatrix(face, 0,1) matrixArray[1,0] = qd.getCurrentFormMatrix(face, 1,0) matrixArray[1,1] = qd.getCurrentFormMatrix(face, 1,1) #saving this in dictionary #print matrixArray formmatrixDictionary[faceid] = np.copy(matrixArray) face = faces.next() return formmatrixDictionary
def getTargetFormMatrixEllipsePoints(targetface=10): #getting the Target Form Matrix faces = qd.CellFaceIterator(cell) face = faces.next() while True: if face.getID() == targetface: break face = faces.next() #print "Face Id : ", face.getID() targetformmatrix = np.array([[ qd.getTargetFormMatrix(face, 0, 0), qd.getTargetFormMatrix(face, 0, 1) ], [ qd.getTargetFormMatrix(face, 1, 0), qd.getTargetFormMatrix(face, 1, 1) ]]) unitx = face.getUnitx() unity = face.getUnity() unitz = face.getUnitz() unit_mat = np.matrix([[ qd.doublearray_getitem(unitx, 0), qd.doublearray_getitem(unitx, 1), qd.doublearray_getitem(unitx, 2) ], [ qd.doublearray_getitem(unity, 0), qd.doublearray_getitem(unity, 1), qd.doublearray_getitem(unity, 2) ], [ qd.doublearray_getitem(unitz, 0), qd.doublearray_getitem(unitz, 1), qd.doublearray_getitem(unitz, 2) ]]) ##### getting data from ellipse data = plot_ellipse(cov=targetformmatrix, data_out=True) ################################ return data