Beispiel #1
0
CCopasiObject::DataObjectSet CMetab::getDeletedObjects() const
{
  CCopasiObject::DataObjectSet Deleted = CModelEntity::getDeletedObjects();

  Deleted.insert(mpIConcReference);
  Deleted.insert(mpConcReference);
  Deleted.insert(mpConcRateReference);
  Deleted.insert(mpTTReference);

  return Deleted;
}
Beispiel #2
0
bool CQUnitDM::removeRows(QModelIndexList rows, const QModelIndex&)
{
  if (rows.isEmpty())
    return false;

  assert(CCopasiRootContainer::getDatamodelList()->size() > 0);
  CCopasiDataModel* pDataModel = &CCopasiRootContainer::getDatamodelList()->operator[](0);
  assert(pDataModel != NULL);
  CModel * pModel = pDataModel->getModel();

  if (pModel == NULL)
    return false;

  // Build the list of pointers to items to be deleted
  // before actually deleting any item.

  QList <CUnitDefinition *> pUnitDefQList;
  QModelIndexList::const_iterator i;
  CUnitDefinition * pUnitDef;

  for (i = rows.begin(); i != rows.end(); ++i)
    {
      if (!isDefaultRow(*i) &&
          (pUnitDef = &CCopasiRootContainer::getUnitList()->operator[](i->row())) != NULL &&
          pModel->getUnitSymbolUsage(pUnitDef->getSymbol()).empty() &&
          !pUnitDef->isReadOnly())//Don't delete built-ins or used units
        pUnitDefQList.append(&CCopasiRootContainer::getUnitList()->operator[](i->row()));
    }

  for (QList <CUnitDefinition *>::const_iterator j = pUnitDefQList.begin(); j != pUnitDefQList.end(); ++j)
    {
      size_t delRow =
        CCopasiRootContainer::getUnitList()->CCopasiVector< CUnitDefinition >::getIndex(*j);

      if (delRow != C_INVALID_INDEX)
        {
          CCopasiObject::DataObjectSet DeletedObjects;
          DeletedObjects.insert(*j);

          QMessageBox::StandardButton choice =
            CQMessageBox::confirmDelete(NULL, "unit",
                                        FROM_UTF8((*j)->getObjectName()),
                                        DeletedObjects);

          if (choice == QMessageBox::Ok)
            removeRow((int) delRow);
        }
    }

  return true;
}
Beispiel #3
0
// static
bool CCopasiObject::compare(const CCopasiObject * lhs, const CCopasiObject * rhs)
{
  if (lhs != rhs)
    {
      CCopasiObject::DataObjectSet Candidates;
      CCopasiObject::DataObjectSet VerifiedSet;

      Candidates.insert(lhs);

      if (rhs->hasCircularDependencies(Candidates, VerifiedSet))
        return true;
    }

  return false;
}
Beispiel #4
0
// virtual
bool CCopasiObject::mustBeDeleted(const CCopasiObject::DataObjectSet & deletedObjects) const
{
  bool MustBeDeleted = false;

  DataObjectSet::const_iterator it = mDependencies.begin();
  DataObjectSet::const_iterator end = mDependencies.end();

  for (; it != end; ++it)
    {
      if (deletedObjects.find(*it) != deletedObjects.end())
        {
          MustBeDeleted = true;
          break;
        }
    }

  return MustBeDeleted;
}
Beispiel #5
0
void CMetab::compileIsInitialConcentrationChangeAllowed()
{
  // We check whether changing the initial concentration will lead to circular
  // dependencies in the system.

  // These circular dependencies must always involve the initial particle number, i.e.,
  // it suffices to check whether the initial particle number has circular dependencies when the
  // concentration is changes.

  CCopasiObject::DataObjectSet Candidates;
  CCopasiObject::DataObjectSet Verified;
  CCopasiObject::DataObjectSet Context;

  Context.insert(this->mpIConcReference);

  mIsInitialConcentrationChangeAllowed = !mpIValueReference->hasCircularDependencies(Candidates, Verified, Context);

  return;
}
Beispiel #6
0
// virtual
bool CEvent::mustBeDeleted(const CCopasiObject::DataObjectSet & deletedObjects) const
{
  bool MustBeDeleted = false;

  CCopasiObject::DataObjectSet ChildObjects;

  if (mpTriggerExpression != NULL)
    {
      ChildObjects.insert(mpTriggerExpression);
    }

  if (mpDelayExpression != NULL)
    {
      ChildObjects.insert(mpDelayExpression);
    }

  if (mpPriorityExpression != NULL)
    {
      ChildObjects.insert(mpPriorityExpression);
    }

  // We need to add all assignment targets and expressions
  CCopasiVector< CEventAssignment >::const_iterator itAssignment = mAssignments.begin();
  CCopasiVector< CEventAssignment >::const_iterator endAssignment = mAssignments.end();

  for (; itAssignment != endAssignment; ++itAssignment)
    {
      if (itAssignment->getTargetObject() != NULL)
        {
          ChildObjects.insert(itAssignment->getTargetObject());
        }

      if (itAssignment->getExpressionPtr() != NULL)
        {
          ChildObjects.insert(itAssignment->getExpressionPtr());
        }
    }

  DataObjectSet::const_iterator it = ChildObjects.begin();
  DataObjectSet::const_iterator end = ChildObjects.end();

  for (; it != end; ++it)
    {
      if ((*it)->mustBeDeleted(deletedObjects))
        {
          MustBeDeleted = true;
          break;
        }
    }

  return MustBeDeleted;
}
Beispiel #7
0
bool CCopasiObject::hasCircularDependencies(CCopasiObject::DataObjectSet & candidates,
    CCopasiObject::DataObjectSet & verified,
    const CCopasiObject::DataObjectSet & context) const
{
  bool hasCircularDependencies = false;

  if (verified.count(this) != 0)
    return hasCircularDependencies;

  const CCopasiObject::DataObjectSet & DirectDependencies = getDirectDependencies(context);
  CCopasiObject::DataObjectSet::const_iterator it = DirectDependencies.begin();
  CCopasiObject::DataObjectSet::const_iterator end = DirectDependencies.end();

  std::pair<CCopasiObject::DataObjectSet::iterator, bool> Inserted;

  // Dual purpose insert
  Inserted = candidates.insert(this);

  // Check whether the insert was successful, if not
  // the object "this" was among the candidates. Thus we have a detected
  // a circular dependency
  if (Inserted.second)
    {
      for (; it != end && !hasCircularDependencies; ++it)
        {
          hasCircularDependencies = (*it)->hasCircularDependencies(candidates, verified, context);
        }

      // Remove the inserted object this from the candidates to avoid any
      // side effects.
      candidates.erase(this);
    }
  else
    hasCircularDependencies = true;

  // The element has been checked and does not need to be checked again.
  verified.insert(this);

  return hasCircularDependencies;
}
Beispiel #8
0
void CCopasiObject::getAllDependencies(CCopasiObject::DataObjectSet & dependencies,
                                       const CCopasiObject::DataObjectSet & context) const
{
  const CCopasiObject::DataObjectSet & DirectDependencies = getDirectDependencies(context);
  CCopasiObject::DataObjectSet::const_iterator it = DirectDependencies.begin();
  CCopasiObject::DataObjectSet::const_iterator end = DirectDependencies.end();

  std::pair<CCopasiObject::DataObjectSet::iterator, bool> Inserted;

  for (; it != end; ++it)
    {
      // Dual purpose insert
      Inserted = dependencies.insert(*it);

      // The direct dependency *it was among the dependencies
      // we assume also its dependencies have been added already.
      if (!Inserted.second) continue;

      // Add all the dependencies of the direct dependency *it.
      (*it)->getAllDependencies(dependencies, context);
    }
}
Beispiel #9
0
//static
std::vector< Refresh * >
CCopasiObject::buildUpdateSequence(const CCopasiObject::DataObjectSet & objects,
                                   const CCopasiObject::DataObjectSet & uptoDateObjects,
                                   const CCopasiObject::DataObjectSet & context)
{
  CCopasiObject::DataObjectSet DependencySet;
  CCopasiObject::DataObjectSet VerifiedSet;

  CCopasiObject::DataObjectSet::const_iterator itSet;
  CCopasiObject::DataObjectSet::const_iterator endSet = objects.end();
  std::pair<CCopasiObject::DataObjectSet::iterator, bool> InsertedObject;

  assert(objects.count(NULL) == 0);

  // Check whether we have any circular dependencies
  for (itSet = objects.begin(); itSet != endSet; ++itSet)
    if ((*itSet)->hasCircularDependencies(DependencySet, VerifiedSet, context))
      CCopasiMessage(CCopasiMessage::EXCEPTION, MCObject + 1, (*itSet)->getCN().c_str());

  // Build the complete set of dependencies
  for (itSet = objects.begin(); itSet != endSet; ++itSet)
    {
      // At least the object itself needs to be up to date.
      InsertedObject = DependencySet.insert(*itSet);

      // Add all its dependencies
      if (InsertedObject.second)
        (*itSet)->getAllDependencies(DependencySet, context);
    }

  // Remove all objects which do not have any refresh method as they will
  // be ignored anyway, i.e., no need to sort them.
  for (itSet = DependencySet.begin(), endSet = DependencySet.end(); itSet != endSet;)
    if ((*itSet)->getRefresh() == NULL ||
        ((dynamic_cast< const CParticleReference * >(*itSet) != NULL ||
          dynamic_cast< const CConcentrationReference * >(*itSet) != NULL) &&
         (*itSet)->getDirectDependencies(context).size() == 0))
      {
        const CCopasiObject * pObject = *itSet;
        ++itSet;
        DependencySet.erase(pObject);
      }
    else
      ++itSet;

  // Build the list of all up to date objects
  CCopasiObject::DataObjectSet UpToDateSet;

  for (itSet = uptoDateObjects.begin(), endSet = uptoDateObjects.end(); itSet != endSet; ++itSet)
    {
      // At least the object itself is up to date.
      InsertedObject = UpToDateSet.insert(*itSet);

      // Add all its dependencies too
      if (InsertedObject.second)
        (*itSet)->getAllDependencies(UpToDateSet, context);
    }

  // Now remove all objects in the dependency set which are up to date
  for (itSet = UpToDateSet.begin(), endSet = UpToDateSet.end(); itSet != endSet; ++itSet)
    DependencySet.erase(*itSet);

  // Create a properly sorted list.
  std::list< const CCopasiObject * > SortedList =
    sortObjectsByDependency(DependencySet.begin(), DependencySet.end(), context);

  std::list< const CCopasiObject * >::iterator itList;
  std::list< const CCopasiObject * >::iterator endList;

  // Build the vector of pointers to refresh methods
  Refresh * pRefresh;

  std::vector< Refresh * > UpdateVector;
  std::vector< Refresh * >::const_iterator itUpdate;
  std::vector< Refresh * >::const_iterator endUpdate;

  itList = SortedList.begin();
  endList = SortedList.end();

  for (; itList != endList; ++itList)
    {
      pRefresh = (*itList)->getRefresh();
      itUpdate = UpdateVector.begin();
      endUpdate = UpdateVector.end();

      while (itUpdate != endUpdate && !(*itUpdate)->isEqual(pRefresh)) ++itUpdate;

      if (itUpdate == endUpdate)
        UpdateVector.push_back(pRefresh);
    }

  return UpdateVector;
}
Beispiel #10
0
void CMetab::setStatus(const CModelEntity::Status & status)
{
  Status OldStatus = getStatus();

  CModelEntity::setStatus(status);

  if (status == OldStatus) return;

  CCopasiObject::DataObjectSet Dependencies;

  const CCopasiObject * pVolumeReference = NULL;

  if (mpCompartment)
    pVolumeReference = mpCompartment->getValueReference();

  switch (getStatus())
    {
      case FIXED:
        break;

      case ASSIGNMENT:
        Dependencies.insert(mpConcReference);

        if (pVolumeReference)
          Dependencies.insert(pVolumeReference);

        mpValueReference->setDirectDependencies(Dependencies);
        mpConcReference->setDirectDependencies(mpExpression->getDirectDependencies());

        // The dependencies and refresh of the rate are correct (see CModelEntity::setStatus).
        mpConcRateReference->setDirectDependencies(mpRateReference->getDirectDependencies());
        break;

      case ODE:
        mpValueReference->setDirectDependencies(Dependencies);

        Dependencies.insert(mpValueReference);

        if (pVolumeReference)
          Dependencies.insert(pVolumeReference);

        mpConcReference->setDirectDependencies(Dependencies);

        Dependencies.clear();
        Dependencies.insert(mpConcRateReference);

        if (pVolumeReference)
          Dependencies.insert(pVolumeReference);

        mpRateReference->setDirectDependencies(Dependencies);
        mpConcRateReference->setDirectDependencies(mpExpression->getDirectDependencies());
        break;

      case REACTIONS:
        mpValueReference->setDirectDependencies(Dependencies);

        if (pVolumeReference)
          Dependencies.insert(pVolumeReference);

        Dependencies.insert(mpValueReference);
        mpConcReference->setDirectDependencies(Dependencies);

        Dependencies.clear();

        if (pVolumeReference)
          Dependencies.insert(pVolumeReference);

        Dependencies.insert(mpRateReference);
        mpConcRateReference->setDirectDependencies(Dependencies);
        break;

      default:
        break;
    }

  if (mpModel && mpCompartment) refreshConcentration();
}