00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include <CompuCell3D/Simulator.h>
00026 #include <CompuCell3D/Potts3D/Cell.h>
00027 #include <CompuCell3D/Potts3D/Potts3D.h>
00028 #include <CompuCell3D/Field3D/Point3D.h>
00029 #include <CompuCell3D/Field3D/Dim3D.h>
00030 #include <CompuCell3D/Field3D/WatchableField3D.h>
00031 using namespace CompuCell3D;
00032
00033
00034
00035
00036 #include <BasicUtils/BasicString.h>
00037 #include <BasicUtils/BasicException.h>
00038
00039 #include <BasicUtils/BasicClassGroup.h>
00040 #include <BasicUtils/BasicRandomNumberGenerator.h>
00041 #include <CompuCell3D/Potts3D/CellInventory.h>
00042 #include <CompuCell3D/plugins/CellType/CellTypePlugin.h>
00043 #include <PublicUtilities/StringUtils.h>
00044 #include <XMLUtils/CC3DXMLElement.h>
00045
00046 #include <string>
00047
00048 #include <math.h>
00049
00050 #include <iostream>
00051 using namespace std;
00052
00053 #define EXP_STL
00054 #include "BlobFieldInitializer.h"
00055
00056
00057 std::string BlobFieldInitializer::steerableName(){
00058 return toString();
00059 }
00060
00061 std::string BlobFieldInitializer::toString(){
00062 return "BlobInitializer";
00063 }
00064
00065
00066 BlobFieldInitializer::BlobFieldInitializer() :
00067 potts(0){}
00068
00069 void BlobFieldInitializer::init(Simulator *simulator, CC3DXMLElement * _xmlData){
00070
00071 potts = simulator->getPotts();
00072 WatchableField3D<CellG *> *cellFieldG = (WatchableField3D<CellG *> *)potts->getCellFieldG();
00073 ASSERT_OR_THROW("initField() Cell field G cannot be null!", cellFieldG);
00074 Dim3D dim = cellFieldG->getDim();
00075
00076
00077
00078
00079 if(_xmlData->getFirstElement("Radius")){
00080 oldStyleInitData.radius=_xmlData->getFirstElement("Radius")->getUInt();
00081 cerr<<"Got FE This Radius: "<<oldStyleInitData.radius<<endl;
00082 ASSERT_OR_THROW("Radius has to be greater than 0 and 2*radius cannot be bigger than lattice dimension x", oldStyleInitData.radius>0 && 2*(oldStyleInitData.radius)<(dim.x-2));
00083 }
00084
00085 if(_xmlData->getFirstElement("Width")){
00086 oldStyleInitData.width=_xmlData->getFirstElement("Width")->getUInt();
00087 cerr<<"Got FE This Width: "<<oldStyleInitData.width<<endl;
00088 }
00089 if(_xmlData->getFirstElement("Gap")){
00090 oldStyleInitData.gap=_xmlData->getFirstElement("Gap")->getUInt();
00091 cerr<<"Got FE This Gap: "<<oldStyleInitData.gap<<endl;
00092 }
00093
00094
00095
00096 if (_xmlData->getFirstElement("CellSortInit")){
00097 if(_xmlData->getFirstElement("CellSortInit")->getText()=="yes" ||_xmlData->getFirstElement("CellSortInit")->getText()=="Yes"){
00098 cellSortInit=true;
00099 cerr<<"SET CELLSORT INIT"<<endl;
00100 }
00101 }
00102
00103
00104
00105 CC3DXMLElement *elem=_xmlData->getFirstElement("Engulfment");
00106 if (elem){
00107 engulfmentData.engulfment=true;
00108 engulfmentData.bottomType=elem->getAttribute("BottomType");
00109 engulfmentData.topType=elem->getAttribute("TopType");
00110 engulfmentData.engulfmentCutoff=elem->getAttributeAsUInt("EngulfmentCutoff");
00111 engulfmentData.engulfmentCoordinate=elem->getAttribute("EngulfmentCoordinate");
00112 }
00113
00114
00115
00116 blobInitializerData.clear();
00117
00118 CC3DXMLElementList regionVec=_xmlData->getElements("Region");
00119
00120 for (int i = 0 ; i<regionVec.size(); ++i){
00121 BlobFieldInitializerData initData;
00122 initData.radius=regionVec[i]->getFirstElement("Radius")->getUInt();
00123 initData.gap=regionVec[i]->getFirstElement("Gap")->getUInt();
00124 initData.width=regionVec[i]->getFirstElement("Width")->getUInt();
00125 initData.typeNamesString=regionVec[i]->getFirstElement("Types")->cdata;
00126
00127 parseStringIntoList(initData.typeNamesString , initData.typeNames , ",");
00128
00129 initData.center.x=regionVec[i]->getFirstElement("Center")->getAttributeAsUInt("x");
00130 initData.center.y=regionVec[i]->getFirstElement("Center")->getAttributeAsUInt("y");
00131 initData.center.z=regionVec[i]->getFirstElement("Center")->getAttributeAsUInt("z");
00132
00133 cerr<<"radius="<<initData.radius<<" gap="<<initData.gap<<" types="<<initData.typeNamesString<<endl;
00134 blobInitializerData.push_back(initData);
00135 }
00136
00137
00138
00139
00140
00141
00142 cerr<<"GOT HERE BEFORE EXIT"<<endl;
00143
00144 }
00145
00146
00147
00148 double BlobFieldInitializer::distance(double ax, double ay, double az, double bx, double by, double bz) {
00149
00150
00151
00152 return sqrt((double)(ax - bx) * (ax - bx) +
00153 (double)(ay - by) * (ay - by) +
00154 (double)(az - bz) * (az - bz));
00155 }
00156
00157 void BlobFieldInitializer::layOutCells(const BlobFieldInitializerData & _initData){
00158
00159 int size = _initData.gap + _initData.width;
00160 int cellWidth=_initData.width;
00161
00162 WatchableField3D<CellG *> *cellField =(WatchableField3D<CellG *> *) potts->getCellFieldG();
00163 ASSERT_OR_THROW("initField() Cell field cannot be null!", cellField);
00164
00165 Dim3D dim = cellField->getDim();
00166
00167 ASSERT_OR_THROW("Radius has to be greater than 0 and 2*radius cannot be bigger than lattice dimension x", _initData.radius>0 && 2*_initData.radius<(dim.x-2));
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187 Dim3D itDim=getBlobDimensions(dim,size);
00188 cerr<<"itDim="<<itDim<<endl;
00189
00190
00191 Point3D pt;
00192 Point3D cellPt;
00193 CellG *cell;
00194
00195 for (int z = 0; z < itDim.z; z++)
00196 for (int y = 0; y < itDim.y; y++)
00197 for (int x = 0; x < itDim.x; x++) {
00198 pt.x = x * size;
00199 pt.y = y * size;
00200 pt.z = z * size;
00201
00202
00203 if(! (distance(pt.x, pt.y, pt.z, _initData.center.x, _initData.center.y, _initData.center.z) < _initData.radius) ){
00204 continue;
00205 }
00206
00207 if (BoundaryStrategy::getInstance()->isValid(pt)){
00208 cell = potts->createCellG(pt);
00209 cell->type=initCellType(_initData);
00210 }
00211 else{
00212 continue;
00213 }
00214
00215 for (cellPt.z = pt.z; cellPt.z < pt.z + cellWidth &&
00216 cellPt.z < dim.z; cellPt.z++)
00217 for (cellPt.y = pt.y; cellPt.y < pt.y + cellWidth &&
00218 cellPt.y < dim.y; cellPt.y++)
00219 for (cellPt.x = pt.x; cellPt.x < pt.x + cellWidth &&
00220 cellPt.x < dim.x; cellPt.x++){
00221
00222 if (BoundaryStrategy::getInstance()->isValid(pt))
00223 cellField->set(cellPt, cell);
00224
00225 }
00226 }
00227
00228
00229
00230 }
00231
00232 unsigned char BlobFieldInitializer::initCellType(const BlobFieldInitializerData & _initData){
00233 Automaton * automaton=potts->getAutomaton();
00234 if(_initData.typeNames.size()==0){
00235 return 1;
00236 }
00237
00238 else{
00239 BasicRandomNumberGenerator * randGen=BasicRandomNumberGenerator::getInstance();
00240 int index = randGen->getInteger(0, _initData.typeNames.size()-1);
00241 return automaton->getTypeId(_initData.typeNames[index]);
00242 }
00243
00244 }
00245
00246 void BlobFieldInitializer::start() {
00247
00248
00249
00252
00253
00254
00255
00256 WatchableField3D<CellG *> *cellFieldG = (WatchableField3D<CellG *> *)potts->getCellFieldG();
00257 ASSERT_OR_THROW("initField() Cell field G cannot be null!", cellFieldG);
00258
00259 cout<<"********************BLOB INIT***********************"<<endl;
00260 Dim3D dim = cellFieldG->getDim();
00261 if(blobInitializerData.size()!=0){
00262 for (int i = 0 ; i < blobInitializerData.size(); ++i){
00263 cerr<<"GOT HERE"<<endl;
00264 layOutCells(blobInitializerData[i]);
00265
00266 }
00267 }else{
00268 oldStyleInitData.center=Point3D(dim.x / 2,dim.y / 2,dim.z / 2);
00269 layOutCells(oldStyleInitData);
00270
00271 if(cellSortInit){
00272 initializeCellTypesCellSort();
00273 }
00274
00275 if(engulfmentData.engulfment){
00276 initializeEngulfment();
00277 }
00278 }
00279
00280
00281
00282
00283 }
00284
00285 Dim3D BlobFieldInitializer::getBlobDimensions(const Dim3D & dim,int size){
00286 Dim3D itDim;
00287
00288 itDim.x = dim.x / size;
00289 if (dim.x % size) itDim.x += 1;
00290 itDim.y = dim.y / size;
00291 if (dim.y % size) itDim.y += 1;
00292 itDim.z = dim.z / size;
00293 if (dim.z % size) itDim.z += 1;
00294
00295 blobDim=itDim;
00296
00297 return itDim;
00298
00299 }
00300
00301
00302 void BlobFieldInitializer::initializeEngulfment(){
00303
00304 unsigned char topId,bottomId;
00305 CellTypePlugin * cellTypePluginPtr=(CellTypePlugin*)(Simulator::pluginManager.get("CellType"));
00306 ASSERT_OR_THROW("CellType plugin not initialized!", cellTypePluginPtr);
00307
00308 EngulfmentData &enData=engulfmentData;
00309
00310 topId=cellTypePluginPtr->getTypeId(enData.topType);
00311 bottomId=cellTypePluginPtr->getTypeId(enData.bottomType);
00312
00313 cerr<<"topId="<<(int)topId<<" bottomId="<<(int)bottomId<<" enData.engulfmentCutoff="<<enData.engulfmentCutoff<<" enData.engulfmentCoordinate="<<enData.engulfmentCoordinate<<endl;
00314
00315
00316
00317
00318 WatchableField3D<CellG *> *cellFieldG =(WatchableField3D<CellG *> *) potts->getCellFieldG();
00319 Dim3D dim = cellFieldG->getDim();
00320
00321 CellInventory * cellInventoryPtr=& potts->getCellInventory();
00323 CellInventory::cellInventoryIterator cInvItr;
00324
00325 CellG * cell;
00326 Point3D pt;
00327
00329 for(cInvItr=cellInventoryPtr->cellInventoryBegin() ; cInvItr !=cellInventoryPtr->cellInventoryEnd() ;++cInvItr ){
00330
00331 cell=*cInvItr;
00332 cell->type=1;
00333 }
00334
00335 for (int x = 0 ; x < dim.x ; ++x){
00336 for (int y = 0 ; y < dim.y ; ++y){
00337 for (int z = 0 ; z < dim.z ; ++z){
00338 pt.x=x;
00339 pt.y=y;
00340 pt.z=z;
00341 cell=cellFieldG->get(pt);
00342
00343 if(enData.engulfmentCoordinate=="x" || enData.engulfmentCoordinate=="X"){
00344 if(cell && pt.x<enData.engulfmentCutoff){
00345 cell->type=bottomId;
00346 }else if(cell && pt.x>=enData.engulfmentCutoff){
00347 cell->type=topId;
00348 }
00349
00350 }
00351 if(enData.engulfmentCoordinate=="y" || enData.engulfmentCoordinate=="Y"){
00352 if(cell && pt.y<enData.engulfmentCutoff){
00353 cell->type=bottomId;
00354 }else if(cell && pt.y>=enData.engulfmentCutoff){
00355 cell->type=topId;
00356 }
00357 }
00358 if(enData.engulfmentCoordinate=="z" || enData.engulfmentCoordinate=="Z"){
00359 if(cell && pt.z<enData.engulfmentCutoff){
00360 cell->type=bottomId;
00361 }else if(cell && pt.z>=enData.engulfmentCutoff){
00362 cell->type=topId;
00363 }
00364 }
00365
00366 }
00367
00368 }
00369 }
00370
00371
00372 }
00373
00374
00375 void BlobFieldInitializer::initializeCellTypesCellSort(){
00376
00377
00378
00379
00380
00381 BasicRandomNumberGenerator *rand = BasicRandomNumberGenerator::getInstance();
00382 CellInventory * cellInventoryPtr=& potts->getCellInventory();
00383
00385 CellInventory::cellInventoryIterator cInvItr;
00386
00387 CellG * cell;
00388
00390 for(cInvItr=cellInventoryPtr->cellInventoryBegin() ; cInvItr !=cellInventoryPtr->cellInventoryEnd() ;++cInvItr ){
00391
00392 cell=*cInvItr;
00393
00394 if(rand->getRatio()<0.5){
00395 cell->type=1;
00396 }else{
00397 cell->type=2;
00398 }
00399
00400 }
00401
00402 }
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495