Exemple #1
0
 async def MOTDallow(self, ctx, *, allowingRole: discord.Role):
     if await fs.isAdmin(ctx.author):
         # checks if role is already in db
         serverEntry = await fs.getServerEntry(fs.serverPath, ctx.guild.id)
         motdRole = discord.utils.get(ctx.guild.roles,
                                      id=serverEntry['motdRoleID'])
         exemptRoles = serverEntry['exemptRoles']
         if allowingRole == motdRole:
             await ctx.send('pls dont break my code')
             return
         elif allowingRole.id in exemptRoles:
             # remove role from exemptions
             try:
                 exemptRoles.remove(allowingRole.id)
                 await fs.updateServerVal(fs.serverPath, ctx.guild.id,
                                          'exemptRoles', exemptRoles)
                 await ctx.send(
                     f'**{allowingRole.name}** is now allowed for {motdRole.name}.'
                 )
                 logger.info(
                     f'\nServList DB update: {ctx.guild.name} | Role exemption REMOVED: {allowingRole.name}'
                 )
             except:
                 await ctx.send('**An error occurred!**')
         else:
             # role already allowed
             await ctx.send(
                 f'**{allowingRole.name}** was already allowed for {motdRole.name}.\n'
                 f'Use **!exemptedroles** to get a list of all exempted roles.'
             )
Exemple #2
0
 async def hiscores(self, ctx):
     topScoreLst = []
     serverEntry = await fs.getServerEntry(fs.serverPath, ctx.guild.id)
     motdRole = discord.utils.get(ctx.guild.roles,
                                  id=serverEntry['motdRoleID'])
     exemptRoles = serverEntry['exemptRoles']
     scoresEntry = await fs.getServerEntry(fs.scorePath, ctx.guild.id)
     try:
         counter = 0
         for k, v in scoresEntry.items():
             try:
                 mem = ctx.guild.get_member(int(k))
                 # check if member is exempted. if so, exclude from list
                 if any(role.id in exemptRoles for role in mem.roles):
                     pass
                 else:
                     topScoreLst.append(f"*{mem.name}*" + "  **|**  " +
                                        f"{str(v)}\n")
                     counter += 1
                     if counter == 15:  # how many members to show
                         break
             except:
                 logger.debug(
                     f'Skipped {k} in !hiscores: {ctx.guild.name} - {ctx.guild.id}'
                 )
                 pass
         topScoreLst = "".join(topScoreLst)
         await ctx.send(
             f'**Top {str(counter)} Hiscores - {motdRole.name}**\n' +
             topScoreLst)
     except:
         await ctx.send('No servers in database.')
     logger.info(
         f'!hiscores called in {ctx.guild.name} by {ctx.author.name}')
Exemple #3
0
 async def totalvotes(self, ctx):
     # TEMP
     # await ctx.send(f'Total votes are hidden right now!')
     # return
     # STARTS HERE
     voteLst = []
     serverEntry = await fs.getServerEntry(fs.serverPath, ctx.guild.id)
     votingEntry = await fs.getServerEntry(fs.votePath, ctx.guild.id)
     motdRole = discord.utils.get(ctx.guild.roles,
                                  id=serverEntry['motdRoleID'])
     voteCounts = votingEntry['voteCounts']
     try:
         for k, v in voteCounts.items():
             try:
                 mem = ctx.guild.get_member(int(k))
                 voteLst.append(f"*{mem.name}*" + "  **|**  " +
                                f"{str(v)}\n")
             except:
                 logger.debug(f'Skipped {k} in !totalvotes')
                 pass
         voteLst = "".join(voteLst)
         await ctx.send(f'**Member Votes - {motdRole.name}**\n{voteLst}')
     except:
         await ctx.send('No members have been voted for.')
     logger.info(
         f'!totalvotes called in {ctx.guild.name} by {ctx.author.name}')
