Exemplo n.º 1
0
def main(argv):

  wrapper = simplewrap.Wrapper()
  wrap = wrapper.wrap

  parser = argparse.ArgumentParser(description=wrap(DESCRIPTION),
                                   formatter_class=argparse.RawTextHelpFormatter)
  parser.set_defaults(**OPT_DEFAULTS)

  wrapper.width = wrapper.width - 24
  parser.add_argument('infile', metavar='read-families.tsv', nargs='?',
    help=wrap('The output of align_families.py. 6 columns:\n'
              '1. (canonical) barcode\n'
              '2. order ("ab" or "ba")\n'
              '3. mate ("1" or "2")\n'
              '4. read name\n'
              '5. aligned sequence\n'
              '6. aligned quality scores.'))
  parser.add_argument('-r', '--min-reads', type=int,
    help=wrap('The minimum number of reads (from each strand) required to form a single-strand '
              'consensus. Strands with fewer reads will be skipped. Default: %(default)s.'))
  parser.add_argument('-q', '--qual', type=int,
    help=wrap('Base quality threshold. Bases below this quality will not be counted. '
              'Default: %(default)s.'))
  parser.add_argument('-F', '--qual-format', choices=('sanger', 'solexa'),
    help=wrap('FASTQ quality score format. Sanger scores are assumed to begin at \'{}\' ({}). '
              'Default: %(default)s.'.format(SANGER_START, chr(SANGER_START))))
  parser.add_argument('--incl-sscs', action='store_true',
    help=wrap('When outputting duplex consensus sequences, include reads without a full duplex '
              '(missing one strand). The result will just be the single-strand consensus of the '
              'remaining read.'))
  parser.add_argument('-s', '--sscs-file',
    help=wrap('Save single-strand consensus sequences in this file (FASTA format). Currently does '
              'not work when in parallel mode.'))
  parser.add_argument('-l', '--log', metavar='LOG_FILE', dest='stats_file',
    help=wrap('Print statistics on the run to this file. Use "-" to print to stderr.'))
  parser.add_argument('-p', '--processes', type=int,
    help=wrap('Number of processes to use. If > 1, launches this many worker subprocesses. Note: '
              'if this option is used, no output will be generated until the end of the entire '
              'run, so no streaming is possible. Default: %(default)s.'))
  parser.add_argument('--phone-home', action='store_true',
    help=wrap('Report helpful usage data to the developer, to better understand the use cases and '
              'performance of the tool. The only data which will be recorded is the name and '
              'version of the tool, the size of the input data, the time taken to process it, and '
              'the IP address of the machine running it. No parameters or filenames are sent. All '
              'the reporting and recording code is available at https://github.com/NickSto/ET.'))
  parser.add_argument('--galaxy', dest='platform', action='store_const', const='galaxy',
    help=wrap('Tell the script it\'s running on Galaxy. Currently this only affects data reported '
              'when phoning home.'))
  parser.add_argument('--test', action='store_true',
    help=wrap('If reporting usage data, mark this as a test run.'))
  parser.add_argument('-v', '--version', action='version', version=str(version.get_version()),
    help=wrap('Print the version number and exit.'))

  args = parser.parse_args(argv[1:])

  start_time = time.time()
  if args.phone_home:
    run_id = phone.send_start(__file__, version.get_version(), platform=args.platform, test=args.test)

  assert args.processes > 0, '-p must be greater than zero'
  # Make dict of process_family() parameters that don't change between families.
  static = {}
  static['processes'] = args.processes
  static['incl_sscs'] = args.incl_sscs
  static['min_reads'] = args.min_reads
  if args.sscs_file:
    static['sscs_fh'] = open(args.sscs_file, 'w')
  if args.qual_format == 'sanger':
    static['qual_thres'] = chr(args.qual + SANGER_START)
  elif args.qual_format == 'solexa':
    static['qual_thres'] = chr(args.qual + SOLEXA_START)
  else:
    fail('Error: unrecognized --qual-format.')

  if args.infile:
    infile = open(args.infile)
  else:
    infile = sys.stdin

  if args.stats_file:
    if args.stats_file == '-':
      logging.basicConfig(stream=sys.stderr, level=logging.INFO, format='%(message)s')
    else:
      logging.basicConfig(filename=args.stats_file, filemode='w', level=logging.INFO,
                          format='%(message)s')
  else:
    logging.disable(logging.CRITICAL)

  # Open all the worker processes, if we're using more than one.
  workers = None
  if args.processes > 1:
    workers = open_workers(args.processes, args)

  stats = {'time':0, 'reads':0, 'runs':0, 'families':0}
  all_reads = 0
  duplex = collections.OrderedDict()
  family = []
  barcode = None
  order = None
  mate = None
  for line in infile:
    fields = line.rstrip('\r\n').split('\t')
    if len(fields) != 6:
      continue
    (this_barcode, this_order, this_mate, name, seq, qual) = fields
    this_mate = int(this_mate)
    # If the barcode or order has changed, we're in a new single-stranded family.
    # Process the reads we've previously gathered as one family and start a new family.
    if this_barcode != barcode or this_order != order or this_mate != mate:
      duplex[(order, mate)] = family
      # We're at the end of the duplex pair if the barcode changes or if the order changes without
      # the mate changing, or vice versa (the second read in each duplex comes when the barcode
      # stays the same while both the order and mate switch). Process the duplex and start
      # a new one. If the barcode is the same, we're in the same duplex, but we've switched strands.
      if this_barcode != barcode or not (this_order != order and this_mate != mate):
        # sys.stderr.write('New duplex:  {}, {}, {}\n'.format(this_barcode, this_order, this_mate))
        process_duplex(duplex, barcode, workers=workers, stats=stats, **static)
        duplex = collections.OrderedDict()
      # else:
      #   sys.stderr.write('Same duplex: {}, {}, {}\n'.format(this_barcode, this_order, this_mate))
      barcode = this_barcode
      order = this_order
      mate = this_mate
      family = []
    read = {'name': name, 'seq':seq, 'qual':qual}
    family.append(read)
    all_reads += 1
  # Process the last family.
  duplex[(order, mate)] = family
  process_duplex(duplex, barcode, workers=workers, stats=stats, **static)

  if args.processes > 1:
    close_workers(workers)
    compile_results(workers)
    delete_tempfiles(workers)

  if args.sscs_file:
    static['sscs_fh'].close()
  if infile is not sys.stdin:
    infile.close()

  end_time = time.time()
  run_time = int(end_time - start_time)

  # Final stats on the run.
  logging.info('Processed {} reads and {} duplexes in {} seconds.'
               .format(all_reads, stats['runs'], run_time))
  per_read = stats['time'] / stats['reads']
  per_run = stats['time'] / stats['runs']
  logging.info('{:0.3f}s per read, {:0.3f}s per run.'.format(per_read, per_run))

  if args.phone_home:
    stats['consensus_time'] = stats['time']
    del stats['time']
    phone.send_end(__file__, version.get_version(), run_id, run_time, stats, platform=args.platform,
                   test=args.test)
