COPASI API  4.16.103
CQAnimationWindow.cpp
Go to the documentation of this file.
1 // Copyright (C) 2013 - 2015 by Pedro Mendes, Virginia Tech Intellectual
2 // Properties, Inc., University of Heidelberg, and The University
3 // of Manchester.
4 // All rights reserved.
5 
6 #include <QtGui/QGraphicsItem>
7 #include <QtGui/QGraphicsEffect>
8 #include <QtGui/QDockWidget>
9 #include <QtGui/QFileDialog>
10 #include <QtCore/QDateTime>
11 #include <QtGui/QToolBar>
12 
16 #include <qlayout/CQLayoutScene.h>
17 #include <qlayout/CQCopasiEffect.h>
19 
22 
23 #include <layout/CLayout.h>
24 
28 
29 #include <model/CModel.h>
30 #include <model/CReaction.h>
34 
36 {
37  virtual void initialize(const CCopasiDataModel &dataModel)
38  {
39  mpDataModel = &dataModel;
40  const CModel& model = *dataModel.getModel();
41  const CCopasiVector< CMetab > & metabs = model.getMetabolites();
43 
44  while (it != metabs.end())
45  {
46  mEntries.push_back(new CQEffectDescription((*it)->getCN()));
47  ++it;
48  }
49 
50  // initialize number of steps
51  const CCopasiVector< CMoiety > & moieties = model.getMoieties();
52  mNumSteps = moieties.size();
53  }
54 
55  virtual void getScales(std::vector<qreal>& scales, int step)
56  {
57  if (mpDataModel == NULL) return;
58 
59  const CModel& model = *mpDataModel->getModel();
60  const CCopasiVector< CMoiety > & moieties = model.getMoieties();
61  mNumSteps = moieties.size();
62 
63  if (moieties.size() <= (size_t)step) return;
64 
65  const CMoiety* moiety = moieties[step];
66  const std::vector<std::pair< C_FLOAT64, CMetab * > > &eqn = moiety->getEquation();
67  std::map<std::string, double> cnValueMap;
68  std::vector<std::pair< C_FLOAT64, CMetab * > >::const_iterator it = eqn.begin();
69 
70  while (it != eqn.end())
71  {
72  cnValueMap[(*it).second->getCN()] = (*it).first;
73  ++it;
74  }
75 
76  for (size_t i = 0; i < mEntries.size(); ++i)
77  scales.push_back(cnValueMap[mEntries[i]->getCN()]);
78  }
79 };
80 
81 /**
82  * Animation, that displays one fluxmode per frame
83  */
85 {
86 public:
87  virtual void initialize(const CCopasiDataModel &dataModel)
88  {
89  mpDataModel = &dataModel;
90  const CModel& model = *dataModel.getModel();
91  const CCopasiVector< CReaction > & reactions = model.getReactions();
93  size_t count = 0;
94 
95  while (it != reactions.end())
96  {
97  mEntries.push_back(new CQEffectDescription((*it)->getCN(), CQEffectDescription::Colorize, Qt::black, Qt::red));
98  indexMap[count] = (*it)->getCN();
99  ++it;
100  ++count;
101  }
102 
103  // initialize number of steps
104  CEFMTask *task = dynamic_cast< CEFMTask * >((*mpDataModel->getTaskList())["Elementary Flux Modes"]);
105 
106  if (task == NULL) return;
107 
108  const CEFMProblem* problem = dynamic_cast<const CEFMProblem*>(task->getProblem());
109 
110  if (problem == NULL) return;
111 
112  const std::vector< CFluxMode >& fluxModes = problem->getFluxModes();
113  mNumSteps = fluxModes.size();
114  }
115  virtual void getScales(std::vector<qreal>& scales, int step)
116  {
117  if (mpDataModel == NULL) return;
118 
119  CEFMTask *task = dynamic_cast< CEFMTask * >((*mpDataModel->getTaskList())["Elementary Flux Modes"]);
120 
121  if (task == NULL) return;
122 
123  const CEFMProblem* problem = dynamic_cast<const CEFMProblem*>(task->getProblem());
124 
125  if (problem == NULL) return;
126 
127  const std::vector< CFluxMode >& fluxModes = problem->getFluxModes();
128  mNumSteps = fluxModes.size();
129 
130  if (fluxModes.size() <= (size_t)step) return;
131 
132  const CFluxMode& mode = fluxModes[step];
133 
134  const std::vector< const CReaction * > &reordered = problem->getReorderedReactions();
135  std::map<std::string, double> cnValueMap;
136 
137  CFluxMode::const_iterator modeIt = mode.begin();
138 
139  while (modeIt != mode.end())
140  {
141  const size_t reactionIndex = (*modeIt).first;
142  const double coefficient = (*modeIt).second;
143  cnValueMap[reordered[reactionIndex]->getCN()] = qAbs(coefficient);
144  ++modeIt;
145  }
146 
147  for (size_t i = 0; i < mEntries.size(); ++i)
148  scales.push_back(cnValueMap[mEntries[i]->getCN()]);
149  }
150 
151 protected:
152  std::map<size_t, std::string> indexMap;
153 };
154 
155 #include <model/CModel.h>
157 /**
158  * Animation that displays the concentrations per time
159  */
161 {
162 public:
163  double getMax(const CTimeSeries* series, size_t index = C_INVALID_INDEX)
164  {
165  double max = 0;
166 
167  if (index != C_INVALID_INDEX)
168  {
169  for (size_t i = 0; i < series->getRecordedSteps(); ++i)
170  {
171  max = qMax(max, series->getData(i, index));
172  }
173  }
174  else
175  {
176 
177  for (size_t i = 0; i < series->getRecordedSteps(); ++i)
178  {
179  for (size_t j = 0; j < series->getNumVariables(); ++j)
180  {
181  max = qMax(max, series->getData(i, j));
182  }
183  }
184  }
185 
186  return max;
187  }
188 
189  size_t getIndex(const CTimeSeries*series, const std::string& cn)
190  {
191  const std::string& key = keyMap[cn];
192 
193  for (size_t i = 0; i < series->getNumVariables(); ++i)
194  if (series->getKey(i) == key)
195  return i;
196 
197  return C_INVALID_INDEX;
198  }
199 
200  double getValue(const CTimeSeries* series, const std::string& cn, int step)
201  {
202  return series->getData(step, getIndex(series, cn));
203  }
204 
205  virtual void getScales(std::vector<qreal>& scales, int step)
206  {
207  if (mpDataModel == NULL) return;
208 
209  CTrajectoryTask *task = dynamic_cast< CTrajectoryTask * >((*mpDataModel->getTaskList())["Time-Course"]);
210 
211  if (task == NULL) return;
212 
213  const CTimeSeries* series = &task->getTimeSeries();
214 
215  if (series == NULL) return;
216 
217  mNumSteps = series->getRecordedSteps();
218 
219  if (series->getRecordedSteps() < (size_t)step)
220  return;
221 
222  double max = mMode == CQCopasiAnimation::Global ? getMax(series) : 0;
223 
224  for (size_t i = 0; i < mEntries.size(); ++i)
225  {
227  max = getMax(series, getIndex(series, mEntries[i]->getCN()));
228 
229  double value = getValue(series, mEntries[i]->getCN(), step);
230  scales.push_back(value / max);
231  }
232  }
233 
234  virtual void initialize(const CCopasiDataModel &dataModel)
235  {
236  mpDataModel = &dataModel;
237  const CModel& model = *dataModel.getModel();
238  const CCopasiVector< CMetab > & metabs = model.getMetabolites();
240 
241  while (it != metabs.end())
242  {
243  mEntries.push_back(new CQEffectDescription((*it)->getCN(), CQEffectDescription::Scale));
244  keyMap[(*it)->getCN()] = (*it)->getKey();
245  ++it;
246  }
247 
248  // initialize number of steps
249  CTrajectoryTask *task = dynamic_cast< CTrajectoryTask * >((*mpDataModel->getTaskList())["Time-Course"]);
250 
251  if (task == NULL) return;
252 
253  const CTimeSeries* series = &task->getTimeSeries();
254 
255  if (series == NULL) return;
256 
257  mNumSteps = series->getRecordedSteps();
258  }
259 protected:
260  std::map<std::string, std::string> keyMap;
261 };
262 
264  : mpScene(NULL)
265  , mpModel(NULL)
266  , mpWindowMenu(NULL)
267  , mAnimation(NULL)
268  , mpLayoutThread(NULL)
269  , mpCopy(NULL)
270 {
271  init();
272  setScene(new CQLayoutScene(layout, dataModel), dataModel);
273 }
274 
276  : mpScene(NULL)
277  , mpModel(NULL)
278  , mpWindowMenu(NULL)
279  , mAnimation(NULL)
280  , mpLayoutThread(NULL)
281  , mpCopy(NULL)
282 {
283  init();
284 }
285 
287 {
288  setupUi(this);
290  setUnifiedTitleAndToolBarOnMac(true);
291 
292  actionAuto_Layout->setIcon(CQIconResource::icon(CQIconResource::play));
293  actionRandomize_Layout->setIcon(CQIconResource::icon(CQIconResource::roll));
294  actionExport->setIcon(CQIconResource::icon(CQIconResource::fileExport));
295 
296  QMenu* viewMenu = menuBar()->addMenu(tr("&View"));
297  graphicsView->fillZoomMenu(viewMenu);
298 
299  QToolBar* actionToolbar = this->addToolBar("Actions");
300  actionToolbar->addAction(actionExport);
301  actionToolbar->addAction(actionAuto_Layout);
302  actionToolbar->addAction(actionRandomize_Layout);
303 
304  QToolBar* selectToolbar = this->addToolBar("Select");
305  graphicsView->fillSelectionToolBar(selectToolbar);
306 
307  QToolBar* viewToolBar = this->addToolBar("View");
308  graphicsView->fillZoomTooBar(viewToolBar);
309 
310  mpWindowMenu = menuBar()->addMenu(tr("&Window"));
311 
312  mpLayoutThread = new CQLayoutThread(this);
313  connect(mpLayoutThread, SIGNAL(layoutFinished()), this, SLOT(slotStopLayout()));
314  connect(mpLayoutThread, SIGNAL(layoutStateChanged(QSharedPointer<CLayoutState>)), this, SLOT(slotLayoutStateChanged(QSharedPointer<CLayoutState>)));
315 
316  QDockWidget* pParameterWindow = mpLayoutThread->getParameterWindow();
317  addDockWidget(Qt::LeftDockWidgetArea, pParameterWindow);
318  viewMenu->addSeparator();
319  viewMenu->addAction(pParameterWindow->toggleViewAction());
320  toggleUI(false);
321 }
322 
324 {
325  QString fileName = QFileDialog::getSaveFileName(this, tr("Export Image"),
326  "",
327  tr("PDF files (*.pdf);;Images (*.png *.xpm *.jpg);;All files (*.*)"));
328  graphicsView->slotSaveToFile(fileName);
329 }
330 
332 {
334 
335  if (mpCopy != NULL)
336  {
337  delete mpCopy;
338  mpCopy = NULL;
339  }
340 
341  if (mAnimation != NULL)
342  {
343  delete mAnimation;
344  mAnimation = NULL;
345  }
346 
348 
349  pdelete(mpScene);
351 }
352 
354 {
355  mpModel = dataModel;
356 
357  if (mpScene != NULL && mpScene != scene)
358  pdelete(mpScene);
359 
360  mpScene = scene;
361  this->graphicsView->setScene(mpScene);
362  mpScene->recreate();
363  graphicsView->setDataModel(dataModel, scene->getCurrentLayout());
364  this->graphicsView->invalidateScene();
365  //setAnimation(new QConservedSpeciesAnimation(), dataModel);
366  //setAnimation(new QFluxModeAnimation(), dataModel);
367  setAnimation(new QTimeCourseAnimation(), dataModel);
368 }
369 
371 {
372  QAction *action = dynamic_cast<QAction *>(sender());
373 
374  if (action == NULL) return;
375 
376  if (action->text() == "View Time Course")
377  {
378  setAnimation(new QTimeCourseAnimation(), graphicsView->getDataModel());
379  }
380  else if (action->text() == "View Elementary Modes")
381  {
382  setAnimation(new QFluxModeAnimation(), graphicsView->getDataModel());
383  }
384  else if (action->text() == "View Conserved Species")
385  {
386  setAnimation(new QConservedSpeciesAnimation(), graphicsView->getDataModel());
387  }
388 }
389 
391 {
392  return mpWindowMenu;
393 }
394 
396 {
397  if (mAnimation != NULL)
398  {
400  delete mAnimation;
401  }
402 
403  mAnimation = animation;
404  mAnimation->initialize(*dataModel);
405  size_t numSteps = mAnimation->getNumSteps();
406 
407  if (numSteps > 0)
408  {
409  mpControls->setVisible(true);
410  mpControls->setNumSteps(numSteps);
411  slotShowStep(0);
412  }
413  else
414  {
415  mpControls->setVisible(false);
416  statusBar()->showMessage("No data for the animation! Run task first, and load data.", 1000);
417  }
418 }
419 
421 {
422  statusBar()->showMessage(QString("Displaying step %1").arg(step + 1), 1000);
423 
424  if (mAnimation == NULL) return;
425 
427  mpControls->setNumSteps(mAnimation->getNumSteps());
428  mpScene->update();
429 }
430 
431 void CQAnimationWindow::closeEvent(QCloseEvent * /*closeEvent*/)
432 {
433  // stop the autolayout
435 }
436 
438 {
440  editor.initFrom(mAnimation);
441 
442  if (editor.exec() == QDialog::Accepted)
443  {
444  editor.saveTo(mAnimation);
445  }
446 }
447 
449 {
451  mpLayoutThread->wait();
454 }
455 
457 #include <layout/CLayoutEngine.h>
458 
459 #include <QtCore/QAbstractEventDispatcher>
460 #include <QtCore/QAbstractEventDispatcher>
461 
462 #include <QtCore/QTimer>
463 
465 {
466  if (mpCopy != NULL)
467  {
468  delete mpCopy;
469  mpCopy = NULL;
470  }
471 
472  actionAuto_Layout->setChecked(false);
473  actionAuto_Layout->setText("Run Auto Layout");
474  actionAuto_Layout->setIcon(CQIconResource::icon(CQIconResource::play));
475 }
476 
477 void CQAnimationWindow::slotLayoutStateChanged(QSharedPointer<CLayoutState> state)
478 {
479  state->applyTo(mpScene->getCurrentLayout());
480  mpScene->recreate();
481 }
482 
483 void CQAnimationWindow::toggleUI(bool isPlaying)
484 {
485  if (isPlaying)
486  {
487  actionAuto_Layout->setChecked(true);
488  actionAuto_Layout->setText("Stop Auto Layout");
489  actionAuto_Layout->setIcon(CQIconResource::icon(CQIconResource::pause));
490  }
491  else
492  {
494  }
495 }
496 
497 /// <summary>
498 /// Slots the auto layout.
499 /// </summary>
501 {
502  if (sender() != NULL && !actionAuto_Layout->isChecked())
503  {
505  return;
506  }
507 
508  toggleUI(true);
509 
510  // work on a copy!
512 
513  if (mpCopy != NULL)
514  {
515  delete mpCopy;
516  mpCopy = NULL;
517  }
518 
521 }
const CLayout * getCurrentLayout() const
void slotAutoLayout()
Slots the auto layout.
const size_t & getRecordedSteps() const
virtual void getScales(std::vector< qreal > &scales, int step)
void createSpringLayout(CLayout *layout, int numIntervals=1000, int updateWait=100)
static void tagLayout(CLayout *layout)
void removeFromMainWindow(CopasiUI3Window *window=NULL)
#define pdelete(p)
Definition: copasi.h:215
const size_t & getNumVariables() const
virtual int getNumSteps()
virtual void removeFromScene(CQLayoutScene &scene)
CCopasiProblem * getProblem()
virtual void getScales(std::vector< qreal > &scales, int step)
const CCopasiVector< CMetab > & getMetabolites() const
Definition: CModel.cpp:1051
virtual size_t size() const
iterator begin()
void toggleUI(bool isPlaying)
double getMax(const CTimeSeries *series, size_t index=C_INVALID_INDEX)
CCopasiDataModel * mpModel
size_t getIndex(const CTimeSeries *series, const std::string &cn)
#define C_INVALID_INDEX
Definition: copasi.h:222
const std::vector< std::pair< C_FLOAT64, CMetab * > > & getEquation() const
Definition: CMoiety.cpp:267
virtual QMenu * getWindowMenu() const
const CCopasiVector< CMoiety > & getMoieties() const
Definition: CModel.cpp:1163
void setScene(CQLayoutScene *scene, CCopasiDataModel *dataModel)
void setAnimation(CQCopasiAnimation *animation, CCopasiDataModel *dataModel)
const std::string & getKey(const size_t &variable) const
iterator end()
std::vector< CType * >::const_iterator const_iterator
Definition: CCopasiVector.h:57
const std::vector< CFluxMode > & getFluxModes() const
Definition: CEFMProblem.cpp:80
void slotLayoutStateChanged(QSharedPointer< CLayoutState > state)
virtual void initialize(const CCopasiDataModel &dataModel)
CQLayoutThread * mpLayoutThread
virtual void getScales(std::vector< qreal > &scales, int step)
static const QIcon & icon(const IconID &id)
virtual void initialize(const CCopasiDataModel &model)=0
CCopasiVectorN< CCopasiTask > * getTaskList()
const_iterator begin() const
Definition: CFluxMode.cpp:69
const std::vector< const CReaction * > & getReorderedReactions() const
Definition: CEFMProblem.cpp:86
std::map< size_t, std::string > indexMap
const CTimeSeries & getTimeSeries() const
const C_FLOAT64 & getData(const size_t &step, const size_t &variable) const
void randomizeLayout(CLayout *layout)
void saveTo(CQCopasiAnimation *target)
CQLayoutScene * mpScene
std::vector< CQEffectDescription * > mEntries
QDockWidget * getParameterWindow()
std::map< size_t, C_FLOAT64 >::const_iterator const_iterator
Definition: CFluxMode.h:43
virtual void closeEvent(QCloseEvent *closeEvent)
CCopasiVectorNS< CReaction > & getReactions()
Definition: CModel.cpp:1039
const CCopasiDataModel * mpDataModel
virtual void initialize(const CCopasiDataModel &dataModel)
virtual void applyToScene(CQLayoutScene &scene, int step)
double getValue(const CTimeSeries *series, const std::string &cn, int step)
Definition: CModel.h:50
std::map< std::string, std::string > keyMap
CQCopasiAnimation * mAnimation
void initFrom(CQCopasiAnimation *other)
const_iterator end() const
Definition: CFluxMode.cpp:74
virtual void initialize(const CCopasiDataModel &dataModel)
#define max(a, b)
Definition: f2c.h:176