nodes: 0, module; 1, function_definition; 2, function_name:get_input; 3, parameters; 4, block; 5, identifier:source; 6, identifier:files; 7, default_parameter; 8, default_parameter; 9, default_parameter; 10, default_parameter; 11, default_parameter; 12, expression_statement; 13, expression_statement; 14, expression_statement; 15, expression_statement; 16, with_statement; 17, if_statement; 18, expression_statement; 19, expression_statement; 20, if_statement; 21, identifier:threads; 22, integer:4; 23, identifier:readtype; 24, string:"1D"; 25, identifier:combine; 26, string:"simple"; 27, identifier:names; 28, None; 29, identifier:barcoded; 30, False; 31, comment:"""Get input and process accordingly.
  
      Data can be:
      - a uncompressed, bgzip, bzip2 or gzip compressed fastq file
      - a uncompressed, bgzip, bzip2 or gzip compressed fasta file
      - a rich fastq containing additional key=value information in the description,
        as produced by MinKNOW and albacore with the same compression options as above
      - a sorted bam file
      - a sorted cram file
      - a (compressed) sequencing_summary.txt file generated by albacore
  
      Handle is passed to the proper functions to get DataFrame with metrics
      Multiple files of the same type can be used to extract info from, which is done in parallel
      Arguments:
      - source: defines the input data type and the function that needs to be called
      - files: is a list of one or more files to operate on, from the type of <source>
      - threads: is the amount of workers which can be used
      - readtype: (only relevant for summary input) and specifies which columns have to be extracted
      - combine: is either 'simple' or 'track', with the difference that  with 'track' an additional
        field is created with the name of the dataset
      - names: if combine="track", the names to be used for the datasets. Needs to have same length as
        files, or None
      """; 32, assignment; 33, assignment; 34, assignment; 35, with_clause; 36, block; 37, boolean_operator; 38, block; 39, assignment; 40, call; 41, comparison_operator:len(datadf) == 0; 42, block; 43, else_clause; 44, identifier:proc_functions; 45, dictionary; 46, identifier:filethreads; 47, call; 48, identifier:threadsleft; 49, binary_operator:threads - filethreads; 50, with_item; 51, expression_statement; 52, expression_statement; 53, comparison_operator:"readIDs" in datadf; 54, call; 55, expression_statement; 56, identifier:datadf; 57, call; 58, attribute; 59, argument_list; 60, call; 61, integer:0; 62, expression_statement; 63, expression_statement; 64, block; 65, pair; 66, pair; 67, pair; 68, pair; 69, pair; 70, pair; 71, pair; 72, pair; 73, identifier:min; 74, argument_list; 75, identifier:threads; 76, identifier:filethreads; 77, as_pattern; 78, assignment; 79, assignment; 80, string:"readIDs"; 81, identifier:datadf; 82, attribute; 83, argument_list; 84, call; 85, identifier:calculate_start_time; 86, argument_list; 87, identifier:logging; 88, identifier:info; 89, call; 90, identifier:len; 91, argument_list; 92, call; 93, call; 94, return_statement; 95, string; 96, attribute; 97, string; 98, attribute; 99, string; 100, attribute; 101, string; 102, attribute; 103, string; 104, attribute; 105, string; 106, attribute; 107, string; 108, attribute; 109, string; 110, attribute; 111, call; 112, identifier:threads; 113, call; 114, as_pattern_target; 115, identifier:extration_function; 116, call; 117, identifier:datadf; 118, call; 119, call; 120, identifier:any; 121, attribute; 122, argument_list; 123, identifier:datadf; 124, attribute; 125, argument_list; 126, identifier:datadf; 127, attribute; 128, argument_list; 129, attribute; 130, argument_list; 131, identifier:datadf; 132, string_content:fastq; 133, identifier:ex; 134, identifier:process_fastq_plain; 135, string_content:fasta; 136, identifier:ex; 137, identifier:process_fasta; 138, string_content:bam; 139, identifier:ex; 140, identifier:process_bam; 141, string_content:summary; 142, identifier:ex; 143, identifier:process_summary; 144, string_content:fastq_rich; 145, identifier:ex; 146, identifier:process_fastq_rich; 147, string_content:fastq_minimal; 148, identifier:ex; 149, identifier:process_fastq_minimal; 150, string_content:cram; 151, identifier:ex; 152, identifier:process_cram; 153, string_content:ubam; 154, identifier:ex; 155, identifier:process_ubam; 156, identifier:len; 157, argument_list; 158, attribute; 159, argument_list; 160, identifier:executor; 161, identifier:partial; 162, argument_list; 163, identifier:combine_dfs; 164, argument_list; 165, attribute; 166, argument_list; 167, identifier:datadf; 168, identifier:drop; 169, string:"readIDs"; 170, keyword_argument; 171, keyword_argument; 172, string:"Nanoget: Gathered all metrics of {} reads"; 173, identifier:format; 174, call; 175, identifier:logging; 176, identifier:critical; 177, call; 178, identifier:sys; 179, identifier:exit; 180, string:"Fatal: No reads found in input."; 181, identifier:files; 182, identifier:cfutures; 183, identifier:ProcessPoolExecutor; 184, keyword_argument; 185, subscript; 186, keyword_argument; 187, keyword_argument; 188, keyword_argument; 189, keyword_argument; 190, keyword_argument; 191, keyword_argument; 192, identifier:pd; 193, identifier:isna; 194, subscript; 195, identifier:axis; 196, string; 197, identifier:inplace; 198, True; 199, identifier:len; 200, argument_list; 201, attribute; 202, argument_list; 203, identifier:max_workers; 204, identifier:filethreads; 205, identifier:proc_functions; 206, identifier:source; 207, identifier:threads; 208, identifier:threadsleft; 209, identifier:readtype; 210, identifier:readtype; 211, identifier:barcoded; 212, identifier:barcoded; 213, identifier:dfs; 214, list_comprehension; 215, identifier:names; 216, boolean_operator; 217, identifier:method; 218, identifier:combine; 219, identifier:datadf; 220, string:"readIDs"; 221, string_content:columns; 222, identifier:datadf; 223, string:"Nanoget: no reads retrieved."; 224, identifier:format; 225, call; 226, identifier:out; 227, for_in_clause; 228, identifier:names; 229, identifier:files; 230, identifier:len; 231, argument_list; 232, identifier:out; 233, call; 234, identifier:datadf; 235, attribute; 236, argument_list; 237, identifier:executor; 238, identifier:map; 239, identifier:extration_function; 240, identifier:files
