def test_cutoff_case_C(self): """UNIT test: services.common.slots.cutoff_slot (CASE C) CASE C: slot[0] > interval[0] && slot[1] < interval[1] """ self.assertEquals( slots.cutoff(( misc.get_next_midnight(), misc.get_next_midnight() + py_delta(hours=1) ), ( misc.get_next_midnight() + py_delta(minutes=15), misc.get_next_midnight() + py_delta(minutes=30) )), ( misc.get_next_midnight() + py_delta(minutes=15), misc.get_next_midnight() + py_delta(minutes=30) ) ) self.assertEquals( slots.cutoff(( misc.get_next_midnight(), misc.get_next_midnight() + py_delta(hours=1) ), ( misc.get_next_midnight() + py_delta(minutes=15), misc.get_next_midnight() + py_delta(hours=1) )), ( misc.get_next_midnight() + py_delta(minutes=15), misc.get_next_midnight() + py_delta(hours=1) ) )
def get_applicable(self, groundstation, start=None, end=None): """ This method returns all the availability slots that can be applied within the given interval defined by the start and the duration. :param groundstation: The object of the GroundStation. :param start: Start of the applicability slot. :param end: End of the applicability slot. :return: The list of the applicable AvailabilitySlots during the defined applicability slot. """ if start is None or end is None: start, end = simulation.OrbitalSimulator.get_simulation_window() elif start >= end: raise TypeError( '<start=' + str( start ) + '> should occurr sooner than <end=' + str(end) + '>' ) result = [] for a_i in self.filter( groundstation=groundstation ).filter(start__lt=end, end__gt=start): result.append( sn_slots.cutoff((a_i.start, a_i.end), (start, end)) ) return result
def availability_generates_slots(self, availability_slot): """ Method that generates the Operational slots corresponding to the given Availability slot. :param availability_slot: reference to the Availability object """ logger.info( '>>> @availability_generates_slots.availability_slot = ' + str( availability_slot ) ) # 1) Pass slots for all the spacecraft that: # (a) are compatible with the GroundStation whose rules update # provoked the generation of this Availability slot, # (b) occur within the applicability range of the Availability slot compatible_p_slots = pass_models.PassSlots.objects.filter( groundstation=availability_slot.groundstation, spacecraft__in=[ c.spacecraft for c in compatibility_models.ChannelCompatibility.objects.filter( groundstation=availability_slot.groundstation ) ] ) p_slots = compatible_p_slots.filter( OperationalSlotsManager._slots_query( availability_slot.start, availability_slot.end ) ) logger.info( '>>> @availability_generates_slots.compatible_p_slots = ' + sn_misc.list_2_string(compatible_p_slots) ) logger.info( '>>> @availability_generates_slots.p = ' + sn_misc.list_2_string( p_slots ) ) # 2) we filter the pass slots that are applicable to the window of this # availability slot; truncating the first and the last one if # necessary for p in p_slots: start, end = sn_slots.cutoff( (availability_slot.start, availability_slot.end), (p.start, p.end) ) self.create( availability_slot=availability_slot, pass_slot=p, start=start, end=end )
def get_applicable(self, groundstation, start=None, end=None): """ This method returns all the availability slots that can be applied within the given interval defined by the start and the duration. :param groundstation: The object of the GroundStation. :param start: Start of the applicability slot. :param end: End of the applicability slot. :return: The list of the applicable AvailabilitySlots during the defined applicability slot. """ if start is None or end is None: start, end = simulation.OrbitalSimulator.get_simulation_window() elif start >= end: raise TypeError('<start=' + str(start) + '> should occurr sooner than <end=' + str(end) + '>') result = [] for a_i in self.filter(groundstation=groundstation).filter( start__lt=end, end__gt=start): result.append(sn_slots.cutoff((a_i.start, a_i.end), (start, end))) return result
def generate_available_slots_once(rule_values, interval=None): """ This method generates the available slots for a only-once rule that starts and ends in the given dates, during the specified interval. :param interval: Interval of applicability :param rule_values: The values for the ONCE availability rule """ if interval is None: interval = simulation.OrbitalSimulator.get_simulation_window() try: r = AvailabilityRuleOnce.objects.get( availabilityrule_ptr_id=rule_values['id'] ) except dj_exceptions.ObjectDoesNotExist as ex: logger.warning( '>>> Child rule does not exist, returning no slots, ex = ' + str(ex) ) return [] try: slot = slots.cutoff( interval, (r.starting_time, r.ending_time) ) except ValueError as ex: logger.warning( '>>> onceRules.generate_available_slots, no slots generated, ' 'ex = ' + str(ex) ) return [] return [slot]
def generate_available_slots_daily(rule_values, interval=None): """ This method generates the available slots for a daily rule that starts and ends in the given dates, during the specified interval. TODO :: improve the generation algorithm in order to avoid generating slots since the start of the rule until the validity of the current interval (can be long) :param interval: Interval of applicability :param rule_values: The values for the ONCE availability rule """ if interval is None: interval = simulation.OrbitalSimulator.get_simulation_window() try: r = AvailabilityRuleDaily.objects.get( availabilityrule_ptr_id=rule_values['id']) except dj_exceptions.ObjectDoesNotExist as ex: logger.warning( '>>> Child rule does not exist, returning no slots, ex = ' + str(ex)) return [] result = [] slot_i = slots.position(interval, (r.starting_time, r.ending_time)) while slot_i[0] < interval[1]: slot = slots.cutoff(interval, slot_i) result.append((slot[0], slot[1])) slot_i = (slot_i[0] + py_timedelta(days=1), slot_i[1] + py_timedelta(days=1)) return result
def generate_available_slots_once(rule_values, interval=None): """ This method generates the available slots for a only-once rule that starts and ends in the given dates, during the specified interval. :param interval: Interval of applicability :param rule_values: The values for the ONCE availability rule """ if interval is None: interval = simulation.OrbitalSimulator.get_simulation_window() try: r = AvailabilityRuleOnce.objects.get( availabilityrule_ptr_id=rule_values['id']) except dj_exceptions.ObjectDoesNotExist as ex: logger.warning( '>>> Child rule does not exist, returning no slots, ex = ' + str(ex)) return [] try: slot = slots.cutoff(interval, (r.starting_time, r.ending_time)) except ValueError as ex: logger.warning( '>>> onceRules.generate_available_slots, no slots generated, ' 'ex = ' + str(ex)) return [] return [slot]
def availability_generates_slots(self, availability_slot): """ Method that generates the Operational slots corresponding to the given Availability slot. :param availability_slot: reference to the Availability object """ logger.info('>>> @availability_generates_slots.availability_slot = ' + str(availability_slot)) # 1) Pass slots for all the spacecraft that: # (a) are compatible with the GroundStation whose rules update # provoked the generation of this Availability slot, # (b) occur within the applicability range of the Availability slot compatible_p_slots = pass_models.PassSlots.objects.filter( groundstation=availability_slot.groundstation, spacecraft__in=[ c.spacecraft for c in compatibility_models.ChannelCompatibility.objects. filter(groundstation=availability_slot.groundstation) ]) p_slots = compatible_p_slots.filter( OperationalSlotsManager._slots_query(availability_slot.start, availability_slot.end)) logger.info('>>> @availability_generates_slots.compatible_p_slots = ' + sn_misc.list_2_string(compatible_p_slots)) logger.info('>>> @availability_generates_slots.p = ' + sn_misc.list_2_string(p_slots)) # 2) we filter the pass slots that are applicable to the window of this # availability slot; truncating the first and the last one if # necessary for p in p_slots: start, end = sn_slots.cutoff( (availability_slot.start, availability_slot.end), (p.start, p.end)) self.create(availability_slot=availability_slot, pass_slot=p, start=start, end=end)
def pass_generates_slots(self, pass_slot): """ Method that generates all the Operational slots related to the newly created pass slot. :param pass_slot: reference to the Pass slot """ # 0) Check compatibility... if not compatible, no slot if not compatibility_models.ChannelCompatibility.objects.filter( groundstation=pass_slot.groundstation, spacecraft=pass_slot.spacecraft ).exists(): logger.warn('No compatibility for pass slot = ' + str(pass_slot)) return # 1) Availability slots for all the spacecraft that: # (a) are owned by the GroundStation over which the Spacecraft passes, # (b) occur within the applicability range of the Availability slot a_slots = availability_models.AvailabilitySlot.objects.filter( groundstation=pass_slot.groundstation ).filter( OperationalSlotsManager._slots_query( pass_slot.start, pass_slot.end ) ) # 2) we filter the pass slots that are applicable to the window of this # availability slot; truncating the first and the last one if # necessary for a in a_slots: start, end = sn_slots.cutoff( (a.start, a.end), (pass_slot.start, pass_slot.end) ) self.create( availability_slot=a, pass_slot=pass_slot, start=start, end=end )
def generate_available_slots_daily(rule_values, interval=None): """ This method generates the available slots for a daily rule that starts and ends in the given dates, during the specified interval. TODO :: improve the generation algorithm in order to avoid generating slots since the start of the rule until the validity of the current interval (can be long) :param interval: Interval of applicability :param rule_values: The values for the ONCE availability rule """ if interval is None: interval = simulation.OrbitalSimulator.get_simulation_window() try: r = AvailabilityRuleDaily.objects.get( availabilityrule_ptr_id=rule_values['id'] ) except dj_exceptions.ObjectDoesNotExist as ex: logger.warning( '>>> Child rule does not exist, returning no slots, ex = ' + str(ex) ) return [] result = [] slot_i = slots.position(interval, (r.starting_time, r.ending_time)) while slot_i[0] < interval[1]: slot = slots.cutoff(interval, slot_i) result.append((slot[0], slot[1])) slot_i = ( slot_i[0] + py_timedelta(days=1), slot_i[1] + py_timedelta(days=1) ) return result
def pass_generates_slots(self, pass_slot): """ Method that generates all the Operational slots related to the newly created pass slot. :param pass_slot: reference to the Pass slot """ # 0) Check compatibility... if not compatible, no slot if not compatibility_models.ChannelCompatibility.objects.filter( groundstation=pass_slot.groundstation, spacecraft=pass_slot.spacecraft).exists(): logger.warn('No compatibility for pass slot = ' + str(pass_slot)) return # 1) Availability slots for all the spacecraft that: # (a) are owned by the GroundStation over which the Spacecraft passes, # (b) occur within the applicability range of the Availability slot a_slots = availability_models.AvailabilitySlot.objects.filter( groundstation=pass_slot.groundstation).filter( OperationalSlotsManager._slots_query(pass_slot.start, pass_slot.end)) # 2) we filter the pass slots that are applicable to the window of this # availability slot; truncating the first and the last one if # necessary for a in a_slots: start, end = sn_slots.cutoff((a.start, a.end), (pass_slot.start, pass_slot.end)) self.create(availability_slot=a, pass_slot=pass_slot, start=start, end=end)