Designing a Custom Enzyme

library(rbcmodel)

Overview

This vignette is for users who plan to create an enzyme from scratch, modify an enzyme, or combine information from more than one entry. Users who wish only to use a model enzyme and one of the provided temperature dependence scales can stick to the basic workflow in the introductory vignette. First, we provide a more thorough explanation of the different ways of searching the database for a particular enzyme’s kinetics or temperature dependences than we gave in the introductory vignette. Second, we go into detail about the different scenarios of constructing an appropriate Enzyme object from the kinetics data, starting with those in which there is a lot of data and moving to those in which there is very little data. We repeat this in the third section with the different scenarios that may crop up when constructing an appropriate DHScale object. Fourth, we discuss how to decide which PGS pathway to use when there is no data. Finally, we discuss our philosophy on creating the various averages and composite enzymes we have provided in the package database, in the hopes that it will provide a starting point for those that are truly stuck.

1. Searching for my enzyme

In the introductory vignette, we mostly stuck to the abridged table for kinetics and the averages table for the temperature dependences, since those are the tables that have the most complete data in them. If all you want to do is look at a model enzyme that many people have measured, this should cover your use case! However, for those of you who are interested in looking at enzymes with fewer measurements or forms of Rubisco with fewer measurements, you will probably have to use the comprehensive enzyme table and the abridged DHScale table.

1.1 Recommendations for searching

The comprehensive enzyme table has a lot more columns than the abridged enzyme table, to provide the full range of data about each of the studies and the measurements. If you are overwhelmed by the amount of information, we recommend saving your searches as an object and calling only those columns that you plan to use to distinguish between studies:

test<-search_enzyme("Synechococcus",data="comprehensive")
#> Matched genus in comprehensive table
#filter columns and restrict entries for readability
test[1:10,c(1:5,9,12,15,18,21,24,26,27,29)]
#>                           identifier         genus   species subspecies mutant
#> 1  synechococcus_aguiló-nicolau_2023 Synechococcus        sp   PCC 6301  FALSE
#> 2          elongatus_Bainbridge_1998 Synechococcus elongatus       6301  FALSE
#> 3    elongatus_K128R_Bainbridge_1998 Synechococcus elongatus       6301   TRUE
#> 4    elongatus_K128G_Bainbridge_1998 Synechococcus elongatus       6301   TRUE
#> 5    elongatus_K128Q_Bainbridge_1998 Synechococcus elongatus       6301   TRUE
#> 6    elongatus_K128H_Bainbridge_1998 Synechococcus elongatus       6301   TRUE
#> 7    elongatus_K128D_Bainbridge_1998 Synechococcus elongatus       6301   TRUE
#> 8           synechococcus_banda_2020 Synechococcus        sp   PCC 6301  FALSE
#> 9  synechococcus_bsa11s_de_pins_2024 Synechococcus        sp     BSA11S  FALSE
#> 10      elongatus_11801_de_pins_2024 Synechococcus elongatus  PCC 11801  FALSE
#>    kcat_val Kc_val Ko_val S_val temp form      taxonomy    group
#> 1      8.70  147.2  631.6  48.2   25  1Bc Cyanobacteria Bacteria
#> 2      7.20  124.3     NA  46.3   25  1Bc Cyanobacteria Bacteria
#> 3      2.90   86.4     NA  42.5   25  1Bc Cyanobacteria Bacteria
#> 4      0.15  204.5     NA  38.3   25  1Bc Cyanobacteria Bacteria
#> 5      0.23  204.4     NA   6.7   25  1Bc Cyanobacteria Bacteria
#> 6      0.22  215.5     NA   6.1   25  1Bc Cyanobacteria Bacteria
#> 7      0.13  109.6     NA   5.1   25  1Bc Cyanobacteria Bacteria
#> 8     14.30  235.0  983.0  56.1   25  1Bc Cyanobacteria Bacteria
#> 9     10.50     NA     NA    NA   NA  1Ac Cyanobacteria Bacteria
#> 10     7.90     NA     NA    NA   NA  1Bc Cyanobacteria Bacteria
#>              short_ref
#> 1  Aguiló-Nicolau 2023
#> 2      Bainbridge 1998
#> 3      Bainbridge 1998
#> 4      Bainbridge 1998
#> 5      Bainbridge 1998
#> 6      Bainbridge 1998
#> 7      Bainbridge 1998
#> 8           Banda 2020
#> 9         de Pins 2024
#> 10        de Pins 2024

In our example, we removed most of the information not provided in the abridged table, in addition to the individual kinetics’ temperature columns, as a look at the data shows that none of them were measured at anything other than 25°C (and are therefore all comparable with each other). Once we’ve decided on the studies we want to include, we can look over their whole rows to make sure there aren’t any red flags in the other columns.

We can also do some other filtering, like removing from our search all of the kinetics for those mutants included in the larger table:

test<-test[test$mutant=="FALSE",]
#no longer restricting entry number
test[,c(1:4,9,12,15,18,21,24,26,27,29)] #removed mutant column, as they are all not mutants now
#>                             identifier         genus   species subspecies
#> 1    synechococcus_aguiló-nicolau_2023 Synechococcus        sp   PCC 6301
#> 2            elongatus_Bainbridge_1998 Synechococcus elongatus       6301
#> 8             synechococcus_banda_2020 Synechococcus        sp   PCC 6301
#> 9    synechococcus_bsa11s_de_pins_2024 Synechococcus        sp     BSA11S
#> 10        elongatus_11801_de_pins_2024 Synechococcus elongatus  PCC 11801
#> 11    synechococcus_bs56d_de_pins_2024 Synechococcus        sp      BS56D
#> 12         elongatus_6301_de_pins_2024 Synechococcus elongatus       6301
#> 13 synechococcus_pcc 7336_de_pins_2024 Synechococcus        sp   PCC 7336
#> 14              lacustris_de_pins_2024 Synechococcus lacustris  str. Tous
#> 15  synechococcus_a15-127_de_pins_2024 Synechococcus        sp    A15-127
#> 16    synechococcus_gfb01_de_pins_2024 Synechococcus        sp      GFB01
#> 17 synechococcus_rsccf101_de_pins_2024 Synechococcus        sp   RSCCF101
#> 18    synechococcus_bs56d_de_pins_2025 Synechococcus        sp      BS56D
#> 19 synechococcus_rsccf101_de_pins_2025 Synechococcus        sp   RSCCF101
#> 20       s_elongatus_6301_de_pins_2025 Synechococcus elongatus       6301
#> 21   synechococcus_bsa11s_de_pins_2025 Synechococcus        sp     BSA11S
#> 22              lacustris_de_pins_2025 Synechococcus lacustris  str. Tous
#> 23  synechococcus_a15-127_de_pins_2025 Synechococcus        sp    A15-127
#> 24      s_elongatus_11801_de_pins_2025 Synechococcus elongatus  PCC 11801
#> 25 synechococcus_pcc 7336_de_pins_2025 Synechococcus        sp   PCC 7336
#> 26    synechococcus_gfb01_de_pins_2025 Synechococcus        sp      GFB01
#> 27               elongatus_Greene_2007 Synechococcus elongatus       6301
#> 31           elongatus_Gutteridge_1986 Synechococcus elongatus       6301
#> 32    elongatus_Horken_and_Tabita_1998 Synechococcus elongatus       6301
#> 33       synechococcus_sp_Iñiguez_2021 Synechococcus        sp       <NA>
#> 34                 elongatus_Kane_1994 Synechococcus elongatus       6301
#> 35                elongatus__Kane_1994 Synechococcus elongatus       6301
#> 36             elongatus_Lee_G.J._1993 Synechococcus elongatus       6301
#> 37               elongatus_Morell_1994 Synechococcus elongatus       6301
#> 41        elongatus_Mueller-Cajar_2008 Synechococcus elongatus       6301
#> 50                elongatus_Parry_1989 Synechococcus elongatus       6301
#> 51                 elongatus_Paul_1991 Synechococcus elongatus       6301
#> 57               elongatus_Pearce_2006 Synechococcus elongatus       6301
#> 58                elongatus_Read_1992a Synechococcus elongatus       6301
#> 63                elongatus_Read_1992b Synechococcus elongatus       6301
#> 66                 elongatus_Read_1994 Synechococcus elongatus       6301
#> 72               elongatus_schulz_2022 Synechococcus elongatus       6301
#> 73                 elongatus_Shih_2016 Synechococcus elongatus       6301
#> 74                 elongatus_tsai_2025 Synechococcus elongatus   PCC 6301
#> 75     elongatus_davidi_2020_corrected Synechococcus elongatus   PCC 6301
#> 76                 elongatus_Wang_2001 Synechococcus elongatus       6301
#> 77            elongatus_Whitehead_2014 Synechococcus elongatus       6301
#> 78 elongatus_Whitney_and_Sharwood_2007 Synechococcus elongatus       6301
#> 89                elongatus_Witte_2010 Synechococcus elongatus       6301
#> 90            synechococcus_zhang_2021 Synechococcus        sp   PCC 7002
#> 91                  elongatus_Zhu_1998 Synechococcus elongatus       6301
#>    kcat_val Kc_val Ko_val S_val temp form      taxonomy    group
#> 1   8.70000  147.2  631.6  48.2   25  1Bc Cyanobacteria Bacteria
#> 2   7.20000  124.3     NA  46.3   25  1Bc Cyanobacteria Bacteria
#> 8  14.30000  235.0  983.0  56.1   25  1Bc Cyanobacteria Bacteria
#> 9  10.50000     NA     NA    NA   NA  1Ac Cyanobacteria Bacteria
#> 10  7.90000     NA     NA    NA   NA  1Bc Cyanobacteria Bacteria
#> 11 13.10000     NA     NA    NA   NA  1Ac Cyanobacteria Bacteria
#> 12 10.60000     NA     NA    NA   NA  1Bc Cyanobacteria Bacteria
#> 13  7.10000     NA     NA    NA   NA  1Bc Cyanobacteria Bacteria
#> 14 10.20000     NA     NA    NA   NA  1Ac Cyanobacteria Bacteria
#> 15  9.00000     NA     NA    NA   NA  1Ac Cyanobacteria Bacteria
#> 16  6.40000     NA     NA    NA   NA  1Ac Cyanobacteria Bacteria
#> 17 11.00000     NA     NA    NA   NA  1Ac Cyanobacteria Bacteria
#> 18 28.31851     NA     NA    NA   NA  1Ac Cyanobacteria Bacteria
#> 19 23.84716     NA     NA    NA   NA  1Ac Cyanobacteria Bacteria
#> 20 22.99548     NA     NA    NA   NA  1Bc Cyanobacteria Bacteria
#> 21 22.56964     NA     NA    NA   NA  1Ac Cyanobacteria Bacteria
#> 22 21.93087     NA     NA    NA   NA  1Ac Cyanobacteria Bacteria
#> 23 19.37582     NA     NA    NA   NA  1Ac Cyanobacteria Bacteria
#> 24 17.03369     NA     NA    NA   NA  1Bc Cyanobacteria Bacteria
#> 25 15.33032     NA     NA    NA   NA  1Bc Cyanobacteria Bacteria
#> 26 13.83987     NA     NA    NA   NA  1Ac Cyanobacteria Bacteria
#> 27 11.40000  273.0     NA  43.9   25  1Bc Cyanobacteria Bacteria
#> 31       NA     NA     NA  52.0   NA  1Bc Cyanobacteria Bacteria
#> 32  2.70000  173.0     NA  38.5   30  1Bc Cyanobacteria Bacteria
#> 33  7.00000  139.6  690.0  43.9   25   1B Cyanobacteria Bacteria
#> 34       NA     NA     NA  42.5   NA  1Bc Cyanobacteria Bacteria
#> 35       NA     NA     NA  44.8   NA  1Bc Cyanobacteria Bacteria
#> 36       NA     NA     NA  40.0   NA  1Bc Cyanobacteria Bacteria
#> 37 11.60000  284.0     NA  43.0   25  1Bc Cyanobacteria Bacteria
#> 41 11.80000  200.0  199.0  41.5   25  1Bc Cyanobacteria Bacteria
#> 50       NA     NA     NA  52.0   NA  1Bc Cyanobacteria Bacteria
#> 51 11.80000  251.0     NA    NA   25  1Bc Cyanobacteria Bacteria
#> 57 13.90000     NA     NA    NA   NA  1Bc Cyanobacteria Bacteria
#> 58       NA  175.0  565.0  40.8   25  1Bc Cyanobacteria Bacteria
#> 63  2.57000  142.0  664.0  41.0   25  1Bc Cyanobacteria Bacteria
#> 66  3.71000  167.0  529.0  41.0   25  1Bc Cyanobacteria Bacteria
#> 72       NA     NA     NA  45.7   25  1Bc Cyanobacteria Bacteria
#> 73  9.78000  152.0 1230.0  50.3   25  1Bc Cyanobacteria Bacteria
#> 74 14.20000  156.0     NA  42.7   25  1Bc Cyanobacteria Bacteria
#> 75 16.40000  130.0     NA 162.0   25  1Bc Cyanobacteria Bacteria
#> 76       NA  117.0     NA   5.1   25  1Bc Cyanobacteria Bacteria
#> 77 14.40000  169.2     NA    NA   25  1Bc Cyanobacteria Bacteria
#> 78  6.10000  240.0     NA  40.6   25  1Bc Cyanobacteria Bacteria
#> 89  2.70000     NA     NA  36.8   23  1Bc Cyanobacteria Bacteria
#> 90 12.30000  194.6     NA    NA   25  1Bc Cyanobacteria Bacteria
#> 91  6.60000   81.0  460.0  47.0   25  1Bc Cyanobacteria Bacteria
#>                    short_ref
#> 1        Aguiló-Nicolau 2023
#> 2            Bainbridge 1998
#> 8                 Banda 2020
#> 9               de Pins 2024
#> 10              de Pins 2024
#> 11              de Pins 2024
#> 12              de Pins 2024
#> 13              de Pins 2024
#> 14              de Pins 2024
#> 15              de Pins 2024
#> 16              de Pins 2024
#> 17              de Pins 2024
#> 18              de Pins 2025
#> 19              de Pins 2025
#> 20              de Pins 2025
#> 21              de Pins 2025
#> 22              de Pins 2025
#> 23              de Pins 2025
#> 24              de Pins 2025
#> 25              de Pins 2025
#> 26              de Pins 2025
#> 27               Greene 2007
#> 31           Gutteridge 1986
#> 32    Horken and Tabita 1998
#> 33              Iñiguez 2021
#> 34                 Kane 1994
#> 35                 Kane 1994
#> 36             Lee G.J. 1993
#> 37               Morell 1994
#> 41        Mueller-Cajar 2008
#> 50                Parry 1989
#> 51                 Paul 1991
#> 57               Pearce 2006
#> 58                Read 1992a
#> 63                Read 1992b
#> 66                 Read 1994
#> 72               Schulz 2022
#> 73                 Shih 2016
#> 74                 Tsai 2025
#> 75                 Tsai 2025
#> 76                 Wang 2001
#> 77            Whitehead 2014
#> 78 Whitney and Sharwood 2007
#> 89                Witte 2010
#> 90                Zhang 2021
#> 91                  Zhu 1998

