Skip to content

Commit

Permalink
Merge pull request #67 from LCOGT/feature/update-scicollab-alloc
Browse files Browse the repository at this point in the history
Feature/update scicollab alloc
  • Loading branch information
eheinrich committed Aug 16, 2019
2 parents 27abe49 + 3266dea commit 3329902
Show file tree
Hide file tree
Showing 10 changed files with 152 additions and 57 deletions.
34 changes: 24 additions & 10 deletions observation_portal/common/configdb.py
Expand Up @@ -128,6 +128,14 @@ def get_telescope_class_tuples(self):
telescope_classes.add(telescope['code'][:-1])
return [(telescope_class, telescope_class) for telescope_class in telescope_classes]

def get_telescope_name_tuples(self):
telescope_names = set()
for site in self.get_site_data():
for enclosure in site['enclosure_set']:
for telescope in enclosure['telescope_set']:
telescope_names.add(telescope['name'].strip().lower())
return [(telescope_name, telescope_name) for telescope_name in telescope_names]

def get_instrument_type_tuples(self):
instrument_types = set()
for site in self.get_site_data():
Expand All @@ -153,6 +161,14 @@ def get_configuration_type_tuples(self):
configuration_types.add(config_type.upper())
return [(config_type, config_type) for config_type in configuration_types]

def get_raw_telescope_name(self, telescope_name):
for site in self.get_site_data():
for enclosure in site['enclosure_set']:
for telescope in enclosure['telescope_set']:
if telescope['name'].strip().lower() == telescope_name.strip().lower():
return telescope['name'].strip()
return telescope_name

def get_instruments_at_location(self, site_code, enclosure_code, telescope_code, only_schedulable=False):
instrument_names = set()
instrument_types = set()
Expand Down Expand Up @@ -238,8 +254,8 @@ def get_instruments(self, exclude_states=None):
telescope=telescope['code']
)
instrument['telescope_key'] = telescope_key
instrument['telescope_name'] = telescope['name'].strip().lower()
instruments.append(instrument)

return instruments

