Beispiel #1
0
def main(essay_configs):

  """
  Purpose: read configuration files in a essay folder and execute them
  Arguments:
  - essay_configs: configuration file or subdiretory containing multiple configuration files,
                   representing essay(s) that must be executed
  Returns: None, but each essay run creates multiple files at Essays folder:
  """

  # identifies all config files that comprises the essay (must be in dir_essay_configs directory)
  tsprint('Processing essay specs at [{0}]\n'.format(essay_configs))
  if(isdir(essay_configs)):
    configFiles = [join(essay_configs, f) for f in listdir(essay_configs) if isfile(join(essay_configs, f))]
  elif(isfile(essay_configs)):
    configFiles = [essay_configs]
  else:
    print('Command line parameter is neither a recognised file nor directory: {0}'.format(essay_configs))
    raise ValueError

  # recovers each essay configuration and runs it
  for configFile in configFiles:

    # loads the essay configuration stored in the current config file
    ud.LogBuffer = []
    tsprint('Processing essay configuration file [{0}]\n{1}'.format(configFile, setupEssayConfig(configFile)))

    # recovers attributes related to essay identification
    essayid  = getEssayParameter('ESSAY_ESSAYID')
    configid = getEssayParameter('ESSAY_CONFIGID')
    scenario = getEssayParameter('ESSAY_SCENARIO')

    # assures the essay slot (where files will be created during a run) is available
    essay_beginning_ts = stimestamp()
    slot  = join('..', 'Essays', essayid, configid, essay_beginning_ts)
    if(not exists(slot)): makedirs(slot)

    # recovers parameters related to the problem instance
    param_dataset    = getEssayParameter('PARAM_DATASET')
    param_sourcepath = [getMountedOn()] + getEssayParameter('PARAM_SOURCEPATH') + [essayid]
    param_targetpath = [getMountedOn()] + getEssayParameter('PARAM_TARGETPATH') + [essayid, 'optimise', configid]
    param_maxcores   = getEssayParameter('PARAM_MAXCORES')
    param_stocklist  = getEssayParameter('PARAM_STOCKLIST')
    param_sampling   = getEssayParameter('PARAM_SAMPLING')
    param_adjinflat  = getEssayParameter('PARAM_ADJINFLAT')
    param_prices     = getEssayParameter('PARAM_PRICES')
    param_models     = getEssayParameter('PARAM_MODELS')
    param_optimode   = getEssayParameter('PARAM_OPTIMODE')

    if('PARAM_SAMPLING' in os.environ):
      param_sampling = os.environ['PARAM_SAMPLING']
      tsprint('-- option {0} updated from {1} to {2} (environment variable setting)'.format('PARAM_SAMPLING',
                                                                                              getEssayParameter('PARAM_SAMPLING'),
                                                                                              param_sampling))

    if('PARAM_MODELS' in os.environ):
      param_models = [(os.environ['PARAM_MODELS'], None)]
      tsprint('-- option {0} updated from {1} to {2} (environment variable setting)'.format('PARAM_MODELS',
                                                                                              getEssayParameter('PARAM_MODELS'),
                                                                                              param_models))
    if('PARAM_ADJINFLAT' in os.environ):
      param_adjinflat = os.environ['PARAM_ADJINFLAT'] == 'True'
      tsprint('-- option {0} updated from {1} to {2} (environment variable setting)'.format('PARAM_ADJINFLAT',
                                                                                              getEssayParameter('PARAM_ADJINFLAT'),
                                                                                              param_adjinflat))

    if('PARAM_OPTIMODE' in os.environ):
      param_optimode = os.environ['PARAM_OPTIMODE'] == 'True'
      tsprint('-- option {0} updated from {1} to {2} (environment variable setting)'.format('PARAM_OPTIMODE',
                                                                                              getEssayParameter('PARAM_OPTIMODE'),
                                                                                              param_optimode))

    # runs the essay configuration the required number of times
    (runID, maxRuns) = (0, getEssayParameter('ESSAY_RUNS'))
    while(runID < maxRuns):

      # decreases the number of runs and changes the random seed
      runID = runID + 1
      random.seed(ECO_SEED + runID)
      run_beginning_ts = stimestamp()

      # prints the run header
      print()
      tsprint('Starting run {0} of {1} for scenario [{2}]'.format(runID, maxRuns, scenario))
      tsprint('Essay [{0}], Config [{1}], Label [{2}]'.format(essayid, configid, run_beginning_ts))
      tsprint('Files will be created in [{0}]'.format(slot))
      print()

      # ensures output directory exists abd previous results are removed
      param_targetpath.append(getFolderOptimise(param_sampling, param_models, param_adjinflat, param_optimode))
      if(exists(join(*param_targetpath))):
        for f in listdir(join(*param_targetpath)):
          remove(join(*param_targetpath, f))
      else:
        makedirs(join(*param_targetpath))

      # performs the problem-specific task
      # ------------------------------------------------------------------------------------------------------

      tsprint('Loading preprocessed data.')
      constituents = deserialise(join(*param_sourcepath, 'preprocess', 'constituents'))
      stocks       = deserialise(join(*param_sourcepath, 'preprocess', 'stocks'))
      timeline     = deserialise(join(*param_sourcepath, 'preprocess', 'timeline'))

      folder = getFolderForecast(param_sampling, param_models)
      testPoints              = deserialise(join(*param_sourcepath, 'forecast', configid, folder, 'testPoints'))
      (forecasts, failures)   = deserialise(join(*param_sourcepath, 'forecast', configid, folder, 'forecasts'))

      tsprint('-- {0} test points allocated to the sample to be employed in model evaluation.'.format(len(testPoints)))
      tsprint('   {0}'.format(', '.join([ts2datestr(timeline[timepos]) + ' ({0})'.format(timepos) for timepos in testPoints])), False)
      tsprint('-- {0} forecasts were performed (#stocks:{1}, #models:{2}, #prices:{3}, #testpoints: {4}).'.format(len(forecasts), len(param_stocklist), len(param_models), len(param_prices), len(testPoints)))
      tsprint('-- {0} forecasts failed because the raw data was unavailable or the model failed.'.format(failures))

      tsprint('Performing iterative weights optimisation.')
      weights, thresholds, limits, pairs = applyWeights(param_stocklist, param_prices, param_models, param_adjinflat, param_optimode, timeline, forecasts, testPoints)
      tsprint('-- {0} forecasts are available for model evaluation.'.format(len(list(chain(*pairs.values())))))

      # ------------------------------------------------------------------------------------------------------

      # saves main datastructures produce in this module
      serialise(weights,     join(*param_targetpath, 'weights'))
      serialise(thresholds,  join(*param_targetpath, 'thresholds'))
      serialise(limits,      join(*param_targetpath, 'limits'))
      serialise(pairs,       join(*param_targetpath, 'pairs'))

      # saving the pairs dictionary into a csv file for easier visual inspection
      content = ['{0}\t{1}\t{2}\t{3}\t{4}\t{5}\t{6}'.format('Ticker', 'Date', 'Actual', 'Predicted', 'Actual', 'Predicted', 'Result')]
      for ticker in pairs:
        for (timepos, realVal, predVal, realClass, predClass) in pairs[ticker]:
          content.append('{0}\t{1}\t{2:7.2f}\t{3:7.2f}\t{4}\t{5}\t{6}'.format(ticker, ts2datestr(timeline[timepos]), realVal, predVal, realClass, predClass, 'match' if realClass == predClass else 'miss'))
      saveAsText('\n'.join(content), join(*param_targetpath, 'pairs.csv'))

      content = 'Execution details can be found in the essay config file at {0}\n\n{1}'.format(slot, setupEssayConfig(configFile))
      saveAsText(content, join(*param_targetpath, 'config.log'))

    tsprint('Finished processing essay specs at [{0}]\n'.format(essay_configs))
    saveLog(join(slot, 'config.log'))
    saveLog(join(*param_targetpath, 'config.log'))

  print()
  tsprint('Essay completed.')
