diff --git a/data/leaves/circ.xml b/data/leaves/circ.xml deleted file mode 100644 --- a/data/leaves/circ.xml +++ /dev/null @@ -1,794 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #include <fstream> -#include <sstream> -#include <cstring> -#include <functional> -#include <getopt.h> -#include <cerrno> -#include "mesh.h" -#include "parameter.h" -#include "random.h" -#include "pi.h" -#include "cellitem.h" -#include "canvas.h" -#include "cell.h" -#include "output.h" -#include <qwidget.h> -#include <q3process.h> -#include <qapplication.h> -#include <QDesktopWidget> -#include <QGraphicsScene> -#include <QMessageBox> -//Added by qt3to4: -#include <QMouseEvent> - -#include <unistd.h> -#include <q3textstream.h> - - -#ifdef HAVE_QWT -#include "data_plot.h" -#endif -#include <QPalette> -#include <QBrush> -#include <QToolTip> -#include "simplugin.h" -#include "testplugin.h" - -/* #define _xstr_(s) _str_(s) -#define _str_(s) #s -#include _xstr_(REACTIONS_HEADER) -*/ -extern Parameter par; - -MainBase *main_window = 0; -double auxin_account = 0.; - - - -TestPlugin *plugin = new TestPlugin(); - -#ifdef XFIGGRAPHICS -#define TIMESTEP double Graphics::TimeStep(void) -#endif - -class PrintNode { -public: - void operator() (const Node &n) const - { - cerr << n.Index() << ": " << n << endl; - } -}; - - -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()); - - info_string += "\n" + 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(); - - - static int count=0; - 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() )) { - - static int frame = 0; - // frame numbers are sequential for the most frequently written file type. - // for the less frequently written file type they match the other type - if (!(count%par.storage_stride) ) { - - stringstream fname; - fname << par.datadir << "/leaf."; - fname.fill('0'); - fname.width(6); - - /* - fname << frame << ".pdf"; - if (par.storage_stride <= par.xml_storage_stride) { - frame++; - } - - // Write high-res JPG snapshot every plot step - Save(fname.str().c_str(), "PDF"); - */ - - fname << frame << ".jpg"; - if (par.storage_stride <= par.xml_storage_stride) { - frame++; - } - - // Write high-res JPG snapshot every plot step - Save(fname.str().c_str(), "JPEG",1024,768); - - } - - if (!(count%par.xml_storage_stride)) { - stringstream fname; - fname << par.datadir << "/leaf."; - fname.fill('0'); - fname.width(6); - fname << frame << ".xml"; - - if (par.xml_storage_stride < par.storage_stride) { - frame++; - } - // Write XML file every ten plot steps - mesh.XMLSave(fname.str().c_str(), XMLSettingsTree()); - } - - } -} - - -void Cell::Flux(double *flux, double *D) { - - - // loop over cell edges - - for (int c=0;c<Cell::nchem;c++) flux[c]=0.; - - for (list<Wall *>::iterator i=walls.begin(); - i!=walls.end(); - i++) { - - - // leaf cannot take up chemicals from environment ("no flux boundary") - if ((*i)->c2->BoundaryPolP()) continue; - - - // flux depends on edge length and concentration difference - for (int c=0;c<Cell::nchem;c++) { - double phi = (*i)->length * ( D[c] ) * ( (*i)->c2->chem[c] - chem[c] ); - - if ((*i)->c1!=this) { - cerr << "Warning, bad cells boundary: " << (*i)->c1->index << ", " << index << endl; - } - - flux[c] += phi; - } - } - -} - -INIT { - - if (leaffile) { - 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 { - - Cell &circle=mesh.CircularCell(0,0,10,10); - - circle.SetTargetArea(circle.CalcArea()); - mesh.SetBaseArea(); - // clean up chemicals - for (int c=0; c<Cell::NChem(); c++) { - circle.SetChemical(c, 0.); - } - } -} - -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.LoopCurrentCells(&TestPlugin::CellHouseKeeping); // this includes cell division - - // Reaction diffusion - /*CelltoCellTransport *transport_f = &TestPlugin::CelltoCellTransport; - CellReaction *cellreaction_f = new plugin->CellDynamics(); - WallReaction *wall_f = new WallDynamics();*/ - - mesh.ReactDiffuse(plugin, par.rd_dt); - - - t++; - - Plot(par.resize_stride); - - /*QVector< QPair<double, int> > angles=mesh.VertexAnglesValues(); - QString afname=QString("Angles/anglesvalues%1.dat").arg(t,6,10,QChar('0')); - ofstream af(afname.toStdString().c_str()); - */ - - /*for (QVector< QPair<qreal, int> >::const_iterator v=angles.begin(); - v!=angles.end(); - v++) { - af << v->first << " " << v->second << endl; - } - */ - } - - } else { - - /* TransportFunction *transport_f = new CelltoCellTransport(); - CellReaction *cellreaction_f = new CellDynamics(); - WallReaction *wall_f = new WallDynamics(); - - mesh.ReactDiffuse_New(transport_f, cellreaction_f, wall_f, par.rd_dt);*/ - mesh.ReactDiffuse(plugin, par.rd_dt); - - Plot(par.resize_stride); - - } - - - - - - i++; - return mesh.getTime(); - -} - - - -/* Called if a cell is clicked */ -void Cell::OnClick(QMouseEvent *e) { - -} - - - -void Wall::OnWallInsert(void) { - - -} - - - - -int main(int argc,char **argv) { - - try { - - - int c; - - - char *leaffile=0; - - - while (1) { - - //int this_option_optind = optind ? optind : 1; - int option_index = 0; - static struct option long_options[] = { - {"batch", 0, 0, 0}, - {"leaffile", 2, 0, 0} - }; - - // short option 'p' creates trouble for non-commandline usage on MacOSX. Option -p changed to -P (capital) - static char *short_options = "bl"; - c = getopt_long (argc, argv, "bl:", - 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 '?': - 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"); - } - - MakeDir("Angles"); - bool useGUI = !batch; - 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(); - } - } else { - main_window=new MainBase(canvas, mesh); - - } - - - - canvas.setSceneRect(QRectF()); - if (!batch) { - QObject::connect( qApp, SIGNAL(lastWindowClosed()), qApp, SLOT(quit()) ); - } - - - - main_window->Init(leaffile); - - Cell::SetMagnification(10); - 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; - abort(); - } else { - QString qmess(error_message.str().c_str()); - QMessageBox::critical(0, "I/O Error", qmess ); - abort(); - } - } - -} - - - -// Executed after the cellular mechanics steps have equillibrized -class CellHouseKeeping { -public: - void operator() (Cell &c) const { - - c.EnlargeTargetArea(par.cell_expansion_rate); - - if (c.Area() > par.rel_cell_div_threshold * c.BaseArea() ) { - c.Divide(); - } - } -}; - -// The number of chemical species in the cels -const int Cell::nchem = 0; - -// Differential equations describing transport of chemicals from cell to cell -class CelltoCellTransport : public TransportFunction { - - public: - virtual void operator()(Wall *w, double *dchem_c1, double *dchem_c2) {} - - }; - -// Differential equations describing chemical reactions taking place at or near the cell walls -// (e.g. PIN accumulation) -class WallDynamics : public WallReaction { - public: - virtual void operator()(Wall *w, double *dw1, double *dw2) {}; - -}; - - -// Differential equations describing chemical reactions inside the cells -class CellDynamics : public CellReaction { - public: - virtual void operator()(Cell *c, double *dchem) { - - }; - -}; - -// Rules for cell coloring -void Cell::SetColor(QColor &color) { } - -// To be executed after cell division -void Cell::OnDivide(ParentInfo &parent_info, Cell &daughter) {} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -