Changeset - f4023d64bb53
[Not reviewed]
default
0 5 0
Roeland Merks - 11 years ago 2014-05-01 16:15:10
merks@cwi.nl
Fixed some minor syntactic errors that popped up after compiling on MacOSX10.8.5
5 files changed with 8 insertions and 8 deletions:
0 comments (0 inline, 0 general)
src/VirtualLeaf.cpp
Show inline comments
 
@@ -75,395 +75,395 @@ public:
 
  }
 
};
 

	
 

	
 
class EdgeSource {
 

	
 
public:
 
  void operator() (Cell &c) {
 

	
 
    if (c.AtBoundaryP()) {
 
      cerr << "Cell " << c.Index() << " is a source cell.\n";
 
      c.SetSource(0,par.source);
 
    } else {
 
      cerr << "Cell " << c.Index() << " is _not_ a source cell.\n";
 
    }
 
  }
 
};
 

	
 

	
 

	
 
class CellInfo {
 
public:
 
  void operator() (Cell &c,std::ostream &os) const {
 
    os << "Cell " << c.index << " says: " << endl;
 
    os << "c.nodes.size() = " << c.nodes.size() << endl;
 
    for (list<Node *>::iterator i=c.nodes.begin(); i!=c.nodes.end(); i++) {
 
      cerr << (*i)->Index() << " ";
 
    }
 
    cerr << endl;
 
  }
 
};
 

	
 
double PINSum(Cell &c) {
 
  return c.Chemical(1) + c.SumTransporters(1);// + c.ReduceCellAndWalls<double>( complex_PijAj );
 
}
 

	
 

	
 
class DrawCell {
 
public:
 
  void operator() (Cell &c,QGraphicsScene &canvas, MainBase &m) const {
 
    if (m.ShowBorderCellsP() || c.Boundary()==Cell::None) {
 
      if (!m.ShowBoundaryOnlyP() && !m.HideCellsP()) {
 
	if (m.ShowToolTipsP()) {
 
	  //QString info_string=QString("Cell %1, chemicals: ( %2, %3, %4, %5, %6)\n %7 of PIN1 at walls.\n Area is %8\n PIN sum is %9\n Circumference is %10\n Boundary type is %11").arg(c.Index()).arg(c.Chemical(0)).arg(c.Chemical(1)).arg(c.Chemical(2)).arg(c.Chemical(3)).arg(c.Chemical(4)).arg(c.SumTransporters(1)).arg(c.Area()).arg(PINSum(c)).arg(c.Circumference()).arg(c.BoundaryStr());
 
		QString info_string=QString("Cell %1, chemicals(%2): ").arg(c.Index()).arg(Cell::NChem());
 
		for (int i=0;i<Cell::NChem();i++) {
 
			info_string += QString("%1 ").arg(c.Chemical(i));
 
		}
 
		info_string += QString("\nArea is %1\n Circumference is %2\n Boundary type is %3").arg(c.Area()).arg(c.WallCircumference()).arg(c.BoundaryStr());
 
		
 
	  info_string += "\nNodes: " + c.printednodelist();
 
	  c.Draw(&canvas, info_string);
 
	} else {
 
	  c.Draw(&canvas);
 
	}
 
      }
 
      if (m.ShowCentersP()){
 
	c.DrawCenter(&canvas);
 
      }
 
      if (m.ShowFluxesP()){
 
	c.DrawFluxes(&canvas, par.arrowsize);
 
      }
 
    }
 
  }
 
};
 

	
 
Mesh mesh;
 
bool batch=false;
 

	
 
void MainBase::Plot(int resize_stride)
 
{
 

	
 
  clear();
 

	
 
  int count=(int)mesh.getTime();
 

	
 
  if (resize_stride) {
 
    if ( !((count)%resize_stride) ) {
 
      FitLeafToCanvas();
 
    }
 
  }
 

	
 
  mesh.LoopCells(DrawCell(),canvas,*this);
 

	
 
  if (ShowNodeNumbersP()) 
 
    mesh.LoopNodes( bind2nd (mem_fun_ref ( &Node::DrawIndex), &canvas ) ) ;
 
  if (ShowCellNumbersP()) 
 
    mesh.LoopCells( bind2nd (mem_fun_ref ( &Cell::DrawIndex), &canvas ) ) ;
 

	
 
  if (ShowCellAxesP()) 
 
    mesh.LoopCells( bind2nd (mem_fun_ref ( &Cell::DrawAxis), &canvas ) );
 

	
 
  if (ShowCellStrainP()) 
 
    mesh.LoopCells( bind2nd (mem_fun_ref ( &Cell::DrawStrain), &canvas ) );
 

	
 
  if (ShowWallsP())
 
    mesh.LoopWalls( bind2nd( mem_fun_ref( &Wall::Draw ), &canvas ) );
 

	
 
  /*  if (ShowApoplastsP()) 
 
      mesh.LoopWalls( bind2nd( mem_fun_ref( &Wall::DrawApoplast ), &canvas ) );
 
  */
 
  if (ShowMeshP()) 
 
    mesh.DrawNodes(&canvas);
 

	
 
  if (ShowBoundaryOnlyP()) 
 
    mesh.DrawBoundary(&canvas);
 

	
 
  if ( ( batch || MovieFramesP() )) {
 
    if (!(count%par.storage_stride) ) {
 
      stringstream fname;
 
      fname << par.datadir << "/leaf.";
 
      fname.fill('0');
 
      fname.width(6);
 
      fname << count << ".png";
 
      // Write high-res PNG snapshot every plot step
 
      Save(fname.str().c_str(), "PNG", 1024, 768);
 
    }
 

	
 
    if (!(count%par.xml_storage_stride)) {
 
      stringstream fname;
 
      fname << par.datadir << "/leaf.";
 
      fname.fill('0');
 
      fname.width(6);
 
      fname << count << ".xml";
 
      // Write XML file every ten plot steps
 
      mesh.XMLSave(fname.str().c_str(), XMLSettingsTree());
 
    }
 
  }
 
}
 

	
 

	
 
INIT {
 

	
 
  //mesh.SetSimPlugin(plugin);
 
  if (leaffile) { 
 
    if (qApp->type()==QApplication::Tty) {
 
      
 
      xmlNode *settings;
 
      mesh.XMLRead(leaffile, &settings);
 
      
 
      main_window->XMLReadSettings(settings);
 
      xmlFree(settings);
 
      main_window->UserMessage(QString("Ready. Time is %1").arg(mesh.getTimeHours().c_str()));
 
    } else {
 
      ((Main *)main_window)->readStateXML(leaffile);
 
    }
 
    
 
  } else {
 
    mesh.StandardInit();
 
  }
 
  
 
  Cell::SetMagnification(1);
 
  Cell::setOffset(0,0);
 
  
 
  FitLeafToCanvas();
 
  Plot();
 

	
 
}
 

	
 
TIMESTEP {
 

	
 
  static int i=0;
 
  static int t=0;
 
  static int ncells;
 

	
 
  if (!batch) {
 
    UserMessage(QString("Time: %1").arg(mesh.getTimeHours().c_str()),0);
 
  }
 

	
 
  ncells=mesh.NCells();
 

	
 

	
 
  double dh;
 

	
 
  if(DynamicCellsP()) {
 
    dh = mesh.DisplaceNodes();
 

	
 
    // Only allow for node insertion, cell division and cell growth
 
    // if the system has equillibrized
 
    // i.e. cell wall tension equillibrization is much faster
 
    // than biological processes, including division, cell wall yielding
 
    // and cell expansion
 
    mesh.InsertNodes(); // (this amounts to cell wall yielding)
 

	
 
    if ( (-dh) < par.energy_threshold) {
 

	
 
      mesh.IncreaseCellCapacityIfNecessary();
 
      mesh.DoCellHouseKeeping();
 
      //mesh.LoopCurrentCells(mem_fun(&plugin->CellHouseKeeping)); // this includes cell division
 

	
 
      // Reaction diffusion	
 
      mesh.ReactDiffuse(par.rd_dt);
 
      t++;
 
      Plot(par.resize_stride);
 
    }
 
  } else {
 
    mesh.ReactDiffuse(par.rd_dt);
 
    Plot(par.resize_stride);
 
  }
 
  i++;
 
  return mesh.getTime();
 
}
 

	
 

	
 

	
 
  /* Called if a cell is clicked */
 
void Cell::OnClick(QMouseEvent *e){}
 

	
 

	
 
  /* Custom message handler - Default appends a newline character to the end of each line. */ 
 
void vlMessageOutput(QtMsgType type, const char *msg)
 
{
 
  switch (type) {
 
  case QtDebugMsg:
 
    //fprintf(stderr, "Debug: %s\n", msg);
 
    cerr << msg << flush;
 
    break;
 
  case QtWarningMsg:
 
    //fprintf(stderr, "Warning: %s\n", msg);
 
    cerr << "Warning: " << msg << flush;
 
    break;
 
  case QtCriticalMsg:
 
    fprintf(stderr, "Critical: %s\n", msg);
 
    cerr << "Critical: " << msg << flush;
 
    break;
 
  case QtFatalMsg:
 
    //fprintf(stderr, "Fatal: %s\n", msg);
 
    cerr << "Fatal: " << msg << flush;
 
    abort();
 
  }
 
}
 

	
 

	
 
Parameter par;
 

	
 
int main(int argc,char **argv) {
 

	
 
  try {
 
    int c;
 
    char *leaffile=0;
 
    char *modelfile=0;
 

	
 
    while (1) {
 

	
 
      //int this_option_optind = optind ? optind : 1;
 
      int option_index = 0;
 
      static struct option long_options[] = {
 
	{"batch", no_argument, NULL, 'b'},
 
	{"leaffile", required_argument, NULL, 'l'},
 
	{"model", required_argument, NULL, 'm'} 
 
      };
 

	
 
      // short option 'p' creates trouble for non-commandline usage on MacOSX. Option -p changed to -P (capital)
 
      static char *short_options = "blm";
 
      c = getopt_long (argc, argv, "bl:m:",
 
		       long_options, &option_index);
 
      if (c == -1)
 
	break;
 

	
 

	
 
      if (c==0) {
 
	printf ("option %s", long_options[option_index].name);
 
	if (optarg)
 
	  printf (" with arg %s", optarg);
 
	printf ("\n");
 

	
 
	c = short_options[option_index];
 
      }
 

	
 
      switch (c) {
 
      case 'b':
 
	cerr << "Running in batch mode\n";
 
	batch=true;
 
	break;
 

	
 
      case 'l':
 
	leaffile=strdup(optarg);
 
	if (!leaffile) {
 
	  throw("Out of memory");
 
	}
 
	printf("Reading leaf state file '%s'\n", leaffile);
 
	break;
 

	
 
      case 'm':
 
	modelfile=strdup(optarg);
 
	if (!modelfile) {
 
	  throw("Out of memory");
 
	}
 
	break;
 

	
 
      case '?':
 
	break;
 

	
 
      default:
 
	printf ("?? getopt returned character code 0%o ??\n", c);
 
      }
 
    }
 

	
 

	
 
    if (optind < argc) {
 
      printf ("non-option ARGV-elements: ");
 
      while (optind < argc)
 
	printf ("%s ", argv[optind++]);
 
      printf ("\n");
 
    }
 

	
 
    bool useGUI = !batch;
 
    qInstallMsgHandler(vlMessageOutput); // custom message handler
 
    QApplication app(argc,argv,useGUI);
 

	
 

	
 

	
 
    QPalette tooltippalette = QToolTip::palette();
 
    QColor transparentcolor = QColor(tooltippalette.brush(QPalette::Window).color());
 

	
 
    tooltippalette.setBrush (QPalette::Window, QBrush (transparentcolor) );
 
    QToolTip::setPalette( tooltippalette );
 

	
 
    QGraphicsScene canvas(0,0,8000,6000);
 

	
 

	
 
    if (useGUI) {
 
      main_window=new Main(canvas, mesh);
 
      if ( QApplication::desktop()->width() > ((Main *)main_window)->width() + 10
 
	   && QApplication::desktop()->height() > ((Main *)main_window)->height() +30 ) {
 

	
 
	((Main *)main_window)->show();
 
	((Main *)main_window)->resize( ((Main *)main_window)->sizeHint());
 
      } else {
 
	((Main *)main_window)->showMaximized();
 
      }
 
      
 
      // show "About" window at start up
 
      ((Main *)main_window)->about();
 
    } else {
 
      main_window=new MainBase(canvas, mesh);
 
    }
 

	
 
    canvas.setSceneRect(QRectF());
 
    if (!batch) {
 
      QObject::connect( qApp, SIGNAL(lastWindowClosed()), qApp, SLOT(quit()) );
 
    }
 

	
 
    //    main_window->Init(leaffile);
 

	
 
    // Install model or read catalogue of models
 
    ModelCatalogue model_catalogue(&mesh, main_window,modelfile);
 

	
 

	
 
    if (useGUI)
 
      model_catalogue.PopulateModelMenu();
 
    model_catalogue.InstallFirstModel();
 
    
 
    
 

	
 
    /*    Cell::SetMagnification(1);
 
	  Cell::setOffset(0,0);
 

	
 
	  main_window->FitLeafToCanvas();
 

	
 
	  main_window->Plot();
 
    */
 
    if (batch) {
 
      double t=0.;
 
      do {
 
	t = main_window->TimeStep();
 
      } while (t < par.maxt);
 
    } else
 
      return app.exec();
 

	
 
  } catch (const char *message) {
 
    if (batch) { 
 
      cerr << "Exception caught:" << endl;
 
      cerr << message << endl;
 
      abort();
 
    } else {
 
      QString qmess=QString("Exception caught: %1").arg(message);
 
      QMessageBox::critical(0, "Critical Error", qmess);
 
      abort();
 
    }
 
  } catch (ios_base::failure) {
 
    stringstream error_message;
 
    error_message << "I/O failure: " << strerror(errno);
 
    if (batch) {
 
      cerr << error_message.str() <<endl;
 
      cerr << error_message.str().c_str() <<endl;
 
      abort();
 
    } else {
 
      QString qmess(error_message.str().c_str());
 
      QMessageBox::critical(0, "I/O Error", qmess );
 
      abort();
 
    }
 
  }
 
}
 

	
 
/* finis */
src/canvas.cpp
Show inline comments
 
@@ -338,896 +338,896 @@ void FigureEditor::mouseReleaseEvent(QMo
 
	for (NodeSet::iterator i = node_set->begin(); i != node_set->end(); i++) {
 
	  (*i)->SetSAM();
 
	  (*i)->SetBoundary();
 
	}
 

	
 
	// Make cells attached to nodeset part of the boundary
 
	// This is a temporary solution for the following:
 
	//   If a cell attached to a NodeSet divides (with a division plane intersecting the node set), 
 
	//   we must insert a new node into the node set.
 
	// For now, we add a layer of "virtual cells" inbetween. 
 
	list<Cell *> cells_attached_to_nodeset = node_set->getCells();
 
	for ( list<Cell *>::iterator c = cells_attached_to_nodeset.begin(); c != cells_attached_to_nodeset.end(); c++) {
 
	  (*c)->SetBoundary(Cell::SAM);
 
	}
 

	
 

	
 

	
 
#ifdef QDEBUG
 
	qDebug() << "Done CutAwayBelowLine" << endl;
 
#endif
 
	mesh.TestIllegalWalls();
 
	mesh.RepairBoundaryPolygon();
 
#ifdef QDEBUG
 
	qDebug() << "Done RepairBoundaryPolygon" << endl;
 
#endif
 
	mesh.TestIllegalWalls();
 
	mesh.CleanUpWalls();
 
#ifdef QDEBUG
 
	qDebug() << "Done CleanUpWalls" << endl;
 
#endif
 
	mesh.TestIllegalWalls();
 
      }
 

	
 
      dynamic_cast<Main *>(parent())->Plot();
 

	
 