def parse_settings(settings_file):
    """ Creates multiple dictionaries containing the settings parsed from a settings file.
    Each type of plot has its own settings dictionary.
    
    settings_file is the name of the text file containing the settings

    Return values:
    data is a pandas.DataFrame object which contains the alternative splicing data
    hive_plot_settings is a dictionary containing the settings for the hive plot
    struct_plot_settings is a dictionary containing the settings for the structure plot
    """
    try:
        config = configparser.ConfigParser()
        logger.info('Reading settings from {0}...'.format(settings_file))
        config.read(settings_file)

        # hive_plot_settings = parse_hive_plot_settings(config)
        # struct_plot_settings = parse_struct_plot_settings(config)

        return parse_sashimi_settings(config)

        # print('Done reading settings.')
        # return hive_plot_settings, struct_plot_settings, sashimi_plot_settings
    except IOError:
        logger.error('{0} is not a valid file path')
        sys.exit(1)
Exemple #5
0
def is_bam(infile):
    u"""
    check if input file is bam or sam file
    :param infile: path to input file
    :return: Boolean
    """

    try:
        create = False
        if not os.path.exists(infile + ".bai"):
            create = True
        elif os.path.getctime(infile + ".bai") < os.path.getctime(infile):
            os.remove(infile + ".bai")
            create = True
        else:
            try:
                with pysam.AlignmentFile(infile) as r:
                    r.check_index()
            except ValueError:
                create = True

        if create:
            logger.info("Creating index for %s" % infile)
            pysam.index(infile)
        return True

    except pysam.utils.SamtoolsError:
        return False
Exemple #6
0
 async def MOTDexempt(self, ctx, *, exemptingRole: discord.Role):
     if await fs.isAdmin(ctx.author):
         # checks if role is already in db
         serverEntry = await fs.getServerEntry(fs.serverPath, ctx.guild.id)
         motdRole = discord.utils.get(ctx.guild.roles,
                                      id=serverEntry['motdRoleID'])
         exemptRoles = serverEntry['exemptRoles']
         if exemptingRole == motdRole:
             await ctx.send('pls dont break my code')
             return
         elif exemptingRole.id in exemptRoles:
             # role already exempted
             await ctx.send(
                 f'**{exemptingRole.name}** was already exempted from {motdRole.name}!'
             )
         else:
             # add role to exemptions
             try:
                 exemptRoles.append(exemptingRole.id)
                 await fs.updateServerVal(fs.serverPath, ctx.guild.id,
                                          'exemptRoles', exemptRoles)
                 await ctx.send(
                     f'**{exemptingRole.name}** is now exempted from {motdRole.name}.'
                 )
                 logger.info(
                     f'\nServer List DB update: {ctx.guild.name} | Role exemption ADDED: {exemptingRole.name}'
                 )
             except:
                 await ctx.send('**An error occurred!**')
def run():
    # 登入,输入讲师姓名无密码
    teacher = None
    while True:
        show_teacher_menu()
        s = input('>>>').strip()
        if s.isdigit():
            s = int(s)
            if s == 1:
                logger.info('teacher login...')
                print('请输入讲师姓名')
                name = input('>>>').strip()
                teacher = login(name, tp='teacher')
                if not teacher:
                    print('登入失败')
            elif s == 2:
                logger.info('check grades...')
                check_grades(teacher)
            elif s == 3:
                logger.info('check grades...')
                check_grades_students(teacher)
            elif s == 4:
                logger.info('modify score...')
                modify_score(teacher)
            elif s == 5:
                logger.info('teaching...')
                teach(teacher, )
        elif s == 'q' or s == 'Q':
            # save_student(student)
            exit('bye')
        else:
            print('输入错误')