Now it is much easier to review the data. The rest of the data is still in the database and can be recalled by running the same search as before with whatever rows you have decided are potentially useful rows, for that red flag check we mentioned before. Say you like the Iñiguez composite enzyme and the Mueller-Cajar 2008 enzyme (rows 33 and 41 in the initial search, based on the row numbers on the left of our test outputs):

search_enzyme("Synechococcus",data="comprehensive")[c(33,41),]
#> Matched genus in comprehensive table
#>                       identifier         genus   species subspecies mutant
#> 33 synechococcus_sp_Iñiguez_2021 Synechococcus        sp       <NA>  FALSE
#> 41  elongatus_Mueller-Cajar_2008 Synechococcus elongatus       6301  FALSE
#>    mutant_details primary heterologous_expression kcat_val kcat_T kcat_pH
#> 33           <NA>   FALSE                   FALSE      7.0     NA      NA
#> 41           <NA>    TRUE                 E. coli     11.8     NA      NA
#>    Kc_val Kc_T Kc_pH Ko_val Ko_T Ko_pH S_val S_T S_pH temp pH pKa_used form
#> 33  139.6   NA    NA    690   NA    NA  43.9  NA   NA   25 NA       NA   1B
#> 41  200.0   NA    NA    199   NA    NA  41.5  NA  8.3   25  8     6.25  1Bc
#>      PGS      taxonomy    group
#> 33 canon Cyanobacteria Bacteria
#> 41 canon Cyanobacteria Bacteria
#>                                                                                                                                                                                                                    note
#> 33                                                                                                                                       methodology-corrected average from Iñiguez et al. 2021 across multiple strains
#> 41 Used Kane method for S so no pKa correction needed; no pKa listed for Kc, but cites Whitney & Sharwood 2007; Whitney & Sharwood 2007 does not report pKa, but Iniguez et al. 2021 cites a pKa of 6.25 for that study
#>             short_ref year
#> 33       Iñiguez 2021 2021
#> 41 Mueller-Cajar 2008 2008

For all of these examples, we used a model genus with complete data present in the abridged table. Those of you looking at this vignette are far more likely to be looking for species or genera that have very few measurements, or forms of Rubisco with few measurements. If nothing comes up when searching for your species/genus, we suggest moving to their taxonomy first, followed by the form of Rubisco. If you are still having trouble finding analogous Rubisco sequences, we also have a group category, which groups Rubisco into five broad categories: plants, algae, bacteria, archaea, and metagenomes. The final category is for Rubisco sequences that were derived from metagenomes and were not isolated from any particular organism, but rather used to transform something (predominantly E. coli) for expression. As these cannot be confirmed to represent a single organism’s Rubisco sequence rather than a population consensus, we decided to group them separately, even when there is an assigned taxonomy.

When searching for temperature dependences, we suggest that you follow the same progression (species -> genus -> taxonomy -> form -> group). There are many fewer temperature dependence measurements in the tables, and all of the temperature dependence tables have fewer columns, making it easier to look at and manipulate a broader search (taxonomy/form/group), which is far more likely to be necessary for temperature dependences given the scarcity of that data.

1.2 Taxonomic classifications

There are many possible ways that these sequences could have been classified. For our taxonomy category, we have maintained many of the classifications in use by the Rubisco community, and added some additional class-level taxonomy categories for the bacteria, which with the inclusion of metagenome-derived sequences span a much broader range of classes. For archaea, there were not enough sequences to make it worthwhile to classify them to the class level at the present time, so the taxonomy for all archaea is simply Archaea. This may change in future versions of the package, as more data is collected. We also implemented a Reconstruction taxonomy for those sequences that are ancestral reconstructions. For these sequences, their group category places them into algae or bacteria, as appropriate. Finally, there are a few sequences classified as Unknown which did not have a known taxonomic classification, or were bacteria with no known class.

The following tables list the taxonomic classifications present in the database for algae, plants, and bacteria. The first has the algal taxonomies, and the second the plant taxonomies, and the third lists the bacterial taxonomies. Since some of the bacterial classes only have a handful of measurements in them, the second table also groups these classes by their phyla to make it easier to determine what other classes are most likely to contain related sequences.

Algae
Brown algae
Chromerida
Coccolithophores
Diatoms
Dinoflagellate
Green algae
Haptophytes
Macroalgae
Red algae
Plants
Aquatic plants
Basal angiosperms
Bryophytes
C3 plants
C3-C4 plants
C4 plants
CAM plants
Carnivorous plants
Gymnosperms, Ferns, and Lycopods
Bacteria Phylum Class
Actinomycetota Actinomycetes
Bacillota Bacilli
Clostridia
Calditrichota Calditrichia
Chloroflexota Anaerolineae
Ardenticatenia
Chloroflexi
Limnocylindria
Candidate phyla radiation CPR
Cyanobacteriota Cyanobacteria
Peregrinibacteriota Peregrinibacteria
Pseudomonadota Acidithiobacillia
Alphaproteobacteria
Betaproteobacteria
Mariprofundia
Gammaproteobacteria
Hydrogenophilia
Spirochaetota Leptospiria
Thermosdesulfobacteriota Desulfovibrionia
Verrucomicrobiota Verrucomicrobiia

1.3 Forms of Rubisco

The forms of Rubisco included in this package are as follows:

Forms of Rubisco
1A
1Aq
1Ac
1B
1Bc
1C
1D
1E
1_Anaero
1’
1’’
2
3
2_3

1A is implemented only for kinetic measurements where an organism has both form 1Ac and 1Aq, and the study authors did not purify the Rubisco before measuring the kinetics.

2. Kinetics

Once you have found any appropriate kinetics that apply to your enzyme, the next step is to create an Enzyme object that represents the enzyme as best as possible. We have separated this section by the various scenarios you may encounter when creating a custom enzyme, although strategies between many of these scenarios will be shared.

2.1 I have measured the kinetics for my enzyme (or there’s a study not in the database)

If you have measurements of the kinetics for your enzyme, you can fill those in manually. This is, in many ways, the easiest scenario to deal with. In our example, we will assume that you have measured all four of the parameters, but if you have measured only some of them, you can go to section 2.4 to figure out how to fill in those missing parameters.

Let’s say we’ve measured the kinetics at 25°C for the form II Rubisco from the Gammaproteobacterium SUP05: kcat,C = 7.2, Kc=36, Ko=68, SC/O=14. To create a custom Enzyme object, we’ll use the function new_enzyme():

SUP05_Rbc<-new_enzyme(kcat_val=7.2,Kc_val=36,Ko_val=68,S_val=14)
SUP05_Rbc
#> Enzyme "":
#>   kcat = 7.2 s⁻¹ @ T_kcat = 25°C
#>   K_c = 36 μM @ T_c = 25°C
#>   K_o = 68 μM @ T_o = 25°C
#>   S = 14 @ T_S = 25°C
#>   Upper thermal limit = 55°C
#>   PGS = NA

Since our measurements were done at 25°C, the default assumption, we do not need to input a temperature in any way. However, let’s say that instead we measured all of these at 22°C, and our SC/O was measured at 30°C. We can input our temperatures using the temp argument and the specific argument for SC/O, S_T:

SUP05_Rbc2<-new_enzyme(kcat_val=7.2,Kc_val=36,Ko_val=68,S_val=14,temp=22,S_T=30)
SUP05_Rbc2
#> Enzyme "":
#>   kcat = 7.2 s⁻¹ @ T_kcat = 22°C
#>   K_c = 36 μM @ T_c = 22°C
#>   K_o = 68 μM @ T_o = 22°C
#>   S = 14 @ T_S = 30°C
#>   Upper thermal limit = 55°C
#>   PGS = NA

2.1.1 new_enzyme() Arguments

new_enzyme() also includes the arguments PGS, to add a PGS pathway (which can also be added when combining the Enzyme and DHScale objects using CO2_dependence()), and name, if you wish to have more description than what the object name can provide.

Argument Description Default Accepted Inputs
kcat_val Value of kcat,c (required) Any number
Kc_val Value of Kc (required) Any number
Ko_val Value of Ko (required) Any number
S_val Value of SC/O (required) Any number
temp Shared temperature for all kinetic parameters 25 Any number
kcat_T Measurement temperature for kcat,c NULL (default to temp) Any number
Kc_T Measurement temperature for Kc NULL (default to temp) Any number
Ko_T Measurement temperature for Ko NULL (default to temp) Any number
S_T Measurement temperature for SC/O NULL (default to temp) Any number
T_max Upper thermal limit for enzyme NULL (default to 55) Any number
PGS PGS stoichiometry to use NA “canon”, “diatom”, “gross”, or “alt”
name Name of the enzyme "" Any string

2.2 There are multiple complete studies for my enzyme