Exemplo n.º 2
0
    def build(self):
        """Build window."""
        self.setWindowTitle("MSFS Mod Manager - {}".format(
            get_version(self.appctxt)))
        self.setWindowIcon(
            QtGui.QIcon(
                self.appctxt.get_resource(os.path.join("icons", "icon.png"))))

        self.main_widget = main_widget(self, self.appctxt)
        self.main_widget.build()

        self.setCentralWidget(self.main_widget)

        main_menu = self.menuBar()
        file_menu = main_menu.addMenu("File")

        self.theme_menu_action = QtWidgets.QAction("FS Theme",
                                                   self,
                                                   checkable=True)
        self.theme_menu_action.setChecked(get_theme())
        self.theme_menu_action.triggered.connect(self.set_theme)
        file_menu.addAction(self.theme_menu_action)

        file_menu.addSeparator()

        menu_action = QtWidgets.QAction("Install Mod(s) from Archive", self)
        menu_action.triggered.connect(self.main_widget.install_archive)
        file_menu.addAction(menu_action)

        menu_action = QtWidgets.QAction("Install Mod from Folder", self)
        menu_action.triggered.connect(self.main_widget.install_folder)
        file_menu.addAction(menu_action)

        menu_action = QtWidgets.QAction("Uninstall Mods", self)
        menu_action.triggered.connect(self.main_widget.uninstall)
        file_menu.addAction(menu_action)

        file_menu.addSeparator()

        menu_action = QtWidgets.QAction("Create Backup", self)
        menu_action.triggered.connect(self.main_widget.create_backup)
        file_menu.addAction(menu_action)

        file_menu.addSeparator()

        menu_action = QtWidgets.QAction("Exit", self)
        menu_action.triggered.connect(self.parent.quit)
        file_menu.addAction(menu_action)

        edit_menu = main_menu.addMenu("Edit")

        menu_action = QtWidgets.QAction("Enable Selected Mods", self)
        menu_action.triggered.connect(self.main_widget.enable)
        edit_menu.addAction(menu_action)

        menu_action = QtWidgets.QAction("Disable Selected Mods", self)
        menu_action.triggered.connect(self.main_widget.disable)
        edit_menu.addAction(menu_action)

        info_menu = main_menu.addMenu("Info")

        menu_action = QtWidgets.QAction("Refresh Mods", self)
        menu_action.triggered.connect(self.main_widget.refresh)
        info_menu.addAction(menu_action)

        menu_action = QtWidgets.QAction("Mod Info", self)
        menu_action.triggered.connect(self.main_widget.info)
        info_menu.addAction(menu_action)

        info_menu.addSeparator()

        menu_action = QtWidgets.QAction("About", self)
        menu_action.triggered.connect(self.main_widget.about)
        info_menu.addAction(menu_action)
