COPASI API  4.16.103
CDotOutput.cpp
Go to the documentation of this file.
1 // Begin CVS Header
2 // $Source: /Volumes/Home/Users/shoops/cvs/copasi_dev/copasi/model/CDotOutput.cpp,v $
3 // $Revision: 1.10 $
4 // $Name: $
5 // $Author: shoops $
6 // $Date: 2011/11/23 15:45:43 $
7 // End CVS Header
8 
9 // Copyright (C) 2011 - 2010 by Pedro Mendes, Virginia Tech Intellectual
10 // Properties, Inc., University of Heidelberg, and The University
11 // of Manchester.
12 // All rights reserved.
13 
14 // Copyright (C) 2008 by Pedro Mendes, Virginia Tech Intellectual
15 // Properties, Inc., EML Research, gGmbH, University of Heidelberg,
16 // and The University of Manchester.
17 // All rights reserved.
18 
19 // Copyright (C) 2001 - 2007 by Pedro Mendes, Virginia Tech Intellectual
20 // Properties, Inc. and EML Research, gGmbH.
21 // All rights reserved.
22 
23 #include "copasi.h"
24 
25 #include "CDotOutput.h"
26 
30 #include "model/CModel.h"
31 
33  mInUpToDateList(false),
34  mSimulatedRefreshesIndex(C_INVALID_INDEX),
35  mNonSimulatedRefreshesIndex(C_INVALID_INDEX),
36  mConstantRefreshesIndex(C_INVALID_INDEX)
37 {};
38 
40  : mSkipCompartments(false),
42 {}
43 
44 void CDotOutput::writeDependencies(std::ostream & os, const CModel* pModel, const CCopasiObject * rootNode)
45 {
46  const CCopasiObject * obj;
47 
48  if (rootNode)
49  obj = rootNode;
50  else
51  obj = pModel->getObjectDataModel();
52 
53  mObjects.clear();
54 
55  os << "digraph G {\n";
56 
57  //edges
58  writeDotRecursively(obj, os);
59 
60  //this is done after the edges since it requires all relevant object to be in the mObjects map
62 
63  //nodes
64  std::map<const CCopasiObject*, ObjectData>::const_iterator it, itEnd = mObjects.end();
65 
66  for (it = mObjects.begin(); it != itEnd; ++it)
67  {
68  writeObjectNode(os, it->first, it->second);
69  }
70 
71  os << "}" << std::endl;
72 }
73 
74 void CDotOutput::findObjectsWithUpdateMethod(const CCopasiObject * obj, std::set<const CCopasiObject*> & objectSet, size_t recursion) const
75 {
76  if (!obj) return;
77 
78  if (recursion > 10) return; //limit recursion
79 
80  //it is assumed *obj has no UpdateMethod
81 
82  std::set< const CCopasiObject * >::const_iterator it, itEnd = obj->getDirectDependencies().end();
83 
84  for (it = obj->getDirectDependencies().begin(); it != itEnd; ++it)
85  {
86  if ((*it)->hasUpdateMethod())
87  objectSet.insert(*it);
88  else
89  findObjectsWithUpdateMethod(*it, objectSet, recursion + 1);
90  }
91 }
92 
93 void CDotOutput::writeDotRecursively(const CCopasiObject * obj, std::ostream & os)
94 {
95 
97  {
98  std::set< const CCopasiObject * >::const_iterator it, itEnd = obj->getDirectDependencies().end();
99 
100  for (it = obj->getDirectDependencies().begin(); it != itEnd; ++it)
101  {
102  //skip deps on compartments
103  if (mSkipCompartments)
104  if ((*it)->getObjectParent() && ((*it)->getObjectParent()->getObjectType() == "Compartment"
105  || (*it)->getObjectType() == "Compartment")) continue;
106 
108  {
109  if ((*it)->hasUpdateMethod())
110  {
111  writeEdge(os, obj, *it);
112  }
113  else
114  {//find indirect dependencies
115  std::set<const CCopasiObject* > tmpObjectSet;
116  findObjectsWithUpdateMethod(*it, tmpObjectSet);
117  std::set<const CCopasiObject* >::const_iterator tmpIt, tmpItEnd = tmpObjectSet.end();
118 
119  for (tmpIt = tmpObjectSet.begin(); tmpIt != tmpItEnd; ++tmpIt)
120  writeEdge(os, obj, *tmpIt, true); //
121  }
122  }
123  else
124  {
125  writeEdge(os, obj, *it);
126  }
127  }
128  }
129 
130  //recursion
131  if (obj->isContainer())
132  {
133  CCopasiContainer* container;
134  container = (CCopasiContainer*)obj;
135 
136  CCopasiContainer::objectMap::const_iterator it = container->getObjects().begin();
137 
138  for (; it != container->getObjects().end(); ++it)
139  {
140  //the next line skips name references...
141  if (it->second->getObjectName() == "Name") continue;
142 
143  if (it->second->getObjectType() == "Function") continue;
144 
145  //skip if the contained object is not owned by this container
146  if (it->second->getObjectParent() != container) continue;
147 
148  writeDotRecursively(it->second, os);
149  }
150 
151  //return;
152  }
153 }
154 
155 void CDotOutput::writeObjectNode(std::ostream & os, const CCopasiObject * ptr, const ObjectData & od) const
156 {
157  os << "//" << std::endl;
158 
159  bool flagUM = ptr->hasUpdateMethod();
160  bool flagRM = ptr->getRefresh() != NULL;
161  bool flagInUpToDateList = od.mInUpToDateList;
162 
163  std::ostringstream oss;
164 
166  oss << "SR=" << od.mSimulatedRefreshesIndex << " ";
167 
169  oss << "NSR=" << od.mNonSimulatedRefreshesIndex << " ";
170 
172  oss << "CR=" << od.mConstantRefreshesIndex << " ";
173 
174  os << "\"" << ptr->getObjectDisplayName() << "\" [shape=plaintext, color=blue, " << std::endl;
175  os << "label=<\n";
176  os << "<TABLE CELLSPACING=\"0\">\n";
177  os << " <TR><TD COLSPAN=\"4\">" << ptr->getObjectDisplayName() << "</TD></TR>\n";
178  os << " <TR>\n";
179  os << " <TD " << (flagUM ? "BGCOLOR=\"red\"" : " ") << "><FONT POINT-SIZE=\"7.0\">UM</FONT>" << "" << "</TD>\n";
180  os << " <TD " << (flagRM ? "BGCOLOR=\"green\"" : " ") << "><FONT POINT-SIZE=\"7.0\">RM</FONT>" << "" << "</TD>\n";
181  os << " <TD " << (flagInUpToDateList ? "BGCOLOR=\"blue\"" : " ") << "><FONT POINT-SIZE=\"7.0\">UtD</FONT>" << "" << "</TD>\n";
182  os << " <TD><FONT POINT-SIZE=\"7.0\">" << oss.str() << " </FONT></TD>\n";
183  os << " </TR>\n";
184  os << "</TABLE>\n";
185  os << "\n";
186  os << ">];\n";
187 }
188 
189 void CDotOutput::writeEdge(std::ostream & os, const CCopasiObject * ptr1, const CCopasiObject * ptr2, bool indirect)
190 {
191  assert(ptr1);
192  assert(ptr2);
193 
194  mObjects[ptr1];
195  mObjects[ptr2];
196 
197  os << "\"" << ptr1->getObjectDisplayName() << "\" -> \"" << ptr2->getObjectDisplayName() << "\"";
198 
199  if (indirect) os << " [color=blue]";
200 
201  os << "\n";
202 }
203 
205 {
206  const std::set< const CCopasiObject * > & objectSet = model->getUptoDateObjects();
207 
208  std::set< const CCopasiObject * >::const_iterator it, itEnd = objectSet.end();
209 
210  for (it = objectSet.begin(); it != itEnd; ++it)
211  {
212  mObjects[*it].mInUpToDateList = true;
213  }
214 
215  size_t i, imax;
216 
217  imax = model->getListOfSimulatedRefreshes().size();
218 
219  for (i = 0; i < imax; ++i)
220  {
222 
223  if (pOD) pOD->mSimulatedRefreshesIndex = i;
224  }
225 
226  imax = model->getListOfNonSimulatedRefreshes().size();
227 
228  for (i = 0; i < imax; ++i)
229  {
231 
232  if (pOD) pOD->mNonSimulatedRefreshesIndex = i;
233  }
234 
235  imax = model->getListOfConstantRefreshes().size();
236 
237  for (i = 0; i < imax; ++i)
238  {
240 
241  if (pOD) pOD->mConstantRefreshesIndex = i;
242  }
243 
244  /* const std::vector< Refresh * > getListOfSimulatedRefreshes() const; //mSimulatedRefreshes;
245  const std::vector< Refresh * > getListOfConstantRefreshes() const; //mConstantRefreshes;
246  const std::vector< Refresh * > getListOfNonSimulatedRefreshes() const; //mNonSimulatedRefreshes;
247  */
248 }
249 
251 {
252  std::map <const CCopasiObject*, ObjectData>::iterator it, itEnd = mObjects.end();
253 
254  for (it = mObjects.begin(); it != itEnd; ++it)
255  {
256  if (it->first->getRefresh() == ref) return &it->second;
257  }
258 
259  return NULL;
260 }
261 
262 void CDotOutput::simpleCall(const CModel* pModel)
263 {
264  std::ofstream os;
265  os.open("CopasiDependencies.dot", std::ios::out);
266 
269  writeDependencies(os, pModel);
270 
271  os.close();
272 }
CCopasiDataModel * getObjectDataModel()
virtual Refresh * getRefresh() const
bool isContainer() const
void findObjectsWithUpdateMethod(const CCopasiObject *obj, std::set< const CCopasiObject * > &objectSet, size_t recursion=0) const
Definition: CDotOutput.cpp:74
ObjectData * getObjectDataFromRefresh(const Refresh *ref)
Definition: CDotOutput.cpp:250
virtual std::string getObjectDisplayName(bool regular=true, bool richtext=false) const
void setOnlyAlgebraicDependencies(bool b)
Definition: CDotOutput.h:44
std::map< const CCopasiObject *, ObjectData > mObjects
Definition: CDotOutput.h:77
const std::vector< Refresh * > & getListOfConstantRefreshes() const
Definition: CModel.cpp:4139
virtual const objectMap & getObjects() const
void writeEdge(std::ostream &os, const CCopasiObject *ptr1, const CCopasiObject *ptr2, bool indirect=false)
Definition: CDotOutput.cpp:189
const std::set< const CCopasiObject * > & getUptoDateObjects() const
Definition: CModel.cpp:1178
#define C_INVALID_INDEX
Definition: copasi.h:222
size_t mSimulatedRefreshesIndex
Definition: CDotOutput.h:53
const std::vector< Refresh * > & getListOfSimulatedRefreshes() const
Definition: CModel.cpp:4136
void simpleCall(const CModel *pModel)
Definition: CDotOutput.cpp:262
bool mSkipCompartments
Definition: CDotOutput.h:74
void writeDependencies(std::ostream &os, const CModel *pModel, const CCopasiObject *rootNode=NULL)
Definition: CDotOutput.cpp:44
void writeObjectNode(std::ostream &os, const CCopasiObject *ptr, const ObjectData &od) const
Definition: CDotOutput.cpp:155
const std::vector< Refresh * > & getListOfNonSimulatedRefreshes() const
Definition: CModel.cpp:4142
void writeDotRecursively(const CCopasiObject *obj, std::ostream &os)
Definition: CDotOutput.cpp:93
void updateObjectNodesFromModel(const CModel *model)
Definition: CDotOutput.cpp:204
void setSkipDependenciesOnCompartments(bool b)
Definition: CDotOutput.h:43
Header file of class CCopasiContainer.
bool hasUpdateMethod() const
virtual const DataObjectSet & getDirectDependencies(const DataObjectSet &context=DataObjectSet()) const
size_t mNonSimulatedRefreshesIndex
Definition: CDotOutput.h:54
bool mOnlyAlgebraicDependencies
Definition: CDotOutput.h:75
size_t mConstantRefreshesIndex
Definition: CDotOutput.h:55
Definition: CModel.h:50