Working with Reports

For the use case, where you are using basico to prepare files to run later (say on a cluster environment or such). It is often useful to manipulate the report definitions we store in COPASI files. This notebook demonstrate to work with them. Lets just start by importing basico.

[1]:
from basico import *

here we simply load the brusselator example:

[2]:
load_example('brusselator');

Retrieving Report Definitions

The first function to look into is get_reports which will retrieve all report definition encoded in the file and returns its content as a data frame. You can filter by name, task or whether or not the reports is an automatically generated one. So while the following line reports there are 11 reports in the model, we can ignore them if we so choose (hence not getting a result printed at the end)

[3]:
print('there are {0} reports in the model'.format(len(get_reports())))
get_reports(ignore_automatic=True)
there are 11 reports in the model

lets look at the reports that apply to steady state tasks:

[4]:
get_reports(task=T.STEADY_STATE)
[4]:
separator precision task comment is_table header body footer
name
Steady-State \t 6 Steady-State <body xmlns="http://www.w3.org/1999/xhtml">\n ... False [] [] [CN=Root,Vector=TaskList[Steady-State]]

analoge as to when working with plots, the reports can be retrieved as dictionaries, by specifying the name of the report to retrieve. The dictionary will either include a key body with lists of elements to collect (in that case is_table will be True), or as seen below, a header, body and footer entries. Each entry in those lists can be either a display name, or common name (as not all elements can be retrieved via names).

The key thing to keep in mind, is that header entries will be collected before runing the task, body and table entries during running of the task. And footer entries, once the task is complete.

[5]:
get_report_dict('Steady-State')
[5]:
{'name': 'Steady-State',
 'separator': '\t',
 'precision': 6,
 'task': 'Steady-State',
 'comment': '<body xmlns="http://www.w3.org/1999/xhtml">\n          Automatically generated report.\n        </body>',
 'is_table': False,
 'header': [],
 'body': [],
 'footer': ['CN=Root,Vector=TaskList[Steady-State]']}

Adding Reports

lets add a new report for a custom time course in which we collect the models time, the concentration of the species X and their rate of change:

[6]:
add_report('X Time-Course', task=T.TIME_COURSE, table=['Time', '[X]', 'X.Rate']);
[7]:
get_report_dict('X Time-Course')
[7]:
{'name': 'X Time-Course',
 'separator': '\t',
 'precision': 6,
 'task': 'Time-Course',
 'comment': '',
 'is_table': True,
 'print_headers': True,
 'table': ['Time', '[X]', 'X.Rate']}

the value in print_headers indicates, whether the name of the elements will be printed in the header column.

using the table element directly, does only work for tasks that generate output during the execution of the task, as in the time course example above. Other tasks, such as steady state computation only provide results after the task has completed. In the following we add a report for the steady state concentration (and rate of X). We use the function wrap_copasi_string, to indicate that we want to have the literal string [X] in the header, rather than the initial concentration.

One other important thing to note, is that when specifying headers manually, the separators also need to be included manually. That can be done using the separator char manually, or the special String Separator=\t to indicate that it is the separator of the report. Alternatively, you can specify the boolean flagg add_sepratator=True, so that between header, footer and body entries the separator is automatically added.

[9]:
add_report('X Steady-State', task=T.STEADY_STATE,
           header=[wrap_copasi_string('[X]'), wrap_copasi_string('X.Rate')],
           footer=['[X]','X.Rate'], add_separator=True);
[10]:
get_report_dict('X Steady-State')
[10]:
{'name': 'X Steady-State',
 'separator': '\t',
 'precision': 6,
 'task': 'Steady-State',
 'comment': '',
 'is_table': False,
 'header': ['String=\\[X\\]', 'Separator=\t', 'String=X.Rate'],
 'body': [],
 'footer': ['[X]', 'Separator=\t', 'X.Rate']}

Changing values

of course all the values can be changed using the set_report_dict function, say we wanted to collect CSV information for the plot above, we would specify to use , as separator:

[11]:
set_report_dict('X Time-Course', separator=',')
[12]:
get_report_dict('X Time-Course')
[12]:
{'name': 'X Time-Course',
 'separator': ',',
 'precision': 6,
 'task': 'Time-Course',
 'comment': '',
 'is_table': True,
 'print_headers': True,
 'table': ['Time', '[X]', 'X.Rate']}

if you at any point set the header, body or footer, the table entries will be removed.

Assigning to task

In order to use a report definition, it has to be assigned to a task. COPASI will only create the report if a filename is assigned to it.

[13]:
assign_report('X Time-Course', task=T.TIME_COURSE, filename='out.txt', append=True)

Alternatively, it is also possible to assign a report directly using the set_task_settings method, so for example:

[14]:
set_task_settings(T.TIME_COURSE,
   settings = {'report':
              {'report_definition': 'X Time-Course'}})

that with get_task_settings you can query which report is assigned to a given task:

[15]:
get_task_settings(T.TIME_COURSE)['report']['report_definition']
[15]:
'X Time-Course'