#ifdef QDEBUG
 
      cerr << "NodeSet of cutting line: " << *node_set << endl;
 
#endif
 
    }
 
  } else 
 
    if (e->button()==Qt::RightButton) {
 

	
 
      if (intersection_line /* && !angle_line*/) {
 

	
 
	QPointF p = mapToScene(e->pos());
 
	QPointF sp = intersection_line->line().p1();
 

	
 
	viewport()->setMouseTracking( TRUE );
 
      } 
 
    }
 
}
 

	
 

	
 
// returns a vector of pointer to cells colliding with intersection line
 
vector <CellItem *> FigureEditor::getIntersectedCells(void)
 
{ 
 
  vector <CellItem *> colliding_cells;
 

	
 
  QList<QGraphicsItem *> l = intersection_line->collidingItems( );
 

	
 
#ifdef QDEBUG
 
  qDebug() <<  "l.size() = " << l.size() << endl;
 
#endif
 

	
 
  for (QList<QGraphicsItem *>::Iterator it=l.begin(); it!=l.end(); ++it) {
 

	
 
#ifdef QDEBUG
 
    qDebug() << typeid(**it).name() << endl;
 
#endif
 

	
 
    if ( !strcmp(typeid(**it).name(),"8CellItem") ) {
 
      colliding_cells.push_back(dynamic_cast<CellItem *>(*it));
 
    }
 
  }
 

	
 
  delete intersection_line;
 
  intersection_line = 0;
 
  return colliding_cells;
 
}
 

	
 
void FigureEditor::FullRedraw(void)
 
{
 
  QList<QRectF> rl;
 
  rl << sceneRect();
 
  updateScene(rl);   
 
}
 

	
 

	
 
NodeItem *FigureEditor::selectedNodeItem(QList<QGraphicsItem *> graphicItems) const
 
{
 
  NodeItem *nodeItem = 0;
 
  // graphicItems is a list of the QgraphicItems under the mouse click event 
 
  QList<QGraphicsItem *>::Iterator it = graphicItems.begin();
 
  for (; it != graphicItems.end(); ++it) {
 
    if ( !strcmp(typeid(**it).name(),"8NodeItem")) {
 
      // the object under the mouse click is a Nodeitem
 
      nodeItem = dynamic_cast<NodeItem *>(*it);
 
      // indicate we've selected it
 
      nodeItem->setBrush(dark_red);
 
      break;
 
    }
 
  }
 
  return nodeItem;
 
}
 

	
 

	
 
void FigureEditor::insertNode(QPointF p)
 
{
 
  Node *node = new Node(p.x(), p.y(), 0);
 
  mesh.AddNode(node);
 
  scene()->clearSelection();
 
  dynamic_cast<Main *>(parent())->Plot();
 
  FullRedraw();
 
#ifdef QDEBUG  
 
  qDebug() << "Node: " << p << endl;
 
#endif
 
}
 

	
 
static uint mainCount = 0;
 

	
 
Main::Main(QGraphicsScene& c, Mesh &m, QWidget* parent, const char* name, Qt::WindowFlags f) :
 
  Q3MainWindow(parent,name,f),
 
  MainBase(c,m),
 
  mesh(m)
 
{
 
  editor = new FigureEditor(canvas,mesh, this);
 

	
 
#ifdef QDEBUG
 
  qDebug() << "Interactive = " << editor->isEnabled();
 
#endif
 

	
 
  working_dir = 0;
 
  QObject::connect( editor, SIGNAL(MousePressed()), this, SLOT(PauseIfRunning()));
 
  QObject::connect( editor, SIGNAL(MouseReleased()), this, SLOT(ContIfRunning()));
 
  QMenuBar* menu = menuBar();
 

	
 
  Q3PopupMenu* file = new Q3PopupMenu( menu );
 

	
 
  file->insertItem("&Read leaf", this, SLOT(readStateXML()));
 
  file->insertItem("&Save leaf", this, SLOT(saveStateXML()));
 
  file->insertItem("Snapshot", this, SLOT(snapshot()), Qt::CTRL+Qt::SHIFT+Qt::Key_S);
 

	
 
  file->insertSeparator();
 
  file->insertItem("Read next leaf", this, SLOT(readNextStateXML()), Qt::Key_PageDown);
 
  file->insertItem("Read previous leaf", this, SLOT(readPrevStateXML()), Qt::Key_PageUp);
 
  file->insertItem("Read last leaf", this, SLOT(readLastStateXML()), Qt::Key_End);
 
  file->insertItem("Read first leaf", this, SLOT(readFirstStateXML()), Qt::Key_Home);
 
  file->insertItem("Export cell data", this, SLOT(exportCellData()));
 

	
 
  file->insertSeparator();
 
  file->insertItem("&Print...", this, SLOT(print()), Qt::CTRL+Qt::Key_P);
 
  file->insertSeparator();
 
  file->insertItem("E&xit", qApp, SLOT(quit()), Qt::CTRL+Qt::Key_Q);
 
  menu->insertItem("&File", file);
 

	
 
  Q3PopupMenu* edit = new Q3PopupMenu( menu );
 
  edit->insertItem("Reset Chemicals and Transporters", this, SLOT( CleanMesh()), Qt::CTRL+Qt::Key_R );
 
  edit->insertItem("Reset Chemicals", this, SLOT( CleanMeshChemicals()) );
 
  edit->insertItem("Reset Transporters", this, SLOT( CleanMeshTransporters()) );
 
  edit->insertItem("Randomize PIN1 Transporters", this, SLOT( RandomizeMesh()) );
 
  edit->insertItem("Cut away SAM", this, SLOT( CutSAM() ));
 
  menu->insertItem("&Edit", edit);
 

	
 
  run = new Q3PopupMenu( menu );
 
  running = false;
 
  paused_id = run->insertItem("&Simulation paused", this, SLOT(togglePaused()), Qt::Key_S);
 
  run->setItemChecked(paused_id, FALSE);
 

	
 
  menu->insertItem("&Run", run);
 

	
 
  view = new Q3PopupMenu( menu );
 
  view->insertItem("&Zoom in", this, SLOT(zoomIn()), Qt::CTRL+Qt::Key_Equal);
 
  view->insertItem("Zoom &out", this, SLOT(zoomOut()), Qt::CTRL+Qt::Key_Minus);
 
  view->insertSeparator();
 
  com_id = view->insertItem("Show cell &centers", this, SLOT(toggleShowCellCenters()));
 
  view->setItemChecked(com_id, FALSE);
 

	
 
  mesh_id = view->insertItem("Show &nodes", this, SLOT(toggleShowNodes()), Qt::CTRL+Qt::SHIFT+Qt::Key_N);
 
  view->setItemChecked(mesh_id, TRUE);
 
  node_number_id = view->insertItem("Show node numbers", this, SLOT(toggleNodeNumbers()), Qt::CTRL+Qt::SHIFT+Qt::Key_M);
 
  view->setItemChecked(node_number_id, FALSE);
 
  cell_number_id = view->insertItem("Show cell numbers", this, SLOT(toggleCellNumbers()));
 
  view->setItemChecked(cell_number_id, FALSE);
 
  hide_cells_id = view->insertItem("Hide cells", this, SLOT(toggleHideCells()));
 
  view->setItemChecked(hide_cells_id, FALSE);
 
  border_id = view->insertItem("Show &border cells", this, SLOT(toggleShowBorderCells()));
 
  view->setItemChecked(border_id, FALSE);
 
  cell_axes_id = view->insertItem("Show cell &axes", this, SLOT(toggleCellAxes()));
 
  cell_strain_id = view->insertItem("Show cell &strain", this, SLOT(toggleCellStrain()));
 
  view->setItemChecked(cell_axes_id, FALSE);
 
  fluxes_id = view->insertItem("Show &fluxes", this, SLOT(toggleShowFluxes()));
 
  view->setItemChecked(fluxes_id, FALSE);
 
  cell_walls_id = view->insertItem("Show transporters", this, SLOT(toggleShowWalls()));
 
  view->setItemChecked(cell_walls_id, FALSE);
 
 // apoplasts_id = view->insertItem("Show apoplasts", this, SLOT(toggleShowApoplasts()));
 
 // view->setItemChecked(apoplasts_id, FALSE);
 
  view->insertSeparator();
 
  only_boundary_id = view->insertItem("Show only leaf &boundary", this, SLOT(toggleLeafBoundary()));
 
  view->insertSeparator();
 
  movie_frames_id = view->insertItem("Start saving movie &frames", this, SLOT(toggleMovieFrames()));
 
  view->setItemChecked(movie_frames_id, par.movie);
 

	
 
  view->setItemChecked(only_boundary_id, FALSE);
 
  menu->insertItem("&View", view);
 

	
 

	
 
  options = new Q3PopupMenu( menu );
 
  dyn_cells_id = options->insertItem("Cell growth", this, SLOT(toggleDynCells()));
 
  options->setItemChecked(dyn_cells_id, true);
 

	
 
  options->insertItem("Edit &parameters", this, SLOT(EditParameters()), Qt::CTRL+Qt::Key_E);
 

	
 
  rotation_mode_id = options->insertItem("Rotate leaf", this, SLOT(EnterRotationMode()), Qt::CTRL + Qt::SHIFT + Qt::Key_R);
 
  options->setItemChecked(rotation_mode_id, false);
 

	
 
  menu->insertItem("&Options",options);
 

	
 
  // Menu of models
 
  modelmenu = new QMenu( menu );
 
  menu->insertItem("&Models", modelmenu);
 

	
 

	
 
  menu->insertSeparator();
 

	
 
  helpmenu = new Q3PopupMenu( menu );
 
  tooltips_id = helpmenu->insertItem("Show Cell&Info", this, SLOT(Refresh()));
 
  helpmenu->setItemChecked(tooltips_id, true);
 
  helpmenu->insertSeparator();
 
    //helpmenu->insertSeparator();
 
  helpmenu->insertItem("&LICENSE", this, SLOT(gpl()) );
 
  helpmenu->insertItem("About", this, SLOT(about()) ); //, Key_F1);
 
	
 
	menu->insertItem("&Help",helpmenu);
 
  statusBar();
 
  setCentralWidget(editor);
 
  printer = 0;
 
  init();
 

	
 
  // Start timer which repetitively invokes
 
  // a simulation time step
 
  timer = new QTimer( this );
 
  connect( timer, SIGNAL(timeout()), SLOT(TimeStepWrap()) );
 

	
 
  stopSimulation();
 
  statusBar()->addWidget(new QLabel("Ready."));
 
  setCaption(caption);
 
  gifanim = 0;
 

	
 
  infobar = new InfoBar();
 
  addDockWindow(infobar);
 

	
 
}
 

	
 
void Main::RefreshInfoBar(void)
 
{
 
  infobar->SetText(mesh.ModelID());
 
}
 

	
 

	
 
void Main::UserMessage(QString message, int timeout)
 
{
 
  statusBar()->showMessage(message, timeout);
 
}
 

	
 

	
 
void Main::init()
 
{
 
  clear();
 

	
 
  static int r=24;
 
  srand(++r);
 

	
 
  mainCount++;
 
}
 

	
 
Main::~Main()
 
{
 
  delete printer;
 
  if ( !--mainCount ) {
 
  }
 
  //EndGifAnim();
 
}
 

	
 
void Main::newView()
 
{
 
  // Open a new view... have it delete when closed.
 
  Main *m = new Main(canvas, mesh, 0, 0, Qt::WDestructiveClose);
 
  qApp->setMainWidget(m);
 
  m->show();
 
  qApp->setMainWidget(0);
 
}
 

	
 

	
 
void Main::EditParameters()
 
{
 

	
 
  ParameterDialog *pardial = new ParameterDialog(this, "stridediag");
 

	
 
  // Make sure the values in the parameter dialog are updated after a file is read 
 
  // each method changing the parameters (reading XML or PAR files) should
 
  // emit this signal
 
  QObject::connect(   this, SIGNAL( ParsChanged() ), pardial, SLOT( Reset() ) );
 
}
 

	
 
void Main::savePars()
 
{
 

	
 
  stopSimulation();
 

	
 
  Q3FileDialog *fd = new Q3FileDialog( this, "file dialog", TRUE );
 
  fd->setMode( Q3FileDialog::AnyFile );
 
  fd->setFilter( "Parameter files (*.par)");
 
  fd->setDir(par.datadir);
 

	
 
  QString fileName;
 
  if ( fd->exec() == QDialog::Accepted ) {
 
    fileName = fd->selectedFile();
 
    ofstream parfile((const char *)fileName);
 
    par.Write(parfile);
 
  }
 

	
 
  startSimulation();
 
}
 

	
 
void Main::readPars()
 
{
 

	
 
  stopSimulation();
 

	
 
  Q3FileDialog *fd = new Q3FileDialog( this, "file dialog", TRUE );
 
  fd->setMode( Q3FileDialog::ExistingFile );
 
  fd->setFilter( "Parameter files (*.par)");
 
  fd->setDir(par.datadir);
 

	
 
  QString fileName;
 
  if ( fd->exec() == QDialog::Accepted ) {
 
    fileName = fd->selectedFile();
 
    par.Read((const char *)fileName);
 
  }
 

	
 
  emit ParsChanged();
 
}
 

	
 

	
 
void Main::saveStateXML()
 
{
 

	
 
  stopSimulation();
 
  Q3FileDialog *fd = new Q3FileDialog( this, "file dialog", TRUE );
 
  fd->setMode( Q3FileDialog::AnyFile );
 
  fd->setFilter( "LeafML files (*.xml)");
 
  fd->setDir(par.datadir);
 
  QString fileName;
 

	
 
  if ( fd->exec() == QDialog::Accepted ) {
 
    fileName = fd->selectedFile();
 

	
 
    // extract extension from filename
 
    QFileInfo fi(fileName);
 
    QString extension = fi.suffix();
 
    
 
    if (extension.isEmpty()) {
 
      extension = "xml";
 
      fileName += ".";
 
      fileName += extension;
 
    }
 
    
 
    
 
    if ( QFile::exists( fileName ) &&
 
	 QMessageBox::question(
 
			       this,
 
			       tr("Overwrite File? -- Leaf Growth"),
 
			       tr("A file called %1 already exists."
 
				  " Do you want to overwrite it?")
 
			       .arg( fileName ),
 
			       tr("&Yes"), tr("&No"),
 
			       QString::null, 1, 1 ) ) {
 
      return saveStateXML();
 

	
 
    } else {
 

	
 
      mesh.XMLSave((const char *)fileName, XMLSettingsTree());
 
      QString status_message;
 
      status_message = QString("Wrote LeafML to %1").arg(fileName);
 
      cerr << status_message.toStdString() << endl;
 
      cerr << status_message.toStdString().c_str() << endl;
 
      statusBar()->showMessage(status_message);
 
    }
 
  }
 
}
 

	
 

	
 

	
 
void Main::snapshot()
 