Beispiel #2
0
def main(essayid):

    tsprint('Process started.')

    # sets up the scope delimiting variables
    base_path = [
        getMountedOn(), 'Task Stage', 'Task - Trend Analysis', 'datasets',
        'sp500', essayid, 'measure'
    ]
    all_models = [('MA', None), ('ARIMA', None), ('EWMA', None), ('KNN', None),
                  ('SAX', None), ('LSTM', None)]
    all_conditions = [
        ('linear', False, False),
        ('linear', False, True),
        ('linear', True, False),
        ('linear', True, True),
        ('heuristic', False, False),
        ('heuristic', False, True),
        ('heuristic', True, False),
        ('heuristic', True, True),
        ('random', False, False),
        ('random', False, True),
        ('random', True, False),
        ('random', True, True),
    ]
    all_configs = ['C1', 'C2', 'C3']
    tsprint('-- analysing experiment results in {0}.'.format(join(*base_path)))

    # goes through the measurement results and collects accuracy metrics
    tsprint('Summarising results obtained from each model and conditions.')
    summary, content = gatherResults(all_configs, all_models, all_conditions,
                                     base_path)
    saveAsText('\n'.join(content), join(*base_path, 'summary.csv'))

    # compares results according to the set of hypothesis in the study
    tsprint('Performing comparisons for all hypotheses.')
    header = [
        'HH\tComparand\tRelation\tReference\tc1.ss\tc1.lb\tc1.ub\tc2.ss\tc2.lb\tc2.ub'
    ]
    cpH1, hl_H1 = gencpH1(all_configs, all_models, all_conditions, summary)
    cpH2, hl_H2 = gencpH2(all_configs, all_models, all_conditions, summary)
    cpH3, hl_H3 = gencpH3(all_configs, all_models, all_conditions, summary)
    cpH4, hl_H4 = gencpH4(all_configs, all_models, all_conditions, summary)
    cpH5, hl_H5 = gencpH5(all_configs, all_models, all_conditions, summary)
    content = header + cpH1 + cpH2 + cpH3 + cpH4 + cpH5
    saveAsText('\n'.join(content), join(*base_path, 'hypotheses.csv'))

    # draws the result panels
    tsprint('Plotting the results panel.')
    saveit = True
    param_targetpath = [
        getMountedOn(), 'Task Stage', 'Task - Trend Analysis', 'datasets',
        'sp500', essayid, 'measure'
    ]

    filename = 'panel_H1'
    plotH1(summary, hl_H1, all_models, (saveit, param_targetpath, filename))

    for configid in ['C1', 'C2', 'C3']:
        filename = 'panel_H2_{0}'.format(configid)
        plotH2(summary, hl_H2, all_models,
               (saveit, param_targetpath, filename), [configid])

    for configid in ['C1', 'C2', 'C3']:
        filename = 'panel_H3_{0}'.format(configid)
        plotH3(summary, hl_H3, all_models,
               (saveit, param_targetpath, filename), [configid])

    for configid in ['C1', 'C2', 'C3']:
        filename = 'panel_H4_{0}'.format(configid)
        plotH4(summary, hl_H4, all_models,
               (saveit, param_targetpath, filename), [configid])

    # creates a text file with the table contents and the panels for Figures 1 and 2
    tsprint('Process completed.')
