Example #1
0
def tagCompounds(request, action):
    if request.is_ajax() and request.method == 'POST':
        rawJson = request.body
        data = json.loads(rawJson.decode("utf-8"))
        compoundIds = []
        tags = []
        try:
            tags = data["tags"]
            compoundIds = [int(id) for id in data["ids"]]
        except:
            print("failed to parse json for tags and compound ids: " +
                  str(rawJson))
            return HttpResponse("failed to parse JSON", status=404)

        #print("adding tags "+str(tags)+" to compounds "+str(compoundIds))

        Tag.ensureAllExist(tags, request.user)

        tagObjects = Tag.objects.filter(user=request.user, name__in=tags)
        compounds = Compound.objects.filter(user=request.user,
                                            id__in=compoundIds)
        for compound in compounds:
            if action == 'add':
                compound.tags.add(*tagObjects)
            elif action == 'remove':
                compound.tags.remove(*tagObjects)
            else:
                return HttpResponse("Unknown action given", status=404)
            compound.save()

    return HttpResponse('')
Example #2
0
def tagDuplicateCompounds(request):
    from django.db.models import Count
    import itertools
    from operator import itemgetter

    #print("tagging duplicates")
    if request.is_ajax() and request.method == 'GET':
        # group all compounds by inchi and return groups with size > 1
        groupInfo =Compound.objects.values_list('inchi') \
            .annotate(duplicate_count=Count('inchi')) \
            .filter(user=request.user,duplicate_count__gt=1) \
            .order_by('inchi')
        dupedInchis = [row[0] for row in groupInfo]
        numGroups = len(groupInfo)

        #print("duped inchi's: "+str(dupedInchis))

        # get the id and inchi of duplicated compounds
        dupedCompounds = Compound.objects \
                            .values_list("id","inchi") \
                            .filter(user=request.user,inchi__in=dupedInchis)

        #print("duped compounds: "+str(dupedCompounds))
        allIds = [row[0] for row in dupedCompounds]
        groups = itertools.groupby(sorted(dupedCompounds, key=itemgetter(1)),
                                   key=itemgetter(1))
        #print("groups: "+str(groups))

        # tag all group memebers with 'duplicated'
        Tag.ensureAllExist(["duplicate-extra"], request.user)
        extraTag = Tag.objects.filter(user=request.user,
                                      name__exact="duplicate-extra").get()
        #print("duplicatedTag: "+str(extraTag))

        # create all tags we'll need at once
        tagNames = ["duplicate-set-" + str(i) for i in range(numGroups)]
        Tag.ensureAllExist(tagNames, request.user)
        tags = Tag.objects.filter(user=request.user,
                                  name__in=tagNames).order_by("id")

        newTags = {}
        # tag all but the first member of each group with duplicted-X
        for setNum, group in enumerate(
                groups
        ):  # groups is a list of tuples, each tuple is (inchi,[ids])
            ids = [row[0] for row in list(group[1])]
            #print("group: "+str(ids))
            for i, compound in enumerate(
                    Compound.objects.filter(user=request.user, id__in=ids)):
                t = newTags.setdefault(compound.id, [])
                if i != 0:  #don't tag first compound in each group, that will be the one to keep
                    compound.tags.add(extraTag)
                    t.append(extraTag.name)
                compound.tags.add(tags[setNum])
                t.append(tags[setNum].name)
                compound.save()
        return JsonResponse(newTags)

    return JsonResponse({})
Example #3
0
def addCompoundsAjax(user, source_id, ids, tags):
    if len(tags) != 0:
        Tag.ensureAllExist(tags, user)

    if len(ids) == 0:
        raise Exception('Empty list of "ids".')

    if source_id == 'chembl':
        sdfs = get_chembl_sdfs(ids)
        sdf = '\n$$$$\n'.join(sdfs) + '\n$$$$\n'

        newJob = createJob(
            user, 'Upload Compounds', '',
            ['--user='******'--tags=' + (','.join(tags))], sdf)
        time.sleep(2)
        newJob = updateJob(user, newJob.id)
        if newJob.status == Job.RUNNING:
            ajaxResponse = {
                'success':
                True,
                'message':
                'Compound upload in progress. Check "Past Jobs" for status.'
            }
        elif newJob.status == Job.FINISHED:
            ajaxResponse = {
                'success': True,
                'message': 'Compounds uploaded successfully.'
            }
        else:
            ajaxResponse = {
                'success': False,
                'message': 'An error occurred while uploading your compounds.'
            }
        return ajaxResponse
    else:
        raise Exception('Unknown source_id: {}'.format(source_id))