{
 

	
 
#ifdef QDEBUG
 
  qDebug() << "Supported Image Formats: " << QImageWriter::supportedImageFormats() << endl;
 
#endif
 

	
 
  stopSimulation();
 
  Q3FileDialog *fd = new Q3FileDialog( this, "Save snapshot", TRUE );
 
  fd->setDir(par.datadir);
 
  fd->setMode( Q3FileDialog::AnyFile );
 

	
 
  QString supported_file_formats = " *.pdf";
 
  foreach (QString format, QImageWriter::supportedImageFormats()){
 
    supported_file_formats += (" *." + format);
 
  }
 

	
 
  fd->setFilter("Image files (" + supported_file_formats + " )");
 

	
 
  QString fileName;
 
  if ( fd->exec() == QDialog::Accepted ) {
 
    fileName = fd->selectedFile();
 
    
 
    // extract extension from filename
 
    QFileInfo fi(fileName);
 
    QString extension = fi.suffix();
 
    
 
    if (extension.isEmpty()) {
 
      extension = "png";
 
      fileName += ".";
 
      fileName += extension;
 
    }
 
    
 
    
 
    if ( QFile::exists( fileName ) &&
 
	 QMessageBox::question(
 
			       this,
 
			       tr("Overwrite file? -- Cell data export"),
 
			       tr("A file called %1 already exists."
 
				  " Do you want to overwrite it?").arg( fileName ),
 
			       QMessageBox::Yes, QMessageBox::No 
 
			       ) == QMessageBox::No
 
	 ) {
 
      
 
      return snapshot();
 
      
 
    } else {
 

	
 
      // Save bitmaps at 1024x768
 
      QString status_message;
 
      if (Save((const char *)fileName, extension, 1024, 768)==0) {
 
	status_message = QString("Wrote snapshot to %1").arg(fileName);
 
      } else {
 
	status_message = QString("Error writing snapshot to %1").arg(fileName);
 
      }
 
      cerr << status_message.toStdString() << endl;
 
      cerr << status_message.toStdString().c_str() << endl;
 
      statusBar()->showMessage(status_message);
 

	
 
    }
 
  }
 
}
 

	
 

	
 

	
 
void Main::readPrevStateXML()
 
{
 

	
 
  // if we have already read a file, read the next file
 
  if (!currentFile.isEmpty() && working_dir) {
 
    QString next_file;
 

	
 
    QStringList xml_files = working_dir->entryList("*.xml");
 
    QString currentFile_nopath = currentFile.section( '/', -1 );
 
    QString currentFile_path = currentFile.section( '/', 0, -2 );
 

	
 
    QList<QString>::iterator f = xml_files.find( currentFile_nopath );
 

	
 
    if (f == xml_files.end()) {
 
      return;
 
    }
 

	
 
    if (f==xml_files.begin()) {
 
      QMessageBox mb( "Read previous leaf",
 
		      "No more files",
 
		      QMessageBox::Information,
 
		      QMessageBox::Ok | QMessageBox::Default,
 
		      QMessageBox::NoButton,
 
		      QMessageBox::NoButton);
 
      mb.exec();
 
      return;
 
    }
 
    next_file = *(--f);
 
    next_file = currentFile_path+"/"+next_file;
 

	
 
    readStateXML((const char *)next_file);
 

	
 
  }
 
}
 

	
 
int Main::readStateXML(const char *filename, bool geometry, bool pars, bool simtime)
 
{
 

	
 
  try {
 
    xmlNode *settings;
 
    mesh.XMLRead((const char *)filename, &settings, geometry, pars, simtime);
 
#ifdef QDEBUG
 
    qDebug() << "Reading done."<< endl;
 
#endif
 
    XMLReadSettings(settings);
 
    xmlFree(settings);
 
    Cell::SetMagnification(1);
 
    Cell::setOffset(0,0);
 

	
 
    FitLeafToCanvas();
 
    
 
    currentFile =  QString(filename);
 

	
 
    Plot();
 
    QString status_message = QString("Successfully read leaf from file %1. Time is %2 h.").arg(currentFile).arg(mesh.getTimeHours().c_str());
 
    cerr << status_message.toStdString() << endl;
 
    cerr << status_message.toStdString().c_str() << endl;
 
    setCaption(caption_with_file.arg(filename));
 
    statusBar()->message(status_message);
 
    emit ParsChanged();
 
#ifdef QDEBUG
 
    qDebug() << "Done. Returning 0." << endl;
 
#endif
 
    return 0;
 
  } catch (const char *error_message) {
 
    QMessageBox mb( "Read leaf from XML file",
 
		    QString(error_message),
 
		    QMessageBox::Critical,
 
		    QMessageBox::Ok | QMessageBox::Default,
 
		    Qt::NoButton,
 
		    Qt::NoButton);
 
    mb.exec();
 
    return 1;
 
  }
 
}
 

	
 

	
 
void Main::readNextStateXML()
 
{
 

	
 
  // if we have already read a file, read the next file
 
  if (!currentFile.isEmpty() && working_dir) {
 
    QString next_file;
 

	
 
    QStringList xml_files = working_dir->entryList("*.xml");
 
    QString currentFile_nopath = currentFile.section( '/', -1 );
 
    QString currentFile_path = currentFile.section( '/', 0, -2 );
 

	
 

	
 
    QList<QString>::iterator f = xml_files.find( currentFile_nopath );
 

	
 
    if (f == xml_files.end()) {
 
      return;
 
    }
 

	
 
    ++f;
 
    if (f==xml_files.end()) {
 
      QMessageBox mb( "Read next leaf",
 
		      "No more files",
 
		      QMessageBox::Information,
 
		      QMessageBox::Ok | QMessageBox::Default,
 
		      QMessageBox::NoButton,
 
		      QMessageBox::NoButton);
 
      mb.exec();
 
      return;
 
    }
 
    next_file = *f;
 
    next_file = currentFile_path+"/"+next_file;
 

	
 
    readStateXML((const char*)next_file);
 
  }
 
}
 

	
 
void Main::readLastStateXML()
 
{
 

	
 
  // if we have already read a file, read the next file
 
  if (!currentFile.isEmpty() && working_dir) {
 
    QString next_file;
 

	
 
    QStringList xml_files = working_dir->entryList("*.xml");
 
    QString currentFile_nopath = currentFile.section( '/', -1 );
 
    QString currentFile_path = currentFile.section( '/', 0, -2 );
 

	
 

	
 
    next_file = xml_files.back();
 

	
 
    next_file = currentFile_path+"/"+next_file;
 

	
 
    readStateXML((const char*)next_file);
 
  }
 
}
 

	
 

	
 
void Main::readFirstStateXML()
 
{
 

	
 
  // if we have already read a file, read the next file
 
  if (!currentFile.isEmpty() && working_dir) {
 
    QString next_file;
 

	
 
    QStringList xml_files = working_dir->entryList("*.xml");
 
    QString currentFile_nopath = currentFile.section( '/', -1 );
 
    QString currentFile_path = currentFile.section( '/', 0, -2 );
 

	
 

	
 
    next_file = xml_files.front();
 

	
 
    next_file = currentFile_path+"/"+next_file;
 

	
 
    readStateXML((const char*)next_file);
 
  }
 
}
 

	
 
QDir Main::GetLeafDir(void) {
 
   
 
  QDir LeafDir(QApplication::applicationDirPath()); 
 
  QStringList plugin_filters; // filter for plugins, i.e "*.dll", "*.dylib"
 
  
 
  
 
#if defined(Q_OS_WIN) 
 
  if (LeafDir.dirName().toLower() =="debug" 
 
      ||LeafDir.dirName().toLower() =="release") 
 
    LeafDir.cdUp(); 
 
  //plugin_filters << "*.dll";
 
#elif defined(Q_OS_MAC) 
 
  if (LeafDir.dirName() =="MacOS"){ 
 
    LeafDir.cdUp(); 
 
    LeafDir.cdUp(); 
 
    LeafDir.cdUp(); 
 
  }
 
  
 
#endif
 
  // for all OS-es. Move from "bin" directory to root application folder.
 
  if (LeafDir.dirName() == "bin") {
 
    LeafDir.cdUp();
 
  }
 

	
 
  LeafDir.cd("data/leaves");
 
  /* if (!LeafDir.cd("data/leaves")) {
 
    QString status_message = QString("No directory data/leaves");
 
    statusBar()->showMessage(status_message);
 
    
 
    return LeafDir;
 
  } 
 
  */
 
  return LeafDir;
 
      
 
}
 
 
 

	
 
void Main::readStateXML()
 
{
 

	
 
  //  extern Mesh mesh;
 

	
 
  stopSimulation();
 
#ifdef QDEBUG
 
  qDebug() << "Trying to open an OptionFileDialog" << endl;
 
#endif
 
  OptionFileDialog *fd = new OptionFileDialog( this, "read dialog", TRUE );
 
  fd->setMode( OptionFileDialog::ExistingFile );
 
  fd->setFilter( "LeafML files (*.xml)");
 
  if (working_dir) {
 
    fd->setDir(*working_dir);
 
  } else {
 
    fd->setDir(par.datadir);
 
  }
 
  QString fileName;
 
  if ( fd->exec() == QDialog::Accepted ) {
 

	
 
    fileName = fd->selectedFile();
 
    if (working_dir) {
 
      delete working_dir;
 
    }
 
    working_dir = fd->dir();
 

	
 
    if (readStateXML((const char *)fileName,fd->readGeometryP(), fd->readParametersP()) )
 
      return readStateXML(); // user can try again
 
  }
 
}
 

	
 

	
 
void Main::clear()
 
{
 
  editor->clear();
 
}
 

	
 
void Main::about()
 
{
 
  static QMessageBox* about = new QMessageBox
 
    ( "VirtualLeaf V1.0.1",
 
      "<h3>VirtualLeaf V1.0.1</h3>\
 
       <p>\
 
         An Open Source framework for cell-based modeling of plant\
 
         tissue growth and development.\
 
       </p>\
 
       <p>(c) 2005-2008, Roeland Merks <i>et al.</i>\
 
         <a href=\"http://www.psb.vib-ugent.be\">VIB Department Plant Systems Biology</a>,\
 
         Ghent, Belgium.\
 
       </p>\
 
       <p>(c) 2008-2010,\
 
         <a href=\"http://www.cwi.nl/~merks\">Roeland Merks <i>et al.</i></a>\
 
         <a href=\"http://www.cwi.nl\">Centrum Wiskunde & Informatica (CWI)</a> and\
 
         <a href=\"http://www.ncsb.nl\"> Netherlands Consortium for Systems Biology (NCSB)</a>,\
 
         Amsterdam, the Netherlands.\
 
       </p>\
 
       <p>\
 
         VirtualLeaf is free software: you can redistribute it and/or\
 
         modify it under the terms of the GNU General Public License as\
 
         published by the Free Software Foundation, either version 3 of the\
 
         License, or (at your option) any later version.\
 
       </p>\
 
       <p>\
 
         If you use this code for your projects, please cite our paper in\
 
         <a href=\"http://www.plantphysiol.org\">Plant Physiology</a>, &lsquo;\
 
         Roeland M. H. Merks, Michael Guravage, Dirk Inz&eacute;, and Gerrit T.S. Beemster,\
 
         <a href=\"http://www.plantphysiol.org/cgi/reprint/155/2/656.pdf\">\
 
         VirtualLeaf: an Open Source framework for cell-based modeling of plant tissue growth and development</a>,<br>\
 
         Plant Physiology 2011: 155:656-666.\
 
       </p>\
 
       <p>\
 
         Please share your model plugins and extensions at\
 
         <a href=\"http://virtualleaf.googlecode.com\">http://virtualleaf.googlecode.com</a>.\
 
       </p>",
 
      QMessageBox::Information, 1, 0, 0, this, 0, FALSE );
 
  about->setButtonText( 1, "Dismiss" );
 
  about->setIconPixmap(QPixmap( leaficon_small ));
 
  about->show();
 
}
 

	
 

	
 
void Main::gpl()
 
{
 
  static QMessageBox* gpl = new QMessageBox ( "GPL License", "", 
 
      QMessageBox::Information, 1, 0, 0, this, 0, FALSE );
 

	
 
  QDir docDir(QApplication::applicationDirPath());
 
  docDir.cd("../doc"); // Where Linux expects gpl3.txt
 
  QString path = docDir.filePath("gpl3.txt");
 
  if (!docDir.exists("gpl3.txt")){
 
    docDir = QApplication::applicationDirPath();
 
    docDir.cd("doc"); // Where Windows expects gpl3.txt
 
    path = docDir.filePath("gpl3.txt");
 
  }
 

	
 
  // At this point path points either to the linux variant, which
 
  // exists, or the windows variant, which may exist. Testing the
 
  // ifstream object will determine whether we've found gpl3.txt.
 

	
 
  std::ifstream file(path.toStdString().c_str());
 
  std::string str;
 

	
 
  if (file) {
 
    file.seekg(0, std::ios::end);   
 
    str.reserve(file.tellg());
 
    file.seekg(0, std::ios::beg);
 

	
 
    str.assign((std::istreambuf_iterator<char>(file)),
 
	       std::istreambuf_iterator<char>());
 

	
 
    gpl->setDetailedText(QString(str.c_str()));
 
  }
 

	
 
  gpl->setText(QString( "<h3>GNU GENERAL PUBLIC LICENSE</h3>"
 
			"<p>Version 3, 29 June 2007</p>"
 
			"<p>Copyright &copy; 2007 Free Software Foundation, Inc. "
 
			"&lt;<a href=\"http://fsf.org/\">http://fsf.org/</a>&gt;</p><p>"
 
			"Everyone is permitted to copy and distribute verbatim copies "
 
			"of this license document, but changing it is not allowed.</p>"
 
			"<h2>GNU GENERAL PUBLIC LICENSE</h2>"));
 

	
 
  gpl->setButtonText( 1, "Dismiss" );
 
  gpl->show();
 
}
 

	
 
void Main::aboutQt(){
 
  QMessageBox::aboutQt( this, "Virtual Leaf" );
 
}
 

	
 
void Main::toggleShowCellCenters()
 
{
 
  Plot();
 
}
 

	
 
void Main::toggleShowWalls()
 
{
 
  Plot();
 
}
 

	
 
void Main::toggleShowApoplasts()
 
{
 
  Plot();
 
}
 

	
 
void Main::toggleShowNodes()
 
{
 
  Plot();
 
}
 

	
 
void Main::toggleNodeNumbers(void)
 
{
 
  Plot();
 
}
 

	
 
void Main::toggleCellNumbers(void)
 
{
 
  Plot();
 
}
 

	
 
void Main::toggleCellAxes(void)
 
{
 
  Plot();
 
}
 

	
 
void Main::toggleCellStrain(void)
 
{
 
  Plot();
 
}
 

	
 
void Main::toggleShowFluxes(void)
 
{
 
  Plot();
 
}
 

	
 
void Main::toggleShowBorderCells()
 
{
 
  Plot();
 
}
 

	
 
void Main::toggleHideCells(void)
 
{
 
  Plot();
 
  editor->FullRedraw();
 
}
 

	
 
void Main::toggleMovieFrames(){}
 

	
 
void Main::toggleLeafBoundary(){}
 

	
 
void Main::toggleDynCells() {}
 

	
 
void Main::startSimulation(void)
 
{
 
  timer->start( 0 );
 
  statusBar()->message("Simulation started");
 
  running = true;
 
}
 

	
 
void Main::stopSimulation(void)
 
{
 
  timer->stop();
 
  cerr << "Stopping simulation" << endl;
 
  statusBar()->message("Simulation paused");
 
  running = false;
 
}
 

	
 
void Main::togglePaused()
 
{
 
  bool s = run->isItemChecked(paused_id);
 
  if (s) {
 
    cerr << "Calling start simulation" << endl;
 
    startSimulation();
 
  } else {
 
    cerr << "Calling stop simulation" << endl;
 
    stopSimulation();
 
  }
 
}
 

	
 
void Main::setFluxArrowSize(int size)
 
{
 
  flux_arrow_size = size/100.;
 
}
 

	
 

	
 
void Main::enlarge()
 
{
 
  canvas.setSceneRect( QRectF( 0,0, canvas.width()*4./3., canvas.height()*4./3.) );
 
}
 

	
 
void Main::shrink()
 
{
 
  canvas.setSceneRect( QRectF( 0,0, canvas.width()*3/4, canvas.height()*3/4) );
 
}
 

	
 

	
 
void Main::scale(double factor)
 
