Beispiel #1
0
def clear_annotations(request,rid,report=None):
    '''clear all annotations for a specific report and user'''

    if report == None:
        report = get_report(rid)

    # Right now, only owners allowed to contribute
    annotate_permission = has_collection_annotate_permission(request,report.collection)
    if annotate_permission:

        if request.method == 'POST':
            try:
                clear_user_annotations(request.user,report)
                response_data = {'result':'Annotations successfully cleared'}
            except:
                response_data = {'result':'Error clearing annotations.'}

            return JsonResponse(response_data)

        else:
            return JsonResponse({"have you ever seen...": "a radiologist rigatoni?"})

    else:
        context = {"message":"You are not authorized to perform this action"}
        return render(request, "messages/not_authorized.html", context)
Beispiel #2
0
def delete_report(request,rid):
    report = get_report(rid)
    collection = report.collection
    if request.user == collection.owner:
        report.delete()
    else:
        messages.warning(request, "You are not authorized to perform this operation.")
    return HttpResponseRedirect(collection.get_absolute_url())
Beispiel #3
0
def view_report(request,rid):
    report = get_report(rid)
    #TODO: In the future if we ever want to allow counting across collection, this needs to change
    annotation_counts = get_annotation_counts(report.collection,reports=[report])
    context = {"report":report,
               "annotation_counts":annotation_counts,
               "collection":report.collection}

    # Get all permissions, context must have collection as key
    context = get_permissions(request,context)

    return render(request, 'reports/report_details.html', context)
Beispiel #4
0
def annotate_report_testing(request,rid,sid=None,report=None,next=None,allowed_annotations=None):
    '''annotate_report_testing is the view to return a report annotation interface to test an id
    :param sid: a report set id, if coming from annotate_random with a report set
    :param report_set: a report set.
    :param next: the next page to show (annotate/reports/{{ collection.id }}/{{ next }}
    :param allowed_annotations: a custom set of allowed annotations to use. If not provided,
    the entire set of a collection is used.
    '''
    if report == None:
        report = get_report(rid)
    collection = report.collection

    context = {"collection":collection,
               "report":report}

    if sid != None:
        next = "%s/set" %(sid)
        context['sid'] = sid

    # If next is None, return random
    elif next == None:
        next = "%s/random" %(collection.id)

    # If it's not None, we still need to add collection id
    else:
        next = "%s/%s" %(collection.id,next)

    # Next url will direct to either set, or random
    context['next'] = next

    # Get the concise annotations
    annotations = get_annotations(user=request.user, report=report)
    annotations = summarize_annotations(annotations)
    if "labels" in annotations:
        context["annotations"] = annotations['labels']
    if "counts" in annotations:
        context["counts"] = annotations['counts']

    # Get the allowed_annotations, and organize them into a lookup dictionary with key:options
    if allowed_annotations == None:
        allowed_annotations = report.collection.allowed_annotations.all()
    context["allowed_annotations"] = group_allowed_annotations(allowed_annotations)

    # Format markup
    context["markup"] = ["%s" %(x) for x in report.collection.markup.split(",")]  

    # Get all permissions, context must have collection as key
    context = get_permissions(request,context)

    return render(request, "annotate/testing_random.html", context)
Beispiel #5
0
def update_annotation(request,rid,report=None):
    '''update_annotation is the view to update an annotation when it changes. It should return a JSON response.
    '''
    if report == None:
        report = get_report(rid)

    # Does the user have permission to annotate the collection?
    annotate_permission = has_collection_annotate_permission(request,report.collection)
    if annotate_permission:

        if request.method == 'POST':
            try:
                new_annotations = json.loads(request.POST.get('annotations'))
            
            except:
                return JsonResponse({"error": "error parsing array!"})

            # Update the annotations
            for new_annotation in new_annotations:
                if new_annotation['value'] == "on":
                    aname,alabel = new_annotation['name'].split('||')
                    annotation_object = AllowedAnnotation.objects.get(name=aname,
                                                                      label=alabel)
                    annot = update_user_annotation(user=request.user,
                                                   allowed_annotation=annotation_object,
                                                   report=report)

            response_data = {'result':'Create post successful!'}

            return JsonResponse(response_data)

        else:
            return JsonResponse({"have you ever seen...": "a radiologist ravioli?"})

    else:
        context = {"message":"You are not authorized to annotate this collection."}
        return render(request, "messages/not_authorized.html", context)