def draw_line_plot(output_file_path,
                   settings,
                   average_depths_dict,
                   splice_region,
                   no_bam=False,
                   show_gene=True,
                   dpi=300,
                   log=None,
                   title=None,
                   distance_ratio=0.3):
    """
        draw_sashimi_plot draws the complete sashimi plot

        output_file_path is the file path that the plot will be written to

        settings is a dict containing the settings for the sashimi plot

        var_pos is the location of the SNP, in the format chr1:12345

        average_depths_dict {group: {BAM: ReadDepth}, group: {BAM: ReadDepth}}

        mRNAs_object is an mRNAsObject containing information about the transcript structure

        plot_title is the title of the plot


        return values:
            None. Draws sashimi plot

    """

    assert isinstance(
        splice_region, SpliceRegion
    ), "splice_region should be SpliceRegion, not %s" % type(splice_region)
    u"""
    @2019.01.04
    If there is no bam, reduce the height of figure
    """
    if no_bam:
        height = settings['height'] * (len(average_depths_dict) +
                                       len(splice_region.transcripts)) // 2
    else:
        height = settings['height'] * (len(average_depths_dict) +
                                       len(splice_region.transcripts) // 2)

    plt.figure(figsize=[settings['width'], height], dpi=dpi)

    plot_density(
        settings,  # plot settings, untouched
        read_depths_dict=average_depths_dict,  # reads coverage
        splice_region=splice_region,  # Exon and transcript information
        show_gene=show_gene,  # decide whether display gene id in this plot
        no_bam=no_bam,
        log=log,
        title=title,
        distance_ratio=distance_ratio)

    logger.info("save to %s" % output_file_path)
    plt.savefig(output_file_path, transparent=True, bbox_inches='tight')
Exemple #9
0
async def quintVotesDay(servID,ctx): # server id
    serverEntry = await fs.getServerEntry(fs.serverPath,servID)
    currentEvents = serverEntry['currentEvents']
    currentEvents['quintVotes'] = True
    await fs.updateServerVal(fs.serverPath,servID,'currentEvents',currentEvents)
    await ctx.send("**It's Quintuple Vote Day!** Everyone in the server now has **5** votes to give out!\n"
            "All votes will be reset during the next drawing tomorrow!")
    logger.info(f'  Started Quintuple Vote Day')
Exemple #10
0
async def resetEvents(servID): # server id
    serverEntry = await fs.getServerEntry(fs.serverPath,servID)
    currentEvents = serverEntry['currentEvents']
    logger.debug('Looping current events...')
    for event in currentEvents:
        currentEvents[event] = False
    logger.debug('All events set False...')
    await fs.updateServerVal(fs.serverPath,servID,'currentEvents',currentEvents)
    logger.info(f'  Reset all events')
Exemple #11
0
 async def when(self, ctx):
     # gather variables from command
     server = ctx.guild
     serverEntry = await fs.getServerEntry(fs.serverPath, ctx.guild.id)
     motdRole = discord.utils.get(ctx.guild.roles,
                                  id=serverEntry['motdRoleID'])
     await ctx.send(
         f"**{ctx.guild.name} - {motdRole.name}**\n"
         f"**{serverEntry['timeStart']}** in *#{serverEntry['chanName']}*")
     logger.info(f'!when called by {ctx.author.name} in {ctx.guild.name}')
async def delServerDB(servID, servName):
    dataSe = await openJson(serverPath)
    dataV = await openJson(votePath)
    # delete server in server DB
    if str(servID) in dataSe:
        del dataSe[str(servID)]
    # delete server in voting DB
    if str(servID) in dataV:
        del dataV[str(servID)]
    await writeJson(serverPath, dataSe)
    await writeJson(votePath, dataV)
    logger.info(f'\nGuild removed from databases: {servName} | {servID}')
Exemple #13
0
 async def MOTDhelp(self, ctx):
     await ctx.send(
         'Use the **!MOTDsetup** command to set up Member of the Day. '
         'In order to run Member of the Day on this server I will create a MOTD role '
         'and secret text channel. I will also need a text channel to post announcements '
         'in. This is determined by the text channel you run the setup command in. '
         'Lastly, I will need a specified minute (CST) during the day to run the script '
         'which should be formatted HRS:MINS after the command. '
         'For example, If the following was posted in the #general chat, I will announce '
         'a new member for the Member of the Day role at 10PM CST every day in #general: \n'
         '**!MOTDsetup 22:00** <--- (you can copy and paste this if you want)'
     )
     logger.info(f'!MOTDhelp called in {ctx.guild.name}')
Exemple #14
0
def read_reads_depth_from_bam(bam_list,
                              splice_region,
                              threshold=0,
                              log=None,
                              n_jobs=1):
    u"""
    read reads coverage info from all bams
    :param bam_list: namedtuple (alias, title, path, label)
    :param splice_region: SpliceRegion
    :param threshold: filter low abundance junctions
    :param log
    :param n_jobs
    :return: dict {alias, ReadDepth}
    """
    logger.info("Reading from bam files")
    assert isinstance(
        splice_region, SpliceRegion
    ), "splice_region should be SplcieRegion, not %s" % type(splice_region)

    res = OrderedDict()

    try:
        # not using multiprocessing when only single process, in case the data size limitation of pickle issue
        if n_jobs == 1:
            for i in [[splice_region, bam, threshold, log, idx]
                      for idx, bam in enumerate(bam_list)]:
                # print(i)
                res.update(__read_from_bam__(i)[0])
        else:
            with Pool(min(n_jobs, len(bam_list))) as p:
                temp = p.map(__read_from_bam__,
                             [[splice_region, bam, threshold, log, idx]
                              for idx, bam in enumerate(bam_list)])

                temp = [x for x in temp if x is not None]
                temp = sorted(temp, key=lambda x: x[1])
                for i in temp:
                    if i is None:
                        continue
                    res.update(i[0])
    except Exception as err:
        logger.error(err)
        traceback.print_exc()
        exit(err)

    if len(res) == 0:
        logger.error("Error reading files, cannot read anything")
        exit(1)

    return res
Exemple #15
0
async def on_guild_remove(guild):
    serverEntry = await fs.getServerEntry(fs.serverPath, guild.id)
    # delete server run time in rt.runTimes
    delRuntime = serverEntry['timeStart']
    # only try to delete run time if its not None in db
    if delRuntime != None:
        if delRuntime in rt.runTimes:
            rt.runTimesDel(delRuntime)
            pass
    # delete server from DBs
    await fs.delServerDB(guild.id, guild.name)
    logger.info(
        f'\nServer List DB update: bot removed from {guild.name} | {guild.id}\n'
    )
async def updateScores(servID, motdID):
    scoresEntry = await getServerEntry(scorePath, servID)
    # if member has been picked before
    if str(motdID) in scoresEntry:
        scoresEntry[str(motdID)] += 1
        sortedScores = {
            k: v
            for k, v in sorted(
                scoresEntry.items(), key=lambda x: x[1], reverse=True)
        }
        logger.info(f'Score added to ID {motdID}')
    # if member has NOT been picked before
    else:
        scoresEntry[str(motdID)] = 1
        sortedScores = scoresEntry
        #sortedScores = {k: v for k, v in sorted(scoresEntry.items(), key=lambda x: x[1], reverse=True)}
        logger.info(f'ID {motdID} added to score dict')
    await updateServerEntry(scorePath, servID, sortedScores)
Exemple #17
0
 async def MOTDservs(self, ctx):
     if await fs.isAdmin(ctx.author):
         servLst = []
         logger.info(
             f'ServList DB query: {ctx.author.name} in {ctx.guild.name} ({ctx.guild.id})'
         )
         try:
             data = await fs.openJson(fs.serverPath)
             for a, b in data.items():
                 servLst.append(f"{b['servName']}" + " | " +
                                f"#{b['chanName']}" + " | " +
                                f"{b['timeStart']}\n")
             servLst = "".join(servLst)
             await ctx.send(
                 '**Member of the Day - Server List & Run Times**\n'
                 '```' + servLst + '```')
         except:
             await ctx.send('There are no servers in the database.')
Exemple #18
0
 async def exemptedroles(self, ctx):
     # gather variables from command
     serverEntry = await fs.getServerEntry(fs.serverPath, ctx.guild.id)
     motdRole = discord.utils.get(ctx.guild.roles,
                                  id=serverEntry['motdRoleID'])
     exemptRoles = serverEntry['exemptRoles']
     if not exemptRoles:
         await ctx.send(
             f'There are no roles being exempted from {motdRole.name}')
     else:
         exemptNames = []
         for roleid in exemptRoles:
             role = discord.utils.get(ctx.guild.roles, id=roleid)
             exemptNames.append(f'**{role.name}**')
         exemptNames = ", ".join(exemptNames)
         await ctx.send(
             f'Roles exempted from {motdRole.name}:\n{exemptNames}')
     logger.info(
         f'!exemptedroles called by {ctx.author.name} in {ctx.guild.name}')
Exemple #19
0
async def on_guild_join(guild):
    sysChan = False
    if guild.system_channel != None:
        sysChan = True
        await guild.system_channel.send(
            f'Thanks for having me, {guild.name}\n'
            'Use **!MOTDhelp** to learn how to start Member of the Day\n'
            'Use **!help** to get a list of all my functions')
    logger.info('\n---------------------------------------\n'
                f'Joined {guild.name} with {guild.member_count} users!\n'
                f' System channel = {sysChan}\n'
                '---------------------------------------')
    await asyncio.sleep(1)
    botRole = discord.utils.get(guild.roles, name='MOTD Bot')
    await fs.addServerDB(guild.id, guild.name, botRole.id)
    if guild.system_channel != None:
        await guild.system_channel.send(
            f'Move my role ({botRole.mention}) above all hoisted roles to use Member of the Day!'
        )
Exemple #20
0
 async def servertotals(self, ctx):
     serverEntry = await fs.getServerEntry(fs.serverPath, ctx.guild.id)
     scoresEntry = await fs.getServerEntry(fs.scorePath, ctx.guild.id)
     motdRole = discord.utils.get(ctx.guild.roles,
                                  id=serverEntry['motdRoleID'])
     # get counts
     try:
         counter1 = 0
         counter2 = 0
         for k, v in scoresEntry.items():
             counter1 += v
             counter2 += 1
         await ctx.send(
             f"**{ctx.guild.name} - {motdRole.name}**\n"
             f"*Total Picks:*  {str(counter1)}  **|**  *Unique Winners:*  {str(counter2)}"
         )
     except:
         await ctx.send(f'There have been no picks in {ctx.guild.name}')
     logger.info(
         f'!servertotals called in {ctx.guild.name} by {ctx.author.name}')
async def getVoteLst(serv):  # server object
    voteLst = []
    votingEntry = await getServerEntry(votePath, serv.id)
    voteCounts = votingEntry['voteCounts']
    badIDs = []
    # get member objects from keys
    for k, v in voteCounts.items():
        mem = serv.get_member(int(k))
        # append number of mems to list based on value amount
        if mem != None:
            for i in range(v):
                voteLst.append(mem)
        else:
            badIDs.append(k)
    # if we cant get member, remove bad entry from our json
    if badIDs:
        for memID in badIDs:
            del voteCounts[memID]
        votingEntry['voteCounts'] = voteCounts
        await updateServerEntry(votePath, serv.id, votingEntry)
        logger.info(f'Bad member IDs in vote list! Deleted: {k}!')
    return voteLst
async def updateServerMOTD(servID, servName, chanName, chanID, timeRun,
                           motdRoleID, secretChID):
    # open server list
    serverEntry = await getServerEntry(serverPath, servID)
    # adjust runTimes list in motd_times.py
    oldTime = serverEntry['timeStart']
    if oldTime in rt.runTimes:
        rt.runTimesDel(oldTime)
        rt.runTimesAdd(timeRun)
        pass
    else:
        rt.runTimesAdd(timeRun)
        pass
    # replace values
    serverEntry['servName'] = servName
    serverEntry['chanName'] = chanName
    serverEntry['channelID'] = chanID
    serverEntry['timeStart'] = timeRun
    serverEntry['motdRoleID'] = motdRoleID
    serverEntry['secretChID'] = secretChID
    # update server list
    await updateServerEntry(serverPath, servID, serverEntry)
    logger.info(f'\nServList DB update: {servName} | #{chanName} | {timeRun}\n'
                f' *Updated run-time entry: {oldTime} --> {timeRun}')
Exemple #23
0
 async def MOTDpause(self, ctx):
     if await fs.isAdmin(ctx.author):
         serverEntry = await fs.getServerEntry(fs.serverPath, ctx.guild.id)
         try:
             if serverEntry['isPaused'] == False:
                 await fs.updateServerVal(fs.serverPath, ctx.guild.id,
                                          'isPaused', True)
                 await ctx.send(
                     f'I am now **PAUSED** on *{ctx.guild.name}*!\n'
                     'Use !MOTDpause again to unpause me!')
                 logger.info(
                     f'\nServer List DB update: {ctx.guild.name} | isPaused: True'
                 )
             else:
                 await fs.updateServerVal(fs.serverPath, ctx.guild.id,
                                          'isPaused', False)
                 await ctx.send(
                     f'I am now **UNPAUSED** on *{ctx.guild.name}*!\n'
                     'Use !MOTDpause again to pause me!')
                 logger.info(
                     f'\nServer List DB update: {ctx.guild.name} | isPaused: False'
                 )
         except:
             await ctx.send('**An error occurred!**')
Exemple #24
0
 async def MOTDreminder(self, ctx):
     if await fs.isAdmin(ctx.author):
         serverEntry = await fs.getServerEntry(fs.serverPath, ctx.guild.id)
         try:
             if serverEntry['reminder'] == True:
                 await fs.updateServerVal(fs.serverPath, ctx.guild.id,
                                          'reminder', False)
                 await ctx.send(
                     f'I will **NOT** remind an hour before on *{ctx.guild.name}*!\n'
                     'Use !MOTDreminder again to enable the reminder!')
                 logger.info(
                     f'\nServer List DB update: {ctx.guild.name} | reminder: False'
                 )
             else:
                 await fs.updateServerVal(fs.serverPath, ctx.guild.id,
                                          'reminder', True)
                 await ctx.send(
                     f'I **WILL** remind an hour before on *{ctx.guild.name}*!\n'
                     'Use !MOTDreminder again to enable the reminder!')
                 logger.info(
                     f'\nServer List DB update: {ctx.guild.name} | reminder: True'
                 )
         except:
             await ctx.send('**An error occurred!**')
Exemple #25
0
def read_transcripts(gtf_file, region, genome=None, retry=0):
    u"""
    Read transcripts from tabix indexed gtf files

    The original function check if the junctions corresponding to any exists exons, I disable this here

    :param gtf_file: path to bgzip gtf files (with tabix index), only ordered exons in this gtf file
    :param region: splice region
    :param retry: if the gtf chromosome and input chromosome does not match. eg: chr9:1-100:+ <-> 9:1-100:+
    :param genome: path to genome fasta file
    :return: SpliceRegion
    """
    if not os.path.exists(gtf_file):
        raise FileNotFoundError("%s not found" % gtf_file)

    try:
        logger.info("Reading from %s" % gtf_file)

        if genome:
            with pysam.FastaFile(genome) as fa:
                region.sequence = fa.fetch(region.chromosome, region.start - 1,
                                           region.end + 1)

        with pysam.Tabixfile(gtf_file, 'r') as gtf_tabix:
            relevant_exons_iterator = gtf_tabix.fetch(region.chromosome,
                                                      region.start - 1,
                                                      region.end + 1,
                                                      parser=pysam.asGTF())

            # min_exon_start, max_exon_end, exons_list = float("inf"), float("-inf"),  []
            for line in relevant_exons_iterator:
                try:
                    region.add_gtf(line)
                except IndexError as err:
                    logger.error(err)

    except ValueError as err:
        logger.warn(err)

        # handle the mismatch of chromosomes here
        if retry < 2:
            if not region.chromosome.startswith("chr"):
                logger.info("Guess need 'chr'")
                region.chromosome = "chr" + region.chromosome
            else:
                logger.info("Guess 'chr' is redundant")
                region.chromosome = region.chromosome.replace("chr", "")

            return read_transcripts(gtf_file=gtf_file,
                                    region=region,
                                    retry=retry + 1)

    return region
Exemple #26
0
async def on_ready():
    logger.info(f'\n** BOT STARTED: {bot.user.name} - {bot.user.id} **')
    # gather run times from server db
    rt.runTimesInit()
    await bot.change_presence(activity=gamePlaying)
Exemple #27
0
                   pm_help=True,
                   intents=intents)