{
 
  QMatrix m = editor->matrix();
 
  m.scale(factor, factor);
 
  editor->setMatrix( m );
 
}
 

	
 
void Main::zoomIn()
 
{
 
  QMatrix m = editor->matrix();
 
  m.scale( 1.1, 1.1 );
 
  editor->setMatrix( m );
 
}
 

	
 
void Main::zoomOut()
src/modelcatalogue.cpp
Show inline comments
 
/*
 
 *
 
 *  This file is part of the Virtual Leaf.
 
 *
 
 *  VirtualLeaf is free software: you can redistribute it and/or modify
 
 *  it under the terms of the GNU General Public License as published by
 
 *  the Free Software Foundation, either version 3 of the License, or
 
 *  (at your option) any later version.
 
 *
 
 *  VirtualLeaf is distributed in the hope that it will be useful,
 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
 *  GNU General Public License for more details.
 
 *
 
 *  You should have received a copy of the GNU General Public License
 
 *  along with the Virtual Leaf.  If not, see <http://www.gnu.org/licenses/>.
 
 *
 
 *  Copyright 2010 Roeland Merks.
 
 *
 
 */
 

	
 
#include <string>
 
#include "modelcatalogue.h"
 
#include <QVariant>
 

	
 
static const std::string _module_id("$Id$");
 

	
 
ModelCatalogue::ModelCatalogue(Mesh *_mesh, MainBase *_mainwin, const char *model=0) {
 
  mesh = _mesh;
 
  mainwin = _mainwin;
 
  if (model) {
 
    cerr << "Loading model: " << model << endl;
 
    LoadPlugin(model);
 
  } else {
 
    cerr << "Loading all models." << endl;
 
    LoadPlugins();
 
  }
 
}
 

	
 
void ModelCatalogue::LoadPlugins() {
 

	
 
  QDir pluginDir(QApplication::applicationDirPath()); 
 
  QStringList plugin_filters; // filter for plugins, i.e "*.dll", "*.dylib"
 
#if defined(Q_OS_WIN) 
 
  if (pluginDir.dirName().toLower() =="debug" 
 
      ||pluginDir.dirName().toLower() =="release") 
 
    pluginDir.cdUp(); 
 
  plugin_filters << "*.dll";
 
#elif defined(Q_OS_MAC) 
 
  if (pluginDir.dirName() =="MacOS"){ 
 
    pluginDir.cdUp(); 
 
    pluginDir.cdUp(); 
 
    pluginDir.cdUp(); 
 
  } 
 
  plugin_filters << "*.dylib";
 
#endif 
 
  pluginDir.setNameFilters(plugin_filters);
 

	
 
  if (!pluginDir.cd("models")) {
 
    MyWarning::error("Directory 'models' not found!");
 
  }
 

	
 

	
 
  //QVector<SimPluginInterface *> plugins;
 
  foreach (QString fileName, pluginDir.entryList(QDir::Files)){ 
 
    QPluginLoader loader(pluginDir.absoluteFilePath(fileName)); 
 
    if (SimPluginInterface *plugin = 
 
	qobject_cast<SimPluginInterface *>(loader.instance())) {
 
      models.append(plugin); 
 
    } else {
 
      cerr << loader.errorString().toStdString().c_str() << endl;
 
      MyWarning::warning("Could not load model %s: %s",fileName.toStdString().c_str(), loader.errorString().toStdString().c_str());
 
    }
 
  }
 
  if (models.size()==0) {
 
    MyWarning::error("No models could be loaded.");
 
  }
 
}
 

	
 
void ModelCatalogue::LoadPlugin(const char *model) {
 

	
 

	
 
  QDir pluginDir(QApplication::applicationDirPath()); 
 
  QStringList plugin_filters; // filter for plugins, i.e "*.dll", "*.dylib"
 

	
 

	
 
#if defined(Q_OS_WIN) 
 
  if (pluginDir.dirName().toLower() =="debug" 
 
      ||pluginDir.dirName().toLower() =="release") 
 
    pluginDir.cdUp(); 
 
  //plugin_filters << "*.dll";
 
#elif defined(Q_OS_MAC) 
 
  if (pluginDir.dirName() =="MacOS"){ 
 
    pluginDir.cdUp(); 
 
    pluginDir.cdUp(); 
 
    pluginDir.cdUp(); 
 
  } 
 
  //plugin_filters << "*.dylib";
 
#endif
 
  plugin_filters << model;
 
  pluginDir.setNameFilters(plugin_filters);
 

	
 
  if (!pluginDir.cd("models")) {
 
    MyWarning::error("Directory 'models' not found!");
 
  }
 

	
 
  QStringList modelnames=pluginDir.entryList(QDir::Files);
 
  if (modelnames.empty()) {
 
    MyWarning::error("Model %s not found - hint: do not include path in filename.",model);
 
  }
 
  foreach (QString fileName, modelnames){ 
 
    QPluginLoader loader(pluginDir.absoluteFilePath(fileName)); 
 

	
 
    if (SimPluginInterface *plugin = 
 
	qobject_cast<SimPluginInterface *>(loader.instance())) {
 
      models.append(plugin); 
 
      //MyWarning::warning("Successfully loaded model %s",fileName.toStdString().c_str());
 
    } else {
 
      MyWarning::warning("Could not load plugin %s",fileName.toStdString().c_str());
 
    }
 
  }
 
}
 

	
 
void ModelCatalogue::InstallFirstModel() {
 
  InstallModel(models[0]);
 
}
 
void ModelCatalogue::PopulateModelMenu() {
 
  foreach (SimPluginInterface *model, models) {
 
    QAction *modelaction = new QAction(model->ModelID(), (Main *)mainwin); 
 
    QVariant data;
 
    data.setValue(model);
 
    modelaction->setData(data);
 
    ((Main *)mainwin)->modelmenu->addAction(modelaction);
 

	
 
  }
 
  connect(((Main *)mainwin)->modelmenu, SIGNAL(triggered(QAction *)), this, SLOT(InstallModel(QAction *)) );
 
}	
 

	
 
void ModelCatalogue::InstallModel(QAction *modelaction) {
 
  QVariant data = modelaction->data();
 
  SimPluginInterface *model = data.value<SimPluginInterface *>();
 
  cerr << "You chose model " << model->ModelID().toStdString() << "!\n";
 
  cerr << "You chose model " << model->ModelID().toStdString().c_str() << "!\n";
 
  mesh->Clean();
 
  InstallModel(model);
 
}
 

	
 
void ModelCatalogue::InstallModel(SimPluginInterface *plugin) {
 

	
 
  // make sure both main and plugin use the same static datamembers (ncells, nchems...)
 
  mesh->Clean();
 
  plugin->SetCellsStaticDatamembers(CellBase::GetStaticDataMemberPointer());
 

	
 
  mesh->SetSimPlugin(plugin);
 
 
 

	
 
  Cell::SetNChem(plugin->NChem());
 
  plugin->SetParameters(&par);
 
  
 
  if (mainwin) {
 
    
 
    if (!qApp->type()==QApplication::Tty)  // only do this if we are running a GUI
 
      ((Main *)mainwin)->RefreshInfoBar();
 
    
 
    if (plugin->DefaultLeafML().isEmpty()) {
 
      mainwin->Init(0);
 
    } else {
 
      // locate LeafML file
 
      
 
      QDir pluginDir(QApplication::applicationDirPath()); 
 
      QStringList plugin_filters; // filter for plugins, i.e "*.dll", "*.dylib"
 
      
 
      
 
#if defined(Q_OS_WIN) 
 
      if (pluginDir.dirName().toLower() =="debug" 
 
	  ||pluginDir.dirName().toLower() =="release") 
 
	pluginDir.cdUp(); 
 
      //plugin_filters << "*.dll";
 
#elif defined(Q_OS_MAC) 
 
      if (pluginDir.dirName() =="MacOS"){ 
 
	pluginDir.cdUp(); 
 
	pluginDir.cdUp(); 
 
	pluginDir.cdUp(); 
 
      }
 
     
 
#endif
 
      // for all OS-es. Move from "bin" directory to root application folder.
 
      if (pluginDir.dirName() == "bin") {
 
	pluginDir.cdUp();
 
      }
 
      cerr << "pluginDir: " << pluginDir.dirName().toStdString().c_str() << endl;
 
      if (!pluginDir.cd("data/leaves")) {
 
	MyWarning::warning("Directory 'data/leaves' not found! Cannot load LeafML file '%s'. Reverting to standard initial condition now...",plugin->DefaultLeafML().toStdString().c_str());
 
	mainwin->Init(0);
 
      } else {
 
      
 
	if (!pluginDir.exists(plugin->DefaultLeafML())) {
 
	  MyWarning::error("LeafML file '%s' not found - hint: is file in data/leaves folder? Reverting to standard initial condition now...",plugin->DefaultLeafML().toStdString().c_str());
 
	  mainwin->Init(0); 
 
	} else {
 
	  // Initialize simulation using default LeafML file referenced in plugin.
 
	  //mainwin->Init(0);
 
	  cerr << "Default LeafML: " << plugin->DefaultLeafML().toStdString().c_str() << endl;
 
	  mainwin->Init(pluginDir.absFilePath(plugin->DefaultLeafML()).toStdString().c_str());
 
	}
 
      }
 
    }
 
  }
 

	
 
}
src/parameter.cpp
Show inline comments
 
@@ -7,981 +7,981 @@
 
 *  the Free Software Foundation, either version 3 of the License, or
 
 *  (at your option) any later version.
 
 *
 
 *  VirtualLeaf is distributed in the hope that it will be useful,
 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
 *  GNU General Public License for more details.
 
 *
 
 *  You should have received a copy of the GNU General Public License
 
 *  along with the Virtual Leaf.  If not, see <http://www.gnu.org/licenses/>.
 
 *
 
 *  Copyright 2010 Roeland Merks.
 
 *
 
 */
 

	
 
// WARNING: This file is automatically generated by make_parameter_source.pl.
 
// Do not edit. All edits will be discarded.
 

	
 
#include "parameter.h"
 
#include <cstdio>
 
#include <cstring>
 
#include <cstdlib>
 
#include <cerrno>
 
#include <iostream>
 
#include <sstream>
 
#include "output.h"
 
#include "parse.h"
 
#include "xmlwrite.h"
 
#include "warning.h"
 
#include <QLocale>
 
#include <QDir>
 
#include <QStringList>
 

	
 
using namespace std;
 

	
 
static const std::string _module_id("$Id$");
 

	
 
Parameter::Parameter() {
 
  arrowcolor = strdup("white");
 
  arrowsize = 100;
 
  textcolor = strdup("red");
 
  cellnumsize = 1;
 
  nodenumsize = 1;
 
  node_mag = 1.0;
 
  outlinewidth = 1.0;
 
  cell_outline_color = strdup("forestgreen");
 
  resize_stride = 0;
 
  export_interval = 0;
 
  export_fn_prefix = strdup("cell.");
 
  storage_stride = 10;
 
  xml_storage_stride = 500;
 
  datadir = strdup(".");
 
  datadir = AppendHomeDirIfPathRelative(datadir);
 
  T = 1.0;
 
  lambda_length = 100.;
 
  yielding_threshold = 4.;
 
  lambda_celllength = 0.;
 
  target_length = 60.;
 
  cell_expansion_rate = 1.;
 
  cell_div_expansion_rate = 0.;
 
  auxin_dependent_growth = true;
 
  ode_accuracy = 1e-4;
 
  mc_stepsize = 0.4;
 
  mc_cell_stepsize = 0.2;
 
  energy_threshold = 1000.;
 
  bend_lambda = 0.;
 
  alignment_lambda = 0.;
 
  rel_cell_div_threshold = 2.;
 
  rel_perimeter_stiffness = 2;
 
  collapse_node_threshold = 0.05;
 
  morphogen_div_threshold = 0.2;
 
  morphogen_expansion_threshold = 0.01;
 
  copy_wall = true;
 
  source = 0.;
 
  D = new double[15];
 
  D[0] = 0.;
 
  D[1] = 0.0;
 
  D[2] = 0.0;
 
  D[3] = 0.;
 
  D[4] = 0.;
 
  D[5] = 0.;
 
  D[6] = 0.;
 
  D[7] = 0.;
 
  D[8] = 0.;
 
  D[9] = 0.;
 
  D[10] = 0.;
 
  D[11] = 0.;
 
  D[12] = 0.;
 
  D[13] = 0.;
 
  D[14] = 0.;
 
  initval = new double[15];
 
  initval[0] = 0.;
 
  initval[1] = 0.;
 
  initval[2] = 0.;
 
  initval[3] = 0.;
 
  initval[4] = 0.;
 
  initval[5] = 0.;
 
  initval[6] = 0.;
 
  initval[7] = 0.;
 
  initval[8] = 0.;
 
  initval[9] = 0.;
 
  initval[10] = 0.;
 
  initval[11] = 0.;
 
  initval[12] = 0.;
 
  initval[13] = 0.;
 
  initval[14] = 0.;
 
  k1 = 1.;
 
  k2 = 0.3;
 
  r = 1.;
 
  kr = 1.;
 
  km = 1.;
 
  Pi_tot = 1.;
 
  transport = 0.036;
 
  ka = 1;
 
  pin_prod = 0.001;
 
  pin_prod_in_epidermis = 0.1;
 
  pin_breakdown = 0.001;
 
  pin_breakdown_internal = 0.001;
 
  aux1prod = 0.001;
 
  aux1prodmeso = 0.;
 
  aux1decay = 0.001;
 
  aux1decaymeso = 0.1;
 
  aux1transport = 0.036;
 
  aux_cons = 0.;
 
  aux_breakdown = 0.;
 
  kaux1 = 1;
 
  kap = 1;
 
  leaf_tip_source = 0.001;
 
  sam_efflux = 0.0001;
 
  sam_auxin = 10.;
 
  sam_auxin_breakdown = 0;
 
  van3prod = 0.002;
 
  van3autokat = 0.1;
 
  van3sat = 10;
 
  k2van3 = 0.3;
 
  dt = 0.1;
 
  rd_dt = 1.0;
 
  movie = false;
 
  nit = 100000;
 
  maxt = 1000.;
 
  rseed = -1;
 
  constituous_expansion_limit = 16;
 
  vessel_inh_level = 1;
 
  vessel_expansion_rate = 0.25;
 
  d = 0.;
 
  e = 0.;
 
  f = 0.;
 
  c = 0.;
 
  mu = 0.;
 
  nu = 0.;
 
  rho0 = 0.;
 
  rho1 = 0.;
 
  c0 = 0.;
 
  gamma = 0.;
 
  eps = 0.;
 
  k = new double[15];
 
  k[0] = 0.;
 
  k[1] = 0.0;
 
  k[2] = 0.0;
 
  k[3] = 0.;
 
  k[4] = 0.;
 
  k[5] = 0.;
 
  k[6] = 0.;
 
  k[7] = 0.;
 
  k[8] = 0.;
 
  k[9] = 0.;
 
  k[10] = 0.;
 
  k[11] = 0.;
 
  k[12] = 0.;
 
  k[13] = 0.;
 
  k[14] = 0.;
 
  i1 = 0;
 
  i2 = 0;
 
  i3 = 0;
 
  i4 = 0;
 
  i5 = 0;
 
  s1 = strdup("");
 
  s2 = strdup("");
 
  s3 = strdup("");
 
  b1 = false;
 
  b2 = false;
 
  b3 = false;
 
  b4 = false;
 
  dir1 = strdup(".");
 
  dir2 = strdup(".");
 
}
 

	
 
Parameter::~Parameter() {
 
    
 
// destruct parameter object
 
// free string parameter
 
CleanUp();
 
}
 

	
 