Exemplo n.º 3
0
 def get_versions(self):
     self.app_version_field.setText(get_version(self.appctxt))
     self.game_version_field.setText(self.flight_sim.get_game_version())
Exemplo n.º 4
0
    def build(self) -> None:
        """Build window."""
        self.setWindowTitle("MSFS Mod Manager - {}".format(
            get_version(self.appctxt)))  # type: ignore
        self.setWindowIcon(
            QtGui.QIcon(
                self.appctxt.get_resource(os.path.join("icons", "icon.png"))))

        self.main_widget = main_widget(self, self.appctxt)
        self.main_widget.build()

        self.setCentralWidget(self.main_widget)

        main_menu = self.menuBar()
        file_menu = main_menu.addMenu("File")

        self.theme_menu_action = QtWidgets.QAction(
            "FS Theme", self, checkable=True)  # type: ignore
        self.theme_menu_action.setChecked(get_theme())
        self.theme_menu_action.triggered.connect(
            self.set_theme)  # type: ignore
        file_menu.addAction(self.theme_menu_action)  # type: ignore

        file_menu.addSeparator()

        menu_action = QtWidgets.QAction("Install Mod(s) from Archive", self)
        menu_action.triggered.connect(
            self.main_widget.install_archive)  # type: ignore
        file_menu.addAction(menu_action)  # type: ignore

        menu_action = QtWidgets.QAction("Install Mod from Folder", self)
        menu_action.triggered.connect(
            self.main_widget.install_folder)  # type: ignore
        file_menu.addAction(menu_action)  # type: ignore

        menu_action = QtWidgets.QAction("Uninstall Mods", self)
        menu_action.triggered.connect(
            self.main_widget.uninstall)  # type: ignore
        file_menu.addAction(menu_action)  # type: ignore

        file_menu.addSeparator()

        menu_action = QtWidgets.QAction("Create Backup", self)
        menu_action.triggered.connect(
            self.main_widget.create_backup)  # type: ignore
        file_menu.addAction(menu_action)  # type: ignore

        file_menu.addSeparator()

        menu_action = QtWidgets.QAction("Exit", self)
        menu_action.triggered.connect(self.parent.quit)  # type: ignore
        file_menu.addAction(menu_action)  # type: ignore

        edit_menu = main_menu.addMenu("Edit")

        menu_action = QtWidgets.QAction("Enable Selected Mods", self)
        menu_action.triggered.connect(self.main_widget.enable)  # type: ignore
        edit_menu.addAction(menu_action)  # type: ignore

        menu_action = QtWidgets.QAction("Disable Selected Mods", self)
        menu_action.triggered.connect(self.main_widget.disable)  # type: ignore
        edit_menu.addAction(menu_action)  # type: ignore

        edit_menu.addSeparator()

        menu_action = QtWidgets.QAction("Change Mod Install Folder", self)
        menu_action.triggered.connect(
            self.main_widget.select_mod_install)  # type: ignore
        edit_menu.addAction(menu_action)  # type: ignore

        info_menu = main_menu.addMenu("Info")

        menu_action = QtWidgets.QAction("Refresh Mods", self)
        menu_action.triggered.connect(self.main_widget.refresh)  # type: ignore
        info_menu.addAction(menu_action)  # type: ignore

        menu_action = QtWidgets.QAction("Mod Info", self)
        menu_action.triggered.connect(self.main_widget.info)  # type: ignore
        info_menu.addAction(menu_action)  # type: ignore

        help_menu = main_menu.addMenu("Help")

        menu_action = QtWidgets.QAction("About", self)
        menu_action.triggered.connect(self.main_widget.about)  # type: ignore
        help_menu.addAction(menu_action)  # type: ignore

        menu_action = QtWidgets.QAction("Versions", self)
        menu_action.triggered.connect(
            self.main_widget.versions)  # type: ignore
        help_menu.addAction(menu_action)  # type: ignore

        help_menu.addSeparator()

        menu_action = QtWidgets.QAction("Open Official Website", self)
        menu_action.triggered.connect(  # type: ignore
            lambda: webbrowser.open(
                "https://github.com/NathanVaughn/msfs-mod-manager/"))
        help_menu.addAction(menu_action)  # type: ignore

        menu_action = QtWidgets.QAction("Open Issues/Suggestions", self)
        menu_action.triggered.connect(  # type: ignore
            lambda: webbrowser.open(
                "https://github.com/NathanVaughn/msfs-mod-manager/issues/"))
        help_menu.addAction(menu_action)  # type: ignore

        help_menu.addSeparator()

        menu_action = QtWidgets.QAction("Open Debug Log", self)
        menu_action.triggered.connect(
            lambda: os.startfile(DEBUG_LOG))  # type: ignore
        help_menu.addAction(menu_action)  # type: ignore

        menu_action = QtWidgets.QAction("Open Config File", self)
        menu_action.triggered.connect(
            lambda: os.startfile(CONFIG_FILE))  # type: ignore
        help_menu.addAction(menu_action)  # type: ignore

        help_menu.addSeparator()

        menu_action = QtWidgets.QAction("Open Community Folder", self)
        menu_action.triggered.connect(  # type: ignore
            lambda: os.startfile(self.main_widget.flight_sim.
                                 get_sim_mod_folder()))
        help_menu.addAction(menu_action)  # type: ignore

        menu_action = QtWidgets.QAction("Open Mod Install Folder", self)
        menu_action.triggered.connect(  # type: ignore
            lambda: os.startfile(files.get_mod_install_folder()))
        help_menu.addAction(menu_action)  # type: ignore