For a few enzymes, there are multiple studies that have determined all of the kinetics, but there is no methodology-corrected average or other composite. For example, there have been two complete studies of Beta vulgaris: Hermida-Carrera 2016 and Orr 2016. How do you choose between these studies? In the abridged table, there is minimal data about the two studies, but if we look at the same studies in the comprehensive table, we can see more data.

search_enzyme("Beta",data="comprehensive")[3:4,]
#> Matched genus in comprehensive table
#>                           identifier genus  species subspecies mutant
#> 3 beta_vulgaris_Hermida-Carrera_2016  Beta vulgaris    Detroit  FALSE
#> 4             beta_vulgaris_Orr_2016  Beta vulgaris   vulgaris  FALSE
#>   mutant_details primary heterologous_expression kcat_val kcat_T kcat_pH Kc_val
#> 3           <NA>    TRUE                   FALSE      2.0     NA       8   10.8
#> 4           <NA>    TRUE                   FALSE      3.8     NA      NA   17.0
#>   Kc_T Kc_pH Ko_val Ko_T Ko_pH S_val S_T S_pH temp  pH pKa_used form   PGS
#> 3   NA     8    357   NA    NA 101.0  NA   NA   25 8.2     6.11   1B canon
#> 4   NA    NA    401   NA    NA  97.8  NA  8.2   25 8.0     6.11   1B canon
#>    taxonomy  group
#> 3 C3 plants Plants
#> 4 C3 plants Plants
#>                                                                                                                                         note
#> 3 Ko is reported in Iniguez databases (Iniguez et al. 2019, Iniguez et al. 2021, etc.) although only kcat_o/Ko is reported in original paper
#> 4                       Points to Prins JExpB 2016 for methods. Extracted pH and pKa from there. S measured at pH 8.2, rest measured at 8.0.
#>              short_ref year
#> 3 Hermida-Carrera 2016 2016
#> 4             Orr 2016 2016

We can see that the subspecies (for plants this is usually a variant or cultivar) differs, so if we were interested in one of the two, we could choose that study. Alternatively, if we were interested in a different subspecies, we could merge the entries together using merge_entries(). merge_entries() will take multiple entries and merge each kinetic parameter by averaging them (method="mean"), finding the median (method="median"), or taking the last non-NA value (method="last"), as desired.

Let’s say we’re interested in this second option, investigating B. vulgaris more broadly. The first step is to look at the comprehensive table to ensure that we have captured all the measurements of Beta vulgaris, not just the complete entries:

df1<-search_enzyme("Beta",data="comprehensive")
#> Matched genus in comprehensive table
df1
#>                           identifier genus  species subspecies mutant
#> 1      vulgaris_marcosii_Galmés_2005  Beta vulgaris   marcosii  FALSE
#> 2      vulgaris_maritima_Galmés_2005  Beta vulgaris   maritima  FALSE
#> 3 beta_vulgaris_Hermida-Carrera_2016  Beta vulgaris    Detroit  FALSE
#> 4             beta_vulgaris_Orr_2016  Beta vulgaris   vulgaris  FALSE
#>   mutant_details primary heterologous_expression kcat_val kcat_T kcat_pH Kc_val
#> 1           <NA>    TRUE                   FALSE       NA     NA      NA     NA
#> 2           <NA>    TRUE                   FALSE       NA     NA      NA     NA
#> 3           <NA>    TRUE                   FALSE      2.0     NA       8   10.8
#> 4           <NA>    TRUE                   FALSE      3.8     NA      NA   17.0
#>   Kc_T Kc_pH Ko_val Ko_T Ko_pH S_val S_T S_pH temp  pH pKa_used form   PGS
#> 1   NA    NA     NA   NA    NA  96.3  25  8.2   NA  NA     6.20   1B canon
#> 2   NA    NA     NA   NA    NA  92.9  25  8.2   NA  NA     6.20   1B canon
#> 3   NA     8    357   NA    NA 101.0  NA   NA   25 8.2     6.11   1B canon
#> 4   NA    NA    401   NA    NA  97.8  NA  8.2   25 8.0     6.11   1B canon
#>    taxonomy  group
#> 1 C3 plants Plants
#> 2 C3 plants Plants
#> 3 C3 plants Plants
#> 4 C3 plants Plants
#>                                                                                                                                         note
#> 1                                                                                Cites Parry 1989 for method, so assumed pKa from that study
#> 2                                                                                Cites Parry 1989 for method, so assumed pKa from that study
#> 3 Ko is reported in Iniguez databases (Iniguez et al. 2019, Iniguez et al. 2021, etc.) although only kcat_o/Ko is reported in original paper
#> 4                       Points to Prins JExpB 2016 for methods. Extracted pH and pKa from there. S measured at pH 8.2, rest measured at 8.0.
#>              short_ref year
#> 1          Galmés 2005 2005
#> 2          Galmés 2005 2005
#> 3 Hermida-Carrera 2016 2016
#> 4             Orr 2016 2016

We bound them into a dataframe, since we know we will want to manipulate these entries later. The two studies that are not complete only measured the specificity, so there are 4 specificity measurements, with the rest of the parameters measured only twice. Our first step is to check the temp, kcat_T, Kc_T, Ko_T, and S_T columns, which would tell us if any of these measurements were done at a different temperature, in which case we can’t combine them. Lucky for us, all four of the studies only measured parameters at 25°C, so we can proceed to the merge. (At this point, you can remove columns for viewing ease, like we did in section 1. It is possible to use merge_entries() with these smaller dataframes, as long as you’ve included the identifier, kcat_val, Kc_val, Ko_val, S_val, and temp columns.)

To use merge_entries(), we have to choose a column that is unique to the different studies. In this case, identifier, subspecies, or short_ref would all work, but in general we recommend using identifier, which is always unique to each entry. Since one of the methods to combine entries relies on order ("last"), you also need to input the values of each identifier in the argument id_vals. However, in this first pass, we will use median to combine them, so we don’t care about order (which also lets us simply use that column of the dataframe to call the identifiers). merge_entries() requires, in order: 1) the data, 2) id_col aka the column of the unique values used to determine the order of the studies, 3) id_vals aka the values of the individual entries in that column, and 4) the method, which must be one of "median", "average", or "last". You should also add a new name for your entry in new_id, which can be any string. Here’s an example using "median" as our method:

df2<-merge_entries(df1,"identifier",df1$identifier,"median",new_id="Vulgaris_merged")
df2
#>                           identifier genus  species subspecies mutant
#> 1      vulgaris_marcosii_Galmés_2005  Beta vulgaris   marcosii  FALSE
#> 2      vulgaris_maritima_Galmés_2005  Beta vulgaris   maritima  FALSE
#> 3 beta_vulgaris_Hermida-Carrera_2016  Beta vulgaris    Detroit  FALSE
#> 4             beta_vulgaris_Orr_2016  Beta vulgaris   vulgaris  FALSE
#> 5                    Vulgaris_merged  Beta vulgaris       <NA>  FALSE
#>   mutant_details primary heterologous_expression kcat_val kcat_T kcat_pH Kc_val
#> 1           <NA>    TRUE                   FALSE       NA     NA      NA     NA
#> 2           <NA>    TRUE                   FALSE       NA     NA      NA     NA
#> 3           <NA>    TRUE                   FALSE      2.0     NA       8   10.8
#> 4           <NA>    TRUE                   FALSE      3.8     NA      NA   17.0
#> 5           <NA>    TRUE                   FALSE      2.9     NA       8   13.9
#>   Kc_T Kc_pH Ko_val Ko_T Ko_pH  S_val S_T S_pH temp  pH pKa_used form   PGS
#> 1   NA    NA     NA   NA    NA  96.30  25  8.2   NA  NA    6.200   1B canon
#> 2   NA    NA     NA   NA    NA  92.90  25  8.2   NA  NA    6.200   1B canon
#> 3   NA     8    357   NA    NA 101.00  NA   NA   25 8.2    6.110   1B canon
#> 4   NA    NA    401   NA    NA  97.80  NA  8.2   25 8.0    6.110   1B canon
#> 5   NA     8    379   NA    NA  97.05  25  8.2   25 8.1    6.155   1B canon
#>    taxonomy  group
#> 1 C3 plants Plants
#> 2 C3 plants Plants
#> 3 C3 plants Plants
#> 4 C3 plants Plants
#> 5 C3 plants Plants
#>                                                                                                                                         note
#> 1                                                                                Cites Parry 1989 for method, so assumed pKa from that study
#> 2                                                                                Cites Parry 1989 for method, so assumed pKa from that study
#> 3 Ko is reported in Iniguez databases (Iniguez et al. 2019, Iniguez et al. 2021, etc.) although only kcat_o/Ko is reported in original paper
#> 4                       Points to Prins JExpB 2016 for methods. Extracted pH and pKa from there. S measured at pH 8.2, rest measured at 8.0.
#> 5                                                                                                                                       <NA>
#>              short_ref year
#> 1          Galmés 2005 2005
#> 2          Galmés 2005 2005
#> 3 Hermida-Carrera 2016 2016
#> 4             Orr 2016 2016
#> 5                 <NA> <NA>

Any text column that did not match in all entries was set to NA. This would be the same if you used the "mean" merging method as well. The "last" method will instead take the final entry that is not NA and fill that in for any text column. The mathematical merges (median and mean) also combine ancillary numerical columns like pKa and pH.

This new dataframe includes all of the original entries that we used to merge. If we don’t want that to be the case, we can set the argument keep_merged to FALSE:

df3<-merge_entries(df1,"identifier",df1$identifier,"median",new_id="Vulgaris_merged",keep_merged=FALSE)
df3
#>        identifier genus  species subspecies mutant mutant_details primary
#> 1 Vulgaris_merged  Beta vulgaris         NA  FALSE             NA    TRUE
#>   heterologous_expression kcat_val kcat_T kcat_pH Kc_val Kc_T Kc_pH Ko_val Ko_T
#> 1                   FALSE      2.9     NA       8   13.9   NA     8    379   NA
#>   Ko_pH S_val S_T S_pH temp  pH pKa_used form   PGS  taxonomy  group note
#> 1    NA 97.05  25  8.2   25 8.1    6.155   1B canon C3 plants Plants   NA
#>   short_ref year
#> 1        NA   NA

What if we were interested in the marcosii cultivar, and so we wanted to keep its measured specificity value? We have two options: 1) we can use a different study as the base and replace only the specificity, or 2) we can find the median of all values, and then replace only the specificity. Either of these will require the use of the "last" merging method.

We’ll start with 1) as it’s the easier option. We decide that we will combine the Beta vulgaris vulgaris entry with the Beta vulgaris marcosii entry. Now, our argument for id_vals will not be all four of our studies in the base df1 dataframe, but only these two:

df4<-merge_entries(df1,"identifier",c(df1$identifier[1],df1$identifier[4]),"last",new_id="Vulgaris_merged",keep_unmerged=FALSE)
df4
#>                       identifier genus  species subspecies mutant
#> 1  vulgaris_marcosii_Galmés_2005  Beta vulgaris   marcosii  FALSE
#> 4         beta_vulgaris_Orr_2016  Beta vulgaris   vulgaris  FALSE
#> 11               Vulgaris_merged  Beta vulgaris   vulgaris  FALSE
#>    mutant_details primary heterologous_expression kcat_val kcat_T kcat_pH
#> 1            <NA>    TRUE                   FALSE       NA     NA      NA
#> 4            <NA>    TRUE                   FALSE      3.8     NA      NA
#> 11           <NA>    TRUE                   FALSE      3.8     NA      NA
#>    Kc_val Kc_T Kc_pH Ko_val Ko_T Ko_pH S_val S_T S_pH temp pH pKa_used form
#> 1      NA   NA    NA     NA   NA    NA  96.3  25  8.2   NA NA     6.20   1B
#> 4      17   NA    NA    401   NA    NA  97.8  NA  8.2   25  8     6.11   1B
#> 11     17   NA    NA    401   NA    NA  97.8  25  8.2   25  8     6.11   1B
#>      PGS  taxonomy  group
#> 1  canon C3 plants Plants
#> 4  canon C3 plants Plants
#> 11 canon C3 plants Plants
#>                                                                                                                    note
#> 1                                                           Cites Parry 1989 for method, so assumed pKa from that study
#> 4  Points to Prins JExpB 2016 for methods. Extracted pH and pKa from there. S measured at pH 8.2, rest measured at 8.0.
#> 11 Points to Prins JExpB 2016 for methods. Extracted pH and pKa from there. S measured at pH 8.2, rest measured at 8.0.
#>      short_ref year
#> 1  Galmés 2005 2005
#> 4     Orr 2016 2016
#> 11    Orr 2016 2016