Beispiel #3
0
def main(essay_configs):
    """
  Purpose: read configuration files in a essay folder and execute them
  Arguments:
  - essay_configs: configuration file or subdiretory containing multiple configuration files,
                   representing essay(s) that must be executed
  Returns: None, but each essay run creates multiple files at Essays folder:
  """

    # identifies all config files that comprises the essay (must be in dir_essay_configs directory)
    tsprint('Processing essay specs at [{0}]\n'.format(essay_configs))
    if (isdir(essay_configs)):
        configFiles = [
            join(essay_configs, f) for f in listdir(essay_configs)
            if isfile(join(essay_configs, f))
        ]
    elif (isfile(essay_configs)):
        configFiles = [essay_configs]
    else:
        print(
            'Command line parameter is neither a recognised file nor directory: {0}'
            .format(essay_configs))
        raise ValueError

    # recovers each essay configuration and runs it
    for configFile in configFiles:

        # loads the essay configuration stored in the current config file
        ud.LogBuffer = []
        tsprint('Processing essay configuration file [{0}]\n{1}'.format(
            configFile, setupEssayConfig(configFile)))

        # recovers attributes related to essay identification
        essayid = getEssayParameter('ESSAY_ESSAYID')
        configid = getEssayParameter('ESSAY_CONFIGID')
        scenario = getEssayParameter('ESSAY_SCENARIO')

        # assures the essay slot (where files will be created during a run) is available
        essay_beginning_ts = stimestamp()
        slot = join('..', 'Essays', essayid, configid, essay_beginning_ts)
        if (not exists(slot)): makedirs(slot)

        # recovers parameters related to the problem instance
        param_dataset = getEssayParameter('PARAM_DATASET')
        param_sourcepath = [getMountedOn()
                            ] + getEssayParameter('PARAM_SOURCEPATH')
        param_targetpath = [
            getMountedOn()
        ] + getEssayParameter('PARAM_TARGETPATH') + [essayid, 'preprocess']
        param_consttfile = getEssayParameter('PARAM_CONSTTFILE')
        param_stocksfile = getEssayParameter('PARAM_STOCKSFILE')
        param_encoding = getEssayParameter('PARAM_ENCODING')
        param_maxcores = getEssayParameter('PARAM_MAXCORES')
        param_loadprices = getEssayParameter('PARAM_LOADPRICES')

        # runs the essay configuration the required number of times
        (runID, maxRuns) = (0, getEssayParameter('ESSAY_RUNS'))
        while (runID < maxRuns):

            # decreases the number of runs and changes the random seed
            runID = runID + 1
            random.seed(ECO_SEED + runID)
            run_beginning_ts = stimestamp()

            # prints the run header
            print()
            tsprint('Starting run {0} of {1} for scenario [{2}]'.format(
                runID, maxRuns, scenario))
            tsprint('Essay [{0}], Config [{1}], Label [{2}]'.format(
                essayid, configid, run_beginning_ts))
            tsprint('Files will be created in [{0}]'.format(slot))
            print()

            # performs the problem-specific task
            # ------------------------------------------------------------------------------------------------------

            tsprint('Loading constituents file.')
            constituents = loadConstituents(param_sourcepath, param_consttfile,
                                            param_encoding)

            tsprint('Loading from the {0} dataset the following series: {1}.'.
                    format(param_dataset, ', '.join(param_loadprices)))
            stocks = loadStocks(param_sourcepath, param_stocksfile,
                                param_encoding, param_loadprices)

            tsprint(
                'Building the master timeline and updating the constituents time ranges'
            )
            timeline, newConstituents = buildTimeline(stocks, constituents)

            # ------------------------------------------------------------------------------------------------------

            # saves the data generated during each run
            tsprint('-- saving preprocessed data.')

            if (exists(join(*param_targetpath))):
                for f in listdir(join(*param_targetpath)):
                    remove(join(*param_targetpath, f))
            else:
                makedirs(join(*param_targetpath))

            serialise(newConstituents, join(*param_targetpath, 'constituents'))
            serialise(stocks, join(*param_targetpath, 'stocks'))
            serialise(timeline, join(*param_targetpath, 'timeline'))

            content = 'Execution details can be found in the essay config file at {0}\n\n{1}'.format(
                slot, setupEssayConfig(configFile))
            saveAsText(content, join(*param_targetpath, 'config.log'))

        tsprint(
            'Finished processing essay specs at [{0}]\n'.format(essay_configs))
        saveLog(join(slot, 'config.log'))
        saveLog(join(*param_targetpath, 'config.log'))

    print()
    tsprint('Essay completed.')
