void CModelExpansion::duplicateEvent(CEvent* source, const std::string & index, const SetOfModelElements & sourceSet, ElementsMap & emap) { //if the source object has already been duplicated: do nothing if (emap.exists(source)) return; CEvent* newObj = NULL; if (expressionContainsObject(source->getTriggerExpressionPtr(), sourceSet) || expressionContainsObject(source->getDelayExpressionPtr(), sourceSet)) { //we need to duplicate the event itself (because the trigger refers to a duplicated object) //try creating the object until we find a name that is not yet used std::ostringstream infix; do { std::ostringstream name; name << source->getObjectName() << infix.str() << index; newObj = mpModel->createEvent(name.str()); infix << "_"; } while (!newObj); //add duplicated object to the map emap.add(source, newObj); //now do the trigger newObj->setTriggerExpression(source->getTriggerExpression()); newObj->getTriggerExpressionPtr()->compile(); //I don't know why this is necessary updateExpression(newObj->getTriggerExpressionPtr(), index, sourceSet, emap); //delay newObj->setDelayExpression(source->getDelayExpression()); newObj->getDelayExpressionPtr()->compile(); //I don't know why this is necessary updateExpression(newObj->getDelayExpressionPtr(), index, sourceSet, emap); newObj->setDelayAssignment(source->getDelayAssignment()); } else { newObj = source; //no copying necessary //add duplicated object to the map emap.add(source, newObj); } //now the event assignments... size_t i; for (i = 0; i < source->getAssignments().size(); ++i) { const CEventAssignment* pSourceAssignment = source->getAssignments()[i]; //const CModelEntity * pSourceTarget = dynamic_cast<const CModelEntity * >(CCopasiRootContainer::getKeyFactory()->get(pSourceAssignment->getTargetKey())); if (sourceSet.contains(pSourceAssignment->getTargetKey())) { //we assume that the duplicate of the target object already exists. //this should be true since events are duplicated last. if (!emap.exists(pSourceAssignment->getTargetKey())) continue; //create duplicate of assignment (this can be either in the original event or in the //duplicate of an event) CEventAssignment * pNewAssignment = new CEventAssignment(emap.getDuplicateKey(pSourceAssignment->getTargetKey())); newObj->getAssignments().add(pNewAssignment, true); //we do an assumption: //It should not happen that the assignment expression contains a reference to an object that is duplicated, //but the assignment target is not duplicated. //now copy the expression pNewAssignment->setExpression(pSourceAssignment->getExpression()); pNewAssignment->getExpressionPtr()->compile(); updateExpression(pNewAssignment->getExpressionPtr(), index, sourceSet, emap); } } newObj->setNotes(source->getNotes()); newObj->setMiriamAnnotation(source->getMiriamAnnotation(), newObj->getKey(), source->getKey()); }
bool CModelMerging::mergeMetabolites(std::string toKey, std::string key) { bool info = false; //merge in the relevant reactions size_t i, imax = mpModel->getReactions().size(); size_t j, jmax; for (i = 0; i < imax; ++i) { CReaction * reac = &mpModel->getReactions()[i]; jmax = reac->getChemEq().getSubstrates().size(); for (j = 0; j < jmax; ++j) { CChemEqElement * subst = const_cast< CChemEqElement * >(&reac->getChemEq().getSubstrates()[j]); if (subst->getMetabolite()->getKey() == key) subst->setMetabolite(toKey); } jmax = reac->getChemEq().getProducts().size(); for (j = 0; j < jmax; ++j) { CChemEqElement * prod = const_cast< CChemEqElement * >(&reac->getChemEq().getProducts()[j]); if (prod->getMetabolite()->getKey() == key) prod->setMetabolite(toKey); } jmax = reac->getChemEq().getModifiers().size(); for (j = 0; j < jmax; ++j) { CChemEqElement * modif = const_cast< CChemEqElement * >(&reac->getChemEq().getModifiers()[j]); if (modif->getMetabolite()->getKey() == key) modif->setMetabolite(toKey); } //change parameters of the kinetic function for (j = 0; j < reac->getFunctionParameters().size(); ++j) { switch (reac->getFunctionParameters()[j]->getUsage()) { case CFunctionParameter::SUBSTRATE: case CFunctionParameter::PRODUCT: case CFunctionParameter::MODIFIER: //translate the metab keys { //we assume that only SUBSTRATE, PRODUCT, MODIFIER can be vectors size_t k, kmax = reac->getParameterMappings()[j].size(); for (k = 0; k < kmax; ++k) if (reac->getParameterMappings()[j][k] == key) reac->getParameterMappings()[j][k] = toKey; } break; case CFunctionParameter::TIME: break; case CFunctionParameter::VOLUME: // ??? TODO : have to ask break; case CFunctionParameter::PARAMETER: break; default: return info; break; } } } imax = mpModel->getEvents().size(); for (i = 0; i < imax; ++i) { CEvent * event = &mpModel->getEvents()[i]; if (!event) return info; /* merge in trigger expressions */ CExpression* pExpression = event->getTriggerExpressionPtr(); if (pExpression == NULL) return info; if (!mergeInExpression(toKey, key, pExpression)) return info; pExpression = event->getDelayExpressionPtr(); if (pExpression) if (!mergeInExpression(toKey, key, pExpression)) return info; jmax = event->getAssignments().size(); for (j = 0; j < jmax; ++j) { CEventAssignment* assignment = &event->getAssignments()[j]; if (!assignment) return info; std::string assignmentKey = assignment->getTargetKey(); if (assignmentKey == key) assignment->setTargetKey(toKey); pExpression = assignment->getExpressionPtr(); if (pExpression == NULL) return info; if (!mergeInExpression(toKey, key, pExpression)) return info; } } imax = mpModel->getMetabolites().size(); for (i = 0; i < imax; ++i) { CMetab* metab = &mpModel->getMetabolites()[i]; if (!metab) return info; switch (metab->getStatus()) { case CModelEntity::FIXED: case CModelEntity::REACTIONS: break; case CModelEntity::ASSIGNMENT: if (!mergeInExpression(toKey, key, metab->getExpressionPtr())) return info; break; case CModelEntity::ODE: if (!mergeInExpression(toKey, key, metab->getExpressionPtr())) return info; if (metab->getInitialExpression() != "") if (!mergeInExpression(toKey, key, metab->getInitialExpressionPtr())) return info; break; default: return info; break; } } imax = mpModel->getCompartments().size(); for (i = 0; i < imax; ++i) { CCompartment* comp = &mpModel->getCompartments()[i]; if (!comp) return info; switch (comp ->getStatus()) { case CModelEntity::FIXED: break; case CModelEntity::ASSIGNMENT: if (!mergeInExpression(toKey, key, comp->getExpressionPtr())) return info; break; case CModelEntity::ODE: if (!mergeInExpression(toKey, key, comp->getExpressionPtr())) return info; if (comp->getInitialExpression() != "") if (!mergeInExpression(toKey, key, comp->getInitialExpressionPtr())) return info; break; default: return info; break; } } imax = mpModel->getModelValues().size(); for (i = 0; i < imax; ++i) { CModelValue* modval = &mpModel->getModelValues()[i]; if (!modval) return info; switch (modval ->getStatus()) { case CModelEntity::FIXED: break; case CModelEntity::ASSIGNMENT: if (!mergeInExpression(toKey, key, modval->getExpressionPtr())) return info; break; case CModelEntity::ODE: if (!mergeInExpression(toKey, key, modval->getExpressionPtr())) return info; if (modval->getInitialExpression() != "") if (!mergeInExpression(toKey, key, modval->getInitialExpressionPtr())) return info; break; default: return info; break; } } return true; }
void CQEventWidget1::addEvent(UndoEventData *pSData) { assert(CCopasiRootContainer::getDatamodelList()->size() > 0); CCopasiDataModel* pDataModel = (*CCopasiRootContainer::getDatamodelList())[0]; assert(pDataModel != NULL); CModel * pModel = pDataModel->getModel(); assert(pModel != NULL); //reinsert the Event CEvent *pEvent = pModel->createEvent(pSData->getName()); //set the expressions pEvent->setTriggerExpression(pSData->getTriggerExpression()); pEvent->setDelayExpression(pSData->getDelayExpression()); pEvent->setPriorityExpression(pSData->getPriorityExpression()); QList <UndoEventAssignmentData *> *assignmentData = pSData->getEventAssignmentData(); QList <UndoEventAssignmentData *>::const_iterator i; for (i = assignmentData->begin(); i != assignmentData->end(); ++i) { UndoEventAssignmentData * assignData = *i; CCopasiObject * pObject = NULL; bool speciesExist = false; size_t ci; for (ci = 0; ci < pModel->getCompartments().size(); ci++) { CCompartment * pCompartment = pModel->getCompartments()[ci]; if (pCompartment->getMetabolites().getIndex(assignData->getName()) != C_INVALID_INDEX) speciesExist = true; } if (speciesExist) { size_t index = pModel->findMetabByName(assignData->getName()); pObject = pModel->getMetabolites()[index]; } else if (pModel->getModelValues().getIndex(assignData->getName()) != C_INVALID_INDEX) { pObject = pModel->getModelValues()[assignData->getName()]; } else if (pModel->getReactions().getIndex(assignData->getName()) != C_INVALID_INDEX) { pObject = pModel->getReactions()[assignData->getName()]; } const CModelEntity * pEntity = dynamic_cast< const CModelEntity * >(pObject); CEventAssignment *eventAssign = new CEventAssignment(pObject->getKey(), pEvent->getObjectParent()); eventAssign->setExpression(assignData->getExpression()); eventAssign->getExpressionPtr()->compile(); pEvent->getAssignments().add(eventAssign); } std::string key = pEvent->getKey(); protectedNotify(ListViews::EVENT, ListViews::ADD, key); mpListView->switchToOtherWidget(C_INVALID_INDEX, key); }
bool CModelAdd::addEvents(std::string name) { bool info = false; size_t i, imax = mmModel->getEvents().size(); for (i = 0; i < imax; ++i) { const CEvent* sourceEvent = &mmModel->getEvents()[i]; if (!sourceEvent) return info; //create new event std::string eventName; eventName = sourceEvent->getObjectName(); std::string appendix = ""; #if 0 unsigned int counter = 2; std::ostringstream numberStream; while (mpModel->getEvents().getIndex(eventName + appendix) != C_INVALID_INDEX) { numberStream.str(""); numberStream << "_" << counter; counter++; appendix = numberStream.str(); } #else appendix = "_" + name; #endif CEvent* newEvent = mpModel->createEvent(eventName + appendix); if (newEvent == NULL) return info; /* copy trigger expression */ if (sourceEvent->getTriggerExpressionPtr() != NULL) { if (!copyTriggerExpression(sourceEvent, newEvent)) return info; } else { return info; } /* set whether the calculation or the assignment shall be delayed */ newEvent->setDelayAssignment(sourceEvent->getDelayAssignment()); /* copy the delay expression */ if (sourceEvent->getDelayExpressionPtr() != NULL) if (!copyDelayExpression(sourceEvent, newEvent)) return info; /* copy the assignments */ size_t j, jmax = sourceEvent->getAssignments().size(); for (j = 0; j < jmax; ++j) { const CEventAssignment* sourceAssignment = &sourceEvent->getAssignments()[j]; if (!sourceAssignment) return info; std::string key = sourceAssignment->getTargetKey(); CEventAssignment* newAssignment = new CEventAssignment; newEvent->getAssignments().add(newAssignment, true); newAssignment->setTargetKey(keyMap[key]); if (sourceAssignment->getExpressionPtr() != NULL) { if (!copyEventAssignmentExpression(sourceAssignment, newAssignment)) return info; } else { return info; } } } return true; }