From 63c92f8ddbebcc1711365fda27e8b4a92c4cfa4b Mon Sep 17 00:00:00 2001 From: "J.-S. Caux" <J.S.Caux@uva.nl> Date: Sat, 27 Jan 2018 08:39:37 +0100 Subject: [PATCH] Add tiered-level stats --- journals/models.py | 49 ++++++- stats/templates/stats/statistics.html | 182 ++++++++++++++++---------- stats/templatetags/stats_extras.py | 67 +++------- 3 files changed, 176 insertions(+), 122 deletions(-) diff --git a/journals/models.py b/journals/models.py index 0d30f3a42..0f833006d 100644 --- a/journals/models.py +++ b/journals/models.py @@ -51,11 +51,26 @@ class Journal(models.Model): def get_abbreviation_citation(self): return journal_name_abbrev_citation(self.name) - def citation_rate(self): + def nr_publications(self, Tier=None): + pubs = Publication.objects.filter(in_issue__in_volume__in_journal=self) + if Tier: + pubs.filter(accepted_submission__eicrecommendations__recommendation=Tier) + return pubs.count() + + def avg_processing_duration(self): + duration = Publication.objects.filter( + in_issue__in_volume__in_journal=self).aggregate( + avg=Avg(F('publication_date') - F('submission_date')))['avg'] + if not duration: return 0 + return duration.days + duration.seconds/86400 + + def citation_rate(self, Tier=None): """ Returns the citation rate in units of nr citations per article per year. """ pubs = Publication.objects.filter(in_issue__in_volume__in_journal=self) + if Tier: + pubs.filter(accepted_submission__eicrecommendations__recommendation=Tier) ncites = 0 deltat = 1 # to avoid division by zero for pub in pubs: @@ -83,11 +98,26 @@ class Volume(models.Model): def doi_string(self): return '10.21468/' + self.doi_label + def nr_publications(self, Tier=None): + pubs = Publication.objects.filter(in_issue__in_volume=self) + if Tier: + pubs.filter(accepted_submission__eicrecommendations__recommendation=Tier) + return pubs.count() + + def avg_processing_duration(self): + duration = Publication.objects.filter( + in_issue__in_volume=self).aggregate( + avg=Avg(F('publication_date') - F('submission_date')))['avg'] + if not duration: return 0 + return duration.days + duration.seconds/86400 + def citation_rate(self): """ Returns the citation rate in units of nr citations per article per year. """ pubs = Publication.objects.filter(in_issue__in_volume=self) + if Tier: + pubs.filter(accepted_submission__eicrecommendations__recommendation=Tier) ncites = 0 deltat = 1 # to avoid division by zero for pub in pubs: @@ -147,11 +177,26 @@ class Issue(models.Model): return self.start_date <= timezone.now().date() and\ self.until_date >= timezone.now().date() - def citation_rate(self): + def nr_publications(self, Tier=None): + pubs = Publication.objects.filter(in_issue=self) + if Tier: + pubs.filter(accepted_submission__eicrecommendations__recommendation=Tier) + return pubs.count() + + def avg_processing_duration(self): + duration = Publication.objects.filter( + in_issue=self).aggregate( + avg=Avg(F('publication_date') - F('submission_date')))['avg'] + if not duration: return 0 + return duration.days + duration.seconds/86400 + + def citation_rate(self, Tier=None): """ Returns the citation rate in units of nr citations per article per year. """ pubs = Publication.objects.filter(in_issue=self) + if Tier: + pubs.filter(accepted_submission__eicrecommendations__recommendation=Tier) ncites = 0 deltat = 1 # to avoid division by zero for pub in pubs: diff --git a/stats/templates/stats/statistics.html b/stats/templates/stats/statistics.html index 61fa1a21d..3f02a3981 100644 --- a/stats/templates/stats/statistics.html +++ b/stats/templates/stats/statistics.html @@ -41,78 +41,122 @@ </ul> {% if journal %} - <h2>Results:</h2> - <table class="table"> - <tr> - <th>DOI label</th> - {% if year %} - <th>Year</th> - <th>Nr submissions<br/>(distinct)</th> - <th>Nr submissions<br/>(including resubmissions)</th> - <th>Nr assignment failed</th> - <th>Nr accepted/<br/>published</th> - <th>Nr rejected</th> - <th>Nr withdrawn</th> - {% else %} - <th>Nr publications</th> - <th>Duration average</th> - <th>Citation rate (per paper per year)</ht> - {% endif %} - </tr> - <tr> - {% if issue %} - <td>{{ issue.doi_label }}</td> - <td>{{ issue|issue_nr_publications }}</td> - <td>{{ issue|issue_avg_processing_duration|floatformat:2 }} days</td> - <td>{{ issue|issue_citation_rate|floatformat:2 }}</td> - {% elif volume %} - <td>{{ volume.doi_label }}</td> - <td>{{ volume|volume_nr_publications }}</td> - <td>{{ volume|volume_avg_processing_duration|floatformat:2 }} days</td> - <td>{{ volume|volume_citation_rate|floatformat:2 }}</td> - {% else %} - <td>{{ journal.doi_label }}</td> - {% if year %} - <td>{{ year }}</td> - <td>{{ submissions|submissions_count_distinct }}</td> - <td>{{ submissions|length }}</td> - <td>{{ submissions.assignment_failed.count }}</td> - <td>{{ submissions.accepted.count|add:submissions.published.count }}</td> - <td>{{ submissions.rejected.count }}</td> - <td>{{ submissions.withdrawn.count }}</td> - {% else %} - <td>{{ journal|journal_nr_publications }}</td> - <td>{{ journal|journal_avg_processing_duration|floatformat:2 }} days</td> - <td>{{ journal|journal_citation_rate|floatformat:2 }}</td> - {% endif %} - {% endif %} - </tr> - </table> +<h2>Results:</h2> +<table class="table"> + <tr> + <th>DOI label</th> + {% if year %} + <th>Year</th> + <th>Nr submissions<br/>(distinct)</th> + <th>Nr submissions<br/>(including resubmissions)</th> + <th>Nr assignment failed</th> + <th>Nr accepted/<br/>published</th> + <th>Nr rejected</th> + <th>Nr withdrawn</th> + {% else %} + <th>Nr publications</th> + <th>Duration average</th> + <th>Citation rate (per paper per year)</th> {% endif %} - + </tr> + <tr> + {% if issue %} + <td>{{ issue.doi_label }}</td> + <td>{% nr_publications issue %}</td> + <td>{% avg_processing_duration issue as avg %}{{ avg|floatformat:2 }} days</td> + <td>{% citation_rate issue as cr %}{{ cr|floatformat:2 %}</td> + {% elif volume %} + <td>{{ volume.doi_label }}</td> + <td>{% nr_publications volume %}</td> + <td>{% avg_processing_duration volume as avg %}{{ avg|floatformat:2 }} days</td> + <td>{% citation_rate volume as cr %}{{ cr|floatformat:2 }}</td> + {% else %} + <td>{{ journal.doi_label }}</td> {% if year %} - <h2>Refereeing stats for {{ year }}</h2> - <table class="table"> - <tr> - <th>Nr refereeing<br/>invitations</th> - <th>Nr accepted</th> - <th>Nr declined</th> - <th>Nr pending</th> - <th>Nr reports<br/>obtained</th> - <th>Nr obtained<br/>(invited)</th> - <th>Nr obtained<br/>(contributed)</th> - </tr> - <tr> - <td>{{ nr_ref_inv }}</td> - <td>{{ nr_acc }} ({% widthratio nr_acc nr_ref_inv 100 %}%)</td> - <td>{{ nr_dec }} ({% widthratio nr_dec nr_ref_inv 100 %}%)</td> - <td>{{ nr_pen }} ({% widthratio nr_pen nr_ref_inv 100 %}%)</td> - <td>{{ nr_rep_obt }}</td> - <td>{{ nr_rep_obt_inv }} ({% widthratio nr_rep_obt_inv nr_rep_obt 100 %}%)</td> - <td>{{ nr_rep_obt_con }} ({% widthratio nr_rep_obt_con nr_rep_obt 100 %}%)</td> - </tr> - </table> + <td>{{ year }}</td> + <td>{{ submissions|submissions_count_distinct }}</td> + <td>{{ submissions|length }}</td> + <td>{{ submissions.assignment_failed.count }}</td> + <td>{{ submissions.accepted.count|add:submissions.published.count }}</td> + <td>{{ submissions.rejected.count }}</td> + <td>{{ submissions.withdrawn.count }}</td> + {% else %} + <td>{% nr_publications journal %}</td> + <td>{% avg_processing_duration journal as avg %}{{ avg|floatformat:2 }} days</td> + <td>{% citation_rate journal as cr %}{{ cr|floatformat:2 }}</td> + {% endif %} {% endif %} + </tr> +</table> + +<table class="table"> + <tr> + <th>DOI label</th> + <th colspan="3">Nr per Tier</th> + <th colspan="3">Citation rate (per paper per year)</th> + </tr> + <tr> + <th></th> + <th>I</th> + <th>II</th> + <th>IIII</th> + <th>I</th> + <th>II</th> + <th>IIII</th> + </tr> + <tr> + {% if issue %} + <td>{% issue.doi_label }}</td> + <td>{% nr_publications issue Tier=1 %}</td> + <td>{% nr_publications issue Tier=2 %}</td> + <td>{% nr_publications issue Tier=3 %}</td> + <td>{% citation_rate issue Tier=1 as cr %}{{ cr|floatformat:2 }}</td> + <td>{% citation_rate issue Tier=2 as cr %}{{ cr|floatformat:2 }}</td> + <td>{% citation_rate issue Tier=3 as cr %}{{ cr|floatformat:2 }}</td> + {% elif volume %} + <td>{{ volume.doi_label }}</td> + <td>{% nr_publications volume Tier=1 %}</td> + <td>{% nr_publications volume Tier=2 %}</td> + <td>{% nr_publications volume Tier=3 %}</td> + <td>{% citation_rate volume Tier=1 as cr %}{{ cr|floatformat:2 }}</td> + <td>{% citation_rate volume Tier=2 as cr %}{{ cr|floatformat:2 }}</td> + <td>{% citation_rate volume Tier=3 as cr %}{{ cr|floatformat:2 }}</td> + {% else %} + <td>{{ journal.doi_label }}</td> + <td>{% nr_publications journal Tier=1 %}</td> + <td>{% nr_publications journal Tier=2 %}</td> + <td>{% nr_publications journal Tier=3 %}</td> + <td>{% citation_rate journal Tier=1 as cr %}{{ cr|floatformat:2 }}</td> + <td>{% citation_rate journal Tier=2 as cr %}{{ cr|floatformat:2 }}</td> + <td>{% citation_rate journal Tier=3 as cr %}{{ cr|floatformat:2 }}</td> + {% endif %} + </tr> +</table> +{% endif %} + +{% if year %} +<h2>Refereeing stats for {{ year }}</h2> +<table class="table"> + <tr> + <th>Nr refereeing<br/>invitations</th> + <th>Nr accepted</th> + <th>Nr declined</th> + <th>Nr pending</th> + <th>Nr reports<br/>obtained</th> + <th>Nr obtained<br/>(invited)</th> + <th>Nr obtained<br/>(contributed)</th> + </tr> + <tr> + <td>{{ nr_ref_inv }}</td> + <td>{{ nr_acc }} ({% widthratio nr_acc nr_ref_inv 100 %}%)</td> + <td>{{ nr_dec }} ({% widthratio nr_dec nr_ref_inv 100 %}%)</td> + <td>{{ nr_pen }} ({% widthratio nr_pen nr_ref_inv 100 %}%)</td> + <td>{{ nr_rep_obt }}</td> + <td>{{ nr_rep_obt_inv }} ({% widthratio nr_rep_obt_inv nr_rep_obt 100 %}%)</td> + <td>{{ nr_rep_obt_con }} ({% widthratio nr_rep_obt_con nr_rep_obt 100 %}%)</td> + </tr> +</table> +{% endif %} {% endblock content %} diff --git a/stats/templatetags/stats_extras.py b/stats/templatetags/stats_extras.py index d63622554..fb0b8cdf2 100644 --- a/stats/templatetags/stats_extras.py +++ b/stats/templatetags/stats_extras.py @@ -9,6 +9,22 @@ register = template.Library() +@register.simple_tag +def avg_processing_duration(obj, *args, **kwargs): + method = getattr(obj, avg_processing_duration) + return method(*args, **kwargs) + +@register.simple_tag +def nr_publications(obj, *args, **kwargs): + method = getattr(obj, nr_publications) + return method(*args, **kwargs) + +@register.simple_tag +def citation_rate(obj, *args, **kwargs): + method = getattr(obj, citation_rate) + return method(*args, **kwargs) + + @register.filter(name='submissions_count_distinct') def submissions_count_distinct(submissions): identifiers_wo_vn_nr = [] @@ -25,54 +41,3 @@ def journal_publication_years(journal): if volume.until_date.year not in years: years.append(volume.until_date.year) return sorted(years) - - -@register.filter(name='journal_nr_publications') -def journal_nr_publications(journal): - return Publication.objects.filter(in_issue__in_volume__in_journal=journal).count() - -@register.filter(name='journal_avg_processing_duration') -def journal_avg_processing_duration(journal): - duration = Publication.objects.filter( - in_issue__in_volume__in_journal=journal).aggregate( - avg=Avg(F('publication_date') - F('submission_date')))['avg'] - if not duration: return 0 - return duration.days + duration.seconds/86400 - -@register.filter(name='journal_citation_rate') -def journal_citation_rate(journal): - return journal.citation_rate() - - -@register.filter(name='volume_nr_publications') -def volume_nr_publications(volume): - return Publication.objects.filter(in_issue__in_volume=volume).count() - -@register.filter(name='volume_avg_processing_duration') -def volume_avg_processing_duration(volume): - duration = Publication.objects.filter( - in_issue__in_volume=volume).aggregate( - avg=Avg(F('publication_date') - F('submission_date')))['avg'] - if not duration: return 0 - return duration.days + duration.seconds/86400 - -@register.filter(name='volume_citation_rate') -def volume_citation_rate(volume): - return volume.citation_rate() - - -@register.filter(name='issue_nr_publications') -def issue_nr_publications(issue): - return Publication.objects.filter(in_issue=issue).count() - -@register.filter(name='issue_avg_processing_duration') -def issue_avg_processing_duration(issue): - duration = Publication.objects.filter( - in_issue=issue).aggregate( - avg=Avg(F('publication_date') - F('submission_date')))['avg'] - if not duration: return 0 - return duration.days + duration.seconds/86400 - -@register.filter(name='issue_citation_rate') -def issue_citation_rate(issue): - return issue.citation_rate() -- GitLab