Beispiel #4
0
def main(essay_configs):

  """
  Purpose: read configuration files in a essay folder and execute them
  Arguments:
  - essay_configs: configuration file or subdiretory containing multiple configuration files,
                   representing essay(s) that must be executed
  Returns: None, but each essay run creates multiple files at Essays folder:
  """

  # identifies all config files that comprises the essay (must be in dir_essay_configs directory)
  tsprint('Processing essay specs at [{0}]\n'.format(essay_configs))
  if(isdir(essay_configs)):
    configFiles = [join(essay_configs, f) for f in listdir(essay_configs) if isfile(join(essay_configs, f))]
  elif(isfile(essay_configs)):
    configFiles = [essay_configs]
  else:
    print('Command line parameter is neither a recognised file nor directory: {0}'.format(essay_configs))
    raise ValueError

  # recovers each essay configuration and runs it
  for configFile in configFiles:

    # loads the essay configuration stored in the current config file
    ud.LogBuffer = []
    tsprint('Processing essay configuration file [{0}]\n{1}'.format(configFile, setupEssayConfig(configFile)))

    # recovers attributes related to essay identification
    essayid  = getEssayParameter('ESSAY_ESSAYID')
    configid = getEssayParameter('ESSAY_CONFIGID')
    scenario = getEssayParameter('ESSAY_SCENARIO')

    # assures the essay slot (where files will be created during a run) is available
    essay_beginning_ts = stimestamp()
    slot  = join('..', 'Essays', essayid, configid, essay_beginning_ts)
    if(not exists(slot)): makedirs(slot)

    # recovers parameters related to the problem instance
    param_dataset    = getEssayParameter('PARAM_DATASET')
    param_sourcepath = [getMountedOn()] + getEssayParameter('PARAM_SOURCEPATH') + [essayid]
    param_targetpath = [getMountedOn()] + getEssayParameter('PARAM_TARGETPATH') + [essayid, 'measure', configid]
    param_sampling   = getEssayParameter('PARAM_SAMPLING')
    param_adjinflat  = getEssayParameter('PARAM_ADJINFLAT')
    param_models     = getEssayParameter('PARAM_MODELS')
    param_optimode   = getEssayParameter('PARAM_OPTIMODE')
    param_saveimages = getEssayParameter('PARAM_SAVEIMAGES')

    if('PARAM_SAMPLING' in os.environ):
      param_sampling = os.environ['PARAM_SAMPLING']
      tsprint('-- option {0} updated from {1} to {2} (environment variable setting)'.format('PARAM_SAMPLING',
                                                                                              getEssayParameter('PARAM_SAMPLING'),
                                                                                              param_sampling))

    if('PARAM_MODELS' in os.environ):
      param_models = [(os.environ['PARAM_MODELS'], None)]
      tsprint('-- option {0} updated from {1} to {2} (environment variable setting)'.format('PARAM_MODELS',
                                                                                              getEssayParameter('PARAM_MODELS'),
                                                                                              param_models))
    if('PARAM_ADJINFLAT' in os.environ):
      param_adjinflat = os.environ['PARAM_ADJINFLAT'] == 'True'
      tsprint('-- option {0} updated from {1} to {2} (environment variable setting)'.format('PARAM_ADJINFLAT',
                                                                                              getEssayParameter('PARAM_ADJINFLAT'),
                                                                                              param_adjinflat))

    if('PARAM_OPTIMODE' in os.environ):
      param_optimode = os.environ['PARAM_OPTIMODE'] == 'True'
      tsprint('-- option {0} updated from {1} to {2} (environment variable setting)'.format('PARAM_OPTIMODE',
                                                                                              getEssayParameter('PARAM_OPTIMODE'),
                                                                                              param_optimode))


    # runs the essay configuration the required number of times
    (runID, maxRuns) = (0, getEssayParameter('ESSAY_RUNS'))
    while(runID < maxRuns):

      # decreases the number of runs and changes the random seed
      runID = runID + 1
      random.seed(ECO_SEED + runID)
      run_beginning_ts = stimestamp()

      # prints the run header
      print()
      tsprint('Starting run {0} of {1} for scenario [{2}]'.format(runID, maxRuns, scenario))
      tsprint('Essay [{0}], Config [{1}], Label [{2}]'.format(essayid, configid, run_beginning_ts))
      tsprint('Files will be created in [{0}]'.format(slot))
      print()

      # assures the target path (where results will be saved) is available
      param_targetpath.append(getFolderOptimise(param_sampling, param_models, param_adjinflat, param_optimode))
      if(exists(join(*param_targetpath))):
        for f in listdir(join(*param_targetpath)):
          remove(join(*param_targetpath, f))
      else:
        makedirs(join(*param_targetpath))

      # performs the problem-specific task
      # ------------------------------------------------------------------------------------------------------

      tsprint('Loading preprocessed data.')
      folder = getFolderOptimise(param_sampling, param_models, param_adjinflat, param_optimode)
      pairs = deserialise(join(*param_sourcepath, 'optimise', configid, folder, 'pairs'))
      tsprint('-- {0} predictions are available for model evaluation.'.format(len(list(chain(*pairs.values())))))

      tsprint('Computing ensemble accuracy.')
      results, all_true, all_pred = computeMetrics(pairs)
      res = results[ECO_TICKER_ENSEMBLE]
      tsprint('-- ensemble metrics: sample size: {0}, accuracy: {1:5.3f}, error: {2:5.3f}'.format(res.ss, res.accuracy, res.smape))

      tsprint('Plotting the confusion matrix and ROC curve for the ensemble.')
      plotDesc = getPlotDesc(configid, param_sampling, param_models, param_adjinflat, param_optimode)
      flag = plot_confusion_matrix(all_true, all_pred,
                            '{0}'.format(plotDesc),
                            param_saveimages, param_targetpath, 'cm_{0}_{1}'.format(configid, folder))

      if(flag):
        plot_ROC_curve(all_true, all_pred,
                              '{0}'.format(plotDesc),
                              param_saveimages, param_targetpath, 'roc_{0}_{1}'.format(configid, folder))
      else:
        tsprint('-- ROC curve was not produced because confusion matrix misses at least one class.')

      # ------------------------------------------------------------------------------------------------------

      # saves the data produced during the run
      serialise(results, join(*param_targetpath, 'results'))

      # saving the results dictionary into a csv file for easier visual inspection
      content = ['{0}\t{1}\t{2}\t{3}'.format('Ticker', 'Sample Size', 'Accuracy', 'SMAPE')]
      for ticker in results:
        content.append('{0}\t{1}\t{2:4.3f}\t{3:4.3f}'.format(ticker, results[ticker].ss, results[ticker].accuracy, results[ticker].smape))
      saveAsText('\n'.join(content), join(*param_targetpath, 'results.csv'))

      content = 'Execution details can be found in the essay config file at {0}\n\n{1}'.format(slot, setupEssayConfig(configFile))
      saveAsText(content, join(*param_targetpath, 'config.log'))

    tsprint('Finished processing essay specs at [{0}]\n'.format(essay_configs))
    saveLog(join(slot, 'config.log'))
    saveLog(join(*param_targetpath, 'config.log'))

  print()
  tsprint('Essay completed.')
