From b44b9b81a924a5841dbb536eaf07e43c4a4387ea Mon Sep 17 00:00:00 2001
From: Claus Jonathan Fritzemeier <clausjonathan.fritzemeier@hhu.de>
Date: Wed, 18 May 2016 15:54:21 +0200
Subject: [PATCH] new slots for attributes

---
 R/addReact.R          |  22 ++++++++++++++
 R/generics.R          |  28 ++++++++++++++++++
 R/modelorgClass.R     |  67 +++++++++++++++++++++++++++++++++++++++++-
 R/parseBoolean.R      |   1 +
 R/readTEXTmod.R       |   9 ++++--
 R/readTSVmod.R        |   4 +--
 R/rmReact.R           |   8 +++++
 R/upgradeModelorg.R   |  14 +++++++--
 R/validmodelorg.R     |  24 +++++++++++++++
 data/Ec_core.RData    | Bin 6338 -> 6407 bytes
 man/modelorg-class.Rd |  31 +++++++++++++++++++
 11 files changed, 199 insertions(+), 9 deletions(-)

diff --git a/R/addReact.R b/R/addReact.R
index 31a8c66..35e6a25 100644
--- a/R/addReact.R
+++ b/R/addReact.R
@@ -139,6 +139,11 @@ addReact <- function(model,
         newsubSys       <- subSys(model)
 
         newS            <- S(model)
+        
+        newMetAttr <- met_attr(model)
+        newReactAttr <- react_attr(model)
+        newCompAttr <- comp_attr(model)
+        newModAttr <- mod_attr(model)
 
     
         if (isTRUE(addRow)) {
@@ -181,6 +186,11 @@ addReact <- function(model,
                                       nrow = nNewRows,
                                       ncol = react_num(model))
             newS <- Matrix::rBind(newS, newRows)
+            
+            # new met attrs
+            if(ncol(newMetAttr) > 0){
+            	newMetAttr[nrow(newMetAttr)+1:nNewRows, ] <- NA
+            }
         }
     
         if (isTRUE(addCol)) {                        # we add at most one column
@@ -211,6 +221,12 @@ addReact <- function(model,
             # new column in stoichiometric matrix
             newS <- cBind(newS, rep(0, nrow(newS)))
             
+            # new react Attr
+            # only one new row, /bc we can only add one reaction a time.
+            if(ncol(newReactAttr) > 0){
+            	newReactAttr[nrow(newReactAttr)+1, ] <- NA
+            }
+            
             # subsystems
             if (any(is.na(subSystem))) {
             	ss <- subSys(model)
@@ -359,6 +375,12 @@ addReact <- function(model,
         subSys(mod_out)       <- newsubSys
 
         S(mod_out)            <- newS
+        
+        react_attr(mod_out) <- newReactAttr
+        met_attr(mod_out) <- newMetAttr
+        comp_attr(mod_out) <- newCompAttr
+        mod_attr(mod_out) <- newModAttr
+        
 
     }
     else {
diff --git a/R/generics.R b/R/generics.R
index 3c393a8..af64b93 100644
--- a/R/generics.R
+++ b/R/generics.R
@@ -151,6 +151,13 @@ setGeneric(name = "cmd<-",
            def  = function(object, value) { standardGeneric("cmd<-") }
 )
 
+setGeneric(name = "comp_attr",
+           def  = function(object) { standardGeneric("comp_attr") }
+)
+setGeneric(name = "comp_attr<-",
+           def  = function(object, value) { standardGeneric("comp_attr<-") }
+)
+
 setGeneric(name = "ctrlfl",
            def  = function(object) { standardGeneric("ctrlfl") }
 )
@@ -540,6 +547,13 @@ setGeneric(name = "maxSol",
            def  = function(object, ...) { standardGeneric("maxSol") }
 )
 
+setGeneric(name = "met_attr",
+           def  = function(object) { standardGeneric("met_attr") }
+)
+setGeneric(name = "met_attr<-",
+           def  = function(object, value) { standardGeneric("met_attr<-") }
+)
+
 setGeneric(name = "met_comp",
            def  = function(object) { standardGeneric("met_comp") }
 )
@@ -600,6 +614,13 @@ setGeneric(name = "minSol",
            def  = function(object, ...) { standardGeneric("minSol") }
 )
 
+setGeneric(name = "mod_attr",
+           def  = function(object) { standardGeneric("mod_attr") }
+)
+setGeneric(name = "mod_attr<-",
+           def  = function(object, value) { standardGeneric("mod_attr<-") }
+)
+
 setGeneric(name = "mod_compart",
            def  = function(object) { standardGeneric("mod_compart") }
 )
@@ -763,6 +784,13 @@ setGeneric(name = "react<-",
            def  = function(object, value) { standardGeneric("react<-") }
 )
 
+setGeneric(name = "react_attr",
+           def  = function(object) { standardGeneric("react_attr") }
+)
+setGeneric(name = "react_attr<-",
+           def  = function(object, value) { standardGeneric("react_attr<-") }
+)
+
 setGeneric(name = "react_de",
            def  = function(object) { standardGeneric("react_de") }
 )
diff --git a/R/modelorgClass.R b/R/modelorgClass.R
index d44d548..5cd4063 100644
--- a/R/modelorgClass.R
+++ b/R/modelorgClass.R
@@ -39,18 +39,22 @@ setClass("modelorg",
          mod_id       = "character",   # model id
          mod_key      = "character",   # model key (unique character string)
          mod_compart  = "character",   # vector compartments
+         mod_attr     = "data.frame",  # dataframe to store attributes of the model
+         comp_attr    = "data.frame",  # dataframe to store attributes of the compartments
          met_num      = "integer",     # number of metabolites
          met_id       = "character",   # vector metabolite id's
          met_name     = "character",   # vector metabolite names
          met_comp     = "integer",     # vector the metabolites compartment
          met_single   = "logical",     # metabolites appearing only once in S
          met_de       = "logical",     # dead end metabolites
+         met_attr     = "data.frame",  # dataframe to store attributes of the metabolites
          react_num    = "integer",     # number of reactions
          react_rev    = "logical",     # vector reversibilities
          react_id     = "character",   # vector reaction id's
          react_name   = "character",   # vector reaction names
          react_single = "logical",     # reactions using metabolites appearing only once in S
          react_de     = "logical",     # reactions using dead end metabolites
+         react_attr   = "data.frame",  # dataframe to store attributes of the reactions
          S            = "Matrix",      # matrix S
          lowbnd       = "numeric",     # vector reactions lower bounds
          uppbnd       = "numeric",     # vector reactions upper bounds
@@ -111,6 +115,10 @@ setMethod(f = "initialize",
                   .Object@mod_key    <- as.character(.generateModKey())
                   .Object@react_num  <- as.integer(0)
                   .Object@met_num    <- as.integer(0)
+                  .Object@react_attr <- data.frame()
+                  .Object@met_attr   <- data.frame()
+                  .Object@mod_attr   <- data.frame()
+                  .Object@comp_attr  <- data.frame()
                   .Object@S          <- Matrix::Matrix(0, 0, 0)
                   .Object@rxnGeneMat <- Matrix::Matrix(0, 0, 0)
                   .Object@subSys     <- Matrix::Matrix(0, 0, length(subSys))
@@ -206,7 +214,6 @@ setReplaceMethod("mod_compart", signature(object = "modelorg"),
           }
 )
 
-
 # number of metabolites
 setMethod("met_num", signature(object = "modelorg"),
           function(object) {
@@ -565,6 +572,64 @@ setReplaceMethod("version", signature(object = "modelorg"),
           }
 )
 
+# metabolites attributes
+setMethod("met_attr", signature(object = "modelorg"),
+          function(object) {
+              return(object@met_attr)
+          }
+)
+
+setReplaceMethod("met_attr", signature(object = "modelorg"),
+          function(object, value) {
+              object@met_attr <- value
+              return(object)
+          }
+)
+
+# reaction attributes
+setMethod("react_attr", signature(object = "modelorg"),
+          function(object) {
+              return(object@react_attr)
+          }
+)
+
+setReplaceMethod("react_attr", signature(object = "modelorg"),
+          function(object, value) {
+              object@react_attr <- value
+              return(object)
+          }
+)
+
+# compartment attributes
+setMethod("comp_attr", signature(object = "modelorg"),
+          function(object) {
+              return(object@comp_attr)
+          }
+)
+
+setReplaceMethod("comp_attr", signature(object = "modelorg"),
+          function(object, value) {
+              object@comp_attr <- value
+              return(object)
+          }
+)
+
+# model attributes
+setMethod("mod_attr", signature(object = "modelorg"),
+          function(object) {
+              return(object@mod_attr)
+          }
+)
+
+setReplaceMethod("mod_attr", signature(object = "modelorg"),
+          function(object, value) {
+              object@mod_attr <- value
+              return(object)
+          }
+)
+
+
+
 
 #------------------------------------------------------------------------------#
 #                               other methods                                  #
diff --git a/R/parseBoolean.R b/R/parseBoolean.R
index b10a46d..4546b26 100644
--- a/R/parseBoolean.R
+++ b/R/parseBoolean.R
@@ -31,6 +31,7 @@
 # The algorithm is the same.
 #
 # 2015-06-17 CJF: added handling for emtpy gprRule like "( )"
+# 2016-05-18 CJF: format of gprRules was changed.
 
 
 .parseBoolean <- function(gprRule, tokens = "()&|~") {
diff --git a/R/readTEXTmod.R b/R/readTEXTmod.R
index 8746664..00e71cc 100644
--- a/R/readTEXTmod.R
+++ b/R/readTEXTmod.R
@@ -24,9 +24,9 @@
 
 ################################################
 # Function: readTEXTmod
-#
-# 
 # 
+# 2016-05-18 CJF: format of gprRules was changed.
+
 
 readTEXTmod <- function(filename,
                         description,
@@ -112,7 +112,10 @@ parse_genes <- function(gene) {
     }
 
     # for the gpr slot and gprRules slot
-    gene_pos <- which(allGenes %in% gene)
+    #gene_pos <- which(allGenes %in% gene)
+    #new gprRules:
+    gene_pos <- seq(along=gene)
+    
     if (length(gene) > 1) {
         gpr_string <- paste("(", paste(gene, sep = "", collapse = " and "), ")")
         rules_string <- paste("x[", gene_pos, "]", sep = "")
diff --git a/R/readTSVmod.R b/R/readTSVmod.R
index 0bd2604..032e82f 100644
--- a/R/readTSVmod.R
+++ b/R/readTSVmod.R
@@ -26,7 +26,7 @@
 # Function: readTSVmod
 #
 #
-#
+# 2016-05-18 CJF: format of gprRules was changed.
 
 readTSVmod <- function(prefix, suffix,
                        reactList, metList = NA, modDesc = NA,
@@ -950,7 +950,7 @@ readTSVmod <- function(prefix, suffix,
             geneInd <- match(Rgenes[[i]], allGenes)
             rxnGeneMat[i, geneInd] <- TRUE
 			
-			# not needed for version 2.0 modelorgs
+			# not needed for version 2.0 modelorg gprRules
 #            for (j in 1 : length(geneInd)) {
 #                pat  <- paste("x(", j, ")", sep = "")
 #                repl <- paste("x[", geneInd[j], "]", sep = "")
diff --git a/R/rmReact.R b/R/rmReact.R
index 45ab6ed..0efb32c 100644
--- a/R/rmReact.R
+++ b/R/rmReact.R
@@ -133,6 +133,10 @@ rmReact <- function(model, react, rm_met = TRUE) {
   obj_coef(mod_out)     <- obj_coef(model)[keepReact]
   react_single(mod_out) <- react_single(model)[keepReact]
   react_de(mod_out)     <- react_de(model)[keepReact]
+  
+  if(ncol(react_attr(model))>0){
+      	react_attr(mod_out)   <- react_attr(model)[keepReact, ]
+  }
 
   react_num(mod_out)    <- length(react_id(mod_out))
 
@@ -210,6 +214,10 @@ rmReact <- function(model, react, rm_met = TRUE) {
       met_comp(mod_out)   <- met_comp(model)[keepMet]
       met_single(mod_out) <- met_single(model)[keepMet]
       met_de(mod_out)     <- met_de(model)[keepMet]
+      
+      if(ncol(met_attr(model))>0){
+      	met_attr(mod_out)   <- met_attr(model)[keepMet, ]
+      }
   }
   else {
       met_num(mod_out)  <- met_num(model)
diff --git a/R/upgradeModelorg.R b/R/upgradeModelorg.R
index 54031c1..a10cdfd 100644
--- a/R/upgradeModelorg.R
+++ b/R/upgradeModelorg.R
@@ -33,16 +33,24 @@
 upgradeModelorg <- function(object){
 	stopifnot(is(object, "modelorg"))
 	
-	if(!.hasSlot(object, "version")){
+	if(!.hasSlot(object, "version") || compareVersion(version(object), "2.0") == -1){
 		# object is from a time before versions were introduced.
-		# just add version slot and run again.
+		
+		# just add version slot
 		object@version <- "2.0"
 		
+		# update gprRules to new format
 		rules <- lapply(gpr(object), .parseBoolean)
 		genes(object) <- sapply(rules, "[[", "gene")
 		gprRules(object) <- sapply(rules, "[[", "rule")
 		
-		#recursively upgrad to latest version.
+		# set attribute slots
+		react_attr(object) <- data.frame()
+		comp_attr(object) <- data.frame()
+		met_attr(object) <- data.frame()
+		mod_attr(object) <- data.frame()
+		
+		#recursively upgrade to latest version.
 		return(upgradeModelorg(object))
 	}
 	
diff --git a/R/validmodelorg.R b/R/validmodelorg.R
index 2aaee84..9ac0dd2 100644
--- a/R/validmodelorg.R
+++ b/R/validmodelorg.R
@@ -169,6 +169,30 @@
                 return("Wrong dimension of rxnGeneMat!")
             }
         }
+        
+        # attributes
+        
+        if(0 < ncol(met_attr(object))){
+        	if(nrow(met_attr(object)) != met){
+        		return("Wrong nrow of metabolite attributes")
+        	}
+        }
+        if(0 < ncol(react_attr(object))){
+        	if(nrow(react_attr(object)) != react){
+        		return("Wrong nrow of reaction attributes")
+        	}
+        }
+        if(0 < ncol(comp_attr(object))){
+        	if(nrow(comp_attr(object)) != length(mod_compart(object))){
+        		return("Wrong nrow of compartment attributes")
+        	}
+        }
+        if(0 < ncol(mod_attr(object))){
+        	if(nrow(mod_attr(object)) != 1){
+        		return("Wrong nrow of model attributes")
+        	}
+        }
+        
     }
     return(TRUE)
 }
diff --git a/data/Ec_core.RData b/data/Ec_core.RData
index ebf33613cc778356128bc432ac0ee3f02d95b12f..93dd81cd5a51117c39246a8701d39073edb12bbb 100644
GIT binary patch
delta 6396
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

delta 6326
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
YU*`JKKEp=vsOEqE$#d!@q)HhW0D9|!<p2Nx

diff --git a/man/modelorg-class.Rd b/man/modelorg-class.Rd
index c76921d..dfeb47d 100644
--- a/man/modelorg-class.Rd
+++ b/man/modelorg-class.Rd
@@ -8,6 +8,10 @@
 \alias{allGenes,modelorg-method}
 \alias{allGenes<-}
 \alias{allGenes}
+\alias{comp_attr<-,modelorg-method}
+\alias{comp_attr,modelorg-method}
+\alias{comp_attr<-}
+\alias{comp_attr}
 \alias{dim,modelorg-method}
 \alias{genes<-,modelorg-method}
 \alias{genes,modelorg-method}
@@ -25,6 +29,10 @@
 \alias{lowbnd,modelorg-method}
 \alias{lowbnd<-}
 \alias{lowbnd}
+\alias{met_attr<-,modelorg-method}
+\alias{met_attr,modelorg-method}
+\alias{met_attr<-}
+\alias{met_attr}
 \alias{met_comp<-,modelorg-method}
 \alias{met_comp,modelorg-method}
 \alias{met_comp<-}
@@ -49,6 +57,10 @@
 \alias{met_single,modelorg-method}
 \alias{met_single<-}
 \alias{met_single}
+\alias{mod_attr<-,modelorg-method}
+\alias{mod_attr,modelorg-method}
+\alias{mod_attr<-}
+\alias{mod_attr}
 \alias{mod_compart<-,modelorg-method}
 \alias{mod_compart,modelorg-method}
 \alias{mod_compart<-}
@@ -75,6 +87,10 @@
 \alias{obj_coef}
 \alias{printObjFunc,modelorg-method}
 \alias{printObjFunc}
+\alias{react_attr<-,modelorg-method}
+\alias{react_attr,modelorg-method}
+\alias{react_attr<-}
+\alias{react_attr}
 \alias{react_de<-,modelorg-method}
 \alias{react_de,modelorg-method}
 \alias{react_de<-}
@@ -174,9 +190,16 @@
       Object of class \code{"character"} containing a single character string
       functioning as a unique key to a model object.
     }
+    \item{\code{mod_attr}:}{
+      Object of class \code{"data.frame"} to store additional attributes of the model.
+    }
     \item{\code{mod_compart}:}{
       Object of class \code{"character"} containing the model compartments.
     }
+    \item{\code{comp_attr}:}{
+      Object of class \code{"data.frame"} to store additional attributes for 
+      each compartment.
+    }
     \item{\code{met_num}:}{
       Object of class \code{"integer"} indicating the number of metabolites.
     }
@@ -189,6 +212,10 @@
     \item{\code{met_comp}:}{
       Object of class \code{"integer"} containing the metabolites compartment.
     }
+    \item{\code{met_attr}:}{
+      Object of class \code{"data.frame"} to store additional attributes for 
+      each metabolite.
+    }
     \item{\code{met_single}:}{
       Object of class \code{"logical"} with length \code{met_num}. Element
       \code{i} is \code{TRUE}, if metabolite \code{i} appears only once in S.
@@ -210,6 +237,10 @@
     \item{\code{react_name}:}{
       Object of class \code{"character"} containing the reaction names.
     }
+    \item{\code{react_attr}:}{
+      Object of class \code{"data.frame"} to store additional attributes for 
+      each reaction.
+    }
     \item{\code{react_single}:}{
       Object of class \code{"logical"} with length \code{react_num}. Element
       \code{i} is \code{TRUE}, if reaction \code{i} uses metabolites appearing
-- 
GitLab