Blame view

src/scheduler/simulator.py 4.96 KB
ddf59dd4   haribo   Remaniement :
1
2
from scheduler.Scheduler import Scheduler
from common.models import *
715fabb7   haribo   #3430 (100%)
3
4
5
import urllib.request as urllib2
from html.parser import HTMLParser
import math
715fabb7   haribo   #3430 (100%)
6
7
from decimal import Decimal
import time
715fabb7   haribo   #3430 (100%)
8

94336356   haribo   Added starting fi...
9

715fabb7   haribo   #3430 (100%)
10
11
12
13
14
15
16
17
18
19
20
class MyHTMLParser(HTMLParser):
    '''
        Subclassing HTMLParser to access the data properly
    '''

    def __init__(self):
        HTMLParser.__init__(self)
        self.data = []

    def handle_data(self, data):
        self.data.append(data)
94336356   haribo   Added starting fi...
21

715fabb7   haribo   #3430 (100%)
22
23
24
    def handle_comment(self, data):
        pass

94336356   haribo   Added starting fi...
25

715fabb7   haribo   #3430 (100%)
26
27
28
29
class Simulator():
    '''
        Simulates the creation of a planning thanks to an HTML file
    '''
94336356   haribo   Added starting fi...
30

715fabb7   haribo   #3430 (100%)
31
32
    def __init__(self):
        pass
94336356   haribo   Added starting fi...
33

715fabb7   haribo   #3430 (100%)
34
35
36
    def simulate(self, sequences_file):
        '''
           ENTRY POINT
94336356   haribo   Added starting fi...
37

715fabb7   haribo   #3430 (100%)
38
           Parse the file with sequences, then call the Scheduler simulation function and give the result to the view
94336356   haribo   Added starting fi...
39

715fabb7   haribo   #3430 (100%)
40
41
42
           :param sequences_file : HTML file containing sequences description 
           :returns : a tuple (Schedule, list of sequences) after the scheduling process
        '''
94336356   haribo   Added starting fi...
43

715fabb7   haribo   #3430 (100%)
44
45
        file = urllib2.urlopen(sequences_file)
        data = str(file.read())
715fabb7   haribo   #3430 (100%)
46
47
48
49
        parser = MyHTMLParser()
        parser.feed(data)

        """filter unwanted \n and other data"""
77816f10   haribo   Workflow implemen...
50
51
        filtered_list = list(map(lambda s: s.strip(), parser.data))
        page_text = "".join(filtered_list[11:])
715fabb7   haribo   #3430 (100%)
52

77816f10   haribo   Workflow implemen...
53
54
        raw_sequences = page_text.split("\\n")
        del raw_sequences[0]
94336356   haribo   Added starting fi...
55
56
        del raw_sequences[len(raw_sequences) - 1]
        raw_sequences = [
aeab475e   Microaster   Windows adaptatio...
57
            sequence for sequence in raw_sequences if len(sequence) > 10]
715fabb7   haribo   #3430 (100%)
58
59
60
61
62

        """Create the default models linked to the sequences"""
        sp = ScientificProgram()
        country = Country()
        usr_lvl = UserLevel()
53787d30   Jeremy   Alert now inherit...
63
        py_usr = PyrosUser(username="toto", country=country, user_level=usr_lvl, quota=1000)
94336356   haribo   Added starting fi...
64
        req = Request(scientific_program=sp, pyros_user=py_usr)
715fabb7   haribo   #3430 (100%)
65
66
67
68
69

        scheduler = Scheduler()

        """Create the sequences"""
        sequences = []
77816f10   haribo   Workflow implemen...
70
71
72
73
        for raw_sequence in raw_sequences:
            sequence_array = raw_sequence.split(" ")
            id_seq = sequence_array[0]
            priority = int(sequence_array[2])
715fabb7   haribo   #3430 (100%)
74
            ''' transforms the duration (seconds) in days (86,400s in a day)'''
77816f10   haribo   Workflow implemen...
75
76
77
            duration = Decimal(float(sequence_array[4]) / 86400.0)
            jd1 = Decimal("%.8f" % float(sequence_array[5]))
            jd2 = Decimal("%.8f" % float(sequence_array[6]))
94336356   haribo   Added starting fi...
78