Hmm. We ended up with an entry that is simply a duplicate of the Orr 2016 entry. (This example also illustrates why the use of keep_unmerged=FALSE may be helpful, as it removed the two that are not being merged.) Our problem here lies in the order of the entries that we gave to id_vals; since we listed the marcosii study first, and "last" takes the final entry it is presented with, only the Orr study was kept. We have to flip the order in id_vals to get the result we want:

df4<-merge_entries(df1,"identifier",c(df1$identifier[4],df1$identifier[1]),"last",new_id="Vulgaris_merged",keep_unmerged=FALSE)
df4
#>                       identifier genus  species subspecies mutant
#> 1  vulgaris_marcosii_Galmés_2005  Beta vulgaris   marcosii  FALSE
#> 4         beta_vulgaris_Orr_2016  Beta vulgaris   vulgaris  FALSE
#> 11               Vulgaris_merged  Beta vulgaris   marcosii  FALSE
#>    mutant_details primary heterologous_expression kcat_val kcat_T kcat_pH
#> 1            <NA>    TRUE                   FALSE       NA     NA      NA
#> 4            <NA>    TRUE                   FALSE      3.8     NA      NA
#> 11           <NA>    TRUE                   FALSE      3.8     NA      NA
#>    Kc_val Kc_T Kc_pH Ko_val Ko_T Ko_pH S_val S_T S_pH temp pH pKa_used form
#> 1      NA   NA    NA     NA   NA    NA  96.3  25  8.2   NA NA     6.20   1B
#> 4      17   NA    NA    401   NA    NA  97.8  NA  8.2   25  8     6.11   1B
#> 11     17   NA    NA    401   NA    NA  96.3  25  8.2   25  8     6.20   1B
#>      PGS  taxonomy  group
#> 1  canon C3 plants Plants
#> 4  canon C3 plants Plants
#> 11 canon C3 plants Plants
#>                                                                                                                    note
#> 1                                                           Cites Parry 1989 for method, so assumed pKa from that study
#> 4  Points to Prins JExpB 2016 for methods. Extracted pH and pKa from there. S measured at pH 8.2, rest measured at 8.0.
#> 11                                                          Cites Parry 1989 for method, so assumed pKa from that study
#>      short_ref year
#> 1  Galmés 2005 2005
#> 4     Orr 2016 2016
#> 11 Galmés 2005 2005

So that’s option one. Our second option, if we don’t want to rely on a single study, is to find the median (or average) of all the values measured by everyone, and then replace only the specificity. In this case, we’ll do exactly the same thing we did before to produce the median, keeping the merged entries, and then merge only our new merged entry and the marcosii study with the "last" method:

df5<-merge_entries(df1,"identifier",df1$identifier,"median",new_id="Vulgaris_merged")
df5<-merge_entries(df5,"identifier",c("Vulgaris_merged",df1$identifier[1]),"last",new_id="Marcosii_merged",keep_unmerged=FALSE)
df5
#>                       identifier genus  species subspecies mutant
#> 1  vulgaris_marcosii_Galmés_2005  Beta vulgaris   marcosii  FALSE
#> 5                Vulgaris_merged  Beta vulgaris       <NA>  FALSE
#> 11               Marcosii_merged  Beta vulgaris   marcosii  FALSE
#>    mutant_details primary heterologous_expression kcat_val kcat_T kcat_pH
#> 1            <NA>    TRUE                   FALSE       NA     NA      NA
#> 5            <NA>    TRUE                   FALSE      2.9     NA       8
#> 11           <NA>    TRUE                   FALSE      2.9     NA       8
#>    Kc_val Kc_T Kc_pH Ko_val Ko_T Ko_pH S_val S_T S_pH temp  pH pKa_used form
#> 1      NA   NA    NA     NA   NA    NA 96.30  25  8.2   NA  NA    6.200   1B
#> 5    13.9   NA     8    379   NA    NA 97.05  25  8.2   25 8.1    6.155   1B
#> 11   13.9   NA     8    379   NA    NA 96.30  25  8.2   25 8.1    6.200   1B
#>      PGS  taxonomy  group
#> 1  canon C3 plants Plants
#> 5  canon C3 plants Plants
#> 11 canon C3 plants Plants
#>                                                           note   short_ref year
#> 1  Cites Parry 1989 for method, so assumed pKa from that study Galmés 2005 2005
#> 5                                                         <NA>        <NA> <NA>
#> 11 Cites Parry 1989 for method, so assumed pKa from that study Galmés 2005 2005

Any of these new dataframes we’ve made (as an example we’ll use this most recent one) can then be used as the base data for Enzyme(), using the argument data:

marcosii_Rbc<-Enzyme("Marcosii_merged",data=df5)
marcosii_Rbc
#> Enzyme "Marcosii_merged":
#>   kcat = 2.9 s⁻¹ @ T_kcat = 25°C
#>   K_c = 13.9 μM @ T_c = 25°C
#>   K_o = 379 μM @ T_o = 25°C
#>   S = 96.3 @ T_S = 25°C
#>   Upper thermal limit = 55°C
#>   PGS = "canon"

We use our new_id and the dataframe to call the appropriate enzyme. If we’d used a different column for our unique ids and therefore left identifier blank on our new entry, we would also need to set the id_col argument in Enzyme() to the appropriate column name for Enzyme() to correctly identify the entry.

2.2.1 merge_entries() arguments

Further customization of merged entries can be done; for example, providing a list of columns that must be the same in order for the merge to occur. Here are all the arguments that can be provided to merge_entries():

Argument Description Default Accepted Inputs
data The dataframe with the entries (required) Any dataframe
id_col The identifying column for the entries desired (required) Any column name string (i.e. “identifier”)
id_vals The values of the desired entries in the identifying column (required) Any vector of values
method Which method to use for merging (required) “average”, “median”, or “last”
new_id The new value of the merged entry in the identifying column NA Any single input, numerical or string
const_cols Columns whose values must be constant in the desired entries for the merge to occur NULL Any list of strings identifying the columns
keep_merged Whether to keep pre-merged entries TRUE TRUE or FALSE
keep_unmerged Whether to keep unmerged entries TRUE TRUE or FALSE

2.3 All kinetics for my enzyme have been measured, but not in the same study

If all of the kinetics for your enzyme have been measured, but there are no “complete” entries, i.e. entries where all four kinetic parameters are present, you will need to merge entries into each other. We show one example workflow here, but since we have already provided many examples of ways to merge entries in section 2.2, we will not go into extensive detail here.

Let’s say we want to create an enzyme for the diatom Thalassiosira antarctica. When we search for it, we determine that there are two studies, one of which measured SC/O, the other which measured the other three kinetic parameters. We would like to combine them. In this case, because there are only two studies and no overlaps between them, it does not matter which combination method we use ("average", "median", or "last"). We’ll use "median".

ta_df<-search_enzyme("antarctica")[2:3,]
#> Matched species in comprehensive table
ta_merged<-merge_entries(ta_df,"identifier",ta_df$identifier,"median",new_id="t_antarctica_merged")
Enzyme("t_antarctica_merged",data=ta_merged)
#> Enzyme "t_antarctica_merged":
#>   kcat = 3.725 s⁻¹ @ T_kcat = 25°C
#>   K_c = 93 μM @ T_c = 25°C
#>   K_o = 1740 μM @ T_o = 25°C
#>   S = 90 @ T_S = 25°C
#>   Upper thermal limit = 55°C
#>   PGS = "canon"

2.4 Some of the kinetics for my enzyme have been measured

If you can use sections 2.1, 2.2, or 2.3, you are in some ways quite fortunate! For many of the non-plant organisms and sequences present in our database, only one or two of Rubisco’s four kinetic parameters have been measured. If you wish to create an enzyme for one of these, you’ll have to get more creative.

2.4.1 Other members of the genus have been measured

We’re going to start with the easiest option and work our way down. We want to compare the T. antarctica enzyme we created with another diatom, Skeletonema costatum. However, when we search for S. costatum, we find out that only the Kc and SC/O have been measured.

search_enzyme("costatum")
#> Matched species in comprehensive table
#>             identifier       genus  species subspecies mutant mutant_details
#> 1 costatum_Boller_2015 Skeletonema costatum       <NA>  FALSE           <NA>
#> 2 costatum_Haslam_2005 Skeletonema costatum       <NA>  FALSE           <NA>
#>   primary heterologous_expression kcat_val kcat_T kcat_pH Kc_val Kc_T Kc_pH
#> 1    TRUE                   FALSE       NA     NA      NA   48.9   25   7.5
#> 2    TRUE                   FALSE       NA     NA      NA     NA   NA    NA
#>   Ko_val Ko_T Ko_pH S_val S_T S_pH temp pH pKa_used form   PGS taxonomy group
#> 1     NA   NA    NA    NA  NA   NA   NA NA     6.08   1D canon  Diatoms Algae
#> 2     NA   NA    NA    72  25  8.2   NA NA     6.20   1D canon  Diatoms Algae
#>                                                                                                                                         note
#> 1 Vmax not included because they don't quantify Rubisco; calculated pKa individually for each vial so I'm not sure a correction can be made.
#> 2                                                                                                    References Parry 1989 for S measurement
#>     short_ref year
#> 1 Boller 2015 2015
#> 2 Haslam 2005 2005

We have to broaden our search, so we search for the genus next, keeping the data argument set to “comprehensive” to make sure we also capture our S. costatum data.

sc_df<-search_enzyme("Skeletonema",data="comprehensive")
#> Matched genus in comprehensive table
sc_df
#>              identifier       genus  species subspecies mutant mutant_details
#> 1  costatum_Boller_2015 Skeletonema costatum       <NA>  FALSE           <NA>
#> 2  costatum_Haslam_2005 Skeletonema costatum       <NA>  FALSE           <NA>
#> 3 marinoi_Valegård_2018 Skeletonema  marinoi       <NA>  FALSE           <NA>
#> 4    marinoi_Young_2016 Skeletonema  marinoi   CCMP1332  FALSE           <NA>
#>   primary heterologous_expression kcat_val kcat_T kcat_pH Kc_val Kc_T Kc_pH
#> 1    TRUE                   FALSE       NA     NA      NA   48.9   25   7.5
#> 2    TRUE                   FALSE       NA     NA      NA     NA   NA    NA
#> 3    TRUE                   FALSE    4.665     NA      NA   48.0   NA    NA
#> 4    TRUE                   FALSE    3.200     NA      NA   68.0   NA    NA
#>   Ko_val Ko_T Ko_pH S_val S_T S_pH temp  pH pKa_used form   PGS taxonomy group
#> 1     NA   NA    NA    NA  NA   NA   NA  NA     6.08   1D canon  Diatoms Algae
#> 2     NA   NA    NA    72  25  8.2   NA  NA     6.20   1D canon  Diatoms Algae
#> 3   1810   NA    NA    96  NA  8.1   25 8.2     6.11   1D canon  Diatoms Algae
#> 4    883   NA    NA    NA  NA   NA   25 8.0     6.25   1D canon  Diatoms Algae
#>                                                                                                                                         note
#> 1 Vmax not included because they don't quantify Rubisco; calculated pKa individually for each vial so I'm not sure a correction can be made.
#> 2                                                                                                    References Parry 1989 for S measurement
#> 3                                                                                                            pH from Carmo-Silva et al. 2010
#> 4                                                                                   pKa from Whitney et al. 2011; pKa not necessary for Sc/o
#>       short_ref year
#> 1   Boller 2015 2015
#> 2   Haslam 2005 2005
#> 3 Valegård 2018 2018
#> 4    Young 2016 2016