gamePlaying = discord.Game(name='!vote | !score')
# gamePlaying = discord.Streaming(name='!vote | !score',
#                                 url='https://www.twitch.tv/thegreendonut')

# define extensions
#cogsLoc = '/home/pi/code_pi/gavinbot/cogs/'
initial_extensions = ['cogs.motd_cmds', 'cogs.motd_looper']

# load extensions
if __name__ == '__main__':
    for extension in initial_extensions:
        try:
            bot.load_extension(extension)
            logger.info(f'Loaded extension {extension}.')
        except Exception as e:
            logger.warning(f'Failed to load extension {extension}.')
            traceback.print_exc()


# bot main start
@bot.event
async def on_ready():
    logger.info(f'\n** BOT STARTED: {bot.user.name} - {bot.user.id} **')
    # gather run times from server db
    rt.runTimesInit()
    await bot.change_presence(activity=gamePlaying)


# --- ERROR & COOLDOWN RESPONSES
Exemple #28
0
def index_gtf(input_gtf, sort_gtf=True, retry=0):
    u"""
    Created by ygidtu

    Extract only exon tags and keep it clean

    :param input_gtf: path to input gtf file
    :param sort_gtf: Boolean value, whether to sort gtf file first
    :param retry: only try to sort gtf once
    :return path to compressed and indexed bgzipped gtf file
    """
    gtf = is_gtf(input_gtf)

    if gtf % 10 != 1:
        raise ValueError("gtf file required, %s seems not a valid gtf file" %
                         input_gtf)

    index = False
    if gtf // 10 > 0:
        output_gtf = input_gtf
    else:
        output_gtf = input_gtf + ".gz"
    if not os.path.exists(output_gtf) or not os.path.exists(output_gtf +
                                                            ".tbi"):
        index = True

    elif os.path.getctime(output_gtf) < os.path.getctime(output_gtf) or \
            os.path.getctime(output_gtf) < os.path.getctime(output_gtf):
        index = True

    # 2018.12.21 used to handle gtf not sorted error
    if sort_gtf and retry > 1:
        raise OSError(
            "Create index for %s failed, and trying to sort it failed too" %
            input_gtf)
    elif sort_gtf:
        data = []

        logger.info("Sorting %s" % input_gtf)

        old_input_gtf = input_gtf
        input_gtf = re.sub("\.gtf$", "", input_gtf) + ".sorted.gtf"

        output_gtf = input_gtf + ".gz"

        if os.path.exists(input_gtf) and os.path.exists(output_gtf):
            return output_gtf

        try:
            w = open(input_gtf, "w+")
        except IOError as err:
            w = open("/tmp/sorted.gtf")

        with open(old_input_gtf) as r:
            for line in tqdm(r):
                if line.startswith("#"):
                    w.write(line)
                    continue

                lines = line.split()

                if len(lines) < 1:
                    continue

                data.append(
                    GenomicLoci(chromosome=lines[0],
                                start=lines[3],
                                end=lines[4],
                                strand=lines[6],
                                gtf_line=line))

        for i in sorted(data):
            w.write(i.gtf_line)

        w.close()

    if index:
        logger.info("Create index for %s", input_gtf)
        try:
            pysam.tabix_index(input_gtf,
                              preset="gff",
                              force=True,
                              keep_original=True)
        except OSError as err:

            if re.search("could not open", str(err)):
                raise err

            logger.error(err)
            logger.error("Guess gtf needs to be sorted")
            return index_gtf(input_gtf=input_gtf,
                             sort_gtf=True,
                             retry=retry + 1)

    return output_gtf
