def __init__(self, xLength=150, yLength=200, zLength=1, voxelDensity=1, initNutrientDiffusion = False, MCSperDay=500, simDurationDays=720, sampleIntervalInDays=0.5, fluctuationAmplitude=10.0, flip2DimRatio=0.5, neighborOrder=1, boundary_x="Periodic", debugOutputFrequency=50000, SEED=-1): """ :param xLength: :param yLength: :param zLength: :param voxelDensity: :param MCSperDay: MC steps per Day. Default is 500, i.e. 500 MCS = 1 day. :param simDurationDays: :param fluctuationAmplitude: :param flip2DimRatio: :param neighborOrder: :param boundary_x: :param debugOutputFrequency: :param SEED: :return: """ self.xLength = xLength self.yLength = yLength self.zLength = zLength self.voxelDensity = voxelDensity # 1 voxel / 1 mu self.initNutrientDiffusion = initNutrientDiffusion self.dimensions = 2 if zLength <= 0 else 3 self.xDimension = self.calcPixelFromMuMeter(xLength) self.yDimension = self.calcPixelFromMuMeter(yLength) self.zDimension = 1 if self.dimensions == 2 else self.calcPixelFromMuMeterMin1(zLength) self.latticeSizeInVoxel = self.xDimension * self.yDimension * self.zDimension self.MCSperDay = MCSperDay self.simDurationDays = simDurationDays self.sampleIntervalInDays = sampleIntervalInDays self.sampleIntervalInMCS = self.calcMCSfromDays(sampleIntervalInDays) self.maxSteps = self.calcMCSfromDays(simDurationDays) self.fluctuationAmplitude = fluctuationAmplitude self.flip2DimRatio = flip2DimRatio self.neighborOrder = neighborOrder self.boundary_x = boundary_x self.debugOutputFrequency = debugOutputFrequency # TODO: change the seed value of every random number used in Moduro project self.SEED = (int(round(time.time() * 1000)) % 9999) if SEED < 0 else SEED self.__cc3d = None self.parameterStore = ParameterStore() self.parameterStore.addObj(self)
class ExecConfig(object): def __init__(self, xLength=150, yLength=200, zLength=1, voxelDensity=1, initNutrientDiffusion = False, MCSperDay=500, simDurationDays=720, sampleIntervalInDays=0.5, fluctuationAmplitude=10.0, flip2DimRatio=0.5, neighborOrder=1, boundary_x="Periodic", debugOutputFrequency=50000, SEED=-1): """ :param xLength: :param yLength: :param zLength: :param voxelDensity: :param MCSperDay: MC steps per Day. Default is 500, i.e. 500 MCS = 1 day. :param simDurationDays: :param fluctuationAmplitude: :param flip2DimRatio: :param neighborOrder: :param boundary_x: :param debugOutputFrequency: :param SEED: :return: """ self.xLength = xLength self.yLength = yLength self.zLength = zLength self.voxelDensity = voxelDensity # 1 voxel / 1 mu self.initNutrientDiffusion = initNutrientDiffusion self.dimensions = 2 if zLength <= 0 else 3 self.xDimension = self.calcPixelFromMuMeter(xLength) self.yDimension = self.calcPixelFromMuMeter(yLength) self.zDimension = 1 if self.dimensions == 2 else self.calcPixelFromMuMeterMin1(zLength) self.latticeSizeInVoxel = self.xDimension * self.yDimension * self.zDimension self.MCSperDay = MCSperDay self.simDurationDays = simDurationDays self.sampleIntervalInDays = sampleIntervalInDays self.sampleIntervalInMCS = self.calcMCSfromDays(sampleIntervalInDays) self.maxSteps = self.calcMCSfromDays(simDurationDays) self.fluctuationAmplitude = fluctuationAmplitude self.flip2DimRatio = flip2DimRatio self.neighborOrder = neighborOrder self.boundary_x = boundary_x self.debugOutputFrequency = debugOutputFrequency # TODO: change the seed value of every random number used in Moduro project self.SEED = (int(round(time.time() * 1000)) % 9999) if SEED < 0 else SEED self.__cc3d = None self.parameterStore = ParameterStore() self.parameterStore.addObj(self) def initPotts(self): self.__cc3d = ElementCC3D("CompuCell3D", {"version": "3.7.3"}) potts = self.__cc3d.ElementCC3D("Potts") potts.ElementCC3D("Dimensions", {"x": self.xDimension, "y": self.yDimension, "z": self.zDimension}) potts.ElementCC3D("Steps", {}, self.maxSteps) potts.ElementCC3D("FluctuationAmplitude", {}, self.fluctuationAmplitude) potts.ElementCC3D("Flip2DimRatio", {}, self.flip2DimRatio) potts.ElementCC3D("NeighborOrder", {}, self.neighborOrder) potts.ElementCC3D("Boundary_x", {}, self.boundary_x) potts.ElementCC3D("DebugOutputFrequency", {}, self.debugOutputFrequency) potts.ElementCC3D("RandomSeed", {}, self.SEED) def initCellTypes(self, cellTypes): PluginElmnt = self.__cc3d.ElementCC3D("Plugin", {"Name": "CellType"}) for i in range(cellTypes.__len__()): if cellTypes[i].frozen: PluginElmnt.ElementCC3D("CellType", {"Freeze": "", "TypeId": cellTypes[i].id, "TypeName": cellTypes[i].name}) else: PluginElmnt.ElementCC3D("CellType", {"TypeId": cellTypes[i].id, "TypeName": cellTypes[i].name}) def initEnergyMatrix(self, cellTypes, energyMatrix, adhFactor): contact = self.__cc3d.ElementCC3D("Plugin", {"Name": "Contact"}) for i in range(cellTypes.__len__()): for j in range(i, cellTypes.__len__()): contact.ElementCC3D("Energy", {"Type1": cellTypes[i].name, "Type2": cellTypes[j].name}, adhFactor * energyMatrix[i][j]) def initPlugins(self, *args): for a in args: self.__cc3d.ElementCC3D("Plugin", {"Name": a}) def initDiffusion(self, cellType, secretionRateNutr, decayConstantNutr): SteppableElmnt = self.__cc3d.ElementCC3D("Steppable", {"Type": "FlexibleDiffusionSolverFE"}) DiffusionFieldElmnt = SteppableElmnt.ElementCC3D("DiffusionField") DiffusionDataElmnt = DiffusionFieldElmnt.ElementCC3D("DiffusionData") DiffusionDataElmnt.ElementCC3D("FieldName", {}, "Nutrients") DiffusionDataElmnt.ElementCC3D("DiffusionConstant", {}, secretionRateNutr) DiffusionDataElmnt.ElementCC3D("DecayConstant", {}, decayConstantNutr) SecretionDataElmnt = DiffusionFieldElmnt.ElementCC3D("SecretionData") SecretionDataElmnt.ElementCC3D("Secretion", {"Type": cellType.name}, secretionRateNutr) def getCC3D(self): return self.__cc3d def calculateLatticeSize(self): return self.xDimension * self.yDimension * self.zDimension def interuptMCS(self, mcs): return (mcs == 0) or (mcs % self.sampleIntervalInMCS == 0) def addParameter(self, key, value): # TODO: ghj return None def calcPixelFromMuMeter(self, mum): """ Convert a length in micro meter to a pixel length. This is influenced by the voxelDensity. :param mum: :return: """ #python has approximation errors when casted into int with long number of .99999999 return int(self.voxelDensity * mum + 0.000001) def calcPixelFromMuMeterMin1(self, mum): """ Convert a length in micro meter to a pixel length. This is influenced by the voxelDensity. :param mum: :return: """ return self.__truncate(self.voxelDensity * mum) def calculateVolume(self, diameter): if self.dimensions == 2: return PI * (diameter / 2.0) ** 2 # Area else: return 4.0 / 3.0 * PI * (diameter / 2.0) ** 3 # Volume def calculateSurface(self, diameter): if self.dimensions == 2: return 2 * PI * (diameter / 2.0) # Circumference else: return 4 * PI * (diameter / 2.0) ** 2 # Surface def calcVoxelVolumeFromVolume(self, volume): """ Calculates the voxel volume from a physical volume. The results depends on the dimension of the simulation (2D or 3D). The scaling is influenced by the voxelDensity. :param volume: physical volume in mu m^3. :return: Voxel volume. """ r = (3 * volume / (4.0 * PI)) ** (1.0 / 3.0) # Radius of a sphere with known volume. rDimension = self.calcPixelFromMuMeter(r) # Convert it to a pixel unit. if self.dimensions == 2: # a = self.__truncateToVoxel(PI * (rDimension ** 2)) # if volume > 0: # print "volume=", volume, ", rDim=", rDimension, ", r=", r, ", A=", a return self.__truncate(PI * (rDimension ** 2)) # Area of a circle. else: return self.__truncate(4.0 / 3.0 * PI * (rDimension ** 3)) # Volume of a sphere. def calcVoxelSurfaceFromVoxelVolume(self, voxelVolume): """ Calculates the voxel surface from a voxel volume. The results depends on the dimension of the simulation (2D or 3D). :param voxelVolume: volume (in pixel^3). :return: Surface in pixel^2 ^(3D) or pixel (2). """ if self.dimensions == 2: # some fractal factor! return self.__truncate(1.5 * 2 * (PI * voxelVolume) ** (1.0 / 2.0)) # Circumference. else: return self.__truncate(2.0 * 4 * PI * (3 * voxelVolume / (4 * PI)) ** (2.0 / 3.0)) # Surface. def __truncate(self, value): res = int(value + 0.00001) if res <= 1: return 1 # Ensure that size is at least 1. else: return res def calcMCSfromDays(self, days): """ Convert the time scale days into MC steps. :param days: :return: """ return self.__truncate(self.MCSperDay * days) def calcDaysFromMCS(self, mcs): """ Convert the MCS number into days. :param mcs: :return: """ return mcs / (1.0 * self.MCSperDay) def calcHoursFromMCS(self, mcs): """ Convert the MCS number into hours. :param mcs: :return: """ return mcs / (1.0 * self.MCSperDay) * 24.0 def calcSurLambdaFromSurFit(self, surFit): return 0.05 * surFit def calcVolLambdaFromVolFit(self, volFit): return 1.0 * volFit