void Parameter::CleanUp(void) {
 
  if (arrowcolor) 
 
     free(arrowcolor);
 
  if (textcolor) 
 
     free(textcolor);
 
  if (cell_outline_color) 
 
     free(cell_outline_color);
 
  if (export_fn_prefix) 
 
     free(export_fn_prefix);
 
  if (datadir) 
 
     free(datadir);
 
  if (D) 
 
     free(D);
 
  if (initval) 
 
     free(initval);
 
  if (k) 
 
     free(k);
 
  if (s1) 
 
     free(s1);
 
  if (s2) 
 
     free(s2);
 
  if (s3) 
 
     free(s3);
 
  if (dir1) 
 
     free(dir1);
 
  if (dir2) 
 
     free(dir2);
 

	
 
}
 

	
 
void Parameter::Read(const char *filename) {
 
    
 
  static bool ReadP=false;
 

	
 
  if (ReadP) {
 

	
 
    //throw "Run Time Error in parameter.cpp: Please Read parameter file only once!!";
 
    CleanUp();
 
	
 
  } else
 
    ReadP=true;
 

	
 
  FILE *fp=OpenReadFile(filename);
 

	
 

	
 
  arrowcolor = sgetpar(fp, "arrowcolor", "white", true);
 
  arrowsize = fgetpar(fp, "arrowsize", 100, true);
 
  textcolor = sgetpar(fp, "textcolor", "red", true);
 
  cellnumsize = igetpar(fp, "cellnumsize", 1, true);
 
  nodenumsize = igetpar(fp, "nodenumsize", 1, true);
 
  node_mag = fgetpar(fp, "node_mag", 1.0, true);
 
  outlinewidth = fgetpar(fp, "outlinewidth", 1.0, true);
 
  cell_outline_color = sgetpar(fp, "cell_outline_color", "forestgreen", true);
 
  resize_stride = igetpar(fp, "resize_stride", 0, true);
 
  export_interval = igetpar(fp, "export_interval", 0, true);
 
  export_fn_prefix = sgetpar(fp, "export_fn_prefix", "cell.", true);
 
  storage_stride = igetpar(fp, "storage_stride", 10, true);
 
  xml_storage_stride = igetpar(fp, "xml_storage_stride", 500, true);
 
  datadir = sgetpar(fp, "datadir", ".", true);
 
  datadir = AppendHomeDirIfPathRelative(datadir);
 
  if (strcmp(datadir, "."))
 
    MakeDir(datadir);
 
  T = fgetpar(fp, "T", 1.0, true);
 
  lambda_length = fgetpar(fp, "lambda_length", 100., true);
 
  yielding_threshold = fgetpar(fp, "yielding_threshold", 4., true);
 
  lambda_celllength = fgetpar(fp, "lambda_celllength", 0., true);
 
  target_length = fgetpar(fp, "target_length", 60., true);
 
  cell_expansion_rate = fgetpar(fp, "cell_expansion_rate", 1., true);
 
  cell_div_expansion_rate = fgetpar(fp, "cell_div_expansion_rate", 0., true);
 
  auxin_dependent_growth = bgetpar(fp, "auxin_dependent_growth", true, true);
 
  ode_accuracy = fgetpar(fp, "ode_accuracy", 1e-4, true);
 
  mc_stepsize = fgetpar(fp, "mc_stepsize", 0.4, true);
 
  mc_cell_stepsize = fgetpar(fp, "mc_cell_stepsize", 0.2, true);
 
  energy_threshold = fgetpar(fp, "energy_threshold", 1000., true);
 
  bend_lambda = fgetpar(fp, "bend_lambda", 0., true);
 
  alignment_lambda = fgetpar(fp, "alignment_lambda", 0., true);
 
  rel_cell_div_threshold = fgetpar(fp, "rel_cell_div_threshold", 2., true);
 
  rel_perimeter_stiffness = fgetpar(fp, "rel_perimeter_stiffness", 2, true);
 
  collapse_node_threshold = fgetpar(fp, "collapse_node_threshold", 0.05, true);
 
  morphogen_div_threshold = fgetpar(fp, "morphogen_div_threshold", 0.2, true);
 
  morphogen_expansion_threshold = fgetpar(fp, "morphogen_expansion_threshold", 0.01, true);
 
  copy_wall = bgetpar(fp, "copy_wall", true, true);
 
  source = fgetpar(fp, "source", 0., true);
 
  D = dgetparlist(fp, "D", 15, true);
 
  initval = dgetparlist(fp, "initval", 15, true);
 
  k1 = fgetpar(fp, "k1", 1., true);
 
  k2 = fgetpar(fp, "k2", 0.3, true);
 
  r = fgetpar(fp, "r", 1., true);
 
  kr = fgetpar(fp, "kr", 1., true);
 
  km = fgetpar(fp, "km", 1., true);
 
  Pi_tot = fgetpar(fp, "Pi_tot", 1., true);
 
  transport = fgetpar(fp, "transport", 0.036, true);
 
  ka = fgetpar(fp, "ka", 1, true);
 
  pin_prod = fgetpar(fp, "pin_prod", 0.001, true);
 
  pin_prod_in_epidermis = fgetpar(fp, "pin_prod_in_epidermis", 0.1, true);
 
  pin_breakdown = fgetpar(fp, "pin_breakdown", 0.001, true);
 
  pin_breakdown_internal = fgetpar(fp, "pin_breakdown_internal", 0.001, true);
 
  aux1prod = fgetpar(fp, "aux1prod", 0.001, true);
 
  aux1prodmeso = fgetpar(fp, "aux1prodmeso", 0., true);
 
  aux1decay = fgetpar(fp, "aux1decay", 0.001, true);
 
  aux1decaymeso = fgetpar(fp, "aux1decaymeso", 0.1, true);
 
  aux1transport = fgetpar(fp, "aux1transport", 0.036, true);
 
  aux_cons = fgetpar(fp, "aux_cons", 0., true);
 
  aux_breakdown = fgetpar(fp, "aux_breakdown", 0., true);
 
  kaux1 = fgetpar(fp, "kaux1", 1, true);
 
  kap = fgetpar(fp, "kap", 1, true);
 
  leaf_tip_source = fgetpar(fp, "leaf_tip_source", 0.001, true);
 
  sam_efflux = fgetpar(fp, "sam_efflux", 0.0001, true);
 
  sam_auxin = fgetpar(fp, "sam_auxin", 10., true);
 
  sam_auxin_breakdown = fgetpar(fp, "sam_auxin_breakdown", 0, true);
 
  van3prod = fgetpar(fp, "van3prod", 0.002, true);
 
  van3autokat = fgetpar(fp, "van3autokat", 0.1, true);
 
  van3sat = fgetpar(fp, "van3sat", 10, true);
 
  k2van3 = fgetpar(fp, "k2van3", 0.3, true);
 
  dt = fgetpar(fp, "dt", 0.1, true);
 
  rd_dt = fgetpar(fp, "rd_dt", 1.0, true);
 
  movie = bgetpar(fp, "movie", false, true);
 
  nit = igetpar(fp, "nit", 100000, true);
 
  maxt = fgetpar(fp, "maxt", 1000., true);
 
  rseed = igetpar(fp, "rseed", -1, true);
 
  constituous_expansion_limit = igetpar(fp, "constituous_expansion_limit", 16, true);
 
  vessel_inh_level = fgetpar(fp, "vessel_inh_level", 1, true);
 
  vessel_expansion_rate = fgetpar(fp, "vessel_expansion_rate", 0.25, true);
 
  d = fgetpar(fp, "d", 0., true);
 
  e = fgetpar(fp, "e", 0., true);
 
  f = fgetpar(fp, "f", 0., true);
 
  c = fgetpar(fp, "c", 0., true);
 
  mu = fgetpar(fp, "mu", 0., true);
 
  nu = fgetpar(fp, "nu", 0., true);
 
  rho0 = fgetpar(fp, "rho0", 0., true);
 
  rho1 = fgetpar(fp, "rho1", 0., true);
 
  c0 = fgetpar(fp, "c0", 0., true);
 
  gamma = fgetpar(fp, "gamma", 0., true);
 
  eps = fgetpar(fp, "eps", 0., true);
 
  k = dgetparlist(fp, "k", 15, true);
 
  i1 = igetpar(fp, "i1", 0, true);
 
  i2 = igetpar(fp, "i2", 0, true);
 
  i3 = igetpar(fp, "i3", 0, true);
 
  i4 = igetpar(fp, "i4", 0, true);
 
  i5 = igetpar(fp, "i5", 0, true);
 
  s1 = sgetpar(fp, "s1", "", true);
 
  s2 = sgetpar(fp, "s2", "", true);
 
  s3 = sgetpar(fp, "s3", "", true);
 
  b1 = bgetpar(fp, "b1", false, true);
 
  b2 = bgetpar(fp, "b2", false, true);
 
  b3 = bgetpar(fp, "b3", false, true);
 
  b4 = bgetpar(fp, "b4", false, true);
 
  dir1 = sgetpar(fp, "dir1", ".", true);
 
  if (strcmp(dir1, "."))
 
    MakeDir(dir1);
 
  dir2 = sgetpar(fp, "dir2", ".", true);
 
  if (strcmp(dir2, "."))
 
    MakeDir(dir2);
 
}
 

	
 
const char *sbool(const bool &p) {
 

	
 
  const char *true_str="true";
 
  const char *false_str="false";
 
  if (p)
 
    return true_str;
 
  else
 
    return false_str;
 
}
 

	
 
void Parameter::Write(ostream &os) const {
 

	
 

	
 
  if (arrowcolor) 
 
  os << " arrowcolor = " << arrowcolor << endl;
 
  os << " arrowsize = " << arrowsize << endl;
 

	
 
  if (textcolor) 
 
  os << " textcolor = " << textcolor << endl;
 
  os << " cellnumsize = " << cellnumsize << endl;
 
  os << " nodenumsize = " << nodenumsize << endl;
 
  os << " node_mag = " << node_mag << endl;
 
  os << " outlinewidth = " << outlinewidth << endl;
 

	
 
  if (cell_outline_color) 
 
  os << " cell_outline_color = " << cell_outline_color << endl;
 
  os << " resize_stride = " << resize_stride << endl;
 
  os << " export_interval = " << export_interval << endl;
 

	
 
  if (export_fn_prefix) 
 
  os << " export_fn_prefix = " << export_fn_prefix << endl;
 
  os << " storage_stride = " << storage_stride << endl;
 
  os << " xml_storage_stride = " << xml_storage_stride << endl;
 
  if (datadir) {
 
                                     QDir dataDir = QDir::home().relativeFilePath(datadir);
 
                                     os << " datadir = " << dataDir.dirName().toStdString() << endl;
 
                                     os << " datadir = " << dataDir.dirName().toStdString().c_str() << endl;
 
                                 }
 
                                 else {
 
                                     os << "datadir = ." << endl;
 
                                 }
 
  os << " T = " << T << endl;
 
  os << " lambda_length = " << lambda_length << endl;
 
  os << " yielding_threshold = " << yielding_threshold << endl;
 
  os << " lambda_celllength = " << lambda_celllength << endl;
 
  os << " target_length = " << target_length << endl;
 
  os << " cell_expansion_rate = " << cell_expansion_rate << endl;
 
  os << " cell_div_expansion_rate = " << cell_div_expansion_rate << endl;
 
  os << " auxin_dependent_growth = " << sbool(auxin_dependent_growth) << endl;
 
  os << " ode_accuracy = " << ode_accuracy << endl;
 
  os << " mc_stepsize = " << mc_stepsize << endl;
 
  os << " mc_cell_stepsize = " << mc_cell_stepsize << endl;
 
  os << " energy_threshold = " << energy_threshold << endl;
 
  os << " bend_lambda = " << bend_lambda << endl;
 
  os << " alignment_lambda = " << alignment_lambda << endl;
 
  os << " rel_cell_div_threshold = " << rel_cell_div_threshold << endl;
 
  os << " rel_perimeter_stiffness = " << rel_perimeter_stiffness << endl;
 
  os << " collapse_node_threshold = " << collapse_node_threshold << endl;
 
  os << " morphogen_div_threshold = " << morphogen_div_threshold << endl;
 
  os << " morphogen_expansion_threshold = " << morphogen_expansion_threshold << endl;
 
  os << " copy_wall = " << sbool(copy_wall) << endl;
 
  os << " source = " << source << endl;
 
  os << " D = "<< D[0] << ", " << D[1] << ", " << D[2] << ", " << D[3] << ", " << D[4] << ", " << D[5] << ", " << D[6] << ", " << D[7] << ", " << D[8] << ", " << D[9] << ", " << D[10] << ", " << D[11] << ", " << D[12] << ", " << D[13] << ", " << D[14] << endl;
 
  os << " initval = "<< initval[0] << ", " << initval[1] << ", " << initval[2] << ", " << initval[3] << ", " << initval[4] << ", " << initval[5] << ", " << initval[6] << ", " << initval[7] << ", " << initval[8] << ", " << initval[9] << ", " << initval[10] << ", " << initval[11] << ", " << initval[12] << ", " << initval[13] << ", " << initval[14] << endl;
 
  os << " k1 = " << k1 << endl;
 
  os << " k2 = " << k2 << endl;
 
  os << " r = " << r << endl;
 
  os << " kr = " << kr << endl;
 
  os << " km = " << km << endl;
 
  os << " Pi_tot = " << Pi_tot << endl;
 
  os << " transport = " << transport << endl;
 
  os << " ka = " << ka << endl;
 
  os << " pin_prod = " << pin_prod << endl;
 
  os << " pin_prod_in_epidermis = " << pin_prod_in_epidermis << endl;
 
  os << " pin_breakdown = " << pin_breakdown << endl;
 
  os << " pin_breakdown_internal = " << pin_breakdown_internal << endl;
 
  os << " aux1prod = " << aux1prod << endl;
 
  os << " aux1prodmeso = " << aux1prodmeso << endl;
 
  os << " aux1decay = " << aux1decay << endl;
 
  os << " aux1decaymeso = " << aux1decaymeso << endl;
 
  os << " aux1transport = " << aux1transport << endl;
 
  os << " aux_cons = " << aux_cons << endl;
 
  os << " aux_breakdown = " << aux_breakdown << endl;
 
  os << " kaux1 = " << kaux1 << endl;
 
  os << " kap = " << kap << endl;
 
  os << " leaf_tip_source = " << leaf_tip_source << endl;
 
  os << " sam_efflux = " << sam_efflux << endl;
 
  os << " sam_auxin = " << sam_auxin << endl;
 
  os << " sam_auxin_breakdown = " << sam_auxin_breakdown << endl;
 
  os << " van3prod = " << van3prod << endl;
 
  os << " van3autokat = " << van3autokat << endl;
 
  os << " van3sat = " << van3sat << endl;
 
  os << " k2van3 = " << k2van3 << endl;
 
  os << " dt = " << dt << endl;
 
  os << " rd_dt = " << rd_dt << endl;
 
  os << " movie = " << sbool(movie) << endl;
 
  os << " nit = " << nit << endl;
 
  os << " maxt = " << maxt << endl;
 
  os << " rseed = " << rseed << endl;
 
  os << " constituous_expansion_limit = " << constituous_expansion_limit << endl;
 
  os << " vessel_inh_level = " << vessel_inh_level << endl;
 
  os << " vessel_expansion_rate = " << vessel_expansion_rate << endl;
 
  os << " d = " << d << endl;
 
  os << " e = " << e << endl;
 
  os << " f = " << f << endl;
 
  os << " c = " << c << endl;
 
  os << " mu = " << mu << endl;
 
  os << " nu = " << nu << endl;
 
  os << " rho0 = " << rho0 << endl;
 
  os << " rho1 = " << rho1 << endl;
 
  os << " c0 = " << c0 << endl;
 
  os << " gamma = " << gamma << endl;
 
  os << " eps = " << eps << endl;
 
  os << " k = "<< k[0] << ", " << k[1] << ", " << k[2] << ", " << k[3] << ", " << k[4] << ", " << k[5] << ", " << k[6] << ", " << k[7] << ", " << k[8] << ", " << k[9] << ", " << k[10] << ", " << k[11] << ", " << k[12] << ", " << k[13] << ", " << k[14] << endl;
 
  os << " i1 = " << i1 << endl;
 
  os << " i2 = " << i2 << endl;
 
  os << " i3 = " << i3 << endl;
 
  os << " i4 = " << i4 << endl;
 
  os << " i5 = " << i5 << endl;
 

	
 
  if (s1) 
 
  os << " s1 = " << s1 << endl;
 

	
 
  if (s2) 
 
  os << " s2 = " << s2 << endl;
 

	
 
  if (s3) 
 
  os << " s3 = " << s3 << endl;
 
  os << " b1 = " << sbool(b1) << endl;
 
  os << " b2 = " << sbool(b2) << endl;
 
  os << " b3 = " << sbool(b3) << endl;
 
  os << " b4 = " << sbool(b4) << endl;
 

	
 
  if (dir1) 
 
  os << " dir1 = " << dir1 << endl;
 

	
 
  if (dir2) 
 
  os << " dir2 = " << dir2 << endl;
 
}
 

	
 