Ok, that’s better. There are two studies that measured Skeletonema marinoi and all of the four parameters are measured at least once. We can use this data as a base, and in our final merged entry, replace the Kc and SC/O with the S. costatum measurements. Since it doesn’t matter if we include the S. costatum measurements in the medians we construct (we’ll be replacing any of those with the value from S. costatum at the end), we can just use "median" to combine all these entries, and then "last" with the merged entry listed first followed by the S. costatum entries at the end to create a S. costatum enzyme. (See Section 2.2 for a more thorough explanation of this.)

sc_merged<-merge_entries(sc_df,"identifier",sc_df$identifier,"median",new_id="Skeletonema_merged")
sc_merged<-merge_entries(sc_merged,"identifier",c("Skeletonema_merged",sc_df$identifier[1:2]),"last",new_id="Costatum_merged",keep_unmerged=FALSE)
sc_merged
#>              identifier       genus  species subspecies mutant mutant_details
#> 1  costatum_Boller_2015 Skeletonema costatum       <NA>  FALSE           <NA>
#> 2  costatum_Haslam_2005 Skeletonema costatum       <NA>  FALSE           <NA>
#> 5    Skeletonema_merged Skeletonema     <NA>   CCMP1332  FALSE           <NA>
#> 11      Costatum_merged Skeletonema costatum   CCMP1332  FALSE           <NA>
#>    primary heterologous_expression kcat_val kcat_T kcat_pH Kc_val Kc_T Kc_pH
#> 1     TRUE                   FALSE       NA     NA      NA   48.9   25   7.5
#> 2     TRUE                   FALSE       NA     NA      NA     NA   NA    NA
#> 5     TRUE                   FALSE   3.9325     NA      NA   48.9   25   7.5
#> 11    TRUE                   FALSE   3.9325     NA      NA   48.9   25   7.5
#>    Ko_val Ko_T Ko_pH S_val S_T S_pH temp  pH pKa_used form   PGS taxonomy group
#> 1      NA   NA    NA    NA  NA   NA   NA  NA    6.080   1D canon  Diatoms Algae
#> 2      NA   NA    NA    72  25 8.20   NA  NA    6.200   1D canon  Diatoms Algae
#> 5  1346.5   NA    NA    84  25 8.15   25 8.1    6.155   1D canon  Diatoms Algae
#> 11 1346.5   NA    NA    72  25 8.20   25 8.1    6.200   1D canon  Diatoms Algae
#>                                                                                                                                          note
#> 1  Vmax not included because they don't quantify Rubisco; calculated pKa individually for each vial so I'm not sure a correction can be made.
#> 2                                                                                                     References Parry 1989 for S measurement
#> 5                                                                                                                                        <NA>
#> 11                                                                                                    References Parry 1989 for S measurement
#>      short_ref year
#> 1  Boller 2015 2015
#> 2  Haslam 2005 2005
#> 5         <NA> <NA>
#> 11 Haslam 2005 2005
Enzyme("Costatum_merged",data=sc_merged)
#> Enzyme "Costatum_merged":
#>   kcat = 3.9325 s⁻¹ @ T_kcat = 25°C
#>   K_c = 48.9 μM @ T_c = 25°C
#>   K_o = 1346.5 μM @ T_o = 25°C
#>   S = 72 @ T_S = 25°C
#>   Upper thermal limit = 55°C
#>   PGS = "canon"

2.4.2 Other members of the taxonomic group or Rubisco form have been measured

A very similar process can be followed when instead of other members of the genus, other members of the taxonomic group (or Rubisco form) have been measured. Instead of S. costatum, now we’re interested in Bellerochea horologicalis, but specificity has never been measured for this Rubisco, or any Rubisco in this genus. So we broaden our search to all diatoms (which we already know have at least one specificity measurement), and save the result as a dataframe.

search_enzyme("horologicalis")
#> Matched species in comprehensive table
#>                 identifier       genus       species subspecies mutant
#> 1 horologicalis_Young_2016 Bellerochea horologicalis  CS-874/01  FALSE
#>   mutant_details primary heterologous_expression kcat_val kcat_T kcat_pH Kc_val
#> 1           <NA>    TRUE                   FALSE      2.1     NA      NA     50
#>   Kc_T Kc_pH Ko_val Ko_T Ko_pH S_val S_T S_pH temp pH pKa_used form   PGS
#> 1   NA    NA    764   NA    NA    NA  NA   NA   25  8     6.25   1D canon
#>   taxonomy group                                                     note
#> 1  Diatoms Algae pKa from Whitney et al. 2011; pKa not necessary for Sc/o
#>    short_ref year
#> 1 Young 2016 2016
diatom_df<-search_enzyme("Diatoms",data="comprehensive")
#> Matched taxonomy in comprehensive table

We could then use that dataframe to average or find the median of all of the diatom data, and at the end, replace it with the B. horologicalis data - just a bigger version of the merge we did in section 2.4.1 when merging the genus. However, in the package we have also included average versions of many of the taxonomic groups or forms of Rubisco present in the database (medians of all the data from 25°C in the database that matches that taxonomic group/form of Rubisco, as appropriate). When we look at the averages, we can see that there is a diatom 1D already available for us to use.

search_enzyme("average")
#> Matched genus in abridged table
#>                    identifier   genus species     subspecies kcat_val kcat_T
#> 1   average_1Ac_cyanobacteria Average     1Ac  Cyanobacteria     9.40     NA
#> 2  average_1Ac_proteobacteria Average     1Ac Proteobacteria     7.00     30
#> 3                 average_1Aq Average     1Aq           <NA>     6.90     NA
#> 4        average_1B_C3_plants Average      1B      C3 plants     2.80     NA
#> 5        average_1B_C4_plants Average      1B      C4 plants     4.16     NA
#> 6     average_1B_C3-C4_plants Average      1B   C3-C4 plants     2.86     NA
#> 7       average_1B_CAM_plants Average      1B     CAM plants     4.50     NA
#> 8       average_1B_bryophytes Average      1B     Bryophytes     3.35     NA
#> 9   average_1B_Aquatic_plants Average      1B Aquatic plants     2.38     NA
#> 10     average_1B_Green_algae Average      1B    Green algae     2.47     NA
#> 11             average_1B_all Average      1B           <NA>     2.96     NA
#> 12                average_1Bc Average     1Bc           <NA>     9.78     NA
#> 13                 average_1C Average      1C           <NA>     2.10     30
#> 14         average_1D_Diatoms Average      1D        Diatoms     3.25     NA
#> 15       average_1D_Red_algae Average      1D      Red algae     1.59     NA
#> 16      average_1D_Macroalgae Average      1D     Macroalgae     2.08     NA
#> 17             average_1D_all Average      1D           <NA>     2.27     NA
#> 18       average_2_Prokaryote Average       2     Prokaryote    12.30     NA
#> 19            average_Rubisco Average Rubisco           <NA>     3.19     NA
#>    Kc_val Kc_T Ko_val Ko_T S_val S_T temp form   PGS       taxonomy    group
#> 1   169.0   NA   1310   NA  53.5  NA   25  1Ac canon  Cyanobacteria Bacteria
#> 2   460.8   NA   1310   NA  33.1  30   25  1Ac  <NA>           <NA> Bacteria
#> 3    34.8   NA    965   NA  43.5  NA   25  1Aq  <NA>           <NA> Bacteria
#> 4    15.3   NA    429   NA  98.2  NA   25   1B canon      C3 plants   Plants
#> 5    26.3   NA    444   NA  82.2  NA   25   1B canon      C4 plants   Plants
#> 6    12.4   NA    646   NA  82.6  NA   25   1B canon   C3-C4 plants   Plants
#> 7    15.0   NA    312   NA  88.7  NA   25   1B canon     CAM plants   Plants
#> 8    24.4   NA    565   NA  70.5  NA   25   1B canon     Bryophytes   Plants
#> 9    22.0   NA    989   NA  90.0  NA   25   1B canon Aquatic plants   Plants
#> 10   32.0   NA    480   NA  62.0  NA   25   1B canon    Green algae   Plants
#> 11   17.3   NA    463   NA  94.5  NA   25   1B canon           <NA>   Plants
#> 12  168.0   NA    841   NA  45.5  NA   25  1Bc canon  Cyanobacteria Bacteria
#> 13   55.5   30   1282   NA  62.0  NA   25   1C  <NA>           <NA> Bacteria
#> 14   48.5   NA    764   NA  92.0  NA   25   1D canon        Diatoms    Algae
#> 15    8.0   NA   1238   NA 166.0  NA   25   1D canon      Red algae    Algae
#> 16   18.2   NA   1112   NA 120.9  NA   25   1D canon     Macroalgae    Algae
#> 17   23.9   NA    862   NA 104.0  NA   25   1D canon           <NA>    Algae
#> 18  161.0   NA    220   NA  13.3  NA   25    2  <NA>           <NA> Bacteria
#> 19   18.8   NA    466   NA  91.6  NA   25 <NA>  <NA>           <NA>     <NA>
#>                                                                                                                           note
#> 1                                                               values medians of collected cyanobacterial measurements at 25C
#> 2  kcat & S median of 1Ac proteobacteria at 30C, Kc median of 1Ac proteobacteria at 25C, Ko median of 1Ac cyanobacteria at 25C
#> 3                                                                          values medians of collected 1Aq measurements at 25C
#> 4                                                                           values medians of collected C3 measurements at 25C
#> 5                                                                           values medians of collected C4 measurements at 25C
#> 6                                                                        values medians of collected C3-C4 measurements at 25C
#> 7                                                                          values medians of collected CAM measurements at 25C
#> 8                                                                    values medians of collected Bryophyte measurements at 25C
#> 9                                                                values medians of collected aquatic plant measurements at 25C
#> 10                                                                 values medians of collected green algae measurements at 25C
#> 11                                                                          values medians of collected 1B measurements at 25C
#> 12                                                                         values medians of collected 1Bc measurements at 25C
#> 13                     kcat, Kc medians of collected 1C measurements at 30C; Ko, S medians of collected 1C measurements at 25C
#> 14                                                                      values medians of collected diatom measurements at 25C
#> 15                                                                   values medians of collected red algae measurements at 25C
#> 16                                                                  values medians of collected macroalgae measurements at 25C
#> 17                                                                          values medians of collected 1D measurements at 25C
#> 18                                                           values medians of collected prokaryote form 2 measurements at 25C
#> 19                                          values medians of collected Rubisco measurements at 25C, excluding forms 2/3 and 3
#>       short_ref
#> 1  this package
#> 2  this package
#> 3  this package
#> 4  this package
#> 5  this package
#> 6  this package
#> 7  this package
#> 8  this package
#> 9  this package
#> 10 this package
#> 11 this package
#> 12 this package
#> 13 this package
#> 14 this package
#> 15 this package
#> 16 this package
#> 17 this package
#> 18 this package
#> 19 this package
diatom_base<-search_enzyme("average")[14,]
#> Matched genus in abridged table

We can then call the B. horologicalis enzyme, and replace the only missing value with the one we just saved as diatom_base. Since the average enzymes are all from the abridged table and thus don’t have all the columns, we’ll want to do that with modify_enzyme(). (Alternatively, you could pare the B. horologicalis dataframe down to have only the columns the abridged table contains, which would allow you to use merge_entries())

First, we need to make the incomplete B. horologicalis enzyme (although you could of course do this the other way around as well).

bh_Rbc<-Enzyme("horologicalis_Young_2016")
bh_Rbc
#> Enzyme "horologicalis_Young_2016":
#>   kcat = 2.1 s⁻¹ @ T_kcat = 25°C
#>   K_c = 50 μM @ T_c = 25°C
#>   K_o = 764 μM @ T_o = 25°C
#>   S = NA @ T_S = 25°C
#>   Upper thermal limit = 55°C
#>   PGS = "canon"

