示例#1
0
    def test_step_one_infected_unity_rate_infects_other(self):
        self.two_in_contact[0].infected = True
        propagator = Propagator(self.two_in_contact, rate=1.0)

        propagator.step()

        self.assertTrue(self.two_in_contact[1].infected)
示例#2
0
    def test_results_has_length_of_steps_with_three_steps(self):
        propagator = Propagator(self.two_in_contact)

        n_steps = 3
        propagator.step_n(n_steps)

        self.assertEqual(n_steps, len(propagator.results.day))
示例#3
0
    def test_results_days_are_consecutive_for_four_days(self):
        propagator = Propagator(self.two_in_contact)

        n_steps = 4
        propagator.step_n(n_steps)

        self.assertEqual([0, 1, 2, 3], propagator.results.day)
示例#4
0
    def test_step_with_two_in_contact_and_zero_rate_does_nothing(self):
        propagator = Propagator(self.two_in_contact, rate=0.0)

        propagator.step()

        self.assertFalse(self.two_in_contact[0].infected)
        self.assertFalse(self.two_in_contact[1].infected)
示例#5
0
    def test_recovered_do_not_get_reinfected(self):
        self.two_in_contact[0].infected = True
        propagator = Propagator(self.two_in_contact, rate=1.0, infection_length=1)

        propagator.step_n(2)

        self.assertFalse(self.two_in_contact[0].infected)
示例#6
0
    def test_not_infected_with_mortality_1_dont_die(self):
        person = Person()
        propagator = Propagator([person], daily_mortality=1.0)

        propagator.step()

        self.assertFalse(person.dead)
示例#7
0
    def make_primitive_helper(*cells):
        inputs, output = cells[:-1], cells[-1]
        lifted_f = _lift_to_cell_contents(f)

        def to_do():
            output.add_content(lifted_f(*[c.content for c in inputs]))

        return Propagator(inputs, to_do)
示例#8
0
    def test_results_recovered_count_recovered(self):
        self.two_in_contact[0].infected = True

        propagator = Propagator(self.two_in_contact, infection_length=1, daily_mortality=0)

        propagator.step_n(2)

        self.assertEqual([0, 1], propagator.results.recovered_count)
示例#9
0
    def test_none_in_contact_do_not_infect(self):
        people = [Person(), Person()]
        people[0].infected = True
        propagator = Propagator(people, rate=1.0)

        propagator.step()

        self.assertFalse(people[1].infected)
示例#10
0
    def test_all_infected_die_with_mortality_1(self):
        person = Person()
        person.infected = True
        propagator = Propagator([person], daily_mortality=1.0)

        propagator.step()

        self.assertTrue(person.dead)
示例#11
0
    def test_infected_given_infection_length_3_is_still_infected_after_2_steps(self):
        infected_person = Person()
        infected_person.infected = True
        propagator = Propagator([infected_person], infection_length=3)

        propagator.step_n(2)

        self.assertTrue(infected_person.infected)
示例#12
0
    def test_infected_recover_after_infection_length_steps_of_2(self):
        infected_person = Person()
        infected_person.infected = True
        propagator = Propagator([infected_person], infection_length=2)

        propagator.step_n(2)

        self.assertFalse(infected_person.infected)
示例#13
0
    def test_step_half_rate_infects_other_with_rng_zero(self, mock_random):
        mock_random.return_value = 0.0
        self.two_in_contact[0].infected = True
        propagator = Propagator(self.two_in_contact, rate=0.5)

        propagator.step()

        self.assertTrue(self.two_in_contact[1].infected)
示例#14
0
    def test_results_dead_count_dead(self):
        self.two_in_contact[0].infected = True
        self.two_in_contact[1].dead = True

        propagator = Propagator(self.two_in_contact, infection_length=10, daily_mortality=1.0)

        propagator.step_n(2)

        self.assertEqual([1, 2], propagator.results.dead_count)
示例#15
0
    def test_those_that_die_do_not_recover(self, mock_random):
        mock_random.return_value = 0.0
        person = Person()
        person.infected = True
        propagator = Propagator([person], daily_mortality=1.0, infection_length=1)

        propagator.step()

        self.assertFalse(person.recovered)
示例#16
0
    def test_the_dead_do_not_infect(self, mock_random):
        mock_random.return_value = 0.0
        self.two_in_contact[0].dead = True
        self.two_in_contact[0].infected = True
        propagator = Propagator(self.two_in_contact, daily_mortality=1.0, rate=1.0)

        propagator.step()

        self.assertFalse(self.two_in_contact[1].infected)
示例#17
0
    def test_results_infected_count_infected(self):
        self.two_in_contact[0].infected = True
        self.two_in_contact[1].infected = True

        propagator = Propagator(self.two_in_contact, infection_length=1)

        propagator.step_n(2)

        self.assertEqual([2, 0], propagator.results.infected_count)
示例#18
0
    def test_all_infected_die_with_mortality_one_tenth_and_rng_0(self, mock_random):
        mock_random.return_value = 0.0
        person = Person()
        person.infected = True
        propagator = Propagator([person], daily_mortality=0.1)

        propagator.step()

        self.assertTrue(person.dead)
示例#19
0
    def test_those_that_die_are_not_considered_infected(self, mock_random):
        mock_random.return_value = 0.0
        person = Person()
        person.infected = True
        propagator = Propagator([person], daily_mortality=1.0)

        propagator.step()

        self.assertFalse(person.infected)
示例#20
0
def conditional(p, if_true, if_false, output):
    def conditional_helper():
        if p.content is not None:
            if p.content:
                output.add_content(if_true.content)
            else:
                output.add_content(if_false.content)

    return Propagator([p, if_true, if_false], conditional_helper)
示例#21
0
    def new_propagator_appends_function_to_neighbors(self):
        a = Cell()
        b = Cell()
        c = Cell()
        f = lambda x: x

        Propagator([a, b, c], f)

        for cell in [a, b, c]:
            self.assertEqual(cell.neighbors, [f])
示例#22
0
def propagate():

    action_help = """
    
    Actions
    ========
     info     : print all info about the spacecraft
     get_all  : get all data and return as a csv
     get_pass : quickly find upcoming pass(es)
     compute  : compute pass details
    
    Ground station specification
    ============================
     The ground station can be specified with the --gslat, --gslon, --gselev params,
     or alternatively by a simple text file with those three fields separated by comma.
     The file should either be called gs.txt or specified with --gs.
     
    
    Examples
    ========
    
    $ libgs-propagate info
      Print info about current state of spacecraft described by TLE. Get TLE from stdin
       
    $ libgs-propagate -i tles.txt -w "2018-01-01 10:00" "2018-01-01 10:05" "2018-01-01 10:10" get_all
      Compute everything we can about the tles at the times specified and return a CSV
      
    $ libgs-propagate -i tles.txt -N 10 get_pass
      Get overview of next 10 passes and return a CSV
    
    $ libgs-propagate -i tles.txt --nid 25440 compute 
      Compute upcoming pass for TLE 25440 and return a CSV with same fields as get_all
    
    """

    parser = argparse.ArgumentParser(
        formatter_class=argparse.RawDescriptionHelpFormatter,
        description='Propagate a TLE',
        epilog=action_help)
    parser.add_argument(
        "-i",
        "--input",
        help="Input file with TLE(s). Omit to get TLE(s) from stdin")
    parser.add_argument(
        "-n",
        "--nid",
        type=int,
        nargs="*",
        help=
        "Norad ID(s) of TLE(s) to propagate. If omitted does all provided TLEs"
    )
    parser.add_argument("-w",
                        "--when",
                        type=str,
                        nargs="*",
                        help="Timestamps at which to propegate. Default=now")
    parser.add_argument("--gslat",
                        type=float,
                        help="Ground station latitiude (overrides --gs)")
    parser.add_argument("--gslon",
                        type=float,
                        help="Ground station longitude (overrides --gs)")
    parser.add_argument("--gselev",
                        type=float,
                        help="Ground station elevation (overrides --gs)")
    parser.add_argument(
        "-g",
        "--gs",
        type=str,
        default="gs.txt",
        help="Ground station specification file (use instead of gslat/lon/elev)"
    )
    parser.add_argument("-H",
                        "--horizon",
                        type=float,
                        default=5,
                        help="Visibility  horizon")
    parser.add_argument(
        "-N",
        type=int,
        default=1,
        help="(Only with get_pass action) Number of passes to get")
    parser.add_argument(
        "--dt",
        type=int,
        help="(Only with compute action) Time interval to compute data at")
    parser.add_argument("action",
                        choices=["info", "get_all", "get_pass", "compute"],
                        help="Action to take")
    parser.add_argument("-p",
                        "--print",
                        action="store_true",
                        help="Pretty print output")
    parser.add_argument("-f",
                        "--field",
                        nargs="+",
                        help="Filter output by one or more fields")
    parser.add_argument("--no-header",
                        action="store_true",
                        help="Dont output csv header")
    args = parser.parse_args()

    if args.input is not None:
        try:
            with open(args.input, "r") as fp:
                tles = fp.read()
        except Exception as e:
            _print("ERROR: Could not read file {}".format(args.input))
            exit(1)
    else:
        _print("Enter TLE(s). EOF (Ctrl-D) to finish")
        tles = sys.stdin.read()
    tles = tles.strip()

    if (args.gslat is not None and args.gslon is not None
            and args.gselev is not None):
        pass
    elif args.gs is not None:
        try:
            with open(args.gs, "r") as fp:
                gslat, gslon, gselev = [float(x) for x in fp.read().split(',')]
        except Exception as e:
            _print(
                "ERROR: Could not parse groundstation definition file. Message ({}): {}"
                .format(e.__class__.__name__, e))
            exit(1)
    else:
        _print(
            "ERROR: Ground station location needs to be defined (either with --gslat/--gslon/--gselev or wiht --gs file)"
        )
        exit(1)

    if args.gslat is not None:
        gslat = args.gslat

    if args.gslon is not None:
        gslon = args.gslon

    if args.gselev is not None:
        gselev = args.gselev

    try:
        p = Propagator(tles=tles, gs_lat=gslat, gs_lon=gslon, gs_elev=gselev)
    except Exception as e:
        _print("ERROR: Could not create Propagator. Message ({}): {}".format(
            e.__class__.__name__, e))
        raise
        exit(1)

    if args.nid is None:
        nids = p.nids_to_track
        # # try to extract NIDs from tle string
        # raw_tles = tles.replace('\r', '').split('\n')
        # raw_tles = [rtle.strip() for rtle in raw_tles]
        #
        # # do a tiny bit of error checking and extract nids
        #
        # if  (not all([x[0] == '0' for x in raw_tles[0::3]])) or\
        #     (not all([x[0] == '1' for x in raw_tles[1::3]])) or\
        #     (not all([x[0] == '2' for x in raw_tles[2::3]])) :
        #     _print("ERROR: Malformed TLE string")
        #     exit(1)
        #
        # nids = [int(x.split(' ')[1]) for x in  raw_tles[2::3]]
    else:
        nids = args.nid

    if len(nids) < 1:
        _print("ERROR: No valid TLEs and/or no NIDs. Dont know what to do")
        exit(1)

    if args.action == 'info':

        try:
            for nid in nids:
                for w in [None] if args.when is None else args.when:
                    p.print_info(nid=nid, when=_fix_timestamp(w))

        except Exception as e:
            _print("ERROR: action info. Message ({}):{}".format(
                e.__class__.__name__, e))
            exit(1)

        exit(0)

    elif args.action == 'get_all':
        if len(nids) > 1:
            _print(
                "ERROR: get_all action only works with a single NID, you have specified {}"
                .format(nids))
            exit(1)

        try:
            when = [_fix_timestamp(w) for w in args.when]
            data = p.get_all(nid=nids[0], when=when)
            data.tstamp_str = data.tstamp_str.apply(_rev_timestamp)

            if isinstance(data, pd.Series):
                data = pd.DataFrame(data).transpose()

        except Exception as e:
            _print("ERROR: action get_all. Message ({}):{}".format(
                e.__class__.__name__, e))
            exit(1)

    elif args.action == 'get_pass':

        try:
            if args.when is not None and len(args.when) != 1:
                _print(
                    "ERROR: get_pass requires when to be a single date. Use -N if you want to compute multiple passes"
                )
                exit(1)
            data = p.get_passes(nid=nids,
                                when=_fix_timestamp(args.when[0])
                                if args.when is not None else None,
                                N=args.N,
                                horizon=args.horizon)

            if isinstance(data, pd.Series):
                data = pd.DataFrame(data).transpose()
                data.index.name = "pass_no"

            data.rise_t = data.rise_t.apply(_rev_timestamp)
            data.max_elev_t = data.max_elev_t.apply(_rev_timestamp)
            data.set_t = data.set_t.apply(_rev_timestamp)

        except Exception as e:
            _print("ERROR: action get_pass. Message ({}):{}".format(
                e.__class__.__name__, e))
            exit(1)

    elif args.action == 'compute':
        if len(nids) > 1:
            _print(
                "ERROR: compute action only works with a single NID, you have specified {}"
                .format(nids))
            exit(1)

        if args.when is not None:
            if len(args.when) != 1:
                _print("ERROR: action compute. When must be a single value")
                exit(1)
            else:
                when = _fix_timestamp(args.when[0])
        else:
            when = None

        try:
            data, psum = p.compute_pass(nid=nids[0], when=when, dt=args.dt)
            data.tstamp_str = data.tstamp_str.apply(_rev_timestamp)

        except Exception as e:
            _print("ERROR: action compute. Message ({}):{}".format(
                e.__class__.__name__, e))
            exit(1)

    else:
        _print("ERROR: Invalid action {}".format(args.action))
        exit(1)

    data = data.reset_index()
    if args.field is not None:
        try:
            data = data.loc[:, args.field]
        except Exception as e:
            _print("ERROR: Could not filter by {}. Message ({}):{}".format(
                args.field, e.__class__.__name__, e))
            exit(1)

    if args.print:
        print(data)
    else:
        print(data.to_csv(index=False, header=not args.no_header))

    exit(0)
示例#23
0
 def __init__(self, grid_size, sample, pattern_size):
     self.patterns = Pattern.from_sample(sample, pattern_size)
     self.grid = self._create_grid(grid_size)
     self.propagator = Propagator(self.patterns)
示例#24
0
    def test_results_has_length_of_steps_with_one_step(self):
        propagator = Propagator(self.two_in_contact)

        propagator.step()

        self.assertEqual(1, len(propagator.results.day))