def get_instrument_types_per_telescope(self, only_schedulable: bool = False) -> dict:
Expand Down Expand Up @@ -285,23 +301,21 @@ def get_instrument_names(
instrument_names.add(instrument['science_camera']['code'].lower())
return instrument_names

def get_instrument_types_per_telescope_class(self, exclude_states=None) -> dict:
def get_instrument_types_per_telescope_name(self, exclude_states=None) -> dict:
"""Get a set of instrument types.
Instrument types are returned by telescope class (0m4, 1m0, etc...)
Instrument types are returned by telescope name (1 meter, 2 meter, etc...)
Parameters:
only_schedulable: Whether to only include schedulable telescopes
exclude_states: Instrument states to exclude
Returns:
Instrument types separated by class
"""
telescope_instrument_types = {}
telescope_instrument_names = defaultdict(set)
for instrument in self.get_instruments(exclude_states=exclude_states):
tel_code = instrument['telescope_key'].telescope[:3]
if tel_code not in telescope_instrument_types:
telescope_instrument_types[tel_code] = set()
telescope_instrument_types[tel_code].add(instrument['science_camera']['camera_type']['code'].upper())
return telescope_instrument_types
tel_name = instrument['telescope_name']
telescope_instrument_names[tel_name].add(instrument['science_camera']['camera_type']['code'].upper())
return telescope_instrument_names

def get_telescopes_per_instrument_type(self, instrument_type: str, only_schedulable: bool = False) -> set:
"""Get a set of telescope keys.
Expand Down
5 changes: 5 additions & 0 deletions observation_portal/common/test_data/configdb.json
Expand Up @@ -12,6 +12,7 @@
"telescope_set": [
{
"code": "1m0a",
"name": "1 Meter",
"lat": -32.3805542,
"long": 20.8100352,
"horizon": 15.0,
Expand Down Expand Up @@ -399,6 +400,7 @@
},
{
"code": "2m0a",
"name": "2 Meter",
"lat": -32.3805542,
"long": 20.8100352,
"horizon": 15.0,
Expand Down Expand Up @@ -560,6 +562,7 @@
"telescope_set": [
{
"code": "1m0a",
"name": "1 Meter",
"lat": -32.3805542,
"long": 20.8100352,
"horizon": 15.0,
Expand Down Expand Up @@ -808,6 +811,7 @@
},
{
"code": "2m0a",
"name": "2 Meter",
"lat": -32.3805542,
"long": 20.8100352,
"horizon": 15.0,
Expand Down Expand Up @@ -974,6 +978,7 @@
"telescope_set": [
{
"code": "1m0a",
"name": "1 Meter",
"lat": -32.3805542,
"long": 20.8100352,
"horizon": 15.0,
Expand Down
11 changes: 9 additions & 2 deletions observation_portal/proposals/admin.py
@@ -1,11 +1,12 @@
# -*- coding: utf-8 -*-
from django.contrib import admin

from observation_portal.proposals.forms import TimeAllocationForm
from observation_portal.proposals.forms import TimeAllocationForm, CollaborationAllocationForm

from observation_portal.proposals.models import (
Semester,
ScienceCollaborationAllocation,
CollaborationAllocation,
Proposal,
TimeAllocation,
Membership,
Expand All @@ -20,9 +21,16 @@ class SemesterAdmin(admin.ModelAdmin):
raw_id_fields = ('proposals',)


class CollaborationAllocationAdminInline(admin.TabularInline):
model = CollaborationAllocation
form = CollaborationAllocationForm
extra = 0


class ScienceCollaborationAllocationAdmin(admin.ModelAdmin):
list_display = ('id', 'name')
raw_id_fields = ['admin']
inlines = [CollaborationAllocationAdminInline]

def get_readonly_fields(self, request, obj=None):
if obj:
Expand All @@ -49,7 +57,6 @@ class ProposalAdmin(admin.ModelAdmin):
'created',
'modified'
)

list_filter = ('active', 'sca', 'public')
raw_id_fields = ('users',)
inlines = [TimeAllocationAdminInline]
Expand Down
14 changes: 12 additions & 2 deletions observation_portal/proposals/forms.py
@@ -1,12 +1,23 @@
from django import forms

from observation_portal.common.configdb import configdb
from observation_portal.proposals.models import TimeAllocation
from observation_portal.proposals.models import TimeAllocation, CollaborationAllocation


class ProposalNotificationForm(forms.Form):
notifications_enabled = forms.BooleanField(required=False)


class CollaborationAllocationForm(forms.ModelForm):
class Meta:
model = CollaborationAllocation
fields = '__all__'

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['telescope_name'] = forms.ChoiceField(choices=configdb.get_telescope_name_tuples())


class TimeAllocationForm(forms.ModelForm):
class Meta:
model = TimeAllocation
Expand All @@ -15,4 +26,3 @@ class Meta:
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['instrument_type'] = forms.ChoiceField(choices=configdb.get_instrument_type_tuples())

35 changes: 35 additions & 0 deletions observation_portal/proposals/migrations/0002_auto_20190815_1942.py
@@ -0,0 +1,35 @@
# Generated by Django 2.2.2 on 2019-08-15 19:42

from django.db import migrations, models
import django.db.models.deletion


class Migration(migrations.Migration):

dependencies = [
('proposals', '0001_initial'),
]

operations = [
migrations.RemoveField(
model_name='sciencecollaborationallocation',
name='four_meter_alloc',
),
migrations.RemoveField(
model_name='sciencecollaborationallocation',
name='one_meter_alloc',
),
migrations.RemoveField(
model_name='sciencecollaborationallocation',
name='two_meter_alloc',
),
migrations.CreateModel(
name='CollaborationAllocation',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('telescope_name', models.CharField(max_length=255)),
('allocation', models.FloatField(default=0)),
('sca', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='proposals.ScienceCollaborationAllocation')),
],
),
]
22 changes: 11 additions & 11 deletions observation_portal/proposals/models.py
Expand Up @@ -40,28 +40,28 @@ class ScienceCollaborationAllocation(models.Model):
id = models.CharField(max_length=20, primary_key=True)
name = models.CharField(max_length=255, blank=True, default='')
admin = models.OneToOneField(User, null=True, blank=True, on_delete=models.SET_NULL)
# TODO: Replace these allocations with something else
one_meter_alloc = models.PositiveIntegerField(default=0, blank=True)
two_meter_alloc = models.PositiveIntegerField(default=0, blank=True)
four_meter_alloc = models.PositiveIntegerField(verbose_name='0.4 Meter Alloc', default=0, blank=True)

def __str__(self):
return self.id

def time_requested_for_semester(self, semester):
allocs = {
'1m0': 0,
'2m0': 0,
'0m4': 0
}
allocs = {ca.telescope_name: 0 for ca in self.collaborationallocation_set.all()}
for sciapp in self.admin.scienceapplication_set.filter(call__semester=semester, call__proposal_type='COLAB'):
for k, v in sciapp.time_requested_by_class.items():
for k, v in sciapp.time_requested_by_telescope_name.items():
if k in allocs:
allocs[k] += v

return allocs


class CollaborationAllocation(models.Model):
sca = models.ForeignKey(ScienceCollaborationAllocation, on_delete=models.CASCADE)
telescope_name = models.CharField(max_length=255)
allocation = models.FloatField(default=0)

def __str__(self):
return f'CollaborationAllocation for {self.sca.id}-{self.telescope_name}'


class Proposal(models.Model):
id = models.CharField(max_length=255, primary_key=True)
active = models.BooleanField(default=True)
Expand Down
12 changes: 7 additions & 5 deletions observation_portal/sciapplications/models.py
Expand Up @@ -132,13 +132,15 @@ def proposal_code(self):
)

@property
def time_requested_by_class(self):
telescope_instrument_types = configdb.get_instrument_types_per_telescope_class(exclude_states=['DISABLED'])
def time_requested_by_telescope_name(self):
telescope_instrument_types = configdb.get_instrument_types_per_telescope_name(exclude_states=['DISABLED'])
time_requests = {}
for tel_code, instrument_types in telescope_instrument_types.items():
time_requests[tel_code] = sum(
for tel_name, instrument_types in telescope_instrument_types.items():
time_requests[tel_name] = sum(
sum([tr.std_time, tr.rr_time, tr.tc_time]) for tr in self.timerequest_set.filter(
instrument__code__in=list(instrument_types)))
instrument__code__in=list(instrument_types)
)
)
return time_requests

def get_absolute_url(self):
Expand Down
Expand Up @@ -57,17 +57,24 @@ <h1>{{ user.sciencecollaborationallocation.name }} Proposals</h1>
</p>
<table class="table">
<thead>
<tr><td>Semester</td><td>1 Meter</td><td>2 Meter</td><td>0.4 Meter</td><td>Deadline</td><td></td></tr>
<tr>
<td>Semester</td>
{% for alloc in user.sciencecollaborationallocation.collaborationallocation_set.all %}
<td>{{ alloc.telescope_name|raw_telescope_name }}</td>
{% endfor %}
<td>Deadline</td>
<td></td>
</tr>
</thead>
<tbody>
{% for call in calls %}
{% if call.proposal_type == 'COLAB'%}
{% time_requested_by_sca user.sciencecollaborationallocation call.semester as time_requested %}
<tr>
<td>{{ call.semester }}</td>
<td>{{ time_requested.1m0 }}/{{ request.user.sciencecollaborationallocation.one_meter_alloc }}</td>
<td>{{ time_requested.2m0 }}/{{ request.user.sciencecollaborationallocation.two_meter_alloc }}</td>
<td>{{ time_requested.0m4 }}/{{ request.user.sciencecollaborationallocation.four_meter_alloc }}</td>
{% for alloc in user.sciencecollaborationallocation.collaborationallocation_set.all %}
<td>{{ time_requested|get_from_dict:alloc.telescope_name }}/{{ alloc.allocation }}</td>
{% endfor %}
<td>{{ call.deadline }}</td>
<td><a href="{% url 'sciapplications:create' call=call.id %}" class="btn btn-info">Add Proposal</a></td>
</tr>
Expand All @@ -83,9 +90,9 @@ <h4>Draft Proposals</h4>
<tr>
<td>{% trans 'Title' %}</td>
<td>{% trans 'Rank' %}</td>
<td>{% trans '1m0' %}</td>
<td>{% trans '2m0' %}</td>
<td>{% trans '0m4' %}</td>
{% for alloc in user.sciencecollaborationallocation.collaborationallocation_set.all %}
<td>{% trans alloc.telescope_name|raw_telescope_name %}</td>
{% endfor %}
<td>{% trans 'Semester' %}</td>
<td>{% trans 'Deadline' %}</td>
<td>{% trans 'Status' %}</td>
Expand All @@ -99,9 +106,9 @@ <h4>Draft Proposals</h4>
<tr>
<td><a href="{% url 'sciapplications:update' pk=app.id %}">{{ app.title }}</a></td>
<td>{{ app.tac_rank }}</td>
<td>{{ app.time_requested_by_class.1m0 }}</td>
<td>{{ app.time_requested_by_class.2m0 }}</td>
<td>{{ app.time_requested_by_class.0m4 }}</td>
{% for alloc in user.sciencecollaborationallocation.collaborationallocation_set.all %}
<td>{{ app.time_requested_by_telescope_name|get_from_dict:alloc.telescope_name }}</td>
{% endfor %}
<td>{{ app.call.semester }}</td>
<td>{{ app.call.deadline }}</td>
<td>{{ app.status }}</td>
Expand All @@ -123,9 +130,9 @@ <h4>Submitted Proposals</h4>
<tr>
<td>{% trans 'Title' %}</td>
<td>{% trans 'Rank' %}</td>
<td>{% trans '1m0' %}</td>
<td>{% trans '2m0' %}</td>
<td>{% trans '0m4' %}</td>
{% for alloc in user.sciencecollaborationallocation.collaborationallocation_set.all %}
<td>{% trans alloc.telescope_name|raw_telescope_name %}</td>
{% endfor %}
<td>{% trans 'Semester' %}</td>
<td>{% trans 'Deadline' %}</td>
<td>{% trans 'Status' %}</td>
Expand All @@ -138,9 +145,10 @@ <h4>Submitted Proposals</h4>
<tr>
<td>{{ app.title }}</td>
<td>{{ app.tac_rank }}</td>
<td>{{ app.time_requested_by_class.1m0 }}</td>
<td>{{ app.time_requested_by_class.2m0 }}</td>
<td>{{ app.time_requested_by_class.0m4 }}</td>

{% for alloc in user.sciencecollaborationallocation.collaborationallocation_set.all %}
<td>{{ app.time_requested_by_telescope_name|get_from_dict:alloc.telescope_name }}</td>
{% endfor %}
<td>{{ app.call.semester }}</td>
<td>{{ app.call.deadline }}</td>
<td>{{ app.status }}</td>
Expand Down

0 comments on commit 3329902

Please sign in to comment.