Beispiel #5
0
def main(essayid):

    tsprint('Process started.')

    # sets up the scope delimiting variables
    base_path = [
        getMountedOn(), 'Task Stage', 'Task - Trend Analysis', 'datasets',
        'sp500', essayid, 'measure'
    ]
    all_models = [('MA', None), ('EWMA', None), ('ARIMA', None), ('KNN', None),
                  ('SAX', None), ('LSTM', None)]
    all_conditions = [
        ('linear', False, False),
        ('linear', False, True),
        ('linear', True, False),
        ('linear', True, True),
        ('heuristic', False, False),
        ('heuristic', False, True),
        ('heuristic', True, False),
        ('heuristic', True, True),
        ('random', False, False),
        ('random', False, True),
        ('random', True, False),
        ('random', True, True),
    ]
    all_configs = ['C1', 'C2', 'C3']
    tsprint('-- analysing experiment results in {0}.'.format(join(*base_path)))

    # goes through the measurement results and collects accuracy metrics for the ensemble
    tsprint(
        'Rendering details for Table A - Accuracy results obtained from the ensemble.'
    )
    tableA = [
        '*** Insert this snippet in the TEX document, after the "%--- Table A, snippet from gentex.py -- START" remark'
    ]
    tableA.append('% data obtained from python gentex.py {0}'.format(essayid))
    performance = {}
    state = 0
    for (param_sampling, param_adjinflat, param_optimode) in all_conditions:
        condition = param_sampling[0].upper() + (
            'A' if param_adjinflat else 'U') + ('O' if param_optimode else 'N')
        for configid in all_configs:
            path = base_path + [
                configid,
                getFolderOptimise(param_sampling, all_models, param_adjinflat,
                                  param_optimode)
            ]

            # recover experiment results for specific model, condition and config
            if (exists(join(*path, 'results.pkl'))):
                results = deserialise(join(*path, 'results'))
                # collect mean accuracy and bootstraped confidence interval
                vm = results[ECO_TICKER_ENSEMBLE].accuracy
                vl = results[ECO_TICKER_ENSEMBLE].accuracy_lb
                vh = results[ECO_TICKER_ENSEMBLE].accuracy_ub
            else:
                vm = -1
                vl = -1
                vh = -1

            # missing entries will be represented by a dash
            performance[(ECO_TICKER_ENSEMBLE, param_sampling, param_adjinflat,
                         param_optimode, configid)] = (vm, vl, vh)
            if (state == 0):
                newrow = [ECO_TICKER_ENSEMBLE, condition, fmtaccci(vl, vh)]
            elif (state == 3):
                newrow += [condition, fmtaccci(vl, vh)]
            else:
                newrow.append(fmtaccci(vl, vh))
            state += 1

        # creates a new row in the table
        if (state % 6 == 0):
            tableA.append(
                'proposed&{0}&{1}&{2}&{3}&{4}&{5}&{6}&{7}&{8}\\\\'.format(
                    *newrow))
            tableA.append('\\midrule')
            state = 0
    tableA.append('')

    # goes through the measurement results of each model and collect accuracy metrics
    tsprint(
        'Rendering details for Table B - Accuracy results obtained from individual models.'
    )
    tableB = [
        '*** Insert this snippet in the TEX document, after the "%--- Table B, snippet from gentex.py -- START" remark'
    ]
    tableB.append('% data obtained from python gentex.py {0}'.format(essayid))
    performance = {}
    for (param_model, _) in all_models:
        state = 0
        for (param_sampling, param_adjinflat,
             param_optimode) in all_conditions:
            condition = param_sampling[0].upper() + (
                'A' if param_adjinflat else 'U') + ('O'
                                                    if param_optimode else 'N')
            for configid in all_configs:
                path = base_path + [
                    configid,
                    getFolderOptimise(param_sampling, [(param_model, _)],
                                      param_adjinflat, param_optimode)
                ]

                # recover experiment results for specific model, condition and config
                if (exists(join(*path, 'results.pkl'))):
                    results = deserialise(join(*path, 'results'))
                    # collect mean accuracy and bootstraped confidence interval
                    vm = results[ECO_TICKER_ENSEMBLE].accuracy
                    vl = results[ECO_TICKER_ENSEMBLE].accuracy_lb
                    vh = results[ECO_TICKER_ENSEMBLE].accuracy_ub
                else:
                    vm = -1
                    vl = -1
                    vh = -1

                # missing entries will be represented by a dash
                performance[(param_model, param_sampling, param_adjinflat,
                             param_optimode, configid)] = (vl, vh)
                if (state == 0):
                    newrow = [param_model, condition, fmtaccci(vl, vh)]
                elif (state == 3):
                    newrow += [condition, fmtaccci(vl, vh)]
                else:
                    newrow.append(fmtaccci(vl, vh))
                state += 1

            # creates a new row in the table
            if (state % 6 == 0):
                tableB.append(
                    'proposed&{0}&{1}&{2}&{3}&{4}&{5}&{6}&{7}&{8}\\\\'.format(
                        *newrow))
                tableB.append('\\midrule')
                state = 0
    tableB.append('')

    # Figure A1 - different models produce different errors under different conditions?
    # it consists of three panels, one for each config
    # each panel is a 2x3 grid with confusion matrices for each individual model
    # only for the LON condition: linear sampling, original prices, non-optimised weights
    tsprint('Rendering the panels for Figure A1.')
    figureA1 = [
        '*** Insert snippet in the TEX document, after the "%--- Figure A1, snippet from gentex.py -- START" remark'
    ]
    figureA1.append(
        '% data obtained from python gentex.py {0}'.format(essayid))
    (param_sampling, param_adjinflat, param_optimode) = ('linear', False,
                                                         False)
    for configid in all_configs:
        figureA1.append('%--- Panel for Group {0}'.format(configid))
        for i in range(len(all_models)):
            (param_model, _) = all_models[i]
            path = base_path + [
                configid,
                getFolderOptimise(param_sampling, [(param_model, None)],
                                  param_adjinflat, param_optimode)
            ]
            config_desc = getFolderOptimise(param_sampling,
                                            [(param_model, None)],
                                            param_adjinflat, param_optimode)
            filename = 'cm_{0}_{1}'.format(configid, config_desc)
            if (not exists(join(*path, filename + '.png'))):
                filename = 'placeholder'
            figureA1.append('% new row' if (i % 3 == 0) else '\\hfill')
            figureA1.append('\\begin{subfigure}[t]{0.32\\textwidth}')
            figureA1.append(
                '  \\includegraphics[width=\\textwidth]{{images/{0}}}'.format(
                    filename))
            figureA1.append(
                '  \\caption{{\\scriptsize {0}}}'.format(param_model))
            figureA1.append('  \\label{{fig:{0}}}'.format(filename))
            figureA1.append('\\end{subfigure}')
        figureA1.append('')

    # Figure A2 - the ensemble produces different errors under different conditions?
    # it consists of three panels, one for each config
    # each panel is a 2x3 grid with confusion matrices for each individual model
    # only for the LON condition: linear sampling, original prices, non-optimised weights
    tsprint('Rendering the panels for Figure A2.')
    figureA2 = []

    # Figure B1 - ?
    figureB1 = []

    # Figure B2 - ?
    figureB2 = []

    # creates a text file with the table contents and the panels for Figures 1 and 2
    saveAsText(
        '\n'.join(tableA + tableB + figureA1 + figureA2 + figureB1 + figureB2),
        join(*base_path, 'measure_summary.tex'))
    tsprint('Process completed.')