Then we can use modify_enzyme() to adjust the missing SC/O. modify_enzyme() has largely the same arguments as new_enzyme() (see Section 2.1.1), with the addition of the first, required argument - the enzyme to be modified! Its only difference is the lack of a temp argument. If you need to change the temperature certain kinetic values were measured at, you’ll need to modify kcat_T, Kc_T, Ko_T, and S_T separately.

bh_Rbc<-modify_enzyme(bh_Rbc,S_val=diatom_base$S_val)
bh_Rbc
#> Enzyme "horologicalis_Young_2016":
#>   kcat = 2.1 s⁻¹ @ T_kcat = 25°C
#>   K_c = 50 μM @ T_c = 25°C
#>   K_o = 764 μM @ T_o = 25°C
#>   S = 92 @ T_S = 25°C
#>   Upper thermal limit = 55°C
#>   PGS = "canon"

If there weren’t any measurements of specificity in diatoms, we could instead pull that from an average of form 1D, or if form 1D had no specificity measurements, we could go even more broad to form 1 as a whole. This gets increasingly less likely to be similar to the real value, but unfortunately there’s no way around that except to measure more Rubisco kinetics!

2.5 None of the kinetics for my enzyme have been measured

If you have gotten to this point, this is pretty much the end of the road. If there are no kinetics for your enzyme, you’ll have to try and find an option that seems likely to be close, or go with the average for your taxonomic group/Rubisco form. We’ll start with the former.

This time we’re interested in looking at some autotrophic bacteria, in particular, the Gammaproteobacterium Thiomicrorhabdus arctica. T. arctica has two forms of Rubisco (a form 2 and a form 1Aq), but only the form 2 has been measured at all (kcat,C by Davidi 2020). If we’re interested in the form 1Aq, we are completely out of luck. So, ok. Let’s try looking at the Gammaproteobacteria and see what our options are. To cut down on the amount of entries that will be unhelpful, we filter our final search_enzyme() output so we only keep the form 1Aq non-metagenome-derived measurements (and we removed some columns that are unimportant for this example, along with the results from de Pins 2025 that are a reinterpretation of rates from de Pins 2024).

gpb_df<-search_enzyme("Gammaproteobacteria",data="comprehensive")[,c(1:4,7,9:10,12,15,18,21,24,26,27,29)]
#> Matched taxonomy in comprehensive table
gpb_df<-gpb_df[gpb_df$form=="1Aq",]
gpb_df<-gpb_df[gpb_df$group=="Bacteria",]
gpb_df<-gpb_df[gpb_df$primary,]
#now to remove the primary and group columns, which we don't need anymore
gpb_df<-gpb_df[,-c(5,14)]
gpb_df
#>                    identifier           genus       species subspecies kcat_val
#> 3         vinosum_Jordan_1985  Allochromatium       vinosum       <NA>   6.7000
#> 4         vinosum_Uemura_1996  Allochromatium       vinosum       <NA>       NA
#> 5         vinosum_Uemura_1997  Allochromatium       vinosum       <NA>   8.8000
#> 7      vinosum_Iaq_Viale_1990  Allochromatium       vinosum   Strain D   7.1000
#> 23   halochloris_de_pins_2024  Halorhodospira   halochloris       <NA>   2.7000
#> 29  kuenenii_1Aq_de_pins_2024 Hydrogenovibrio      kuenenii       <NA>   4.1000
#> 38   marinus_Iaq_Hayashi_1998 Hydrogenovibrio       marinus     MH-110   1.3752
#> 42      purpurea_de_pins_2024     Imhoffiella      purpurea       <NA>   4.4000
#> 47    ishizawaii_de_pins_2024   Methylomagnum    ishizawaii       <NA>   1.0000
#> 69 denitrificans_de_pins_2024 Thiohalorhabdus denitrificans       <NA>   3.8000
#>    kcat_T Kc_val Ko_val S_val temp form            taxonomy    short_ref
#> 3      NA   37.0    290  41.0   25  1Aq Gammaproteobacteria  Jordan 1985
#> 4      NA     NA     NA  44.4   NA  1Aq Gammaproteobacteria  Uemura 1996
#> 5      NA   28.4     NA  44.4   25  1Aq Gammaproteobacteria  Uemura 1997
#> 7      NA   32.5     NA    NA   25  1Aq Gammaproteobacteria   Viale 1990
#> 23     30     NA     NA    NA   NA  1Aq Gammaproteobacteria de Pins 2024
#> 29     30     NA     NA    NA   NA  1Aq Gammaproteobacteria de Pins 2024
#> 38     NA     NA     NA  26.6   30  1Aq Gammaproteobacteria Hayashi 1998
#> 42     30     NA     NA    NA   NA  1Aq Gammaproteobacteria de Pins 2024
#> 47     30     NA     NA    NA   NA  1Aq Gammaproteobacteria de Pins 2024
#> 69     30     NA     NA    NA   NA  1Aq Gammaproteobacteria de Pins 2024

1Aq has been measured in a variety of Gammaproteobacteria. We happen to know that H. marinus is very closely related to T. arctica, so that’s probably our best bet. However, Kc and Ko were not measured in that, so we’ll have to pull those from A. vinosum. Unfortunately, H. marinus was measured at 30°C, so we’ll have to remake our dataframe to include the individual kinetics’ temperature parameters and make sure those are correctly set at the end. Then we find the median of all the Gammaproteobacteria 1Aq data, and follow it by replacing the kcat,C and SC/O values with H. marinus’s. (See Sections 2.2 and 2.4.1 to see a more thorough explanation of the merge_entries() code used here.)

gpb_df<-search_enzyme("Gammaproteobacteria",data="comprehensive")[,c(1:4,9:10,12:13,15:16,18:19,21,24,26,27,29)]
#> Matched taxonomy in comprehensive table
gpb_df<-gpb_df[gpb_df$form=="1Aq",]
gpb_merged<-merge_entries(gpb_df,"identifier",gpb_df$identifier,"median",new_id="gpb_1Aq_merged")
gpb_merged<-merge_entries(gpb_merged,"identifier",c("gpb_1Aq_merged","marinus_Iaq_Hayashi_1998"),"last",new_id="Ta_merged",keep_unmerged=FALSE)
gpb_merged
#>                  identifier           genus species subspecies kcat_val kcat_T
#> 38 marinus_Iaq_Hayashi_1998 Hydrogenovibrio marinus     MH-110   1.3752     NA
#> 1            gpb_1Aq_merged            <NA>    <NA>       <NA>   4.9000     30
#> 11                Ta_merged Hydrogenovibrio marinus     MH-110   1.3752     30
#>    Kc_val Kc_T Ko_val Ko_T S_val S_T temp form            taxonomy    group
#> 38     NA   NA     NA   NA  26.6  NA   30  1Aq Gammaproteobacteria Bacteria
#> 1    32.5   NA    290   NA  42.7  25   25  1Aq Gammaproteobacteria     <NA>
#> 11   32.5   NA    290   NA  26.6  25   30  1Aq Gammaproteobacteria Bacteria
#>       short_ref
#> 38 Hayashi 1998
#> 1          <NA>
#> 11 Hayashi 1998
ta_1Aq<-Enzyme("Ta_merged",data=gpb_merged)
ta_1Aq
#> Enzyme "Ta_merged":
#>   kcat = 1.3752 s⁻¹ @ T_kcat = 30°C
#>   K_c = 32.5 μM @ T_c = 30°C
#>   K_o = 290 μM @ T_o = 30°C
#>   S = 26.6 @ T_S = 25°C
#>   Upper thermal limit = 55°C
#>   PGS = NA

Because of the way this particular merge worked out, we ended up with some wrong temperatures, so we need to go back in and modify the enzyme’s kcat_T, Kc_T, Ko_T, and S_T to fix that (see Section 2.4.2 for more details on modifying enzymes). Remember that there is no more global temp argument! After that, we have an Enzyme object we can use.

ta_1Aq<-modify_enzyme(ta_1Aq,kcat_T=30,Kc_T=25,Ko_T=25,S_T=30)
ta_1Aq
#> Enzyme "Ta_merged":
#>   kcat = 1.3752 s⁻¹ @ T_kcat = 30°C
#>   K_c = 32.5 μM @ T_c = 25°C
#>   K_o = 290 μM @ T_o = 25°C
#>   S = 26.6 @ T_S = 30°C
#>   Upper thermal limit = 55°C
#>   PGS = NA

If this data was not available and an average is provided in the database that matches the taxonomic group or form that you are interested in, you can always just use that average.

2.6 Some of the kinetics for my Rubisco form are not measured

Now we’re really at the end of the road. If there are no measurements of e.g. Ko for your Rubisco form (true of many of the more recently-discovered Rubisco forms), you will have to make a best judgment call of what the closest Rubisco form is and use the value from the average of that form, or look at an average or median or whatever you would like of all the Rubisco present in the database, or some other method we haven’t thought of. You can look at the previous sections for examples of merging entries to help you process the data.

3. Temperature Dependences

Temperature dependence (ΔH) data is much sparser than kinetics data for Rubisco, so most Rubiscos, even model ones, will need to rely on other data to fill in some of the gaps. Many of the procedures for dealing with these gaps will be the same as the ones we followed for Section 2’s enzyme kinetics. We will provide an example for each of these sections, but we will also point to the appropriate section of Section 2 for more information.

For all of the following examples, we use whatever data is available for ΔH Ko, but you will note that for the averages we have constructed, all of them use the same ΔH Ko, 26.7. As Galmés et al. 2016 discusses, in vitro measurements of ΔH Ko vary dramatically, even by sign. It is possible that this is accurate. However, it is also possible that this is due to the fact that almost all Ko values are determined by finding the slope of the Kc response as oxygen changes, and typically have quite large error bars. It is therefore not surprising that the subsequent step of determining ΔH Ko from these individual uncertain measurements leads to some quite confusing data points. When Galmés looked only at in vivo measurements of ΔH Ko, which measured Ko directly, all of the ΔH Ko values agreed in sign. We found the median of these values, excluding Arabidopsis thaliana’s measurement, which had a noticeably lower R2 value than everything else, and this median is what we have included in all of our average DHScales, with the thought that it is more accurate to the real ΔH Ko value than the median of the in vitro data would be. One major caveat here is that all of these in vivo values are from plants, so unfortunately any natural variation in the ΔH Ko value has been flattened. We still recommend using that value regardless, and hope that future studies will be able to measure ΔH Ko more directly.

3.1 I have measured the temperature dependences for my enzyme

If you have measurements of the temperature dependences for your enzyme, you can fill those in manually. In our example, we will assume that you have measured all four of the parameters, but if you have measured only some of them, you can go to section 3.3 to figure out how to fill in those missing parameters.

Let’s say we’ve measured the temperature dependences for the form II Rubisco from the Gammaproteobacterium SUP05: ΔH kcat,C=35.6, ΔH Kc=40.1, ΔH Ko=15.5, ΔH SC/O=-25.1. To create a custom DHScale object, we’ll use the function new_DHScale():

SUP05_DH<-new_DHScale(kcat_dH=35.6,Kc_dH=40.1,Ko_dH=15.5,S_dH=-25.1)
SUP05_DH
#> ΔH scaling "":
#>   ΔH_kcat = 35.6 kJ/mol
#>   ΔH_Kc = 40.1 kJ/mol
#>   ΔH_Ko = 15.5 kJ/mol
#>   ΔH_S = -25.1 kJ/mol

3.1.1 new_DHScale() Arguments

As with creating a new enzyme, the easiest way to create a DHScale object is to use one of the options presented in the provided data, but if you wish to create one from scratch, you can use new_DHScale(). The function has four required arguments, which are the ΔH values for each of kcat,c, Kc, Ko, and SC/O. As with new_enzyme(), new_DHScale() has an additional optional input, name, which can be any text string. name can be used to provide further information about the DHScale object that might not be contained within the name of the resulting object. Although a second constant (c) is measured and reported along with ΔH values, we calculate c during CO2_dependence(), from the DHScale’s ΔH for a particular kinetic parameter, the Enzyme object’s value for that parameter, and the temperature the Enzyme object’s value was measured at. That way, we ensure that the temperature scaling would actually produce the measured value: \[x(T)=e^{c-\frac{\Delta H}{RT}}\] \[c=ln{x(T)}+\frac{\Delta H}{RT}\]