Beispiel #6
0
 def get_object(self, report_id):
     report = get_report(report_id)
     if report != None:
         return report
     else:
         return Http404
Beispiel #7
0
def test_annotator(request, sid, rid=None):
    '''test_annotator will ask an annotator to answer the specified number of
    questions to be granted access to annotate a collection. The data is stored
    in a session, and the session expires (and is reset) when the user has viewed
    the total number of required questions
    :param sid: the id of the report set
    :param rid: the report id that was tested
    '''
    from whatisit.apps.wordfish.views import (annotate_report_testing,
                                              annotate_set, get_permissions,
                                              view_report_collection)
    from whatisit.apps.users.models import Credential

    if rid != None:  # scoring is needed
        completed_report = get_report(rid)

    user = request.user

    report_set = get_report_set(sid)
    context = {'collection': report_set.collection}
    permissions = get_permissions(request, context)

    # Double check that user has permission to annotate
    if permissions["annotate_permission"] == True:

        # Also check that user hasn't previously failed.
        credential = Credential.objects.get(user=user, report_set=report_set)

        # Double check user status
        user_status = get_annotation_status(report_set=report_set, user=user)

        # Only continue if user_status is TESTING
        if user_status == "TESTING":

            # Get session variable
            session = get_testing_session(user=user, report_set=report_set)
            session_key = 'reports_testing_%s' % (session.id)

            # testing set is stored in request.session with corresponding id
            testing_set = request.session.get(session_key, None)
            testing_report = None
            testing_correct = session.correct
            testing_incorrect = session.incorrect

            # Total reports required for taking, and for passing
            N = report_set.number_tests
            N_pass = report_set.passing_tests

            ###########################################################
            # NEW TESTING SESSION
            ###########################################################
            if testing_set == None:
                messages.info(
                    request,
                    '''This is the start of the test. You will be asked to annotate %s reports.
                                       You should click on the correct label below, and then you can 
                                       use your right arrow key (or the arrow at the bottom) to submit your answer.
                                       ''' % (N))

                # Randomly select N reports from the set
                testing_reports = select_random_reports(
                    reports=report_set.reports.all(), N=N)
                testing_reports = list(testing_reports)

                # Remove the first for testing
                testing_report = testing_reports.pop(0)
                request.session[session_key] = testing_reports

            ###########################################################
            # RESUME TESTING SESSION
            ###########################################################
            else:
                # If the testing set session is not empty, get any updated answers
                if request.method == "POST":

                    # Get the correct annotations from the database
                    correct_annotations = get_annotations(
                        user=report_set.gold_standard, report=completed_report)
                    answers = summarize_annotations(
                        correct_annotations)['labels']

                    post_keys = list(request.POST.keys())
                    for post_key in post_keys:
                        # The annotation labels have a '||'
                        if re.search('[||]', post_key):
                            new_annotation = request.POST[post_key]
                            user_selected = False
                            if new_annotation == "on":
                                selected_name, selected_label = post_key.split(
                                    '||')
                                user_selected = True

                            # If we have an answer
                            option_chosen = ''
                            if selected_name in answers:
                                correct_answer = answers[selected_name]

                                # The user selected the right answer
                                if user_selected and correct_answer == selected_label:
                                    testing_correct += 1

                                # The user selected, but not right answer
                                elif user_selected and correct_answer != selected_label:
                                    testing_incorrect += 1

                                # The user didn't select, is right answer
                                elif not user_selected and correct_answer == selected_label:
                                    testing_incorrect += 1

                                # The user didn't select, is not right answer
                                elif not user_selected and correct_answer != selected_label:
                                    continue

                    # If the total number tests (correct and incorrect)
                    if len(testing_set) == 0:

                        # Did the user pass?
                        if testing_correct >= N_pass:
                            user_status = credential.status = "PASSED"
                        else:
                            user_status = credential.status = "DENIED"
                        credential.save()

                    # Update the counts
                    session.correct = testing_correct
                    session.incorrect = testing_incorrect
                    session.save()

        # If user status is (still) TESTING, start or continue
        if user_status == "TESTING":

            # If we didn't select a testing report
            if testing_report == None:
                testing_report = testing_set.pop(0)
                request.session[session_key] = testing_set

            # Update the user with remaining reports
            remaining_tests = N - (testing_correct + testing_incorrect)
            messages.info(
                request, 'You have %s reports remaining in this session' %
                (remaining_tests))

            # Get allowed annotations for set
            testing_annotations = get_testing_annotations(report_set)

            # Start testing the user
            return annotate_report_testing(
                request=request,
                rid=testing_report.id,
                sid=report_set.id,
                report=testing_report,
                allowed_annotations=testing_annotations)

        # If the user status was approved, either previously or aboved, move on to annotation
        elif user_status == "PASSED":
            messages.info(
                request,
                "Congratulations, you have passed the testing! You are now annotating the collection set."
            )
            request = delete_testing_session(
                request, session)  # deletes session, sets reports to None
            # Add the user to the set
            if request.user not in report_set.annotators.all():
                report_set.annotators.add(request.user)
                report_set.save()
            return annotate_set(request, report_set.id)

        elif user_status == "DENIED":
            messages.info(request,
                          "You are not qualified to annotate this set.")
            session = get_testing_session(user=user, report_set=report_set)
            request = delete_testing_session(
                request, session)  # deletes session, sets reports to None
            return view_report_collection(request, report_set.collection.id)

    # User does not have permission to annotate, return to collection view
    else:
        messages.info(
            request, "You do not have permissions to perform this operation.")

    # Denied, or not annotate permission returns to see collection
    return view_report_collection(request, report_set.collection.id)