void Parameter::XMLAdd(xmlNode *root) const {
 
    xmlNode *xmlparameter = xmlNewChild(root, NULL, BAD_CAST "parameter", NULL);
 
{
 
  xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL);
 
  xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "arrowcolor" );
 
  ostringstream text;
 

	
 
  if (arrowcolor) 
 
    text << arrowcolor;
 
xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str());
 
}
 
{
 
  xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL);
 
  xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "arrowsize" );
 
  ostringstream text;
 
    text << arrowsize;
 
xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str());
 
}
 
{
 
  xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL);
 
  xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "textcolor" );
 
  ostringstream text;
 

	
 
  if (textcolor) 
 
    text << textcolor;
 
xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str());
 
}
 
{
 
  xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL);
 
  xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "cellnumsize" );
 
  ostringstream text;
 
    text << cellnumsize;
 
xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str());
 
}
 
{
 
  xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL);
 
  xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "nodenumsize" );
 
  ostringstream text;
 
    text << nodenumsize;
 
xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str());
 
}
 
{
 
  xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL);
 
  xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "node_mag" );
 
  ostringstream text;
 
    text << node_mag;
 
xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str());
 
}
 
{
 
  xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL);
 
  xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "outlinewidth" );
 
  ostringstream text;
 
    text << outlinewidth;
 
xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str());
 
}
 
{
 
  xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL);
 
  xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "cell_outline_color" );
 
  ostringstream text;
 

	
 
  if (cell_outline_color) 
 
    text << cell_outline_color;
 
xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str());
 
}
 
{
 
  xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL);
 
  xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "resize_stride" );
 
  ostringstream text;
 
    text << resize_stride;
 
xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str());
 
}
 
{
 
  xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL);
 
  xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "export_interval" );
 
  ostringstream text;
 
    text << export_interval;
 
xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str());
 
}
 
{
 
  xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL);
 
  xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "export_fn_prefix" );
 
  ostringstream text;
 

	
 
  if (export_fn_prefix) 
 
    text << export_fn_prefix;
 
xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str());
 
}
 
{
 
  xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL);
 
  xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "storage_stride" );
 
  ostringstream text;
 
    text << storage_stride;
 
xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str());
 
}
 
{
 
  xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL);
 
  xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "xml_storage_stride" );
 
  ostringstream text;
 
    text << xml_storage_stride;
 
xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str());
 
}
 
{
 
  xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL);
 
  xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "datadir" );
 
  ostringstream text;
 

	
 
  if (datadir) {
 
                                     QDir dataDir = QDir::home().relativeFilePath(datadir);
 
                                     text << dataDir.dirName().toStdString();
 
                                     text << dataDir.dirName().toStdString().c_str();
 
                                   }
 
xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str());
 
}
 
{
 
  xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL);
 
  xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "T" );
 
  ostringstream text;
 
    text << T;
 
xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str());
 
}
 
{
 
  xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL);
 
  xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "lambda_length" );
 
  ostringstream text;
 
    text << lambda_length;
 
xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str());
 
}
 
{
 
  xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL);
 
  xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "yielding_threshold" );
 
  ostringstream text;
 
    text << yielding_threshold;
 
xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str());
 
}
 
{
 
  xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL);
 
  xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "lambda_celllength" );
 
  ostringstream text;
 
    text << lambda_celllength;
 
xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str());
 
}
 
{
 
  xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL);
 
  xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "target_length" );
 
  ostringstream text;
 
    text << target_length;
 
xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str());
 
}
 
{
 
  xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL);
 
  xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "cell_expansion_rate" );
 
  ostringstream text;
 
    text << cell_expansion_rate;
 
xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str());
 
}
 
{
 
  xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL);
 
  xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "cell_div_expansion_rate" );
 
  ostringstream text;
 
    text << cell_div_expansion_rate;
 
xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str());
 
}
 
{
 
  xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL);
 
  xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "auxin_dependent_growth" );
 
  ostringstream text;
 
text << sbool(auxin_dependent_growth);
 
xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str());
 
}
 
{
 
  xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL);
 
  xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "ode_accuracy" );
 
  ostringstream text;
 
    text << ode_accuracy;
 
xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str());
 
}
 
{
 
  xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL);
 
  xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "mc_stepsize" );
 
  ostringstream text;
 
    text << mc_stepsize;
 
xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str());
 
}
 
{
 
  xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL);
 
  xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "mc_cell_stepsize" );
 
  ostringstream text;
 
    text << mc_cell_stepsize;
 
xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str());
 
}
 
{
 
  xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL);
 
  xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "energy_threshold" );
 
  ostringstream text;
 
    text << energy_threshold;
 
xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str());
 
}
 
{
 
  xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL);
 
  xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "bend_lambda" );
 
  ostringstream text;
 
    text << bend_lambda;
 
xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str());
 
}
 
{
 
  xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL);
 
  xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "alignment_lambda" );
 
  ostringstream text;
 
    text << alignment_lambda;
 
xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str());
 
}
 
{
 
  xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL);
 
  xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "rel_cell_div_threshold" );
 
  ostringstream text;
 
    text << rel_cell_div_threshold;
 
xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str());
 
}
 
{
 
  xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL);
 
  xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "rel_perimeter_stiffness" );
 
  ostringstream text;
 
    text << rel_perimeter_stiffness;
 
xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str());
 
}
 
{
 
  xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL);
 
  xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "collapse_node_threshold" );
 
  ostringstream text;
 
    text << collapse_node_threshold;
 
xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str());
 
}
 
{
 
  xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL);
 
  xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "morphogen_div_threshold" );
 
  ostringstream text;
 
    text << morphogen_div_threshold;
 
xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str());
 
}
 
{
 
  xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL);
 
  xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "morphogen_expansion_threshold" );
 
  ostringstream text;
 
    text << morphogen_expansion_threshold;
 
xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str());
 
}
 
{
 
  xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL);
 
  xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "copy_wall" );
 
  ostringstream text;
 
text << sbool(copy_wall);
 
xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str());
 
}
 
{
 
  xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL);
 
  xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "source" );
 
  ostringstream text;
 
    text << source;
 
xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str());
 
}
 
{
 
  xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL);
 
  xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "D" );
 
  xmlNode *xmlvalarray = xmlNewChild(xmlpar, NULL, BAD_CAST "valarray", NULL);
 
  {
 
    ostringstream text;
 
    text << D[0];
 
    xmlNode *xmlval = xmlNewChild(xmlvalarray, NULL, BAD_CAST "val", NULL);
 
    xmlNewProp(xmlval, BAD_CAST "v", BAD_CAST text.str().c_str());
 
  }
 
  {
 
    ostringstream text;
 
    text << D[1];
 
    xmlNode *xmlval = xmlNewChild(xmlvalarray, NULL, BAD_CAST "val", NULL);
 
    xmlNewProp(xmlval, BAD_CAST "v", BAD_CAST text.str().c_str());
 
  }
 
  {
 
    ostringstream text;
 
    text << D[2];
 
    xmlNode *xmlval = xmlNewChild(xmlvalarray, NULL, BAD_CAST "val", NULL);
 
    xmlNewProp(xmlval, BAD_CAST "v", BAD_CAST text.str().c_str());
 
  }
 
  {
 
    ostringstream text;
 
    text << D[3];
 
    xmlNode *xmlval = xmlNewChild(xmlvalarray, NULL, BAD_CAST "val", NULL);
 
    xmlNewProp(xmlval, BAD_CAST "v", BAD_CAST text.str().c_str());
 
  }
 
  {
 
    ostringstream text;
 
    text << D[4];
 
    xmlNode *xmlval = xmlNewChild(xmlvalarray, NULL, BAD_CAST "val", NULL);
 
    xmlNewProp(xmlval, BAD_CAST "v", BAD_CAST text.str().c_str());
 
  }
 
  {
 
    ostringstream text;
 
    text << D[5];
 
    xmlNode *xmlval = xmlNewChild(xmlvalarray, NULL, BAD_CAST "val", NULL);
 
    xmlNewProp(xmlval, BAD_CAST "v", BAD_CAST text.str().c_str());
 
  }
 
  {
 
    ostringstream text;
 
    text << D[6];
 
    xmlNode *xmlval = xmlNewChild(xmlvalarray, NULL, BAD_CAST "val", NULL);
 
    xmlNewProp(xmlval, BAD_CAST "v", BAD_CAST text.str().c_str());
 
  }
 
  {
 
    ostringstream text;
 
    text << D[7];
 
    xmlNode *xmlval = xmlNewChild(xmlvalarray, NULL, BAD_CAST "val", NULL);
 
    xmlNewProp(xmlval, BAD_CAST "v", BAD_CAST text.str().c_str());
 
  }
 
  {
 
    ostringstream text;
 
    text << D[8];
 
    xmlNode *xmlval = xmlNewChild(xmlvalarray, NULL, BAD_CAST "val", NULL);
 
    xmlNewProp(xmlval, BAD_CAST "v", BAD_CAST text.str().c_str());
 
  }
 
  {
 
    ostringstream text;
 
    text << D[9];
 
    xmlNode *xmlval = xmlNewChild(xmlvalarray, NULL, BAD_CAST "val", NULL);
 
    xmlNewProp(xmlval, BAD_CAST "v", BAD_CAST text.str().c_str());
 
  }
 
  {
 
    ostringstream text;
 
    text << D[10];
 
    xmlNode *xmlval = xmlNewChild(xmlvalarray, NULL, BAD_CAST "val", NULL);
 
    xmlNewProp(xmlval, BAD_CAST "v", BAD_CAST text.str().c_str());
 
  }
 
  {
 
    ostringstream text;
 
    text << D[11];
 
    xmlNode *xmlval = xmlNewChild(xmlvalarray, NULL, BAD_CAST "val", NULL);
 
    xmlNewProp(xmlval, BAD_CAST "v", BAD_CAST text.str().c_str());
 
  }
 
  {
 
    ostringstream text;
 
    text << D[12];
 
    xmlNode *xmlval = xmlNewChild(xmlvalarray, NULL, BAD_CAST "val", NULL);
 
    xmlNewProp(xmlval, BAD_CAST "v", BAD_CAST text.str().c_str());
 
  }
 
  {
 
    ostringstream text;
 
    text << D[13];
 
    xmlNode *xmlval = xmlNewChild(xmlvalarray, NULL, BAD_CAST "val", NULL);
 
    xmlNewProp(xmlval, BAD_CAST "v", BAD_CAST text.str().c_str());
 
  }
 
  {
 
    ostringstream text;
 
    text << D[14];
 
    xmlNode *xmlval = xmlNewChild(xmlvalarray, NULL, BAD_CAST "val", NULL);
 
    xmlNewProp(xmlval, BAD_CAST "v", BAD_CAST text.str().c_str());
 
  }
 
}
 
{
 
  xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL);
 
  xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "initval" );
 
  xmlNode *xmlvalarray = xmlNewChild(xmlpar, NULL, BAD_CAST "valarray", NULL);
 
  {
 
    ostringstream text;
 
    text << initval[0];
 
    xmlNode *xmlval = xmlNewChild(xmlvalarray, NULL, BAD_CAST "val", NULL);
 
    xmlNewProp(xmlval, BAD_CAST "v", BAD_CAST text.str().c_str());
 
  }
 
  {
 
    ostringstream text;
 
    text << initval[1];
 
    xmlNode *xmlval = xmlNewChild(xmlvalarray, NULL, BAD_CAST "val", NULL);
 
    xmlNewProp(xmlval, BAD_CAST "v", BAD_CAST text.str().c_str());
 
  }
 
  {
 
    ostringstream text;
 
    text << initval[2];
 
    xmlNode *xmlval = xmlNewChild(xmlvalarray, NULL, BAD_CAST "val", NULL);
 
    xmlNewProp(xmlval, BAD_CAST "v", BAD_CAST text.str().c_str());
 
  }
 
  {
 
    ostringstream text;
 
    text << initval[3];
 
    xmlNode *xmlval = xmlNewChild(xmlvalarray, NULL, BAD_CAST "val", NULL);
 
    xmlNewProp(xmlval, BAD_CAST "v", BAD_CAST text.str().c_str());
 
  }
 
  {
 
    ostringstream text;
 
    text << initval[4];
 
    xmlNode *xmlval = xmlNewChild(xmlvalarray, NULL, BAD_CAST "val", NULL);
 
    xmlNewProp(xmlval, BAD_CAST "v", BAD_CAST text.str().c_str());
 
  }
 
  {
 
    ostringstream text;
 
    text << initval[5];
 
    xmlNode *xmlval = xmlNewChild(xmlvalarray, NULL, BAD_CAST "val", NULL);
 
    xmlNewProp(xmlval, BAD_CAST "v", BAD_CAST text.str().c_str());
 
  }
 
  {
 
    ostringstream text;
 
    text << initval[6];
 
    xmlNode *xmlval = xmlNewChild(xmlvalarray, NULL, BAD_CAST "val", NULL);
 
    xmlNewProp(xmlval, BAD_CAST "v", BAD_CAST text.str().c_str());
 
  }
 
  {
 
    ostringstream text;
 
    text << initval[7];
 
    xmlNode *xmlval = xmlNewChild(xmlvalarray, NULL, BAD_CAST "val", NULL);
 
    xmlNewProp(xmlval, BAD_CAST "v", BAD_CAST text.str().c_str());
 
  }
 
  {
 
    ostringstream text;
 
    text << initval[8];
 
    xmlNode *xmlval = xmlNewChild(xmlvalarray, NULL, BAD_CAST "val", NULL);
 
    xmlNewProp(xmlval, BAD_CAST "v", BAD_CAST text.str().c_str());
 
  }
 
  {
 
    ostringstream text;
 
    text << initval[9];
 
    xmlNode *xmlval = xmlNewChild(xmlvalarray, NULL, BAD_CAST "val", NULL);
 
    xmlNewProp(xmlval, BAD_CAST "v", BAD_CAST text.str().c_str());
 
  }
 
  {
 
    ostringstream text;
 
    text << initval[10];
 
    xmlNode *xmlval = xmlNewChild(xmlvalarray, NULL, BAD_CAST "val", NULL);
 
    xmlNewProp(xmlval, BAD_CAST "v", BAD_CAST text.str().c_str());
 
  }
 
  {
 
    ostringstream text;
 
    text << initval[11];
 
    xmlNode *xmlval = xmlNewChild(xmlvalarray, NULL, BAD_CAST "val", NULL);
 
    xmlNewProp(xmlval, BAD_CAST "v", BAD_CAST text.str().c_str());
 
  }
 
  {
 
    ostringstream text;
 
    text << initval[12];
 
    xmlNode *xmlval = xmlNewChild(xmlvalarray, NULL, BAD_CAST "val", NULL);
 
    xmlNewProp(xmlval, BAD_CAST "v", BAD_CAST text.str().c_str());
 
  }
 
  {
 
    ostringstream text;
 
    text << initval[13];
 
    xmlNode *xmlval = xmlNewChild(xmlvalarray, NULL, BAD_CAST "val", NULL);
 
    xmlNewProp(xmlval, BAD_CAST "v", BAD_CAST text.str().c_str());
 
  }
 
  {
 
    ostringstream text;
 
    text << initval[14];
 
    xmlNode *xmlval = xmlNewChild(xmlvalarray, NULL, BAD_CAST "val", NULL);
 
    xmlNewProp(xmlval, BAD_CAST "v", BAD_CAST text.str().c_str());
 
  }
 
}
 