Argument Description Default Accepted Inputs
kcat_dH Value of ΔH for kcat,c (required) Any number
Kc_dH Value of ΔH for Kc (required) Any number
Ko_dH Value of ΔH for Ko (required) Any number
S_dH Value of ΔH for SC/O (required) Any number
name Name of the enzyme "" Any string

3.2 All temperature dependences for my enzyme have been measured, but not in the same study

If all of the ΔH values for your enzyme have been measured, but there are no “complete” entries, i.e. entries where all four are present, you will need to merge entries into each other. We show one example workflow here, but since we have already provided many examples of ways to merge entries in section 2.2, we will not go into extensive detail here.

Let’s say we want to create a DHScale for the plant Trifolium repens. When we search for it, we determine that there are two studies, one of which measured ΔH kcat,C, and a second that measured the other three. We would like to combine them. In this case, because there are only two studies and no overlaps between them, it does not matter which combination method we use ("average", "median", or "last"). We’ll use "median".

tr_dH<-search_DHScale("repens")
#> Matched species in abridged table
tr_merged<-merge_entries(tr_dH,"identifier",tr_dH$identifier,"median",new_id="t_repens_dH_merged")
DHScale("t_repens_dH_merged",data=tr_merged)
#> ΔH scaling "t_repens_dH_merged":
#>   ΔH_kcat = 86.1 kJ/mol
#>   ΔH_Kc = 48.9 kJ/mol
#>   ΔH_Ko = 9.3 kJ/mol
#>   ΔH_S = -18 kJ/mol

3.3 Some of the temperature dependences for my enzyme have been measured

This scenario and 3.4 (none of the temperature dependences measured) are the most likely options for building a DHScale object, given the scarcity of temperature dependence data. As in the equivalent section for enzyme kinetics (section 2.4), we will begin with the easiest scenario to solve and proceed through the more complicated ones.

3.3.1 Other members of the genus have been measured

We want to make a DHScale for the plant Chenopodium album, but when we search for its temperature dependences, we see that only its ΔH kcat,C is measured.

search_DHScale("album")
#> Matched species in abridged table
#>             identifier       genus species subspecies kcat_dH Kc_dH Ko_dH S_dH
#> 1 album_galmés_2015_dH Chenopodium   album       <NA>    52.9    NA    NA   NA
#>   form  taxonomy  group                  note   short_ref
#> 1   1B C3 plants Plants From Sage et al. 1995 Galmés 2015

We have to broaden our search, so we search for the genus next.

ca_dH<-search_DHScale("Chenopodium")
#> Matched genus in abridged table
ca_dH
#>              identifier       genus   species subspecies kcat_dH Kc_dH Ko_dH
#> 1  album_galmés_2015_dH Chenopodium     album       <NA>    52.9    NA    NA
#> 2    murale_orr_2016_dH Chenopodium    murale       <NA>    54.0  41.9 -14.3
#> 3 petiolare_orr_2016_dH Chenopodium petiolare       <NA>    67.7  65.7 -39.1
#>    S_dH form  taxonomy  group                  note   short_ref
#> 1    NA   1B C3 plants Plants From Sage et al. 1995 Galmés 2015
#> 2 -16.3   1B C3 plants Plants                  <NA>    Orr 2016
#> 3 -14.9   1B C3 plants Plants                  <NA>    Orr 2016

Ok, Orr 2016 measured all the ΔH values for two other Chenopodium species, C. murale and C. petiolare. We can use this data as a base, and in our final merged entry, replace ΔH kcat,C with the C. album measurement. Since it doesn’t matter if we include the C. album measurement in the medians we construct (we’ll be replacing any that would pull from C. album with the actual value from C. album at the end), we can use "median" to combine all these entries, and then "last" with the merged entry listed first followed by the C. album entry at the end to replace the ΔH kcat,C with its C. album value. Now, we have a C. album DHScale. (See Section 2.2 for a more thorough explanation of this process.)

ca_merged<-merge_entries(ca_dH,"identifier",ca_dH$identifier,"median",new_id="Chenopodium_merged")
ca_merged<-merge_entries(ca_merged,"identifier",c("Chenopodium_merged",ca_dH$identifier[1]),"last",new_id="album_merged",keep_unmerged=FALSE)
ca_merged
#>              identifier       genus species subspecies kcat_dH Kc_dH Ko_dH
#> 1  album_galmés_2015_dH Chenopodium   album       <NA>    52.9    NA    NA
#> 4    Chenopodium_merged Chenopodium    <NA>       <NA>    54.0  53.8 -26.7
#> 11         album_merged Chenopodium   album       <NA>    52.9  53.8 -26.7
#>     S_dH form  taxonomy  group                  note   short_ref
#> 1     NA   1B C3 plants Plants From Sage et al. 1995 Galmés 2015
#> 4  -15.6   1B C3 plants Plants From Sage et al. 1995        <NA>
#> 11 -15.6   1B C3 plants Plants From Sage et al. 1995 Galmés 2015
DHScale("album_merged",data=ca_merged)
#> ΔH scaling "album_merged":
#>   ΔH_kcat = 52.9 kJ/mol
#>   ΔH_Kc = 53.8 kJ/mol
#>   ΔH_Ko = -26.7 kJ/mol
#>   ΔH_S = -15.6 kJ/mol

3.3.2 Other members of the taxonomic group or Rubisco form have been measured

A very similar process can be followed when instead of other members of the genus, other members of the taxonomic group (or Rubisco form) have been measured. Let us say that we are interested in building a DHScale for Zea mays, for which only ΔH Kc and ΔH SC/O have been measured, and no other species from Zea have been measured at all. So we broaden our search to all C4 plants and save the result as a dataframe.

search_DHScale("Zea")
#> Matched genus in abridged table
#>            identifier genus species subspecies kcat_dH Kc_dH Ko_dH  S_dH form
#> 1 mays_galmés_2016_dH   Zea    mays       <NA>      NA  22.9    NA -20.1   1B
#>    taxonomy  group                             note   short_ref
#> 1 C4 plants Plants From Hermida-Carrera et al. 2016 Galmés 2016
C4_df<-search_DHScale("C4 plants",data="abridged")
#> Matched taxonomy in abridged table

We can then use that dataframe to average or find the median of all of the C4 plant data, and at the end, replace it with the Z. mays data - just a bigger version of the merge we did in section 3.3.1 when merging the genus.

C4_merged<-merge_entries(C4_df,"identifier",C4_df$identifier,"median",new_id="C4_merged")
zm_merged<-merge_entries(C4_merged,"identifier",c("C4_merged","95"),"last",new_id="Zmays_merged",keep_unmerged=FALSE)
DHScale("Zmays_merged",data=zm_merged)
#> ΔH scaling "Zmays_merged":
#>   ΔH_kcat = 52.3 kJ/mol
#>   ΔH_Kc = 34.3 kJ/mol
#>   ΔH_Ko = -10.8 kJ/mol
#>   ΔH_S = -20.3 kJ/mol

Alternatively, we have also included average versions of many of the taxonomic groups or forms of Rubisco present in the database (medians of all the data in the database that matches that taxonomic group or form of Rubisco, as appropriate, with the ΔH Ko value set to 26.7). When we look at the averages, we can see that there is a C4 plant 1B average DHScale already available for us to use.

C4_average<-search_DHScale("C4 plants",data="averaged")
#> Matched taxonomy in averages table
C4_average
#>                identifier   genus species subspecies kcat_dH Kc_dH Ko_dH  S_dH
#> 1 average_1B_C4_Plants_dH Average      1B  C4 plants    52.8  34.7  26.7 -22.3
#>   form  taxonomy  group
#> 1   1B C4 plants Plants
#>                                                                             note
#> 1 Ko from in vivo estimates, all others average C4 Streptophyta from Galmés 2016
#>      short_ref
#> 1 this package

We can then call the Z. mays enzyme, and replace the only missing value with the C4_average one. We could do this with merge_entries() or modify_DHScale(). We will provide an example with modify_DHScale() here, as we have already demonstrated merge_entries() with this kind of data.

First, we need to make the incomplete Z. mays DHScale (although you could of course do this the other way around as well).

zm_dH<-DHScale("mays_galmés_2016_dH", data="abridged")
zm_dH
#> ΔH scaling "mays_galmés_2016_dH":
#>   ΔH_kcat = NA kJ/mol
#>   ΔH_Kc = 22.9 kJ/mol
#>   ΔH_Ko = NA kJ/mol
#>   ΔH_S = -20.1 kJ/mol

Then we can use modify_DHScale() to adjust the missing ΔH kcat,C and ΔH Ko. modify_DHScale() has all the same arguments as new_DHScale() (see Section 3.1.1), with the addition of the first, required argument - the DHScale to be modified!

zm_dH<-modify_DHScale(zm_dH,kcat_dH=C4_average$kcat_dH,Ko_dH=C4_average$Ko_dH)
zm_dH
#> ΔH scaling "mays_galmés_2016_dH":
#>   ΔH_kcat = 52.8 kJ/mol
#>   ΔH_Kc = 22.9 kJ/mol
#>   ΔH_Ko = 26.7 kJ/mol
#>   ΔH_S = -20.1 kJ/mol

If there weren’t any measurements of these values in C4 plants, we could instead pull that from an average of plant form 1B, and so on up the chain. This gets increasingly less likely to be similar to the real value, but especially with the temperature dependence data, which is sparse outside of plant form 1B values, it is unavoidable. In the next section, we will get into these stickier scenarios.

3.4 None of the temperature dependences for my enzyme/taxonomic group/form have been measured

With the scarcity of temperature dependence data, this is very likely to occur, especially for non-plant Rubiscos. If there are no temperature dependences for your enzyme, you’ll have to try and find an option that seems likely to be close, go with the average for your taxonomic group/Rubisco form, or use other appropriate data to fill in the gaps.

The initial steps of this process (look for something else in the taxonomic group that is similar, or find an average for your taxonomic group or Rubisco form) follow the same pattern as Sections 3.3.1 and 3.3.2, so we will skip to the more difficult cases. What do you do if some of the temperature dependence values from your form of Rubisco have never been measured? Or, as is very possible, no temperature dependence has ever been measured for your form of Rubisco?

3.4.1 Some of the temperature dependences for my form of Rubisco have never been measured

In the database currently, form 1D only has temperature dependence measurements for kcat,C and SC/O. As we recommend using 26.7 for the ΔH Ko, we can fill in that value easily, but what about the value for ΔH Kc? Unfortunately, our only choice is to take values from a different form. Outside of plants, there is currently only one single measurement of ΔH Kc, from Anabaena variabilis, a cyanobacterium with form 1Bc. As this is another aquatic organism, we will decide to use this value. Our other option is to use a median/average of all known values, which will be heavily weighted towards plants. This is also a reasonable approach to take; at this point, the decision is up to the priorities of the user.

In the following example, we will mix the ΔH Kc from A. variabilis with the median diatom values, and add the ΔH Ko value in.