code: def get_input(source, files, threads=4, readtype="1D",
                combine="simple", names=None, barcoded=False):
      """Get input and process accordingly.
  
      Data can be:
      - a uncompressed, bgzip, bzip2 or gzip compressed fastq file
      - a uncompressed, bgzip, bzip2 or gzip compressed fasta file
      - a rich fastq containing additional key=value information in the description,
        as produced by MinKNOW and albacore with the same compression options as above
      - a sorted bam file
      - a sorted cram file
      - a (compressed) sequencing_summary.txt file generated by albacore
  
      Handle is passed to the proper functions to get DataFrame with metrics
      Multiple files of the same type can be used to extract info from, which is done in parallel
      Arguments:
      - source: defines the input data type and the function that needs to be called
      - files: is a list of one or more files to operate on, from the type of <source>
      - threads: is the amount of workers which can be used
      - readtype: (only relevant for summary input) and specifies which columns have to be extracted
      - combine: is either 'simple' or 'track', with the difference that  with 'track' an additional
        field is created with the name of the dataset
      - names: if combine="track", the names to be used for the datasets. Needs to have same length as
        files, or None
      """
      proc_functions = {
          'fastq': ex.process_fastq_plain,
          'fasta': ex.process_fasta,
          'bam': ex.process_bam,
          'summary': ex.process_summary,
          'fastq_rich': ex.process_fastq_rich,
          'fastq_minimal': ex.process_fastq_minimal,
          'cram': ex.process_cram,
          'ubam': ex.process_ubam, }
      filethreads = min(len(files), threads)
      threadsleft = threads - filethreads
      with cfutures.ProcessPoolExecutor(max_workers=filethreads) as executor:
          extration_function = partial(proc_functions[source],
                                       threads=threadsleft,
                                       readtype=readtype,
                                       barcoded=barcoded)
          datadf = combine_dfs(
              dfs=[out for out in executor.map(extration_function, files)],
              names=names or files,
              method=combine)
      if "readIDs" in datadf and pd.isna(datadf["readIDs"]).any():
          datadf.drop("readIDs", axis='columns', inplace=True)
      datadf = calculate_start_time(datadf)
      logging.info("Nanoget: Gathered all metrics of {} reads".format(len(datadf)))
      if len(datadf) == 0:
          logging.critical("Nanoget: no reads retrieved.".format(len(datadf)))
          sys.exit("Fatal: No reads found in input.")
      else:
          return datadf