/* * * 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 . * * Copyright 2010 Roeland Merks. * */ #include #include #include #include #include #include #include #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 #include #include #include #include #include //Added by qt3to4: #include #include #include #ifdef HAVE_QWT #include "data_plot.h" #endif #include #include #include #include "simplugin.h" #include #include #include "modelcatalogue.h" static const std::string _module_id("$Id$"); extern Parameter par; MainBase *main_window = 0; #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::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( 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;itype()==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() <