docs: def main():
      """
      Entry point, calling :py:func:`pastml.acr.pastml_pipeline` with command-line arguments.
  
      :return: void
      """
      import argparse
  
      parser = argparse.ArgumentParser(description="Ancestral character reconstruction and visualisation "
                                                   "for rooted phylogenetic trees.", prog='pastml')
  
      tree_group = parser.add_argument_group('tree-related arguments')
      tree_group.add_argument('-t', '--tree', help="input tree in newick format (must be rooted).",
                              type=str, required=True)
  
      annotation_group = parser.add_argument_group('annotation-file-related arguments')
      annotation_group.add_argument('-d', '--data', required=True, type=str,
                                    help="annotation file in tab/csv format with the first row "
                                         "containing the column names.")
      annotation_group.add_argument('-s', '--data_sep', required=False, type=str, default='\t',
                                    help="column separator for the annotation table. "
                                         "By default is set to tab, i.e. for a tab-delimited file. "
                                         "Set it to ',' if your file is csv.")
      annotation_group.add_argument('-i', '--id_index', required=False, type=int, default=0,
                                    help="index of the annotation table column containing tree tip names, "
                                         "indices start from zero (by default is set to 0).")
  
      acr_group = parser.add_argument_group('ancestral-character-reconstruction-related arguments')
      acr_group.add_argument('-c', '--columns', nargs='*',
                             help="names of the annotation table columns that contain characters "
                                  "to be analysed. "
                                  "If not specified, all columns are considered.",
                             type=str)
      acr_group.add_argument('--prediction_method',
                             choices=[MPPA, MAP, JOINT, DOWNPASS, ACCTRAN, DELTRAN, COPY, ALL, ML, MP],
                             type=str, nargs='*', default=MPPA,
                             help='ancestral character reconstruction (ACR) method, '
                                  'can be one of the max likelihood (ML) methods: {ml}, '
                                  'one of the max parsimony (MP) methods: {mp}; '
                                  'or {copy} to keep the annotated character states as-is without inference. '
                                  'One can also specify one of the meta-methods {meta} that would perform ACR '
                                  'with multiple methods (all of them for {meta_all}, '
                                  'all the ML methods for {meta_ml}, or all the MP methods for {meta_mp}) '
                                  'and save/visualise the results as multiple characters '
                                  'suffixed with the corresponding method.'
                                  'When multiple ancestral characters are specified (see -c, --columns), '
                                  'the same method can be used for all of them (if only one method is specified), '
                                  'or different methods can be used (specified in the same order as -c, --columns). '
                                  'If multiple methods are given, but not for all the characters, '
                                  'for the rest of them the default method ({default}) is chosen.'
                             .format(ml=', '.join(ML_METHODS), mp=', '.join(MP_METHODS), copy=COPY, default=MPPA,
                                     meta=', '.join(META_ML_METHODS | {MP}), meta_ml=ML, meta_mp=MP, meta_all=ALL))
      acr_group.add_argument('--forced_joint', action='store_true',
                             help='add {joint} state to the {mppa} state selection '
                                  'even if it is not selected by Brier score.'.format(joint=JOINT, mppa=MPPA))
      acr_group.add_argument('-m', '--model', default=F81,
                             choices=[JC, F81, EFT, HKY, JTT],
                             type=str, nargs='*',
                             help='evolutionary model for ML methods (ignored by MP methods). '
                                  'When multiple ancestral characters are specified (see -c, --columns), '
                                  'the same model can be used for all of them (if only one model is specified), '
                                  'or different models can be used (specified in the same order as -c, --columns). '
                                  'If multiple models are given, but not for all the characters, '
                                  'for the rest of them the default model ({}) is chosen.'.format(F81))
      acr_group.add_argument('--parameters', type=str, nargs='*',
                             help='optional way to fix some of the ML-method parameters '
                                  'by specifying files that contain them. '
                                  'Should be in the same order '
                                  'as the ancestral characters (see -c, --columns) '
                                  'for which the reconstruction is to be preformed. '
                                  'Could be given only for the first few characters. '
                                  'Each file should be tab-delimited, with two columns: '
                                  'the first one containing parameter names, '
                                  'and the second, named "value", containing parameter values. '
                                  'Parameters can include character state frequencies '
                                  '(parameter name should be the corresponding state, '
                                  'and parameter value - the float frequency value, between 0 and 1),'
                                  'and tree branch scaling factor (parameter name {}).'.format(SCALING_FACTOR))
  
      vis_group = parser.add_argument_group('visualisation-related arguments')
      vis_group.add_argument('-n', '--name_column', type=str, default=None,
                             help="name of the character to be used for node names "
                                  "in the compressed map visualisation "
                                  "(must be one of those specified via -c, --columns). "
                                  "If the annotation table contains only one column it will be used by default.")
      vis_group.add_argument('--date_column', required=False, default=None,
                             help="name of the annotation table column that contains tip dates, "
                                  "if specified it is used to add a time slider to the visualisation.",
                             type=str)
      vis_group.add_argument('--tip_size_threshold', type=int, default=REASONABLE_NUMBER_OF_TIPS,
                             help="recursively remove the tips of size less than threshold-th largest tip"
                                  "from the compressed map (set to 1e10 to keep all tips). "
                                  "The larger it is the less tips will be trimmed.")
  
      out_group = parser.add_argument_group('output-related arguments')
      out_group.add_argument('-o', '--out_data', required=False, type=str,
                             help="path to the output annotation file with the reconstructed ancestral character states.")
      out_group.add_argument('--work_dir', required=False, default=None, type=str,
                             help="path to the folder where pastml parameter, named tree "
                                  "and marginal probability (for marginal ML methods ({}) only) files are to be stored. "
                                  "Default is <path_to_input_file>/<input_file_name>_pastml. "
                                  "If the folder does not exist, it will be created."
                             .format(', '.join(MARGINAL_ML_METHODS)))
      out_group.add_argument('-p', '--html_compressed', required=False, default=None, type=str,
                             help="path to the output compressed map visualisation file (html).")
      out_group.add_argument('-l', '--html', required=False, default=None, type=str,
                             help="path to the output full tree visualisation file (html).")
      out_group.add_argument('-v', '--verbose', action='store_true',
                             help="print information on the progress of the analysis (to console)")
  
      parser.add_argument('--version', action='version', version='%(prog)s {version}'.format(version=PASTML_VERSION))
  
      itol_group = parser.add_argument_group('iTOL-related arguments')
      itol_group.add_argument('--upload_to_itol', action='store_true',
                              help="upload the ACR annotated tree to iTOL (https://itol.embl.de/)")
      itol_group.add_argument('--itol_id', required=False, default=None, type=str,
                              help="iTOL user batch upload ID that enables uploading to your iTOL account "
                                   "(see https://itol.embl.de/help.cgi#batch). "
                                   "If not specified, the tree will not be associated to any account.")
      itol_group.add_argument('--itol_project', required=False, default=None, type=str,
                              help="iTOL project the annotated tree should be associated with "
                                   "(must exist, and --itol_id must be specified). "
                                   "If not specified, the tree will not be associated with any project.")
      itol_group.add_argument('--itol_tree_name', required=False, default=None, type=str,
                              help="name for the tree uploaded to iTOL.")
  
      params = parser.parse_args()
  
      pastml_pipeline(**vars(params))