{
 
  xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL);
 
  xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "k1" );
 
  ostringstream text;
 
    text << k1;
 
xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str());
 
}
 
{
 
  xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL);
 
  xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "k2" );
 
  ostringstream text;
 
    text << k2;
 
xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str());
 
}
 
{
 
  xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL);
 
  xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "r" );
 
  ostringstream text;
 
    text << r;
 
xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str());
 
}
 
{
 
  xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL);
 
  xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "kr" );
 
  ostringstream text;
 
    text << kr;
 
xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str());
 
}
 
{
 
  xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL);
 
  xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "km" );
 
  ostringstream text;
 
    text << km;
 
xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str());
 
}
 
{
 
  xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL);
 
  xmlNewProp(xmlpar, BAD_CAST "name", BAD_CAST "Pi_tot" );
 
  ostringstream text;
 
    text << Pi_tot;
 
xmlNewProp(xmlpar, BAD_CAST "val", BAD_CAST text.str().c_str());
 
}
 
{
 
  xmlNode *xmlpar = xmlNewChild(xmlparameter, NULL, BAD_CAST "par", NULL);
src/xmlwrite.cpp
Show inline comments
 
@@ -244,769 +244,769 @@ void Node::XMLAdd(xmlNodePtr nodes_node)
 
    ostringstream text;
 
    text << bool_name(sam);
 
    xmlNewProp(xmlnode, BAD_CAST "sam", BAD_CAST text.str().c_str());
 
  }
 

	
 
  if (node_set) {
 
    ostringstream text;
 
    text << XMLIO::list_index(m->node_sets.begin(),m->node_sets.end(),node_set);
 
    xmlNewProp(xmlnode, BAD_CAST "nodeset", BAD_CAST text.str().c_str());    
 
  }
 
}
 

	
 
void Neighbor::XMLAdd(xmlNodePtr neighbors_node) const {
 

	
 
  xmlNodePtr xmlnode = xmlNewChild(neighbors_node, NULL, BAD_CAST "neighbor",NULL);
 
  {
 
    ostringstream text;
 
    text << cell->Index();
 
    xmlNewProp(xmlnode, BAD_CAST "cell", BAD_CAST text.str().c_str());
 
  }
 

	
 
  {
 
    ostringstream text;
 
    text << nb1->Index();
 
    xmlNewProp(xmlnode, BAD_CAST "nb1", BAD_CAST text.str().c_str());
 
  }
 

	
 
  {
 
    ostringstream text;
 
    text << nb2->Index();
 
    xmlNewProp(xmlnode, BAD_CAST "nb2", BAD_CAST text.str().c_str());
 
  }
 
}
 

	
 

	
 
// from example code on www.libxml.org:
 
xmlXPathObjectPtr
 
getnodeset (xmlDocPtr doc, xmlChar *xpath){
 

	
 
  xmlXPathContextPtr context;
 
  xmlXPathObjectPtr result;
 

	
 
  context = xmlXPathNewContext(doc);
 
  if (context == NULL) {
 
    //printf("Error in xmlXPathNewContext\n");
 
    return NULL;
 
  }
 
  result = xmlXPathEvalExpression(xpath, context);
 
  xmlXPathFreeContext(context);
 
  if (result == NULL) {
 
    //printf("Error in xmlXPathEvalExpression\n");
 
    return NULL;
 
  }
 
  if(xmlXPathNodeSetIsEmpty(result->nodesetval)){
 
    xmlXPathFreeObject(result);
 
    // printf("No result\n");
 
    return NULL;
 
  }
 
  return result;
 
}
 

	
 

	
 

	
 
int Cell::XMLRead(xmlNode *cur)
 
{
 

	
 
  xmlNode *n = cur->xmlChildrenNode;
 
  QLocale standardlocale(QLocale::C);
 
  bool ok;
 

	
 
  vector<int> tmp_nodes;
 

	
 
  while(n!=NULL) {
 
    if ((!xmlStrcmp(n->name, (const xmlChar *)"node"))) {
 
      xmlChar *nc = xmlGetProp(n, BAD_CAST "n");
 

	
 
      if (nc==0) {
 
	unique_warning("Token \"n\" not found in xmlwrite.cpp at or around line no. 966");
 
      }
 
      tmp_nodes.push_back(atoi( (char *)nc));
 
      xmlFree(nc);
 

	
 
    }
 
    n = n->next;
 
  }
 

	
 
  int nnodes = tmp_nodes.size();
 
  for (int i=0;i<nnodes;i++) {
 
    m->AddNodeToCell( this, 
 
		      m->nodes[tmp_nodes[i]], 
 
		      m->nodes[tmp_nodes[(nnodes+i-1)%nnodes]],
 
		      m->nodes[tmp_nodes[(i+1)%nnodes]] );
 

	
 
  }
 

	
 
  n = cur->xmlChildrenNode;
 
  while(n!=NULL) {
 
    if ((!xmlStrcmp(n->name, (const xmlChar *)"chem"))) {
 

	
 
      xmlNode *v_node = n->xmlChildrenNode;
 
      int nv=0;
 
      while (v_node!=NULL) {
 
	if ((!xmlStrcmp(v_node->name, (const xmlChar *)"val"))) {
 

	
 

	
 
	  if (nv>=Cell::NChem()) {
 
	    {
 
	      stringstream text;
 
	      text << "Exception in Mesh::XMLRead: Too many chemical values given for cell(s). Ignoring remaining values.";
 
	      unique_warning(text.str().c_str());
 
	      break;
 
	    }
 
	  }
 

	
 
	  xmlChar *nc = xmlGetProp(v_node, (const xmlChar *) "v");
 

	
 
	  if (nc==0) {
 
	    unique_warning("Token \"v\" not found in xmlwrite.cpp at or around line no. 1002");
 
	  }
 
	  double v=standardlocale.toDouble((char *)nc, &ok);
 
	  if (!ok) MyWarning::error("Could not convert \"%s\" to double in XMLRead.",(char *)nc);
 
	  chem[nv++]=v;
 
	  xmlFree(nc);
 
	}
 
	v_node = v_node->next; 
 
      }
 
    }
 
    n = n->next;
 
  }
 

	
 
  // read cell properties
 
  {
 
    xmlChar *v_str = xmlGetProp(cur, BAD_CAST "area");
 

	
 
    if (v_str==0) {
 
      unique_warning("Token \"area\" not found in xmlwrite.cpp at or around line no. 1018");
 
    }
 
    if (v_str != NULL) {
 
      area=standardlocale.toDouble((char *)v_str, &ok);
 
      if (!ok) MyWarning::error("Could not convert \"%s\" to double in XMLRead.",(char *)v_str);
 
      xmlFree(v_str);
 
    }
 
  }
 

	
 
  {
 
    xmlChar *v_str = xmlGetProp(cur, BAD_CAST "target_area");
 

	
 
    if (v_str==0) {
 
      unique_warning("Token \"target_area\" not found in xmlwrite.cpp at or around line no. 1029");
 
    }
 
    if (v_str != NULL) {
 
      target_area=standardlocale.toDouble((char *)v_str, &ok);
 
      if (!ok) MyWarning::error("Could not convert \"%s\" to double in XMLRead.",(char *)v_str);
 
      xmlFree(v_str);
 
    }
 
  }
 

	
 

	
 
  {
 
    xmlChar *v_str = xmlGetProp(cur, BAD_CAST "target_length");
 

	
 
    if (v_str==0) {
 
      unique_warning("Token \"target_length\" not found in xmlwrite.cpp at or around line no. 1041");
 
    }
 
    if (v_str != NULL) {
 
      target_length=standardlocale.toDouble((char *)v_str, &ok);
 
      if (!ok) MyWarning::error("Could not convert \"%s\" to double in XMLRead.",(char *)v_str);
 
      xmlFree(v_str);
 
    }
 
  }
 

	
 
  {
 
    xmlChar *v_str = xmlGetProp(cur, BAD_CAST "lambda_celllength");
 

	
 
    if (v_str==0) {
 
      unique_warning("Token \"lambda_celllength\" not found in xmlwrite.cpp at or around line no. 1052");
 
    }
 
    if (v_str != NULL) {
 
      lambda_celllength=standardlocale.toDouble((char *)v_str, &ok);
 
      if (!ok) MyWarning::error("Could not convert \"%s\" to double in XMLRead.",(char *)v_str);
 
      xmlFree(v_str);
 
    }
 
  }
 

	
 
  {
 
    xmlChar *v_str = xmlGetProp(cur, BAD_CAST "stiffness");
 

	
 
    if (v_str==0) {
 
      unique_warning("Token \"stiffness\" not found in xmlwrite.cpp at or around line no. 1063");
 
    }
 
    if (v_str != NULL) {
 
      stiffness=standardlocale.toDouble((char *)v_str, &ok);
 
      if (!ok) MyWarning::error("Could not convert \"%s\" to double in XMLRead.",(char *)v_str);
 
      xmlFree(v_str);
 
    }
 
  }
 

	
 

	
 
  {
 
    xmlChar *v_str = xmlGetProp(cur, BAD_CAST "fixed");
 

	
 
    if (v_str==0) {
 
      unique_warning("Token \"fixed\" not found in xmlwrite.cpp at or around line no. 1075");
 
    }
 
    if (v_str != NULL) {
 
      fixed = strtobool( (char *)v_str);
 
      xmlFree(v_str);
 
    }
 
  }
 

	
 
  {
 
    xmlChar *v_str = xmlGetProp(cur, BAD_CAST "pin_fixed");
 

	
 
    if (v_str==0) {
 
      unique_warning("Token \"pin_fixed\" not found in xmlwrite.cpp at or around line no. 1086");
 
    }
 
    if (v_str != NULL) {
 
      pin_fixed = strtobool( (char *)v_str);
 
      xmlFree(v_str);
 
    }
 
  }
 

	
 
  {
 
    xmlChar *v_str = xmlGetProp(cur, BAD_CAST "at_boundary");
 

	
 
    if (v_str==0) {
 
      unique_warning("Token \"at_boundary\" not found in xmlwrite.cpp at or around line no. 1097");
 
    }
 
    if (v_str != NULL) {
 
      at_boundary = strtobool( (char *)v_str);
 
      xmlFree(v_str);
 
    }
 
  }
 

	
 
  {
 
    xmlChar *v_str = xmlGetProp(cur, BAD_CAST "dead");
 

	
 
    if (v_str==0) {
 
      unique_warning("Token \"dead\" not found in xmlwrite.cpp at or around line no. 1108");
 
    }
 
    if (v_str != NULL) {
 
      dead = strtobool( (char *)v_str);
 
      xmlFree(v_str);
 
    }
 
  }
 

	
 
  {
 
    xmlChar *v_str = xmlGetProp(cur, BAD_CAST "source");
 

	
 
    if (v_str==0) {
 
      unique_warning("Token \"source\" not found in xmlwrite.cpp at or around line no. 1119");
 
    }
 
    if (v_str != NULL) {
 
      source = strtobool( (char *)v_str);
 
      xmlFree(v_str);
 
    }
 
  }
 

	
 
  {
 
    xmlChar *v_str = xmlGetProp(cur, BAD_CAST "boundary");
 

	
 
    if (v_str==0) {
 
      unique_warning("Token \"boundary\" not found in xmlwrite.cpp at or around line no. 1130");
 
    }
 
    if (v_str != NULL) {
 
      for (int i=0;i<4;i++) {
 
	if (!xmlStrcmp( v_str, (const xmlChar *)Cell::boundary_type_names[i])) {
 
	  boundary=(Cell::boundary_type)i;
 
	  break;
 
	}
 
      }
 
      xmlFree(v_str);
 
    }
 
  }
 

	
 
  {
 
    xmlChar *v_str = xmlGetProp(cur, BAD_CAST "div_counter");
 

	
 
    if (v_str==0) {
 
      unique_warning("Token \"div_counter\" not found in xmlwrite.cpp at or around line no. 1119");
 
    }
 
    if (v_str != NULL) {
 
      div_counter = atoi( (char *)v_str);
 
      xmlFree(v_str);
 
    }
 
  }
 

	
 
  {
 
    xmlChar *v_str = xmlGetProp(cur, BAD_CAST "cell_type");
 

	
 
    if (v_str==0) {
 
      unique_warning("Token \"cell_type\" not found in xmlwrite.cpp at or around line no. 1237");
 
    }
 
    if (v_str != NULL) {
 
      cell_type = atoi( (char *)v_str);
 
      xmlFree(v_str);
 
    }
 
  }
 

	
 
  // Recalculate moments and area
 
  SetIntegrals();
 
  return 0;
 
}
 

	
 
void NodeSet::XMLRead(xmlNode *root, Mesh *m)
 
{
 

	
 
  xmlNode *n = root->xmlChildrenNode;
 

	
 
  vector<int> tmp_nodes;
 
  while(n!=NULL) {
 
    if ((!xmlStrcmp(n->name, (const xmlChar *)"node"))) {
 
      xmlChar *nc = xmlGetProp(n, BAD_CAST "n");
 

	
 
      if (nc==0) {
 
	unique_warning("Token \"n\" not found in xmlwrite.cpp at or around line no. 966");
 
      }
 
      tmp_nodes.push_back(atoi( (char *)nc));
 
      xmlFree(nc);
 
    }
 
    n = n->next;
 
  }
 

	
 
  int nnodes = tmp_nodes.size();
 
  for (int i=0;i<nnodes;i++) {
 
    AddNode( &(m->getNode(tmp_nodes[i])) );
 
  }
 
}
 

	
 

	
 

	
 

	
 