Beispiel #8
0
def annotate_report(request,rid,sid=None,report=None,next=None,template=None,
                    allowed_annotations=None,show_count=True):
    '''annotate_report is the view to return a report annotation interface for a particular report id
    :param rid: report id to annotate
    :param sid: a report set id, if coming from annotate_random with a report set
    :param report_set: a report set.
    :param show_count: if true, will show the user the total reports annotated
    :param next: the next page to show (annotate/reports/{{ collection.id }}/{{ next }}
    :param template: an optional template, if not provided, default is used
    :param allowed_annotations: a custom set of allowed annotations to use. If not provided,
    the entire set of a collection is used.
    '''
    if report == None:
        report = get_report(rid)
    collection = report.collection

    if template == None:
        template = "annotate/annotate_random.html"

    context = {"collection":collection,
               "report":report}

    if sid != None:
        next = "%s/set" %(sid)
        context['sid'] = sid

    # If next is None, return random
    elif next == None:
        next = "%s/random" %(collection.id)

    # If it's not None, we still need to add collection id
    else:
        next = "%s/%s" %(collection.id,next)

    # Tell the user how many annotated / remaining
    if show_count == True:
        remaining_message = count_remaining_reports(user=request.user,
                                                    collection=collection,
                                                    sid=sid,
                                                    return_message=True)
        messages.info(request,remaining_message)


    # Next url will direct to either set, or random
    context['next'] = next

    # Get the concise annotations
    annotations = get_annotations(user=request.user, report=report)
    annotations = summarize_annotations(annotations)
    if "labels" in annotations:
        context["annotations"] = annotations['labels']
    if "counts" in annotations:
        context["counts"] = annotations['counts']

    # Get the allowed_annotations, and organize them into a lookup dictionary with key:options
    if allowed_annotations == None:
        allowed_annotations = report.collection.allowed_annotations.all()
    context["allowed_annotations"] = group_allowed_annotations(allowed_annotations)

    # Format markup
    context["markup"] = ["%s" %(x) for x in report.collection.markup.split(",")]  

    # Get all permissions, context must have collection as key
    context = get_permissions(request,context)

    return render(request, template, context)