Exemplo n.º 5
0
def main(argv):

  wrapper = simplewrap.Wrapper()
  wrap = wrapper.wrap

  parser = argparse.ArgumentParser(description=wrap(DESCRIPTION),
                                   formatter_class=argparse.RawTextHelpFormatter)
  parser.set_defaults(**OPT_DEFAULTS)

  wrapper.width = wrapper.width - 24
  parser.add_argument('infile', metavar='read-families.tsv', nargs='?',
    help=wrap('The input reads, sorted into families. One line per read pair, 8 tab-delimited '
              'columns:\n'
              '1. canonical barcode\n'
              '2. barcode order ("ab" for alpha+beta, "ba" for beta-alpha)\n'
              '3. read 1 name\n'
              '4. read 1 sequence\n'
              '5. read 1 quality scores\n'
              '6. read 2 name\n'
              '7. read 2 sequence\n'
              '8. read 2 quality scores'))
  parser.add_argument('-p', '--processes', type=int,
    help=wrap('Number of worker subprocesses to use. Must be at least 1. Default: %(default)s.'))
  parser.add_argument('--phone-home', action='store_true',
    help=wrap('Report helpful usage data to the developer, to better understand the use cases and '
              'performance of the tool. The only data which will be recorded is the name and '
              'version of the tool, the size of the input data, the time taken to process it, and '
              'the IP address of the machine running it. No parameters or filenames are sent. All '
              'the reporting and recording code is available at https://github.com/NickSto/ET.'))
  parser.add_argument('--galaxy', dest='platform', action='store_const', const='galaxy',
    help=wrap('Tell the script it\'s running on Galaxy. Currently this only affects data reported '
              'when phoning home.'))
  parser.add_argument('--test', action='store_true',
    help=wrap('If reporting usage data, mark this as a test run.'))
  parser.add_argument('-v', '--version', action='version', version=str(version.get_version()),
    help=wrap('Print the version number and exit.'))

  args = parser.parse_args(argv[1:])

  start_time = time.time()
  if args.phone_home:
    run_id = phone.send_start(__file__, version.get_version(), platform=args.platform, test=args.test)

  assert args.processes > 0, '-p must be greater than zero'

  # Check for required commands.
  missing_commands = []
  for command in REQUIRED_COMMANDS:
    if not distutils.spawn.find_executable(command):
      missing_commands.append(command)
  if missing_commands:
    fail('Error: Missing commands: "'+'", "'.join(missing_commands)+'".')

  if args.infile:
    infile = open(args.infile)
  else:
    infile = sys.stdin

  # Open all the worker processes.
  workers = open_workers(args.processes)

  # Main loop.
  """This processes whole duplexes (pairs of strands) at a time for a future option to align the
  whole duplex at a time.
  duplex data structure:
  duplex = {
    'ab': [
      {'name1': 'read_name1a',
       'seq1':  'GATT-ACA',
       'qual1': 'sc!0 /J*',
       'name2': 'read_name1b',
       'seq2':  'ACTGACTA',
       'qual2': '34I&SDF)'
      },
      {'name1': 'read_name2a',
       ...
      }
    ]
  }
  e.g.:
  seq = duplex[order][pair_num]['seq1']
  """
  stats = {'duplexes':0, 'time':0, 'pairs':0, 'runs':0, 'aligned_pairs':0}
  current_worker_i = 0
  duplex = collections.OrderedDict()
  family = []
  barcode = None
  order = None
  for line in infile:
    fields = line.rstrip('\r\n').split('\t')
    if len(fields) != 8:
      continue
    (this_barcode, this_order, name1, seq1, qual1, name2, seq2, qual2) = fields
    # If the barcode or order has changed, we're in a new family.
    # Process the reads we've previously gathered as one family and start a new family.
    if this_barcode != barcode or this_order != order:
      duplex[order] = family
      # If the barcode is different, we're at the end of the whole duplex. Process the it and start
      # a new one. If the barcode is the same, we're in the same duplex, but we've switched strands.
      if this_barcode != barcode:
        # sys.stderr.write('processing {}: {} orders ({})\n'.format(barcode, len(duplex),
        #                  '/'.join([str(len(duplex[order])) for order in duplex])))
        output, run_stats, current_worker_i = delegate(workers, stats, duplex, barcode)
        process_results(output, run_stats, stats)
        duplex = collections.OrderedDict()
      barcode = this_barcode
      order = this_order
      family = []
    pair = {'name1': name1, 'seq1':seq1, 'qual1':qual1, 'name2':name2, 'seq2':seq2, 'qual2':qual2}
    family.append(pair)
    stats['pairs'] += 1
  # Process the last family.
  duplex[order] = family
  # sys.stderr.write('processing {}: {} orders ({}) [last]\n'.format(barcode, len(duplex),
  #                  '/'.join([str(len(duplex[order])) for order in duplex])))
  output, run_stats, current_worker_i = delegate(workers, stats, duplex, barcode)
  process_results(output, run_stats, stats)

  # Do one last loop through the workers, reading the remaining results and stopping them.
  # Start at the worker after the last one processed by the previous loop.
  start = current_worker_i + 1
  for i in range(len(workers)):
    worker_i = (start + i) % args.processes
    worker = workers[worker_i]
    output, run_stats = worker['parent_pipe'].recv()
    process_results(output, run_stats, stats)
    worker['parent_pipe'].send(None)

  if infile is not sys.stdin:
    infile.close()

  end_time = time.time()
  run_time = int(end_time - start_time)

  # Final stats on the run.
  sys.stderr.write('Processed {pairs} read pairs in {duplexes} duplexes.\n'.format(**stats))
  if stats['aligned_pairs'] > 0:
    per_pair = stats['time'] / stats['aligned_pairs']
    per_run = stats['time'] / stats['runs']
    sys.stderr.write('{:0.3f}s per pair, {:0.3f}s per run.\n'.format(per_pair, per_run))
    sys.stderr.write('{}s total time.\n'.format(run_time))

  if args.phone_home:
    stats['align_time'] = stats['time']
    del stats['time']
    phone.send_end(__file__, version.get_version(), run_id, run_time, stats, platform=args.platform,
                   test=args.test)