void Wall::XMLAdd(xmlNode *parent) const { 
 

	
 
  // Save the node to a stream so we can reconstruct its state later
 
  xmlNodePtr xmlwall = xmlNewChild(parent, NULL, BAD_CAST "wall",NULL);
 

	
 
  {
 
    ostringstream text;
 
    text << Index();
 
    xmlNewProp(xmlwall, BAD_CAST "index" , BAD_CAST text.str().c_str() );
 
  }
 

	
 
  {
 
    ostringstream text;
 
    text << c1->Index();
 
    xmlNewProp(xmlwall, BAD_CAST "c1", BAD_CAST text.str().c_str());
 
  }
 

	
 

	
 
  {
 
    ostringstream text;
 
    text << c2->Index();
 
    xmlNewProp(xmlwall, BAD_CAST "c2", BAD_CAST text.str().c_str());
 
  }
 

	
 

	
 
  {
 
    ostringstream text;
 
    text << n1->Index();
 
    xmlNewProp(xmlwall, BAD_CAST "n1", BAD_CAST text.str().c_str());
 
  }
 

	
 
  {
 
    ostringstream text;
 
    text << n2->Index();
 
    xmlNewProp(xmlwall, BAD_CAST "n2", BAD_CAST text.str().c_str());
 
  }
 

	
 
  {
 
    ostringstream text;
 
    text << length;
 
    xmlNewProp(xmlwall, BAD_CAST "length", BAD_CAST text.str().c_str());
 
  }
 

	
 

	
 
  {
 
    ostringstream text;
 
    text << viz_flux;
 
    xmlNewProp(xmlwall, BAD_CAST "viz_flux", BAD_CAST text.str().c_str());
 
  }
 

	
 
  {
 
    ostringstream text;
 
    text << WallTypetoStr(wall_type);
 
    text << WallTypetoStr(wall_type).c_str();
 
    xmlNewProp(xmlwall, BAD_CAST "wall_type", BAD_CAST text.str().c_str());
 
  }
 

	
 

	
 
  xmlNodePtr tr1_xml = xmlNewChild(xmlwall, NULL, BAD_CAST "transporters1", NULL); 
 
  if (transporters1) {
 
    for (int i=0;i<Cell::NChem();i++) {
 
      xmlNodePtr tr1_val_xml = xmlNewChild(tr1_xml, NULL, BAD_CAST "val", NULL);
 
      { 
 
	ostringstream text;
 
	text << transporters1[i];
 
	xmlNewProp(tr1_val_xml, BAD_CAST "v", BAD_CAST text.str().c_str());
 

	
 
      }
 
    }
 
  }
 
  if (transporters2) {
 
    xmlNodePtr tr2_xml = xmlNewChild(xmlwall, NULL, BAD_CAST "transporters2", NULL); 
 

	
 
    for (int i=0;i<Cell::NChem();i++) {
 
      xmlNodePtr tr2_val_xml = xmlNewChild(tr2_xml, NULL, BAD_CAST "val", NULL);
 
      { 
 
	ostringstream text;
 
	text << transporters2[i];
 
	xmlNewProp(tr2_val_xml, BAD_CAST "v", BAD_CAST text.str().c_str());
 
      }
 
    }
 
  }
 

	
 
/*  if (apoplast) {
 
    xmlNodePtr apo_xml = xmlNewChild(xmlwall, NULL, BAD_CAST "apoplast", NULL); 
 

	
 
    for (int i=0;i<Cell::NChem();i++) {
 
      xmlNodePtr apo_val_xml = xmlNewChild(apo_xml, NULL, BAD_CAST "val", NULL);
 
      { 
 
	ostringstream text;
 
	text << transporters2[i];
 
	xmlNewProp(apo_val_xml, BAD_CAST "v", BAD_CAST text.str().c_str());
 
      }
 
    }
 
  } */
 
}
 

	
 

	
 
vector<double> XMLIO::XMLReadValArray(xmlNode *cur)
 
{
 

	
 
  vector<double> result;
 
  QLocale standardlocale(QLocale::C);
 
  bool ok;
 

	
 
  xmlNode *valarray_node = cur->xmlChildrenNode;
 
  while (valarray_node!=NULL) {
 
    if (!xmlStrcmp(valarray_node->name, (const xmlChar *)"val")) {
 
      xmlChar *vc = xmlGetProp(valarray_node, BAD_CAST "v");
 
      if (vc) {
 
	//result.push_back(strtod( (const char *)vc, 0));
 
	result.push_back(standardlocale.toDouble((char *)vc, &ok));
 
	if (!ok) MyWarning::error("Could not convert \"%s\" to double in XMLRead.",(char *)vc);
 
	xmlFree(vc);
 
      }
 

	
 
    }
 
    valarray_node = valarray_node->next;
 
  }
 
  return result;
 
}
 

	
 
void Mesh::XMLSave(const char *docname, xmlNode *options) const
 
{
 

	
 
  // based on libxml2 example code "tree2.c"
 

	
 
  xmlDocPtr doc = NULL;       /* document pointer */
 
  xmlNodePtr root_node = NULL;/* node pointers */
 
  //xmlDtdPtr dtd = NULL;       /* DTD pointer */
 

	
 
  //  LIBXML_TEST_VERSION;
 

	
 
  /* 
 
   * Creates a new document, a node and set it as a root node
 
   */
 
  doc = xmlNewDoc(BAD_CAST "1.0");
 
  root_node = xmlNewNode(NULL, BAD_CAST "leaf");
 
  xmlDocSetRootElement(doc, root_node);
 

	
 
  /* 
 
   * xmlNewProp() creates attributes, which is "attached" to an node.
 
   * It returns xmlAttrPtr, which isn't used here.
 
   */
 
  xmlNewProp(root_node, BAD_CAST "name", BAD_CAST docname);
 

	
 
  time_t t;
 
  std::time(&t);
 

	
 
  char *tstring = strdup(asctime(localtime(&t))); // but this does
 
  // replace "end of line character by '\0'
 
  char *eol=strchr(tstring,'\n');
 
  if (eol!=NULL)
 
    *eol='\0';
 

	
 
  xmlNewProp(root_node, BAD_CAST "date", BAD_CAST tstring);
 
  free(tstring);
 

	
 

	
 
  QString simtime = QString("%1").arg(time);
 
  xmlNewProp(root_node, BAD_CAST "simtime", BAD_CAST simtime.toStdString().c_str()); 
 
  /*
 
   * Creates a DTD declaration. Isn't mandatory. 
 
   */
 

	
 
  par.XMLAdd(root_node);
 

	
 
  xmlNodePtr xmlnodes = xmlNewChild(root_node, NULL, BAD_CAST "nodes",NULL);
 
  { ostringstream text;
 
    text << NNodes();
 
    xmlNewProp(xmlnodes, BAD_CAST "n", BAD_CAST text.str().c_str());
 
  }
 

	
 
  { ostringstream text;
 
    text << Node::target_length;
 
    xmlNewProp(xmlnodes, BAD_CAST "target_length", BAD_CAST text.str().c_str());
 
  }
 

	
 
  for (vector<Node *>::const_iterator i=nodes.begin(); i!=nodes.end(); i++) {
 
    (*i)->XMLAdd(xmlnodes) ;
 
  }
 

	
 

	
 
  /* 
 
   * xmlNewChild() creates a new node, which is "attached" as child node
 
   * of root_node node. 
 
   */
 
  xmlNodePtr xmlcells = xmlNewChild(root_node, NULL, BAD_CAST "cells",NULL);
 
  {
 
    ostringstream text;
 
    text << NCells();
 
    xmlNewProp(xmlcells, BAD_CAST "n", BAD_CAST text.str().c_str());
 
  }
 
  {
 
    ostringstream text;
 
    text << Cell::offset[0];
 
    xmlNewProp(xmlcells, BAD_CAST "offsetx", BAD_CAST text.str().c_str());
 
  }
 

	
 
  {
 
    ostringstream text;
 
    text << Cell::offset[1];
 
    xmlNewProp(xmlcells, BAD_CAST "offsety", BAD_CAST text.str().c_str());
 
  }
 

	
 
  {
 
    ostringstream text;
 
    text << Cell::factor;
 
    xmlNewProp(xmlcells, BAD_CAST "magnification", BAD_CAST text.str().c_str());
 
  }
 

	
 
  {
 
    ostringstream text;
 
    text << cells.front()->BaseArea();
 
    xmlNewProp(xmlcells, BAD_CAST "base_area", BAD_CAST text.str().c_str());
 
  }
 

	
 
  { 
 
    ostringstream text;
 
    text << Cell::NChem();
 
    xmlNewProp(xmlcells, BAD_CAST "nchem", BAD_CAST text.str().c_str());
 
  }
 

	
 
  for (vector<Cell *>::const_iterator i=cells.begin(); i!=cells.end(); i++) {
 
    (*i)->XMLAdd(xmlcells) ;
 
  }
 

	
 
  boundary_polygon->XMLAdd(xmlcells);
 

	
 
  xmlNodePtr xmlwalls = xmlNewChild(root_node, NULL, BAD_CAST "walls",NULL);
 
  { 
 
    ostringstream text;
 
    text << walls.size();
 
    xmlNewProp(xmlwalls, BAD_CAST "n", BAD_CAST text.str().c_str());
 
  }
 

	
 

	
 
  for (list<Wall *>::const_iterator i=walls.begin(); i!=walls.end(); i++) {
 
    (*i)->XMLAdd(xmlwalls) ;
 
  }
 

	
 

	
 
  xmlNodePtr xmlnodesets = xmlNewChild(root_node, NULL, BAD_CAST "nodesets",NULL);
 
  { 
 
    ostringstream text;
 
    text << node_sets.size();
 
    xmlNewProp(xmlnodesets, BAD_CAST "n", BAD_CAST text.str().c_str());
 
  }
 

	
 
  for_each( node_sets.begin(), node_sets.end(), bind2nd ( mem_fun( &NodeSet::XMLAdd ), xmlnodesets ) );
 

	
 
  // Add option tree for interactive application
 
  if (options) {
 
    xmlAddChild(root_node, options);
 
  }
 

	
 

	
 
  /* 
 
   * Dumping document to stdio or file
 
   */
 
  // Transparent compression seems not to work on Windows. So write uncompressed XML to ensure compatibility of LeafML files.
 
  xmlSetDocCompressMode(doc,0);
 
  xmlSaveFormatFileEnc(docname, doc, "UTF-8", 1);
 

	
 
  /*free the document */
 
  xmlFreeDoc(doc);
 

	
 
  /*
 
   *Free the global variables that may
 
   *have been allocated by the parser.
 
   */
 
  xmlCleanupParser();
 

	
 
  /*
 
   * this is to debug memory for regression tests
 
   */
 
}
 

	
 

	
 

	
 
void Mesh::XMLReadSimtime(const xmlNode *a_node)
 
{
 

	
 
  xmlNode *root_node;
 
  root_node = (xmlNode *)a_node;
 
  xmlChar *strsimtime = xmlGetProp(root_node, BAD_CAST "simtime");
 

	
 

	
 
  if (strsimtime) {
 

	
 
    QLocale standardlocale(QLocale::C);
 
    bool ok;
 

	
 
    double simtime=standardlocale.toDouble((char *)strsimtime, &ok);
 
    if (!ok) MyWarning::error("Could not convert \"%s\" to double in XMLRead.",(char *)strsimtime);
 
    time = simtime;
 
#ifdef QDEBUG
 
    qDebug() << "Simtime = " << strsimtime << endl;
 
#endif
 
  } else {
 
#ifdef QDEBUG
 
    qDebug() << "No simtime found in file." << endl;
 
#endif
 
    time =0;
 
  }	
 
}
 

	
 
void Mesh::XMLReadPars(const xmlNode * a_node)
 
{
 
  xmlNode *root_node;
 
  root_node = (xmlNode *)a_node;
 
  par.XMLRead(root_node);
 
  Seed(par.rseed);
 
  MakeDir(par.datadir);
 
}
 

	
 
void Mesh::XMLReadGeometry(const xmlNode * a_node)
 
{
 

	
 
  xmlNode *root_node;
 
  root_node = (xmlNode *)a_node;
 
  xmlNode *cur;
 
  QLocale standardlocale(QLocale::C);
 
  bool ok;
 
  // allocate Nodes
 
  cur = root_node->xmlChildrenNode;
 
  while (cur!=NULL) {
 
    if ((!xmlStrcmp(cur->name, (const xmlChar *)"nodes"))){
 
      XMLReadNodes(cur);
 
    }
 
    cur=cur->next;
 
  }
 

	
 
  cur = root_node->xmlChildrenNode;
 
  while (cur!=NULL) {
 
    if ((!xmlStrcmp(cur->name, (const xmlChar *)"nodesets"))) {
 
      XMLReadNodeSets(cur);
 
    }
 
    cur=cur->next;
 
  }
 

	
 
  cur=root_node->xmlChildrenNode;
 
  while (cur!=NULL) {
 
    if ((!xmlStrcmp(cur->name, (const xmlChar *)"nodes"))) {
 
      XMLReadNodeSetsToNodes(cur);
 
    }
 
    cur = cur->next;
 
  }
 

	
 

	
 
  // allocate Cells
 
  cur = root_node;
 

	
 
  // allocate Cells
 
  cur = cur->xmlChildrenNode;
 
  while (cur!=NULL) {
 
    if ((!xmlStrcmp(cur->name, (const xmlChar *)"cells"))){
 
      xmlChar *offsetxc = xmlGetProp(cur, BAD_CAST "offsetx");
 
      xmlChar *offsetyc = xmlGetProp(cur, BAD_CAST "offsety");
 

	
 
      double ox=standardlocale.toDouble((const char *)offsetxc, &ok);
 
      if (!ok) MyWarning::error("Could not convert \"%s\" to double in XMLRead.",(const char *)offsetxc);
 

	
 
      double oy=standardlocale.toDouble((const char *)offsetyc, &ok);
 
      if (!ok) MyWarning::error("Could not convert \"%s\" to double in XMLRead.",(const char *)offsetyc);
 
      Cell::setOffset(ox, oy);
 
      xmlFree(offsetxc);
 
      xmlFree(offsetyc);
 

	
 
      xmlChar *magnificationc = xmlGetProp(cur, BAD_CAST "magnification");
 

	
 
      Cell::SetMagnification(standardlocale.toDouble((const char *)magnificationc, &ok));
 
      if (!ok) MyWarning::error("Could not convert \"%s\" to double in XMLRead.",(const char *)magnificationc);
 
      xmlFree(magnificationc);
 

	
 
      xmlChar *baseareac = xmlGetProp(cur, BAD_CAST "base_area");
 

	
 
      Cell::BaseArea() = standardlocale.toDouble((const char *)baseareac, &ok);
 
      if (!ok) MyWarning::error("Could not convert \"%s\" to double in XMLRead.",(const char *)baseareac);
 
      xmlFree(baseareac);
 

	
 
      XMLReadCells(cur);
 
    }
 
    cur=cur->next;
 
  }
 

	
 
  // allocate Walls (we need to have read the cells before constructing walls)
 
  vector <Wall *> tmp_walls;
 
  cur = root_node->xmlChildrenNode;
 
  while (cur!=NULL) {
 
    if ((!xmlStrcmp(cur->name, (const xmlChar *)"walls"))){
 
      XMLReadWalls(cur, &tmp_walls);
 
    }
 
    cur=cur->next;
 
  }
 

	
 
  // read walls to cells and boundary_polygon
 
  cur = root_node->xmlChildrenNode;
 
  while (cur!=NULL) {
 
    if ((!xmlStrcmp(cur->name, (const xmlChar *)"cells"))) {
 
      XMLReadWallsToCells(cur, &tmp_walls);
 
    }
 
    cur=cur->next;
 
  }
 

	
 
  boundary_polygon->ConstructNeighborList();
 
  boundary_polygon->ConstructConnections();
 

	
 
  for (vector<Cell *>::iterator c=cells.begin(); c!=cells.end(); c++) {
 
    (*c)->ConstructNeighborList();
 
    (*c)->ConstructConnections();
 
  }
 

	
 
  shuffled_cells.clear();
 
  shuffled_cells = cells;
 

	
 
  MyUrand r(shuffled_cells.size());
 
  random_shuffle(shuffled_cells.begin(),shuffled_cells.end(),r);
 
}
 

	
 
void Mesh::XMLParseTree(const xmlNode *root_node)
 
{
 
  XMLReadSimtime(root_node);
 
  XMLReadPars(root_node);
 
  XMLReadGeometry(root_node);
 
}
 

	
 

	
 
void Mesh::XMLReadNodes(xmlNode *root)
 
{
 

	
 
  QLocale standardlocale(QLocale::C);
 
  bool ok;
 

	
 
  xmlNode *cur = root;
 
  cur = cur->xmlChildrenNode;
 

	
 
  for (vector<Node *>::iterator i=nodes.begin(); i!=nodes.end(); i++) {
0 comments (0 inline, 0 general)