Exemple #29
0
def read_reads_depth_from_count_table(count_table,
                                      splice_region,
                                      required,
                                      colors,
                                      threshold=0):
    u"""
    Read junction counts from count_table
    :param count_table: path to count table
    :param splice_region:
    :param required: list of str, which columns are required to draw
    :param threshold: threshold to filter out low abundance junctions
    :param colors: {key: color}
    :return: {label: ReadDepth}
    """

    data = {}
    header = {}
    with open(count_table) as r:
        for line in r:
            lines = line.split()

            if not header:
                for i, j in enumerate(lines):
                    header[i] = clean_star_filename(j)
            else:
                # check file header, to avoide file format error
                if len(header) == len(lines) - 1:
                    logger.info(
                        "Change header index due to: Number of headers == number of columns - 1"
                    )
                    new_header = {k + 1: v for k, v in header.items()}
                    header = new_header

                for i, j in enumerate(lines):
                    if i == 0:
                        tmp = GenomicLoci.create_loci(lines[0])

                        if not splice_region.is_overlap(tmp):
                            break
                    else:
                        key = header[i]
                        if required:
                            if header[i] in required.keys():
                                key = required[header[i]]
                            else:
                                continue

                        tmp_junctions = data[key] if key in data.keys() else {}

                        if j != "NA" and int(j) >= threshold:
                            tmp_junctions[lines[0]] = int(j)

                        data[key] = tmp_junctions

    res = {}
    for key, value in data.items():

        # customized junctions will introduce string type of key, and list of colors
        # use this try catch to convert key to index to assign colors
        try:
            color = colors[key]
        except TypeError:
            color = colors[len(res) % len(colors)]

        key = BamInfo(path=None, alias=key, label=None, title="", color=color)

        res[key] = ReadDepth.create_depth(value, splice_region)

        res[key].shrink(splice_region.start, splice_region.end)

    return res