form1D_df<-search_DHScale("1D")
#> Matched form in abridged table
form1D_merged<-merge_entries(form1D_df,"identifier",form1D_df$identifier,"median",new_id="1D_merged")
form1D_merged[9,]
#>   identifier genus species subspecies  kcat_dH Kc_dH Ko_dH  S_dH form taxonomy
#> 9  1D_merged  <NA>    <NA>     Tokara 55.87345    NA    NA -24.2   1D     <NA>
#>   group note short_ref
#> 9 Algae <NA>      <NA>
Rbc_form1D<-DHScale("1D_merged",data=form1D_merged)
#print to show it's missing values
Rbc_form1D
#> ΔH scaling "1D_merged":
#>   ΔH_kcat = 55.87345 kJ/mol
#>   ΔH_Kc = NA kJ/mol
#>   ΔH_Ko = NA kJ/mol
#>   ΔH_S = -24.2 kJ/mol
search_DHScale("Anabaena")
#> Matched genus in abridged table
#>                  identifier    genus    species subspecies kcat_dH Kc_dH Ko_dH
#> 1 variabilis_galmés_2015_dH Anabaena variabilis       <NA>    57.3    NA    NA
#> 2 variabilis_galmés_2016_dH Anabaena variabilis         M3      NA  38.8    NA
#>   S_dH form      taxonomy    group             note   short_ref
#> 1   NA  1Bc Cyanobacteria Bacteria From Badger 1980 Galmés 2015
#> 2   NA  1Bc Cyanobacteria Bacteria From Badger 1980 Galmés 2016
Rbc_form1D<-modify_DHScale(Rbc_form1D,Kc_dH=38.8,Ko_dH=26.7)
Rbc_form1D
#> ΔH scaling "1D_merged":
#>   ΔH_kcat = 55.87345 kJ/mol
#>   ΔH_Kc = 38.8 kJ/mol
#>   ΔH_Ko = 26.7 kJ/mol
#>   ΔH_S = -24.2 kJ/mol

This same process was how we created the average form 1D DHScale entry available for use. Forms 1A, 2, and 3 are also missing measurements of at least one of the ΔH values. To see a thorough description of how we constructed all of the average enzymes, see Section 5.

3.4.2 None of the temperature dependences have been measured for my form of Rubisco

Of the forms currently included in the package, there are no temperature dependence measurements for form 1C, form 1E, form 1 Anaero, form 1’, form 1’’, form 1ɑ, and form 2_3. In this case, we recommend using the median value of all known temperature dependence measurements, included in the package as the “Average Rubisco” entry of the average temperature dependence table.

4. Adding an appropriate PGS pathway

The PGS pathway is an important component of this package, and is necessary for calculating the loss of CO2 caused by Rubisco’s oxygenation reaction. We have included four different stoichiometries for PGS pathways in the package:

PGS Pathway Stoichiometry Organisms
gross No RO For calculations
canon 2 RO:1 CO2 lost plants, algae, cyanobacteria, some bacteria
diatom 1 RO:1 CO2 lost diatoms (only under high stress)
alt 1 RO:2 CO2 lost cyanobacteria, bacteria (usually as a last resort), archaea (export from cell)

Usually we recommend using "canon", as both the glycerate and the C2 cycle use this stoichiometry, and one of those two pathways is usually the PGS pathway of choice in plants, algae, cyanobacteria, and bacteria. The "diatom" stoichiometry is probably used only under high stress in diatoms. The pathways that use the "alt" stoichiometry are usually supplemental pathways for the organism, but if you want to look at e.g. the effect of exporting the oxygenation product (2-phosphoglycolate) from the cell, this is a good choice. "alt" is also the right choice for archaea, since archaea only export 2-phospholycolate out of the cell. "gross" assumes that the oxygenation reaction does not occur, so O2 acts as a competitive inhibitor of the carboxylation reaction but there is no additional penalty for fixing oxygen. This may be useful for some model scenarios.

There is a PGS pathway noted as a recommendation for many of the kinetics entries, which would automatically be imported when you call that entry with Enzyme(). If there is no recommendation, if you merged entries and ended up with a PGS pathway that is not appropriate, or if you wish to model the impact of a different PGS pathway, you can always modify the PGS pathway afterwards with modify_enzyme().

Here is an example, using our Thiomicrorhabdus arctica 1Aq enzyme we created in 2.5.

ta_1Aq
#> Enzyme "Ta_merged":
#>   kcat = 1.3752 s⁻¹ @ T_kcat = 30°C
#>   K_c = 32.5 μM @ T_c = 25°C
#>   K_o = 290 μM @ T_o = 25°C
#>   S = 26.6 @ T_S = 30°C
#>   Upper thermal limit = 55°C
#>   PGS = NA
modify_enzyme(ta_1Aq,PGS="canon")
#> Enzyme "Ta_merged":
#>   kcat = 1.3752 s⁻¹ @ T_kcat = 30°C
#>   K_c = 32.5 μM @ T_c = 25°C
#>   K_o = 290 μM @ T_o = 25°C
#>   S = 26.6 @ T_S = 30°C
#>   Upper thermal limit = 55°C
#>   PGS = "canon"

If the PGS pathway is not defined earlier, you can also set it in CO2_dependence() when you combine the Enzyme object and the DHScale object:

#define a DHScale first
avg_1A<-DHScale(search_DHScale("1A",data="averaged")[1,1])
#> Matched species in averaged table
#set PGS pathway to get CO2_dependence() to work
Rbc_ta<-CO2_dependence(ta_1Aq,avg_1A,PGS="canon")
Rbc_ta(100,200,5)
#> [1] 0.1998745

5. How we constructed the averages and composites

This section contains a list of all the averages and composites we have included in the package, along with the source of the data and the reasoning behind our choices.

5.1 Composite kinetics entries for model enzymes

In Iñiguez et al. 2021, methodology-corrected average kinetics for many of the model Rubisco enzymes were calculated. Most of the time, these contained a value for all four kinetic parameters, but for a few model Rubisco enzymes, one of the kinetic parameters was not calculated. We filled in the missing values with medians of available studies of those parameters in those species:

  1. composite Allochromatium vinosum: kcat,C from Iñiguez et al. 2021; Kc, Ko, SC/O medians of collected A. vinosum studies at 25°C
  2. composite Arabidopsis thaliana: kcat,C from Iñiguez et al. 2021; Kc average of Galmés et al. 2014 and Oh et al. 2024; Ko from Galmés et al. 2014; SC/O from Oh et al. 2024
  3. composite Glycine max: kcat,C, Kc, Ko from Iñiguez et al. 2021; SC/O median of collected G. max studies at 25°C
  4. composite Helianthus annuus: kcat,C from Iñiguez et al. 2021; Kc from Makino et al. 1985; Ko from median value of C3 plants measured at 25°C (calculated by this package); SC/O median of collected H. annuus studies at 25°C
  5. composite Oryza sativa: kcat,C, Kc, Ko from Iñiguez et al. 2021; SC/O median of collected O. sativa studies at 25°C
  6. composite Phaseolus vulgaris: kcat,C from Iñiguez et al. 2021; Kc, Ko, SC/O median of collected P. vulgaris studies at 25°C (currently Hermida-Carrera et al. 2016 & Orr 2016)

5.2 Average kinetics for Rubisco forms and taxonomic groups

We have also provided an average for many of the combinations of Rubisco forms and kinetics available in the database so far, including an “all Rubisco” average for those forms that had too few measurements to form a useful average. These averages were largely calculated as the median value of all non-metagenome-derived and non-mutant measurements matching that category taken at 25°C, with some exceptions. For a longer description of each average’s specific construction, we present the list of all average kinetics we constructed. As we will be referring to non-metagenome-derived and non-mutant sequences frequently, we shorten that to “NMM”.

  1. Average 1Ac (Cyanobacteria): kcat,C, Kc, Ko, SC/O medians of all collected Cyanobacteria NMM measurements at 25°C
  2. Average 1Ac (Proteobacteria): kcat,C median of all collected Proteobacteria NMM sequences at 30°C; Kc median of all collected Proteobacteria NMM measurements at 25°C; Ko median of all collected 1Ac Cyanobacteria NMM measurements at 25°C (no Proteobacteria measurements); SC/O the Hydrogenovibrio marinus value measured at 30°C
  3. Average 1Aq: kcat,C, Kc, Ko, SC/O medians of collected NMM form 1Aq measurements at 25°C
  4. Average 1B (C3 plants): kcat,C, Kc, Ko, SC/O medians of collected NMM C3 plant measurements at 25°C
  5. Average 1B (C4 plants): kcat,C, Kc, Ko, SC/O medians of collected NMM C4 plant measurements at 25°C
  6. Average 1B (C3-C4 plants): kcat,C, Kc, Ko, SC/O medians of collected NMM C3-C4 plant measurements at 25°C
  7. Average 1B (CAM plants): kcat,C, Kc, Ko, SC/O medians of collected NMM CAM plant measurements at 25°C
  8. Average 1B (Bryophytes): kcat,C, Kc, Ko, SC/O medians of collected NMM bryophyte measurements at 25°C
  9. Average 1B (Aquatic plants): kcat,C, Kc, Ko, SC/O medians of collected NMM aquatic plant measurements at 25°C
  10. Average 1B (Green algae): kcat,C, Kc, Ko, SC/O medians of collected NMM green algae measurements at 25°C
  11. Average 1B: kcat,C, Kc, Ko, SC/O medians of collected NMM form 1B measurements at 25°C
  12. Average 1Bc: kcat,C, Kc, Ko, SC/O medians of collected NMM form 1Bc measurements at 25°C
  13. Average 1C: kcat,C, Kc medians of collected NMM form 1C measurements at 30°C; Ko, SC/O medians of collected NMM form 1C measurements at 25°C
  14. Average 1D (Diatoms): kcat,C, Kc, Ko, SC/O medians of collected NMM diatom measurements at 25°C
  15. Average 1D (Red algae): kcat,C, Kc, Ko, SC/O medians of collected NMM red algae measurements at 25°C
  16. Average 1D (Macroalgae): kcat,C, Kc, Ko, SC/O medians of collected NMM macroalgae measurements at 25°C
  17. Average 1D: kcat,C, Kc, Ko, SC/O medians of collected NMM form 1D measurements at 25°C
  18. Average 2 (Prokaryote): kcat,C, Kc, Ko, SC/O medians of collected NMM prokaryotic form 2 measurements (i.e., excepting the dinoflagellates) at 25°C
  19. Average Rubisco: kcat,C, Kc, Ko, SC/O medians of collected NMM measurements (excluding forms 2/3 and 3) at 25°C

5.3 Average temperature dependence scales for Rubisco forms and taxonomic groups

Finally, we have provided average temperature dependence scales for a few taxonomic group and form combinations, many of them taken from Galmés et al. 2016. For the recommended ΔH Ko value, we have stuck to the use of 26.7, the mean of the in vivo studies presented in Galmés et al. 2016, as they all measured Ko more directly and all agree in sign. We did remove the Arabidopsis thaliana measurement from that average, as it has a noticeably lower R2 value than the other 3 values.

  1. Average 1B (All plants): ΔH Ko from in vivo estimates; all others average Streptophyta presented in Galmés et al. 2016
  2. Average 1B (C3 plants, cool): ΔH Ko from in vivo estimates; all others average cool C3 Streptophyta presented in Galmés et al. 2016
  3. Average 1B (C3 plants, warm): ΔH Ko from in vivo estimates; all others average warm C3 Streptophyta presented in Galmés et al. 2016
  4. Average 1B (C4 plants): ΔH Ko from in vivo estimates; all others average C4 Streptophyta presented in Galmés et al. 2016
  5. Average 1A (Proteobacteria): ΔH kcat,C median of collected Proteobacteria measurements (excluding Thiomicrospira thyasirae, as closest relative has both form 1A and form 2, so 1991 study may not have caught the form 2); ΔH Kc median of all collected measurements; ΔH Ko from in vivo estimates; ΔH SC/O median of all form 1 measurements
  6. Average 1Ac (Cyanobacteria): Ko from in vivo estimates; all others average Cyanobacteria presented in Galmés et al. 2016*
  7. Average 1Bc: Ko from in vivo estimates; all others average Cyanobacteria presented in Galmés et al. 2016*
  8. Average 2: ΔH kcat,C median of all values; ΔH Kc median of all values; ΔH Ko from in vivo estimates; ΔH SC/O from Rhodospirillum rubrum
  9. Average Rubisco: ΔH Ko from in vivo measurements; all others medians of collected measurements (excluding the form 3 measurement)

*The scales for forms 1Ac (Cyanobacteria) and 1Bc are identical, as there are so few cyanobacterial measurements.