# HG changeset patch # User Michael Guravage # Date 2010-06-14 11:16:57 # Node ID 03ad6bb2f07254e3fba10dfc83aff71b58e96606 # Parent 8b6e1d8e0734fc7ab3aa6ffe8038e8ccb6fff2fa # Parent f23676d337dbc7cf8219cd03a9f3244444d6c4b5 Merged my code (8b6e1d8e0734) with Roeland's latest changes (f23676d337db). diff --git a/src/TutorialCode/Tutorial1A/mymodel.cpp b/src/TutorialCode/Tutorial1A/mymodel.cpp new file mode 100644 --- /dev/null +++ b/src/TutorialCode/Tutorial1A/mymodel.cpp @@ -0,0 +1,70 @@ +/* + * + * This file is part of the Virtual Leaf. + * + * The Virtual Leaf 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. + * + * The Virtual Leaf 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 "simplugin.h" + +#include "parameter.h" + +#include "wallbase.h" +#include "cellbase.h" +#include "mymodel.h" + +static const std::string _module_id("$Id$"); + +QString MyModel::ModelID(void) { + // specify the name of your model here + return QString( "Cell growth" ); +} + +// return the number of chemicals your model uses +int MyModel::NChem(void) { return 0; } + +// To be executed after cell division +void MyModel::OnDivide(ParentInfo *parent_info, CellBase *daughter1, CellBase *daughter2) { + // rules to be executed after cell division go here + // (e.g., cell differentiation rules) +} + +void MyModel::SetCellColor(CellBase *c, QColor *color) { + // add cell coloring rules here + +} + +void MyModel::CellHouseKeeping(CellBase *c) { + // add cell behavioral rules here + c->EnlargeTargetArea(par->cell_expansion_rate); +} + +void MyModel::CelltoCellTransport(Wall *w, double *dchem_c1, double *dchem_c2) { + // add biochemical transport rules here +} +void MyModel::WallDynamics(Wall *w, double *dw1, double *dw2) { + // add biochemical networks for reactions occuring at walls here +} +void MyModel::CellDynamics(CellBase *c, double *dchem) { + // add biochemical networks for intracellular reactions here +} + + +Q_EXPORT_PLUGIN2(mymodel, MyModel) diff --git a/src/TutorialCode/Tutorial1A/mymodel.h b/src/TutorialCode/Tutorial1A/mymodel.h new file mode 100644 --- /dev/null +++ b/src/TutorialCode/Tutorial1A/mymodel.h @@ -0,0 +1,60 @@ +/* + * $Id$ + * + * This file is part of the Virtual Leaf. + * + * The Virtual Leaf 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. + * + * The Virtual Leaf 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 "simplugin.h" + + +class MyModel : public QObject, SimPluginInterface { + Q_OBJECT + Q_INTERFACES(SimPluginInterface); + +public: + virtual QString ModelID(void); + + // Executed after the cellular mechanics steps have equillibrized + virtual void CellHouseKeeping (CellBase *c); + // Differential equations describing transport of chemicals from cell to cell + virtual void CelltoCellTransport(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) + virtual void WallDynamics(Wall *w, double *dw1, double *dw2); + + // Differential equations describing chemical reactions inside the cells + virtual void CellDynamics(CellBase *c, double *dchem); + + // to be executed after a cell division + virtual void OnDivide(ParentInfo *parent_info, CellBase *daughter1, CellBase *daughter2); + + // to be executed for coloring a cell + virtual void SetCellColor(CellBase *c, QColor *color); + // return number of chemicals + virtual int NChem(void); +}; + + + + diff --git a/src/TutorialCode/Tutorial1A/mymodel.pro b/src/TutorialCode/Tutorial1A/mymodel.pro new file mode 100644 --- /dev/null +++ b/src/TutorialCode/Tutorial1A/mymodel.pro @@ -0,0 +1,61 @@ +# +# $Id$ +# +# This file is part of the Virtual Leaf. +# +# The Virtual Leaf 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. +# +# The Virtual Leaf 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. +# + + +TARGET = mymodel +VLEAFHOME = ../../.. + +CONFIG += release +CONFIG -= debug +CONFIG += plugin + +BINDIR = $${VLEAFHOME}/bin +LIBDIR = $${VLEAFHOME}/lib +INCDIR = $${VLEAFHOME}/src +DEFINES = QTGRAPHICS # VLEAFPLUGIN +DESTDIR = $${BINDIR}/models +HEADERS = $${TARGET}.h +INCLUDEPATH += $${INCDIR} + +QMAKE_CXXFLAGS += -fexceptions #-I$${INCDIR} +QMAKE_CXXFLAGS_DEBUG += -g3 +QMAKE_CXXFLAGS_DEBUG += -DQDEBUG +QT += qt3support +SOURCES = $${TARGET}.cpp +TEMPLATE = lib + +unix { + LIBS += -L$${LIBDIR} -lvleaf + QMAKE_CXXFLAGS += -fPIC -I/usr/include/libxml2 + QMAKE_LFLAGS += -fPIC +} + +win32 { + LIBXML2DIR = C:\libxml2 + LIBICONVDIR = C:\libiconv + LIBZDIR = C:\libz + LIBS += -L$${LIBDIR} -lvleaf + QMAKE_CXXFLAGS += -DLIBXML_STATIC + QMAKE_CXXFLAGS += -I$${LIBXML2DIR}\include -I$${LIBICONVDIR}\include -I$${LIBZDIR}\include + +} + +# finish diff --git a/src/TutorialCode/Tutorial1B/mymodel.cpp b/src/TutorialCode/Tutorial1B/mymodel.cpp new file mode 100644 --- /dev/null +++ b/src/TutorialCode/Tutorial1B/mymodel.cpp @@ -0,0 +1,73 @@ +/* + * + * This file is part of the Virtual Leaf. + * + * The Virtual Leaf 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. + * + * The Virtual Leaf 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 "simplugin.h" + +#include "parameter.h" + +#include "wallbase.h" +#include "cellbase.h" +#include "mymodel.h" + +static const std::string _module_id("$Id$"); + +QString MyModel::ModelID(void) { + // specify the name of your model here + return QString( "Cell growth and cell division" ); +} + +// return the number of chemicals your model uses +int MyModel::NChem(void) { return 0; } + +// To be executed after cell division +void MyModel::OnDivide(ParentInfo *parent_info, CellBase *daughter1, CellBase *daughter2) { + // rules to be executed after cell division go here + // (e.g., cell differentiation rules) +} + +void MyModel::SetCellColor(CellBase *c, QColor *color) { + // add cell coloring rules here + +} + +void MyModel::CellHouseKeeping(CellBase *c) { + // add cell behavioral rules here + c->EnlargeTargetArea(par->cell_expansion_rate); + if (c->Area() > par->rel_cell_div_threshold * c->BaseArea()) { + c->Divide(); + } +} + +void MyModel::CelltoCellTransport(Wall *w, double *dchem_c1, double *dchem_c2) { + // add biochemical transport rules here +} +void MyModel::WallDynamics(Wall *w, double *dw1, double *dw2) { + // add biochemical networks for reactions occuring at walls here +} +void MyModel::CellDynamics(CellBase *c, double *dchem) { + // add biochemical networks for intracellular reactions here +} + + +Q_EXPORT_PLUGIN2(mymodel, MyModel) diff --git a/src/TutorialCode/Tutorial1B/mymodel.h b/src/TutorialCode/Tutorial1B/mymodel.h new file mode 100644 --- /dev/null +++ b/src/TutorialCode/Tutorial1B/mymodel.h @@ -0,0 +1,60 @@ +/* + * $Id$ + * + * This file is part of the Virtual Leaf. + * + * The Virtual Leaf 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. + * + * The Virtual Leaf 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 "simplugin.h" + + +class MyModel : public QObject, SimPluginInterface { + Q_OBJECT + Q_INTERFACES(SimPluginInterface); + +public: + virtual QString ModelID(void); + + // Executed after the cellular mechanics steps have equillibrized + virtual void CellHouseKeeping (CellBase *c); + // Differential equations describing transport of chemicals from cell to cell + virtual void CelltoCellTransport(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) + virtual void WallDynamics(Wall *w, double *dw1, double *dw2); + + // Differential equations describing chemical reactions inside the cells + virtual void CellDynamics(CellBase *c, double *dchem); + + // to be executed after a cell division + virtual void OnDivide(ParentInfo *parent_info, CellBase *daughter1, CellBase *daughter2); + + // to be executed for coloring a cell + virtual void SetCellColor(CellBase *c, QColor *color); + // return number of chemicals + virtual int NChem(void); +}; + + + + diff --git a/src/TutorialCode/Tutorial1B/mymodel.pro b/src/TutorialCode/Tutorial1B/mymodel.pro new file mode 100644 --- /dev/null +++ b/src/TutorialCode/Tutorial1B/mymodel.pro @@ -0,0 +1,61 @@ +# +# $Id$ +# +# This file is part of the Virtual Leaf. +# +# The Virtual Leaf 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. +# +# The Virtual Leaf 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. +# + + +TARGET = mymodel +VLEAFHOME = ../../.. + +CONFIG += release +CONFIG -= debug +CONFIG += plugin + +BINDIR = $${VLEAFHOME}/bin +LIBDIR = $${VLEAFHOME}/lib +INCDIR = $${VLEAFHOME}/src +DEFINES = QTGRAPHICS # VLEAFPLUGIN +DESTDIR = $${BINDIR}/models +HEADERS = $${TARGET}.h +INCLUDEPATH += $${INCDIR} + +QMAKE_CXXFLAGS += -fexceptions #-I$${INCDIR} +QMAKE_CXXFLAGS_DEBUG += -g3 +QMAKE_CXXFLAGS_DEBUG += -DQDEBUG +QT += qt3support +SOURCES = $${TARGET}.cpp +TEMPLATE = lib + +unix { + LIBS += -L$${LIBDIR} -lvleaf + QMAKE_CXXFLAGS += -fPIC -I/usr/include/libxml2 + QMAKE_LFLAGS += -fPIC +} + +win32 { + LIBXML2DIR = C:\libxml2 + LIBICONVDIR = C:\libiconv + LIBZDIR = C:\libz + LIBS += -L$${LIBDIR} -lvleaf + QMAKE_CXXFLAGS += -DLIBXML_STATIC + QMAKE_CXXFLAGS += -I$${LIBXML2DIR}\include -I$${LIBICONVDIR}\include -I$${LIBZDIR}\include + +} + +# finish diff --git a/src/TutorialCode/Tutorial1C/mymodel.cpp b/src/TutorialCode/Tutorial1C/mymodel.cpp new file mode 100644 --- /dev/null +++ b/src/TutorialCode/Tutorial1C/mymodel.cpp @@ -0,0 +1,72 @@ +/* + * + * This file is part of the Virtual Leaf. + * + * The Virtual Leaf 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. + * + * The Virtual Leaf 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 "simplugin.h" + +#include "parameter.h" + +#include "wallbase.h" +#include "cellbase.h" +#include "mymodel.h" + +static const std::string _module_id("$Id$"); + +QString MyModel::ModelID(void) { + // specify the name of your model here + return QString( "Cell growth and cell division" ); +} + +// return the number of chemicals your model uses +int MyModel::NChem(void) { return 0; } + +// To be executed after cell division +void MyModel::OnDivide(ParentInfo *parent_info, CellBase *daughter1, CellBase *daughter2) { + // rules to be executed after cell division go here + // (e.g., cell differentiation rules) +} + +void MyModel::SetCellColor(CellBase *c, QColor *color) { + // add cell coloring rules here +} + +void MyModel::CellHouseKeeping(CellBase *c) { + // add cell behavioral rules here + c->EnlargeTargetArea(par->cell_expansion_rate); + if (c->Area() > par->rel_cell_div_threshold * c->BaseArea()) { + c->DivideOverAxis(Vector(1,0,0)); + } +} + +void MyModel::CelltoCellTransport(Wall *w, double *dchem_c1, double *dchem_c2) { + // add biochemical transport rules here +} +void MyModel::WallDynamics(Wall *w, double *dw1, double *dw2) { + // add biochemical networks for reactions occuring at walls here +} +void MyModel::CellDynamics(CellBase *c, double *dchem) { + // add biochemical networks for intracellular reactions here +} + + +Q_EXPORT_PLUGIN2(mymodel, MyModel) diff --git a/src/TutorialCode/Tutorial1C/mymodel.h b/src/TutorialCode/Tutorial1C/mymodel.h new file mode 100644 --- /dev/null +++ b/src/TutorialCode/Tutorial1C/mymodel.h @@ -0,0 +1,60 @@ +/* + * $Id$ + * + * This file is part of the Virtual Leaf. + * + * The Virtual Leaf 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. + * + * The Virtual Leaf 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 "simplugin.h" + + +class MyModel : public QObject, SimPluginInterface { + Q_OBJECT + Q_INTERFACES(SimPluginInterface); + +public: + virtual QString ModelID(void); + + // Executed after the cellular mechanics steps have equillibrized + virtual void CellHouseKeeping (CellBase *c); + // Differential equations describing transport of chemicals from cell to cell + virtual void CelltoCellTransport(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) + virtual void WallDynamics(Wall *w, double *dw1, double *dw2); + + // Differential equations describing chemical reactions inside the cells + virtual void CellDynamics(CellBase *c, double *dchem); + + // to be executed after a cell division + virtual void OnDivide(ParentInfo *parent_info, CellBase *daughter1, CellBase *daughter2); + + // to be executed for coloring a cell + virtual void SetCellColor(CellBase *c, QColor *color); + // return number of chemicals + virtual int NChem(void); +}; + + + + diff --git a/src/TutorialCode/Tutorial1C/mymodel.pro b/src/TutorialCode/Tutorial1C/mymodel.pro new file mode 100644 --- /dev/null +++ b/src/TutorialCode/Tutorial1C/mymodel.pro @@ -0,0 +1,61 @@ +# +# $Id$ +# +# This file is part of the Virtual Leaf. +# +# The Virtual Leaf 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. +# +# The Virtual Leaf 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. +# + + +TARGET = mymodel +VLEAFHOME = ../../.. + +CONFIG += release +CONFIG -= debug +CONFIG += plugin + +BINDIR = $${VLEAFHOME}/bin +LIBDIR = $${VLEAFHOME}/lib +INCDIR = $${VLEAFHOME}/src +DEFINES = QTGRAPHICS # VLEAFPLUGIN +DESTDIR = $${BINDIR}/models +HEADERS = $${TARGET}.h +INCLUDEPATH += $${INCDIR} + +QMAKE_CXXFLAGS += -fexceptions #-I$${INCDIR} +QMAKE_CXXFLAGS_DEBUG += -g3 +QMAKE_CXXFLAGS_DEBUG += -DQDEBUG +QT += qt3support +SOURCES = $${TARGET}.cpp +TEMPLATE = lib + +unix { + LIBS += -L$${LIBDIR} -lvleaf + QMAKE_CXXFLAGS += -fPIC -I/usr/include/libxml2 + QMAKE_LFLAGS += -fPIC +} + +win32 { + LIBXML2DIR = C:\libxml2 + LIBICONVDIR = C:\libiconv + LIBZDIR = C:\libz + LIBS += -L$${LIBDIR} -lvleaf + QMAKE_CXXFLAGS += -DLIBXML_STATIC + QMAKE_CXXFLAGS += -I$${LIBXML2DIR}\include -I$${LIBICONVDIR}\include -I$${LIBZDIR}\include + +} + +# finish diff --git a/src/TutorialCode/Tutorial1D/mymodel.cpp b/src/TutorialCode/Tutorial1D/mymodel.cpp new file mode 100644 --- /dev/null +++ b/src/TutorialCode/Tutorial1D/mymodel.cpp @@ -0,0 +1,75 @@ +/* + * + * This file is part of the Virtual Leaf. + * + * The Virtual Leaf 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. + * + * The Virtual Leaf 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 "simplugin.h" + +#include "parameter.h" + +#include "wallbase.h" +#include "cellbase.h" +#include "mymodel.h" + +static const std::string _module_id("$Id$"); + +QString MyModel::ModelID(void) { + // specify the name of your model here + return QString( "Growth, division, coloring" ); +} + +// return the number of chemicals your model uses +int MyModel::NChem(void) { return 0; } + +// To be executed after cell division +void MyModel::OnDivide(ParentInfo *parent_info, CellBase *daughter1, CellBase *daughter2) { + // rules to be executed after cell division go here + // (e.g., cell differentiation rules) +} + +void MyModel::SetCellColor(CellBase *c, QColor *color) { + // add cell coloring rules here + if (c->Area()/c->BaseArea()>1.8) { color->setNamedColor("blue"); } + else { color->setNamedColor("green"); } + +} + +void MyModel::CellHouseKeeping(CellBase *c) { + // add cell behavioral rules here + c->EnlargeTargetArea(par->cell_expansion_rate); + if (c->Area() > par->rel_cell_div_threshold * c->BaseArea()) { + c->Divide(); + } +} + +void MyModel::CelltoCellTransport(Wall *w, double *dchem_c1, double *dchem_c2) { + // add biochemical transport rules here +} +void MyModel::WallDynamics(Wall *w, double *dw1, double *dw2) { + // add biochemical networks for reactions occuring at walls here +} +void MyModel::CellDynamics(CellBase *c, double *dchem) { + // add biochemical networks for intracellular reactions here +} + + +Q_EXPORT_PLUGIN2(mymodel, MyModel) diff --git a/src/TutorialCode/Tutorial1D/mymodel.h b/src/TutorialCode/Tutorial1D/mymodel.h new file mode 100644 --- /dev/null +++ b/src/TutorialCode/Tutorial1D/mymodel.h @@ -0,0 +1,60 @@ +/* + * $Id$ + * + * This file is part of the Virtual Leaf. + * + * The Virtual Leaf 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. + * + * The Virtual Leaf 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 "simplugin.h" + + +class MyModel : public QObject, SimPluginInterface { + Q_OBJECT + Q_INTERFACES(SimPluginInterface); + +public: + virtual QString ModelID(void); + + // Executed after the cellular mechanics steps have equillibrized + virtual void CellHouseKeeping (CellBase *c); + // Differential equations describing transport of chemicals from cell to cell + virtual void CelltoCellTransport(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) + virtual void WallDynamics(Wall *w, double *dw1, double *dw2); + + // Differential equations describing chemical reactions inside the cells + virtual void CellDynamics(CellBase *c, double *dchem); + + // to be executed after a cell division + virtual void OnDivide(ParentInfo *parent_info, CellBase *daughter1, CellBase *daughter2); + + // to be executed for coloring a cell + virtual void SetCellColor(CellBase *c, QColor *color); + // return number of chemicals + virtual int NChem(void); +}; + + + + diff --git a/src/TutorialCode/Tutorial1D/mymodel.pro b/src/TutorialCode/Tutorial1D/mymodel.pro new file mode 100644 --- /dev/null +++ b/src/TutorialCode/Tutorial1D/mymodel.pro @@ -0,0 +1,61 @@ +# +# $Id$ +# +# This file is part of the Virtual Leaf. +# +# The Virtual Leaf 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. +# +# The Virtual Leaf 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. +# + + +TARGET = mymodel +VLEAFHOME = ../../.. + +CONFIG += release +CONFIG -= debug +CONFIG += plugin + +BINDIR = $${VLEAFHOME}/bin +LIBDIR = $${VLEAFHOME}/lib +INCDIR = $${VLEAFHOME}/src +DEFINES = QTGRAPHICS # VLEAFPLUGIN +DESTDIR = $${BINDIR}/models +HEADERS = $${TARGET}.h +INCLUDEPATH += $${INCDIR} + +QMAKE_CXXFLAGS += -fexceptions #-I$${INCDIR} +QMAKE_CXXFLAGS_DEBUG += -g3 +QMAKE_CXXFLAGS_DEBUG += -DQDEBUG +QT += qt3support +SOURCES = $${TARGET}.cpp +TEMPLATE = lib + +unix { + LIBS += -L$${LIBDIR} -lvleaf + QMAKE_CXXFLAGS += -fPIC -I/usr/include/libxml2 + QMAKE_LFLAGS += -fPIC +} + +win32 { + LIBXML2DIR = C:\libxml2 + LIBICONVDIR = C:\libiconv + LIBZDIR = C:\libz + LIBS += -L$${LIBDIR} -lvleaf + QMAKE_CXXFLAGS += -DLIBXML_STATIC + QMAKE_CXXFLAGS += -I$${LIBXML2DIR}\include -I$${LIBICONVDIR}\include -I$${LIBZDIR}\include + +} + +# finish diff --git a/src/TutorialCode/Tutorial2/mymodel.cpp b/src/TutorialCode/Tutorial2/mymodel.cpp --- a/src/TutorialCode/Tutorial2/mymodel.cpp +++ b/src/TutorialCode/Tutorial2/mymodel.cpp @@ -34,26 +34,66 @@ static const std::string _module_id("$Id QString MyModel::ModelID(void) { // specify the name of your model here - return QString( "Cell growth and cell division" ); + return QString( "Growth hormones" ); } // return the number of chemicals your model uses -int MyModel::NChem(void) { return 0; } +int MyModel::NChem(void) { return 1; } // To be executed after cell division void MyModel::OnDivide(ParentInfo *parent_info, CellBase *daughter1, CellBase *daughter2) { // rules to be executed after cell division go here // (e.g., cell differentiation rules) + + // set one cell to source after first division + if (CellBase::NCells()==2) { + daughter1->SetCellType(1); + daughter2->SetCellType(0); + } + + // if a source cells has divided, one of the daughters becomes the new source + if (daughter1->CellType()==1) { + + // if both cells are at the tissue perimeter, choose at random + if (daughter1->AtBoundaryP() && daughter2->AtBoundaryP()) { + + if (qrand()%2){ + daughter1->SetCellType(1); + daughter2->SetCellType(0); + } else { + daughter1->SetCellType(0); + daughter2->SetCellType(1); + } + } else { + // otherwise choose the one that is still at the perimeter + if (daughter1->AtBoundaryP()) { + daughter1->SetCellType(1); + daughter2->SetCellType(0); + } else { + daughter1->SetCellType(0); + daughter2->SetCellType(1); + } + } + } + } void MyModel::SetCellColor(CellBase *c, QColor *color) { // add cell coloring rules here - + + // white: high concentration of growth hormone, black low concentration + double val = 1.-c->Chemical(0)/(1.+c->Chemical(0)); + color->setRgbF(val, val, val); } void MyModel::CellHouseKeeping(CellBase *c) { // add cell behavioral rules here - c->EnlargeTargetArea(par->cell_expansion_rate); + if (CellBase::NCells()==1) + // first cell expands unconditionally + c->EnlargeTargetArea(par->cell_expansion_rate); + else + c->EnlargeTargetArea(c->Chemical(0)*par->cell_expansion_rate); + if (c->Area() > par->rel_cell_div_threshold * c->BaseArea()) { c->Divide(); } @@ -61,12 +101,19 @@ void MyModel::CellHouseKeeping(CellBase void MyModel::CelltoCellTransport(Wall *w, double *dchem_c1, double *dchem_c2) { // add biochemical transport rules here + double phi = w->Length() * par->D[0] * ( w->C2()->Chemical(0) - w->C1()->Chemical(0) ); + dchem_c1[0]+=phi; + dchem_c2[0]-=phi; } + void MyModel::WallDynamics(Wall *w, double *dw1, double *dw2) { // add biochemical networks for reactions occuring at walls here } void MyModel::CellDynamics(CellBase *c, double *dchem) { // add biochemical networks for intracellular reactions here + if (c->CellType()==1) { + dchem[0] = par->leaf_tip_source; + } } diff --git a/src/TutorialCode/Tutorial3/mymodel.cpp b/src/TutorialCode/Tutorial3/mymodel.cpp --- a/src/TutorialCode/Tutorial3/mymodel.cpp +++ b/src/TutorialCode/Tutorial3/mymodel.cpp @@ -34,38 +34,99 @@ static const std::string _module_id("$Id QString MyModel::ModelID(void) { // specify the name of your model here - return QString( "Cell growth and cell division" ); + return QString( "Growth hormones" ); } // return the number of chemicals your model uses -int MyModel::NChem(void) { return 0; } +int MyModel::NChem(void) { return 2; } // To be executed after cell division void MyModel::OnDivide(ParentInfo *parent_info, CellBase *daughter1, CellBase *daughter2) { // rules to be executed after cell division go here // (e.g., cell differentiation rules) + + // set one cell to source after first division + if (CellBase::NCells()==2) { + daughter1->SetCellType(1); + daughter2->SetCellType(0); + } + + // if a source cells has divided, one of the daughters becomes the new source + if (daughter1->CellType()==1) { + + // if both cells are at the tissue perimeter, choose at random + if (daughter1->AtBoundaryP() && daughter2->AtBoundaryP()) { + + if (qrand()%2){ + daughter1->SetCellType(1); + daughter2->SetCellType(0); + } else { + daughter1->SetCellType(0); + daughter2->SetCellType(1); + } + } else { + // otherwise choose the one that is still at the perimeter + if (daughter1->AtBoundaryP()) { + daughter1->SetCellType(1); + daughter2->SetCellType(0); + } else { + daughter1->SetCellType(0); + daughter2->SetCellType(1); + } + } + } + } void MyModel::SetCellColor(CellBase *c, QColor *color) { // add cell coloring rules here + + // white: high concentration of growth hormone, black low concentration + double val = 1.-c->Chemical(0)/(1.+c->Chemical(0)); + color->setRgbF(val, val, val); } void MyModel::CellHouseKeeping(CellBase *c) { // add cell behavioral rules here - c->EnlargeTargetArea(par->cell_expansion_rate); + if (CellBase::NCells()==1) + // first cell expands unconditionally + c->EnlargeTargetArea(par->cell_expansion_rate); + else + c->EnlargeTargetArea(c->Chemical(0)*par->cell_expansion_rate); + if (c->Area() > par->rel_cell_div_threshold * c->BaseArea()) { - c->DivideOverAxis(Vector(1,0,0)); + c->Divide(); } } void MyModel::CelltoCellTransport(Wall *w, double *dchem_c1, double *dchem_c2) { // add biochemical transport rules here + double phi = w->Length() * par->D[0] * ( w->C2()->Chemical(0) - w->C1()->Chemical(0) ); + dchem_c1[0]+=phi; + dchem_c2[0]-=phi; + + // directed transport + // efflux from cell 1 to cell 2 + double trans12 = ( par->transport * w->Transporters1(1) * + w->C1()->Chemical(0) / (par->ka + w->C1()->Chemical(0)) ); + + // efflux from cell 2 to cell 1 + double trans21 = ( par->transport * w->Transporters2(1) * + w->C2()->Chemical(0) / (par->ka + w->C2()->Chemical(0)) ); + + dchem_c1[0] += trans21 - trans12; + dchem_c2[0] += trans12 - trans21; + } + void MyModel::WallDynamics(Wall *w, double *dw1, double *dw2) { // add biochemical networks for reactions occuring at walls here } void MyModel::CellDynamics(CellBase *c, double *dchem) { // add biochemical networks for intracellular reactions here + if (c->CellType()==1) { + dchem[0] = par->leaf_tip_source; + } } diff --git a/src/TutorialCode/Tutorial3/tutorial3_init.xml b/src/TutorialCode/Tutorial3/tutorial3_init.xml new file mode 100644 --- /dev/null +++ b/src/TutorialCode/Tutorial3/tutorial3_init.xml @@ -0,0 +1,20702 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #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(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; + 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) {} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/TutorialCode/Tutorial4/auxin_growth_init.xml b/src/TutorialCode/Tutorial4/auxin_growth_init.xml new file mode 100644 index 0000000000000000000000000000000000000000..1712638981c21653fb443959ec345c47f6f91968 GIT binary patch literal 6918 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 M3p}6-BadqU05YdWBme*a diff --git a/src/TutorialCode/Tutorial4/mymodel b/src/TutorialCode/Tutorial4/mymodel new file mode 100644 --- /dev/null +++ b/src/TutorialCode/Tutorial4/mymodel @@ -0,0 +1,147 @@ +/* + * + * This file is part of the Virtual Leaf. + * + * The Virtual Leaf 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. + * + * The Virtual Leaf 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 "simplugin.h" + +#include "parameter.h" + +#include "wallbase.h" +#include "cellbase.h" +#include "mymodel.h" +#include "flux_function.h" + +static const std::string _module_id("$Id$"); + +QString MyModel::ModelID(void) { + // specify the name of your model here + return QString( "new auxin transport 2" ); +} + +// return the number of chemicals your model uses +int MyModel::NChem(void) { return 2; } + +// To be executed after cell division +void MyModel::OnDivide(ParentInfo *parent_info, CellBase *daughter1, CellBase *daughter2) { + + // After divisions, parent and daughter cells get a standard stock of PINs. + daughter1->SetChemical(1, par->initval[1]); + daughter2->SetChemical(1, par->initval[1]); + + +} + +void MyModel::SetCellColor(CellBase *c, QColor *color) { + // add cell coloring rules here + // Red: PIN1 + // Green: Auxin + color->setRgb(c->Chemical(1)/(1+c->Chemical(1)) * 255.,(c->Chemical(0)/(1+c->Chemical(0)) * 255.), 0); + +} + +void MyModel::CellHouseKeeping(CellBase *c) { + // add cell behavioral rules here + + c->EnlargeTargetArea(c->Chemical(0)/(1.+c->Chemical(0))*par->cell_expansion_rate); + + if (c->Area() > par->rel_cell_div_threshold * c->BaseArea()) { + c->Divide(); + } +} + +void MyModel::CelltoCellTransport(Wall *w, double *dchem_c1, double *dchem_c2) { + // add biochemical transport rules here + double phi = w->Length() * par->D[0] * ( w->C2()->Chemical(0) - w->C1()->Chemical(0) ); + dchem_c1[0]+=phi; + dchem_c2[0]-=phi; + + // Active fluxes (PIN1 mediated transport) + + // (Transporters measured in moles, here) + // efflux from cell 1 to cell 2 + double trans12 = ( par->transport * w->Transporters1(1) * w->C1()->Chemical(0) / (par->ka + w->C1()->Chemical(0)) ); + + // efflux from cell 2 to cell 1 + double trans21 = ( par->transport * w->Transporters2(1) * w->C2()->Chemical(0) / (par->ka + w->C2()->Chemical(0)) ); + + dchem_c1[0] += trans21 - trans12; + dchem_c2[0] += trans12 - trans21; + + // Influx at leaf "AuxinSource" (as specified in initial condition) + if (w->AuxinSource()) { + double aux_flux = par->leaf_tip_source * w->Length(); + dchem_c1[0] += aux_flux; + dchem_c2[0] += aux_flux; + } +} + +double MyModel::PINflux(CellBase *this_cell, CellBase *adjacent_cell, Wall *w) { + // PIN1 localization at wall + // Note: chemical 0 is Auxin (intracellular storage only) + // PIN1 is Chemical 1 (both in walls and intracellular storage) + //! \f$ \frac{d Pij/dt}{dt} = k_1 A_j \frac{P_i}{L_ij} - k_2 P_{ij} \f$ + // Note that Pij is measured in term of concentration (mol/L) + // Pi in terms of quantity (mol) + + // Equations as in Merks et al., Trends in Plant Science 2007 + + // calculate PIN translocation rate from cell to membrane + double adj_auxin = adjacent_cell->Chemical(0); + double receptor_level = adj_auxin * par->r / (par->kr + adj_auxin); + double pin_atwall; // pick the correct side of the Wall + + if (w->C1() == this_cell) pin_atwall = w->Transporters1(1); + else pin_atwall=w->Transporters2(1); + + // note: pin_flux is net flux from endosome to wall + double pin_flux = par->k1 * this_cell->Chemical(1) * receptor_level / ( par->km + this_cell->Chemical(1) ) - par->k2 * pin_atwall; + return pin_flux; + + +} + + +void MyModel::WallDynamics(Wall *w, double *dw1, double *dw2) { + // add biochemical networks for reactions occuring at walls here + dw1[0] = 0.; dw2[0] = 0.; // chemical 0 unused in walls + dw1[1] = PINflux(w->C1(),w->C2(),w); + dw2[1] = PINflux(w->C2(),w->C1(),w); + //static ofstream pf("pin_flux.dat"); + //pf << dw1[1] << " " << dw2[1] << " " << w->C1()->Chemical(1) << " " << w->C2()->Chemical(1) << endl; + +} + +void MyModel::CellDynamics(CellBase *c, double *dchem) { + // add biochemical networks for intracellular reactions here + + // sum all incoming fluxes of PINs + dchem[1] = - SumFluxFromWalls( c, MyModel::PINflux ); + + // auxin degradation + dchem[0] = - par->aux_breakdown * c->Chemical(0); + + +} + + +Q_EXPORT_PLUGIN2(mymodel, MyModel) diff --git a/src/TutorialCode/Tutorial4/mymodel.cpp b/src/TutorialCode/Tutorial4/mymodel.cpp --- a/src/TutorialCode/Tutorial4/mymodel.cpp +++ b/src/TutorialCode/Tutorial4/mymodel.cpp @@ -21,7 +21,7 @@ #include #include - +#include #include "simplugin.h" #include "parameter.h" @@ -29,33 +29,41 @@ #include "wallbase.h" #include "cellbase.h" #include "mymodel.h" +#include "flux_function.h" static const std::string _module_id("$Id$"); QString MyModel::ModelID(void) { // specify the name of your model here - return QString( "Growth, division, coloring" ); + return QString( "new auxin transport 2" ); } // return the number of chemicals your model uses -int MyModel::NChem(void) { return 0; } +int MyModel::NChem(void) { return 2; } // To be executed after cell division void MyModel::OnDivide(ParentInfo *parent_info, CellBase *daughter1, CellBase *daughter2) { - // rules to be executed after cell division go here - // (e.g., cell differentiation rules) + + // After divisions, parent and daughter cells get a standard stock of PINs. + daughter1->SetChemical(1, par->initval[1]); + daughter2->SetChemical(1, par->initval[1]); + + } void MyModel::SetCellColor(CellBase *c, QColor *color) { // add cell coloring rules here - if (c->Area()/c->BaseArea()>1.8) { color->setNamedColor("blue"); } - else { color->setNamedColor("green"); } - + // Red: PIN1 + // Green: Auxin + color->setRgb(c->Chemical(1)/(1+c->Chemical(1)) * 255.,(c->Chemical(0)/(1+c->Chemical(0)) * 255.), 0); + } void MyModel::CellHouseKeeping(CellBase *c) { // add cell behavioral rules here - c->EnlargeTargetArea(par->cell_expansion_rate); + + c->EnlargeTargetArea(c->Chemical(0)/(1.+c->Chemical(0))*par->cell_expansion_rate); + if (c->Area() > par->rel_cell_div_threshold * c->BaseArea()) { c->Divide(); } @@ -63,12 +71,74 @@ void MyModel::CellHouseKeeping(CellBase void MyModel::CelltoCellTransport(Wall *w, double *dchem_c1, double *dchem_c2) { // add biochemical transport rules here + double phi = w->Length() * par->D[0] * ( w->C2()->Chemical(0) - w->C1()->Chemical(0) ); + dchem_c1[0]+=phi; + dchem_c2[0]-=phi; + + // Active fluxes (PIN1 mediated transport) + + // (Transporters measured in moles, here) + // efflux from cell 1 to cell 2 + double trans12 = ( par->transport * w->Transporters1(1) * w->C1()->Chemical(0) / (par->ka + w->C1()->Chemical(0)) ); + + // efflux from cell 2 to cell 1 + double trans21 = ( par->transport * w->Transporters2(1) * w->C2()->Chemical(0) / (par->ka + w->C2()->Chemical(0)) ); + + dchem_c1[0] += trans21 - trans12; + dchem_c2[0] += trans12 - trans21; + + // Influx at leaf "AuxinSource" (as specified in initial condition) + if (w->AuxinSource()) { + double aux_flux = par->leaf_tip_source * w->Length(); + dchem_c1[0] += aux_flux; + dchem_c2[0] += aux_flux; + } } + +double MyModel::PINflux(CellBase *this_cell, CellBase *adjacent_cell, Wall *w) { + // PIN1 localization at wall + // Note: chemical 0 is Auxin (intracellular storage only) + // PIN1 is Chemical 1 (both in walls and intracellular storage) + //! \f$ \frac{d Pij/dt}{dt} = k_1 A_j \frac{P_i}{L_ij} - k_2 P_{ij} \f$ + // Note that Pij is measured in term of concentration (mol/L) + // Pi in terms of quantity (mol) + + // Equations as in Merks et al., Trends in Plant Science 2007 + + // calculate PIN translocation rate from cell to membrane + double adj_auxin = adjacent_cell->Chemical(0); + double receptor_level = adj_auxin * par->r / (par->kr + adj_auxin); + double pin_atwall; // pick the correct side of the Wall + + if (w->C1() == this_cell) pin_atwall = w->Transporters1(1); + else pin_atwall=w->Transporters2(1); + + // note: pin_flux is net flux from endosome to wall + double pin_flux = par->k1 * this_cell->Chemical(1) * receptor_level / ( par->km + this_cell->Chemical(1) ) - par->k2 * pin_atwall; + return pin_flux; + + +} + + void MyModel::WallDynamics(Wall *w, double *dw1, double *dw2) { // add biochemical networks for reactions occuring at walls here + dw1[0] = 0.; dw2[0] = 0.; // chemical 0 unused in walls + dw1[1] = PINflux(w->C1(),w->C2(),w); + dw2[1] = PINflux(w->C2(),w->C1(),w); + //static ofstream pf("pin_flux.dat"); + //pf << dw1[1] << " " << dw2[1] << " " << w->C1()->Chemical(1) << " " << w->C2()->Chemical(1) << endl; + } + void MyModel::CellDynamics(CellBase *c, double *dchem) { - // add biochemical networks for intracellular reactions here + // add biochemical networks for intracellular reactions here + + // sum all incoming fluxes of PINs + dchem[1] = - SumFluxFromWalls( c, MyModel::PINflux ); + + + } diff --git a/src/TutorialCode/Tutorial4/mymodel.h b/src/TutorialCode/Tutorial4/mymodel.h --- a/src/TutorialCode/Tutorial4/mymodel.h +++ b/src/TutorialCode/Tutorial4/mymodel.h @@ -53,6 +53,8 @@ public: virtual void SetCellColor(CellBase *c, QColor *color); // return number of chemicals virtual int NChem(void); + + virtual double PINflux(CellBase *this_cell, CellBase *adjacent_cell, Wall *w); }; diff --git a/src/TutorialCode/Tutorial4/tutorial4_init.xml b/src/TutorialCode/Tutorial4/tutorial4_init.xml new file mode 100644 index 0000000000000000000000000000000000000000..b67595ecfbd63256f35e29a36bf773def8c31133 GIT binary patch literal 54441 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 Yh=AT}+{Z8S*?0iGW=!6_#yo!Le^d>KQvd(} diff --git a/src/TutorialCode/Tutorial5/mymodel b/src/TutorialCode/Tutorial5/mymodel new file mode 100644 --- /dev/null +++ b/src/TutorialCode/Tutorial5/mymodel @@ -0,0 +1,147 @@ +/* + * + * This file is part of the Virtual Leaf. + * + * The Virtual Leaf 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. + * + * The Virtual Leaf 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 "simplugin.h" + +#include "parameter.h" + +#include "wallbase.h" +#include "cellbase.h" +#include "mymodel.h" +#include "flux_function.h" + +static const std::string _module_id("$Id$"); + +QString MyModel::ModelID(void) { + // specify the name of your model here + return QString( "new auxin transport 2" ); +} + +// return the number of chemicals your model uses +int MyModel::NChem(void) { return 2; } + +// To be executed after cell division +void MyModel::OnDivide(ParentInfo *parent_info, CellBase *daughter1, CellBase *daughter2) { + + // After divisions, parent and daughter cells get a standard stock of PINs. + daughter1->SetChemical(1, par->initval[1]); + daughter2->SetChemical(1, par->initval[1]); + + +} + +void MyModel::SetCellColor(CellBase *c, QColor *color) { + // add cell coloring rules here + // Red: PIN1 + // Green: Auxin + color->setRgb(c->Chemical(1)/(1+c->Chemical(1)) * 255.,(c->Chemical(0)/(1+c->Chemical(0)) * 255.), 0); + +} + +void MyModel::CellHouseKeeping(CellBase *c) { + // add cell behavioral rules here + + c->EnlargeTargetArea(c->Chemical(0)/(1.+c->Chemical(0))*par->cell_expansion_rate); + + if (c->Area() > par->rel_cell_div_threshold * c->BaseArea()) { + c->Divide(); + } +} + +void MyModel::CelltoCellTransport(Wall *w, double *dchem_c1, double *dchem_c2) { + // add biochemical transport rules here + double phi = w->Length() * par->D[0] * ( w->C2()->Chemical(0) - w->C1()->Chemical(0) ); + dchem_c1[0]+=phi; + dchem_c2[0]-=phi; + + // Active fluxes (PIN1 mediated transport) + + // (Transporters measured in moles, here) + // efflux from cell 1 to cell 2 + double trans12 = ( par->transport * w->Transporters1(1) * w->C1()->Chemical(0) / (par->ka + w->C1()->Chemical(0)) ); + + // efflux from cell 2 to cell 1 + double trans21 = ( par->transport * w->Transporters2(1) * w->C2()->Chemical(0) / (par->ka + w->C2()->Chemical(0)) ); + + dchem_c1[0] += trans21 - trans12; + dchem_c2[0] += trans12 - trans21; + + // Influx at leaf "AuxinSource" (as specified in initial condition) + if (w->AuxinSource()) { + double aux_flux = par->leaf_tip_source * w->Length(); + dchem_c1[0] += aux_flux; + dchem_c2[0] += aux_flux; + } +} + +double MyModel::PINflux(CellBase *this_cell, CellBase *adjacent_cell, Wall *w) { + // PIN1 localization at wall + // Note: chemical 0 is Auxin (intracellular storage only) + // PIN1 is Chemical 1 (both in walls and intracellular storage) + //! \f$ \frac{d Pij/dt}{dt} = k_1 A_j \frac{P_i}{L_ij} - k_2 P_{ij} \f$ + // Note that Pij is measured in term of concentration (mol/L) + // Pi in terms of quantity (mol) + + // Equations as in Merks et al., Trends in Plant Science 2007 + + // calculate PIN translocation rate from cell to membrane + double adj_auxin = adjacent_cell->Chemical(0); + double receptor_level = adj_auxin * par->r / (par->kr + adj_auxin); + double pin_atwall; // pick the correct side of the Wall + + if (w->C1() == this_cell) pin_atwall = w->Transporters1(1); + else pin_atwall=w->Transporters2(1); + + // note: pin_flux is net flux from endosome to wall + double pin_flux = par->k1 * this_cell->Chemical(1) * receptor_level / ( par->km + this_cell->Chemical(1) ) - par->k2 * pin_atwall; + return pin_flux; + + +} + + +void MyModel::WallDynamics(Wall *w, double *dw1, double *dw2) { + // add biochemical networks for reactions occuring at walls here + dw1[0] = 0.; dw2[0] = 0.; // chemical 0 unused in walls + dw1[1] = PINflux(w->C1(),w->C2(),w); + dw2[1] = PINflux(w->C2(),w->C1(),w); + //static ofstream pf("pin_flux.dat"); + //pf << dw1[1] << " " << dw2[1] << " " << w->C1()->Chemical(1) << " " << w->C2()->Chemical(1) << endl; + +} + +void MyModel::CellDynamics(CellBase *c, double *dchem) { + // add biochemical networks for intracellular reactions here + + // sum all incoming fluxes of PINs + dchem[1] = - SumFluxFromWalls( c, MyModel::PINflux ); + + // auxin degradation + dchem[0] = - par->aux_breakdown * c->Chemical(0); + + +} + + +Q_EXPORT_PLUGIN2(mymodel, MyModel) diff --git a/src/TutorialCode/Tutorial5/mymodel.cpp b/src/TutorialCode/Tutorial5/mymodel.cpp --- a/src/TutorialCode/Tutorial5/mymodel.cpp +++ b/src/TutorialCode/Tutorial5/mymodel.cpp @@ -19,80 +19,44 @@ * */ -#include -#include - -#include "simplugin.h" +#include "vleafmodel.h" -#include "parameter.h" - -#include "wallbase.h" -#include "cellbase.h" -#include "mymodel.h" - + static const std::string _module_id("$Id$"); QString MyModel::ModelID(void) { // specify the name of your model here - return QString( "Growth hormones" ); + return QString( "auxin flux and growth" ); } // return the number of chemicals your model uses -int MyModel::NChem(void) { return 1; } +int MyModel::NChem(void) { return 2; } // To be executed after cell division void MyModel::OnDivide(ParentInfo *parent_info, CellBase *daughter1, CellBase *daughter2) { - // rules to be executed after cell division go here - // (e.g., cell differentiation rules) - - // set one cell to source after first division - if (CellBase::NCells()==2) { - daughter1->SetCellType(1); - daughter2->SetCellType(0); - } + + // After divisions, parent and daughter cells get a standard stock of PINs. + daughter1->SetChemical(1, par->initval[1]); + daughter2->SetChemical(1, par->initval[1]); - // if a source cells has divided, one of the daughters becomes the new source - if (daughter1->CellType()==1) { - - // if both cells are at the tissue perimeter, choose at random - if (daughter1->AtBoundaryP() && daughter2->AtBoundaryP()) { - - if (qrand()%2){ - daughter1->SetCellType(1); - daughter2->SetCellType(0); - } else { - daughter1->SetCellType(0); - daughter2->SetCellType(1); - } - } else { - // otherwise choose the one that is still at the perimeter - if (daughter1->AtBoundaryP()) { - daughter1->SetCellType(1); - daughter2->SetCellType(0); - } else { - daughter1->SetCellType(0); - daughter2->SetCellType(1); - } - } - } + daughter1->SetTransporters(1, 0.); + daughter2->SetTransporters(1, 0.); + } void MyModel::SetCellColor(CellBase *c, QColor *color) { // add cell coloring rules here + // Red: PIN1 + // Green: Auxin + color->setRgb(c->Chemical(1)/(1+c->Chemical(1)) * 255.,(c->Chemical(0)/(1+c->Chemical(0)) * 255.), 0); - // white: high concentration of growth hormone, black low concentration - double val = c->Chemical(0)/(1.+c->Chemical(0)); - color->setRgbF(val, val, val); } void MyModel::CellHouseKeeping(CellBase *c) { // add cell behavioral rules here - if (CellBase::NCells()==1) - // first cell expands unconditionally - c->EnlargeTargetArea(par->cell_expansion_rate); - else - c->EnlargeTargetArea(c->Chemical(0)*par->cell_expansion_rate); + + c->EnlargeTargetArea(c->Chemical(0)/(1.+c->Chemical(0))*par->cell_expansion_rate); if (c->Area() > par->rel_cell_div_threshold * c->BaseArea()) { c->Divide(); @@ -104,16 +68,71 @@ void MyModel::CelltoCellTransport(Wall * double phi = w->Length() * par->D[0] * ( w->C2()->Chemical(0) - w->C1()->Chemical(0) ); dchem_c1[0]+=phi; dchem_c2[0]-=phi; + + // Active fluxes (PIN1 mediated transport) + + // (Transporters measured in moles, here) + // efflux from cell 1 to cell 2 + double trans12 = ( par->transport * w->Transporters1(1) * w->C1()->Chemical(0) / (par->ka + w->C1()->Chemical(0)) ); + + // efflux from cell 2 to cell 1 + double trans21 = ( par->transport * w->Transporters2(1) * w->C2()->Chemical(0) / (par->ka + w->C2()->Chemical(0)) ); + + dchem_c1[0] += trans21 - trans12; + dchem_c2[0] += trans12 - trans21; + + // Influx at leaf "AuxinSource" (as specified in initial condition) + if (w->AuxinSource()) { + double aux_flux = par->leaf_tip_source * w->Length(); + dchem_c1[0] += aux_flux; + dchem_c2[0] += aux_flux; + } } +double MyModel::PINflux(CellBase *this_cell, CellBase *adjacent_cell, Wall *w) { + // PIN1 localization at wall + // Note: chemical 0 is Auxin (intracellular storage only) + // PIN1 is Chemical 1 (both in walls and intracellular storage) + //! \f$ \frac{d Pij/dt}{dt} = k_1 A_j \frac{P_i}{L_ij} - k_2 P_{ij} \f$ + // Note that Pij is measured in term of concentration (mol/L) + // Pi in terms of quantity (mol) + + // Equations as in Merks et al., Trends in Plant Science 2007 + + // calculate PIN translocation rate from cell to membrane + double adj_auxin = adjacent_cell->Chemical(0); + double receptor_level = adj_auxin * par->r / (par->kr + adj_auxin); + double pin_atwall; // pick the correct side of the Wall + + if (w->C1() == this_cell) pin_atwall = w->Transporters1(1); + else pin_atwall=w->Transporters2(1); + + // note: pin_flux is net flux from endosome to wall + double pin_flux = par->k1 * this_cell->Chemical(1) * receptor_level / ( par->km + this_cell->Chemical(1) ) - par->k2 * pin_atwall; + return pin_flux; + + +} + + void MyModel::WallDynamics(Wall *w, double *dw1, double *dw2) { // add biochemical networks for reactions occuring at walls here + dw1[0] = 0.; dw2[0] = 0.; // chemical 0 unused in walls + dw1[1] = PINflux(w->C1(),w->C2(),w); + dw2[1] = PINflux(w->C2(),w->C1(),w); + } + void MyModel::CellDynamics(CellBase *c, double *dchem) { - // add biochemical networks for intracellular reactions here - if (c->CellType()==1) { - dchem[0] = par->leaf_tip_source; - } + // add biochemical networks for intracellular reactions here + + // sum all incoming fluxes of PINs + dchem[1] = - SumFluxFromWalls( c, MyModel::PINflux ); + + // auxin degradation + dchem[0] = - par->aux_breakdown * c->Chemical(0); + + } diff --git a/src/TutorialCode/Tutorial5/mymodel.h b/src/TutorialCode/Tutorial5/mymodel.h --- a/src/TutorialCode/Tutorial5/mymodel.h +++ b/src/TutorialCode/Tutorial5/mymodel.h @@ -53,6 +53,8 @@ public: virtual void SetCellColor(CellBase *c, QColor *color); // return number of chemicals virtual int NChem(void); + + virtual double PINflux(CellBase *this_cell, CellBase *adjacent_cell, Wall *w); }; diff --git a/src/TutorialCode/Tutorial5/tutorial5_init.xml b/src/TutorialCode/Tutorial5/tutorial5_init.xml new file mode 100644 index 0000000000000000000000000000000000000000..593dc26168e75475ce9e81ef66669fc9cadd085b GIT binary patch literal 6905 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 zIifJQo6insertItem("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); @@ -1437,16 +1439,58 @@ void Main::FitLeafToCanvas(void) { } void Main::CleanMesh(void) { - - mesh.SettoInitVals(); + vector clean_chem(Cell::NChem()); + vector clean_transporters(Cell::NChem()); + + for (int i=0;iFullRedraw(); - + Plot(); + + editor->FullRedraw(); + // repaint(); } +void Main::CleanMeshChemicals(void) { + + vector clean_chem(Cell::NChem()); + + for (int i=0;iFullRedraw(); + + // repaint(); +} + +void Main::CleanMeshTransporters(void) { + vector clean_transporters(Cell::NChem()); + for (int i=0;iFullRedraw(); + + // repaint(); +} + void Main::RandomizeMesh(void) { vector max_chem(Cell::NChem()); diff --git a/src/canvas.h b/src/canvas.h --- a/src/canvas.h +++ b/src/canvas.h @@ -226,8 +226,11 @@ class Main : public Q3MainWindow, public void shrink(); void zoomIn(); void zoomOut(); - + void CleanMesh(); + void CleanMeshChemicals(void); + void CleanMeshTransporters(void); + void RandomizeMesh(); signals: diff --git a/src/cellbase.cpp b/src/cellbase.cpp --- a/src/cellbase.cpp +++ b/src/cellbase.cpp @@ -234,6 +234,19 @@ void CellBase::SetChemical(int c, double chem[c]=conc; } +void CellBase::SetTransporters(int ch, double conc) { + if (ch>=NChem()) { + stringstream error; + error << "SetChemical: value ch = " << ch << " is out of range\n"; + throw error.str().c_str(); + } + for (list::iterator w=walls.begin(); + w!=walls.end(); + w++) { + (*w)->setTransporter(this, ch, conc); + } +} + ostream &CellBase::print(ostream &os) const { diff --git a/src/cellbase.h b/src/cellbase.h --- a/src/cellbase.h +++ b/src/cellbase.h @@ -118,7 +118,8 @@ class CellBase : public QObject, public source_chem = chem; source_conc = conc; } - + // set chem 1 to conc in all membranes of this cell + void SetTransporters(int chem, double conc); void UnfixNodes(void); void FixNodes(void); void UnsetSource(void) { diff --git a/src/flux_function.h b/src/flux_function.h new file mode 100644 --- /dev/null +++ b/src/flux_function.h @@ -0,0 +1,22 @@ +/* + * flux_function.h + * VirtualLeaf + * + * Created by Roeland Merks on 07-06-10. + * Copyright 2010 __MyCompanyName__. All rights reserved. + * + */ + +// This header file defines a macro "SumFluxFromWalls" that attempts to hide this +// horrendously confusing member function wrapper construct from VirtualLeaf's end users + +// required format of flux_function is: +// double [model class name]::[function name](CellBase *this_cell, CellBase *adjacent_cell, Wall *w) +// e.g.: +// double MyModel::PINflux(CellBase *this_cell, CellBase *adjacent_cell, Wall *w) + +#include "far_mem_5.h" + +#define SumFluxFromWalls( _vleafcellp_, _flux_function_ ) \ +(( _vleafcellp_->ReduceCellAndWalls( far_3_arg_mem_fun( *this, &_flux_function_ ) ) )) + diff --git a/src/mesh.cpp b/src/mesh.cpp --- a/src/mesh.cpp +++ b/src/mesh.cpp @@ -1888,35 +1888,48 @@ void Mesh::DeleteLooseWalls(void) { }*/ -void Mesh::CleanChemicals(const vector &clean_chem, const vector &clean_transporters) { - - if (clean_chem.size()!=(unsigned)Cell::NChem() || clean_transporters.size()!=(unsigned)Cell::NChem()) { - throw "Run time error in Mesh::CleanChemicals: size of clean_chem and clean_transporters should be equal to Cell::NChem()"; - } - for (vector::iterator c=cells.begin(); - c!=cells.end(); - c++) { - - for (int i=0;iSetChemical(i,clean_chem[i]); - } - (*c)->SetNewChemToChem(); + +void Mesh::CleanChemicals(const vector &clean_chem) { + + if (clean_chem.size()!=(unsigned)Cell::NChem()) { + throw "Run time error in Mesh::CleanChemicals: size of clean_chem should be equal to Cell::NChem()"; + } + for (vector::iterator c=cells.begin(); + c!=cells.end(); + c++) { + + for (int i=0;iSetChemical(i,clean_chem[i]); + } + (*c)->SetNewChemToChem(); + + } + + +} + - } +void Mesh::CleanTransporters(const vector &clean_transporters) { + + if (clean_transporters.size()!=(unsigned)Cell::NChem()) { + throw "Run time error in Mesh::CleanTransporters: size ofclean_transporters should be equal to Cell::NChem()"; + } - // clean transporters - for (list::iterator w=walls.begin(); - w!=walls.end(); - w++) { - - for (int i=0;isetTransporters1(i,clean_transporters[i]); (*w)->setNewTransporters1(i,clean_transporters[i]); - (*w)->setTransporters2(i,clean_transporters[i]); (*w)->setNewTransporters2(i,clean_transporters[i]); - } - } - + + // clean transporters + for (list::iterator w=walls.begin(); + w!=walls.end(); + w++) { + + for (int i=0;isetTransporters1(i,clean_transporters[i]); (*w)->setNewTransporters1(i,clean_transporters[i]); + (*w)->setTransporters2(i,clean_transporters[i]); (*w)->setNewTransporters2(i,clean_transporters[i]); + } + } + } + void Mesh::RandomizeChemicals(const vector &max_chem, const vector &max_transporters) { if (max_chem.size()!=(unsigned)Cell::NChem() || max_transporters.size()!=(unsigned)Cell::NChem()) { @@ -2158,7 +2171,8 @@ void Mesh::SettoInitVals(void) { // Amount of PIN1 //clean_chem[1] = 0.; - CleanChemicals(clean_chem, clean_transporters); + CleanChemicals(clean_chem); + CleanTransporters(clean_transporters); } diff --git a/src/mesh.h b/src/mesh.h --- a/src/mesh.h +++ b/src/mesh.h @@ -413,7 +413,8 @@ public: node_sets.push_back(node_set); } - void CleanChemicals(const vector &clean_chem, const vector &clean_transporters); + void CleanChemicals(const vector &clean_chem); + void CleanTransporters(const vector &clean_transporters); void RandomizeChemicals(const vector &max_chem, const vector &max_transporters); inline double getTime(void) const { return time; } string getTimeHours(void) const; diff --git a/src/vleafmacosx_installer.pmdoc/01virtualleaf-contents.xml b/src/vleafmacosx_installer.pmdoc/01virtualleaf-contents.xml new file mode 100644 --- /dev/null +++ b/src/vleafmacosx_installer.pmdoc/01virtualleaf-contents.xml @@ -0,0 +1,1 @@ +modemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemode \ No newline at end of file diff --git a/src/vleafmacosx_installer.pmdoc/01virtualleaf.xml b/src/vleafmacosx_installer.pmdoc/01virtualleaf.xml new file mode 100644 --- /dev/null +++ b/src/vleafmacosx_installer.pmdoc/01virtualleaf.xml @@ -0,0 +1,1 @@ +com.nisb.virtualleaf.virtualleaf.pkg2/Users/roel/VLeaf1.0/V1.0/bin/VirtualLeaf.app/Applications/VLeaf1.0parentrequireAuthorizationrelocatableversioninstallTo.pathidentifierinstallTo01virtualleaf-contents.xmlisRelocatable/CVS$/\.svn$/\.cvsignore$/\.cvspass$/\.DS_Store$ \ No newline at end of file diff --git a/src/vleafmacosx_installer.pmdoc/02models-contents.xml b/src/vleafmacosx_installer.pmdoc/02models-contents.xml new file mode 100644 --- /dev/null +++ b/src/vleafmacosx_installer.pmdoc/02models-contents.xml @@ -0,0 +1,1 @@ +modemodemode \ No newline at end of file diff --git a/src/vleafmacosx_installer.pmdoc/02models.xml b/src/vleafmacosx_installer.pmdoc/02models.xml new file mode 100644 --- /dev/null +++ b/src/vleafmacosx_installer.pmdoc/02models.xml @@ -0,0 +1,1 @@ +com.nisb.virtualleaf.models.pkg1/Users/roel/VLeaf1.0/V1.0/bin/models/Applications/VLeaf1.0/modelsparentrequireAuthorizationinstallTo.pathinstallTo02models-contents.xml/CVS$/\.svn$/\.cvsignore$/\.cvspass$/\.DS_Store$ \ No newline at end of file diff --git a/src/vleafmacosx_installer.pmdoc/03leaves-contents.xml b/src/vleafmacosx_installer.pmdoc/03leaves-contents.xml new file mode 100644 --- /dev/null +++ b/src/vleafmacosx_installer.pmdoc/03leaves-contents.xml @@ -0,0 +1,1 @@ +modemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemodemode \ No newline at end of file diff --git a/src/vleafmacosx_installer.pmdoc/03leaves.xml b/src/vleafmacosx_installer.pmdoc/03leaves.xml new file mode 100644 --- /dev/null +++ b/src/vleafmacosx_installer.pmdoc/03leaves.xml @@ -0,0 +1,1 @@ +com.nisb.virtualleaf.leaves.pkg1/Users/roel/VLeaf1.0/V1.0/data/leaves/Applications/VLeaf1.0/leavesparentrelocatablerequireAuthorizationinstallTo.pathinstallTo03leaves-contents.xml/CVS$/\.svn$/\.cvsignore$/\.cvspass$/\.DS_Store$ \ No newline at end of file diff --git a/src/vleafmacosx_installer.pmdoc/index.xml b/src/vleafmacosx_installer.pmdoc/index.xml new file mode 100644 --- /dev/null +++ b/src/vleafmacosx_installer.pmdoc/index.xml @@ -0,0 +1,1 @@ +VirtualLeaf/Users/roel/VLeaf1.0/VirtualLeaf.mpkgcom.nisb VirtualLeaf is a cell-based computer-modeling framework for plant tissue morphogenesis./Users/roel/Documents/Manuscripts/Plant Physiology - VirtualLeaf/Fig5/leaf.000077.jpg/Users/roel/VLeaf1.0/V1.0/COPYING.txt01virtualleaf.xml02models.xml03leaves.xmlproperties.userDomainproperties.titledescriptionproperties.anywhereDomain \ No newline at end of file diff --git a/src/vleafmodel.h b/src/vleafmodel.h new file mode 100644 --- /dev/null +++ b/src/vleafmodel.h @@ -0,0 +1,20 @@ +/* + * vleafmodel.h + * mymodel + * + * Created by Roeland Merks on 08-06-10. + * Copyright 2010 __MyCompanyName__. All rights reserved. + * + */ + +#include +#include +#include +#include "simplugin.h" + +#include "parameter.h" + +#include "wallbase.h" +#include "cellbase.h" +#include "mymodel.h" +#include "flux_function.h"