Exemple #30
0
 async def vote(self, ctx, *, member: discord.Member):
     # TEMP
     # await ctx.channel.purge(limit = 1)
     serverEntry = await fs.getServerEntry(fs.serverPath, ctx.guild.id)
     votingEntry = await fs.getServerEntry(fs.votePath, ctx.guild.id)
     currentMOTD = serverEntry['currentMOTD']
     exemptRoles = serverEntry['exemptRoles']
     usedVotes = votingEntry['usedVotes']
     voteCounts = votingEntry['voteCounts']
     motdRole = discord.utils.get(ctx.guild.roles,
                                  id=serverEntry['motdRoleID'])
     # TEMP
     #if member votes themselves
     if ctx.author.id == member.id:
         await ctx.author.edit(nick="I TRIED VOTING MYSELF")
         await ctx.send(f'You cannot vote for yourself!')
         return
     # if member votes a bot
     if member.bot:
         await ctx.send(f'You cannot vote for bots!')
         return
     # if member votes current MOTD
     elif member.id == currentMOTD:
         await ctx.send(
             f'This member is currently the {motdRole.name} and cannot be voted for today!'
         )
         return
     # if member votes exempted member
     elif any(r.id in exemptRoles for r in member.roles):
         await ctx.send(
             f'This member is currently exempted from {motdRole.name} and cannot be voted for!'
         )
         return
     # if member already voted
     elif str(ctx.author.id) in usedVotes:
         # check if event is active for more votes
         if await ev.eventStatus(ctx.guild.id, 'quintVotes') != True:
             await ctx.send(f'You have used up all of your votes today!')
             return
         elif usedVotes[str(ctx.author.id)] >= 5:
             await ctx.send(f'You have used up all of your votes today!')
             return
     # if author hasnt voted today or has more votes to give
     try:
         # update usedVotes with author
         if str(ctx.author.id) in usedVotes:
             usedVotes[str(ctx.author.id)] += 1
         else:
             usedVotes[str(ctx.author.id)] = 1
         # update voteCounts with votee
         if str(member.id) in voteCounts:
             voteCounts[str(member.id)] += 1
         else:
             voteCounts[str(member.id)] = 1
         # update usedVotes + voteCounts dicts
         votingEntry['usedVotes'] = usedVotes
         votingEntry['voteCounts'] = voteCounts
         # write voting dict
         await fs.updateServerEntry(fs.votePath, ctx.guild.id, votingEntry)
         logger.info(
             f'\n{ctx.author.name} voted for {member.name} in {ctx.guild.name}.'
             f'\nTotal votes: {voteCounts[str(member.id)]}')
         # TEMP
         await ctx.send(
             f'{ctx.author.name} voted for **{member.name}**. Total votes: **{voteCounts[str(member.id)]}**'
         )
         # await ctx.send(f'{ctx.author.name} voted! Used votes: **{usedVotes[str(ctx.author.id)]}** out of 5')
     except:
         await ctx.send('**An error occurred!**')