Example #4
0
def uploadCompound(request, resource = None, job_id = None):
    allTags = Tag.allUserTagNames(request.user)


    if (request.method == 'GET') and (resource != u'job'):
        return render(request,'addCompounds.html',
                                  dict(input_mode='smiles-input',
                                      tags=allTags))
    else:
        sdf = None
        name = None
        compid = None
        smiles = None
        compoundTags = []
        input_mode='smiles-input'

        if 'tags' in request.POST:

            compoundTags = set(request.POST.getlist('tags'))

            Tag.ensureAllExist(compoundTags,request.user)

            #existingTags = set(allTags)
            #print("compound tags: "+str(compoundTags))

            #for newTag in compoundTags.difference(existingTags):
            #    print("creating new tag: "+newTag+" for user "+request.user.username)
            #    Tag.objects.create(name = newTag, user=request.user)


        if 'smiles' in request.POST:
            input_mode = 'smiles-input'
            sdf = u''
            try:
                smiles = request.POST['smiles'].split('\n')
                for line in smiles:
                    if re.match(r"^\S+", line):
                        sdf = sdf + smiles_to_sdf(str(line))
            except:
                print("Unexpected error:", sys.exc_info())
                traceback.print_tb(sys.exc_info()[2])
                messages.error(request, 'Error: Invalid SMILES string!')
                sdf = None
        elif resource == 'job':
            input_mode = 'sdf-upload'
            job = updateJob(request.user, job_id)
            f = open(job.output, 'r')
            sdf = f.read()
            f.close()
        elif 'sdf' in request.FILES:
            input_mode = 'sdf-upload'
            try:
                sdf = request.FILES['sdf']
                sdf = sdf.read().decode("utf-8")
            except (InputError, InvalidInputError):
                messages.error(request, 'Invalid SDF!')
                sdf = None
        elif 'sdf' in request.POST:
            if 'draw' in request.POST:
                input_mode = 'draw'
                sdf = request.POST['sdf'] + '$$$$'
                compid = str(request.POST['id'])
                compid = re.match(r"^(\S{0,20})", compid).group(1)
                try:
                    smiles = sdf_to_smiles(sdf)
                    smiles = re.match(r"^(\S+)", smiles).group(1)
                    smiles = smiles + ' ' + compid
                    sdf = smiles_to_sdf(smiles)
                except:
                    print("Unexpected error:", sys.exc_info())
                    traceback.print_tb(sys.exc_info()[2])
                    messages.error(request, 'Invalid drawing!')
                    sdf = None
            else:
                input_mode = 'sdf-input'
                sdf = request.POST['sdf']
                if not sdf:
                    messages.error(request, 'No input found!')
        elif 'pubchem' in request.POST:
            cids = request.POST['pubchem']
            cids = cids.split()
            input_mode = 'pubchem'
            filteredCIDs = []
            for cid in cids[:]:
                match = re.search("(\d{1,200})", cid)
                if match:
                    filteredCIDs.append(int(match.group(1)))

            if len(filteredCIDs) > 0:
                try:
                    sdf = DownloadCIDs(cids)
                except:
                    print("Unexpected error:", sys.exc_info())
                    traceback.print_tb(sys.exc_info()[2])
                    messages.error(request,
                                   'Invalid CIDs or no response from PubChem!'
                                   )
                    sdf = None
            else:
                messages.error(request, 'Error: No valid CIDs entered!')
                sdf = None
        elif 'chembl' in request.POST:
            cids = tuple(request.POST['chembl'].split())

            if len(cids) > 0:
                try:
                    sdfs = get_chembl_sdfs(cids)
                    sdf = "\n$$$$\n".join(sdfs)+"\n$$$$\n"
                except:
                    print("Unexpected error:", sys.exc_info())
                    traceback.print_tb(sys.exc_info()[2])
                    messages.error(request,
                                   'Invalid CIDs or no response from ChEMBL!'
                                   )
                    sdf = None
            else:
                print("no chembl cids given")
                messages.error(request, 'Error: No valid ChEMBL CIDs entered!')
                sdf = None


        if not sdf:
            return render('addCompounds.html',
                    dict(input_mode=input_mode,
                    post_data=request.POST,
                    tags=compoundTags))
        jobArgs = ['--user='******'dedup' in request.POST:
            jobArgs += ["--deduplicate"]
        newJob = createJob(request.user, 'Upload Compounds', '',jobArgs , sdf)
        time.sleep(2)
        return redirect(tools.views.view_job, job_id=newJob.id,
                        resource='')