Exemplo n.º 6
0
def main():

    # Change umask to allow group read/write files
    os.umask(0o007)
    
    # Print welcome art and version
    print(art.art)
    print("Version: {}\n".format(version.get_version()).rjust(55))

    # Remember sessions
    session_name = input("Enter session name: ")
    session = getSession(session_name) 
    if not session:
        print("Enter one or more UNIX file name patterns\nto identify the scripts which need grading.\nSeparate patterns with a comma.")
        patterns = str(input("> ")).replace(' ','').split(',')

        print("Enter paths to all testing scripts you would\nlike to run against the homework,\nseparated by commas.")
        tests = str(input("> "))
        tests = tests.replace(' ','').split(',') if tests != '' else None

        print("Enter the maximum point value for the assignment to verify that students are not given extra credit.")
        maxpoints = input("> ")
        maxpoints = float(maxpoints) if maxpoints != '' else -1

        writeSession(session_name, patterns, tests, maxpoints)
    else:
        patterns = session['patterns']
        tests = session['tests']
        maxpoints = session['maxpoints']

    # Allow for multiple grading sessions at once
    if session_name:
        grade_file_name = session_name + '_grade.csv'
    else:
        grade_file_name = 'grade.csv'

    # Get the list of student files to grade
    student_files = []
    for pattern in patterns:
        files = rfind.find(pattern,'.',IGNORE)
        for f in files:
            if f not in student_files:
                student_files.append(f)

    # Main menu
    menu_main.print_menu()
    opt = menu_main.get_option()
    while opt != menu_main.options.TerminateProgram:

        if opt == menu_main.options.GradeHomeworks:
            gradeHomeworks(grade_file_name, student_files, tests, maxpoints)
            menu_main.print_menu()

        elif opt == menu_main.options.CheckGradeFiles:
            checkGradeFiles(grade_file_name)
            menu_main.print_menu()

        elif opt == menu_main.options.GradingStatistics:
            #printStatistics()
            print("Not yet implemented")

        elif opt == menu_main.options.ConsolidateGrades:
            #consolidateGradeFiles()
            print("Not yet implemented")

        else:
            print("You somehow got an impossible option:", opt)

        opt = menu_main.get_option()

    print("Grading session complete.")
Exemplo n.º 7
0
 def get_versions(self) -> None:
     self.app_version_field.setText(get_version(
         self.appctxt))  # type: ignore
     self.game_version_field.setText(self.flight_sim.get_game_version())