ff448d43   Jeremy   Update
79
            sequence = Sequence(request=req, status=Sequence.PLANNED,
715fabb7   haribo   #3430 (100%)
80
81
82
                                name="sequence", id=id_seq, priority=priority, duration=duration, jd1=jd1, jd2=jd2, t_prefered=-1)
            sequences.append(sequence)

94336356   haribo   Added starting fi...
83
84
        # 1) trouver le nombre qu'on retrouve le plus souvent en troncature de
        # jd1 (faire un dico)
715fabb7   haribo   #3430 (100%)
85
86
87
88
89
90
91
92
        days = {}
        for sequence in sequences:
            truncated = math.floor(float(sequence.jd1))
            if truncated in days.keys():
                days[truncated] += 1
            else:
                days[truncated] = 1
        maximum_truncated = max(days.keys(), key=(lambda key: days[key]))
94336356   haribo   Added starting fi...
93

715fabb7   haribo   #3430 (100%)
94
        # 2) virer toutes les séquences qui n'ont pas ce jd1 en troncature
94336356   haribo   Added starting fi...
95
96
        sequences = [sequence for sequence in sequences if math.floor(
            float(sequence.jd1)) == maximum_truncated]
715fabb7   haribo   #3430 (100%)
97

94336356   haribo   Added starting fi...
98
99
        # 3) set le plan_start et le plan_end en fonction du plus petit jd1 et
        # du plus grand jd2
715fabb7   haribo   #3430 (100%)
100
101
102
103
104
105
106
107
108
        scheduler.schedule.plan_start = -1
        scheduler.schedule.plan_end = -1
        for sequence in sequences:
            if scheduler.schedule.plan_start == -1 or sequence.jd1 < scheduler.schedule.plan_start:
                scheduler.schedule.plan_start = sequence.jd1
            if scheduler.schedule.plan_end == -1 or sequence.jd2 > scheduler.schedule.plan_end:
                scheduler.schedule.plan_end = sequence.jd2

        start = time.time()
94336356   haribo   Added starting fi...
109

bca9a283   Jeremy   Reworked the sche...
110
        schedule, sequences = scheduler.simulateSchedule(sequences)
715fabb7   haribo   #3430 (100%)
111
112

        end = time.time()
94336356   haribo   Added starting fi...
113

715fabb7   haribo   #3430 (100%)
114
        print("Duration : ", end - start)
94336356   haribo   Added starting fi...
115

715fabb7   haribo   #3430 (100%)
116
        self.test_sequences_validity(schedule, sequences)
94336356   haribo   Added starting fi...
117

715fabb7   haribo   #3430 (100%)
118
        return (schedule, sequences)
94336356   haribo   Added starting fi...
119

715fabb7   haribo   #3430 (100%)
120
121
122
123
124
125
126
127
    def test_sequences_validity(self, schedule, sequences):
        '''
            For PLANNED sequences, tests if :
                - all the sequences are in the schedule
                - there is no overlap between sequences
                - [tsp - tep] is in [jd1 - jd2]
                - tep < tsp
        '''
7a79e25b   haribo   Date: 19/05/2016
128
        sequences.sort(key=lambda x: x[1].tsp)
94336356   haribo   Added starting fi...
129

7a79e25b   haribo   Date: 19/05/2016
130
        for index, (sequence, shs) in enumerate(sequences):
eecfb779   haribo   Date: 26/05/2016
131
            if shs.status == Sequence.PENDING:
7a79e25b   haribo   Date: 19/05/2016
132
                if shs.tsp > shs.tep:
715fabb7   haribo   #3430 (100%)
133
                    raise ValueError("tep < tsp ...")
7a79e25b   haribo   Date: 19/05/2016
134
                if shs.tsp < schedule.plan_start or schedule.plan_end < shs.tep:
715fabb7   haribo   #3430 (100%)
135
                    raise ValueError("[tsp;tep] not in [plan_start;plan_end]")
7a79e25b   haribo   Date: 19/05/2016
136
                if shs.tsp < sequence.jd1 or sequence.jd2 < shs.tep:
715fabb7   haribo   #3430 (100%)
137
                    raise ValueError("[tsp;tep] not in [jd1;jd2]")
7a79e25b   haribo   Date: 19/05/2016
138
                if index > 0 and shs.tsp < sequences[index - 1][1].tep:
715fabb7   haribo   #3430 (100%)
139
                    raise ValueError("There is a sequence overlap")