source: TOOLS/PlotRuncard/plot_runcard.py @ 6786

Last change on this file since 6786 was 6650, checked in by omamce, 7 months ago

O.M. :

TOOLS/PlotRuncard :

  • add a small python notebook to plot execution times from run.card file
  • set properties in all files
  • Property svn:keywords set to Date Revision HeadURL Author Id
File size: 9.3 KB
Line 
1#!/bin/env python
2
3#======================================================
4# Author: Patrick.Brockmann@cea.fr
5#
6# Date: 13/11/2012
7#
8#======================================================
9# SVN Information
10SVN = {
11    'Author'  : "$Author$",
12    'Date'    : "$Date$",
13    'Revision': "$Revision$",
14    'Id'      : "$Id $",
15    'HeadURL' : "$HeadUrl:  $"
16    }
17
18#======================================================
19import csv
20import matplotlib.pyplot as plt
21import datetime as dt
22import sys, string, os, re
23import urllib2
24import random
25
26#======================================================
27usage = """######################################################
28Usage:  plot_runcard.py [-h]
29        [--period]
30        [--yscalelog]
31        [--linewidth width]
32        [--linecolor colorcode]
33        [--showtitle]
34        [--pattern  'pattern, options ; ...']
35        list
36
37
38Argument:
39        Argument list is text file with one run.card file accessible by HTTP (http://...) or locally (file:///...) per line.
40        For each line, you can add specific options (linecolor, linewidth, title, showtitle) separated by ',' (whatever order).
41        For example :
42http://dods.extra.cea.fr/work/p86caub/IPSLCM5A/PROD/rcp85GHG/v3.rcp85GHG1/MONITORING/run.card   , linecolor="AFBBAA", title="My text", showtitle=1
43
44Notes:
45        Default color are randomly choosen
46        Default title is built from filename
47
48Examples:
49       ./plot_runcard.py --linecolor "BBBBBB" --pattern 'p86caub, linecolor="00FF00", showtitle=1 ; p25mart, linecolor="FF0000", showtitle=1, linewidth=4'  list_url_work2
50       ./plot_runcard.py --linecolor "BBBBBB" --pattern 'p86.*, linecolor="00FF00", showtitle=1 ; p25.*, linecolor="FF0000", showtitle=1'  list_url_work2
51
52"""
53
54options = """######################################################
55Options:
56        -h, -?, --help, -help
57                Print this manual
58        --period
59                Use CumulPeriod rather than PeriodDateBegin
60        --yscalelog
61                Set a log axis for vertical axis (only with --period option)
62        --linecolor FFFFFF
63                color code in hexa
64        --linewidth width
65                width = float value in points
66        --showtitle
67                title will be displayed
68                By default, titles are displayed only when mouse is passed over simulations
69        --pattern  'pattern, options ; ...'
70                ex: 'p86caub, linecolor="00FF00", showtitle=1 ; p86mart, linecolor="FF0000"'
71                Use single quote to delimit the option and ; between patterns.
72                Options are considered following the order : options from command, options from pattern option, options from list file.
73"""
74
75#======================================================
76periodoption=0 
77yscalelogoption=0
78linecoloroption=0
79linewidthoption=0
80showtitleoption=0
81patternoption=0
82while len(sys.argv[1:]) != 0 :
83        if sys.argv[1] in ('-h','--help') :
84                del(sys.argv[1])
85                print usage + options
86                sys.exit(1)
87        elif sys.argv[1] == '--period' :
88                periodoption=1
89                del(sys.argv[1])
90        elif sys.argv[1] == '--yscalelog' :
91                yscalelogoption=1
92                del(sys.argv[1])
93        elif sys.argv[1] == '--linecolor' :
94                linecoloroptionvalue=sys.argv[2]
95                linecoloroption=1
96                del(sys.argv[1])
97                del(sys.argv[1])
98        elif sys.argv[1] == '--linewidth' :
99                linewidthoptionvalue=string.atof(sys.argv[2])
100                linewidthoption=1
101                del(sys.argv[1])
102                del(sys.argv[1])
103        elif sys.argv[1] == '--showtitle' :
104                showtitleoptionvalue=True
105                showtitleoption=1
106                del(sys.argv[1])
107        elif sys.argv[1] == '--pattern' :
108                pattern=sys.argv[2].split(';')
109                patternoption=1
110                del(sys.argv[1])
111                del(sys.argv[1])
112        elif re.match('-',sys.argv[1]) :
113                print 'Error: option inconnu'
114                print usage + options
115                sys.exit(1)
116                break
117        else:
118                break
119
120if len(sys.argv[1:]) != 1 :
121        print usage + options
122        sys.exit(1)
123
124#======================================================
125fig = plt.figure()
126ax = fig.add_subplot(111)
127
128#======================================================
129nbfile=len(sys.argv[1:])/2
130
131#======================================================
132finput=file(sys.argv[1])
133
134simus_with_annotation=[]
135nbsimus=0
136nbfiles=0
137
138for line in finput :
139        print '#==========================================='
140        nbfiles=nbfiles+1
141
142        line=line.split(',')
143
144        #---------------------------
145        # options from command
146        fileruncard=line[0].strip() 
147
148        if not linecoloroption :
149                linecolor="%06X" % random.randint(0, 16777215)  # a random color for default
150        else :
151                linecolor=linecoloroptionvalue
152
153        if not linewidthoption :
154                linewidth=2.0
155        else :
156                linewidth=linewidthoptionvalue 
157
158        if fileruncard[0:4] == 'http' :
159                # remote file: http://
160                        # http://dods.idris.fr/login
161                if fileruncard[0:20] == 'http://dods.idris.fr' :
162                        title='.'.join(fileruncard.split('/')[3:-2])
163                else :
164                        # http://dods.extra.cea.fr/xxxx/login
165                        title='.'.join(fileruncard.split('/')[4:-2])
166        else : 
167                # local file: file://
168                title=os.path.basename(re.sub(r'_run.card',"",fileruncard))
169
170        if not showtitleoption :
171                showtitle=0
172        else :
173                showtitle=showtitleoptionvalue
174
175        #---------------------------
176        # options from pattern option
177        if patternoption :
178                for pat in pattern :
179                        pat=pat.split(',')
180                        patternword=pat[0].strip()
181                        if re.search(patternword,fileruncard) :
182                                patternoptions=pat[1:]
183                                for i in range(0,len(patternoptions)) :
184                                        exec patternoptions[i].strip()          # set options if defined
185
186        #---------------------------
187        # options from list file
188        for i in range(1,len(line)) :
189                #print i, line[i].strip()
190                exec line[i].strip()            # set options if defined
191
192        #---------------------------
193        print 'file = ', fileruncard
194        print 'linecolor = ', linecolor
195        print 'linewidth = ', linewidth
196        print 'title = ', title
197        print 'showtitle = ', showtitle
198
199        x,y1,y2 = [],[],[]
200        lineref=['# CumulPeriod | PeriodDateBegin |   PeriodDateEnd |        RunDateBegin |          RunDateEnd |     RealCpuTime |     UserCpuTime |      SysCpuTime | ExeDate']
201
202        try:
203                f=urllib2.urlopen(fileruncard)
204                csv_reader = csv.reader(f)
205                headerline = csv_reader.next()
206                while headerline != lineref :           # read until find lineref
207                        headerline = csv_reader.next()
208                # read an extra line
209                headerline = csv_reader.next()
210
211                nblines=0               
212                for line in csv_reader:
213                        a=line[0][1:]           # to remove first character=#
214                        part=a.split('|')
215
216                        PeriodDateBegin=dt.datetime.strptime(part[1].strip(),'%Y%m%d')
217                        CumulPeriod=int(part[0].strip())
218                        RunDateBegin=dt.datetime.strptime(part[3].strip(),'%Y-%m-%dT%H:%M:%S')
219                        RunDateEnd=dt.datetime.strptime(part[4].strip(),'%Y-%m-%dT%H:%M:%S')
220                        x.append(RunDateBegin)
221                        x.append(RunDateEnd)
222                        y1.append(PeriodDateBegin)
223                        y1.append(PeriodDateBegin)
224                        y2.append(CumulPeriod)
225                        y2.append(CumulPeriod)
226                        nblines=nblines+1
227
228                print '--> Read %d lines'%nblines
229                if nblines < 10 :
230                        print '----> File skipped (not enough lines < 10)'
231                        continue       
232
233                if not periodoption :
234                        y=y1
235                else :
236                        y=y2
237
238                simu,=ax.plot(x,y,'-', linewidth=linewidth, color='#'+linecolor)
239                lastx=x[-2] ; lasty=y[-2]               # before last (last is None)
240                simuname=fileruncard[:-9]               # remove _run.card
241                annotation=ax.annotate(title, xy=(lastx, lasty), xytext=(-20,20), 
242                    textcoords='offset points', ha='center', va='bottom',
243                    bbox=dict(boxstyle='round,pad=0.4', fc='yellow', alpha=0.3),
244                    arrowprops=dict(arrowstyle='->', connectionstyle='arc3', 
245                                    color='black'))
246
247                annotation.set_visible(showtitle)
248
249                if not showtitle :              # title will displayed when mouse over
250                        simus_with_annotation.append([simu,annotation])
251
252                nbsimus=nbsimus+1
253
254        except IOError :
255                print "======> IOError when reading run.card"
256                continue       
257
258        except :
259                print "======> Error when reading run.card"
260                continue       
261
262finput.close()
263
264#======================================================
265if nbsimus == 0 :
266        print '#==========================================='
267        print "======> No simulation to plot"
268        sys.exit(1)
269
270#======================================================
271# http://stackoverflow.com/questions/11537374/matplotlib-basemap-popup-box/11556140#11556140
272
273def on_move(event):
274    visibility_changed = False
275    for simu, annotation in simus_with_annotation:
276        should_be_visible = (simu.contains(event)[0] == True)
277
278        if should_be_visible != annotation.get_visible():
279            visibility_changed = True
280            x, y = event.xdata, event.ydata
281            annotation.xy = x, y
282            annotation.set_visible(should_be_visible)
283
284    if visibility_changed:       
285        plt.draw()
286
287#======================================================
288if not periodoption :
289        #from matplotlib.ticker import MaxNLocator
290        #ax.yaxis.set_major_locator(MaxNLocator(5))
291        from matplotlib.dates import YearLocator
292        ax.yaxis.set_major_locator(YearLocator(50))
293        #from matplotlib.dates import AutoDateLocator
294        #locator = AutoDateLocator(maxticks=5)
295        #ax.yaxis.set_major_locator(locator)
296        #ax.yaxis_date()
297
298else :                          # period option (not date)
299        if yscalelogoption :
300                ax.set_yscale('log')
301
302fig.autofmt_xdate()
303plt.grid(True)
304
305on_move_id = fig.canvas.mpl_connect('motion_notify_event', on_move)
306
307print '#==========================================='
308print 'Number of run.card indicated : %d' % nbfiles
309print 'Number of run.card processed : %d' % nbsimus
310print '#==========================================='
311
312plt.show()
313
314
Note: See TracBrowser for help on using the repository browser.